@veltra/desktop 1.2.7 → 1.2.9

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 (81) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/action/action.vue.d.ts +1 -1
  3. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  4. package/dist/components/batch-edit/batch-edit-form.js +41 -79
  5. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  6. package/dist/components/batch-edit/batch-edit-list.js +17 -29
  7. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  8. package/dist/components/batch-edit/batch-edit.js +34 -60
  9. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  10. package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -14
  11. package/dist/components/batch-edit/di.js.map +1 -1
  12. package/dist/components/batch-edit/form-action-header.js +25 -0
  13. package/dist/components/batch-edit/form-action-header.js.map +1 -0
  14. package/dist/components/batch-edit/style2.css +0 -13
  15. package/dist/components/batch-edit/use-edit-state.js +40 -0
  16. package/dist/components/batch-edit/use-edit-state.js.map +1 -0
  17. package/dist/components/batch-edit/use-handlers.js +146 -0
  18. package/dist/components/batch-edit/use-handlers.js.map +1 -0
  19. package/dist/components/batch-edit/use-shortcut-key.js +44 -0
  20. package/dist/components/batch-edit/use-shortcut-key.js.map +1 -0
  21. package/dist/components/cascade/cascade.vue.d.ts +4 -4
  22. package/dist/components/checkbox/checkbox-button.vue.d.ts +2 -2
  23. package/dist/components/checkbox/checkbox.vue.d.ts +1 -1
  24. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
  25. package/dist/components/code-editor/code-editor.vue.d.ts +1 -1
  26. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  27. package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
  28. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
  29. package/dist/components/empty/empty.vue.d.ts +1 -1
  30. package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
  31. package/dist/components/form/form.js.map +1 -1
  32. package/dist/components/form/form.vue.d.ts +5 -1
  33. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +8 -2
  34. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/form-item/form-item.js.map +1 -1
  36. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +3 -2
  37. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/input/input.vue.d.ts +8 -8
  39. package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
  40. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +6 -6
  41. package/dist/components/number-input/number-input.vue.d.ts +4 -4
  42. package/dist/components/number-range-input/number-range-input.vue.d.ts +2 -2
  43. package/dist/components/palette/palette.vue.d.ts +1 -1
  44. package/dist/components/password-input/password-input.vue.d.ts +2 -2
  45. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  46. package/dist/components/progress-nodes/progress-nodes.vue.d.ts +1 -1
  47. package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
  48. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +2 -2
  49. package/dist/components/scroll/scroll.vue.d.ts +2 -2
  50. package/dist/components/select/select.vue.d.ts +2 -2
  51. package/dist/components/steps/steps.vue.d.ts +3 -3
  52. package/dist/components/switch/switch.vue.d.ts +1 -1
  53. package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
  54. package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
  55. package/dist/components/tabs/tabs.vue.d.ts +2 -2
  56. package/dist/components/textarea/textarea.vue.d.ts +4 -4
  57. package/dist/components/tip/tip.vue.d.ts +1 -1
  58. package/dist/components/tree/tree.vue.d.ts +1 -1
  59. package/dist/components/tree-select/tree-select.vue.d.ts +6 -6
  60. package/dist/index.d.ts +4 -4
  61. package/dist/types/batch-edit.d.ts +38 -12
  62. package/dist/types/form.d.ts +4 -1
  63. package/dist/types/index.d.ts +3 -3
  64. package/package.json +6 -6
  65. package/src/components/batch-edit/batch-edit-form.vue +40 -86
  66. package/src/components/batch-edit/batch-edit-list.vue +13 -29
  67. package/src/components/batch-edit/batch-edit.vue +27 -92
  68. package/src/components/batch-edit/di.ts +6 -5
  69. package/src/components/batch-edit/form-action-header.ts +21 -0
  70. package/src/components/batch-edit/style.scss +0 -14
  71. package/src/components/batch-edit/use-dialog-effect.ts +21 -0
  72. package/src/components/batch-edit/use-edit-state.ts +55 -0
  73. package/src/components/batch-edit/use-handlers.ts +226 -0
  74. package/src/components/batch-edit/use-shortcut-key.ts +58 -0
  75. package/src/components/form/form.vue +10 -3
  76. package/src/components/form-item/form-item.vue +4 -2
  77. package/src/types/batch-edit.ts +43 -22
  78. package/src/types/form.ts +4 -0
  79. package/dist/components/batch-edit/use-edit.js +0 -215
  80. package/dist/components/batch-edit/use-edit.js.map +0 -1
  81. package/src/components/batch-edit/use-edit.ts +0 -343
