@veltra/sheet 2.4.0 → 2.5.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 (142) hide show
  1. package/dist/index.d.ts +2 -19
  2. package/dist/index.js +2 -15
  3. package/dist/types/index.d.ts +1 -3
  4. package/package.json +2 -3
  5. package/src/index.ts +1 -27
  6. package/src/types/index.ts +0 -2
  7. package/dist/components/report/binding-badge.js +0 -118
  8. package/dist/components/report/designer/cell-coords.js +0 -46
  9. package/dist/components/report/designer/col-widths.js +0 -29
  10. package/dist/components/report/designer/conditional-rules/helpers.js +0 -139
  11. package/dist/components/report/designer/drill-dialog.js +0 -258
  12. package/dist/components/report/designer/drop-highlight-overlay.js +0 -76
  13. package/dist/components/report/designer/float-panel.js +0 -434
  14. package/dist/components/report/designer/role.js +0 -17
  15. package/dist/components/report/designer/rule-preview.js +0 -33
  16. package/dist/components/report/designer/rule-row.js +0 -253
  17. package/dist/components/report/designer/rules-dialog.js +0 -118
  18. package/dist/components/report/designer/topology-overlay.js +0 -122
  19. package/dist/components/report/designer/topology.js +0 -64
  20. package/dist/components/report/designer/use-grid-overlay.js +0 -75
  21. package/dist/components/report/designer-hub.js +0 -177
  22. package/dist/components/report/field-panel-helpers.js +0 -33
  23. package/dist/components/report/field-panel.js +0 -132
  24. package/dist/components/report/filter-bar.js +0 -74
  25. package/dist/components/report/hub-connection-form.js +0 -145
  26. package/dist/components/report/hub-dataset-editor.js +0 -409
  27. package/dist/components/report/preview-grid-size.js +0 -32
  28. package/dist/components/report/print.js +0 -39
  29. package/dist/components/report/report-designer.js +0 -428
  30. package/dist/components/report/report-viewer.js +0 -253
  31. package/dist/components/report/style.d.ts +0 -17
  32. package/dist/components/report/style.js +0 -18
  33. package/dist/components/report/style2.css +0 -965
  34. package/dist/components/report/use-report-designer.js +0 -387
  35. package/dist/components/report/use-report-viewer.js +0 -140
  36. package/dist/report/binding.d.ts +0 -83
  37. package/dist/report/binding.js +0 -334
  38. package/dist/report/connector.d.ts +0 -66
  39. package/dist/report/connector.js +0 -159
  40. package/dist/report/drill.d.ts +0 -48
  41. package/dist/report/drill.js +0 -78
  42. package/dist/report/export-xlsx.d.ts +0 -13
  43. package/dist/report/export-xlsx.js +0 -13
  44. package/dist/report/filter-bar.d.ts +0 -10
  45. package/dist/report/filter-bar.js +0 -31
  46. package/dist/report/index.d.ts +0 -14
  47. package/dist/report/params.d.ts +0 -13
  48. package/dist/report/params.js +0 -61
  49. package/dist/report/print.d.ts +0 -23
  50. package/dist/report/print.js +0 -197
  51. package/dist/report/render/aggregate.js +0 -193
  52. package/dist/report/render/builder.d.ts +0 -12
  53. package/dist/report/render/builder.js +0 -139
  54. package/dist/report/render/coordinate.d.ts +0 -25
  55. package/dist/report/render/coordinate.js +0 -733
  56. package/dist/report/render/index.d.ts +0 -14
  57. package/dist/report/render/index.js +0 -21
  58. package/dist/report/render/style-resolver.js +0 -50
  59. package/dist/report/render/template-index.d.ts +0 -24
  60. package/dist/report/render/template-index.js +0 -137
  61. package/dist/report/rules/evaluate.d.ts +0 -25
  62. package/dist/report/rules/evaluate.js +0 -82
  63. package/dist/report/rules/index.d.ts +0 -2
  64. package/dist/report/template.d.ts +0 -63
  65. package/dist/report/template.js +0 -83
  66. package/dist/report/types.d.ts +0 -103
  67. package/dist/types/report-designer.d.ts +0 -51
  68. package/dist/types/report-viewer.d.ts +0 -57
  69. package/src/components/report/__test__/binding-badge.test.ts +0 -92
  70. package/src/components/report/__test__/conditional-rules-helpers.test.ts +0 -88
  71. package/src/components/report/__test__/field-panel-helpers.test.ts +0 -65
  72. package/src/components/report/__test__/float-panel-position.test.ts +0 -45
  73. package/src/components/report/__test__/preview-grid-size.test.ts +0 -63
  74. package/src/components/report/__test__/report-designer.test.ts +0 -559
  75. package/src/components/report/__test__/report-drill.test.ts +0 -692
  76. package/src/components/report/__test__/report-viewer.test.ts +0 -400
  77. package/src/components/report/__test__/topology.test.ts +0 -143
  78. package/src/components/report/__test__/use-report-designer.test.ts +0 -804
  79. package/src/components/report/binding-badge.ts +0 -122
  80. package/src/components/report/designer/cell-coords.ts +0 -95
  81. package/src/components/report/designer/col-widths.ts +0 -56
  82. package/src/components/report/designer/conditional-rules/helpers.ts +0 -189
  83. package/src/components/report/designer/drill-dialog.vue +0 -245
  84. package/src/components/report/designer/drop-highlight-overlay.vue +0 -75
  85. package/src/components/report/designer/float-panel.vue +0 -444
  86. package/src/components/report/designer/role.ts +0 -32
  87. package/src/components/report/designer/rule-preview.vue +0 -40
  88. package/src/components/report/designer/rule-row.vue +0 -252
  89. package/src/components/report/designer/rules-dialog.vue +0 -110
  90. package/src/components/report/designer/topology-overlay.vue +0 -128
  91. package/src/components/report/designer/topology.ts +0 -124
  92. package/src/components/report/designer/use-grid-overlay.ts +0 -114
  93. package/src/components/report/designer-hub.vue +0 -198
  94. package/src/components/report/field-panel-helpers.ts +0 -44
  95. package/src/components/report/field-panel.vue +0 -136
  96. package/src/components/report/filter-bar.vue +0 -77
  97. package/src/components/report/hub-connection-form.vue +0 -124
  98. package/src/components/report/hub-dataset-editor.vue +0 -387
  99. package/src/components/report/index.ts +0 -2
  100. package/src/components/report/preview-grid-size.ts +0 -33
  101. package/src/components/report/print.ts +0 -44
  102. package/src/components/report/report-designer.vue +0 -454
  103. package/src/components/report/report-viewer.vue +0 -289
  104. package/src/components/report/style-designer.scss +0 -653
  105. package/src/components/report/style-hub.scss +0 -292
  106. package/src/components/report/style-viewer.scss +0 -144
  107. package/src/components/report/style.scss +0 -3
  108. package/src/components/report/style.ts +0 -20
  109. package/src/components/report/use-report-designer.ts +0 -603
  110. package/src/components/report/use-report-viewer.ts +0 -227
  111. package/src/report/__test__/binding.test.ts +0 -320
  112. package/src/report/__test__/connector.test.ts +0 -239
  113. package/src/report/__test__/drill.test.ts +0 -194
  114. package/src/report/__test__/export-xlsx.test.ts +0 -96
  115. package/src/report/__test__/filter-bar.test.ts +0 -58
  116. package/src/report/__test__/params.test.ts +0 -156
  117. package/src/report/__test__/print.test.ts +0 -170
  118. package/src/report/__test__/render.test.ts +0 -856
  119. package/src/report/__test__/rules.test.ts +0 -131
  120. package/src/report/__test__/template.test.ts +0 -366
  121. package/src/report/binding.ts +0 -474
  122. package/src/report/connector.ts +0 -206
  123. package/src/report/drill.ts +0 -112
  124. package/src/report/export-xlsx.ts +0 -15
  125. package/src/report/filter-bar.ts +0 -36
  126. package/src/report/index.ts +0 -16
  127. package/src/report/params.ts +0 -96
  128. package/src/report/print.ts +0 -234
  129. package/src/report/render/__test__/aggregate.test.ts +0 -16
  130. package/src/report/render/__test__/coordinate.test.ts +0 -405
  131. package/src/report/render/aggregate.ts +0 -289
  132. package/src/report/render/builder.ts +0 -211
  133. package/src/report/render/coordinate.ts +0 -1239
  134. package/src/report/render/index.ts +0 -30
  135. package/src/report/render/style-resolver.ts +0 -68
  136. package/src/report/render/template-index.ts +0 -200
  137. package/src/report/rules/evaluate.ts +0 -113
  138. package/src/report/rules/index.ts +0 -7
  139. package/src/report/template.ts +0 -145
  140. package/src/report/types.ts +0 -116
  141. package/src/types/report-designer.ts +0 -55
  142. package/src/types/report-viewer.ts +0 -54
