|
|
@@ -146,24 +146,45 @@
|
|
|
<div class="sample-stage-head">
|
|
|
<div>
|
|
|
<strong>选择喜欢的课件样式</strong>
|
|
|
- <span>已推荐“{{ selectedTemplate.name }}”,查看代表页面后可直接生成完整课件。</span>
|
|
|
+ <span>已推荐“{{ selectedTemplate.name }}”,可以逐页查看效果后再生成完整课件。</span>
|
|
|
</div>
|
|
|
<button type="button" :disabled="working" @click="templatePickerExpanded = !templatePickerExpanded">
|
|
|
{{ templatePickerExpanded ? "收起模板" : "更换模板" }}
|
|
|
</button>
|
|
|
</div>
|
|
|
|
|
|
- <div class="sample-thumbnail-grid">
|
|
|
+ <div class="sample-carousel-shell">
|
|
|
<button
|
|
|
- v-for="sample in representativeSampleSlides"
|
|
|
- :key="sample.pageNo"
|
|
|
type="button"
|
|
|
- :class="{ active: selectedPageNo === sample.pageNo }"
|
|
|
- :disabled="working"
|
|
|
- @click="selectedPageNo = sample.pageNo"
|
|
|
+ class="sample-carousel-arrow previous"
|
|
|
+ aria-label="查看前面的页面"
|
|
|
+ :disabled="!canScrollSamplePrevious"
|
|
|
+ @click="scrollSampleCarousel(-1)"
|
|
|
>
|
|
|
- <ThumbnailSlide v-if="sample.slide" :slide="sample.slide" :size="170" />
|
|
|
- <span>{{ sample.label }} · 第{{ sample.pageNo }}页</span>
|
|
|
+ ‹
|
|
|
+ </button>
|
|
|
+ <div ref="sampleCarouselRef" class="sample-thumbnail-track" @scroll="updateSampleCarouselNavigation">
|
|
|
+ <button
|
|
|
+ v-for="(slide, index) in previewSlides"
|
|
|
+ :key="slide.id"
|
|
|
+ type="button"
|
|
|
+ :class="['sample-thumbnail-item', { active: selectedPageNo === outline.pages[index]?.pageNo }]"
|
|
|
+ :disabled="working"
|
|
|
+ :title="outline.pages[index]?.title || `第${index + 1}页`"
|
|
|
+ @click="selectSamplePage(outline.pages[index]?.pageNo || index + 1, index)"
|
|
|
+ >
|
|
|
+ <ThumbnailSlide :slide="slide" :size="132" />
|
|
|
+ <span>{{ outline.pages[index]?.title || `第${index + 1}页` }}</span>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ class="sample-carousel-arrow next"
|
|
|
+ aria-label="查看后面的页面"
|
|
|
+ :disabled="!canScrollSampleNext"
|
|
|
+ @click="scrollSampleCarousel(1)"
|
|
|
+ >
|
|
|
+ ›
|
|
|
</button>
|
|
|
</div>
|
|
|
|
|
|
@@ -191,63 +212,18 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div v-if="sampleSlide" class="sample-review simplified-sample-review">
|
|
|
- <div class="sample-copy">
|
|
|
- <div class="sample-eyebrow">当前查看</div>
|
|
|
- <div class="sample-title">第{{ samplePageNo }}页 · {{ samplePageTitle }}</div>
|
|
|
- <div class="sample-hint">{{ samplePageReason }}</div>
|
|
|
- <div v-if="sampleBackgroundState.status === 'error'" class="template-load-error">模板背景加载失败,请更换模板或稍后重试</div>
|
|
|
- <div class="sample-feedback">
|
|
|
- <div class="feedback-label">不满意?告诉系统怎么调整</div>
|
|
|
- <div class="feedback-chips">
|
|
|
- <button
|
|
|
- v-for="item in sampleFeedbackOptions"
|
|
|
- :key="item"
|
|
|
- type="button"
|
|
|
- :class="{ active: sampleFeedbackTags.includes(item) }"
|
|
|
- :disabled="working"
|
|
|
- @click="toggleSampleFeedback(item)"
|
|
|
- >
|
|
|
- {{ item }}
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- <textarea
|
|
|
- v-model="sampleFeedbackText"
|
|
|
- :disabled="working"
|
|
|
- placeholder="也可以直接说明你希望怎么调整"
|
|
|
- @input="invalidateVisualApproval"
|
|
|
- ></textarea>
|
|
|
+ <div v-if="sampleSlide && selectedPage" class="sample-detail-layout">
|
|
|
+ <div class="sample-outline-panel">
|
|
|
+ <div class="sample-panel-heading">
|
|
|
+ <span>当前页大纲</span>
|
|
|
+ <strong>第{{ samplePageNo }}页</strong>
|
|
|
</div>
|
|
|
- <Button @click="regenerateSamplePage" :disabled="working">调整当前页面</Button>
|
|
|
- </div>
|
|
|
- <div class="sample-canvas">
|
|
|
- <ThumbnailSlide :slide="sampleSlide" :size="420" :show-background-error="true" @background-load-state="handleSampleBackgroundLoadState" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <button type="button" class="outline-toggle" @click="outlineExpanded = !outlineExpanded">
|
|
|
- {{ outlineExpanded ? "收起课件大纲" : `查看或修改课件大纲(共${outline.pages.length}页)` }}
|
|
|
- </button>
|
|
|
- <div v-if="outlineExpanded" class="outline-editor-panel">
|
|
|
- <div class="page-nav">
|
|
|
- <button
|
|
|
- v-for="page in outline.pages"
|
|
|
- :key="page.pageNo"
|
|
|
- class="nav-item"
|
|
|
- :class="{ active: selectedPageNo === page.pageNo }"
|
|
|
- type="button"
|
|
|
- @click="selectedPageNo = page.pageNo"
|
|
|
- >
|
|
|
- <span class="nav-no">{{ formatPageNo(page.pageNo) }}</span>
|
|
|
- <span class="nav-title">{{ page.title || "未命名页面" }}</span>
|
|
|
- </button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="selectedPage" class="page-editor simplified-page-editor">
|
|
|
- <div class="editor-head">
|
|
|
- <div class="title-editor">
|
|
|
- <input v-model="selectedPage.title" class="page-title" :disabled="working" />
|
|
|
- </div>
|
|
|
+ <div class="page-editor simplified-page-editor">
|
|
|
+ <div class="editor-head">
|
|
|
+ <div class="title-editor">
|
|
|
+ <label class="outline-field-label">页面主题</label>
|
|
|
+ <input v-model="selectedPage.title" class="page-title" :disabled="working" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<div class="field-card">
|
|
|
@@ -268,16 +244,60 @@
|
|
|
></textarea>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="sample-preview-column">
|
|
|
+ <div class="sample-preview-heading">
|
|
|
+ <div>
|
|
|
+ <span>页面预览</span>
|
|
|
+ <strong>{{ samplePageTitle }}</strong>
|
|
|
+ </div>
|
|
|
+ <small>{{ samplePageReason }}</small>
|
|
|
+ </div>
|
|
|
+ <div class="sample-canvas">
|
|
|
+ <ThumbnailSlide
|
|
|
+ :slide="sampleSlide"
|
|
|
+ :size="600"
|
|
|
+ :show-background-error="true"
|
|
|
+ @background-load-state="handleSampleBackgroundLoadState"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-if="sampleBackgroundState.status === 'error'" class="template-load-error">模板背景加载失败,请更换模板或稍后重试</div>
|
|
|
+ <div class="sample-feedback">
|
|
|
+ <div class="feedback-label">调整当前页面</div>
|
|
|
+ <div class="feedback-chips">
|
|
|
+ <button
|
|
|
+ v-for="item in sampleFeedbackOptions"
|
|
|
+ :key="item"
|
|
|
+ type="button"
|
|
|
+ :class="{ active: sampleFeedbackTags.includes(item) }"
|
|
|
+ :disabled="working"
|
|
|
+ @click="toggleSampleFeedback(item)"
|
|
|
+ >
|
|
|
+ {{ item }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ <div class="sample-feedback-action">
|
|
|
+ <textarea
|
|
|
+ v-model="sampleFeedbackText"
|
|
|
+ :disabled="working"
|
|
|
+ placeholder="也可以直接说明你希望怎么调整"
|
|
|
+ @input="invalidateVisualApproval"
|
|
|
+ ></textarea>
|
|
|
+ <Button @click="regenerateSamplePage" :disabled="working">调整当前页面</Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="footer">
|
|
|
<Button @click="emit('update:visible', false)" :disabled="working">取消</Button>
|
|
|
- <template v-if="workflowStep === 1">
|
|
|
+ <template v-if="isSetupStep">
|
|
|
<Button v-if="outline" @click="workflowStep = 2" :disabled="working">继续选择样式</Button>
|
|
|
<Button type="primary" @click="handleOutline" :disabled="working">{{ outline ? "按当前设置重新生成" : "开始生成课件" }}</Button>
|
|
|
</template>
|
|
|
- <template v-else-if="workflowStep === 2">
|
|
|
+ <template v-else-if="isStyleStep">
|
|
|
<Button @click="workflowStep = 1" :disabled="working">返回修改需求</Button>
|
|
|
<Button type="primary" @click="confirmSamplesAndGenerate" :disabled="working || sampleBackgroundState.status === 'error'"
|
|
|
>使用此样式并生成课件</Button
|
|
|
@@ -295,7 +315,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref, reactive, computed, watch } from "vue"
|
|
|
+import { ref, reactive, computed, watch, nextTick } from "vue"
|
|
|
import { ElMessage } from "element-plus"
|
|
|
import Modal from "@/components/Modal.vue"
|
|
|
import Button from "@/components/Button.vue"
|
|
|
@@ -346,6 +366,8 @@ const extraPrompt = ref("")
|
|
|
const outline = ref<AiCoursewareOutline>()
|
|
|
const taskInfo = ref<AiCoursewareTaskInfo>()
|
|
|
const workflowStep = ref<1 | 2 | 3>(1)
|
|
|
+const isSetupStep = computed(() => workflowStep.value === 1)
|
|
|
+const isStyleStep = computed(() => workflowStep.value === 2)
|
|
|
const workflowSteps = [
|
|
|
{ value: 1, label: "设置需求" },
|
|
|
{ value: 2, label: "选择样式" },
|
|
|
@@ -359,7 +381,6 @@ const templateSelectionMode = ref<"auto" | "manual">("auto")
|
|
|
const templatePickerExpanded = ref(false)
|
|
|
const advancedSettingsExpanded = ref(false)
|
|
|
const showAllTemplates = ref(false)
|
|
|
-const outlineExpanded = ref(false)
|
|
|
const paletteVariant = ref(0)
|
|
|
const pageRange = ref("9-12")
|
|
|
const preferences = reactive<AiCoursewarePreferences>({
|
|
|
@@ -387,6 +408,9 @@ const TEACHER_VISIBLE_PATTERN = /(?:教师|老师)(?:讲述|提问|引导|指导
|
|
|
const PLACEHOLDER_PATTERN = /(?:待补充|待完善|请输入|可参考教材|placeholder|lorem ipsum|\{\{.+?\}\}|\[.+?占位.+?\])/i
|
|
|
const pollTimer = ref<number>()
|
|
|
const selectedPageNo = ref(1)
|
|
|
+const sampleCarouselRef = ref<HTMLElement>()
|
|
|
+const canScrollSamplePrevious = ref(false)
|
|
|
+const canScrollSampleNext = ref(false)
|
|
|
const selectedDraftPageIndex = ref(0)
|
|
|
const outlineLoading = ref(false)
|
|
|
const working = computed(
|
|
|
@@ -522,12 +546,33 @@ const previewSlides = computed(() => {
|
|
|
}).slides
|
|
|
})
|
|
|
const sampleSlide = computed(() => previewSlides.value?.[samplePageIndex.value])
|
|
|
-const representativeSampleSlides = computed(() =>
|
|
|
- representativeSamples.value.map(sample => {
|
|
|
- const pageIndex = outline.value?.pages.findIndex(page => page.pageNo === sample.pageNo) ?? -1
|
|
|
- return { ...sample, slide: pageIndex >= 0 ? previewSlides.value?.[pageIndex] : undefined }
|
|
|
- })
|
|
|
-)
|
|
|
+
|
|
|
+function updateSampleCarouselNavigation() {
|
|
|
+ const carousel = sampleCarouselRef.value
|
|
|
+ if (!carousel) {
|
|
|
+ canScrollSamplePrevious.value = false
|
|
|
+ canScrollSampleNext.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ canScrollSamplePrevious.value = carousel.scrollLeft > 2
|
|
|
+ canScrollSampleNext.value = carousel.scrollLeft + carousel.clientWidth < carousel.scrollWidth - 2
|
|
|
+}
|
|
|
+
|
|
|
+function scrollSampleCarousel(direction: -1 | 1) {
|
|
|
+ const carousel = sampleCarouselRef.value
|
|
|
+ if (!carousel) return
|
|
|
+ carousel.scrollBy({ left: direction * Math.max(320, carousel.clientWidth * 0.72), behavior: "smooth" })
|
|
|
+}
|
|
|
+
|
|
|
+function selectSamplePage(pageNo: number, index: number) {
|
|
|
+ if (selectedPageNo.value !== pageNo) {
|
|
|
+ sampleFeedbackTags.value = []
|
|
|
+ sampleFeedbackText.value = ""
|
|
|
+ }
|
|
|
+ selectedPageNo.value = pageNo
|
|
|
+ const item = sampleCarouselRef.value?.children.item(index) as HTMLElement | null
|
|
|
+ item?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" })
|
|
|
+}
|
|
|
|
|
|
watch(selectedTemplateId, () => {
|
|
|
paletteVariant.value = 0
|
|
|
@@ -560,6 +605,15 @@ watch(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
+watch(
|
|
|
+ [workflowStep, selectedTemplateId, () => outline.value?.pages.length],
|
|
|
+ async () => {
|
|
|
+ await nextTick()
|
|
|
+ updateSampleCarouselNavigation()
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+)
|
|
|
+
|
|
|
async function handleOutline() {
|
|
|
if (!pptWork.id) {
|
|
|
ElMessage.error("当前课件ID为空")
|
|
|
@@ -778,15 +832,16 @@ function invalidateVisualApproval() {
|
|
|
}
|
|
|
|
|
|
async function confirmSamplesAndGenerate() {
|
|
|
- if (representativeSampleSlides.value.length !== 3 || representativeSampleSlides.value.some(sample => !sample.slide)) {
|
|
|
- ElMessage.error("代表样稿尚未准备完成,请稍后重试")
|
|
|
+ const slides = previewSlides.value || []
|
|
|
+ if (!outline.value || slides.length !== outline.value.pages.length) {
|
|
|
+ ElMessage.error("页面预览尚未准备完成,请稍后重试")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
const backgroundUrls = Array.from(
|
|
|
new Set(
|
|
|
- representativeSampleSlides.value
|
|
|
- .map(sample => (sample.slide?.background?.type === "image" ? resolveTemplateAssetUrl(sample.slide.background.image) : ""))
|
|
|
+ slides
|
|
|
+ .map(slide => (slide.background?.type === "image" ? resolveTemplateAssetUrl(slide.background.image) : ""))
|
|
|
.filter(Boolean)
|
|
|
)
|
|
|
)
|
|
|
@@ -1511,31 +1566,73 @@ function shortProgressLabel(message?: string) {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
-.sample-thumbnail-grid {
|
|
|
+.sample-carousel-shell {
|
|
|
display: grid;
|
|
|
- grid-template-columns: repeat(3, 170px);
|
|
|
- justify-content: center;
|
|
|
- gap: 16px;
|
|
|
+ grid-template-columns: 34px minmax(0, 1fr) 34px;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
margin-top: 12px;
|
|
|
- button {
|
|
|
- padding: 0;
|
|
|
- overflow: hidden;
|
|
|
- border: 2px solid transparent;
|
|
|
- border-radius: 7px;
|
|
|
- background: #fff;
|
|
|
- color: #52616b;
|
|
|
- cursor: pointer;
|
|
|
- box-shadow: 0 4px 12px rgba(31, 41, 51, 0.08);
|
|
|
+}
|
|
|
+.sample-carousel-arrow {
|
|
|
+ width: 34px;
|
|
|
+ height: 34px;
|
|
|
+ padding: 0;
|
|
|
+ border: 1px solid #d8e1eb;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #fff;
|
|
|
+ color: #52616b;
|
|
|
+ font-size: 24px;
|
|
|
+ line-height: 30px;
|
|
|
+ cursor: pointer;
|
|
|
+ box-shadow: 0 3px 10px rgba(31, 41, 51, 0.08);
|
|
|
+ &:hover:not(:disabled) {
|
|
|
+ border-color: $themeColor;
|
|
|
+ color: $themeColor;
|
|
|
}
|
|
|
- button.active {
|
|
|
+ &:disabled {
|
|
|
+ opacity: 0.28;
|
|
|
+ cursor: default;
|
|
|
+ }
|
|
|
+}
|
|
|
+.sample-thumbnail-track {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ min-width: 0;
|
|
|
+ overflow-x: auto;
|
|
|
+ padding: 3px;
|
|
|
+ scroll-behavior: smooth;
|
|
|
+ scroll-snap-type: x proximity;
|
|
|
+ scrollbar-width: none;
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+.sample-thumbnail-item {
|
|
|
+ width: 136px;
|
|
|
+ flex: 0 0 136px;
|
|
|
+ padding: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ border: 2px solid transparent;
|
|
|
+ border-radius: 7px;
|
|
|
+ background: #fff;
|
|
|
+ color: #52616b;
|
|
|
+ text-align: left;
|
|
|
+ cursor: pointer;
|
|
|
+ scroll-snap-align: start;
|
|
|
+ box-shadow: 0 3px 10px rgba(31, 41, 51, 0.08);
|
|
|
+ transition: border-color 0.16s ease, box-shadow 0.16s ease;
|
|
|
+ &.active {
|
|
|
border-color: $themeColor;
|
|
|
+ box-shadow: 0 0 0 2px rgba($themeColor, 0.1);
|
|
|
}
|
|
|
- span {
|
|
|
+ > span {
|
|
|
display: block;
|
|
|
- padding: 7px 8px;
|
|
|
+ padding: 6px 7px 7px;
|
|
|
+ overflow: hidden;
|
|
|
font-size: 11px;
|
|
|
font-weight: 600;
|
|
|
- text-align: left;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
}
|
|
|
.compact-template-panel {
|
|
|
@@ -1553,50 +1650,57 @@ function shortProgressLabel(message?: string) {
|
|
|
margin: 0;
|
|
|
}
|
|
|
}
|
|
|
-.simplified-sample-review {
|
|
|
- grid-column: auto;
|
|
|
- margin-top: 12px;
|
|
|
-}
|
|
|
-.outline-toggle {
|
|
|
- display: block;
|
|
|
- margin: 14px auto 0;
|
|
|
-}
|
|
|
-.outline-editor-panel {
|
|
|
+.sample-detail-layout {
|
|
|
display: grid;
|
|
|
- grid-template-columns: 260px minmax(0, 1fr);
|
|
|
- gap: 12px;
|
|
|
- min-height: 280px;
|
|
|
- margin-top: 10px;
|
|
|
-}
|
|
|
-.simplified-page-editor .field-card {
|
|
|
- margin-top: 12px;
|
|
|
+ grid-template-columns: minmax(280px, 0.72fr) minmax(0, 1.45fr);
|
|
|
+ align-items: start;
|
|
|
+ gap: 16px;
|
|
|
+ margin-top: 14px;
|
|
|
}
|
|
|
-.sample-review {
|
|
|
- grid-column: 1 / -1;
|
|
|
- display: grid;
|
|
|
- grid-template-columns: minmax(360px, 1fr) 420px;
|
|
|
- align-items: center;
|
|
|
- gap: 20px;
|
|
|
- padding: 16px;
|
|
|
+.sample-outline-panel,
|
|
|
+.sample-preview-column {
|
|
|
+ min-width: 0;
|
|
|
+ padding: 14px;
|
|
|
border: 1px solid #e5eaf0;
|
|
|
- border-radius: 8px;
|
|
|
+ border-radius: 10px;
|
|
|
background: #fafcff;
|
|
|
}
|
|
|
-.sample-eyebrow {
|
|
|
- color: $themeColor;
|
|
|
- font-size: 12px;
|
|
|
- font-weight: 700;
|
|
|
-}
|
|
|
-.sample-title {
|
|
|
- margin: 7px 0 4px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 700;
|
|
|
-}
|
|
|
-.sample-hint {
|
|
|
+.sample-panel-heading,
|
|
|
+.sample-preview-heading {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ justify-content: space-between;
|
|
|
+ gap: 12px;
|
|
|
margin-bottom: 10px;
|
|
|
+ span,
|
|
|
+ strong {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ span {
|
|
|
+ color: $themeColor;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ strong {
|
|
|
+ margin-top: 3px;
|
|
|
+ color: #1f2933;
|
|
|
+ font-size: 15px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.sample-panel-heading > strong {
|
|
|
+ margin-top: 0;
|
|
|
color: #7b8794;
|
|
|
font-size: 12px;
|
|
|
- line-height: 1.6;
|
|
|
+}
|
|
|
+.sample-preview-heading small {
|
|
|
+ max-width: 52%;
|
|
|
+ color: #7b8794;
|
|
|
+ font-size: 11px;
|
|
|
+ line-height: 1.5;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+.simplified-page-editor .field-card {
|
|
|
+ margin-top: 12px;
|
|
|
}
|
|
|
.representative-samples {
|
|
|
display: grid;
|
|
|
@@ -1871,7 +1975,9 @@ function shortProgressLabel(message?: string) {
|
|
|
}
|
|
|
}
|
|
|
.sample-feedback {
|
|
|
- margin-top: 10px;
|
|
|
+ margin-top: 12px;
|
|
|
+ padding-top: 12px;
|
|
|
+ border-top: 1px solid #e5eaf0;
|
|
|
}
|
|
|
.feedback-label {
|
|
|
color: #52616b;
|
|
|
@@ -1902,8 +2008,8 @@ function shortProgressLabel(message?: string) {
|
|
|
}
|
|
|
.sample-feedback textarea {
|
|
|
width: 100%;
|
|
|
- height: 54px;
|
|
|
- margin-top: 7px;
|
|
|
+ height: 58px;
|
|
|
+ margin: 0;
|
|
|
padding: 8px 10px;
|
|
|
border: 1px solid #dfe5ec;
|
|
|
border-radius: 6px;
|
|
|
@@ -1913,32 +2019,33 @@ function shortProgressLabel(message?: string) {
|
|
|
font-size: 12px;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
-.sample-actions {
|
|
|
- display: flex;
|
|
|
+.sample-feedback-action {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: minmax(0, 1fr) auto;
|
|
|
+ align-items: end;
|
|
|
gap: 8px;
|
|
|
- margin-top: 10px;
|
|
|
+ margin-top: 8px;
|
|
|
+ :deep(.button) {
|
|
|
+ height: 34px;
|
|
|
+ line-height: 34px;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
}
|
|
|
.sample-canvas {
|
|
|
position: relative;
|
|
|
- overflow: hidden;
|
|
|
- border: 2px solid transparent;
|
|
|
- border-radius: 6px;
|
|
|
- box-shadow: 0 6px 20px rgba(31, 41, 51, 0.12);
|
|
|
-}
|
|
|
-.sample-canvas.approved {
|
|
|
- border-color: #168f86;
|
|
|
-}
|
|
|
-.sample-approved-mark {
|
|
|
- position: absolute;
|
|
|
- top: 10px;
|
|
|
- right: 10px;
|
|
|
- padding: 5px 9px;
|
|
|
- border-radius: 999px;
|
|
|
- background: #168f86;
|
|
|
- color: #fff;
|
|
|
- font-size: 11px;
|
|
|
- font-weight: 700;
|
|
|
- box-shadow: 0 4px 12px rgba(22, 143, 134, 0.25);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ overflow: auto;
|
|
|
+ padding: 12px;
|
|
|
+ border: 1px solid #e0e7ef;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: #eef2f7;
|
|
|
+ :deep(.thumbnail-slide) {
|
|
|
+ flex-shrink: 0;
|
|
|
+ border-radius: 6px;
|
|
|
+ box-shadow: 0 8px 24px rgba(31, 41, 51, 0.14);
|
|
|
+ }
|
|
|
}
|
|
|
.result-preview {
|
|
|
min-height: 0;
|
|
|
@@ -2196,6 +2303,13 @@ function shortProgressLabel(message?: string) {
|
|
|
.title-editor {
|
|
|
max-width: 460px;
|
|
|
}
|
|
|
+.outline-field-label {
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #52616b;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
.purpose-card {
|
|
|
margin-top: 12px;
|
|
|
}
|
|
|
@@ -2388,19 +2502,13 @@ function shortProgressLabel(message?: string) {
|
|
|
height: calc(100vh - 64px);
|
|
|
}
|
|
|
.setup-primary-grid,
|
|
|
- .outline-editor-panel {
|
|
|
- grid-template-columns: 1fr;
|
|
|
- }
|
|
|
- .sample-review {
|
|
|
+ .sample-detail-layout {
|
|
|
grid-template-columns: 1fr;
|
|
|
}
|
|
|
.sample-canvas {
|
|
|
justify-self: center;
|
|
|
max-width: 100%;
|
|
|
}
|
|
|
- .sample-thumbnail-grid {
|
|
|
- grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
|
- }
|
|
|
.compact-template-panel .sample-template-picker {
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
}
|
|
|
@@ -2432,9 +2540,24 @@ function shortProgressLabel(message?: string) {
|
|
|
width: 20px;
|
|
|
height: 20px;
|
|
|
}
|
|
|
- .sample-thumbnail-grid {
|
|
|
+ .sample-carousel-shell {
|
|
|
+ grid-template-columns: 30px minmax(0, 1fr) 30px;
|
|
|
+ gap: 5px;
|
|
|
+ }
|
|
|
+ .sample-carousel-arrow {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ }
|
|
|
+ .sample-feedback-action {
|
|
|
grid-template-columns: 1fr;
|
|
|
}
|
|
|
+ .sample-preview-heading {
|
|
|
+ flex-direction: column;
|
|
|
+ small {
|
|
|
+ max-width: none;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+ }
|
|
|
.compact-template-panel .sample-template-picker {
|
|
|
grid-template-columns: 1fr;
|
|
|
}
|