aegon-dangerious 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/build-report/components/AiPromptGenerateDialog.vue +349 -0
  2. package/build-report/components/CapsuleScrollbar.vue +145 -0
  3. package/build-report/components/ChapterTitleScroll.vue +292 -0
  4. package/build-report/components/PromptField.vue +314 -0
  5. package/build-report/components/RecentReportsTable.vue +408 -0
  6. package/build-report/components/ReportChapterPreview.vue +437 -0
  7. package/build-report/components/ReportChapterWorkspace.vue +923 -0
  8. package/build-report/components/ReportCollapsibleSection.vue +132 -0
  9. package/build-report/components/ReportConfigPanel.vue +609 -0
  10. package/build-report/components/ReportGenerateSettingsPanel.vue +403 -0
  11. package/build-report/components/ReportGeneratingPanel.vue +908 -0
  12. package/build-report/components/ReportHistoryList.vue +157 -0
  13. package/build-report/components/ReportHistoryPanel.vue +140 -0
  14. package/build-report/components/ReportPromptPanel.vue +445 -0
  15. package/build-report/components/ReportSectionConfirmPopover.vue +232 -0
  16. package/build-report/components/ReportSourceFileSummary.vue +544 -0
  17. package/build-report/components/ReportSourcesMoreOverlay.vue +279 -0
  18. package/build-report/components/ReportSourcesPanel.vue +1055 -0
  19. package/build-report/components/ReportTemplateDetail.vue +176 -0
  20. package/build-report/components/ReportTemplateEditorFormPanel.vue +602 -0
  21. package/build-report/components/ReportTemplatePicker.vue +802 -0
  22. package/build-report/components/ReportTemplatePromptField.vue +314 -0
  23. package/build-report/components/ReportWorkflowSidebar.vue +104 -0
  24. package/build-report/components/reportEdit.vue +334 -0
  25. package/build-report/index.vue +646 -0
  26. package/build-report/report-list.vue +407 -0
  27. package/build-report/report-template-data.ts +248 -0
  28. package/build-report/styles/report-workflow-dialog.css +33 -0
  29. package/build-report/useReportWorkflow.ts +343 -0
  30. package/build-report/utils/report-edit-route.ts +109 -0
  31. package/build-report/utils/scroll.ts +361 -0
  32. package/package.json +12 -0
