@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.
- package/dist/components/action/action-group.vue.d.ts +2 -2
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
- package/dist/components/batch-edit/batch-edit-form.js +41 -79
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-list.js +17 -29
- package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js +34 -60
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -14
- package/dist/components/batch-edit/di.js.map +1 -1
- package/dist/components/batch-edit/form-action-header.js +25 -0
- package/dist/components/batch-edit/form-action-header.js.map +1 -0
- package/dist/components/batch-edit/style2.css +0 -13
- package/dist/components/batch-edit/use-edit-state.js +40 -0
- package/dist/components/batch-edit/use-edit-state.js.map +1 -0
- package/dist/components/batch-edit/use-handlers.js +146 -0
- package/dist/components/batch-edit/use-handlers.js.map +1 -0
- package/dist/components/batch-edit/use-shortcut-key.js +44 -0
- package/dist/components/batch-edit/use-shortcut-key.js.map +1 -0
- package/dist/components/cascade/cascade.vue.d.ts +4 -4
- package/dist/components/checkbox/checkbox-button.vue.d.ts +2 -2
- package/dist/components/checkbox/checkbox.vue.d.ts +1 -1
- package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
- package/dist/components/code-editor/code-editor.vue.d.ts +1 -1
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
- package/dist/components/empty/empty.vue.d.ts +1 -1
- package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/form/form.vue.d.ts +5 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form-item/form-item.js.map +1 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input/input.vue.d.ts +8 -8
- package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +6 -6
- package/dist/components/number-input/number-input.vue.d.ts +4 -4
- package/dist/components/number-range-input/number-range-input.vue.d.ts +2 -2
- package/dist/components/palette/palette.vue.d.ts +1 -1
- package/dist/components/password-input/password-input.vue.d.ts +2 -2
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/progress-nodes/progress-nodes.vue.d.ts +1 -1
- package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
- package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +2 -2
- package/dist/components/scroll/scroll.vue.d.ts +2 -2
- package/dist/components/select/select.vue.d.ts +2 -2
- package/dist/components/steps/steps.vue.d.ts +3 -3
- package/dist/components/switch/switch.vue.d.ts +1 -1
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
- package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
- package/dist/components/tabs/tabs.vue.d.ts +2 -2
- package/dist/components/textarea/textarea.vue.d.ts +4 -4
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tree/tree.vue.d.ts +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +6 -6
- package/dist/index.d.ts +4 -4
- package/dist/types/batch-edit.d.ts +38 -12
- package/dist/types/form.d.ts +4 -1
- package/dist/types/index.d.ts +3 -3
- package/package.json +6 -6
- package/src/components/batch-edit/batch-edit-form.vue +40 -86
- package/src/components/batch-edit/batch-edit-list.vue +13 -29
- package/src/components/batch-edit/batch-edit.vue +27 -92
- package/src/components/batch-edit/di.ts +6 -5
- package/src/components/batch-edit/form-action-header.ts +21 -0
- package/src/components/batch-edit/style.scss +0 -14
- package/src/components/batch-edit/use-dialog-effect.ts +21 -0
- package/src/components/batch-edit/use-edit-state.ts +55 -0
- package/src/components/batch-edit/use-handlers.ts +226 -0
- package/src/components/batch-edit/use-shortcut-key.ts +58 -0
- package/src/components/form/form.vue +10 -3
- package/src/components/form-item/form-item.vue +4 -2
- package/src/types/batch-edit.ts +43 -22
- package/src/types/form.ts +4 -0
- package/dist/components/batch-edit/use-edit.js +0 -215
- package/dist/components/batch-edit/use-edit.js.map +0 -1
- package/src/components/batch-edit/use-edit.ts +0 -343
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import { ActionProps } from "./action.js";
|
|
2
|
-
import { TableColumn, TableEmits, TableProps, TableRow } from "./table.js";
|
|
2
|
+
import { TableColumn, TableColumnSlotsScope, TableEmits, TableProps, TableRow } from "./table.js";
|
|
3
3
|
import { DeconstructValue } from "@veltra/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/types/batch-edit.d.ts
|
|
6
6
|
/** 批量编辑列 */
|
|
7
7
|
interface BatchEditColumn extends TableColumn {}
|
|
8
|
-
type BatchEditFeature = 'create' | 'update' | '
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
type BatchEditFeature = 'create' | 'update' | 'delete' | 'view' | 'createChild';
|
|
9
|
+
type BatchEditFormStatus = 'hidden';
|
|
10
|
+
/** 批量编辑状态 */
|
|
11
|
+
interface BatchEditStates {
|
|
12
|
+
/** 层级 */
|
|
13
|
+
depth: number;
|
|
14
|
+
/** 表单可见性 */
|
|
15
|
+
formVisible: boolean;
|
|
16
|
+
/** 表单操作类型 */
|
|
17
|
+
formActionType: 'create' | 'update' | 'view' | 'createChild';
|
|
18
|
+
/** 加载状态 */
|
|
19
|
+
loading: boolean;
|
|
20
|
+
/** 当前编辑行 */
|
|
21
|
+
row?: TableRow;
|
|
22
|
+
/** 当前编辑或者新增的父级行 */
|
|
23
|
+
parentRow?: TableRow;
|
|
24
|
+
/** 行索引路径, */
|
|
25
|
+
indexPath: number[];
|
|
26
|
+
}
|
|
11
27
|
/** 批量编辑组件属性 */
|
|
12
28
|
interface BatchEditProps extends TableProps {
|
|
13
29
|
/**
|
|
@@ -24,14 +40,13 @@ interface BatchEditProps extends TableProps {
|
|
|
24
40
|
/** 只读模式 */
|
|
25
41
|
readonly?: boolean;
|
|
26
42
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
29
|
-
* @description `quick` 模式下编辑行时表单直接绑定 `row.data` 实时更新,且不调用 `saveMethod`
|
|
43
|
+
* 开启快速编辑
|
|
44
|
+
* @description 开启后,编辑行时表单实时写回 `row.data`(经 `model` 中转),且不调用 `saveMethod`
|
|
30
45
|
*/
|
|
31
|
-
|
|
46
|
+
quickEdit?: boolean;
|
|
32
47
|
/**
|
|
33
48
|
* 新增前的钩子
|
|
34
|
-
* @description 仅作用于 create
|
|
49
|
+
* @description 仅作用于 create 类操作,在保存时调用。可直接修改传入的 draft 对象
|
|
35
50
|
*/
|
|
36
51
|
beforeCreate?: (data: Record<string, any>, parentData?: Record<string, any>) => void | Promise<void>;
|
|
37
52
|
/** label的宽度 */
|
|
@@ -40,14 +55,14 @@ interface BatchEditProps extends TableProps {
|
|
|
40
55
|
deleteMethod?: (data: Record<string, any>[]) => any;
|
|
41
56
|
/**
|
|
42
57
|
* 保存方法
|
|
43
|
-
* @description
|
|
58
|
+
* @description 保存时调用。`quick` 模式下编辑行时实时写回,不调用此方法;新增时与 `normal` 模式一致
|
|
44
59
|
* @returns 如果返回一个值,那么这个值会被插入,否则插入的为表单值
|
|
45
60
|
*/
|
|
46
61
|
saveMethod?: (/** 表单数据 */
|
|
47
62
|
|
|
48
63
|
data: Record<string, any>, /** 操作类型 */
|
|
49
64
|
|
|
50
|
-
actionType: '
|
|
65
|
+
actionType: BatchEditStates['formActionType'], /** 父级数据 */
|
|
51
66
|
|
|
52
67
|
parentData?: Record<string, any>) => any;
|
|
53
68
|
/**
|
|
@@ -84,10 +99,21 @@ interface BatchEditEmits extends TableEmits {
|
|
|
84
99
|
/** 更新数据 */
|
|
85
100
|
(e: 'update:data', value: Record<string, any>[]): void;
|
|
86
101
|
}
|
|
102
|
+
type BatchEditSlots = {
|
|
103
|
+
form?: (props: {
|
|
104
|
+
/** 当前编辑的层级 */depth?: number; /** 当前编辑的行 */
|
|
105
|
+
row?: TableRow; /** 当前编辑的行索引 */
|
|
106
|
+
index?: number; /** 操作的目标行索引路径 */
|
|
107
|
+
indexes?: number[];
|
|
108
|
+
}) => any;
|
|
109
|
+
header?: () => any;
|
|
110
|
+
} & Partial<{
|
|
111
|
+
[key: `column:${string}`]: (props: TableColumnSlotsScope) => any;
|
|
112
|
+
}>;
|
|
87
113
|
/** 批量编辑组件暴露的属性和方法(组件内部使用) */
|
|
88
114
|
interface _BatchEditExposed {}
|
|
89
115
|
/** 批量编辑组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
90
116
|
type BatchEditExposed = DeconstructValue<_BatchEditExposed>;
|
|
91
117
|
//#endregion
|
|
92
|
-
export { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature,
|
|
118
|
+
export { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, _BatchEditExposed };
|
|
93
119
|
//# sourceMappingURL=batch-edit.d.ts.map
|
package/dist/types/form.d.ts
CHANGED
|
@@ -20,6 +20,9 @@ interface FormProps extends ComponentProps {
|
|
|
20
20
|
/** 是否禁用 */
|
|
21
21
|
disabled?: boolean;
|
|
22
22
|
}
|
|
23
|
+
interface FormEmits {
|
|
24
|
+
(e: 'field:change', field: string, value: any): void;
|
|
25
|
+
}
|
|
23
26
|
interface _FormExposed {
|
|
24
27
|
el: ShallowRef<HTMLElement | null | undefined>;
|
|
25
28
|
validate: (keys?: string[]) => Promise<boolean>;
|
|
@@ -29,5 +32,5 @@ interface _FormExposed {
|
|
|
29
32
|
}
|
|
30
33
|
type FormExposed = DeconstructValue<_FormExposed>;
|
|
31
34
|
//#endregion
|
|
32
|
-
export { FormExposed, FormProps, _FormExposed };
|
|
35
|
+
export { FormEmits, FormExposed, FormProps, _FormExposed };
|
|
33
36
|
//# sourceMappingURL=form.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { DatePanelEmits, DatePanelProps, PanelType } from "./date-panel.js";
|
|
|
24
24
|
import { DialogEmits, DialogExposed, DialogProps, DialogTransition, _DialogExposed } from "./dialog.js";
|
|
25
25
|
import { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, _ActionExposed, _ActionGroupExposed } from "./action.js";
|
|
26
26
|
import { TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, _TableExposed } from "./table.js";
|
|
27
|
-
import { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature,
|
|
27
|
+
import { BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, _BatchEditExposed } from "./batch-edit.js";
|
|
28
28
|
import { BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, _BreadcrumbExposed } from "./breadcrumb.js";
|
|
29
29
|
import { ListEmits, ListExposed, ListProps, _ListExposed } from "./list.js";
|
|
30
30
|
import { EmptyEmits, EmptyExposed, EmptyProps, _EmptyExposed } from "./empty.js";
|
|
@@ -33,7 +33,7 @@ import { FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps
|
|
|
33
33
|
import { CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, _CalendarExposed } from "./calendar.js";
|
|
34
34
|
import { PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, _PaletteExposed } from "./palette.js";
|
|
35
35
|
import { InputEmits, InputExposed, InputProps, _InputExposed } from "./input.js";
|
|
36
|
-
import { FormExposed, FormProps, _FormExposed } from "./form.js";
|
|
36
|
+
import { FormEmits, FormExposed, FormProps, _FormExposed } from "./form.js";
|
|
37
37
|
import { UploaderEmits, UploaderExposed, UploaderProps, _UploaderExposed } from "./file-picker.js";
|
|
38
38
|
import { PopEmits, PopExposed, PopProps, _PopExposed } from "./pop.js";
|
|
39
39
|
import { GridInputEmits, GridInputExposed, GridInputProps, _GridInputExposed } from "./grid-input.js";
|
|
@@ -82,7 +82,7 @@ export type * from "@veltra/utils";
|
|
|
82
82
|
|
|
83
83
|
//#region src/types/index.d.ts
|
|
84
84
|
declare namespace index_d_exports {
|
|
85
|
-
export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature,
|
|
85
|
+
export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditFormStatus, BatchEditProps, BatchEditSlots, BatchEditStates, BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, BreakCols, Breakpoint, ButtonEmits, ButtonExposed, ButtonProps, ButtonType, CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, CardActionProps, CardContentProps, CardCoverProps, CardEmits, CardExposed, CardProps, CascadeEmits, CascadeExposed, CascadeNode, CascadeProps, CheckTagEmits, CheckTagExposed, CheckTagProps, CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxGroupEmits, CheckboxGroupExposed, CheckboxGroupProps, CheckboxProps, CodeEditorEmits, CodeEditorExposed, CodeEditorLang, CodeEditorProps, CollapseEmits, CollapseItemProps, CollapseModelValue, CollapseProps, CollapseValue, ConditionConnector, ConditionEditorEmits, ConditionEditorExposed, ConditionEditorProps, ConditionExpression, ConditionField, ConditionGroup, ConditionLeaf, ConditionNode, ConditionValue, ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, CssTransitionEmits, CssTransitionExposed, CssTransitionProps, DatePanelEmits, DatePanelProps, DatePickerEmits, DatePickerExposed, DatePickerProps, DateRangePickerEmits, DateRangePickerExposed, DateRangePickerProps, DialogEmits, DialogExposed, DialogProps, DialogTransition, DrawerDirection, DrawerEmits, DrawerExposed, DrawerMode, DrawerProps, DropdownEmits, DropdownExposed, DropdownProps, DualNavEmits, DualNavExposed, DualNavProps, DualNavRootItem, EmptyEmits, EmptyExposed, EmptyProps, ExpressionEditorEmits, ExpressionEditorExposed, ExpressionEditorProps, ExpressionSelectableLevels, FileViewerEmits, FileViewerExposed, FileViewerItem, FileViewerKind, FileViewerProps, FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps, FormEmits, FormExposed, FormItemEmits, FormItemExposed, FormItemProps, FormProps, GanttChartEmits, GanttChartExposed, GanttChartProps, GridEmits, GridExposed, GridInputEmits, GridInputExposed, GridInputProps, GridItemProps, GridProps, GroupInputEmits, GroupInputExposed, GroupInputProps, IconEmits, IconExposed, IconProps, InputEmits, InputExposed, InputProps, LayoutEmits, LayoutExposed, LayoutProps, ListEmits, ListExposed, ListProps, LoadingEmits, LoadingExposed, LoadingProps, LoadingType, Message, MessageConfirmEmits, MessageConfirmExposed, MessageConfirmProps, MessageEmits, MessageExposed, MessageInstance, MessageOptions, MessageProps, MessageType, MultiAutoCompleteEmits, MultiAutoCompleteExposed, MultiAutoCompleteProps, MultiSelectEmits, MultiSelectExposed, MultiSelectProps, MultiTreeSelectEmits, MultiTreeSelectExposed, MultiTreeSelectProps, NavEmits, NavExposed, NavItem, NavProps, NodeRenderExposed, NodeRenderProps, NotificationEmits, NotificationExposed, NotificationProps, NumberEmits, NumberExposed, NumberInputEmits, NumberInputExposed, NumberInputProps, NumberProps, NumberRangeInputEmits, NumberRangeInputExposed, NumberRangeInputProps, NumberRangeTuple, PaginatorEmits, PaginatorExposed, PaginatorProps, PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, PanelItem, PanelType, PasswordInputEmits, PasswordInputExposed, PasswordInputProps, PopConfirmEmits, PopConfirmExposed, PopConfirmProps, PopEmits, PopExposed, PopProps, ProgressEmits, ProgressExposed, ProgressNodesEmits, ProgressNodesExposed, ProgressNodesProps, ProgressProps, QuickBatchEditEmits, QuickBatchEditExposed, QuickBatchEditProps, RadioEmits, RadioExposed, RadioGroupEmits, RadioGroupExposed, RadioGroupProps, RadioProps, RichTextEditorEmits, RichTextEditorExposed, RichTextEditorProps, RichTextFormat, ScrollEmits, ScrollExposed, ScrollPosition, ScrollProps, SelectEmits, SelectExposed, SelectProps, SliderEmits, SliderExposed, SliderProps, StepsEmits, StepsExposed, StepsProps, StepsSlotScope, SwitchEmits, SwitchExposed, SwitchProps, TabItem, TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEditorEmits, TableEditorExposed, TableEditorProps, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, TabsEmits, TabsExposed, TabsHorizontalEmits, TabsHorizontalExposed, TabsHorizontalProps, TabsProps, TabsVerticalEmits, TabsVerticalExposed, TabsVerticalProps, TagEmits, TagExposed, TagProps, TextEditorEmits, TextEditorExposed, TextEditorProps, TextEmits, TextExposed, TextProps, TextareaEmits, TextareaExposed, TextareaProps, ThemeExposed, ThemeProps, TipAlign, TipDirection, TipEmits, TipExposed, TipProps, ToolbarItem, TreeEmit, TreeExposed, TreeNode, TreeNodeProps, TreeProps, TreeSelectEmits, TreeSelectExposed, TreeSelectProps, UploaderEmits, UploaderExposed, UploaderProps, VariableItem, WatermarkEmits, WatermarkExposed, WatermarkProps, _ActionExposed, _ActionGroupExposed, _AnimationExposed, _AutoCompleteExposed, _BadgeExposed, _BatchEditExposed, _BreadcrumbExposed, _ButtonExposed, _CalendarExposed, _CardExposed, _CascadeExposed, _CheckTagExposed, _CodeEditorExposed, _ConditionEditorExposed, _ContextmenuExposed, _CssTransitionExposed, _DatePickerExposed, _DateRangePickerExposed, _DialogExposed, _DrawerExposed, _DropdownExposed, _DualNavExposed, _EmptyExposed, _ExpressionEditorExposed, _FileViewerExposed, _FloatButtonExposed, _FormExposed, _GanttChartExposed, _GridExposed, _GridInputExposed, _GroupInputExposed, _InputExposed, _LayoutExposed, _ListExposed, _LoadingExposed, _MessageConfirmExposed, _MessageExposed, _MultiAutoCompleteExposed, _MultiSelectExposed, _MultiTreeSelectExposed, _NavExposed, _NotificationExposed, _PaginatorExposed, _PaletteExposed, _PasswordInputExposed, _PopConfirmExposed, _PopExposed, _ProgressExposed, _ProgressNodesExposed, _QuickBatchEditExposed, _RadioExposed, _RadioGroupExposed, _RichTextEditorExposed, _ScrollExposed, _SelectExposed, _SliderExposed, _StepsExposed, _SwitchExposed, _TableEditorExposed, _TableExposed, _TabsExposed, _TabsHorizontalExposed, _TabsVerticalExposed, _TextEditorExposed, _TextExposed, _TextareaExposed, _ThemeExposed, _TipExposed, _TreeExposed, _TreeSelectExposed, _UploaderExposed, _WatermarkExposed };
|
|
86
86
|
}
|
|
87
87
|
import * as import__veltra_utils from "@veltra/utils";
|
|
88
88
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veltra/desktop",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"src"
|
|
@@ -68,11 +68,11 @@
|
|
|
68
68
|
"@cat-kit/core": ">=1.1.6",
|
|
69
69
|
"@cat-kit/excel": ">=1.0.0",
|
|
70
70
|
"@cat-kit/fe": "^1.1.6",
|
|
71
|
-
"@veltra/compositions": "1.2.
|
|
72
|
-
"@veltra/directives": "1.2.
|
|
73
|
-
"@veltra/icons": "1.2.
|
|
74
|
-
"@veltra/styles": "1.2.
|
|
75
|
-
"@veltra/utils": "1.2.
|
|
71
|
+
"@veltra/compositions": "1.2.9",
|
|
72
|
+
"@veltra/directives": "1.2.9",
|
|
73
|
+
"@veltra/icons": "1.2.9",
|
|
74
|
+
"@veltra/styles": "1.2.9",
|
|
75
|
+
"@veltra/utils": "1.2.9",
|
|
76
76
|
"vue": ">=3.5.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<aside :class="cls.e('form')" v-if="state.
|
|
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(
|
|
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')"
|
|
@@ -27,15 +24,16 @@
|
|
|
27
24
|
<transition name="fade" appear mode="out-in">
|
|
28
25
|
<u-form
|
|
29
26
|
ref="formComponentRef"
|
|
30
|
-
:model="
|
|
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:
|
|
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')"
|
|
48
|
-
|
|
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
|
-
<
|
|
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,10 +64,12 @@
|
|
|
73
64
|
</template>
|
|
74
65
|
|
|
75
66
|
<script lang="ts" setup>
|
|
76
|
-
import {
|
|
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
|
|
70
|
+
import { computed, inject, shallowRef, toRef } from 'vue'
|
|
79
71
|
|
|
72
|
+
import type { BatchEditSlots } from '../../types'
|
|
80
73
|
import type { _FormExposed, FormExposed } from '../../types/form'
|
|
81
74
|
import { UButton } from '../button'
|
|
82
75
|
import { UForm } from '../form'
|
|
@@ -84,21 +77,13 @@ import { UIcon } from '../icon'
|
|
|
84
77
|
import { UKbd } from '../kbd'
|
|
85
78
|
import { UScroll } from '../scroll'
|
|
86
79
|
import { BatchEditDIKey } from './di'
|
|
80
|
+
import { FORM_ACTION_HEADER_MAP } from './form-action-header'
|
|
87
81
|
|
|
88
82
|
defineOptions({ name: 'BatchEditForm' })
|
|
89
83
|
|
|
90
84
|
const batchEditCtx = inject(BatchEditDIKey)!
|
|
91
85
|
|
|
92
|
-
const {
|
|
93
|
-
cls,
|
|
94
|
-
props,
|
|
95
|
-
state,
|
|
96
|
-
insertIndexes,
|
|
97
|
-
handleSave,
|
|
98
|
-
handleClose,
|
|
99
|
-
staticFeatures,
|
|
100
|
-
dynamicFeatures
|
|
101
|
-
} = batchEditCtx
|
|
86
|
+
const { cls, props, state, handleClose, handleSave, staticFeatures, dynamicFeatures } = batchEditCtx
|
|
102
87
|
|
|
103
88
|
const focused = toRef(batchEditCtx, 'focused')
|
|
104
89
|
|
|
@@ -111,68 +96,37 @@ defineExpose<_FormExposed>({
|
|
|
111
96
|
reset: () => formComponentRef.value?.reset()
|
|
112
97
|
})
|
|
113
98
|
|
|
99
|
+
function handleFieldChange(field: string, value: any) {
|
|
100
|
+
if (state.row && props.quickEdit) {
|
|
101
|
+
o(state.row.data).set(field, value)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
114
105
|
const creatable = computed(() => {
|
|
115
|
-
return
|
|
116
|
-
|
|
117
|
-
(staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row))
|
|
118
|
-
)
|
|
106
|
+
if (state.formActionType !== 'create') return false
|
|
107
|
+
return staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row)
|
|
119
108
|
})
|
|
120
109
|
|
|
121
|
-
const
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
(staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row))
|
|
125
|
-
)
|
|
110
|
+
const creatableChild = computed(() => {
|
|
111
|
+
if (state.formActionType !== 'createChild') return false
|
|
112
|
+
return staticFeatures.value.has('createChild') || dynamicFeatures.value.createChild?.(state.row)
|
|
126
113
|
})
|
|
127
114
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const formModel = computed(() => {
|
|
133
|
-
if (isQuick.value && state.type === 'update' && state.row) {
|
|
134
|
-
return state.row.data
|
|
135
|
-
}
|
|
136
|
-
return props.model
|
|
115
|
+
const updatable = computed(() => {
|
|
116
|
+
if (state.formActionType !== 'update') return false
|
|
117
|
+
return staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row)
|
|
137
118
|
})
|
|
138
119
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
tone: 'create' | 'update' | 'view' | 'child'
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const headerInfo = computed<HeaderInfo>(() => {
|
|
147
|
-
if (props.readonly) {
|
|
148
|
-
return {
|
|
149
|
-
icon: View,
|
|
150
|
-
title: '查看详情',
|
|
151
|
-
chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
|
|
152
|
-
tone: 'view'
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (state.parentRow) {
|
|
156
|
-
return {
|
|
157
|
-
icon: AddChild,
|
|
158
|
-
title: '新增子级',
|
|
159
|
-
chip: `归属于第 ${state.parentRow.index + 1} 行`,
|
|
160
|
-
tone: 'child'
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (state.type === 'create') {
|
|
164
|
-
return { icon: Plus, title: '新增', tone: 'create' }
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
icon: EditPen,
|
|
168
|
-
title: '编辑',
|
|
169
|
-
chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,
|
|
170
|
-
tone: 'update'
|
|
171
|
-
}
|
|
120
|
+
const showSaveBtn = computed(() => {
|
|
121
|
+
if (props.readonly) return false
|
|
122
|
+
if (props.quickEdit && state.formActionType === 'update') return false
|
|
123
|
+
return creatable.value || updatable.value || creatableChild.value
|
|
172
124
|
})
|
|
173
125
|
|
|
126
|
+
const headerInfo = computed(() => FORM_ACTION_HEADER_MAP[state.formActionType])
|
|
127
|
+
|
|
174
128
|
/** 通过 row 切换 / 类型切换驱动表单内容淡出淡入 */
|
|
175
129
|
const bodyKey = computed(() => {
|
|
176
|
-
return `${state.
|
|
130
|
+
return `${state.formActionType}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`
|
|
177
131
|
})
|
|
178
132
|
</script>
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
<u-table
|
|
3
3
|
v-bind="tableProps"
|
|
4
4
|
:slots="slots"
|
|
5
|
-
:class="[cls.e('table')
|
|
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
|
-
|
|
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,
|
|
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'
|
|
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"
|
|
14
|
+
<BatchEditList :slots="slots" />
|
|
15
15
|
|
|
16
16
|
<!-- 编辑表单 -->
|
|
17
|
-
<BatchEditForm ref="
|
|
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,
|
|
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 {
|
|
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
|
|
72
|
-
|
|
73
|
-
const
|
|
47
|
+
const formRef = useTemplateRef<FormExposed>('form')
|
|
48
|
+
|
|
49
|
+
const { state, resetState } = useEditState({ props })
|
|
74
50
|
|
|
75
51
|
const { staticFeatures, dynamicFeatures } = useFeatures({ props })
|
|
76
52
|
|
|
77
|
-
const
|
|
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
|
|
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
|
-
|
|
71
|
+
state,
|
|
86
72
|
staticFeatures,
|
|
87
73
|
dynamicFeatures,
|
|
88
74
|
focused,
|
|
89
|
-
...
|
|
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>
|