@veltra/desktop 1.2.8 → 1.2.10

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 (67) hide show
  1. package/dist/components/action/action-group.vue.d.ts +1 -1
  2. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  3. package/dist/components/batch-edit/batch-edit-form.js +40 -74
  4. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  5. package/dist/components/batch-edit/batch-edit-list.js +17 -29
  6. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  7. package/dist/components/batch-edit/batch-edit.js +37 -60
  8. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  9. package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -14
  10. package/dist/components/batch-edit/di.js.map +1 -1
  11. package/dist/components/batch-edit/form-action-header.js +25 -0
  12. package/dist/components/batch-edit/form-action-header.js.map +1 -0
  13. package/dist/components/batch-edit/style2.css +0 -13
  14. package/dist/components/batch-edit/use-edit-state.js +44 -0
  15. package/dist/components/batch-edit/use-edit-state.js.map +1 -0
  16. package/dist/components/batch-edit/use-handlers.js +146 -0
  17. package/dist/components/batch-edit/use-handlers.js.map +1 -0
  18. package/dist/components/batch-edit/use-shortcut-key.js +44 -0
  19. package/dist/components/batch-edit/use-shortcut-key.js.map +1 -0
  20. package/dist/components/cascade/cascade.vue.d.ts +2 -2
  21. package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
  22. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
  23. package/dist/components/form/form.js.map +1 -1
  24. package/dist/components/form/form.vue.d.ts +5 -1
  25. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +8 -2
  26. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/components/form-item/form-item.js.map +1 -1
  28. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +3 -2
  29. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/input/input.vue.d.ts +2 -2
  31. package/dist/components/multi-select/multi-select.vue.d.ts +2 -2
  32. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +3 -3
  33. package/dist/components/number-input/number-input.vue.d.ts +2 -2
  34. package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
  35. package/dist/components/password-input/password-input.vue.d.ts +1 -1
  36. package/dist/components/progress-nodes/progress-nodes.vue.d.ts +1 -1
  37. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
  38. package/dist/components/select/select.vue.d.ts +2 -2
  39. package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
  40. package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
  41. package/dist/components/tabs/tabs.vue.d.ts +2 -2
  42. package/dist/components/textarea/textarea.vue.d.ts +2 -2
  43. package/dist/components/tree/tree.vue.d.ts +1 -1
  44. package/dist/components/tree-select/tree-select.vue.d.ts +3 -3
  45. package/dist/components/watermark/watermark.vue.d.ts +1 -1
  46. package/dist/index.d.ts +4 -4
  47. package/dist/types/batch-edit.d.ts +38 -12
  48. package/dist/types/form.d.ts +4 -1
  49. package/dist/types/index.d.ts +3 -3
  50. package/package.json +6 -6
  51. package/src/components/batch-edit/batch-edit-form.vue +39 -79
  52. package/src/components/batch-edit/batch-edit-list.vue +13 -29
  53. package/src/components/batch-edit/batch-edit.vue +27 -92
  54. package/src/components/batch-edit/di.ts +6 -5
  55. package/src/components/batch-edit/form-action-header.ts +21 -0
  56. package/src/components/batch-edit/style.scss +0 -14
  57. package/src/components/batch-edit/use-dialog-effect.ts +21 -0
  58. package/src/components/batch-edit/use-edit-state.ts +61 -0
  59. package/src/components/batch-edit/use-handlers.ts +226 -0
  60. package/src/components/batch-edit/use-shortcut-key.ts +58 -0
  61. package/src/components/form/form.vue +10 -3
  62. package/src/components/form-item/form-item.vue +4 -2
  63. package/src/types/batch-edit.ts +43 -22
  64. package/src/types/form.ts +4 -0
  65. package/dist/components/batch-edit/use-edit.js +0 -231
  66. package/dist/components/batch-edit/use-edit.js.map +0 -1
  67. package/src/components/batch-edit/use-edit.ts +0 -365
@@ -1,16 +1,13 @@
1
1
  <template>
