@veltra/sheet 2.3.0 → 2.3.2
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 +1 -1
- package/dist/components/report/hub-dataset-editor.js +16 -1
- package/dist/components/report/use-report-designer.js +8 -4
- package/dist/components/sheet/popups/fill-color-popup.js +2 -1
- package/dist/components/sheet/popups/import.worker.js +2 -2
- package/dist/components/sheet/use-sheet-grid.js +1 -1
- package/dist/report/binding.js +7 -5
- package/dist/types/sheet.d.ts +1 -1
- package/package.json +16 -7
- package/src/components/report/binding-badge.ts +1 -1
- package/src/components/report/designer/cell-coords.ts +2 -1
- package/src/components/report/designer/drop-highlight-overlay.vue +2 -1
- package/src/components/report/designer/float-panel.vue +2 -1
- package/src/components/report/designer/topology-overlay.vue +2 -1
- package/src/components/report/designer/use-grid-overlay.ts +2 -1
- package/src/components/report/hub-dataset-editor.vue +19 -1
- package/src/components/report/report-designer.vue +2 -1
- package/src/components/report/use-report-designer.ts +1 -1
- package/src/components/sheet/popups/fill-color-popup.vue +3 -2
- package/src/components/sheet/popups/import.worker.ts +2 -2
- package/src/components/sheet/use-sheet-grid.ts +1 -1
- package/src/index.ts +2 -2
- package/src/report/__test__/export-xlsx.test.ts +2 -2
- package/src/types/sheet.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { formatBindingPlaceholderParts, inferReportPreset } from "../../report/binding.js";
|
|
2
|
-
import { CustomLayout } from "@veltra/sheet-core";
|
|
2
|
+
import { CustomLayout } from "@veltra/sheet-core/grid";
|
|
3
3
|
//#region src/components/report/binding-badge.ts
|
|
4
4
|
const REPORT_PRESET_BADGE_COLORS = {
|
|
5
5
|
groupHeader: {
|
|
@@ -66,11 +66,25 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
66
66
|
resetPreview();
|
|
67
67
|
runDescribe();
|
|
68
68
|
}, { immediate: true });
|
|
69
|
+
/** 立即把草稿 SQL 落入数据集(v-model 实时、change 失焦才发且提交有 debounce),供预览同步拿到最新 SQL */
|
|
70
|
+
function flushSqlDraft(datasetId) {
|
|
71
|
+
if (sqlTimer) {
|
|
72
|
+
clearTimeout(sqlTimer);
|
|
73
|
+
sqlTimer = void 0;
|
|
74
|
+
}
|
|
75
|
+
const current = dataset.value;
|
|
76
|
+
if (!current || current.sql === sqlDraft.value) return;
|
|
77
|
+
props.hub.updateDataset(datasetId, { sql: sqlDraft.value });
|
|
78
|
+
runDescribe();
|
|
79
|
+
}
|
|
69
80
|
function onSqlChange(value) {
|
|
70
81
|
sqlDraft.value = value;
|
|
82
|
+
const datasetId = props.datasetId;
|
|
71
83
|
if (sqlTimer) clearTimeout(sqlTimer);
|
|
72
84
|
sqlTimer = setTimeout(() => {
|
|
73
|
-
|
|
85
|
+
sqlTimer = void 0;
|
|
86
|
+
if (props.datasetId !== datasetId) return;
|
|
87
|
+
props.hub.updateDataset(datasetId, { sql: value });
|
|
74
88
|
runDescribe();
|
|
75
89
|
}, 280);
|
|
76
90
|
}
|
|
@@ -104,6 +118,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
104
118
|
}));
|
|
105
119
|
});
|
|
106
120
|
async function runPreview() {
|
|
121
|
+
flushSqlDraft(props.datasetId);
|
|
107
122
|
previewing.value = true;
|
|
108
123
|
previewError.value = "";
|
|
109
124
|
const result = await props.hub.previewDataset(props.datasetId);
|
|
@@ -155,10 +155,14 @@ function useReportDesigner(options) {
|
|
|
155
155
|
if (("aggregate" in patch || "expand" in patch) && !("preset" in patch) && !presetStillApplies(next)) delete next.preset;
|
|
156
156
|
if (patch.preset === "subtotal") {
|
|
157
157
|
const inferred = inferParentsForPreset(cell, "subtotal", getBindingAt);
|
|
158
|
-
if (parentNeedsCorrection(next.rowParent))
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
if (parentNeedsCorrection(next.rowParent)) {
|
|
159
|
+
if (inferred.rowParent) next.rowParent = inferred.rowParent;
|
|
160
|
+
else delete next.rowParent;
|
|
161
|
+
}
|
|
162
|
+
if (parentNeedsCorrection(next.colParent)) {
|
|
163
|
+
if (inferred.colParent) next.colParent = inferred.colParent;
|
|
164
|
+
else delete next.colParent;
|
|
165
|
+
}
|
|
162
166
|
}
|
|
163
167
|
workbook.value.activeSheet.setCellMeta(cell, REPORT_META_NAMESPACE, next);
|
|
164
168
|
}
|
|
@@ -13,7 +13,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
13
13
|
*/
|
|
14
14
|
const props = __props;
|
|
15
15
|
/** 填充颜色('' = 无填充) */
|
|
16
|
-
const fillColor = ref(
|
|
16
|
+
const fillColor = ref();
|
|
17
17
|
onMounted(() => {
|
|
18
18
|
const active = props.context.getSelection().activeCell;
|
|
19
19
|
const style = active ? props.context.getEffectiveStyle(active) : void 0;
|
|
@@ -21,6 +21,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
21
21
|
});
|
|
22
22
|
/** 填充颜色变化('' = 无填充:清除 fill 保留边框) */
|
|
23
23
|
function applyFillColor(color) {
|
|
24
|
+
fillColor.value = color;
|
|
24
25
|
const range = currentRange(props.context);
|
|
25
26
|
if (!range) return;
|
|
26
27
|
props.context.applyStyle(range, color ? { fill: { color } } : { fill: {} });
|
|
@@ -3,8 +3,8 @@ self.onmessage = (e) => {
|
|
|
3
3
|
const { buffer } = e.data;
|
|
4
4
|
(async () => {
|
|
5
5
|
try {
|
|
6
|
-
const [{ readXlsx }, { buildWorkbookFromHucre }] = await Promise.all([import("hucre/xlsx"), import("@veltra/sheet-core/core/io/import")]);
|
|
7
|
-
const hucreWb = await readXlsx(new Uint8Array(buffer),
|
|
6
|
+
const [{ readXlsx }, { buildWorkbookFromHucre, XLSX_READ_OPTIONS }] = await Promise.all([import("hucre/xlsx"), import("@veltra/sheet-core/core/io/import")]);
|
|
7
|
+
const hucreWb = await readXlsx(new Uint8Array(buffer), XLSX_READ_OPTIONS);
|
|
8
8
|
let lastPercent = -1;
|
|
9
9
|
const wb = buildWorkbookFromHucre(hucreWb, (done, total) => {
|
|
10
10
|
const percent = total > 0 ? Math.floor(done / total * 10) : 10;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { buildBodyMenus, buildColHeaderMenus, buildRowHeaderMenus, ensureContextMenuSelection, resolveRenderSize } from "./sheet-context-menu.js";
|
|
2
2
|
import { onBeforeUnmount, onMounted, watch } from "vue";
|
|
3
3
|
import { contextmenu } from "@veltra/desktop";
|
|
4
|
-
import { SheetGrid } from "@veltra/sheet-core/grid
|
|
4
|
+
import { SheetGrid } from "@veltra/sheet-core/grid";
|
|
5
5
|
//#region src/components/sheet/use-sheet-grid.ts
|
|
6
6
|
/**
|
|
7
7
|
* 缓存容量:最近 N 个 sheet 的 SheetGrid 实例常驻(tab 来回切换零重建)。
|
package/dist/report/binding.js
CHANGED
|
@@ -266,11 +266,13 @@ function inferParentsForPreset(addr, preset, getBindingAt) {
|
|
|
266
266
|
const result = {};
|
|
267
267
|
if (rowSubtotal && rowParent) result.rowParent = rowParent;
|
|
268
268
|
if (columnSubtotal && colParent) result.colParent = colParent;
|
|
269
|
-
if (!rowSubtotal && !columnSubtotal)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
if (!rowSubtotal && !columnSubtotal) {
|
|
270
|
+
if (belowBand && rowParent) result.rowParent = rowParent;
|
|
271
|
+
else if (rightOfBand && colParent) result.colParent = colParent;
|
|
272
|
+
else {
|
|
273
|
+
if (rowParent) result.rowParent = rowParent;
|
|
274
|
+
if (colParent) result.colParent = colParent;
|
|
275
|
+
}
|
|
274
276
|
}
|
|
275
277
|
return result;
|
|
276
278
|
}
|
package/dist/types/sheet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SheetContext } from "../tools/context.js";
|
|
2
2
|
import { ComputedRef } from "vue";
|
|
3
3
|
import { DeconstructValue } from "@veltra/utils";
|
|
4
|
-
import { ResolveCellRenderer, ResolveCellStyleHook, ResolveDisplayValue, SheetGrid } from "@veltra/sheet-core/grid
|
|
4
|
+
import { ResolveCellRenderer, ResolveCellStyleHook, ResolveDisplayValue, SheetGrid } from "@veltra/sheet-core/grid";
|
|
5
5
|
import { Workbook } from "@veltra/sheet-core/core/workbook";
|
|
6
6
|
import { Sheet } from "@veltra/sheet-core/core/sheet";
|
|
7
7
|
//#region src/types/sheet.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veltra/sheet",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
|
+
"homepage": "https://github.com/cabinet-fe/ultra-ui#readme",
|
|
5
|
+
"bugs": {
|
|
6
|
+
"url": "https://github.com/cabinet-fe/ultra-ui/issues"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/cabinet-fe/ultra-ui",
|
|
11
|
+
"directory": "packages/sheet"
|
|
12
|
+
},
|
|
4
13
|
"files": [
|
|
5
14
|
"dist",
|
|
6
15
|
"src"
|
|
@@ -25,17 +34,17 @@
|
|
|
25
34
|
}
|
|
26
35
|
},
|
|
27
36
|
"dependencies": {
|
|
28
|
-
"hucre": "^1.
|
|
37
|
+
"hucre": "^1.1.0"
|
|
29
38
|
},
|
|
30
39
|
"peerDependencies": {
|
|
31
40
|
"@cat-kit/core": ">=1.1.8",
|
|
32
41
|
"@cat-kit/fe": ">=1.1.8",
|
|
33
|
-
"@veltra/compositions": "^1.6.
|
|
34
|
-
"@veltra/desktop": "^1.6.
|
|
42
|
+
"@veltra/compositions": "^1.6.4",
|
|
43
|
+
"@veltra/desktop": "^1.6.4",
|
|
35
44
|
"@veltra/icons": "^1.5.0",
|
|
36
|
-
"@veltra/sheet-core": "^2.3.
|
|
37
|
-
"@veltra/styles": "^1.6.
|
|
38
|
-
"@veltra/utils": "^1.6.
|
|
45
|
+
"@veltra/sheet-core": "^2.3.2",
|
|
46
|
+
"@veltra/styles": "^1.6.4",
|
|
47
|
+
"@veltra/utils": "^1.6.4",
|
|
39
48
|
"vue": ">=3.5.41"
|
|
40
49
|
}
|
|
41
50
|
}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
CustomLayout,
|
|
4
4
|
type ResolveCellRenderer,
|
|
5
5
|
type ResolveCellStyleHook
|
|
6
|
-
} from '@veltra/sheet-core'
|
|
6
|
+
} from '@veltra/sheet-core/grid'
|
|
7
7
|
|
|
8
8
|
import { formatBindingPlaceholderParts, inferReportPreset } from '../../report/binding'
|
|
9
9
|
import type { ReportBinding, ReportPreset } from '../../report/types'
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script lang="ts" setup>
|
|
9
|
-
import type { CellAddress
|
|
9
|
+
import type { CellAddress } from '@veltra/sheet-core'
|
|
10
|
+
import type { SheetGrid } from '@veltra/sheet-core/grid'
|
|
10
11
|
import { bem } from '@veltra/utils'
|
|
11
12
|
import { computed, ref, toRef } from 'vue'
|
|
12
13
|
|
|
@@ -150,7 +150,8 @@
|
|
|
150
150
|
|
|
151
151
|
<script lang="ts" setup>
|
|
152
152
|
import { UButton, URadioGroup, USelect, USwitch } from '@veltra/desktop'
|
|
153
|
-
import type { CellAddress
|
|
153
|
+
import type { CellAddress } from '@veltra/sheet-core'
|
|
154
|
+
import type { SheetGrid } from '@veltra/sheet-core/grid'
|
|
154
155
|
import { bem } from '@veltra/utils'
|
|
155
156
|
import { computed, nextTick, ref, toRef, watch } from 'vue'
|
|
156
157
|
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script lang="ts" setup>
|
|
38
|
-
import type { CellAddress
|
|
38
|
+
import type { CellAddress } from '@veltra/sheet-core'
|
|
39
|
+
import type { SheetGrid } from '@veltra/sheet-core/grid'
|
|
39
40
|
import { bem } from '@veltra/utils'
|
|
40
41
|
import { computed, ref, toRef } from 'vue'
|
|
41
42
|
|
|
@@ -219,11 +219,27 @@ watch(
|
|
|
219
219
|
{ immediate: true }
|
|
220
220
|
)
|
|
221
221
|
|
|
222
|
+
/** 立即把草稿 SQL 落入数据集(v-model 实时、change 失焦才发且提交有 debounce),供预览同步拿到最新 SQL */
|
|
223
|
+
function flushSqlDraft(datasetId: string): void {
|
|
224
|
+
if (sqlTimer) {
|
|
225
|
+
clearTimeout(sqlTimer)
|
|
226
|
+
sqlTimer = undefined
|
|
227
|
+
}
|
|
228
|
+
const current = dataset.value
|
|
229
|
+
if (!current || current.sql === sqlDraft.value) return
|
|
230
|
+
props.hub.updateDataset(datasetId, { sql: sqlDraft.value })
|
|
231
|
+
void runDescribe()
|
|
232
|
+
}
|
|
233
|
+
|
|
222
234
|
function onSqlChange(value: string): void {
|
|
223
235
|
sqlDraft.value = value
|
|
236
|
+
const datasetId = props.datasetId
|
|
224
237
|
if (sqlTimer) clearTimeout(sqlTimer)
|
|
225
238
|
sqlTimer = setTimeout(() => {
|
|
226
|
-
|
|
239
|
+
sqlTimer = undefined
|
|
240
|
+
// 防抖窗口内切换了数据集则丢弃,避免把旧草稿写进新数据集
|
|
241
|
+
if (props.datasetId !== datasetId) return
|
|
242
|
+
props.hub.updateDataset(datasetId, { sql: value })
|
|
227
243
|
void runDescribe()
|
|
228
244
|
}, 280)
|
|
229
245
|
}
|
|
@@ -271,6 +287,8 @@ const schemaRows = computed(() => {
|
|
|
271
287
|
// ---- 记录预览(按参数默认值经连接器取数) ----
|
|
272
288
|
|
|
273
289
|
async function runPreview(): Promise<void> {
|
|
290
|
+
// 编辑器 change 仅在失焦时触发且提交有 debounce,先同步落草稿 SQL,避免用旧 SQL 取数
|
|
291
|
+
flushSqlDraft(props.datasetId)
|
|
274
292
|
previewing.value = true
|
|
275
293
|
previewError.value = ''
|
|
276
294
|
const result = await props.hub.previewDataset(props.datasetId)
|
|
@@ -146,8 +146,9 @@
|
|
|
146
146
|
|
|
147
147
|
<script lang="ts" setup>
|
|
148
148
|
import { UButton, UDrawer } from '@veltra/desktop'
|
|
149
|
-
import type { CellAddress
|
|
149
|
+
import type { CellAddress } from '@veltra/sheet-core'
|
|
150
150
|
import { Workbook } from '@veltra/sheet-core'
|
|
151
|
+
import type { SheetGrid } from '@veltra/sheet-core/grid'
|
|
151
152
|
import { bem } from '@veltra/utils'
|
|
152
153
|
import { computed, nextTick, onScopeDispose, ref, shallowRef, useTemplateRef, watch } from 'vue'
|
|
153
154
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CellAddress } from '@veltra/sheet-core'
|
|
2
|
-
import type { ResolveCellRenderer, ResolveCellStyleHook } from '@veltra/sheet-core'
|
|
3
2
|
import { Workbook } from '@veltra/sheet-core'
|
|
3
|
+
import type { ResolveCellRenderer, ResolveCellStyleHook } from '@veltra/sheet-core/grid'
|
|
4
4
|
import { computed, onScopeDispose, ref, watch, type ComputedRef, type Ref } from 'vue'
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -21,7 +21,7 @@ const props = defineProps<{
|
|
|
21
21
|
}>()
|
|
22
22
|
|
|
23
23
|
/** 填充颜色('' = 无填充) */
|
|
24
|
-
const fillColor = ref(
|
|
24
|
+
const fillColor = ref<string>()
|
|
25
25
|
|
|
26
26
|
// 打开时初始化为活动格当前填充色
|
|
27
27
|
onMounted(() => {
|
|
@@ -31,7 +31,8 @@ onMounted(() => {
|
|
|
31
31
|
})
|
|
32
32
|
|
|
33
33
|
/** 填充颜色变化('' = 无填充:清除 fill 保留边框) */
|
|
34
|
-
function applyFillColor(color
|
|
34
|
+
function applyFillColor(color?: string): void {
|
|
35
|
+
fillColor.value = color
|
|
35
36
|
const range = currentRange(props.context)
|
|
36
37
|
if (!range) return
|
|
37
38
|
props.context.applyStyle(range, color ? { fill: { color } } : { fill: {} })
|
|
@@ -30,11 +30,11 @@ self.onmessage = (e: MessageEvent<{ buffer: ArrayBuffer }>): void => {
|
|
|
30
30
|
const { buffer } = e.data
|
|
31
31
|
void (async () => {
|
|
32
32
|
try {
|
|
33
|
-
const [{ readXlsx }, { buildWorkbookFromHucre }] = await Promise.all([
|
|
33
|
+
const [{ readXlsx }, { buildWorkbookFromHucre, XLSX_READ_OPTIONS }] = await Promise.all([
|
|
34
34
|
import('hucre/xlsx'),
|
|
35
35
|
import('@veltra/sheet-core/core/io/import')
|
|
36
36
|
])
|
|
37
|
-
const hucreWb = await readXlsx(new Uint8Array(buffer),
|
|
37
|
+
const hucreWb = await readXlsx(new Uint8Array(buffer), XLSX_READ_OPTIONS)
|
|
38
38
|
// 分片构建:按 10% 粒度回报进度(避免 196 条/秒的消息风暴与文字跳变过快;
|
|
39
39
|
// 模型构建段约 1s,10 次更新肉眼可见数字推进)
|
|
40
40
|
let lastPercent = -1
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { contextmenu } from '@veltra/desktop'
|
|
2
2
|
import type { CellAddress, CellRange } from '@veltra/sheet-core/core/address'
|
|
3
3
|
import type { Sheet } from '@veltra/sheet-core/core/sheet'
|
|
4
|
-
import { SheetGrid, type SheetGridContextMenuInfo } from '@veltra/sheet-core/grid
|
|
4
|
+
import { SheetGrid, type SheetGridContextMenuInfo } from '@veltra/sheet-core/grid'
|
|
5
5
|
import { onBeforeUnmount, onMounted, watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
import type { SheetContext } from '../../tools/context'
|
package/src/index.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import './tools/builtin'
|
|
5
5
|
|
|
6
6
|
// 数据模型 / 渲染内核在 @veltra/sheet-core(独立发包)。本包**不做** re-export:
|
|
7
|
-
// core API(Workbook / Sheet /
|
|
8
|
-
//
|
|
7
|
+
// core API(Workbook / Sheet / 公式 / IO 等)一律 `from '@veltra/sheet-core'` 直导;
|
|
8
|
+
// SheetGrid 走 `@veltra/sheet-core/grid`;白名单外符号深导入其子路径。
|
|
9
9
|
// 本入口只导出 sheet 自有能力:组件、tools、组件类型。
|
|
10
10
|
|
|
11
11
|
export { createSheetContext, type SheetContext } from './tools/context'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Sheet } from '@veltra/sheet-core'
|
|
2
|
-
import { buildWorkbookFromHucre } from '@veltra/sheet-core/core/io/import'
|
|
2
|
+
import { buildWorkbookFromHucre, XLSX_READ_OPTIONS } from '@veltra/sheet-core/core/io/import'
|
|
3
3
|
import { readXlsx } from 'hucre/xlsx'
|
|
4
4
|
import { describe, expect, it } from 'vitest'
|
|
5
5
|
|
|
@@ -69,7 +69,7 @@ describe('exportFilledReportXlsx', () => {
|
|
|
69
69
|
expect(buffer[0]).toBe(0x50)
|
|
70
70
|
expect(buffer[1]).toBe(0x4b)
|
|
71
71
|
|
|
72
|
-
const hucreWb = await readXlsx(buffer,
|
|
72
|
+
const hucreWb = await readXlsx(buffer, XLSX_READ_OPTIONS)
|
|
73
73
|
const workbook = buildWorkbookFromHucre(hucreWb)
|
|
74
74
|
const sheet = workbook.getSheets()[0]!
|
|
75
75
|
|
package/src/types/sheet.ts
CHANGED