@@ -1,25 +1,26 @@
1
1
  import type { BEM } from '@veltra/utils'
2
- import type { ComputedRef, InjectionKey, ShallowRef, Ref } from 'vue'
2
+ import type { ComputedRef, InjectionKey, ShallowRef } from 'vue'
3
3
 
4
4
  import type {
5
5
  BatchEditEmits,
6
6
  BatchEditFeature,
7
7
  BatchEditProps,
8
- TableExposed,
8
+ BatchEditStates,
9
9
  TableRow
10
10
  } from '../../types'
11
- import type { EditReturned } from './use-edit'
11
+ import type { EditReturned } from './use-handlers'
12
+
12
13
  export const BatchEditDIKey: InjectionKey<
13
14
  {
14
15
  cls: BEM<'batch-edit', 'u-'>
15
16
  props: BatchEditProps
16
17
  emit: BatchEditEmits
17
- tableRef: ShallowRef<TableExposed | undefined>
18
+ state: BatchEditStates
18
19
  staticFeatures: ComputedRef<Set<BatchEditFeature>>
19
20
  dynamicFeatures: ComputedRef<
20
21
  Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>
21
22
  >
22
23
  /** 组件或其子节点是否处于聚焦状态 */
23
- focused: Ref<boolean>
24
+ focused: ShallowRef<boolean>
24
25
  } & EditReturned
25
26
  > = Symbol('BatchEditDIKey')
@@ -0,0 +1,21 @@
1
+ import { AddChild, EditPen, Plus, View } from '@veltra/icons/normal'
2
+ import type { Component } from 'vue'
3
+
4
+ import type { BatchEditStates } from '../../types'
5
+
6
+ /** 表单操作类型对应的头部展示信息 */
7
+ export interface FormActionHeaderInfo {
8
+ icon: Component
9
+ title: string
10
+ }
11
+
12
+ /** 按 formActionType 映射的表单头部信息 */
13
+ export const FORM_ACTION_HEADER_MAP: Record<
14
+ BatchEditStates['formActionType'],
15
+ FormActionHeaderInfo
16
+ > = {
17
+ create: { icon: Plus, title: '新增' },
18
+ update: { icon: EditPen, title: '编辑' },
19
+ view: { icon: View, title: '查看详情' },
20
+ createChild: { icon: AddChild, title: '新增子级' }
21
+ }
@@ -121,20 +121,6 @@ $root-name: batch-edit;
121
121
  }
122
122
  }
123
123
 
124
- @include m.e(form-chip) {
125
- display: inline-block;
126
- padding: 1px 8px;
127
- font-size: 12px;
128
- line-height: 18px;
129
- border-radius: fn.use-var(radius, default);
130
- background-color: fn.use-var(bg-color, default);
131
- color: fn.use-var(text-color, second);
132
- white-space: nowrap;
133
- overflow: hidden;
134
- text-overflow: ellipsis;
135
- max-width: 60%;
136
- }
137
-
138
124
  @include m.e(form-close) {
139
125
  flex-shrink: 0;
140
126
  }