2
- <aside :class="cls.e('form')" v-if="state.visible && props.model">
2
+ <aside :class="cls.e('form')" v-if="state.formVisible && !!props.model">
3
3
  <header :class="cls.e('form-header')">
4
- <span :class="[cls.e('form-icon'), bem.is(headerInfo.tone)]">
4
+ <span :class="[cls.e('form-icon'), bem.is(state.formActionType)]">
5
5
  <u-icon>
6
6
  <component :is="headerInfo.icon" />
7
7
  </u-icon>
8
8
  </span>
9
9
  <div :class="cls.e('form-title')">
10
10
  <h3 :class="cls.e('form-title-text')">{{ headerInfo.title }}</h3>
11
- <span v-if="headerInfo.chip" :class="cls.e('form-chip')">
12
- {{ headerInfo.chip }}
13
- </span>
14
11
  </div>
15
12
  <u-button
16
13
  :class="cls.e('form-close')"
@@ -30,12 +27,13 @@
30
27
  :model="props.model"
31
28
  :readonly="props.readonly"
32
29
  :label-width="props.labelWidth"
30
+ @field:change="handleFieldChange"
33
31
  >
34
32
  <slot
35
33
  v-bind="{
36
34
  row: state.row,
37
35
  depth: state.depth,
38
- indexes: insertIndexes,
36
+ indexes: state.indexPath,
39
37
  index: state.row?.index
40
38
  }"
41
39
  />
@@ -44,27 +42,20 @@
44
42
  </u-scroll>
45
43
 
46
44
  <footer :class="cls.e('form-footer')">
47
- <span :class="cls.e('form-hint')" v-if="props.readonly">只读模式</span>
48
- <span :class="cls.e('form-hint')" v-else-if="isQuickUpdate">
49
- 实时编辑
50
- <span :class="{ [bem.is('concealed')]: !focused }"> · <u-kbd>Esc</u-kbd> 关闭</span>
51
- </span>
52
- <span :class="cls.e('form-hint')" v-else>
45
+ <span :class="cls.e('form-hint')">
46
+ <template v-if="props.readonly"> 只读模式 </template>
47
+
53
48
  <span :class="{ [bem.is('concealed')]: !focused }">
54
- <u-kbd>Ctrl + S</u-kbd> 保存 · <u-kbd>Esc</u-kbd> 关闭
49
+ <template v-if="!(state.formActionType === 'update' && props.quickEdit)">
50
+ <u-kbd>Ctrl + S</u-kbd> 保存 ·
51
+ </template>
52
+ <u-kbd>Esc</u-kbd> 关闭
55
53
  </span>
56
54
  </span>
57
55
 
58
56
  <div :class="cls.e('form-actions')">
59
57
  <u-button text :loading="state.loading" @click="handleClose"> 取消 </u-button>
60
- <u-button
61
- v-if="
62
- !props.readonly && ((isNormal && (creatable || updatable)) || (isQuick && creatable))
63
- "
64
- :type="state.type === 'create' ? 'success' : 'primary'"
65
- :loading="state.loading"
66
- @click="handleSave"
67
- >
58
+ <u-button v-if="showSaveBtn" type="primary" :loading="state.loading" @click="handleSave">
68
59
  保存
69
60
  </u-button>
70
61
  </div>
@@ -73,9 +64,10 @@
73
64
  </template>
74
65
 
75
66
  <script lang="ts" setup>
76
- import { AddChild, Close, EditPen, Plus, View } from '@veltra/icons/normal'
67
+ import { o } from '@cat-kit/core'
68
+ import { Close } from '@veltra/icons/normal'
77
69
  import { bem } from '@veltra/utils'
78
- import { computed, inject, shallowRef, toRef, type Component } from 'vue'
70
+ import { computed, inject, shallowRef, toRef } from 'vue'
79
71
 
80
72
  import type { _FormExposed, FormExposed } from '../../types/form'
81
73
  import { UButton } from '../button'
