@veltra/sheet 2.1.1 → 2.3.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 (212) hide show
  1. package/dist/components/report/binding-badge.js +100 -0
  2. package/dist/components/report/designer/cell-coords.js +46 -0
  3. package/dist/components/report/designer/col-widths.js +29 -0
  4. package/dist/components/report/designer/conditional-rules/helpers.js +139 -0
  5. package/dist/components/report/designer/drop-highlight-overlay.js +76 -0
  6. package/dist/components/report/designer/float-panel.js +422 -0
  7. package/dist/components/report/designer/role.js +17 -0
  8. package/dist/components/report/designer/rule-preview.js +33 -0
  9. package/dist/components/report/designer/rule-row.js +253 -0
  10. package/dist/components/report/designer/rules-dialog.js +118 -0
  11. package/dist/components/report/designer/topology-overlay.js +122 -0
  12. package/dist/components/report/designer/topology.js +64 -0
  13. package/dist/components/report/designer/use-grid-overlay.js +75 -0
  14. package/dist/components/report/designer-hub.js +177 -0
  15. package/dist/components/report/field-panel-helpers.js +33 -0
  16. package/dist/components/report/field-panel.js +132 -0
  17. package/dist/components/report/filter-bar.js +74 -0
  18. package/dist/components/report/hub-connection-form.js +145 -0
  19. package/dist/components/report/hub-dataset-editor.js +394 -0
  20. package/dist/components/report/preview-grid-size.js +32 -0
  21. package/dist/components/report/report-designer.js +393 -0
  22. package/dist/components/report/report-viewer.js +124 -0
  23. package/dist/components/report/style.d.ts +17 -0
  24. package/dist/components/report/style.js +18 -0
  25. package/dist/components/report/style2.css +874 -0
  26. package/dist/components/report/use-report-designer.js +382 -0
  27. package/dist/components/report/use-report-viewer.js +55 -0
  28. package/dist/{vue → components/sheet}/formula-bar.js +1 -1
  29. package/dist/{vue → components/sheet}/formula-suggest-list.js +1 -1
  30. package/dist/{vue → components/sheet}/import-file.js +1 -1
  31. package/dist/{vue → components/sheet}/insert-count-menu-item.js +1 -1
  32. package/dist/{vue → components/sheet}/insert-image.js +1 -1
  33. package/dist/{vue → components/sheet}/popup-helpers.js +1 -1
  34. package/dist/{vue → components/sheet}/popups/border-popup.js +31 -3
  35. package/dist/{vue → components/sheet}/popups/border-preset-glyph.js +1 -1
  36. package/dist/{vue → components/sheet}/popups/export-popup.js +2 -2
  37. package/dist/{vue → components/sheet}/popups/fill-color-popup.js +3 -3
  38. package/dist/{vue → components/sheet}/popups/find-popup.js +1 -1
  39. package/dist/{vue → components/sheet}/popups/font-color-popup.js +3 -3
  40. package/dist/{vue → components/sheet}/popups/font-size-popup.js +3 -3
  41. package/dist/{vue → components/sheet}/popups/import.worker.d.ts +1 -1
  42. package/dist/{vue → components/sheet}/popups/import.worker.js +1 -1
  43. package/dist/{vue → components/sheet}/popups/insert-image-popup.js +1 -1
  44. package/dist/{vue → components/sheet}/sheet-context-menu.js +7 -4
  45. package/dist/{vue → components/sheet}/sheet-tabs.js +1 -1
  46. package/dist/{vue → components/sheet}/sheet-toolbar.js +1 -1
  47. package/dist/{vue → components/sheet}/sheet.js +16 -1
  48. package/dist/{vue → components/sheet}/use-find-replace.js +1 -1
  49. package/dist/{vue → components/sheet}/use-formula-ref-select.js +1 -1
  50. package/dist/{vue → components/sheet}/use-sheet-grid.js +22 -4
  51. package/dist/{vue → components/sheet}/use-sheet-state.js +6 -5
  52. package/dist/{vue → components/sheet}/use-sheet-tabs-bar.js +1 -1
  53. package/dist/{vue → components/sheet}/use-tool-groups.js +2 -2
  54. package/dist/{vue → components/sheet}/use-tool-popup.js +2 -2
  55. package/dist/{vue → components/sheet}/use-toolbar-scroll.js +1 -1
  56. package/dist/index.d.ts +17 -3
  57. package/dist/index.js +13 -3
  58. package/dist/report/binding.d.ts +83 -0
  59. package/dist/report/binding.js +332 -0
  60. package/dist/report/connector.d.ts +66 -0
  61. package/dist/report/connector.js +159 -0
  62. package/dist/report/export-xlsx.d.ts +17 -0
  63. package/dist/report/export-xlsx.js +92 -0
  64. package/dist/report/filter-bar.d.ts +10 -0
  65. package/dist/report/filter-bar.js +31 -0
  66. package/dist/report/index.d.ts +12 -0
  67. package/dist/report/params.d.ts +13 -0
  68. package/dist/report/params.js +61 -0
  69. package/dist/report/render/aggregate.js +169 -0
  70. package/dist/report/render/builder.d.ts +12 -0
  71. package/dist/report/render/builder.js +139 -0
  72. package/dist/report/render/coordinate.d.ts +25 -0
  73. package/dist/report/render/coordinate.js +733 -0
  74. package/dist/report/render/index.d.ts +14 -0
  75. package/dist/report/render/index.js +21 -0
  76. package/dist/report/render/style-resolver.js +50 -0
  77. package/dist/report/render/template-index.d.ts +24 -0
  78. package/dist/report/render/template-index.js +137 -0
  79. package/dist/report/rules/evaluate.d.ts +25 -0
  80. package/dist/report/rules/evaluate.js +82 -0
  81. package/dist/report/rules/index.d.ts +2 -0
  82. package/dist/report/template.d.ts +63 -0
  83. package/dist/report/template.js +83 -0
  84. package/dist/report/types.d.ts +85 -0
  85. package/dist/tools/apply-style.js +29 -0
  86. package/dist/tools/builtin.js +17 -17
  87. package/dist/tools/context.d.ts +39 -6
  88. package/dist/tools/context.js +38 -1
  89. package/dist/types/index.d.ts +3 -2
  90. package/dist/types/report-designer.d.ts +38 -0
  91. package/dist/types/report-viewer.d.ts +38 -0
  92. package/dist/types/sheet.d.ts +21 -1
  93. package/package.json +6 -8
  94. package/src/components/report/__test__/conditional-rules-helpers.test.ts +88 -0
  95. package/src/components/report/__test__/field-panel-helpers.test.ts +65 -0
  96. package/src/components/report/__test__/float-panel-position.test.ts +45 -0
  97. package/src/components/report/__test__/preview-grid-size.test.ts +63 -0
  98. package/src/components/report/__test__/report-designer.test.ts +464 -0
  99. package/src/components/report/__test__/report-viewer.test.ts +357 -0
  100. package/src/components/report/__test__/topology.test.ts +143 -0
  101. package/src/components/report/__test__/use-report-designer.test.ts +697 -0
  102. package/src/components/report/binding-badge.ts +92 -0
  103. package/src/components/report/designer/cell-coords.ts +94 -0
  104. package/src/components/report/designer/col-widths.ts +56 -0
  105. package/src/components/report/designer/conditional-rules/helpers.ts +189 -0
  106. package/src/components/report/designer/drop-highlight-overlay.vue +74 -0
  107. package/src/components/report/designer/float-panel.vue +431 -0
  108. package/src/components/report/designer/role.ts +32 -0
  109. package/src/components/report/designer/rule-preview.vue +40 -0
  110. package/src/components/report/designer/rule-row.vue +252 -0
  111. package/src/components/report/designer/rules-dialog.vue +110 -0
  112. package/src/components/report/designer/topology-overlay.vue +127 -0
  113. package/src/components/report/designer/topology.ts +124 -0
  114. package/src/components/report/designer/use-grid-overlay.ts +113 -0
  115. package/src/components/report/designer-hub.vue +198 -0
  116. package/src/components/report/field-panel-helpers.ts +44 -0
  117. package/src/components/report/field-panel.vue +136 -0
  118. package/src/components/report/filter-bar.vue +77 -0
  119. package/src/components/report/hub-connection-form.vue +124 -0
  120. package/src/components/report/hub-dataset-editor.vue +369 -0
  121. package/src/components/report/index.ts +2 -0
  122. package/src/components/report/preview-grid-size.ts +33 -0
  123. package/src/components/report/report-designer.vue +420 -0
  124. package/src/components/report/report-viewer.vue +136 -0
  125. package/src/components/report/style-designer.scss +587 -0
  126. package/src/components/report/style-hub.scss +292 -0
  127. package/src/components/report/style-viewer.scss +104 -0
  128. package/src/components/report/style.scss +3 -0
  129. package/src/components/report/style.ts +20 -0
  130. package/src/components/report/use-report-designer.ts +596 -0
  131. package/src/components/report/use-report-viewer.ts +88 -0
  132. package/src/{vue → components/sheet}/__test__/formula-bar.test.ts +37 -18
  133. package/src/{vue → components/sheet}/__test__/insert-image-popup.test.ts +1 -1
  134. package/src/{vue → components/sheet}/__test__/insert-image.test.ts +1 -1
  135. package/src/{vue → components/sheet}/__test__/sheet-component.test.ts +77 -3
  136. package/src/{vue → components/sheet}/__test__/sheet-context-menu.test.ts +4 -3
  137. package/src/{vue → components/sheet}/formula-bar.vue +1 -1
  138. package/src/{vue → components/sheet}/insert-image.ts +1 -1
  139. package/src/{vue → components/sheet}/popup-helpers.ts +1 -1
  140. package/src/{vue → components/sheet}/popups/border-popup.vue +32 -4
  141. package/src/{vue → components/sheet}/popups/export-popup.vue +2 -2
  142. package/src/{vue → components/sheet}/popups/fill-color-popup.vue +3 -3
  143. package/src/{vue → components/sheet}/popups/find-popup.vue +1 -1
  144. package/src/{vue → components/sheet}/popups/font-color-popup.vue +3 -3
  145. package/src/{vue → components/sheet}/popups/font-size-popup.vue +3 -3
  146. package/src/{vue → components/sheet}/popups/insert-image-popup.vue +1 -1
  147. package/src/{vue → components/sheet}/sheet-context-menu.ts +10 -4
  148. package/src/{vue → components/sheet}/sheet-toolbar.vue +2 -2
  149. package/src/{vue → components/sheet}/sheet.vue +6 -3
  150. package/src/{vue → components/sheet}/use-find-replace.ts +1 -1
  151. package/src/{vue → components/sheet}/use-sheet-grid.ts +23 -5
  152. package/src/{vue → components/sheet}/use-sheet-state.ts +11 -6
  153. package/src/{vue → components/sheet}/use-tool-groups.ts +2 -2
  154. package/src/{vue → components/sheet}/use-tool-popup.ts +2 -2
  155. package/src/index.ts +24 -188
  156. package/src/report/__test__/binding.test.ts +320 -0
  157. package/src/report/__test__/connector.test.ts +239 -0
  158. package/src/report/__test__/export-xlsx.test.ts +118 -0
  159. package/src/report/__test__/filter-bar.test.ts +58 -0
  160. package/src/report/__test__/params.test.ts +156 -0
  161. package/src/report/__test__/render.test.ts +830 -0
  162. package/src/report/__test__/rules.test.ts +131 -0
  163. package/src/report/__test__/template.test.ts +366 -0
  164. package/src/report/binding.ts +474 -0
  165. package/src/report/connector.ts +206 -0
  166. package/src/report/export-xlsx.ts +113 -0
  167. package/src/report/filter-bar.ts +36 -0
  168. package/src/report/index.ts +13 -0
  169. package/src/report/params.ts +96 -0
  170. package/src/report/render/__test__/aggregate.test.ts +16 -0
  171. package/src/report/render/__test__/coordinate.test.ts +405 -0
  172. package/src/report/render/aggregate.ts +261 -0
  173. package/src/report/render/builder.ts +211 -0
  174. package/src/report/render/coordinate.ts +1239 -0
  175. package/src/report/render/index.ts +30 -0
  176. package/src/report/render/style-resolver.ts +68 -0
  177. package/src/report/render/template-index.ts +200 -0
  178. package/src/report/rules/evaluate.ts +113 -0
  179. package/src/report/rules/index.ts +7 -0
  180. package/src/report/template.ts +145 -0
  181. package/src/report/types.ts +96 -0
  182. package/src/tools/__test__/apply-style.test.ts +129 -0
  183. package/src/tools/apply-style.ts +41 -0
  184. package/src/tools/builtin.ts +20 -20
  185. package/src/tools/context.ts +67 -4
  186. package/src/tools/index.ts +1 -0
  187. package/src/types/index.ts +2 -6
  188. package/src/types/report-designer.ts +38 -0
  189. package/src/types/report-viewer.ts +37 -0
  190. package/src/types/sheet.ts +26 -1
  191. /package/dist/{vue → components/sheet}/style.d.ts +0 -0
  192. /package/dist/{vue → components/sheet}/style.js +0 -0
  193. /package/dist/{vue → components/sheet}/style2.css +0 -0
  194. /package/dist/{vue → components/sheet}/use-formula-suggest.js +0 -0
  195. /package/src/{vue → components/sheet}/__test__/import-file.test.ts +0 -0
  196. /package/src/{vue → components/sheet}/__test__/insert-count-menu-item.test.ts +0 -0
  197. /package/src/{vue → components/sheet}/__test__/use-formula-ref-select.test.ts +0 -0
  198. /package/src/{vue → components/sheet}/__test__/use-formula-suggest.test.ts +0 -0
  199. /package/src/{vue → components/sheet}/formula-suggest-list.vue +0 -0
  200. /package/src/{vue → components/sheet}/import-file.ts +0 -0
  201. /package/src/{vue → components/sheet}/index.ts +0 -0
  202. /package/src/{vue → components/sheet}/insert-count-menu-item.vue +0 -0
  203. /package/src/{vue → components/sheet}/parsing.ts +0 -0
  204. /package/src/{vue → components/sheet}/popups/border-preset-glyph.vue +0 -0
  205. /package/src/{vue → components/sheet}/popups/import.worker.ts +0 -0
  206. /package/src/{vue → components/sheet}/sheet-tabs.vue +0 -0
  207. /package/src/{vue → components/sheet}/style.scss +0 -0
  208. /package/src/{vue → components/sheet}/style.ts +0 -0
  209. /package/src/{vue → components/sheet}/use-formula-ref-select.ts +0 -0
  210. /package/src/{vue → components/sheet}/use-formula-suggest.ts +0 -0
  211. /package/src/{vue → components/sheet}/use-sheet-tabs-bar.ts +0 -0
  212. /package/src/{vue → components/sheet}/use-toolbar-scroll.ts +0 -0