@@ -0,0 +1,21 @@
1
+ import { inject, watch } from 'vue'
2
+
3
+ import { DialogDIKey } from '../dialog/di'
4
+
5
+ interface Options {
6
+ /** 关闭表单 */
7
+ closeForm: () => void
8
+ }
9
+
10
+ /**
11
+ * 在表单上的副作用。
12
+ * 包括:关闭表单
13
+ */
14
+ export function useDialogEffect(options: Options) {
15
+ const dialogCtx = inject(DialogDIKey, undefined)
16
+ if (!dialogCtx) return
17
+
18
+ watch(dialogCtx.visible, (visible) => {
19
+ !visible && options.closeForm?.()
20
+ })
21
+ }
@@ -0,0 +1,55 @@
1
+ import { o } from '@cat-kit/core'
2
+ import { shallowReactive, watch } from 'vue'
3
+
4
+ import type { BatchEditProps, BatchEditStates } from '../../types'
5
+
6
+ interface Options {
7
+ props: BatchEditProps
8
+ }
9
+
10
+ export function useEditState(options: Options) {
11
+ const { props } = options
12
+
13
+ const defaultState: BatchEditStates = {
14
+ depth: -1,
15
+ formVisible: false,
16
+ formActionType: 'create',
17
+ loading: false,
18
+ indexPath: []
19
+ }
20
+
21
+ const state = shallowReactive({ ...defaultState })
22
+
23
+ function resetState() {
24
+ if (state.row) {
25
+ state.row.isCurrent = false
26
+ }
27
+
28
+ Object.keys(state).forEach((key) => {
29
+ delete state[key]
30
+ })
31
+
32
+ Object.assign(state, defaultState)
33
+ }
34
+
35
+ watch(
36
+ () => state.row,
37
+ (row) => {
38
+ if (row) {
39
+ if (props.model) {
40
+ o(props.model).deepExtend(row.data)
41
+ }
42
+ state.formActionType = props.readonly ? 'view' : 'update'
43
+ state.formVisible = true
44
+ state.depth = row.depth
45
+ state.indexPath = [...row.indexes]
46
+
47
+ return
48
+ }
49
+
50
+ resetState()
51
+ }
52
+ )
53
+
54
+ return { state, resetState }
55
+ }
@@ -0,0 +1,226 @@
1
+ import { last, o } from '@cat-kit/core'
2
+ import { computed, nextTick, type ShallowRef } from 'vue'
3
+
4
+ import type {
5
+ TableRow,
6
+ BatchEditEmits,
7
+ BatchEditProps,
8
+ BatchEditStates,
9
+ FormExposed
10
+ } from '../../types'
11
+
12
+ /** 按索引路径在原始数据树中定位节点(等价于历史 Forest.visit 路径访问) */
13
+ function visitDataByIndexPath<T extends Record<string, unknown>>(
14
+ roots: T[],
15
+ indexPath: number[],
16
+ childrenKey: string
17
+ ): T | undefined {
18
+ if (!indexPath.length) return undefined
19
+ let currentList: T[] | undefined = roots
20
+ let node: T | undefined
21
+ for (let i = 0; i < indexPath.length; i++) {
22
+ const idx = indexPath[i]!
23
+ if (!currentList) return undefined
24
+ node = currentList[idx]
25
+ if (node === undefined) return undefined
26
+ if (i < indexPath.length - 1) {
27
+ const next = node[childrenKey]
28
+ currentList = Array.isArray(next) ? (next as T[]) : undefined
29
+ }
30
+ }
31
+ return node
32
+ }
33
+
34
+ interface Options {
35
+ props: BatchEditProps
36
+ emit: BatchEditEmits
37
+ state: BatchEditStates
38
+ formRef: ShallowRef<FormExposed | null>
39
+ resetState: () => void
40
+ }
41
+
42
+ export interface EditReturned {
43
+ handleSave: () => Promise<void>
44
+ handleClose: () => void
45
+ handleCreate: () => void
46
+ handleDelete: (row: TableRow) => Promise<void>
47
+ handleInsertToNext: (row: TableRow) => void
48
+ handleInsertToPrev: (row: TableRow) => void
49
+ handleInsertChild: (row: TableRow) => void
50
+ }
51
+
52
+ export function useHandlers(options: Options): EditReturned {
53
+ const { props, emit, state, resetState, formRef } = options
54
+
55
+ const childrenKey = computed(() => {
56
+ return typeof props.tree === 'string' ? props.tree : 'children'
57
+ })
58
+
59
+ function getInsertData(): Record<string, any> {
60
+ return o(props.model ?? {}).copy()
61
+ }
62
+
63
+ /**
64
+ * 插入数据
65
+ * @param item 数据
66
+ */
67
+ function insert(item: Record<string, any>) {
68
+ const data = [...(props.data ?? [])]
69
+
70
+ const parent = visitDataByIndexPath(data ?? [], state.indexPath.slice(0, -1), childrenKey.value)
71
+
72
+ if (parent) {
73
+ const children = parent[childrenKey.value]
74
+ if (!children) {
75
+ parent[childrenKey.value] = [item]
76
+ } else {
77
+ children.splice(last(state.indexPath), 0, item)
78
+ }
79
+ } else {
80
+ data.splice(last(state.indexPath), 0, item)
81
+ }
82
+
83
+ emit('update:data', data)
84
+
85
+ return item
86
+ }
87
+
88
+ /**
89
+ * 点击新增按钮
90
+ */
91
+ function handleCreate() {
92
+ const { data } = props
93
+
94
+ resetState()
95
+
96
+ nextTick(() => {
97
+ state.formActionType = 'create'
98
+ state.formVisible = true
99
+ state.depth = 1
100
+ state.indexPath = [data?.length ?? 0]
101
+ })
102
+ }
103
+
104
+ function handleInsertToPrev(row: TableRow) {
105
+ resetState()
106
+ state.formActionType = 'create'
107
+ state.formVisible = true
108
+ state.depth = row.depth
109
+ state.indexPath = [...row.indexes]
110
+ }
111
+
112
+ function handleInsertToNext(row: TableRow) {
113
+ resetState()
114
+ state.formActionType = 'create'
115
+ state.formVisible = true
116
+ state.depth = row.depth
117
+ state.indexPath = [...row.indexes.slice(0, -1), row.index + 1]
118
+ }
119
+
120
+ function handleInsertChild(row: TableRow) {
121
+ resetState()
122
+ state.formActionType = 'createChild'
123
+ state.formVisible = true
124
+ state.parentRow = row
125
+ state.depth = row.depth + 1
126
+ row.expanded = true
127
+ state.indexPath = [...row.indexes, row.children?.length ?? 0]
128
+ }
129
+
130
+ function runWithLoading<Arg extends any[]>(fn: (...args: Arg) => Promise<void> | void) {
131
+ return async (...args: Arg) => {
132
+ state.loading = true
133
+ if (state.row) {
134
+ state.row.operating = true
135
+ }
136
+ try {
137
+ await fn.apply(null, args)
138
+ } catch (error) {
139
+ console.error(error)
140
+ }
141
+ state.loading = false
142
+ if (state.row) {
143
+ state.row.operating = false
144
+ }
145
+ }
146
+ }
147
+
148
+ /** 保存 */
149
+ const handleSave = runWithLoading(async () => {
150
+ const { model, saveMethod } = props
151
+ const valid = await formRef.value?.validate()
152
+ if (!model || !valid) return
153
+
154
+ let item = getInsertData()
155
+
156
+ // 新增
157
+ if (state.formActionType === 'create' || state.formActionType === 'createChild') {
158
+ await props.beforeCreate?.(item, state.parentRow?.data)
159
+ if (saveMethod) {
160
+ const result = await saveMethod(item, state.formActionType, state.parentRow?.data)
161
+ if (result) {
162
+ item = result
163
+ }
164
+ }
165
+ insert(item)
166
+ return
167
+ }
168
+
169
+ // 普通模式下的编辑
170
+ if (saveMethod) {
171
+ const result = await saveMethod(item, state.formActionType, state.parentRow?.data)
172
+ if (result) {
173
+ item = result
174
+ }
175
+ }
176
+
177
+ const { row } = state
178
+ row &&
179
+ Object.keys(item).forEach((key) => {
180
+ o(row.data).set(key, o(item).get(key))
181
+ })
182
+ })
183
+
184
+ const handleDelete = runWithLoading(async (row: TableRow) => {
185
+ const { deleteMethod } = props
186
+
187
+ if (deleteMethod) {
188
+ await deleteMethod([row.data])
189
+ }
190
+
191
+ const data = [...(props.data ?? [])]
192
+
193
+ const parent = visitDataByIndexPath(data, row.indexes.slice(0, -1), childrenKey.value)
194
+
195
+ if (parent) {
196
+ const children = parent[childrenKey.value]
197
+ if (children) {
198
+ children.splice(row.index, 1)
199
+ } else {
200
+ console.error('行路径不正确')
201
+ }
202
+ } else {
203
+ data.splice(row.index, 1)
204
+ }
205
+
206
+ if (state.row === row) {
207
+ resetState()
208
+ }
209
+
210
+ emit('update:data', data)
211
+ })
212
+
213
+ function handleClose() {
214
+ resetState()
215
+ }
216
+
217
+ return {
218
+ handleDelete,
219
+ handleInsertChild,
220
+ handleInsertToNext,
221
+ handleInsertToPrev,
222
+ handleCreate,
223
+ handleClose,
224
+ handleSave
225
+ }
226
+ }
@@ -0,0 +1,58 @@
1
+ import { shallowRef } from 'vue'
2
+
3
+ import type { BatchEditProps, BatchEditStates } from '../../types'
4
+
5
+ interface Options {
6
+ props: BatchEditProps
7
+ onSave: () => void
8
+ onClose: () => void
9
+ state: BatchEditStates
10
+ }
11
+ export function useShortcutKey(options: Options) {
12
+ const { props, onClose, onSave, state } = options
13
+ const focused = shallowRef(false)
14
+
15
+ function handleFocusIn() {
16
+ focused.value = true
17
+ }
18
+
19
+ function handleFocusOut(e: FocusEvent) {
20
+ const root = e.currentTarget as HTMLElement
21
+ if (!root.contains(e.relatedTarget as Node | null)) {
22
+ focused.value = false
23
+ }
24
+ }
25
+
26
+ function runEscape(e: KeyboardEvent) {
27
+ e.preventDefault()
28
+ onClose()
29
+ }
30
+
31
+ function runSave(e: KeyboardEvent) {
32
+ if (!state.formVisible) return
33
+ if (props.quickEdit && state.formActionType === 'update') return
34
+ e.preventDefault()
35
+ onSave()
36
+ }
37
+
38
+ /**
39
+ * 键盘快捷键(仅组件获焦时生效):
40
+ * - Esc 关闭表单
41
+ * - ⌘/Ctrl + S 保存(快速编辑模式下编辑行时除外)
42
+ */
43
+ function handleKeydown(e: KeyboardEvent) {
44
+ if (!focused.value) return
45
+ if (props.readonly && e.key !== 'Escape') return
46
+
47
+ if (e.key === 'Escape') return runEscape(e)
48
+
49
+ const meta = e.metaKey || e.ctrlKey
50
+ if (!meta) return
51
+
52
+ const key = e.key.toLowerCase()
53
+
54
+ if (key === 's') return runSave(e)
55
+ }
56
+
57
+ return { focused, handleFocusIn, handleFocusOut, handleKeydown }
58
+ }
@@ -27,9 +27,9 @@
27
27
  import { o } from '@cat-kit/core'
