@veltra/desktop 1.2.24 → 1.2.26
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/action/action-group.vue.d.ts +2 -2
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +2 -2
- package/dist/components/cascade/cascade.js +5 -3
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +3 -3
- package/dist/components/cascade/use-data-map.js +2 -1
- package/dist/components/cascade/use-data-map.js.map +1 -1
- package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
- package/dist/components/checkbox-group/checkbox-group.js +10 -10
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
- package/dist/components/code-editor/basic-setup.js +2 -1
- package/dist/components/code-editor/basic-setup.js.map +1 -1
- package/dist/components/code-editor/code-editor.js +136 -79
- package/dist/components/code-editor/code-editor.js.map +1 -1
- package/dist/components/code-editor/code-editor.vue.d.ts +10 -2
- package/dist/components/code-editor/shell-extension.js +139 -0
- package/dist/components/code-editor/shell-extension.js.map +1 -0
- package/dist/components/code-editor/style.js +1 -0
- package/dist/components/code-editor/style2.css +15 -11
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
- package/dist/components/multi-select/multi-select.js +31 -36
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +2 -2
- package/dist/components/multi-tree-select/multi-tree-select.js +8 -6
- package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +2 -2
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/progress-nodes/progress-nodes.js +6 -4
- package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
- package/dist/components/radio-group/radio-group.js +8 -6
- package/dist/components/radio-group/radio-group.js.map +1 -1
- package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
- package/dist/components/select/select.js +13 -13
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue.d.ts +2 -2
- package/dist/components/select/use-options.js +7 -4
- package/dist/components/select/use-options.js.map +1 -1
- package/dist/components/steps/steps.js +3 -2
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/table/allocate-column-widths.js +32 -0
- package/dist/components/table/allocate-column-widths.js.map +1 -0
- package/dist/components/table/use-col-resize.js +2 -10
- package/dist/components/table/use-col-resize.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tree/use-check.js +2 -1
- package/dist/components/tree/use-check.js.map +1 -1
- package/dist/components/tree/use-select.js +3 -1
- package/dist/components/tree/use-select.js.map +1 -1
- package/dist/components/tree/use-tree-nodes.js +4 -1
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.js +6 -4
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +2 -2
- package/dist/components/watermark/watermark.vue.d.ts +1 -1
- package/dist/node_modules/.bun/@codemirror_commands@6.10.4/node_modules/@codemirror/commands/dist/index.js +12 -1
- package/dist/node_modules/.bun/@codemirror_commands@6.10.4/node_modules/@codemirror/commands/dist/index.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/types/code-editor.d.ts +13 -2
- package/package.json +6 -6
- package/src/components/cascade/cascade.vue +6 -3
- package/src/components/cascade/use-data-map.ts +3 -2
- package/src/components/checkbox-group/checkbox-group.vue +10 -8
- package/src/components/code-editor/basic-setup.ts +3 -1
- package/src/components/code-editor/code-editor.vue +154 -96
- package/src/components/code-editor/shell-extension.ts +199 -0
- package/src/components/code-editor/style.scss +20 -13
- package/src/components/code-editor/style.ts +1 -0
- package/src/components/multi-select/multi-select.vue +31 -30
- package/src/components/multi-tree-select/multi-tree-select.vue +5 -2
- package/src/components/progress-nodes/progress-nodes.vue +7 -4
- package/src/components/radio-group/radio-group.vue +5 -1
- package/src/components/select/select.vue +13 -11
- package/src/components/select/use-options.ts +7 -4
- package/src/components/steps/steps.vue +3 -1
- package/src/components/table/__test__/col-width.test.ts +77 -0
- package/src/components/table/allocate-column-widths.ts +38 -0
- package/src/components/table/use-col-resize.ts +2 -19
- package/src/components/tree/use-check.ts +2 -1
- package/src/components/tree/use-select.ts +3 -1
- package/src/components/tree/use-tree-nodes.ts +5 -9
- package/src/components/tree-select/tree-select.vue +7 -4
- package/src/types/code-editor.ts +13 -2
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import type { TableColumn } from '../../../types'
|
|
4
|
+
import { allocateLeafColumnWidths } from '../allocate-column-widths'
|
|
5
|
+
import { ColumnNode } from '../node/col'
|
|
6
|
+
|
|
7
|
+
function createLeaf(column: TableColumn): ColumnNode {
|
|
8
|
+
return new ColumnNode(column, 0, 0)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('allocateLeafColumnWidths', () => {
|
|
12
|
+
it('fixed right 操作列未设 width 时保持 minWidth,不吞剩余空间', () => {
|
|
13
|
+
const name = createLeaf({ key: 'name', name: '姓名', width: 200 })
|
|
14
|
+
const age = createLeaf({ key: 'age', name: '年龄', width: 200 })
|
|
15
|
+
const action = createLeaf({ key: 'action', name: '操作', fixed: 'right' })
|
|
16
|
+
// 模拟旧算法曾把操作列撑大
|
|
17
|
+
action.data.width = 800
|
|
18
|
+
|
|
19
|
+
allocateLeafColumnWidths([name, age, action], 1000)
|
|
20
|
+
|
|
21
|
+
expect(name.width).toBe(200)
|
|
22
|
+
expect(age.width).toBe(200)
|
|
23
|
+
expect(action.data.width).toBeUndefined()
|
|
24
|
+
expect(action.width).toBe(100)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('多个非 fixed 无 width 列均分剩余宽度', () => {
|
|
28
|
+
const a = createLeaf({ key: 'a', name: 'A', width: 200 })
|
|
29
|
+
const b = createLeaf({ key: 'b', name: 'B' })
|
|
30
|
+
const c = createLeaf({ key: 'c', name: 'C' })
|
|
31
|
+
|
|
32
|
+
// totalBase = 200 + 100 + 100 = 400,剩余 600,每列 +300
|
|
33
|
+
allocateLeafColumnWidths([a, b, c], 1000)
|
|
34
|
+
|
|
35
|
+
expect(a.width).toBe(200)
|
|
36
|
+
expect(b.width).toBe(400)
|
|
37
|
+
expect(c.width).toBe(400)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('fixed left 未设 width 时同样不参与均分', () => {
|
|
41
|
+
const name = createLeaf({ key: 'name', name: '姓名', fixed: 'left' })
|
|
42
|
+
const age = createLeaf({ key: 'age', name: '年龄' })
|
|
43
|
+
const score = createLeaf({ key: 'score', name: '分数' })
|
|
44
|
+
|
|
45
|
+
// totalBase = 100 + 100 + 100 = 300,剩余 700 只分给 age/score
|
|
46
|
+
allocateLeafColumnWidths([name, age, score], 1000)
|
|
47
|
+
|
|
48
|
+
expect(name.data.width).toBeUndefined()
|
|
49
|
+
expect(name.width).toBe(100)
|
|
50
|
+
expect(age.width).toBe(450)
|
|
51
|
+
expect(score.width).toBe(450)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('explicitWidth 列宽度不变', () => {
|
|
55
|
+
const locked = createLeaf({ key: 'locked', name: '锁定', width: 180 })
|
|
56
|
+
locked.explicitWidth = true
|
|
57
|
+
const grow = createLeaf({ key: 'grow', name: '弹性' })
|
|
58
|
+
|
|
59
|
+
allocateLeafColumnWidths([locked, grow], 500)
|
|
60
|
+
|
|
61
|
+
expect(locked.width).toBe(180)
|
|
62
|
+
// totalBase = 180 + 100 = 280,剩余 220 全给 grow
|
|
63
|
+
expect(grow.width).toBe(320)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('无剩余空间时 grow 列回落到 minWidth', () => {
|
|
67
|
+
const a = createLeaf({ key: 'a', name: 'A', width: 400 })
|
|
68
|
+
const b = createLeaf({ key: 'b', name: 'B' })
|
|
69
|
+
b.data.width = 300
|
|
70
|
+
|
|
71
|
+
allocateLeafColumnWidths([a, b], 450)
|
|
72
|
+
|
|
73
|
+
expect(a.width).toBe(400)
|
|
74
|
+
expect(b.data.width).toBeUndefined()
|
|
75
|
+
expect(b.width).toBe(100)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ColumnNode } from './node/col'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 按容器宽度分配叶子列宽。
|
|
5
|
+
*
|
|
6
|
+
* - `explicitWidth` 列:保持配置/拖拽锁定的宽度
|
|
7
|
+
* - `fixed` 且未显式设宽的列:保持 `minWidth`,不参与剩余宽度均分
|
|
8
|
+
* - 其余未显式设宽的列:均分容器剩余宽度
|
|
9
|
+
*/
|
|
10
|
+
export function allocateLeafColumnWidths(leafColumns: ColumnNode[], containerWidth: number): void {
|
|
11
|
+
if (!containerWidth || !leafColumns.length) return
|
|
12
|
+
|
|
13
|
+
const growColumns = leafColumns.filter((column) => !column.explicitWidth && !column.fixed)
|
|
14
|
+
// fixed 且未显式设宽:清掉可能被旧算法撑大的残留 width,回落到 minWidth
|
|
15
|
+
const fixedFlexColumns = leafColumns.filter((column) => !column.explicitWidth && column.fixed)
|
|
16
|
+
|
|
17
|
+
fixedFlexColumns.forEach((column) => {
|
|
18
|
+
column.data.width = undefined
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const explicitWidthTotal = leafColumns
|
|
22
|
+
.filter((column) => column.explicitWidth)
|
|
23
|
+
.reduce((acc, cur) => acc + (cur.width ?? cur.minWidth!), 0)
|
|
24
|
+
const growBaseTotal = growColumns.reduce((acc, cur) => acc + cur.minWidth!, 0)
|
|
25
|
+
const fixedFlexBaseTotal = fixedFlexColumns.reduce((acc, cur) => acc + cur.minWidth!, 0)
|
|
26
|
+
const totalBase = explicitWidthTotal + growBaseTotal + fixedFlexBaseTotal
|
|
27
|
+
|
|
28
|
+
if (growColumns.length > 0 && totalBase < containerWidth) {
|
|
29
|
+
const allocatedWidth = (containerWidth - totalBase) / growColumns.length
|
|
30
|
+
growColumns.forEach((column) => {
|
|
31
|
+
column.width = column.minWidth! + allocatedWidth
|
|
32
|
+
})
|
|
33
|
+
} else {
|
|
34
|
+
growColumns.forEach((column) => {
|
|
35
|
+
column.data.width = undefined
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { nextTick, provide, shallowRef, watchEffect, type ShallowRef } from 'vue'
|
|
2
2
|
|
|
3
3
|
import type { ScrollExposed } from '../../types'
|
|
4
|
+
import { allocateLeafColumnWidths } from './allocate-column-widths'
|
|
4
5
|
import { TableResizeKey } from './di'
|
|
5
6
|
import type { ColumnNode } from './node/col'
|
|
6
7
|
|
|
@@ -34,25 +35,7 @@ export function useColResize(options: Options): UseColResizeReturned {
|
|
|
34
35
|
|
|
35
36
|
if (!containerWidth || !leafColumns.value.length) return
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
const fixedWidthTotal = leafColumns.value
|
|
39
|
-
.filter((column) => column.explicitWidth)
|
|
40
|
-
.reduce((acc, cur) => acc + (cur.width ?? cur.minWidth!), 0)
|
|
41
|
-
const flexBaseTotal = flexColumns.reduce((acc, cur) => acc + cur.minWidth!, 0)
|
|
42
|
-
const totalBase = fixedWidthTotal + flexBaseTotal
|
|
43
|
-
|
|
44
|
-
// 仅未显式指定 width 的列参与剩余宽度均分;指定了 width 的列保持该宽度。
|
|
45
|
-
if (flexColumns.length > 0 && totalBase < containerWidth) {
|
|
46
|
-
const allocatedWidth = (containerWidth - totalBase) / flexColumns.length
|
|
47
|
-
|
|
48
|
-
flexColumns.forEach((column) => {
|
|
49
|
-
column.width = column.minWidth! + allocatedWidth
|
|
50
|
-
})
|
|
51
|
-
} else {
|
|
52
|
-
flexColumns.forEach((column) => {
|
|
53
|
-
column.data.width = undefined
|
|
54
|
-
})
|
|
55
|
-
}
|
|
38
|
+
allocateLeafColumnWidths(leafColumns.value, containerWidth)
|
|
56
39
|
|
|
57
40
|
const fixedLeft = leafColumns.value.filter((column) => column.fixed === 'left')
|
|
58
41
|
const fixedRight = leafColumns.value.filter((column) => column.fixed === 'right')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { dfs, o } from '@cat-kit/core'
|
|
2
|
+
import { fieldKey } from '@veltra/utils'
|
|
2
3
|
import { nextTick, watch, type ComputedRef } from 'vue'
|
|
3
4
|
|
|
4
5
|
import type { TreeEmit, TreeProps } from '../../types'
|
|
@@ -188,7 +189,7 @@ export function useCheck(options: Options): UseCheckReturned {
|
|
|
188
189
|
|
|
189
190
|
const checkedArr = Array.from(checkedData)
|
|
190
191
|
|
|
191
|
-
const valueKey = props.valueKey
|
|
192
|
+
const valueKey = fieldKey(props.valueKey, 'value')
|
|
192
193
|
const nextValues = checkedArr.map((item) => o(item).get(valueKey) as unknown)
|
|
193
194
|
|
|
194
195
|
// 与外部 checked 保持差集缓存同步,避免下一次 watch 回调把刚勾选的值又误判为“新增”。
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fieldKey } from '@veltra/utils'
|
|
1
2
|
import { nextTick, shallowRef, watch, type ComputedRef, type ShallowRef } from 'vue'
|
|
2
3
|
|
|
3
4
|
import type { TreeEmit, TreeProps } from '../../types'
|
|
@@ -55,7 +56,8 @@ export function useSelect(options: Options): UseSelectReturned {
|
|
|
55
56
|
if (node.disabled) return
|
|
56
57
|
selectedData.value = node.data === selectedData.value ? undefined : node.data
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
const valueKey = fieldKey(props.valueKey, 'value')
|
|
60
|
+
emit('update:selected', selectedData.value?.[valueKey], selectedData.value, node)
|
|
59
61
|
|
|
60
62
|
nextTick(() => {
|
|
61
63
|
selectByEvent = false
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Forest } from '@cat-kit/core'
|
|
2
|
+
import { fieldKey } from '@veltra/utils'
|
|
2
3
|
import { computed, shallowRef, triggerRef, watch, type ShallowRef, type ComputedRef } from 'vue'
|
|
3
4
|
|
|
4
5
|
import type { TreeProps } from '../../types'
|
|
@@ -36,8 +37,10 @@ export function useTreeNodes(options: Options): UseTreeNodesReturned {
|
|
|
36
37
|
const nodes = shallowRef<TreeNode[]>([])
|
|
37
38
|
|
|
38
39
|
function buildForest(): Forest<Record<string, unknown>, any> {
|
|
39
|
-
const { disabledNode, expandAll = false
|
|
40
|
+
const { disabledNode, expandAll = false } = props
|
|
40
41
|
const childrenKey = props.childrenKey ?? 'children'
|
|
42
|
+
const valueKey = fieldKey(props.valueKey, 'value')
|
|
43
|
+
const labelKey = fieldKey(props.labelKey, 'label')
|
|
41
44
|
|
|
42
45
|
function createNode(
|
|
43
46
|
data: Record<string, any>,
|
|
@@ -45,14 +48,7 @@ export function useTreeNodes(options: Options): UseTreeNodesReturned {
|
|
|
45
48
|
depth: number,
|
|
46
49
|
parent?: TreeNode
|
|
47
50
|
): TreeNode {
|
|
48
|
-
const node = new TreeNode({
|
|
49
|
-
data,
|
|
50
|
-
index,
|
|
51
|
-
depth,
|
|
52
|
-
parent,
|
|
53
|
-
valueKey: valueKey!,
|
|
54
|
-
labelKey: labelKey!
|
|
55
|
-
})
|
|
51
|
+
const node = new TreeNode({ data, index, depth, parent, valueKey, labelKey })
|
|
56
52
|
node.expanded = expandAll
|
|
57
53
|
return node
|
|
58
54
|
}
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
import { dfs, o } from '@cat-kit/core'
|
|
64
64
|
import { useFormFallbackProps } from '@veltra/compositions'
|
|
65
65
|
import { ArrowDown, Search } from '@veltra/icons/normal'
|
|
66
|
-
import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
|
|
66
|
+
import { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'
|
|
67
67
|
import { injectFormContext } from '@veltra/utils'
|
|
68
68
|
import { computed, nextTick, shallowRef, watch } from 'vue'
|
|
69
69
|
|
|
@@ -114,6 +114,9 @@ const treeProps = computed(() => {
|
|
|
114
114
|
|
|
115
115
|
const cls = bem('tree-select')
|
|
116
116
|
|
|
117
|
+
const labelKey = computed(() => fieldKey(props.labelKey, 'label'))
|
|
118
|
+
const valueKey = computed(() => fieldKey(props.valueKey, 'value'))
|
|
119
|
+
|
|
117
120
|
/**过滤 */
|
|
118
121
|
const qs = shallowRef('')
|
|
119
122
|
watch(qs, (qs) => {
|
|
@@ -158,8 +161,8 @@ watch(
|
|
|
158
161
|
dfs(
|
|
159
162
|
item,
|
|
160
163
|
(v) => {
|
|
161
|
-
if (v[
|
|
162
|
-
label.value = v[
|
|
164
|
+
if (v[valueKey.value] === model) {
|
|
165
|
+
label.value = v[labelKey.value]
|
|
163
166
|
founded = true
|
|
164
167
|
return true
|
|
165
168
|
}
|
|
@@ -182,7 +185,7 @@ const handleSelect = (selected?: string | number, selectedData?: Record<string,
|
|
|
182
185
|
model.value = selected ?? ''
|
|
183
186
|
|
|
184
187
|
if (selectedData) {
|
|
185
|
-
label.value = o(selectedData).get(
|
|
188
|
+
label.value = o(selectedData).get(labelKey.value)
|
|
186
189
|
} else {
|
|
187
190
|
label.value = ''
|
|
188
191
|
}
|
package/src/types/code-editor.ts
CHANGED
|
@@ -5,8 +5,16 @@ export type CodeEditorLang = 'js' | 'sql' | 'java' | 'json'
|
|
|
5
5
|
/** 代码编辑器组件属性(不支持 `size`) */
|
|
6
6
|
export interface CodeEditorProps extends Omit<FormComponentProps, 'size'> {
|
|
7
7
|
modelValue?: string
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* 可选语言列表。长度大于 1 时在编辑器右上角显示内置语言选择器
|
|
10
|
+
*/
|
|
11
|
+
langs?: CodeEditorLang[]
|
|
12
|
+
/** 当前语言,配合 `v-model:lang` 使用 */
|
|
13
|
+
lang?: CodeEditorLang
|
|
14
|
+
/** 不可编辑的前缀外壳(展示在编辑器内,不计入 v-model) */
|
|
15
|
+
prefix?: string
|
|
16
|
+
/** 不可编辑的后缀外壳(展示在编辑器内,不计入 v-model) */
|
|
17
|
+
suffix?: string
|
|
10
18
|
/** 是否使用暗色主题 */
|
|
11
19
|
dark?: boolean
|
|
12
20
|
/**
|
|
@@ -19,6 +27,9 @@ export interface CodeEditorProps extends Omit<FormComponentProps, 'size'> {
|
|
|
19
27
|
/** 代码编辑器组件定义的事件 */
|
|
20
28
|
export interface CodeEditorEmits {
|
|
21
29
|
(e: 'update:modelValue', value: string): void
|
|
30
|
+
(e: 'update:lang', value: CodeEditorLang | undefined): void
|
|
31
|
+
/** 在编辑器失焦且内容有变更时触发 */
|
|
32
|
+
(e: 'change', value: string): void
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
/** 代码编辑器组件暴露的属性和方法(组件内部使用) */
|