@@ -84,21 +76,13 @@ import { UIcon } from '../icon'
84
76
  import { UKbd } from '../kbd'
85
77
  import { UScroll } from '../scroll'
86
78
  import { BatchEditDIKey } from './di'
79
+ import { FORM_ACTION_HEADER_MAP } from './form-action-header'
87
80
 
88
81
  defineOptions({ name: 'BatchEditForm' })
89
82
 
90
83
  const batchEditCtx = inject(BatchEditDIKey)!
91
84
 
92
- const {
93
- cls,
94
- props,
95
- state,
96
- insertIndexes,
97
- handleSave,
98
- handleClose,
99
- staticFeatures,
100
- dynamicFeatures
101
- } = batchEditCtx
85
+ const { cls, props, state, handleClose, handleSave, staticFeatures, dynamicFeatures } = batchEditCtx
102
86
 
103
87
  const focused = toRef(batchEditCtx, 'focused')
104
88
 
@@ -111,61 +95,37 @@ defineExpose<_FormExposed>({
111
95
  reset: () => formComponentRef.value?.reset()
112
96
  })
113
97
 
98
+ function handleFieldChange(field: string, value: any) {
99
+ if (state.row && props.quickEdit) {
100
+ o(state.row.data).set(field, value)
101
+ }
102
+ }
103
+
114
104
  const creatable = computed(() => {
115
- return (
116
- state.type === 'create' &&
117
- (staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row))
118
- )
105
+ if (state.formActionType !== 'create') return false
106
+ return staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row)
119
107
  })
120
108
 
121
- const updatable = computed(() => {
122
- return (
123
- state.type === 'update' &&
124
- (staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row))
125
- )
109
+ const creatableChild = computed(() => {
110
+ if (state.formActionType !== 'createChild') return false
111
+ return staticFeatures.value.has('createChild') || dynamicFeatures.value.createChild?.(state.row)
126
112
  })
127
113
 
128
- const isQuick = computed(() => props.mode === 'quick')
129
- const isNormal = computed(() => props.mode !== 'quick')
130
- const isQuickUpdate = computed(() => isQuick.value && state.type === 'update')
131
-
132
- interface HeaderInfo {
133
- icon: Component
134
- title: string
135
- chip?: string
136
- tone: 'create' | 'update' | 'view' | 'child'
137
- }
114
+ const updatable = computed(() => {
115
+ if (state.formActionType !== 'update') return false
116
+ return staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row)
117
+ })
138
118
 