@@ -0,0 +1,334 @@
1
+ <template>
2
+ <div ref="pageRef" class="report-edit-page" :class="{
3
+ 'is-generating': currentStep === 'generating',
4
+ 'is-prompt': currentStep === 'prompt',
5
+ 'is-sources-more-open': sourcesMoreOpen,
6
+ }">
7
+ <ReportGeneratingPanel v-if="currentStep === 'generating'" class="report-edit-page__generating"
8
+ @enter-editing="handleEnterEditing" />
9
+
10
+ <template v-else>
11
+ <ReportWorkflowSidebar class="report-edit-page__sidebar" :use-more-overlay="true"
12
+ @show-more="openSourcesMore" />
13
+
14
+ <main ref="mainRef" class="report-edit-page__main report-edit-page__main--anchored">
15
+ <ReportTemplatePicker v-if="currentStep === 'select'" @select="handleSelectTemplate" />
16
+
17
+ <ReportTemplateDetail v-else-if="currentStep === 'detail' && selectedTemplate" :template="selectedTemplate"
18
+ @back="goBackToSelect" @generate="goGenerating" />
19
+
20
+ <ReportChapterWorkspace v-else-if="currentStep === 'prompt'" @generate-report="openGenerateSettings"
21
+ @back-to-chapter-edit="backToChapterEdit" />
22
+
23
+ <ReportSourcesMoreOverlay v-if="sourcesMoreOpen" ref="sourcesMoreOverlayRef"
24
+ :parent-label="sourcesOverlayParentLabel" @close="closeSourcesMore" />
25
+ </main>
26
+
27
+ <template v-if="currentStep === 'prompt'">
28
+ <ReportPromptPanel v-if="currentRightPanel === 'prompt'" class="report-edit-page__prompt" />
29
+ <div v-else class="report-edit-page__prompt report-edit-page__right-stack">
30
+ <ReportGenerateSettingsPanel @generate="goGenerating" />
31
+ <ReportHistoryPanel />
32
+ </div>
33
+ </template>
34
+ </template>
35
+ </div>
36
+ </template>
37
+
38
+ <script setup lang="ts">
39
+ import { ElMessage } from 'element-plus'
40
+ import { computed, defineAsyncComponent, nextTick, onMounted, ref, watch } from 'vue'
41
+ import { useRoute, useRouter } from 'vue-router'
42
+ import type { ReportTemplateCard } from '../report-template-data'
43
+ import { useReportWorkflow } from '../useReportWorkflow'
44
+ import {
45
+ createReportEditRouteSyncActions,
46
+ navigateToReportEdit,
47
+ parsePromptRightPanel,
48
+ parseReportEditStep,
49
+ syncWorkflowFromReportEditRoute,
50
+ } from '../utils/report-edit-route'
51
+ import ReportGenerateSettingsPanel from './ReportGenerateSettingsPanel.vue'
52
+ import ReportHistoryPanel from './ReportHistoryPanel.vue'
53
+ import ReportTemplateDetail from './ReportTemplateDetail.vue'
54
+ import ReportTemplatePicker from './ReportTemplatePicker.vue'
55
+ import ReportSourcesMoreOverlay from './ReportSourcesMoreOverlay.vue'
56
+ import ReportWorkflowSidebar from './ReportWorkflowSidebar.vue'
57
+
58
+ type ReportSourcesMoreOverlayExpose = {
59
+ resetBodyScroll: () => void
60
+ }
61
+
62
+ const router = useRouter()
63
+ const route = useRoute()
64
+ const workflow = useReportWorkflow()
65
+ const routeSyncActions = createReportEditRouteSyncActions(workflow)
66
+
67
+ const {
68
+ loadDraftFromSession,
69
+ loadTemplateFromSession,
70
+ setSelectedTemplate,
71
+ selectedTemplate,
72
+ sourceFiles,
73
+ } = workflow
74
+
75
+ const currentStep = computed(() => parseReportEditStep(route) ?? 'select')
76
+ const currentRightPanel = computed(() => parsePromptRightPanel(route))
77
+ const sourcesMoreOpen = ref(false)
78
+ const pageRef = ref<HTMLElement | null>(null)
79
+ const mainRef = ref<HTMLElement | null>(null)
80
+ const sourcesMoreOverlayRef = ref<ReportSourcesMoreOverlayExpose | null>(null)
81
+
82
+ const sourcesOverlayParentLabel = computed(() => {
83
+ switch (currentStep.value) {
84
+ case 'detail':
85
+ return '模板配置'
86
+ case 'prompt':
87
+ return '章節編輯'
88
+ default:
89
+ return '選擇模板'
90
+ }
91
+ })
92
+
93
+ const ReportGeneratingPanel = defineAsyncComponent(() => import('./ReportGeneratingPanel.vue'))
94
+ const ReportChapterWorkspace = defineAsyncComponent(() => import('./ReportChapterWorkspace.vue'))
95
+ const ReportPromptPanel = defineAsyncComponent(() => import('./ReportPromptPanel.vue'))
96
+
97
+ function syncFromRoute(target = route) {
98
+ syncWorkflowFromReportEditRoute(target, routeSyncActions)
99
+ }
100
+
101
+ watch(
102
+ () => [
103
+ route.query.pageName,
104
+ route.query.step,
105
+ route.query.templateId,
106
+ route.query.rightPanel,
107
+ ] as const,
108
+ () => syncFromRoute(),
109
+ { immediate: true },
110
+ )
111
+
112
+ async function navigateStep(
113
+ step: Parameters<typeof navigateToReportEdit>[1],
114
+ templateId?: string,
115
+ rightPanel?: Parameters<typeof navigateToReportEdit>[4],
116
+ ) {
117
+ await navigateToReportEdit(router, step, templateId, true, rightPanel)
118
+ syncFromRoute()
119
+ }
120
+
121
+ function handleSelectTemplate(template: ReportTemplateCard) {
122
+ setSelectedTemplate(template)
123
+ void navigateStep('detail', template.id)
124
+ }
125
+
126
+ function goBackToSelect() {
127
+ void navigateStep('select')
128
+ }
129
+
130
+ function openGenerateSettings() {
131
+ if (!sourceFiles.value.length) {
132
+ ElMessage.warning('請至少添加一個信息源文件')
133
+ return
134
+ }
135
+ void navigateStep('prompt', selectedTemplate.value?.id, 'settings')
136
+ }
137
+
138
+ function backToChapterEdit() {
139
+ void navigateStep('prompt', selectedTemplate.value?.id, 'prompt')
140
+ }
141
+
142
+ function goGenerating() {
143
+ void navigateStep('generating', selectedTemplate.value?.id)
144
+ }
145
+
146
+ function handleEnterEditing() {
147
+ loadTemplateFromSession()
148
+ void navigateStep('prompt', selectedTemplate.value?.id)
149
+ }
150
+
151
+ function ensurePromptTemplate() {
152
+ if (currentStep.value !== 'prompt') return
153
+ if (!selectedTemplate.value) {
154
+ loadTemplateFromSession()
155
+ }
156
+ if (!selectedTemplate.value) {
157
+ void navigateStep('select')
158
+ }
159
+ }
160
+
161
+ function closeSourcesMore() {
162
+ sourcesMoreOpen.value = false
163
+ }
164
+
165
+ function openSourcesMore() {
166
+ sourcesMoreOpen.value = true
167
+
168
+ void nextTick(() => {
169
+ sourcesMoreOverlayRef.value?.resetBodyScroll()
170
+
171
+ const page = pageRef.value
172
+ const main = mainRef.value
173
+ if (!page || !main) return
174
+
175
+ const pageRect = page.getBoundingClientRect()
176
+ const mainRect = main.getBoundingClientRect()
177
+ const delta = mainRect.top - pageRect.top
178
+
179
+ if (Math.abs(delta) <= 1) return
180
+
181
+ page.scrollTo({
182
+ top: Math.max(0, page.scrollTop + delta),
183
+ behavior: 'auto',
184
+ })
185
+ })
186
+ }
187
+
188
+ onMounted(() => {
189
+ loadDraftFromSession()
190
+ loadTemplateFromSession()
191
+ syncFromRoute()
192
+ ensurePromptTemplate()
193
+
194
+ if (currentStep.value === 'detail' && !selectedTemplate.value) {
195
+ void navigateStep('select')
196
+ }
197
+ })
198
+
199
+ watch(currentStep, () => {
200
+ closeSourcesMore()
201
+ ensurePromptTemplate()
202
+ })
203
+ </script>
204
+
205
+ <style scoped>
206
+ .report-edit-page {
207
+ display: grid;
208
+ grid-template-columns: minmax(0, 2fr) minmax(0, 8fr);
209
+ gap: 20px;
210
+ box-sizing: border-box;
211
+ align-items: stretch;
212
+ min-height: calc(100dvh - 48px);
213
+ max-height: 100dvh;
214
+ padding: 24px 30px;
215
+ overflow-y: auto;
216
+ background: #fff;
217
+ }
218
+
219
+ .report-edit-page.is-generating {
220
+ display: block;
221
+ grid-template-columns: none;
222
+ gap: 0;
223
+ padding: 0;
224
+ max-height: none;
225
+ min-height: 100dvh;
226
+ overflow: hidden;
227
+ }
228
+
229
+ .report-edit-page.is-prompt {
230
+ --report-edit-border: #ebeef5;
231
+ grid-template-columns: minmax(0, 2fr) minmax(0, 6fr) minmax(0, 2fr);
232
+ align-items: stretch;
233
+ overflow-x: hidden;
234
+ overflow-y: auto;
235
+ }
236
+
237
+ .report-edit-page.is-prompt .report-edit-page__main {
238
+ display: flex;
239
+ flex-direction: column;
240
+ min-height: calc(100dvh - 96px);
241
+ height: 100%;
242
+ padding: 16px 20px;
243
+ border: 1px solid var(--report-edit-border);
244
+ overflow: visible;
245
+ }
246
+
247
+ .report-edit-page.is-prompt .report-edit-page__main>.report-chapter-workspace {
248
+ flex: 1;
249
+ min-height: 0;
250
+ }
251
+
252
+ .report-edit-page.is-prompt .report-edit-page__prompt,
253
+ .report-edit-page.is-prompt .report-edit-page__right-stack {
254
+ min-height: calc(100dvh - 96px);
255
+ height: 100%;
256
+ overflow: visible;
257
+ }
258
+
259
+ .report-edit-page.is-prompt .report-edit-page__prompt:has(.report-prompt-panel.is-compact) {
260
+ min-height: 0;
261
+ height: auto;
262
+ align-self: flex-start;
263
+ }
264
+
265
+ .report-edit-page__right-stack {
266
+ display: flex;
267
+ flex-direction: column;
268
+ gap: 14px;
269
+ align-self: stretch;
270
+ min-width: 0;
271
+ overflow-y: auto;
272
+ }
273
+
274
+ .report-edit-page__right-stack> :first-child {
275
+ flex: 1;
276
+ min-height: 0;
277
+ }
278
+
279
+ .report-edit-page.is-prompt .report-edit-page__sidebar {
280
+ min-height: calc(100dvh - 96px);
281
+ height: 100%;
282
+ overflow: visible;
283
+ }
284
+
285
+ .report-edit-page__generating {
286
+ min-height: 100dvh;
287
+ }
288
+
289
+ .report-edit-page__sidebar {
290
+ align-self: stretch;
291
+ min-width: 0;
292
+ min-height: 0;
293
+ overflow: visible;
294
+ }
295
+
296
+ .report-edit-page__main {
297
+ min-width: 0;
298
+ min-height: calc(100dvh - 48px);
299
+ border-radius: 8px;
300
+ background: #fff;
301
+ box-sizing: border-box;
302
+ }
303
+
304
+ .report-edit-page__main--anchored {
305
+ position: relative;
306
+ }
307
+
308
+ .report-edit-page.is-sources-more-open {
309
+ overflow: hidden;
310
+ }
311
+
312
+ .report-edit-page.is-sources-more-open .report-edit-page__main--anchored {
313
+ min-height: calc(100dvh - 96px);
314
+ }
315
+
316
+ .report-edit-page__toolbar {
317
+ margin-bottom: 12px;
318
+ }
319
+
320
+ .report-edit-page__prompt {
321
+ align-self: stretch;
322
+ min-width: 0;
323
+ min-height: calc(100dvh - 48px);
324
+ }
325
+
326
+ @media (max-width: 1100px) {
327
+
328
+ .report-edit-page,
329
+ .report-edit-page.is-prompt {
330
+ grid-template-columns: 1fr;
331
+ max-height: none;
332
+ }
333
+ }
334
+ </style>