@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.
- package/dist/components/report/binding-badge.js +100 -0
- package/dist/components/report/designer/cell-coords.js +46 -0
- package/dist/components/report/designer/col-widths.js +29 -0
- package/dist/components/report/designer/conditional-rules/helpers.js +139 -0
- package/dist/components/report/designer/drop-highlight-overlay.js +76 -0
- package/dist/components/report/designer/float-panel.js +422 -0
- package/dist/components/report/designer/role.js +17 -0
- package/dist/components/report/designer/rule-preview.js +33 -0
- package/dist/components/report/designer/rule-row.js +253 -0
- package/dist/components/report/designer/rules-dialog.js +118 -0
- package/dist/components/report/designer/topology-overlay.js +122 -0
- package/dist/components/report/designer/topology.js +64 -0
- package/dist/components/report/designer/use-grid-overlay.js +75 -0
- package/dist/components/report/designer-hub.js +177 -0
- package/dist/components/report/field-panel-helpers.js +33 -0
- package/dist/components/report/field-panel.js +132 -0
- package/dist/components/report/filter-bar.js +74 -0
- package/dist/components/report/hub-connection-form.js +145 -0
- package/dist/components/report/hub-dataset-editor.js +394 -0
- package/dist/components/report/preview-grid-size.js +32 -0
- package/dist/components/report/report-designer.js +393 -0
- package/dist/components/report/report-viewer.js +124 -0
- package/dist/components/report/style.d.ts +17 -0
- package/dist/components/report/style.js +18 -0
- package/dist/components/report/style2.css +874 -0
- package/dist/components/report/use-report-designer.js +382 -0
- package/dist/components/report/use-report-viewer.js +55 -0
- package/dist/{vue → components/sheet}/formula-bar.js +1 -1
- package/dist/{vue → components/sheet}/formula-suggest-list.js +1 -1
- package/dist/{vue → components/sheet}/import-file.js +1 -1
- package/dist/{vue → components/sheet}/insert-count-menu-item.js +1 -1
- package/dist/{vue → components/sheet}/insert-image.js +1 -1
- package/dist/{vue → components/sheet}/popup-helpers.js +1 -1
- package/dist/{vue → components/sheet}/popups/border-popup.js +31 -3
- package/dist/{vue → components/sheet}/popups/border-preset-glyph.js +1 -1
- package/dist/{vue → components/sheet}/popups/export-popup.js +2 -2
- package/dist/{vue → components/sheet}/popups/fill-color-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/find-popup.js +1 -1
- package/dist/{vue → components/sheet}/popups/font-color-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/font-size-popup.js +3 -3
- package/dist/{vue → components/sheet}/popups/import.worker.d.ts +1 -1
- package/dist/{vue → components/sheet}/popups/import.worker.js +1 -1
- package/dist/{vue → components/sheet}/popups/insert-image-popup.js +1 -1
- package/dist/{vue → components/sheet}/sheet-context-menu.js +7 -4
- package/dist/{vue → components/sheet}/sheet-tabs.js +1 -1
- package/dist/{vue → components/sheet}/sheet-toolbar.js +1 -1
- package/dist/{vue → components/sheet}/sheet.js +16 -1
- package/dist/{vue → components/sheet}/use-find-replace.js +1 -1
- package/dist/{vue → components/sheet}/use-formula-ref-select.js +1 -1
- package/dist/{vue → components/sheet}/use-sheet-grid.js +22 -4
- package/dist/{vue → components/sheet}/use-sheet-state.js +6 -5
- package/dist/{vue → components/sheet}/use-sheet-tabs-bar.js +1 -1
- package/dist/{vue → components/sheet}/use-tool-groups.js +2 -2
- package/dist/{vue → components/sheet}/use-tool-popup.js +2 -2
- package/dist/{vue → components/sheet}/use-toolbar-scroll.js +1 -1
- package/dist/index.d.ts +17 -3
- package/dist/index.js +13 -3
- package/dist/report/binding.d.ts +83 -0
- package/dist/report/binding.js +332 -0
- package/dist/report/connector.d.ts +66 -0
- package/dist/report/connector.js +159 -0
- package/dist/report/export-xlsx.d.ts +17 -0
- package/dist/report/export-xlsx.js +92 -0
- package/dist/report/filter-bar.d.ts +10 -0
- package/dist/report/filter-bar.js +31 -0
- package/dist/report/index.d.ts +12 -0
- package/dist/report/params.d.ts +13 -0
- package/dist/report/params.js +61 -0
- package/dist/report/render/aggregate.js +169 -0
- package/dist/report/render/builder.d.ts +12 -0
- package/dist/report/render/builder.js +139 -0
- package/dist/report/render/coordinate.d.ts +25 -0
- package/dist/report/render/coordinate.js +733 -0
- package/dist/report/render/index.d.ts +14 -0
- package/dist/report/render/index.js +21 -0
- package/dist/report/render/style-resolver.js +50 -0
- package/dist/report/render/template-index.d.ts +24 -0
- package/dist/report/render/template-index.js +137 -0
- package/dist/report/rules/evaluate.d.ts +25 -0
- package/dist/report/rules/evaluate.js +82 -0
- package/dist/report/rules/index.d.ts +2 -0
- package/dist/report/template.d.ts +63 -0
- package/dist/report/template.js +83 -0
- package/dist/report/types.d.ts +85 -0
- package/dist/tools/apply-style.js +29 -0
- package/dist/tools/builtin.js +17 -17
- package/dist/tools/context.d.ts +39 -6
- package/dist/tools/context.js +38 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/report-designer.d.ts +38 -0
- package/dist/types/report-viewer.d.ts +38 -0
- package/dist/types/sheet.d.ts +21 -1
- package/package.json +6 -8
- package/src/components/report/__test__/conditional-rules-helpers.test.ts +88 -0
- package/src/components/report/__test__/field-panel-helpers.test.ts +65 -0
- package/src/components/report/__test__/float-panel-position.test.ts +45 -0
- package/src/components/report/__test__/preview-grid-size.test.ts +63 -0
- package/src/components/report/__test__/report-designer.test.ts +464 -0
- package/src/components/report/__test__/report-viewer.test.ts +357 -0
- package/src/components/report/__test__/topology.test.ts +143 -0
- package/src/components/report/__test__/use-report-designer.test.ts +697 -0
- package/src/components/report/binding-badge.ts +92 -0
- package/src/components/report/designer/cell-coords.ts +94 -0
- package/src/components/report/designer/col-widths.ts +56 -0
- package/src/components/report/designer/conditional-rules/helpers.ts +189 -0
- package/src/components/report/designer/drop-highlight-overlay.vue +74 -0
- package/src/components/report/designer/float-panel.vue +431 -0
- package/src/components/report/designer/role.ts +32 -0
- package/src/components/report/designer/rule-preview.vue +40 -0
- package/src/components/report/designer/rule-row.vue +252 -0
- package/src/components/report/designer/rules-dialog.vue +110 -0
- package/src/components/report/designer/topology-overlay.vue +127 -0
- package/src/components/report/designer/topology.ts +124 -0
- package/src/components/report/designer/use-grid-overlay.ts +113 -0
- package/src/components/report/designer-hub.vue +198 -0
- package/src/components/report/field-panel-helpers.ts +44 -0
- package/src/components/report/field-panel.vue +136 -0
- package/src/components/report/filter-bar.vue +77 -0
- package/src/components/report/hub-connection-form.vue +124 -0
- package/src/components/report/hub-dataset-editor.vue +369 -0
- package/src/components/report/index.ts +2 -0
- package/src/components/report/preview-grid-size.ts +33 -0
- package/src/components/report/report-designer.vue +420 -0
- package/src/components/report/report-viewer.vue +136 -0
- package/src/components/report/style-designer.scss +587 -0
- package/src/components/report/style-hub.scss +292 -0
- package/src/components/report/style-viewer.scss +104 -0
- package/src/components/report/style.scss +3 -0
- package/src/components/report/style.ts +20 -0
- package/src/components/report/use-report-designer.ts +596 -0
- package/src/components/report/use-report-viewer.ts +88 -0
- package/src/{vue → components/sheet}/__test__/formula-bar.test.ts +37 -18
- package/src/{vue → components/sheet}/__test__/insert-image-popup.test.ts +1 -1
- package/src/{vue → components/sheet}/__test__/insert-image.test.ts +1 -1
- package/src/{vue → components/sheet}/__test__/sheet-component.test.ts +77 -3
- package/src/{vue → components/sheet}/__test__/sheet-context-menu.test.ts +4 -3
- package/src/{vue → components/sheet}/formula-bar.vue +1 -1
- package/src/{vue → components/sheet}/insert-image.ts +1 -1
- package/src/{vue → components/sheet}/popup-helpers.ts +1 -1
- package/src/{vue → components/sheet}/popups/border-popup.vue +32 -4
- package/src/{vue → components/sheet}/popups/export-popup.vue +2 -2
- package/src/{vue → components/sheet}/popups/fill-color-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/find-popup.vue +1 -1
- package/src/{vue → components/sheet}/popups/font-color-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/font-size-popup.vue +3 -3
- package/src/{vue → components/sheet}/popups/insert-image-popup.vue +1 -1
- package/src/{vue → components/sheet}/sheet-context-menu.ts +10 -4
- package/src/{vue → components/sheet}/sheet-toolbar.vue +2 -2
- package/src/{vue → components/sheet}/sheet.vue +6 -3
- package/src/{vue → components/sheet}/use-find-replace.ts +1 -1
- package/src/{vue → components/sheet}/use-sheet-grid.ts +23 -5
- package/src/{vue → components/sheet}/use-sheet-state.ts +11 -6
- package/src/{vue → components/sheet}/use-tool-groups.ts +2 -2
- package/src/{vue → components/sheet}/use-tool-popup.ts +2 -2
- package/src/index.ts +24 -188
- package/src/report/__test__/binding.test.ts +320 -0
- package/src/report/__test__/connector.test.ts +239 -0
- package/src/report/__test__/export-xlsx.test.ts +118 -0
- package/src/report/__test__/filter-bar.test.ts +58 -0
- package/src/report/__test__/params.test.ts +156 -0
- package/src/report/__test__/render.test.ts +830 -0
- package/src/report/__test__/rules.test.ts +131 -0
- package/src/report/__test__/template.test.ts +366 -0
- package/src/report/binding.ts +474 -0
- package/src/report/connector.ts +206 -0
- package/src/report/export-xlsx.ts +113 -0
- package/src/report/filter-bar.ts +36 -0
- package/src/report/index.ts +13 -0
- package/src/report/params.ts +96 -0
- package/src/report/render/__test__/aggregate.test.ts +16 -0
- package/src/report/render/__test__/coordinate.test.ts +405 -0
- package/src/report/render/aggregate.ts +261 -0
- package/src/report/render/builder.ts +211 -0
- package/src/report/render/coordinate.ts +1239 -0
- package/src/report/render/index.ts +30 -0
- package/src/report/render/style-resolver.ts +68 -0
- package/src/report/render/template-index.ts +200 -0
- package/src/report/rules/evaluate.ts +113 -0
- package/src/report/rules/index.ts +7 -0
- package/src/report/template.ts +145 -0
- package/src/report/types.ts +96 -0
- package/src/tools/__test__/apply-style.test.ts +129 -0
- package/src/tools/apply-style.ts +41 -0
- package/src/tools/builtin.ts +20 -20
- package/src/tools/context.ts +67 -4
- package/src/tools/index.ts +1 -0
- package/src/types/index.ts +2 -6
- package/src/types/report-designer.ts +38 -0
- package/src/types/report-viewer.ts +37 -0
- package/src/types/sheet.ts +26 -1
- /package/dist/{vue → components/sheet}/style.d.ts +0 -0
- /package/dist/{vue → components/sheet}/style.js +0 -0
- /package/dist/{vue → components/sheet}/style2.css +0 -0
- /package/dist/{vue → components/sheet}/use-formula-suggest.js +0 -0
- /package/src/{vue → components/sheet}/__test__/import-file.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/insert-count-menu-item.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/use-formula-ref-select.test.ts +0 -0
- /package/src/{vue → components/sheet}/__test__/use-formula-suggest.test.ts +0 -0
- /package/src/{vue → components/sheet}/formula-suggest-list.vue +0 -0
- /package/src/{vue → components/sheet}/import-file.ts +0 -0
- /package/src/{vue → components/sheet}/index.ts +0 -0
- /package/src/{vue → components/sheet}/insert-count-menu-item.vue +0 -0
- /package/src/{vue → components/sheet}/parsing.ts +0 -0
- /package/src/{vue → components/sheet}/popups/border-preset-glyph.vue +0 -0
- /package/src/{vue → components/sheet}/popups/import.worker.ts +0 -0
- /package/src/{vue → components/sheet}/sheet-tabs.vue +0 -0
- /package/src/{vue → components/sheet}/style.scss +0 -0
- /package/src/{vue → components/sheet}/style.ts +0 -0
- /package/src/{vue → components/sheet}/use-formula-ref-select.ts +0 -0
- /package/src/{vue → components/sheet}/use-formula-suggest.ts +0 -0
- /package/src/{vue → components/sheet}/use-sheet-tabs-bar.ts +0 -0
- /package/src/{vue → components/sheet}/use-toolbar-scroll.ts +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { formatBindingPlaceholderParts, inferReportPreset } from "../../report/binding.js";
|
|
2
|
+
import { CustomLayout } from "@veltra/sheet-core";
|
|
3
|
+
//#region src/components/report/binding-badge.ts
|
|
4
|
+
const REPORT_PRESET_BADGE_COLORS = {
|
|
5
|
+
groupHeader: {
|
|
6
|
+
cell: "#eef4ff",
|
|
7
|
+
fg: "#2f54eb"
|
|
8
|
+
},
|
|
9
|
+
detail: {
|
|
10
|
+
cell: "#effaf3",
|
|
11
|
+
fg: "#1f9254"
|
|
12
|
+
},
|
|
13
|
+
subtotal: {
|
|
14
|
+
cell: "#fff7e6",
|
|
15
|
+
fg: "#d46b08"
|
|
16
|
+
},
|
|
17
|
+
grandTotal: {
|
|
18
|
+
cell: "#fff1f0",
|
|
19
|
+
fg: "#cf1322"
|
|
20
|
+
},
|
|
21
|
+
cross: {
|
|
22
|
+
cell: "#f8f5ff",
|
|
23
|
+
fg: "#5f3dc4"
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const CUSTOM_PRESET_BADGE_COLOR = {
|
|
27
|
+
cell: "#f7f8fa",
|
|
28
|
+
fg: "#495057"
|
|
29
|
+
};
|
|
30
|
+
/** 徽章字段标签文字色(中性深灰,与强调色形成层次) */
|
|
31
|
+
const BADGE_LABEL_COLOR = "#343a40";
|
|
32
|
+
function resolveBadgeColor(binding) {
|
|
33
|
+
const preset = inferReportPreset(binding);
|
|
34
|
+
return preset ? REPORT_PRESET_BADGE_COLORS[preset] : CUSTOM_PRESET_BADGE_COLOR;
|
|
35
|
+
}
|
|
36
|
+
/** 绑定格角色底色(走 resolveCellStyle,保留 VTable 默认边框绘制) */
|
|
37
|
+
function createBindingBadgeStyleResolver(getBindingAt) {
|
|
38
|
+
return (addr, base) => {
|
|
39
|
+
const binding = getBindingAt(addr);
|
|
40
|
+
if (!binding) return base;
|
|
41
|
+
const { cell } = resolveBadgeColor(binding);
|
|
42
|
+
return {
|
|
43
|
+
...base,
|
|
44
|
+
fill: { color: cell }
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 绑定格富渲染徽章(ADR-0004 `resolveCellRenderer` 首个消费者):
|
|
50
|
+
* 绑定单元格渲染为左对齐徽章(强调色聚合标签 + 中性色字段标签),
|
|
51
|
+
* 未绑定格返回 `undefined` 回落默认渲染。
|
|
52
|
+
*/
|
|
53
|
+
function createBindingBadgeRenderer(getBindingAt, resolveLabel) {
|
|
54
|
+
return (addr) => {
|
|
55
|
+
const binding = getBindingAt(addr);
|
|
56
|
+
if (!binding) return void 0;
|
|
57
|
+
const { fg } = resolveBadgeColor(binding);
|
|
58
|
+
const { tag, label } = formatBindingPlaceholderParts(binding, resolveLabel);
|
|
59
|
+
const rootContainer = new CustomLayout.Container({
|
|
60
|
+
display: "flex",
|
|
61
|
+
flexDirection: "row",
|
|
62
|
+
justifyContent: "flex-start",
|
|
63
|
+
alignItems: "center"
|
|
64
|
+
});
|
|
65
|
+
const tagEl = new CustomLayout.Tag({
|
|
66
|
+
text: tag,
|
|
67
|
+
textStyle: {
|
|
68
|
+
fontSize: 10,
|
|
69
|
+
fontWeight: 600,
|
|
70
|
+
fill: "#ffffff"
|
|
71
|
+
},
|
|
72
|
+
panel: {
|
|
73
|
+
visible: true,
|
|
74
|
+
fill: fg,
|
|
75
|
+
cornerRadius: 3
|
|
76
|
+
},
|
|
77
|
+
padding: [
|
|
78
|
+
1,
|
|
79
|
+
4,
|
|
80
|
+
1,
|
|
81
|
+
4
|
|
82
|
+
],
|
|
83
|
+
marginLeft: 6,
|
|
84
|
+
marginRight: 5
|
|
85
|
+
});
|
|
86
|
+
rootContainer.add(tagEl);
|
|
87
|
+
rootContainer.add(new CustomLayout.Text({
|
|
88
|
+
text: label,
|
|
89
|
+
fontSize: 11,
|
|
90
|
+
fontWeight: 500,
|
|
91
|
+
fill: BADGE_LABEL_COLOR
|
|
92
|
+
}));
|
|
93
|
+
return {
|
|
94
|
+
rootContainer,
|
|
95
|
+
renderDefault: false
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { REPORT_PRESET_BADGE_COLORS, createBindingBadgeRenderer, createBindingBadgeStyleResolver };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
function resolveGridOverlayLayout(host) {
|
|
2
|
+
const gridEl = host.querySelector(".u-sheet__grid-instance");
|
|
3
|
+
if (!gridEl) return null;
|
|
4
|
+
const hostBox = host.getBoundingClientRect();
|
|
5
|
+
const gridBox = gridEl.getBoundingClientRect();
|
|
6
|
+
return {
|
|
7
|
+
gridEl,
|
|
8
|
+
layout: {
|
|
9
|
+
offsetX: gridBox.left - hostBox.left,
|
|
10
|
+
offsetY: gridBox.top - hostBox.top,
|
|
11
|
+
viewW: gridEl.clientWidth,
|
|
12
|
+
viewH: gridEl.clientHeight
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** 将屏幕坐标换算为网格落点地址(用于字段拖拽 bind) */
|
|
17
|
+
function resolveGridDropAddress(grid, gridEl, clientX, clientY) {
|
|
18
|
+
const rect = gridEl.getBoundingClientRect();
|
|
19
|
+
return grid.hitTestSheetAddr(clientX - rect.left, clientY - rect.top) ?? null;
|
|
20
|
+
}
|
|
21
|
+
function getCellOverlayRect(grid, cell, layout) {
|
|
22
|
+
const table = grid.getTable();
|
|
23
|
+
let cellRect;
|
|
24
|
+
try {
|
|
25
|
+
cellRect = table.getCellRelativeRect(cell.col + 1, cell.row + 1);
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const left = layout.offsetX + cellRect.left;
|
|
30
|
+
const top = layout.offsetY + cellRect.top;
|
|
31
|
+
const right = layout.offsetX + cellRect.right;
|
|
32
|
+
const bottom = layout.offsetY + cellRect.bottom;
|
|
33
|
+
if (cellRect.bottom < 0 || cellRect.right < 0 || cellRect.top > layout.viewH || cellRect.left > layout.viewW) return null;
|
|
34
|
+
return {
|
|
35
|
+
left,
|
|
36
|
+
top,
|
|
37
|
+
right,
|
|
38
|
+
bottom,
|
|
39
|
+
width: right - left,
|
|
40
|
+
height: bottom - top,
|
|
41
|
+
centerX: (left + right) / 2,
|
|
42
|
+
centerY: (top + bottom) / 2
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { getCellOverlayRect, resolveGridDropAddress, resolveGridOverlayLayout };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/components/report/designer/col-widths.ts
|
|
2
|
+
/** 行号列数(隐藏行头时为 0;与 GridCoords 探测一致) */
|
|
3
|
+
function seriesNumberColCount(table) {
|
|
4
|
+
const rowOffset = table.columnHeaderLevelCount;
|
|
5
|
+
let col = 0;
|
|
6
|
+
while (col < table.colCount && table.isSeriesNumber(col, rowOffset)) col++;
|
|
7
|
+
return col;
|
|
8
|
+
}
|
|
9
|
+
/** 将模型列宽写入 VTable(模型 → grid 同步辅助) */
|
|
10
|
+
function applyGridColWidths(grid, widths) {
|
|
11
|
+
if (!grid) return;
|
|
12
|
+
const table = grid.getTable();
|
|
13
|
+
const colOffset = seriesNumberColCount(table);
|
|
14
|
+
for (const [sheetCol, width] of widths) table.setColWidth(sheetCol + colOffset, width);
|
|
15
|
+
}
|
|
16
|
+
/** 把列宽条目写入 Sheet 模型(不进 undo,对称 setColWidth) */
|
|
17
|
+
function applySheetColWidths(sheet, widths) {
|
|
18
|
+
if (!sheet) return;
|
|
19
|
+
for (const [col, width] of widths) sheet.setColWidth(col, width);
|
|
20
|
+
}
|
|
21
|
+
/** 从当前网格读取指定模型列宽度;网格未就绪时返回 null */
|
|
22
|
+
function readGridColWidths(grid, cols) {
|
|
23
|
+
if (!grid) return null;
|
|
24
|
+
const table = grid.getTable();
|
|
25
|
+
const colOffset = seriesNumberColCount(table);
|
|
26
|
+
return cols.map((sheetCol) => [sheetCol, table.getColWidth(sheetCol + colOffset)]);
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { applyGridColWidths, applySheetColWidths, readGridColWidths };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
//#region src/components/report/designer/conditional-rules/helpers.ts
|
|
2
|
+
const OPERATOR_LABELS = {
|
|
3
|
+
gt: "大于",
|
|
4
|
+
gte: "大于等于",
|
|
5
|
+
lt: "小于",
|
|
6
|
+
lte: "小于等于",
|
|
7
|
+
eq: "等于",
|
|
8
|
+
between: "介于",
|
|
9
|
+
contains: "包含"
|
|
10
|
+
};
|
|
11
|
+
const RULE_SCOPE_OPTIONS = [{
|
|
12
|
+
value: "cell",
|
|
13
|
+
label: "本格"
|
|
14
|
+
}, {
|
|
15
|
+
value: "row",
|
|
16
|
+
label: "整行"
|
|
17
|
+
}];
|
|
18
|
+
/** 求值字段下拉:缺省项表示本格绑定字段 */
|
|
19
|
+
function ruleEvalFieldOptions(bindingField, datasetFields) {
|
|
20
|
+
return [{
|
|
21
|
+
value: "",
|
|
22
|
+
label: "本格字段"
|
|
23
|
+
}, ...datasetFields.filter((field) => field.name !== bindingField).map((field) => ({
|
|
24
|
+
value: field.name,
|
|
25
|
+
label: field.label || field.name
|
|
26
|
+
}))];
|
|
27
|
+
}
|
|
28
|
+
/** 按规则所选求值字段解析字段类型(运算符映射用) */
|
|
29
|
+
function resolveEvalFieldType(rule, bindingField, datasetFields) {
|
|
30
|
+
const fieldName = rule.field ?? bindingField;
|
|
31
|
+
return datasetFields.find((field) => field.name === fieldName)?.type ?? "number";
|
|
32
|
+
}
|
|
33
|
+
const NUMERIC_OPERATORS = [
|
|
34
|
+
"gt",
|
|
35
|
+
"gte",
|
|
36
|
+
"lt",
|
|
37
|
+
"lte",
|
|
38
|
+
"eq",
|
|
39
|
+
"between"
|
|
40
|
+
];
|
|
41
|
+
const STRING_OPERATORS = ["eq", "contains"];
|
|
42
|
+
let draftIdSeq = 0;
|
|
43
|
+
function nextDraftId() {
|
|
44
|
+
draftIdSeq += 1;
|
|
45
|
+
return `rule-${draftIdSeq}`;
|
|
46
|
+
}
|
|
47
|
+
/** 按字段类型返回可用运算符 */
|
|
48
|
+
function operatorsForFieldType(fieldType) {
|
|
49
|
+
return (fieldType === "string" ? STRING_OPERATORS : NUMERIC_OPERATORS).map((value) => ({
|
|
50
|
+
value,
|
|
51
|
+
label: OPERATOR_LABELS[value]
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
function isNumericFieldType(fieldType) {
|
|
55
|
+
return fieldType === "number" || fieldType === "date";
|
|
56
|
+
}
|
|
57
|
+
function defaultRuleValue(operator, fieldType) {
|
|
58
|
+
if (operator === "between") return isNumericFieldType(fieldType) ? [0, 100] : ["", ""];
|
|
59
|
+
if (operator === "contains" || operator === "eq" && fieldType === "string") return "";
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
function defaultRuleStyle() {
|
|
63
|
+
return {
|
|
64
|
+
fill: { color: "#FEF3C7" },
|
|
65
|
+
font: { color: "#B45309" }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function createDraftItem(rule, fieldType = "number", _bindingField) {
|
|
69
|
+
if (rule) return {
|
|
70
|
+
id: nextDraftId(),
|
|
71
|
+
rule: cloneRule(rule)
|
|
72
|
+
};
|
|
73
|
+
const operator = operatorsForFieldType(fieldType)[0]?.value ?? "eq";
|
|
74
|
+
return {
|
|
75
|
+
id: nextDraftId(),
|
|
76
|
+
rule: {
|
|
77
|
+
operator,
|
|
78
|
+
value: defaultRuleValue(operator, fieldType),
|
|
79
|
+
style: defaultRuleStyle()
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function initDraftFromRules(rules, fieldType, bindingField) {
|
|
84
|
+
if (rules.length === 0) return [];
|
|
85
|
+
return rules.map((rule) => createDraftItem(rule, fieldType, bindingField));
|
|
86
|
+
}
|
|
87
|
+
function cloneRule(rule) {
|
|
88
|
+
return {
|
|
89
|
+
operator: rule.operator,
|
|
90
|
+
value: cloneRuleValue(rule.value),
|
|
91
|
+
field: rule.field,
|
|
92
|
+
scope: rule.scope,
|
|
93
|
+
style: {
|
|
94
|
+
...rule.style,
|
|
95
|
+
fill: rule.style.fill ? { ...rule.style.fill } : void 0,
|
|
96
|
+
font: rule.style.font ? { ...rule.style.font } : void 0
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function cloneRuleValue(value) {
|
|
101
|
+
if (Array.isArray(value)) return [...value];
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
function cloneRulesFromDraft(items) {
|
|
105
|
+
return items.map((item) => cloneRule(item.rule));
|
|
106
|
+
}
|
|
107
|
+
/** 运算符切换时重置比较值为合理缺省 */
|
|
108
|
+
function coerceValueForOperator(operator, fieldType, current) {
|
|
109
|
+
if (operator === "between") {
|
|
110
|
+
if (Array.isArray(current) && current.length === 2) return [...current];
|
|
111
|
+
return defaultRuleValue("between", fieldType);
|
|
112
|
+
}
|
|
113
|
+
if (operator === "contains") return typeof current === "string" ? current : "";
|
|
114
|
+
if (isNumericFieldType(fieldType)) {
|
|
115
|
+
const n = typeof current === "number" && Number.isFinite(current) ? current : Number(current);
|
|
116
|
+
return Number.isFinite(n) ? n : 0;
|
|
117
|
+
}
|
|
118
|
+
return typeof current === "string" ? current : "";
|
|
119
|
+
}
|
|
120
|
+
function toDisplayString(value) {
|
|
121
|
+
if (typeof value === "string") return value;
|
|
122
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
123
|
+
return "";
|
|
124
|
+
}
|
|
125
|
+
function readBetweenValue(value, index, fieldType) {
|
|
126
|
+
const raw = (Array.isArray(value) && value.length === 2 ? value : defaultRuleValue("between", fieldType))[index];
|
|
127
|
+
if (isNumericFieldType(fieldType)) {
|
|
128
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
129
|
+
return Number.isFinite(n) ? n : 0;
|
|
130
|
+
}
|
|
131
|
+
return typeof raw === "string" ? raw : toDisplayString(raw);
|
|
132
|
+
}
|
|
133
|
+
function writeBetweenValue(value, index, next, fieldType) {
|
|
134
|
+
const pair = [readBetweenValue(value, 0, fieldType), readBetweenValue(value, 1, fieldType)];
|
|
135
|
+
pair[index] = next;
|
|
136
|
+
return pair;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { OPERATOR_LABELS, RULE_SCOPE_OPTIONS, cloneRule, cloneRulesFromDraft, coerceValueForOperator, createDraftItem, defaultRuleStyle, defaultRuleValue, initDraftFromRules, isNumericFieldType, operatorsForFieldType, readBetweenValue, resolveEvalFieldType, ruleEvalFieldOptions, writeBetweenValue };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { readCellOverlayRect, useGridOverlaySync } from "./use-grid-overlay.js";
|
|
2
|
+
import { computed, createCommentVNode, createElementBlock, defineComponent, normalizeClass, normalizeStyle, openBlock, ref, toDisplayString, toRef, unref } from "vue";
|
|
3
|
+
import { bem } from "@veltra/utils";
|
|
4
|
+
//#region src/components/report/designer/drop-highlight-overlay.vue
|
|
5
|
+
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
6
|
+
name: "UReportDropHighlightOverlay",
|
|
7
|
+
__name: "drop-highlight-overlay",
|
|
8
|
+
props: {
|
|
9
|
+
cell: {},
|
|
10
|
+
hostEl: {},
|
|
11
|
+
getGrid: { type: Function },
|
|
12
|
+
dragging: { type: Boolean },
|
|
13
|
+
fallbackLabel: {}
|
|
14
|
+
},
|
|
15
|
+
setup(__props) {
|
|
16
|
+
const props = __props;
|
|
17
|
+
const cls = bem("report-drop-highlight");
|
|
18
|
+
const hostEl = toRef(props, "hostEl");
|
|
19
|
+
const rectLeft = ref(0);
|
|
20
|
+
const rectTop = ref(0);
|
|
21
|
+
const rectWidth = ref(0);
|
|
22
|
+
const rectHeight = ref(0);
|
|
23
|
+
const inView = ref(false);
|
|
24
|
+
const visible = computed(() => !!props.cell && inView.value);
|
|
25
|
+
const showFallback = computed(() => props.dragging && !props.cell);
|
|
26
|
+
const highlightStyle = computed(() => ({
|
|
27
|
+
left: `${rectLeft.value}px`,
|
|
28
|
+
top: `${rectTop.value}px`,
|
|
29
|
+
width: `${rectWidth.value}px`,
|
|
30
|
+
height: `${rectHeight.value}px`
|
|
31
|
+
}));
|
|
32
|
+
function updateHighlight() {
|
|
33
|
+
const cell = props.cell;
|
|
34
|
+
const host = props.hostEl;
|
|
35
|
+
if (!cell || !host) {
|
|
36
|
+
inView.value = false;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const rect = readCellOverlayRect(cell, host, props.getGrid);
|
|
40
|
+
if (!rect) {
|
|
41
|
+
inView.value = false;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
inView.value = true;
|
|
45
|
+
rectLeft.value = Math.round(rect.left);
|
|
46
|
+
rectTop.value = Math.round(rect.top);
|
|
47
|
+
rectWidth.value = Math.round(rect.width);
|
|
48
|
+
rectHeight.value = Math.round(rect.height);
|
|
49
|
+
}
|
|
50
|
+
useGridOverlaySync({
|
|
51
|
+
hostEl,
|
|
52
|
+
getGrid: () => props.getGrid(),
|
|
53
|
+
watchSources: () => [
|
|
54
|
+
props.cell?.row,
|
|
55
|
+
props.cell?.col,
|
|
56
|
+
props.hostEl,
|
|
57
|
+
props.dragging
|
|
58
|
+
],
|
|
59
|
+
update: updateHighlight
|
|
60
|
+
});
|
|
61
|
+
return (_ctx, _cache) => {
|
|
62
|
+
return __props.cell && visible.value ? (openBlock(), createElementBlock("div", {
|
|
63
|
+
key: 0,
|
|
64
|
+
class: normalizeClass(unref(cls).b),
|
|
65
|
+
style: normalizeStyle(highlightStyle.value),
|
|
66
|
+
"aria-hidden": "true"
|
|
67
|
+
}, null, 6)) : showFallback.value ? (openBlock(), createElementBlock("div", {
|
|
68
|
+
key: 1,
|
|
69
|
+
class: normalizeClass(unref(cls).e("fallback")),
|
|
70
|
+
role: "status"
|
|
71
|
+
}, " 松开将绑定到当前选区 " + toDisplayString(__props.fallbackLabel), 3)) : createCommentVNode("v-if", true);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
//#endregion
|
|
76
|
+
export { _sfc_main as default };
|