@@ -1,289 +0,0 @@
1
- <template>
2
- <div :class="cls.b">
3
- <u-report-filter-bar
4
- v-if="params.length"
5
- :query-params="params"
6
- :values="values"
7
- @update:values="setValues"
8
- />
9
-
10
- <div v-if="canDrillBack" :class="cls.e('drill-bar')">
11
- <u-button size="small" plain @click="drillBack">返回上一层</u-button>
12
- </div>
13
-
14
- <div :class="cls.e('body')">
15
- <div v-if="loading" :class="cls.e('loading')" aria-live="polite">
16
- <div :class="cls.e('loading-spinner')" />
17
- <span>正在加载报表数据…</span>
18
- </div>
19
- <div v-else-if="error" :class="cls.e('error')" role="alert">
20
- {{ error.message }}
21
- </div>
22
-
23
- <u-sheet
24
- ref="sheetRef"
25
- :class="[cls.e('sheet'), drillHover ? cls.em('sheet', 'drill-hover') : '']"
26
- :workbook="workbook"
27
- :rows="renderSize.rows"
28
- :cols="renderSize.cols"
29
- :show-toolbar="false"
30
- :show-formula-bar="false"
31
- :show-tabs="false"
32
- :show-row-header="false"
33
- :show-col-header="false"
34
- :resolve-cell-style="resolveViewerCellStyle"
35
- readonly
36
- @pointerdown="handleGridPointerDown"
37
- @pointermove="handleGridPointerMove"
38
- @pointerleave="handleGridPointerLeave"
39
- @click="handleGridClick"
40
- />
41
- </div>
42
-
43
- <u-dialog
44
- v-if="drillDialog"
45
- v-model="drillDialogVisible"
46
- title="详情报表"
47
- :class="cls.e('drill-dialog')"
48
- >
49
- <u-report-viewer
50
- :connector="connector"
51
- :template="drillDialog.template"
52
- :initial-values="drillDialog.params"
53
- :resolve-template="resolveTemplate"
54
- />
55
- </u-dialog>
56
- </div>
57
- </template>
58
-
59
- <script lang="ts" setup>
60
- import { saveBlob } from '@cat-kit/fe'
61
- import { UButton, UDialog } from '@veltra/desktop'
62
- import type { CellAddress, SheetSnapshot } from '@veltra/sheet-core'
63
- import { Workbook } from '@veltra/sheet-core'
64
- import type { ResolveCellStyleHook } from '@veltra/sheet-core/grid'
65
- import { bem } from '@veltra/utils'
66
- import { computed, nextTick, ref, shallowRef, useTemplateRef, watch } from 'vue'
67
-
68
- import { exportFilledReportXlsx } from '../../report/export-xlsx'
69
- import { buildFilledReportPrintHtml, type ReportPrintOptions } from '../../report/print'
70
- import type { ReportTemplate } from '../../report/template'
71
- import type { ParamValues, ReportDrillConfig } from '../../report/types'
72
- import type { ReportViewerProps, SheetExposed, _ReportViewerExposed } from '../../types'
73
- import { USheet } from '../sheet'
74
- import { applyGridColWidths, applySheetColWidths } from './designer/col-widths'
75
- import UReportFilterBar from './filter-bar.vue'
76
- import { previewGridSize, type PreviewGridSizeMode } from './preview-grid-size'
77
- import { printHtmlDocument } from './print'
78
- import { useReportViewer } from './use-report-viewer'
79
-
80
- defineOptions({ name: 'UReportViewer' })
81
-
82
- /** 与 `ReportViewerProps` 交叉显式列出下钻 props,避免 SFC 对跨文件 interface 漏抽 runtime 声明 */
83
- type ViewerRuntimeProps = ReportViewerProps & {
84
- resolveTemplate?: ReportViewerProps['resolveTemplate']
85
- initialValues?: ReportViewerProps['initialValues']
86
- }
87
-
88
- const props = defineProps<ViewerRuntimeProps>()
89
-
90
- const cls = bem('report-viewer')
91
-
92
- /** 取数未完成时拒绝导出的可读错误 */
93
- const EXPORT_NOT_READY_MESSAGE = '报表数据尚未就绪,请等待取数完成后再导出'
94
- const EXPORT_LOADING_MESSAGE = '报表数据加载中,请稍后再导出'
95
-
96
- /** 取数未完成时拒绝打印的可读错误 */
97
- const PRINT_NOT_READY_MESSAGE = '报表数据尚未就绪,请等待取数完成后再打印'
98
- const PRINT_LOADING_MESSAGE = '报表数据加载中,请稍后再打印'
99
-
100
- /**
101
- * 单击 / 拖拽框选判定位移阈值(px):pointerdown 与 click 位移超过它视为拖选,不触发下钻。
102
- * (VTable 拖选后 DOM click 仍会冒泡,按位移自行抑制。)
103
- */
104
- const DRAG_CLICK_THRESHOLD_PX = 4
105
-
106
- /** 查看器工作簿:宿主可注入(同 USheet `workbook?` 先例),缺省内部自建;模板 / 填充结果都 restore 进活动 sheet 只读展示 */
107
- const internalWorkbook = new Workbook()
108
- const workbook = computed(() => props.workbook ?? internalWorkbook)
109
-
110
- const sheetRef = useTemplateRef<SheetExposed>('sheetRef')
111
-
112
- const {
113
- params,
114
- values,
115
- loading,
116
- error,
117
- filledSnapshot,
118
- filledColWidths,
119
- currentTemplate,
120
- canDrillBack,
121
- resolveDrillHit,
122
- resolveDrillTarget,
123
- drillInto,
124
- drillBack,
125
- refresh,
126
- setValues
127
- } = useReportViewer(props)
128
-
129
- /** 配了下钻的单元格在查看态展示可点击链接样式(蓝字 + 下划线),便于用户直观感知 */
130
- const resolveViewerCellStyle: ResolveCellStyleHook = (addr, base) => {
131
- if (!props.resolveTemplate) return base
132
- const hit = resolveDrillHit(addr)
133
- if (!hit) return base
134
- return {
135
- ...base,
136
- font: {
137
- ...base?.font,
138
- color: base?.font?.color ?? '#2f54eb',
139
- underline: base?.font?.underline ?? true
140
- }
141
- }
142
- }
143
-
144
- /** 弹框下钻:先挂 UDialog 再打开,避免 modelValue 初始为 true 时 overlay 不进入 */
145
- const drillDialogVisible = ref(false)
146
- const drillDialog = shallowRef<{ template: ReportTemplate; params: ParamValues } | null>(null)
147
-
148
- const renderSize = computed(() => {
149
- const filled = filledSnapshot.value
150
- if (filled) return previewGridSize(filled, 'filled')
151
- return previewGridSize(currentTemplate.value, 'template')
152
- })
153
-
154
- /** 宿主显式传入优先;否则取数完成后用展开映射列宽;再回落当前层模板设计态列宽 */
155
- const effectiveColWidths = computed(() => {
156
- if (props.colWidths?.length) return props.colWidths
157
- if (filledColWidths.value?.length) return filledColWidths.value
158
- return currentTemplate.value.colWidths
159
- })
160
-
161
- /** 将运行时列宽写入模型与 VTable(模型为单一事实源;grid 构造/content-reset 也会回放) */
162
- function applyRuntimeColWidths(): void {
163
- if (!effectiveColWidths.value?.length) return
164
- const sheet = workbook.value.activeSheet
165
- applySheetColWidths(sheet, effectiveColWidths.value)
166
- applyGridColWidths(sheetRef.value?.getGrid(), effectiveColWidths.value)
167
- }
168
-
169
- /**
170
- * restore 负责尺寸/冻结/行高/列宽/选区(静默),restoreContent 发 content-reset
171
- * 触发网格全量刷新(grid 层订阅直刷,无需手动 flush);history.clear 使填充不进 undo
172
- */
173
- function applySnapshot(snapshot: SheetSnapshot, mode: PreviewGridSizeMode): void {
174
- const size = previewGridSize(snapshot, mode)
175
- const trimmed: SheetSnapshot = { ...snapshot, rows: size.rows, cols: size.cols }
176
- const sheet = workbook.value.activeSheet
177
- sheet.restore(trimmed)
178
- sheet.restoreContent(trimmed)
179
- sheet.history.clear()
180
- void nextTick(applyRuntimeColWidths)
181
- }
182
-
183
- // 先铺当前层模板静态结构(取数期间 / 取数失败时可见),取数成功后替换为 Filled Report
184
- watch(currentTemplate, (template) => applySnapshot(template, 'template'), { immediate: true })
185
- watch(filledSnapshot, (filled) => {
186
- if (filled) applySnapshot(filled, 'filled')
187
- })
188
- watch(effectiveColWidths, applyRuntimeColWidths)
189
-
190
- // ─── 下钻点击与可点视觉提示 ─────────────────────────────────
191
-
192
- /** 悬停命中下钻格时给网格加 cursor 提示 */
193
- const drillHover = ref(false)
194
- let pointerStart: { x: number; y: number } | null = null
195
-
196
- watch(drillDialogVisible, (visible) => {
197
- if (!visible) drillDialog.value = null
198
- })
199
-
200
- async function openDrillDialog(
201
- config: ReportDrillConfig,
202
- record: Record<string, unknown>
203
- ): Promise<void> {
204
- const next = await resolveDrillTarget(config, record)
205
- if (!next) return
206
- drillDialog.value = next
207
- await nextTick()
208
- drillDialogVisible.value = true
209
- }
210
-
211
- /** 事件坐标 → 模型地址(经当前 SheetGrid 命中测试;网格随内容尺寸重建,实例按事件时刻取) */
212
- function resolveEventAddr(event: MouseEvent): CellAddress | null {
213
- const host = event.currentTarget as HTMLElement
214
- const gridEl = host.querySelector('.u-sheet__grid-instance') as HTMLElement | null
215
- const grid = sheetRef.value?.getGrid()
216
- if (!gridEl || !grid) return null
217
- const rect = gridEl.getBoundingClientRect()
218
- return grid.hitTestSheetAddr(event.clientX - rect.left, event.clientY - rect.top)
219
- }
220
-
221
- function handleGridPointerDown(event: PointerEvent): void {
222
- pointerStart = { x: event.clientX, y: event.clientY }
223
- }
224
-
225
- function handleGridClick(event: MouseEvent): void {
226
- if (!props.resolveTemplate) return
227
- const start = pointerStart
228
- pointerStart = null
229
- if (start) {
230
- const dx = event.clientX - start.x
231
- const dy = event.clientY - start.y
232
- if (dx * dx + dy * dy > DRAG_CLICK_THRESHOLD_PX * DRAG_CLICK_THRESHOLD_PX) return
233
- }
234
- const addr = resolveEventAddr(event)
235
- if (!addr) return
236
- const hit = resolveDrillHit(addr)
237
- if (!hit) return
238
- if (hit.config.openMode === 'dialog') {
239
- void openDrillDialog(hit.config, hit.record)
240
- return
241
- }
242
- void drillInto(hit.config, hit.record)
243
- }
244
-
245
- function handleGridPointerMove(event: PointerEvent): void {
246
- const addr = props.resolveTemplate ? resolveEventAddr(event) : null
247
- const hit = addr ? resolveDrillHit(addr) : null
248
- const next = !!hit
249
- if (next !== drillHover.value) drillHover.value = next
250
- }
251
-
252
- function handleGridPointerLeave(): void {
253
- drillHover.value = false
254
- }
255
-
256
- async function exportXlsx(): Promise<void> {
257
- if (loading.value) {
258
- throw new Error(EXPORT_LOADING_MESSAGE)
259
- }
260
- if (!filledSnapshot.value) {
261
- throw new Error(EXPORT_NOT_READY_MESSAGE)
262
- }
263
-
264
- const sheet = workbook.value.activeSheet
265
- const buffer = await exportFilledReportXlsx(sheet)
266
- saveBlob(
267
- new Blob([buffer as unknown as BlobPart], {
268
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
269
- }),
270
- `${sheet.name || '报表'}.xlsx`
271
- )
272
- }
273
-
274
- /**
275
- * 打印填充报表(纯前端):填充 sheet 模型 → 打印专用 HTML(buildFilledReportPrintHtml)
276
- * → 隐藏 iframe 调起浏览器打印。守卫语义与 exportXlsx 一致(取数完成前拒绝)。
277
- */
278
- function print(options?: ReportPrintOptions): void {
279
- if (loading.value) {
280
- throw new Error(PRINT_LOADING_MESSAGE)
281
- }
282
- if (!filledSnapshot.value) {
283
- throw new Error(PRINT_NOT_READY_MESSAGE)
284
- }
285
- printHtmlDocument(buildFilledReportPrintHtml(workbook.value.activeSheet, options))
286
- }
287
-
288
- defineExpose<_ReportViewerExposed>({ refresh, exportXlsx, print })
289
- </script>