28
28
  import { bem } from '@veltra/utils'
29
29
  import { provideFormContext } from '@veltra/utils'
30
- import { nextTick, shallowRef, toRef, useTemplateRef } from 'vue'
30
+ import { nextTick, toRef, useTemplateRef } from 'vue'
31
31
 
32
- import type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'
32
+ import type { BreakCols, FormProps, _FormExposed, FormEmits } from '../../types'
33
33
  import { UFormItem } from '../form-item'
34
34
  import { UGrid } from '../grid'
35
35
  import { useFormFields } from './use-form-fields'
@@ -39,6 +39,8 @@ defineOptions({ name: 'Form' })
39
39
 
40
40
  const props = defineProps<FormProps>()
41
41
 
42
+ const emit = defineEmits<FormEmits>()
43
+
42
44
  defineSlots<{ default(props?: { data: Record<string, any> | undefined }): any }>()
43
45
 
44
46
  const cls = bem('form')
@@ -68,12 +70,17 @@ async function validate(keys?: string[]) {
68
70
  return valid
69
71
  }
70
72
 
73
+ function handleFieldChange(field: string, value: any) {
74
+ emit('field:change', field, value)
75
+ }
76
+
71
77
  provideFormContext({
72
78
  formProps: props,
73
79
  registerField,
74
80
  unregisterField,
75
81
  validateFields: validate,
76
- shouldValidate
82
+ shouldValidate,
83
+ handleFieldChange
77
84
  })