@@ -0,0 +1,393 @@
1
+ import _sfc_main$1 from "../sheet/sheet.js";
2
+ import { applyGridColWidths, applySheetColWidths, readGridColWidths } from "./designer/col-widths.js";
3
+ import _sfc_main$2 from "./report-viewer.js";
4
+ import _sfc_main$3 from "./designer-hub.js";
5
+ import { resolveGridDropAddress } from "./designer/cell-coords.js";
6
+ import _sfc_main$4 from "./designer/drop-highlight-overlay.js";
7
+ import _sfc_main$5 from "./designer/float-panel.js";
8
+ import _sfc_main$6 from "./designer/rules-dialog.js";
9
+ import _sfc_main$7 from "./designer/topology-overlay.js";
10
+ import { FIELD_DRAG_MIME, parseFieldDragPayload } from "./field-panel-helpers.js";
11
+ import _sfc_main$8 from "./field-panel.js";
12
+ import { useReportDesigner } from "./use-report-designer.js";
13
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, onScopeDispose, openBlock, ref, renderList, shallowRef, toDisplayString, unref, useTemplateRef, watch, withCtx } from "vue";
14
+ import { UButton, UDrawer } from "@veltra/desktop";
15
+ import { bem } from "@veltra/utils";
16
+ import { Workbook } from "@veltra/sheet-core";
17
+ //#region src/components/report/report-designer.vue
18
+ const DESIGN_ROWS = 24;
19
+ const DESIGN_COLS = 10;
20
+ const _sfc_main = /*@__PURE__*/ defineComponent({
21
+ name: "UReportDesigner",
22
+ __name: "report-designer",
23
+ props: {
24
+ connector: {},
25
+ connections: { default: () => [] },
26
+ template: {},
27
+ workbook: {}
28
+ },
29
+ emits: ["update:connections", "datasets-change"],
30
+ setup(__props, { expose: __expose, emit: __emit }) {
31
+ const props = __props;
32
+ const emit = __emit;
33
+ const cls = bem("report-designer");
34
+ /** 设计态网格默认尺寸(新建模板;已声明尺寸后以模型为准,避免删行后被 props 撑回) */
35
+ const EMPTY_CONDITIONAL_RULES = [];
36
+ /** `v-model:connections` 可写代理(连接为纯序列化对象,仅驻留内存) */
37
+ const connections = computed({
38
+ get: () => props.connections,
39
+ set: (value) => emit("update:connections", value)
40
+ });
41
+ const designer = useReportDesigner({
42
+ props,
43
+ connections
44
+ });
45
+ const { workbook, catalog, boundKeys, activeCell, selectionLabel, activeBinding, activeFieldType, activeDatasetFields, resolvedRowParentLabel, resolvedColParentLabel, parentPick, rowParentCandidates, colParentCandidates, bindingEntries, metaTick, getBindingAt, resolveFieldLabel, bindField, patchActiveBinding, startParentPick, cancelParentPick, pickParentAt, clearParent, removeActiveBinding, resolveCellStyle, resolveCellRenderer, getTemplate } = designer;
46
+ /** 渲染行列数跟随模型(删行后不再被固定 props 经 ensureTableSize 撑回) */
47
+ const gridRows = computed(() => {
48
+ const rows = workbook.value.activeSheet.rows;
49
+ return rows > 0 ? rows : DESIGN_ROWS;
50
+ });
51
+ const gridCols = computed(() => {
52
+ const cols = workbook.value.activeSheet.cols;
53
+ return cols > 0 ? cols : DESIGN_COLS;
54
+ });
55
+ const hubVisible = ref(false);
56
+ const rulesDialogVisible = ref(false);
57
+ const pickCandidateCells = computed(() => {
58
+ if (!parentPick.value) return [];
59
+ return parentPick.value.mode === "row" ? rowParentCandidates.value : colParentCandidates.value;
60
+ });
61
+ function onHubClose() {
62
+ hubVisible.value = false;
63
+ }
64
+ watch(hubVisible, (open) => {
65
+ if (!open) emit("datasets-change");
66
+ });
67
+ watch(() => designer.datasets.value, () => emit("datasets-change"), { deep: true });
68
+ const sheetRef = useTemplateRef("sheetRef");
69
+ const previewViewerRef = useTemplateRef("previewViewerRef");
70
+ const gridHostRef = useTemplateRef("gridHostRef");
71
+ const gridHostEl = computed(() => gridHostRef.value ?? null);
72
+ /** 字段拖拽落点高亮(dragover 时更新;落空时 overlay 提示回退当前选区) */
73
+ const isFieldDragging = ref(false);
74
+ const dropTargetAddr = ref(null);
75
+ function getDesignGrid() {
76
+ return sheetRef.value?.getGrid();
77
+ }
78
+ const viewMode = ref("design");
79
+ const isPreview = computed(() => viewMode.value === "preview");
80
+ /** 进入预览时的模板快照(getTemplate 吐出,设计态工作簿不受预览取数影响,切回绑定不丢) */
81
+ const previewTemplate = shallowRef(null);
82
+ /** 预览工作簿自持(XLSX 导出需要拿到填充后的 sheet,05 票 workbook? prop 先例) */
83
+ const previewWorkbook = new Workbook();
84
+ /** 当前设计态列宽(与 Sheet 模型同步;getTemplate 经 snapshot.colWidths 吐出) */
85
+ const designColWidths = ref([]);
86
+ const exporting = ref(false);
87
+ /** 从当前设计网格捕获列宽并写回 Sheet 模型(网格未就绪则保留旧值) */
88
+ function captureDesignColWidths() {
89
+ const widths = readGridColWidths(getDesignGrid(), Array.from({ length: gridCols.value }, (_, col) => col));
90
+ if (!widths) return;
91
+ const custom = widths.filter(([, width]) => width > 0);
92
+ designColWidths.value = custom;
93
+ applySheetColWidths(workbook.value.activeSheet, custom);
94
+ }
95
+ /** 设计网格重建后补刷新与列宽(restore 不发 content-reset 的场景由 grid 自行订阅,这里只管列宽) */
96
+ function syncDesignGridView() {
97
+ const grid = getDesignGrid();
98
+ grid?.flushPending();
99
+ grid?.refresh();
100
+ applyGridColWidths(grid, designColWidths.value);
101
+ }
102
+ function setViewMode(mode) {
103
+ if (viewMode.value === mode) return;
104
+ if (mode === "preview") {
105
+ captureDesignColWidths();
106
+ previewTemplate.value = getTemplate();
107
+ }
108
+ viewMode.value = mode;
109
+ if (mode === "design") nextTick(syncDesignGridView);
110
+ }
111
+ watch(() => props.template, (template) => {
112
+ viewMode.value = "design";
113
+ designColWidths.value = template?.colWidths?.length ? template.colWidths.map(([col, width]) => [col, width]) : [];
114
+ if (designColWidths.value.length) applySheetColWidths(workbook.value.activeSheet, designColWidths.value);
115
+ nextTick(syncDesignGridView);
116
+ });
117
+ watch(activeCell, (cell) => {
118
+ if (cell && parentPick.value) pickParentAt(cell);
119
+ });
120
+ watch(catalog, () => {
121
+ nextTick(() => getDesignGrid()?.refresh());
122
+ });
123
+ const offStructureChange = workbook.value.activeSheet.on("structure-change", () => {
124
+ nextTick(syncDesignGridView);
125
+ });
126
+ onScopeDispose(offStructureChange);
127
+ async function exportPreviewXlsx() {
128
+ if (!isPreview.value || exporting.value) return;
129
+ const viewer = previewViewerRef.value;
130
+ if (!viewer) throw new Error("预览查看器尚未就绪,请稍后再导出");
131
+ exporting.value = true;
132
+ try {
133
+ await viewer.exportXlsx();
134
+ } finally {
135
+ exporting.value = false;
136
+ }
137
+ }
138
+ function saveConditionalRules(rules) {
139
+ patchActiveBinding({ conditionalRules: rules });
140
+ }
141
+ function clearDropState() {
142
+ isFieldDragging.value = false;
143
+ dropTargetAddr.value = null;
144
+ }
145
+ function resolveDropAddress(event) {
146
+ const grid = getDesignGrid();
147
+ const gridEl = gridHostRef.value?.querySelector(".u-sheet__grid-instance");
148
+ if (!grid || !gridEl) return null;
149
+ return resolveGridDropAddress(grid, gridEl, event.clientX, event.clientY);
150
+ }
151
+ function onGridDragOver(event) {
152
+ if (!event.dataTransfer?.types.includes("application/x-sheet-report-field")) return;
153
+ event.preventDefault();
154
+ event.dataTransfer.dropEffect = "copy";
155
+ isFieldDragging.value = true;
156
+ dropTargetAddr.value = resolveDropAddress(event);
157
+ }
158
+ function onGridDragLeave(event) {
159
+ const host = gridHostRef.value;
160
+ const related = event.relatedTarget;
161
+ if (host && related instanceof Node && host.contains(related)) return;
162
+ clearDropState();
163
+ }
164
+ function onGridDrop(event) {
165
+ event.preventDefault();
166
+ clearDropState();
167
+ const raw = event.dataTransfer?.getData(FIELD_DRAG_MIME);
168
+ const payload = raw ? parseFieldDragPayload(raw) : null;
169
+ if (!payload) return;
170
+ const grid = getDesignGrid();
171
+ const gridEl = gridHostRef.value?.querySelector(".u-sheet__grid-instance");
172
+ if (!grid || !gridEl) return;
173
+ const dropAddr = resolveDropAddress(event);
174
+ if (dropAddr) {
175
+ bindField(payload.datasetId, payload.fieldName, dropAddr);
176
+ sheetRef.value?.getContext().selectCell(dropAddr);
177
+ } else bindField(payload.datasetId, payload.fieldName);
178
+ }
179
+ __expose({ getTemplate: () => {
180
+ captureDesignColWidths();
181
+ return getTemplate();
182
+ } });
183
+ return (_ctx, _cache) => {
184
+ return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).b) }, [
185
+ createElementVNode("div", { class: normalizeClass(unref(cls).e("toolbar")) }, [
186
+ createVNode(unref(UButton), {
187
+ size: "small",
188
+ plain: "",
189
+ onClick: _cache[0] || (_cache[0] = ($event) => hubVisible.value = true)
190
+ }, {
191
+ default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode("数据中枢", -1)])]),
192
+ _: 1
193
+ }),
194
+ createElementVNode("div", {
195
+ class: normalizeClass(unref(cls).e("mode-toggle")),
196
+ role: "group",
197
+ "aria-label": "视图模式"
198
+ }, [createVNode(unref(UButton), {
199
+ size: "small",
200
+ type: !isPreview.value ? "primary" : void 0,
201
+ plain: isPreview.value,
202
+ onClick: _cache[1] || (_cache[1] = ($event) => setViewMode("design"))
203
+ }, {
204
+ default: withCtx(() => [..._cache[7] || (_cache[7] = [createTextVNode(" 设计模式 ", -1)])]),
205
+ _: 1
206
+ }, 8, ["type", "plain"]), createVNode(unref(UButton), {
207
+ size: "small",
208
+ type: isPreview.value ? "primary" : void 0,
209
+ plain: !isPreview.value,
210
+ onClick: _cache[2] || (_cache[2] = ($event) => setViewMode("preview"))
211
+ }, {
212
+ default: withCtx(() => [..._cache[8] || (_cache[8] = [createTextVNode(" 预览模式 ", -1)])]),
213
+ _: 1
214
+ }, 8, ["type", "plain"])], 2),
215
+ isPreview.value ? (openBlock(), createBlock(unref(UButton), {
216
+ key: 0,
217
+ size: "small",
218
+ type: "primary",
219
+ plain: "",
220
+ loading: exporting.value,
221
+ onClick: exportPreviewXlsx
222
+ }, {
223
+ default: withCtx(() => [..._cache[9] || (_cache[9] = [createTextVNode(" 导出 XLSX ", -1)])]),
224
+ _: 1
225
+ }, 8, ["loading"])) : createCommentVNode("v-if", true),
226
+ createElementVNode("span", { class: normalizeClass(unref(cls).e("hint")) }, " 在数据中枢配置连接与 SQL 数据集,再将左侧字段点击或拖拽到单元格完成绑定;选中已绑定格可通过悬浮卡片调整预设与条件样式。 ", 2)
227
+ ], 2),
228
+ !isPreview.value ? (openBlock(), createElementBlock("div", {
229
+ key: 0,
230
+ class: normalizeClass(unref(cls).e("body"))
231
+ }, [createVNode(_sfc_main$8, {
232
+ class: normalizeClass(unref(cls).e("field-panel")),
233
+ datasets: unref(catalog),
234
+ "selection-label": unref(selectionLabel),
235
+ "bound-keys": unref(boundKeys),
236
+ onBind: unref(bindField)
237
+ }, null, 8, [
238
+ "class",
239
+ "datasets",
240
+ "selection-label",
241
+ "bound-keys",
242
+ "onBind"
243
+ ]), createElementVNode("div", {
244
+ ref_key: "gridHostRef",
245
+ ref: gridHostRef,
246
+ class: normalizeClass(unref(cls).e("grid")),
247
+ onDragover: onGridDragOver,
248
+ onDragleave: onGridDragLeave,
249
+ onDrop: onGridDrop
250
+ }, [
251
+ createVNode(unref(_sfc_main$1), {
252
+ ref_key: "sheetRef",
253
+ ref: sheetRef,
254
+ class: normalizeClass(unref(cls).e("sheet")),
255
+ workbook: unref(workbook),
256
+ rows: gridRows.value,
257
+ cols: gridCols.value,
258
+ "show-tabs": false,
259
+ "resolve-cell-style": unref(resolveCellStyle),
260
+ "resolve-cell-renderer": unref(resolveCellRenderer)
261
+ }, null, 8, [
262
+ "class",
263
+ "workbook",
264
+ "rows",
265
+ "cols",
266
+ "resolve-cell-style",
267
+ "resolve-cell-renderer"
268
+ ]),
269
+ createVNode(_sfc_main$7, {
270
+ cell: unref(activeCell),
271
+ binding: unref(activeBinding) ?? null,
272
+ entries: unref(bindingEntries),
273
+ "meta-tick": unref(metaTick),
274
+ "host-el": gridHostEl.value,
275
+ "get-grid": getDesignGrid,
276
+ "get-binding-at": unref(getBindingAt)
277
+ }, null, 8, [
278
+ "cell",
279
+ "binding",
280
+ "entries",
281
+ "meta-tick",
282
+ "host-el",
283
+ "get-binding-at"
284
+ ]),
285
+ createVNode(_sfc_main$4, {
286
+ cell: dropTargetAddr.value,
287
+ "host-el": gridHostEl.value,
288
+ "get-grid": getDesignGrid,
289
+ dragging: isFieldDragging.value,
290
+ "fallback-label": unref(selectionLabel)
291
+ }, null, 8, [
292
+ "cell",
293
+ "host-el",
294
+ "dragging",
295
+ "fallback-label"
296
+ ]),
297
+ (openBlock(true), createElementBlock(Fragment, null, renderList(pickCandidateCells.value, (addr) => {
298
+ return openBlock(), createBlock(_sfc_main$4, {
299
+ key: `pick-${addr.row}-${addr.col}`,
300
+ cell: addr,
301
+ "host-el": gridHostEl.value,
302
+ "get-grid": getDesignGrid,
303
+ dragging: false,
304
+ "fallback-label": ""
305
+ }, null, 8, ["cell", "host-el"]);
306
+ }), 128)),
307
+ unref(parentPick) ? (openBlock(), createElementBlock("div", {
308
+ key: 0,
309
+ class: normalizeClass(unref(cls).e("pick-hint")),
310
+ role: "status"
311
+ }, toDisplayString(unref(parentPick).mode === "row" ? "点击分组头作为行方向父格" : "点击分组头作为列方向父格"), 3)) : createCommentVNode("v-if", true),
312
+ createVNode(_sfc_main$5, {
313
+ cell: unref(activeCell),
314
+ binding: unref(activeBinding) ?? null,
315
+ "resolved-row-parent-label": unref(resolvedRowParentLabel),
316
+ "resolved-col-parent-label": unref(resolvedColParentLabel),
317
+ "parent-pick-mode": unref(parentPick)?.mode ?? null,
318
+ "row-parent-candidates": unref(rowParentCandidates),
319
+ "col-parent-candidates": unref(colParentCandidates),
320
+ "resolve-field-label": unref(resolveFieldLabel),
321
+ "get-binding-at": unref(getBindingAt),
322
+ "host-el": gridHostEl.value,
323
+ "get-grid": getDesignGrid,
324
+ onPatch: unref(patchActiveBinding),
325
+ onRemove: unref(removeActiveBinding),
326
+ onOpenRules: _cache[3] || (_cache[3] = ($event) => rulesDialogVisible.value = true),
327
+ onStartParentPick: unref(startParentPick),
328
+ onCancelParentPick: unref(cancelParentPick),
329
+ onClearParent: unref(clearParent)
330
+ }, null, 8, [
331
+ "cell",
332
+ "binding",
333
+ "resolved-row-parent-label",
334
+ "resolved-col-parent-label",
335
+ "parent-pick-mode",
336
+ "row-parent-candidates",
337
+ "col-parent-candidates",
338
+ "resolve-field-label",
339
+ "get-binding-at",
340
+ "host-el",
341
+ "onPatch",
342
+ "onRemove",
343
+ "onStartParentPick",
344
+ "onCancelParentPick",
345
+ "onClearParent"
346
+ ])
347
+ ], 34)], 2)) : previewTemplate.value ? (openBlock(), createElementBlock("div", {
348
+ key: 1,
349
+ class: normalizeClass(unref(cls).e("preview"))
350
+ }, [createVNode(_sfc_main$2, {
351
+ ref_key: "previewViewerRef",
352
+ ref: previewViewerRef,
353
+ connector: props.connector,
354
+ template: previewTemplate.value,
355
+ workbook: unref(previewWorkbook)
356
+ }, null, 8, [
357
+ "connector",
358
+ "template",
359
+ "workbook"
360
+ ])], 2)) : createCommentVNode("v-if", true),
361
+ createVNode(unref(UDrawer), {
362
+ modelValue: hubVisible.value,
363
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => hubVisible.value = $event),
364
+ class: normalizeClass(unref(cls).e("hub-drawer")),
365
+ "show-close": ""
366
+ }, {
367
+ default: withCtx(() => [createVNode(_sfc_main$3, {
368
+ hub: unref(designer),
369
+ onClose: onHubClose
370
+ }, null, 8, ["hub"])]),
371
+ _: 1
372
+ }, 8, ["modelValue", "class"]),
373
+ createVNode(_sfc_main$6, {
374
+ modelValue: rulesDialogVisible.value,
375
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => rulesDialogVisible.value = $event),
376
+ rules: unref(activeBinding)?.conditionalRules ?? EMPTY_CONDITIONAL_RULES,
377
+ "binding-field": unref(activeBinding)?.field ?? "",
378
+ "dataset-fields": unref(activeDatasetFields),
379
+ "field-type": unref(activeFieldType),
380
+ onSave: saveConditionalRules
381
+ }, null, 8, [
382
+ "modelValue",
383
+ "rules",
384
+ "binding-field",
385
+ "dataset-fields",
386
+ "field-type"
387
+ ])
388
+ ], 2);
389
+ };
390
+ }
391
+ });
392
+ //#endregion
393
+ export { _sfc_main as default };
@@ -0,0 +1,124 @@
1
+ import _sfc_main$1 from "../sheet/sheet.js";
2
+ import { exportFilledReportXlsx } from "../../report/export-xlsx.js";
3
+ import { applyGridColWidths, applySheetColWidths } from "./designer/col-widths.js";
4
+ import _sfc_main$2 from "./filter-bar.js";
5
+ import { previewGridSize } from "./preview-grid-size.js";
6
+ import { useReportViewer } from "./use-report-viewer.js";
7
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, nextTick, normalizeClass, openBlock, toDisplayString, unref, useTemplateRef, watch } from "vue";
8
+ import { bem } from "@veltra/utils";
9
+ import { saveBlob } from "@cat-kit/fe";
10
+ import { Workbook } from "@veltra/sheet-core";
11
+ //#region src/components/report/report-viewer.vue
12
+ const EXPORT_NOT_READY_MESSAGE = "报表数据尚未就绪,请等待取数完成后再导出";
13
+ const EXPORT_LOADING_MESSAGE = "报表数据加载中,请稍后再导出";
14
+ /** 查看器工作簿:宿主可注入(同 USheet `workbook?` 先例),缺省内部自建;模板 / 填充结果都 restore 进活动 sheet 只读展示 */
15
+ const _sfc_main = /*@__PURE__*/ defineComponent({
16
+ name: "UReportViewer",
17
+ __name: "report-viewer",
18
+ props: {
19
+ connector: {},
20
+ template: {},
21
+ workbook: {},
22
+ colWidths: {}
23
+ },
24
+ setup(__props, { expose: __expose }) {
25
+ const props = __props;
26
+ const cls = bem("report-viewer");
27
+ /** 取数未完成时拒绝导出的可读错误 */
28
+ const internalWorkbook = new Workbook();
29
+ const workbook = computed(() => props.workbook ?? internalWorkbook);
30
+ const sheetRef = useTemplateRef("sheetRef");
31
+ const { params, values, loading, error, filledSnapshot, filledColWidths, refresh, setValues } = useReportViewer(props);
32
+ const renderSize = computed(() => {
33
+ const filled = filledSnapshot.value;
34
+ if (filled) return previewGridSize(filled, "filled");
35
+ return previewGridSize(props.template, "template");
36
+ });
37
+ /** 宿主显式传入优先;否则取数完成后用展开映射列宽;再回落模板设计态列宽 */
38
+ const effectiveColWidths = computed(() => {
39
+ if (props.colWidths?.length) return props.colWidths;
40
+ if (filledColWidths.value?.length) return filledColWidths.value;
41
+ return props.template.colWidths;
42
+ });
43
+ /** 将运行时列宽写入模型与 VTable(模型为单一事实源;grid 构造/content-reset 也会回放) */
44
+ function applyRuntimeColWidths() {
45
+ if (!effectiveColWidths.value?.length) return;
46
+ const sheet = workbook.value.activeSheet;
47
+ applySheetColWidths(sheet, effectiveColWidths.value);
48
+ applyGridColWidths(sheetRef.value?.getGrid(), effectiveColWidths.value);
49
+ }
50
+ /**
51
+ * restore 负责尺寸/冻结/行高/列宽/选区(静默),restoreContent 发 content-reset
52
+ * 触发网格全量刷新(grid 层订阅直刷,无需手动 flush);history.clear 使填充不进 undo
53
+ */
54
+ function applySnapshot(snapshot, mode) {
55
+ const size = previewGridSize(snapshot, mode);
56
+ const trimmed = {
57
+ ...snapshot,
58
+ rows: size.rows,
59
+ cols: size.cols
60
+ };
61
+ const sheet = workbook.value.activeSheet;
62
+ sheet.restore(trimmed);
63
+ sheet.restoreContent(trimmed);
64
+ sheet.history.clear();
65
+ nextTick(applyRuntimeColWidths);
66
+ }
67
+ watch(() => props.template, (template) => applySnapshot(template, "template"), { immediate: true });
68
+ watch(filledSnapshot, (filled) => {
69
+ if (filled) applySnapshot(filled, "filled");
70
+ });
71
+ watch(effectiveColWidths, applyRuntimeColWidths);
72
+ async function exportXlsx() {
73
+ if (loading.value) throw new Error(EXPORT_LOADING_MESSAGE);
74
+ if (!filledSnapshot.value) throw new Error(EXPORT_NOT_READY_MESSAGE);
75
+ const sheet = workbook.value.activeSheet;
76
+ const buffer = await exportFilledReportXlsx(sheet);
77
+ saveBlob(new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), `${sheet.name || "报表"}.xlsx`);
78
+ }
79
+ __expose({
80
+ refresh,
81
+ exportXlsx
82
+ });
83
+ return (_ctx, _cache) => {
84
+ return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).b) }, [unref(params).length ? (openBlock(), createBlock(_sfc_main$2, {
85
+ key: 0,
86
+ "query-params": unref(params),
87
+ values: unref(values),
88
+ "onUpdate:values": unref(setValues)
89
+ }, null, 8, [
90
+ "query-params",
91
+ "values",
92
+ "onUpdate:values"
93
+ ])) : createCommentVNode("v-if", true), createElementVNode("div", { class: normalizeClass(unref(cls).e("body")) }, [unref(loading) ? (openBlock(), createElementBlock("div", {
94
+ key: 0,
95
+ class: normalizeClass(unref(cls).e("loading")),
96
+ "aria-live": "polite"
97
+ }, [createElementVNode("div", { class: normalizeClass(unref(cls).e("loading-spinner")) }, null, 2), _cache[0] || (_cache[0] = createElementVNode("span", null, "正在加载报表数据…", -1))], 2)) : unref(error) ? (openBlock(), createElementBlock("div", {
98
+ key: 1,
99
+ class: normalizeClass(unref(cls).e("error")),
100
+ role: "alert"
101
+ }, toDisplayString(unref(error).message), 3)) : createCommentVNode("v-if", true), createVNode(unref(_sfc_main$1), {
102
+ ref_key: "sheetRef",
103
+ ref: sheetRef,
104
+ class: normalizeClass(unref(cls).e("sheet")),
105
+ workbook: workbook.value,
106
+ rows: renderSize.value.rows,
107
+ cols: renderSize.value.cols,
108
+ "show-toolbar": false,
109
+ "show-formula-bar": false,
110
+ "show-tabs": false,
111
+ "show-row-header": false,
112
+ "show-col-header": false,
113
+ readonly: ""
114
+ }, null, 8, [
115
+ "class",
116
+ "workbook",
117
+ "rows",
118
+ "cols"
119
+ ])], 2)], 2);
120
+ };
121
+ }
122
+ });
123
+ //#endregion
124
+ export { _sfc_main as default };
@@ -0,0 +1,17 @@
1
+ import "../sheet/style.js";
2
+ import "@veltra/desktop/components/number-input/style";
3
+ import "@veltra/desktop/components/palette/style";
4
+ import "@veltra/desktop/components/input/style";
5
+ import "@veltra/desktop/components/select/style";
6
+ import "@veltra/desktop/components/date-picker/style";
7
+ import "@veltra/desktop/components/date-range-picker/style";
8
+ import "@veltra/desktop/components/button/style";
9
+ import "@veltra/desktop/components/drawer/style";
10
+ import "@veltra/desktop/components/dialog/style";
11
+ import "@veltra/desktop/components/radio-group/style";
12
+ import "@veltra/desktop/components/switch/style";
13
+ import "@veltra/desktop/components/table/style";
14
+ import "@veltra/desktop/components/tabs/style";
15
+ import "@veltra/desktop/components/tag/style";
16
+ import "@veltra/desktop/components/pop-confirm/style";
17
+ import "@veltra/desktop/components/code-editor/style";
@@ -0,0 +1,18 @@
1
+ import "../sheet/style.js";
2
+ import "./style2.css";
3
+ import "@veltra/desktop/components/number-input/style";
4
+ import "@veltra/desktop/components/palette/style";
5
+ import "@veltra/desktop/components/input/style";
6
+ import "@veltra/desktop/components/select/style";
7
+ import "@veltra/desktop/components/date-picker/style";
8
+ import "@veltra/desktop/components/date-range-picker/style";
9
+ import "@veltra/desktop/components/button/style";
10
+ import "@veltra/desktop/components/drawer/style";
11
+ import "@veltra/desktop/components/dialog/style";
12
+ import "@veltra/desktop/components/radio-group/style";
13
+ import "@veltra/desktop/components/switch/style";
14
+ import "@veltra/desktop/components/table/style";
15
+ import "@veltra/desktop/components/tabs/style";
16
+ import "@veltra/desktop/components/tag/style";
17
+ import "@veltra/desktop/components/pop-confirm/style";
18
+ import "@veltra/desktop/components/code-editor/style";