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.
- package/build-report/components/AiPromptGenerateDialog.vue +349 -0
- package/build-report/components/CapsuleScrollbar.vue +145 -0
- package/build-report/components/ChapterTitleScroll.vue +292 -0
- package/build-report/components/PromptField.vue +314 -0
- package/build-report/components/RecentReportsTable.vue +408 -0
- package/build-report/components/ReportChapterPreview.vue +437 -0
- package/build-report/components/ReportChapterWorkspace.vue +923 -0
- package/build-report/components/ReportCollapsibleSection.vue +132 -0
- package/build-report/components/ReportConfigPanel.vue +609 -0
- package/build-report/components/ReportGenerateSettingsPanel.vue +403 -0
- package/build-report/components/ReportGeneratingPanel.vue +908 -0
- package/build-report/components/ReportHistoryList.vue +157 -0
- package/build-report/components/ReportHistoryPanel.vue +140 -0
- package/build-report/components/ReportPromptPanel.vue +445 -0
- package/build-report/components/ReportSectionConfirmPopover.vue +232 -0
- package/build-report/components/ReportSourceFileSummary.vue +544 -0
- package/build-report/components/ReportSourcesMoreOverlay.vue +279 -0
- package/build-report/components/ReportSourcesPanel.vue +1055 -0
- package/build-report/components/ReportTemplateDetail.vue +176 -0
- package/build-report/components/ReportTemplateEditorFormPanel.vue +602 -0
- package/build-report/components/ReportTemplatePicker.vue +802 -0
- package/build-report/components/ReportTemplatePromptField.vue +314 -0
- package/build-report/components/ReportWorkflowSidebar.vue +104 -0
- package/build-report/components/reportEdit.vue +334 -0
- package/build-report/index.vue +646 -0
- package/build-report/report-list.vue +407 -0
- package/build-report/report-template-data.ts +248 -0
- package/build-report/styles/report-workflow-dialog.css +33 -0
- package/build-report/useReportWorkflow.ts +343 -0
- package/build-report/utils/report-edit-route.ts +109 -0
- package/build-report/utils/scroll.ts +361 -0
- package/package.json +12 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ReportCollapsibleSection ref="sectionRef" v-model:open="panelOpen" title="编辑者"
|
|
3
|
+
@before-collapse="handleBeforeCollapse">
|
|
4
|
+
<template #actions>
|
|
5
|
+
<button v-if="canManageReportEditors" ref="addBtnRef" type="button" class="report-icon-btn" aria-label="添加"
|
|
6
|
+
@click.stop="toggleAddOpen">
|
|
7
|
+
<el-icon>
|
|
8
|
+
<Plus />
|
|
9
|
+
</el-icon>
|
|
10
|
+
</button>
|
|
11
|
+
<button v-if="canManageReportEditors" ref="shareBtnRef" type="button" class="report-icon-btn" aria-label="轉移發起人"
|
|
12
|
+
@click.stop="toggleShareOpen">
|
|
13
|
+
<el-icon>
|
|
14
|
+
<Share />
|
|
15
|
+
</el-icon>
|
|
16
|
+
</button>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<div class="report-editor-panel">
|
|
20
|
+
<ul class="report-editor-list">
|
|
21
|
+
<li v-for="editor in editors" :key="editor.id" class="report-editor-list__row">
|
|
22
|
+
<span class="report-editor-list__name" :title="`${editor.name}(${editor.employeeId})`">
|
|
23
|
+
{{ editor.name }}({{ editor.employeeId }})
|
|
24
|
+
</span>
|
|
25
|
+
<span class="report-editor-list__dept">{{ editor.department }}</span>
|
|
26
|
+
<span class="report-editor-list__role">{{ editorRoleLabel(editor.role) }}</span>
|
|
27
|
+
<span class="report-editor-list__action">
|
|
28
|
+
<button v-if="canManageReportEditors && editor.role !== 'initiator'" type="button" class="report-icon-btn"
|
|
29
|
+
:aria-label="`移除${editor.name}`" @click="requestRemoveEditor(editor, $event)">
|
|
30
|
+
<el-icon>
|
|
31
|
+
<Close />
|
|
32
|
+
</el-icon>
|
|
33
|
+
</button>
|
|
34
|
+
</span>
|
|
35
|
+
</li>
|
|
36
|
+
</ul>
|
|
37
|
+
</div>
|
|
38
|
+
</ReportCollapsibleSection>
|
|
39
|
+
|
|
40
|
+
<el-popover :visible="addOpen" :virtual-ref="shareToggleRef" placement="bottom-start" :width="popoverWidth"
|
|
41
|
+
:popper-options="popperOptions" :popper-style="addPopperStyle" popper-class="report-config-popover"
|
|
42
|
+
:transition="popoverInstant ? 'report-config-popover-instant' : 'report-config-popover-fade'"
|
|
43
|
+
:gpu-acceleration="false" :teleported="true">
|
|
44
|
+
<div class="report-source-transfer">
|
|
45
|
+
<h4 class="report-source-transfer__title">添加编辑者</h4>
|
|
46
|
+
<label class="report-source-transfer__field">
|
|
47
|
+
<span class="report-source-transfer__label">用戶</span>
|
|
48
|
+
<el-select v-model="addSelectedUser" class="report-source-transfer__select" filterable clearable
|
|
49
|
+
placeholder="請選擇用戶">
|
|
50
|
+
<el-option v-for="user in addEditorOptions" :key="user.id"
|
|
51
|
+
:label="`${user.name}(${user.employeeId})`" :value="user.id" />
|
|
52
|
+
</el-select>
|
|
53
|
+
</label>
|
|
54
|
+
<div class="report-source-transfer__actions">
|
|
55
|
+
<button type="button" class="report-source-transfer__btn" @click="addOpen = false">取消</button>
|
|
56
|
+
<button type="button" class="report-source-transfer__btn report-source-transfer__btn--primary"
|
|
57
|
+
@click="confirmAdd">
|
|
58
|
+
確認
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</el-popover>
|
|
63
|
+
|
|
64
|
+
<el-popover :visible="shareOpen" :virtual-ref="shareToggleRef" placement="bottom-start" :width="popoverWidth"
|
|
65
|
+
:popper-options="popperOptions" :popper-style="sharePopperStyle" popper-class="report-config-popover"
|
|
66
|
+
:transition="popoverInstant ? 'report-config-popover-instant' : 'report-config-popover-fade'"
|
|
67
|
+
:gpu-acceleration="false" :teleported="true">
|
|
68
|
+
<div class="report-source-transfer">
|
|
69
|
+
<h4 class="report-source-transfer__title">轉移報告發起人權限</h4>
|
|
70
|
+
<label class="report-source-transfer__field">
|
|
71
|
+
<span class="report-source-transfer__label">用戶</span>
|
|
72
|
+
<el-select v-model="transferSelectedUser" class="report-source-transfer__select" filterable clearable
|
|
73
|
+
placeholder="請選擇用戶">
|
|
74
|
+
<el-option v-for="user in transferUserOptions" :key="user.id"
|
|
75
|
+
:label="`${user.name}(${user.employeeId})`" :value="user.id" />
|
|
76
|
+
</el-select>
|
|
77
|
+
</label>
|
|
78
|
+
<div class="report-source-transfer__actions">
|
|
79
|
+
<button type="button" class="report-source-transfer__btn" @click="shareOpen = false">取消</button>
|
|
80
|
+
<button type="button" class="report-source-transfer__btn report-source-transfer__btn--primary"
|
|
81
|
+
@click="confirmTransfer">
|
|
82
|
+
確認
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</el-popover>
|
|
87
|
+
|
|
88
|
+
<ReportSectionConfirmPopover :visible="deleteConfirmOpen" :virtual-ref="deleteConfirmVirtualRef"
|
|
89
|
+
:boundary-el="sectionBoundaryEl" :trigger-btn="deleteConfirmTriggerBtn" :message="deleteConfirmMessage"
|
|
90
|
+
:instant="popoverInstant" @confirm="confirmRemoveEditor" @cancel="closeDeleteConfirm" />
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<script setup lang="ts">
|
|
94
|
+
import { Close, Plus, Share } from '@element-plus/icons-vue'
|
|
95
|
+
import { ElIcon, ElMessage, ElOption, ElPopover, ElSelect } from 'element-plus'
|
|
96
|
+
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
97
|
+
import {
|
|
98
|
+
MOCK_UMS_EDITOR_USERS,
|
|
99
|
+
type ReportEditor,
|
|
100
|
+
type ReportEditorRole,
|
|
101
|
+
} from '../useReportWorkflow'
|
|
102
|
+
import { useReportWorkflow } from '../useReportWorkflow'
|
|
103
|
+
import ReportCollapsibleSection from './ReportCollapsibleSection.vue'
|
|
104
|
+
import ReportSectionConfirmPopover from './ReportSectionConfirmPopover.vue'
|
|
105
|
+
|
|
106
|
+
const workflow = useReportWorkflow()
|
|
107
|
+
const { reportEditors, canManageReportEditors } = workflow
|
|
108
|
+
|
|
109
|
+
const editors = reportEditors
|
|
110
|
+
const addOpen = ref(false)
|
|
111
|
+
const shareOpen = ref(false)
|
|
112
|
+
const popoverInstant = ref(false)
|
|
113
|
+
const addSelectedUser = ref('')
|
|
114
|
+
const transferSelectedUser = ref('')
|
|
115
|
+
|
|
116
|
+
const addBtnRef = ref<HTMLElement | null>(null)
|
|
117
|
+
const shareBtnRef = ref<HTMLElement | null>(null)
|
|
118
|
+
const sectionRef = ref<InstanceType<typeof ReportCollapsibleSection> | null>(null)
|
|
119
|
+
|
|
120
|
+
const shareToggleRef = computed(() => sectionRef.value?.toggleRef ?? null)
|
|
121
|
+
|
|
122
|
+
const popoverWidthPx = ref(240)
|
|
123
|
+
const arrowAlignKey = ref(0)
|
|
124
|
+
const popoverWidth = computed(() => popoverWidthPx.value)
|
|
125
|
+
|
|
126
|
+
const addEditorOptions = computed(() => {
|
|
127
|
+
const existingIds = new Set(editors.value.map((editor) => editor.employeeId))
|
|
128
|
+
return MOCK_UMS_EDITOR_USERS.filter((user) => !existingIds.has(user.employeeId))
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
const transferUserOptions = computed(() => {
|
|
132
|
+
const currentInitiator = editors.value.find((editor) => editor.role === 'initiator')
|
|
133
|
+
const candidates = new Map<string, (typeof MOCK_UMS_EDITOR_USERS)[number]>()
|
|
134
|
+
|
|
135
|
+
for (const user of MOCK_UMS_EDITOR_USERS) {
|
|
136
|
+
if (user.id !== currentInitiator?.id) {
|
|
137
|
+
candidates.set(user.id, user)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const editor of editors.value) {
|
|
141
|
+
if (editor.id !== currentInitiator?.id) {
|
|
142
|
+
candidates.set(editor.id, {
|
|
143
|
+
id: editor.id,
|
|
144
|
+
name: editor.name,
|
|
145
|
+
employeeId: editor.employeeId,
|
|
146
|
+
department: editor.department,
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return Array.from(candidates.values())
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const panelOpen = ref(true)
|
|
155
|
+
|
|
156
|
+
const deleteConfirmOpen = ref(false)
|
|
157
|
+
const deleteConfirmMessage = ref('')
|
|
158
|
+
const deleteConfirmVirtualRef = ref<HTMLElement | null>(null)
|
|
159
|
+
const deleteConfirmTriggerBtn = ref<HTMLElement | null>(null)
|
|
160
|
+
const deleteTargetId = ref<string | null>(null)
|
|
161
|
+
|
|
162
|
+
const sectionBoundaryEl = computed(() => sectionRef.value?.rootRef ?? null)
|
|
163
|
+
|
|
164
|
+
function editorRoleLabel(role: ReportEditorRole) {
|
|
165
|
+
return role === 'initiator' ? '發起人' : '編輯者'
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function requestRemoveEditor(editor: ReportEditor, event: MouseEvent) {
|
|
169
|
+
if (!canManageReportEditors.value) return
|
|
170
|
+
const btn = event.currentTarget as HTMLElement
|
|
171
|
+
deleteConfirmVirtualRef.value = btn.closest('.report-editor-list__row') as HTMLElement ?? btn
|
|
172
|
+
deleteConfirmTriggerBtn.value = btn
|
|
173
|
+
deleteTargetId.value = editor.id
|
|
174
|
+
deleteConfirmMessage.value = `確定刪除「${editor.name}(${editor.employeeId})」?`
|
|
175
|
+
deleteConfirmOpen.value = true
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function confirmRemoveEditor() {
|
|
179
|
+
if (deleteTargetId.value) {
|
|
180
|
+
editors.value = editors.value.filter((item) => item.id !== deleteTargetId.value)
|
|
181
|
+
}
|
|
182
|
+
closeDeleteConfirm()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function closeDeleteConfirm() {
|
|
186
|
+
deleteConfirmOpen.value = false
|
|
187
|
+
deleteTargetId.value = null
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function hasOpenOverlays() {
|
|
191
|
+
return addOpen.value || shareOpen.value || deleteConfirmOpen.value
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function closeAllOverlays() {
|
|
195
|
+
addOpen.value = false
|
|
196
|
+
shareOpen.value = false
|
|
197
|
+
deleteConfirmOpen.value = false
|
|
198
|
+
deleteTargetId.value = null
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function handleBeforeCollapse(done: (hadOpenOverlays: boolean) => void) {
|
|
202
|
+
const hadOpen = hasOpenOverlays()
|
|
203
|
+
if (hadOpen) {
|
|
204
|
+
popoverInstant.value = true
|
|
205
|
+
closeAllOverlays()
|
|
206
|
+
window.setTimeout(() => {
|
|
207
|
+
popoverInstant.value = false
|
|
208
|
+
}, 320)
|
|
209
|
+
}
|
|
210
|
+
done(hadOpen)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function getSectionContentWidth() {
|
|
214
|
+
const sectionEl = sectionRef.value?.rootRef
|
|
215
|
+
if (!sectionEl) return 240
|
|
216
|
+
const styles = getComputedStyle(sectionEl)
|
|
217
|
+
const paddingX = parseFloat(styles.paddingLeft) + parseFloat(styles.paddingRight)
|
|
218
|
+
return Math.round(sectionEl.clientWidth - paddingX)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function getArrowPopperStyle(triggerBtn: HTMLElement | null): Record<string, string> {
|
|
222
|
+
void arrowAlignKey.value
|
|
223
|
+
void panelOpen.value
|
|
224
|
+
const sectionEl = sectionRef.value?.rootRef
|
|
225
|
+
if (!triggerBtn || !sectionEl) return {}
|
|
226
|
+
const sectionRect = sectionEl.getBoundingClientRect()
|
|
227
|
+
const paddingLeft = parseFloat(getComputedStyle(sectionEl).paddingLeft)
|
|
228
|
+
const btnRect = triggerBtn.getBoundingClientRect()
|
|
229
|
+
const left = btnRect.left + btnRect.width / 2 - sectionRect.left - paddingLeft - 8
|
|
230
|
+
return { '--report-config-arrow-left': `${left}px` }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const addPopperStyle = computed(() => getArrowPopperStyle(addBtnRef.value))
|
|
234
|
+
|
|
235
|
+
const sharePopperStyle = computed(() => getArrowPopperStyle(shareBtnRef.value))
|
|
236
|
+
|
|
237
|
+
const popperOptions = computed(() => {
|
|
238
|
+
const boundary = sectionRef.value?.rootRef
|
|
239
|
+
return {
|
|
240
|
+
modifiers: [
|
|
241
|
+
{
|
|
242
|
+
name: 'preventOverflow',
|
|
243
|
+
options: {
|
|
244
|
+
boundary: boundary ?? 'viewport',
|
|
245
|
+
padding: 0,
|
|
246
|
+
altAxis: true,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: 'flip',
|
|
251
|
+
enabled: false,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
function syncPopoverWidth() {
|
|
258
|
+
popoverWidthPx.value = getSectionContentWidth()
|
|
259
|
+
arrowAlignKey.value += 1
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function toggleAddOpen() {
|
|
263
|
+
if (!canManageReportEditors.value) return
|
|
264
|
+
syncPopoverWidth()
|
|
265
|
+
shareOpen.value = false
|
|
266
|
+
addOpen.value = !addOpen.value
|
|
267
|
+
if (addOpen.value) {
|
|
268
|
+
void nextTick(() => {
|
|
269
|
+
arrowAlignKey.value += 1
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function toggleShareOpen() {
|
|
275
|
+
if (!canManageReportEditors.value) return
|
|
276
|
+
syncPopoverWidth()
|
|
277
|
+
addOpen.value = false
|
|
278
|
+
shareOpen.value = !shareOpen.value
|
|
279
|
+
if (shareOpen.value) {
|
|
280
|
+
void nextTick(() => {
|
|
281
|
+
arrowAlignKey.value += 1
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function confirmAdd() {
|
|
287
|
+
if (!canManageReportEditors.value) {
|
|
288
|
+
addOpen.value = false
|
|
289
|
+
return
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const candidate = MOCK_UMS_EDITOR_USERS.find((user) => user.id === addSelectedUser.value)
|
|
293
|
+
if (!candidate) {
|
|
294
|
+
addOpen.value = false
|
|
295
|
+
return
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const alreadyExists = editors.value.some((editor) => editor.employeeId === candidate.employeeId)
|
|
299
|
+
if (alreadyExists) {
|
|
300
|
+
ElMessage.warning('該用戶已是報告編輯者')
|
|
301
|
+
addOpen.value = false
|
|
302
|
+
addSelectedUser.value = ''
|
|
303
|
+
return
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
editors.value.push({
|
|
307
|
+
id: candidate.id,
|
|
308
|
+
name: candidate.name,
|
|
309
|
+
employeeId: candidate.employeeId,
|
|
310
|
+
department: candidate.department,
|
|
311
|
+
role: 'editor',
|
|
312
|
+
})
|
|
313
|
+
addSelectedUser.value = ''
|
|
314
|
+
addOpen.value = false
|
|
315
|
+
ElMessage.success('已添加編輯者')
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function confirmTransfer() {
|
|
319
|
+
if (!canManageReportEditors.value) {
|
|
320
|
+
shareOpen.value = false
|
|
321
|
+
return
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const targetId = transferSelectedUser.value
|
|
325
|
+
if (!targetId) {
|
|
326
|
+
shareOpen.value = false
|
|
327
|
+
return
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const currentInitiator = editors.value.find((editor) => editor.role === 'initiator')
|
|
331
|
+
let target = editors.value.find((editor) => editor.id === targetId)
|
|
332
|
+
|
|
333
|
+
if (!target) {
|
|
334
|
+
const umsUser = MOCK_UMS_EDITOR_USERS.find((user) => user.id === targetId)
|
|
335
|
+
if (!umsUser) {
|
|
336
|
+
shareOpen.value = false
|
|
337
|
+
return
|
|
338
|
+
}
|
|
339
|
+
target = {
|
|
340
|
+
id: umsUser.id,
|
|
341
|
+
name: umsUser.name,
|
|
342
|
+
employeeId: umsUser.employeeId,
|
|
343
|
+
department: umsUser.department,
|
|
344
|
+
role: 'editor',
|
|
345
|
+
}
|
|
346
|
+
editors.value.push(target)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (currentInitiator) {
|
|
350
|
+
currentInitiator.role = 'editor'
|
|
351
|
+
}
|
|
352
|
+
target.role = 'initiator'
|
|
353
|
+
|
|
354
|
+
transferSelectedUser.value = ''
|
|
355
|
+
shareOpen.value = false
|
|
356
|
+
ElMessage.success('已轉移報告發起人權限')
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
watch(panelOpen, (open) => {
|
|
360
|
+
if (!open) closeAllOverlays()
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
let sectionResizeObserver: ResizeObserver | null = null
|
|
364
|
+
|
|
365
|
+
onMounted(() => {
|
|
366
|
+
void nextTick(() => {
|
|
367
|
+
syncPopoverWidth()
|
|
368
|
+
const sectionEl = sectionRef.value?.rootRef
|
|
369
|
+
if (sectionEl) {
|
|
370
|
+
sectionResizeObserver = new ResizeObserver(() => syncPopoverWidth())
|
|
371
|
+
sectionResizeObserver.observe(sectionEl)
|
|
372
|
+
}
|
|
373
|
+
})
|
|
374
|
+
window.addEventListener('resize', syncPopoverWidth)
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
onUnmounted(() => {
|
|
378
|
+
window.removeEventListener('resize', syncPopoverWidth)
|
|
379
|
+
sectionResizeObserver?.disconnect()
|
|
380
|
+
})
|
|
381
|
+
</script>
|
|
382
|
+
|
|
383
|
+
<style scoped>
|
|
384
|
+
.report-editor-panel {
|
|
385
|
+
box-sizing: border-box;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.report-editor-list {
|
|
389
|
+
margin: 0;
|
|
390
|
+
padding: 0;
|
|
391
|
+
list-style: none;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.report-editor-list__row {
|
|
395
|
+
display: grid;
|
|
396
|
+
grid-template-columns: minmax(0, 1fr) auto auto 24px;
|
|
397
|
+
align-items: center;
|
|
398
|
+
gap: 10px;
|
|
399
|
+
height: 36px;
|
|
400
|
+
padding: 0 10px;
|
|
401
|
+
border-radius: 4px;
|
|
402
|
+
font-size: 12px;
|
|
403
|
+
line-height: 1.5;
|
|
404
|
+
color: #303133;
|
|
405
|
+
background: #fff;
|
|
406
|
+
box-sizing: border-box;
|
|
407
|
+
transition: background-color 0.2s ease;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.report-editor-list__row:hover {
|
|
411
|
+
background-color: #f5f7fa;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.report-editor-list__name {
|
|
415
|
+
overflow: hidden;
|
|
416
|
+
text-overflow: ellipsis;
|
|
417
|
+
white-space: nowrap;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.report-editor-list__dept,
|
|
421
|
+
.report-editor-list__role {
|
|
422
|
+
white-space: nowrap;
|
|
423
|
+
color: #303133;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.report-editor-list__action {
|
|
427
|
+
display: flex;
|
|
428
|
+
justify-content: flex-end;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.report-source-transfer__title {
|
|
432
|
+
margin: 0 0 12px;
|
|
433
|
+
font-size: 14px;
|
|
434
|
+
font-weight: 700;
|
|
435
|
+
color: #303133;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.report-source-transfer__field {
|
|
439
|
+
display: grid;
|
|
440
|
+
gap: 6px;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.report-source-transfer__label {
|
|
444
|
+
font-size: 13px;
|
|
445
|
+
color: #909399;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.report-source-transfer__select {
|
|
449
|
+
width: 100%;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.report-source-transfer__select :deep(.el-select__wrapper) {
|
|
453
|
+
min-height: 32px;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.report-source-transfer__actions {
|
|
457
|
+
display: flex;
|
|
458
|
+
justify-content: flex-end;
|
|
459
|
+
gap: 8px;
|
|
460
|
+
margin-top: 12px;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.report-source-transfer__btn {
|
|
464
|
+
min-width: 72px;
|
|
465
|
+
padding: 6px 10px;
|
|
466
|
+
border: 1px solid #dcdfe6;
|
|
467
|
+
border-radius: 4px;
|
|
468
|
+
background: #fff;
|
|
469
|
+
font-size: 12px;
|
|
470
|
+
color: #606266;
|
|
471
|
+
cursor: pointer;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.report-source-transfer__btn--primary {
|
|
475
|
+
border-color: #c53355;
|
|
476
|
+
background: #c53355;
|
|
477
|
+
color: #fff;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.report-source-transfer__btn--primary:hover {
|
|
481
|
+
background: #fff;
|
|
482
|
+
color: #c53355;
|
|
483
|
+
}
|
|
484
|
+
</style>
|
|
485
|
+
|
|
486
|
+
<style>
|
|
487
|
+
.report-icon-btn {
|
|
488
|
+
display: inline-flex;
|
|
489
|
+
align-items: center;
|
|
490
|
+
justify-content: center;
|
|
491
|
+
width: 24px;
|
|
492
|
+
height: 24px;
|
|
493
|
+
padding: 0;
|
|
494
|
+
border: 0;
|
|
495
|
+
background: none;
|
|
496
|
+
color: #4e5969;
|
|
497
|
+
cursor: pointer;
|
|
498
|
+
border-radius: 4px;
|
|
499
|
+
vertical-align: middle;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.report-icon-btn:hover {
|
|
503
|
+
color: #c53355;
|
|
504
|
+
background: #fff5f6;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.report-config-popover.el-popover.el-popper {
|
|
508
|
+
max-width: 100%;
|
|
509
|
+
padding: 12px;
|
|
510
|
+
box-sizing: border-box;
|
|
511
|
+
overflow: hidden;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.report-config-popover.el-popper[data-popper-placement^='bottom'] .el-popper__arrow {
|
|
515
|
+
left: var(--report-config-arrow-left) !important;
|
|
516
|
+
right: auto !important;
|
|
517
|
+
top: -6px !important;
|
|
518
|
+
transform: translateX(-50%) !important;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.report-config-popover.el-popper[data-popper-placement^='bottom'] .el-popper__arrow::before {
|
|
522
|
+
bottom: -1px;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.report-config-popover-fade-enter-active,
|
|
526
|
+
.report-config-popover-fade-leave-active {
|
|
527
|
+
transition: opacity 0.12s ease;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.report-config-popover-fade-enter-from,
|
|
531
|
+
.report-config-popover-fade-leave-to {
|
|
532
|
+
opacity: 0;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
.report-config-popover-instant-enter-active,
|
|
536
|
+
.report-config-popover-instant-leave-active {
|
|
537
|
+
transition: none !important;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.report-config-popover-instant-enter-from,
|
|
541
|
+
.report-config-popover-instant-leave-to {
|
|
542
|
+
opacity: 0;
|
|
543
|
+
}
|
|
544
|
+
</style>
|