78
85
 
79
86
  const { getSlotsNodes } = useNodeInterceptor()
@@ -56,7 +56,8 @@ defineSlots<{
56
56
  }>()
57
57
 
58
58
  /** 表单组件上下文 */
59
- const { formProps, registerField, unregisterField, shouldValidate } = injectFormContext()
59
+ const { formProps, registerField, unregisterField, shouldValidate, handleFieldChange } =
60
+ injectFormContext()
60
61
 
61
62
  const { config } = useConfig()
62
63
 
@@ -127,7 +128,8 @@ watch(
127
128
 
128
129
  stopWatchFieldValue = watch(
129
130
  () => o(model).get(field),
130
- () => {
131
+ (value) => {
132
+ handleFieldChange?.(field, value)
131
133
  fieldItem.validate()
132
134
  }
133
135
  )
@@ -1,25 +1,32 @@
1
1
  import type { DeconstructValue } from '@veltra/utils'
2
2
 
3
3
  import type { ActionProps } from './action'
4
- import type { TableColumn, TableEmits, TableProps, TableRow } from './table'
4
+ import type { TableColumn, TableColumnSlotsScope, TableEmits, TableProps, TableRow } from './table'
5
5
 
6
6
  /** 批量编辑列 */
7
- export interface BatchEditColumn extends TableColumn {
8
- // /**
9
- // * 是否在列中显示
10
- // * @default true
11
- // */
12
- // visible?: boolean
13
- // /** 校验规则 */
14
- // rules?: ValidateRule
15
- // /** 默认值 */
16
- // defaultValue?: any | (() => any)
17
- }
7
+ export interface BatchEditColumn extends TableColumn {}
8
+
9
+ export type BatchEditFeature = 'create' | 'update' | 'delete' | 'view' | 'createChild'
18
10
 
19
- export type BatchEditFeature = 'create' | 'update' | 'copy' | 'delete' | 'view' | 'createChild'
11
+ export type BatchEditFormStatus = 'hidden'
20
12
 
21
- /** 批量编辑模式 */
22
- export type BatchEditMode = 'normal' | 'quick'
13
+ /** 批量编辑状态 */
14
+ export interface BatchEditStates {
15
+ /** 层级 */
16
+ depth: number
17
+ /** 表单可见性 */
18
+ formVisible: boolean
19
+ /** 表单操作类型 */
20
+ formActionType: 'create' | 'update' | 'view' | 'createChild'
21
+ /** 加载状态 */
22
+ loading: boolean
23
+ /** 当前编辑行 */
24
+ row?: TableRow
25
+ /** 当前编辑或者新增的父级行 */
26
+ parentRow?: TableRow
27
+ /** 行索引路径, */
28
+ indexPath: number[]
29
+ }
23
30
 
24
31
  /** 批量编辑组件属性 */
25
32
  export interface BatchEditProps extends TableProps {
@@ -37,14 +44,13 @@ export interface BatchEditProps extends TableProps {
37
44
  /** 只读模式 */
38
45
  readonly?: boolean
39
46
  /**
40
- * 编辑模式
41
- * @default 'normal'
42
- * @description `quick` 模式下编辑行时表单直接绑定 `row.data` 实时更新,且不调用 `saveMethod`
47
+ * 开启快速编辑
48
+ * @description 开启后,编辑行时表单实时写回 `row.data`(经 `model` 中转),且不调用 `saveMethod`
43
49
  */
44
- mode?: BatchEditMode
50
+ quickEdit?: boolean
45
51
  /**
46
52
  * 新增前的钩子
47
- * @description 仅作用于 create 类操作。`normal` 模式在保存时调用;`quick` 模式在点击新增类按钮时立即调用。可直接修改传入的 draft 对象
53
+ * @description 仅作用于 create 类操作,在保存时调用。可直接修改传入的 draft 对象
48
54
  */
49
55
  beforeCreate?: (
50
56
  data: Record<string, any>,
@@ -56,14 +62,14 @@ export interface BatchEditProps extends TableProps {
56
62
  deleteMethod?: (data: Record<string, any>[]) => any
57
63
  /**
58
64
  * 保存方法
59
- * @description 仅在 `normal` 模式下、保存时调用(create / update)
65
+ * @description 保存时调用。`quick` 模式下编辑行时实时写回,不调用此方法;新增时与 `normal` 模式一致
60
66
  * @returns 如果返回一个值,那么这个值会被插入,否则插入的为表单值
61
67
  */
62
68
  saveMethod?: (
63
69
  /** 表单数据 */
64
70
  data: Record<string, any>,
65
71
  /** 操作类型 */
66
- actionType: 'create' | 'update',
72
+ actionType: BatchEditStates['formActionType'],
67
73
  /** 父级数据 */
68
74
  parentData?: Record<string, any>
69
75
  ) => any
@@ -109,6 +115,21 @@ export interface BatchEditEmits extends TableEmits {
109
115
  (e: 'update:data', value: Record<string, any>[]): void
110
116
  }
111
117
 
118
+ export type BatchEditSlots = {
119
+ form?: (props: {
120
+ /** 当前编辑的层级 */
121
+ depth?: number
122
+ /** 当前编辑的行 */
123
+ row?: TableRow
124
+ /** 当前编辑的行索引 */
125
+ index?: number
126
+ /** 操作的目标行索引路径 */
127
+ indexes?: number[]
128
+ }) => any
129
+
130
+ header?: () => any
131
+ } & Partial<{ [key: `column:${string}`]: (props: TableColumnSlotsScope) => any }>
132
+
112
133
  /** 批量编辑组件暴露的属性和方法(组件内部使用) */
113
134
  export interface _BatchEditExposed {}
114
135
 
package/src/types/form.ts CHANGED
@@ -21,6 +21,10 @@ export interface FormProps extends ComponentProps {
21
21
  disabled?: boolean
22
22
  }
23
23
 
24
+ export interface FormEmits {
25
+ (e: 'field:change', field: string, value: any): void
26
+ }
27
+
24
28
  export interface _FormExposed {
25
29
  el: ShallowRef<HTMLElement | null | undefined>
26
30
  validate: (keys?: string[]) => Promise<boolean>