139
- const headerInfo = computed<HeaderInfo>(() => {
140
- if (props.readonly) {
141
- return {
142
- icon: View,
143
- title: '查看详情',
144
- chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
145
- tone: 'view'
146
- }
147
- }
148
- if (state.parentRow) {
149
- return {
150
- icon: AddChild,
151
- title: '新增子级',
152
- chip: `归属于第 ${state.parentRow.index + 1} 行`,
153
- tone: 'child'
154
- }
155
- }
156
- if (state.type === 'create') {
157
- return { icon: Plus, title: '新增', tone: 'create' }
158
- }
159
- return {
160
- icon: EditPen,
161
- title: '编辑',
162
- chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
163
- tone: 'update'
164
- }
119
+ const showSaveBtn = computed(() => {
120
+ if (props.readonly) return false
121
+ if (props.quickEdit && state.formActionType === 'update') return false
122
+ return creatable.value || updatable.value || creatableChild.value
165
123
  })
166
124
 
125
+ const headerInfo = computed(() => FORM_ACTION_HEADER_MAP[state.formActionType])
126
+
167
127
  /** 通过 row 切换 / 类型切换驱动表单内容淡出淡入 */
168
128
  const bodyKey = computed(() => {
169
- return `${state.type}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`
129
+ return `${state.formActionType}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`
170
130
  })
171
131
  </script>
@@ -2,14 +2,13 @@
2
2
  <u-table
3
3
  v-bind="tableProps"
4
4
  :slots="slots"
5
- :class="[cls.e('table'), bem.is('editing', state.visible)]"
5
+ :class="[cls.e('table')]"
6
6
  :columns="columns"
7
7
  highlight-current
8
8
  :current="state.row"
9
9
  @update:current="handleUpdateCurrentRow"
10
10
  @update:checked="emit('update:checked', $event)"
11
11
  @update:selected="emit('update:selected', $event)"
12
- ref="tableRef"
13
12
  >
14
13
  <template #column:__action__="{ row }">
15
14
  <u-action-group :class="cls.e('row-actions')" :max="5" @click.stop circle>
@@ -31,13 +30,6 @@
31
30
  title="添加子级"
32
31
  @run="handleInsertChild(row)"
33
32
  />
34
- <u-action
35
- v-if="allowed('copy', row)"
36
- :icon="Copy"
37
- title="复制此行"
38
- @run="handleCopy(row)"
39
- />
40
-
41
33
  <u-action
42
34
  v-if="canDelete(row)"
43
35
  :icon="Delete"
@@ -49,16 +41,8 @@
49
41
  </u-action-group>
50
42
  </template>
51
43
 
52
- <template #empty v-if="!props.readonly"> {{ null }} </template>
53
-
54
- <template
55
- #append
56
- v-if="
57
- !props.readonly &&
58
- (staticFeatures.has('create') || dynamicFeatures.create?.()) &&
59
- ((state.type === 'create' && !state.visible) || state.type === 'update')
60
- "
61
- >
44
+ <!-- 新增按钮 -->
45
+ <template #append v-if="showCreateBtn">
62
46
  <div :class="cls.e('add')">
63
47
  <u-button
64
48
  :class="cls.e('add-btn')"
@@ -77,8 +61,7 @@
77
61
 
78
62
  <script setup lang="ts">
79
63
  import { o } from '@cat-kit/core'
80
- import { AddChild, Copy, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'
81
- import { bem } from '@veltra/utils'
64
+ import { AddChild, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'
82
65
  import { computed, inject, type Slots } from 'vue'
83
66
 
84
67
  import type { BatchEditFeature, TableRow } from '../../types'
@@ -94,13 +77,11 @@ defineProps<{ slots: Slots }>()
94
77
  const {
95
78
  cls,
96
79
  state,
97
- tableRef,
98
80
  props,
99
81
  emit,
100
82
  staticFeatures,
101
83
  dynamicFeatures,
102
84
  handleCreate,
103
- handleCopy,
104
85
  handleDelete,
105
86
  handleInsertToNext,
106
87
  handleInsertToPrev,
@@ -128,8 +109,7 @@ const allowed = (feature: BatchEditFeature, row?: TableRow) => {
128
109
  }
129
110
 
130
111
  const columns = computed(() => {
131
- if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update', 'copy']))
132
- return props.columns
112
+ if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update'])) return props.columns
133
113
 
134
114
  return (props.columns ?? []).concat({
135
115
  name: '操作',
@@ -143,15 +123,19 @@ const columns = computed(() => {
143
123
 
144
124
  function handleUpdateCurrentRow(row?: TableRow) {
145
125
  if (allowed('update', row)) {
146
- if (row) {
147
- state.type = 'update'
148
- }
149
126
  state.row = row
150
- state.depth = row?.depth
151
127
  }
152
128
  }
153
129
 
154
130
  function canDelete(row: TableRow) {
155
131
  return !props.readonly && allowed('delete', row)
156
132
  }
133
+
134
+ const showCreateBtn = computed(() => {
135
+ if (props.readonly) return false
136
+
137
+ const hasFeature = staticFeatures.value.has('create') || dynamicFeatures.value.create?.()
138
+ const createActionVisible = state.formActionType === 'create' && state.formVisible
139
+ return hasFeature && !createActionVisible
140
+ })
157
141
  </script>
@@ -2,7 +2,7 @@
2
2
  <u-layout
3
3
  :class="cls.b"
4
4
  :cols="cols"
5
- rows="minmax(0, 1fr)"
5
+ rows="minmax(0, 1fr) "
6
6
  gap="8px"
7
7
  resizable
8
8
  tabindex="-1"
@@ -11,10 +11,10 @@
11
11
  @keydown.capture="handleKeydown"
12
12
  >
13
13
  <!-- 编辑列表 -->
14
- <BatchEditList :slots="slots" ref="tableRef" />
14
+ <BatchEditList :slots="slots" />
15
15
 
16
16
  <!-- 编辑表单 -->
17
- <BatchEditForm ref="formRef" v-slot="scoped">
17
+ <BatchEditForm ref="form" v-slot="scoped">
18
18
  <slot name="form" v-bind="scoped" />
19
19
  </BatchEditForm>
20
20
  </u-layout>
@@ -22,121 +22,56 @@
22
22
 
23
23
  <script lang="ts" setup>
24
24
  import { bem } from '@veltra/utils'
25
- import { computed, inject, provide, shallowRef, watch } from 'vue'
25
+ import { computed, provide, useTemplateRef } from 'vue'
26
26
 
27
- import type {
28
- BatchEditEmits,
29
- BatchEditProps,
30
- TableColumnSlotsScope,
31
- TableExposed,
32
- TableRow
33
- } from '../../types'
34
- import type { FormExposed } from '../../types/form'
35
- import { DialogDIKey } from '../dialog/di'
27
+ import type { BatchEditEmits, BatchEditProps, BatchEditSlots, FormExposed } from '../../types'
36
28
  import { ULayout } from '../layout'
37
29
  import BatchEditForm from './batch-edit-form.vue'
38
30
  import BatchEditList from './batch-edit-list.vue'
39
31
  import { BatchEditDIKey } from './di'
40
- import { useEdit } from './use-edit'
32
+ import { useEditState } from './use-edit-state'
41
33
  import { useFeatures } from './use-features'
34
+ import { useHandlers } from './use-handlers'
35
+ import { useShortcutKey } from './use-shortcut-key'
42
36
 
43
37
  defineOptions({ name: 'BatchEdit' })
44
38
 
45
- const props = withDefaults(defineProps<BatchEditProps>(), {
46
- cols: () => ['1fr', '420px'],
47
- mode: 'normal'
48
- })
39
+ const props = withDefaults(defineProps<BatchEditProps>(), { cols: () => ['1fr', '420px'] })
49
40
 
50
41
  const emit = defineEmits<BatchEditEmits>()
51
42
 
52
- const slots = defineSlots<
53
- {
54
- form?: (props: {
55
- /** 当前编辑的层级 */
56
- depth?: number
57
- /** 当前编辑的行 */
58
- row?: TableRow
59
- /** 当前编辑的行索引 */
60
- index?: number
61
- /** 操作的目标行索引路径 */
62
- indexes?: number[]
63
- }) => any
64
-
65
- header?: () => any
66
- } & Partial<{ [key: `column:${string}`]: (props: TableColumnSlotsScope) => any }>
67
- >()
43
+ const slots = defineSlots<BatchEditSlots>()
68
44
 
69
45
  const cls = bem('batch-edit')
70
46
 
71
- const tableRef = shallowRef<TableExposed>()
72
- const formRef = shallowRef<FormExposed>()
73
- const focused = shallowRef(false)
47
+ const formRef = useTemplateRef<FormExposed>('form')
48
+
49
+ const { state, resetState } = useEditState({ props, formRef })
74
50
 
75
51
  const { staticFeatures, dynamicFeatures } = useFeatures({ props })
76
52
 
77
- const editCtx = useEdit({ props, emit, formRef })
53
+ const handlers = useHandlers({ props, emit, state, resetState, formRef })
54
+
55
+ // 快捷键处理
56
+ const { handleFocusIn, handleFocusOut, handleKeydown, focused } = useShortcutKey({
57
+ props,
58
+ onSave: handlers.handleSave,
59
+ onClose: handlers.handleClose,
60
+ state
61
+ })
78
62
 
79
- const { state, handleClose, handleSave } = editCtx
63
+ const cols = computed(() => {
64
+ return state.formVisible ? props.cols : undefined
65
+ })
80
66
 
81
67
  provide(BatchEditDIKey, {
82
68
  cls,
83
69
  props,
84
70
  emit,
85
- tableRef,
71
+ state,
86
72
  staticFeatures,
87
73
  dynamicFeatures,
88
74
  focused,
89
- ...editCtx
90
- })
91
-
92
- const dialogCtx = inject(DialogDIKey, undefined)
93
-
94
- dialogCtx &&
95
- watch(dialogCtx.visible, (visible) => {
96
- !visible && editCtx.handleClose()
97
- })
98
-
99
- const cols = computed(() => {
100
- return !!state.row || state.visible ? props.cols : undefined
75
+ ...handlers
101
76
  })
102
-
103
- function handleFocusIn() {
104
- focused.value = true
105
- }
106
-
107
- function handleFocusOut(e: FocusEvent) {
108
- const root = e.currentTarget as HTMLElement
109
- if (!root.contains(e.relatedTarget as Node | null)) {
110
- focused.value = false
111
- }
112
- }
113
-
114
- /**
115
- * 键盘快捷键(仅组件获焦时生效):
116
- * - Esc 关闭表单
117
- * - ⌘/Ctrl + S 保存(快速编辑模式下编辑行时除外)
118
- */
119
- function handleKeydown(e: KeyboardEvent) {
120
- if (!focused.value) return
121
- if (props.readonly && e.key !== 'Escape') return
122
-
123
- if (e.key === 'Escape') {
124
- if (state.visible) {
125
- e.preventDefault()
126
- handleClose()
127
- }
128
- return
129
- }
130
-
131
- const meta = e.metaKey || e.ctrlKey
132
- if (!meta) return
133
-
134
- const key = e.key.toLowerCase()
135
-
136
- if (key === 's' && state.visible) {
137
- if (props.mode === 'quick' && state.type === 'update') return
138
- e.preventDefault()
139
- handleSave()
140
- }
141
- }
142
77
  </script>
@@ -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,61 @@
1
+ import { o } from '@cat-kit/core'
2
+ import { nextTick, shallowReactive, watch, type ShallowRef } from 'vue'
3
+
4
+ import type { BatchEditProps, BatchEditStates, FormExposed } from '../../types'
5
+
6
+ interface Options {
7
+ props: BatchEditProps
8
+ formRef: ShallowRef<FormExposed | null>
9
+ }
10
+
11
+ export function useEditState(options: Options) {
12
+ const { props, formRef } = options
13
+
14
+ const defaultState: BatchEditStates = {
15
+ depth: -1,
16
+ formVisible: false,
17
+ formActionType: 'create',
18
+ loading: false,
19
+ indexPath: []
20
+ }
21
+
22
+ const state = shallowReactive({ ...defaultState })
23
+
24
+ function resetState() {
25
+ if (state.row) {
26
+ state.row.isCurrent = false
27
+ }
28
+
29
+ Object.keys(state).forEach((key) => {
30
+ delete state[key]
31
+ })
32
+
33
+ Object.assign(state, defaultState)
34
+ }
35
+
36
+ watch(
37
+ () => state.row,
38
+ (row) => {
39
+ formRef.value?.reset()
40
+
41
+ if (row) {
42
+ /** 延迟设置 model,防止表单初始状态丢失 */
43
+ nextTick(() => {
44
+ if (props.model) {
45
+ o(props.model).deepExtend(row.data)
46
+ }
47
+ })
48
+ state.formActionType = props.readonly ? 'view' : 'update'
49
+ state.formVisible = true
50
+ state.depth = row.depth
51
+ state.indexPath = [...row.indexes]
52
+
53
+ return
54
+ }
55
+
56
+ resetState()
57
+ }
58
+ )
59
+
60
+ return { state, resetState }
61
+ }