v-nuxt-ui 0.2.25 → 0.2.27
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/README.md +6 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/AsyncSelect.vue +16 -1
- package/dist/runtime/components/AsyncTreeSelect.vue +15 -9
- package/dist/runtime/components/DeleteModal.d.vue.ts +25 -22
- package/dist/runtime/components/DeleteModal.vue +39 -4
- package/dist/runtime/components/DeleteModal.vue.d.ts +25 -22
- package/dist/runtime/components/ScrollArea.vue +20 -9
- package/dist/runtime/components/form/save-modal-template/ConfirmUpdateModal.d.vue.ts +19 -0
- package/dist/runtime/components/form/save-modal-template/ConfirmUpdateModal.vue +111 -0
- package/dist/runtime/components/form/save-modal-template/ConfirmUpdateModal.vue.d.ts +19 -0
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/WithApi.d.vue.ts +2 -2
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/WithApi.vue +4 -3
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/WithApi.vue.d.ts +2 -2
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/index.d.vue.ts +2 -2
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/index.vue +54 -7
- package/dist/runtime/components/form/{create-modal-template → save-modal-template}/index.vue.d.ts +2 -2
- package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.d.vue.ts +19 -0
- package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.vue +111 -0
- package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.vue.d.ts +19 -0
- package/dist/runtime/components/form/save-model-template/WithApi.d.vue.ts +19 -0
- package/dist/runtime/components/form/save-model-template/WithApi.vue +37 -0
- package/dist/runtime/components/form/save-model-template/WithApi.vue.d.ts +19 -0
- package/dist/runtime/components/form/save-model-template/index.d.vue.ts +21 -0
- package/dist/runtime/components/form/save-model-template/index.vue +123 -0
- package/dist/runtime/components/form/save-model-template/index.vue.d.ts +21 -0
- package/dist/runtime/components/layout/button/UserMenu.vue +1 -2
- package/dist/runtime/components/sys/company/{CreateModal.vue → SaveModal.vue} +2 -2
- package/dist/runtime/components/sys/company/Table.vue +5 -4
- package/dist/runtime/components/sys/department/{CreateModal.vue → SaveModal.vue} +3 -2
- package/dist/runtime/components/sys/department/Table.vue +6 -5
- package/dist/runtime/components/sys/flow/EditNodeModal.vue +4 -3
- package/dist/runtime/components/sys/flow/{CreateModal.vue → SaveModal.vue} +3 -2
- package/dist/runtime/components/sys/flow/Table.vue +5 -4
- package/dist/runtime/components/sys/issue-record/{CreateModal.vue → SaveModal.vue} +2 -2
- package/dist/runtime/components/sys/issue-record/Table.vue +5 -4
- package/dist/runtime/components/sys/job-title/{CreateModal.vue → SaveModal.vue} +2 -2
- package/dist/runtime/components/sys/job-title/Table.vue +5 -4
- package/dist/runtime/components/sys/menu/{CreateModal.vue → SaveModal.vue} +3 -2
- package/dist/runtime/components/sys/menu/Table.vue +6 -5
- package/dist/runtime/components/sys/role/{CreateModal.vue → SaveModal.vue} +8 -5
- package/dist/runtime/components/sys/role/Table.vue +5 -4
- package/dist/runtime/components/sys/table/{CreateModal.vue → SaveModal.vue} +4 -3
- package/dist/runtime/components/sys/table/Table.vue +4 -4
- package/dist/runtime/components/sys/table/TableColumnModal.vue +4 -3
- package/dist/runtime/components/sys/user/{CreateModal.vue → SaveModal.vue} +4 -3
- package/dist/runtime/components/sys/user/Table.vue +7 -6
- package/dist/runtime/components/table/Page.vue +2 -1
- package/dist/runtime/components/table/UpdateDiffModal.d.vue.ts +14 -0
- package/dist/runtime/components/table/UpdateDiffModal.vue +156 -0
- package/dist/runtime/components/table/UpdateDiffModal.vue.d.ts +14 -0
- package/dist/runtime/components/table/header/index.vue +181 -183
- package/dist/runtime/components/table/index.vue +2 -1
- package/dist/runtime/composables/form/index.d.ts +2 -0
- package/dist/runtime/composables/form/index.js +2 -0
- package/dist/runtime/composables/form/useForm.d.ts +21 -0
- package/dist/runtime/composables/{useForm.js → form/useForm.js} +23 -1
- package/dist/runtime/composables/form/useFormUpdate.d.ts +6 -0
- package/dist/runtime/composables/form/useFormUpdate.js +101 -0
- package/dist/runtime/composables/index.d.ts +1 -1
- package/dist/runtime/composables/index.js +1 -1
- package/dist/runtime/composables/table/useTable.js +10 -1
- package/dist/runtime/composables/table/useTableRowActions.d.ts +3 -0
- package/dist/runtime/composables/table/useTableRowActions.js +24 -0
- package/dist/runtime/composables/useDate.js +2 -0
- package/dist/runtime/types/components/form/field.d.ts +2 -0
- package/dist/runtime/types/components/form/index.d.ts +4 -3
- package/dist/runtime/types/components/table/header.d.ts +2 -0
- package/dist/runtime/types/components/table/index.d.ts +1 -0
- package/dist/runtime/types/time.d.ts +1 -1
- package/dist/runtime/utils/cron.d.ts +1 -0
- package/dist/runtime/utils/cron.js +182 -0
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +1 -0
- package/dist/runtime/utils/vueuse.d.ts +1 -1
- package/dist/runtime/utils/vueuse.js +1 -0
- package/package.json +16 -15
- package/dist/runtime/composables/useForm.d.ts +0 -9
- /package/dist/runtime/components/sys/company/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/company/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/department/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/department/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/flow/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/flow/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/issue-record/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/issue-record/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/job-title/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/job-title/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/menu/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/menu/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/role/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/role/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/table/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/table/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
- /package/dist/runtime/components/sys/user/{CreateModal.d.vue.ts → SaveModal.d.vue.ts} +0 -0
- /package/dist/runtime/components/sys/user/{CreateModal.vue.d.ts → SaveModal.vue.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
2
|
+
import { markRaw } from "vue";
|
|
3
3
|
import { defu } from "defu";
|
|
4
4
|
import { useOverlay } from "@nuxt/ui/composables";
|
|
5
5
|
import UButton from "@nuxt/ui/components/Button.vue";
|
|
@@ -21,6 +21,8 @@ const props = defineProps({
|
|
|
21
21
|
fetchList: { type: Function, required: true },
|
|
22
22
|
onEditRowFromModal: { type: Function, required: false },
|
|
23
23
|
selectedIds: { type: Array, required: false },
|
|
24
|
+
selectedModels: { type: Array, required: false },
|
|
25
|
+
displayFnInDeleteModal: { type: Function, required: false },
|
|
24
26
|
disableCreation: { type: Boolean, required: false },
|
|
25
27
|
disableWhereQuery: { type: Boolean, required: false },
|
|
26
28
|
whereQueryProps: { type: Object, required: true },
|
|
@@ -36,190 +38,186 @@ const props = defineProps({
|
|
|
36
38
|
});
|
|
37
39
|
const defaultNewRow = { id: 0 };
|
|
38
40
|
const overlay = useOverlay();
|
|
39
|
-
const deleteModal = overlay.create(DeleteModal);
|
|
40
|
-
const settingsModal = overlay.create(TableHeaderSettings);
|
|
41
|
-
const excelExportModal = overlay.create(TableExcelExportModal);
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
() => "\u65B0\u589E"
|
|
60
|
-
);
|
|
61
|
-
case "refresh":
|
|
62
|
-
return h(
|
|
63
|
-
UButton,
|
|
64
|
-
{
|
|
65
|
-
icon: "i-lucide-refresh-ccw",
|
|
66
|
-
size: props.size,
|
|
67
|
-
color: "neutral",
|
|
68
|
-
loading: props.fetching,
|
|
69
|
-
variant: "outline",
|
|
70
|
-
onClick: () => props.fetchList()
|
|
71
|
-
},
|
|
72
|
-
() => "\u5237\u65B0"
|
|
73
|
-
);
|
|
74
|
-
case "whereQuery":
|
|
75
|
-
if (props.disableWhereQuery) return null;
|
|
76
|
-
return h(
|
|
77
|
-
UChip,
|
|
78
|
-
{ show: !props.whereQueryProps.isWhereQueryValueEmpty },
|
|
79
|
-
() => h(
|
|
80
|
-
UButton,
|
|
81
|
-
{
|
|
82
|
-
icon: "i-lucide-list-filter",
|
|
83
|
-
size: props.size,
|
|
84
|
-
color: props.whereQueryProps.whereQueryOpen ? "primary" : "neutral",
|
|
85
|
-
loading: props.fetching,
|
|
86
|
-
variant: "outline",
|
|
87
|
-
onClick: () => {
|
|
88
|
-
props.whereQueryProps.onUpdateWhereQueryOpen?.(!props.whereQueryProps.whereQueryOpen);
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
() => "\u67E5\u8BE2"
|
|
92
|
-
)
|
|
93
|
-
);
|
|
94
|
-
case "orderQuery":
|
|
95
|
-
if (props.disableOrderQuery) return null;
|
|
96
|
-
return h(
|
|
97
|
-
TableQueryOrder,
|
|
98
|
-
{ ...props.orderQueryProps, size: props.size }
|
|
99
|
-
);
|
|
100
|
-
case "settings":
|
|
101
|
-
if (props.disableSettings) return null;
|
|
102
|
-
return props.rawBizColumns && props.rawBizColumns.length > 0 && props.onUpdateBizColumns && h(
|
|
103
|
-
UButton,
|
|
104
|
-
{
|
|
105
|
-
icon: "i-lucide-settings",
|
|
106
|
-
size: props.size,
|
|
107
|
-
color: "neutral",
|
|
108
|
-
variant: "outline",
|
|
109
|
-
onClick: async () => {
|
|
110
|
-
if (!props.onUpdateBizColumns) return;
|
|
111
|
-
const updateFn = props.onUpdateBizColumns;
|
|
112
|
-
await settingsModal.open({
|
|
113
|
-
tblName: props.name,
|
|
114
|
-
rawBizColumns: props.rawBizColumns,
|
|
115
|
-
// 列数据由父组件创建(VColumn<T>),模态框仅重排顺序后返回,运行时类型不变
|
|
116
|
-
onUpdateBizColumns: ((cols) => updateFn(cols))
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
() => "\u8BBE\u7F6E"
|
|
121
|
-
);
|
|
122
|
-
case "exportExcel": {
|
|
123
|
-
if (!props.exportExcel) return null;
|
|
124
|
-
const exportButton = h(
|
|
125
|
-
UButton,
|
|
126
|
-
{
|
|
127
|
-
icon: "i-lucide-sheet",
|
|
128
|
-
size: props.size,
|
|
129
|
-
color: "neutral",
|
|
130
|
-
variant: "outline",
|
|
131
|
-
onClick: async () => {
|
|
132
|
-
await excelExportModal.open({
|
|
133
|
-
columns: props.rawBizColumns,
|
|
134
|
-
filename: props.exportExcel.filename,
|
|
135
|
-
filenameWithDateTime: props.exportExcel.filenameWithDateTime,
|
|
136
|
-
listFn: props.apiGroup?.().countAndList,
|
|
137
|
-
whereQueryOptions: props.whereQueryProps.whereOptions,
|
|
138
|
-
extraWhereQueryInitValues: defu(props.extraWhereQueryInitValues, props.exportExcel.extraWhereQueryInitValues)
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
() => "\u5BFC\u51FA"
|
|
143
|
-
);
|
|
144
|
-
if (!props.exportExcel.permissionKey) {
|
|
145
|
-
return exportButton;
|
|
146
|
-
}
|
|
147
|
-
return h(PermissionWrapper, { permission: props.exportExcel.permissionKey }, {
|
|
148
|
-
default: () => exportButton
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
case "batchDelete":
|
|
152
|
-
if (props.disableBatchDeletion) return null;
|
|
153
|
-
return props.selectedIds && props.selectedIds.length > 0 && h(
|
|
154
|
-
UButton,
|
|
155
|
-
{
|
|
156
|
-
icon: "i-lucide-trash-2",
|
|
157
|
-
size: props.size,
|
|
158
|
-
color: "error",
|
|
159
|
-
variant: "outline",
|
|
160
|
-
onClick: async () => {
|
|
161
|
-
const result = await deleteModal.open({
|
|
162
|
-
ids: props.selectedIds,
|
|
163
|
-
onDelete: (ids) => props.apiGroup?.().batchDelete({ ids })
|
|
164
|
-
}).result;
|
|
165
|
-
if (result) {
|
|
166
|
-
await props.fetchList();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
default: () => "\u6279\u91CF\u5220\u9664",
|
|
172
|
-
trailing: () => h(UKbd, { size: "sm" }, () => props.selectedIds?.length ?? 0)
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
default:
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
41
|
+
const deleteModal = markRaw(overlay.create(DeleteModal));
|
|
42
|
+
const settingsModal = markRaw(overlay.create(TableHeaderSettings));
|
|
43
|
+
const excelExportModal = markRaw(overlay.create(TableExcelExportModal));
|
|
44
|
+
function omitOnClick(button) {
|
|
45
|
+
const { onClick: _, ...rest } = button;
|
|
46
|
+
return rest;
|
|
47
|
+
}
|
|
48
|
+
async function handleCreate() {
|
|
49
|
+
const result = await props.onEditRowFromModal?.(props.onNew?.() ?? defaultNewRow);
|
|
50
|
+
if (result) {
|
|
51
|
+
props.fetchList();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function handleSettings() {
|
|
55
|
+
if (!props.onUpdateBizColumns) return;
|
|
56
|
+
const updateFn = props.onUpdateBizColumns;
|
|
57
|
+
await settingsModal.open({
|
|
58
|
+
tblName: props.name,
|
|
59
|
+
rawBizColumns: props.rawBizColumns,
|
|
60
|
+
onUpdateBizColumns: ((cols) => updateFn(cols))
|
|
178
61
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
62
|
+
}
|
|
63
|
+
async function handleExportExcel() {
|
|
64
|
+
await excelExportModal.open({
|
|
65
|
+
columns: props.rawBizColumns,
|
|
66
|
+
filename: props.exportExcel.filename,
|
|
67
|
+
filenameWithDateTime: props.exportExcel.filenameWithDateTime,
|
|
68
|
+
listFn: props.apiGroup?.().countAndList,
|
|
69
|
+
whereQueryOptions: props.whereQueryProps.whereOptions,
|
|
70
|
+
extraWhereQueryInitValues: defu(props.extraWhereQueryInitValues, props.exportExcel.extraWhereQueryInitValues)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function handleBatchDelete() {
|
|
74
|
+
const result = await deleteModal.open({
|
|
75
|
+
ids: props.selectedIds,
|
|
76
|
+
models: props.selectedModels,
|
|
77
|
+
displayFn: props.displayFnInDeleteModal,
|
|
78
|
+
onDelete: (ids) => props.apiGroup?.().batchDelete({ ids })
|
|
79
|
+
}).result;
|
|
80
|
+
if (result) {
|
|
81
|
+
await props.fetchList();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function onLeftExtraButtonClick(btn, e) {
|
|
85
|
+
if (btn.withBatchData && props.selectedIds && btn.batchFn) {
|
|
86
|
+
await btn.batchFn(props.selectedIds);
|
|
87
|
+
await props.fetchList();
|
|
88
|
+
}
|
|
89
|
+
const originalOnClick = btn.button.onClick;
|
|
90
|
+
if (Array.isArray(originalOnClick)) {
|
|
91
|
+
originalOnClick.forEach((fn) => fn?.(e));
|
|
92
|
+
} else {
|
|
93
|
+
originalOnClick?.(e);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function onRightExtraButtonClick(btn, e) {
|
|
97
|
+
if (btn.withBatchData && props.selectedIds && btn.batchFn) {
|
|
98
|
+
await btn.batchFn(props.selectedIds);
|
|
99
|
+
}
|
|
100
|
+
const originalOnClick = btn.button.onClick;
|
|
101
|
+
if (Array.isArray(originalOnClick)) {
|
|
102
|
+
originalOnClick.forEach((fn) => fn?.(e));
|
|
103
|
+
} else {
|
|
104
|
+
originalOnClick?.(e);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
221
107
|
</script>
|
|
222
108
|
|
|
223
109
|
<template>
|
|
224
|
-
<
|
|
110
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
111
|
+
<template v-for="(btn, i) in extraButtons" :key="`extra-left-${i}`">
|
|
112
|
+
<UButton
|
|
113
|
+
v-if="(!btn.withBatchData || selectedIds?.length) && btn.appendTo === 'left'"
|
|
114
|
+
v-bind="omitOnClick(btn.button)"
|
|
115
|
+
@click="(e) => onLeftExtraButtonClick(btn, e)"
|
|
116
|
+
/>
|
|
117
|
+
</template>
|
|
118
|
+
|
|
119
|
+
<template v-for="opr in oprOrder" :key="opr">
|
|
120
|
+
<UButton
|
|
121
|
+
v-if="opr === 'create' && !disableCreation"
|
|
122
|
+
icon="i-lucide-plus"
|
|
123
|
+
:size="size"
|
|
124
|
+
@click="handleCreate"
|
|
125
|
+
>
|
|
126
|
+
新增
|
|
127
|
+
</UButton>
|
|
128
|
+
|
|
129
|
+
<UButton
|
|
130
|
+
v-if="opr === 'refresh'"
|
|
131
|
+
icon="i-lucide-refresh-ccw"
|
|
132
|
+
:size="size"
|
|
133
|
+
color="neutral"
|
|
134
|
+
:loading="fetching"
|
|
135
|
+
variant="outline"
|
|
136
|
+
@click="fetchList"
|
|
137
|
+
>
|
|
138
|
+
刷新
|
|
139
|
+
</UButton>
|
|
140
|
+
|
|
141
|
+
<UChip
|
|
142
|
+
v-if="opr === 'whereQuery' && !disableWhereQuery"
|
|
143
|
+
:show="!whereQueryProps.isWhereQueryValueEmpty"
|
|
144
|
+
>
|
|
145
|
+
<UButton
|
|
146
|
+
icon="i-lucide-list-filter"
|
|
147
|
+
:size="size"
|
|
148
|
+
:color="whereQueryProps.whereQueryOpen ? 'primary' : 'neutral'"
|
|
149
|
+
:loading="fetching"
|
|
150
|
+
variant="outline"
|
|
151
|
+
@click="whereQueryProps.onUpdateWhereQueryOpen?.(!whereQueryProps.whereQueryOpen)"
|
|
152
|
+
>
|
|
153
|
+
查询
|
|
154
|
+
</UButton>
|
|
155
|
+
</UChip>
|
|
156
|
+
|
|
157
|
+
<TableQueryOrder
|
|
158
|
+
v-if="opr === 'orderQuery' && !disableOrderQuery"
|
|
159
|
+
v-bind="orderQueryProps"
|
|
160
|
+
:size="size"
|
|
161
|
+
/>
|
|
162
|
+
|
|
163
|
+
<UButton
|
|
164
|
+
v-if="opr === 'settings' && !disableSettings && rawBizColumns?.length && onUpdateBizColumns"
|
|
165
|
+
icon="i-lucide-settings"
|
|
166
|
+
:size="size"
|
|
167
|
+
color="neutral"
|
|
168
|
+
variant="outline"
|
|
169
|
+
@click="handleSettings"
|
|
170
|
+
>
|
|
171
|
+
设置
|
|
172
|
+
</UButton>
|
|
173
|
+
|
|
174
|
+
<template v-if="opr === 'exportExcel' && exportExcel">
|
|
175
|
+
<PermissionWrapper v-if="exportExcel.permissionKey" :permission="exportExcel.permissionKey">
|
|
176
|
+
<UButton
|
|
177
|
+
icon="i-lucide-sheet"
|
|
178
|
+
:size="size"
|
|
179
|
+
color="neutral"
|
|
180
|
+
variant="outline"
|
|
181
|
+
@click="handleExportExcel"
|
|
182
|
+
>
|
|
183
|
+
导出
|
|
184
|
+
</UButton>
|
|
185
|
+
</PermissionWrapper>
|
|
186
|
+
<UButton
|
|
187
|
+
v-else
|
|
188
|
+
icon="i-lucide-sheet"
|
|
189
|
+
:size="size"
|
|
190
|
+
color="neutral"
|
|
191
|
+
variant="outline"
|
|
192
|
+
@click="handleExportExcel"
|
|
193
|
+
>
|
|
194
|
+
导出
|
|
195
|
+
</UButton>
|
|
196
|
+
</template>
|
|
197
|
+
|
|
198
|
+
<UButton
|
|
199
|
+
v-if="opr === 'batchDelete' && !disableBatchDeletion && selectedIds?.length"
|
|
200
|
+
icon="i-lucide-trash-2"
|
|
201
|
+
:size="size"
|
|
202
|
+
color="error"
|
|
203
|
+
variant="outline"
|
|
204
|
+
@click="handleBatchDelete"
|
|
205
|
+
>
|
|
206
|
+
批量删除
|
|
207
|
+
<template #trailing>
|
|
208
|
+
<UKbd size="sm">
|
|
209
|
+
{{ selectedIds?.length ?? 0 }}
|
|
210
|
+
</UKbd>
|
|
211
|
+
</template>
|
|
212
|
+
</UButton>
|
|
213
|
+
</template>
|
|
214
|
+
|
|
215
|
+
<template v-for="(btn, i) in extraButtons" :key="`extra-right-${i}`">
|
|
216
|
+
<UButton
|
|
217
|
+
v-if="(!btn.withBatchData || selectedIds?.length) && btn.appendTo === 'right'"
|
|
218
|
+
v-bind="omitOnClick(btn.button)"
|
|
219
|
+
@click="(e) => onRightExtraButtonClick(btn, e)"
|
|
220
|
+
/>
|
|
221
|
+
</template>
|
|
222
|
+
</div>
|
|
225
223
|
</template>
|
|
@@ -43,7 +43,8 @@ const props = defineProps({
|
|
|
43
43
|
expandable: { type: Boolean, required: false },
|
|
44
44
|
expandVNode: { type: Function, required: false },
|
|
45
45
|
rowSpanColumns: { type: Array, required: false },
|
|
46
|
-
customRowCopyFn: { type: Function, required: false }
|
|
46
|
+
customRowCopyFn: { type: Function, required: false },
|
|
47
|
+
displayFnInDeleteModal: { type: Function, required: false }
|
|
47
48
|
});
|
|
48
49
|
const {
|
|
49
50
|
// data
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Ref, type MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import type { ApiGroup, BaseModel, VFormFieldProps } from '#v/types';
|
|
3
|
+
import type { ConfirmDiffItem } from '#v/components/form/save-modal-template/ConfirmUpdateModal.vue';
|
|
4
|
+
export declare const useFormValues: <T>(raw: Ref<T>, defaultValues?: Partial<T>) => {
|
|
5
|
+
oldValues: Ref<T>;
|
|
6
|
+
newValues: Ref<T>;
|
|
7
|
+
};
|
|
8
|
+
export declare const useFormSubmission: <T extends BaseModel>(oldValues: Ref<T>, newValues: Ref<T>, close: (ok: boolean) => void, save: (model: T) => void, apiGroup: () => ApiGroup<T>, arrayTypeFieldKeys?: (keyof T)[], rowKey?: keyof T, versionKey?: keyof T, getExtraFields?: () => Record<string, any>) => {
|
|
9
|
+
onSubmit: () => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
export declare const useConfirmDiff: (fields: MaybeRefOrGetter<VFormFieldProps[]>, diffItems: MaybeRefOrGetter<ConfirmDiffItem[]>, oldModelValue: MaybeRefOrGetter<Record<string, unknown>>, newModelValue: MaybeRefOrGetter<Record<string, unknown>>) => {
|
|
12
|
+
diffedItems: import("vue").ComputedRef<{
|
|
13
|
+
oldDisplay: string;
|
|
14
|
+
newDisplay: string;
|
|
15
|
+
parts: import("diff").ChangeObject<string>[];
|
|
16
|
+
field: VFormFieldProps | undefined;
|
|
17
|
+
fieldName: string;
|
|
18
|
+
oldValue: unknown;
|
|
19
|
+
newValue: unknown;
|
|
20
|
+
}[]>;
|
|
21
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ref, watch } from "vue";
|
|
1
|
+
import { ref, watch, computed, toValue } from "vue";
|
|
2
2
|
import { defu } from "defu";
|
|
3
3
|
import { getObjWithModifiedFields } from "#v/utils";
|
|
4
|
+
import { resolveDisplayValue, smartDiff } from "#v/composables";
|
|
4
5
|
import { useToast } from "@nuxt/ui/composables";
|
|
5
6
|
export const useFormValues = (raw, defaultValues) => {
|
|
6
7
|
const oldValues = ref({});
|
|
@@ -62,3 +63,24 @@ export const useFormSubmission = (oldValues, newValues, close, save, apiGroup, a
|
|
|
62
63
|
}
|
|
63
64
|
return { onSubmit };
|
|
64
65
|
};
|
|
66
|
+
export const useConfirmDiff = (fields, diffItems, oldModelValue, newModelValue) => {
|
|
67
|
+
const resolvedItems = computed(
|
|
68
|
+
() => toValue(diffItems).map((item) => ({
|
|
69
|
+
...item,
|
|
70
|
+
field: toValue(fields).find((f) => f.name === item.fieldName)
|
|
71
|
+
})).filter((item) => item.field != null)
|
|
72
|
+
);
|
|
73
|
+
const diffedItems = computed(
|
|
74
|
+
() => resolvedItems.value.map((item) => {
|
|
75
|
+
const oldDisplay = resolveDisplayValue(item.field, item.oldValue, toValue(oldModelValue));
|
|
76
|
+
const newDisplay = resolveDisplayValue(item.field, item.newValue, toValue(newModelValue));
|
|
77
|
+
return {
|
|
78
|
+
...item,
|
|
79
|
+
oldDisplay,
|
|
80
|
+
newDisplay,
|
|
81
|
+
parts: smartDiff(oldDisplay, newDisplay)
|
|
82
|
+
};
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
return { diffedItems };
|
|
86
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { VFormFieldProps } from '#v/types';
|
|
2
|
+
export declare function resolveSelectLabel(rawVal: unknown, items: readonly any[]): string;
|
|
3
|
+
export declare function resolveDisplayValue(field: VFormFieldProps, rawVal: unknown, modelSource: Record<string, unknown>): string;
|
|
4
|
+
export declare function smartDiff(oldStr: string, newStr: string): import("diff").ChangeObject<string>[];
|
|
5
|
+
export declare const diffEligibleTypes: Set<string>;
|
|
6
|
+
export declare function formatValue(val: unknown): string;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import { diffWords, diffChars } from "diff";
|
|
3
|
+
import { dateFormat } from "#v/constants";
|
|
4
|
+
export function resolveSelectLabel(rawVal, items) {
|
|
5
|
+
if (Array.isArray(rawVal)) {
|
|
6
|
+
return rawVal.map((v) => items.find((i) => i?.value === v)?.label ?? String(v)).join(", ") || "";
|
|
7
|
+
}
|
|
8
|
+
return items.find((i) => i?.value === rawVal)?.label ?? String(rawVal);
|
|
9
|
+
}
|
|
10
|
+
export function resolveDisplayValue(field, rawVal, modelSource) {
|
|
11
|
+
if (rawVal === null || rawVal === void 0) return "";
|
|
12
|
+
switch (field.type) {
|
|
13
|
+
case "switch":
|
|
14
|
+
case "button-switch":
|
|
15
|
+
return rawVal ? "\u662F" : "\u5426";
|
|
16
|
+
case "date-picker": {
|
|
17
|
+
if (typeof rawVal === "string") {
|
|
18
|
+
const d = dayjs(rawVal);
|
|
19
|
+
if (d.isValid()) return d.format(dateFormat);
|
|
20
|
+
}
|
|
21
|
+
return String(rawVal);
|
|
22
|
+
}
|
|
23
|
+
case "select": {
|
|
24
|
+
const items = field.enableEmptyOption ? [{ label: "\u65E0", value: 0 }, ...field.items ?? []] : field.items ?? [];
|
|
25
|
+
return resolveSelectLabel(rawVal, items);
|
|
26
|
+
}
|
|
27
|
+
case "multiple-select-string":
|
|
28
|
+
case "radio-select":
|
|
29
|
+
return resolveSelectLabel(rawVal, field.items ?? []);
|
|
30
|
+
case "async-select":
|
|
31
|
+
case "async-tree-select":
|
|
32
|
+
case "async-object-select": {
|
|
33
|
+
if (!field.name) return String(rawVal);
|
|
34
|
+
if (rawVal === 0) return "";
|
|
35
|
+
const labelField = field.labelField;
|
|
36
|
+
if (!labelField) return String(rawVal);
|
|
37
|
+
let model;
|
|
38
|
+
for (const v of Object.values(modelSource)) {
|
|
39
|
+
if (v && typeof v === "object" && v[labelField] !== void 0) {
|
|
40
|
+
if (String(v.id) === String(rawVal)) {
|
|
41
|
+
model = v;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!model) {
|
|
47
|
+
model = field.initModel;
|
|
48
|
+
}
|
|
49
|
+
if (!model) return String(rawVal);
|
|
50
|
+
if (Array.isArray(model)) {
|
|
51
|
+
return model.map((m) => m && typeof m === "object" ? String(m[labelField] ?? "") : String(m)).filter(Boolean).join(", ") || "";
|
|
52
|
+
}
|
|
53
|
+
if (typeof model === "object") {
|
|
54
|
+
const label = model[labelField];
|
|
55
|
+
if (label != null) return String(label);
|
|
56
|
+
}
|
|
57
|
+
return String(rawVal);
|
|
58
|
+
}
|
|
59
|
+
case "input-string-number": {
|
|
60
|
+
const v = rawVal === 0 ? "0" : String(rawVal);
|
|
61
|
+
const trailing = field.trailingString;
|
|
62
|
+
return trailing ? `${v} ${trailing}` : v;
|
|
63
|
+
}
|
|
64
|
+
case "tree-select-transfer": {
|
|
65
|
+
if (Array.isArray(rawVal)) {
|
|
66
|
+
return rawVal.map((item) => {
|
|
67
|
+
if (item && typeof item === "object") {
|
|
68
|
+
const obj = item;
|
|
69
|
+
return String(obj.label ?? obj.name ?? "");
|
|
70
|
+
}
|
|
71
|
+
return String(item);
|
|
72
|
+
}).filter(Boolean).join(", ") || "";
|
|
73
|
+
}
|
|
74
|
+
return formatValue(rawVal);
|
|
75
|
+
}
|
|
76
|
+
default:
|
|
77
|
+
return formatValue(rawVal);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function smartDiff(oldStr, newStr) {
|
|
81
|
+
if (!oldStr.includes(" ") && !newStr.includes(" ")) {
|
|
82
|
+
return diffChars(oldStr, newStr);
|
|
83
|
+
}
|
|
84
|
+
return diffWords(oldStr, newStr);
|
|
85
|
+
}
|
|
86
|
+
export const diffEligibleTypes = /* @__PURE__ */ new Set([
|
|
87
|
+
"input",
|
|
88
|
+
"dynamic-input",
|
|
89
|
+
"input-string-number",
|
|
90
|
+
"input-number",
|
|
91
|
+
"textarea",
|
|
92
|
+
"input-pwd",
|
|
93
|
+
"sql-editor",
|
|
94
|
+
"date-picker"
|
|
95
|
+
]);
|
|
96
|
+
export function formatValue(val) {
|
|
97
|
+
if (val === null || val === void 0) return "";
|
|
98
|
+
if (typeof val === "boolean") return val ? "\u662F" : "\u5426";
|
|
99
|
+
if (typeof val === "object") return JSON.stringify(val);
|
|
100
|
+
return String(val);
|
|
101
|
+
}
|
|
@@ -5,7 +5,7 @@ export * from './useApp.js';
|
|
|
5
5
|
export * from './useBoolean.js';
|
|
6
6
|
export * from './useDate.js';
|
|
7
7
|
export * from './useEChart.js';
|
|
8
|
-
export * from './
|
|
8
|
+
export * from './form/index.js';
|
|
9
9
|
export * from './useTheme.js';
|
|
10
10
|
export * from './useSidebarMenu.js';
|
|
11
11
|
export * from './usePermission.js';
|
|
@@ -5,7 +5,7 @@ export * from "./useApp.js";
|
|
|
5
5
|
export * from "./useBoolean.js";
|
|
6
6
|
export * from "./useDate.js";
|
|
7
7
|
export * from "./useEChart.js";
|
|
8
|
-
export * from "./
|
|
8
|
+
export * from "./form/index.js";
|
|
9
9
|
export * from "./useTheme.js";
|
|
10
10
|
export * from "./useSidebarMenu.js";
|
|
11
11
|
export * from "./usePermission.js";
|
|
@@ -44,7 +44,8 @@ export function useTable(props) {
|
|
|
44
44
|
disableRowSelection,
|
|
45
45
|
expandable,
|
|
46
46
|
rowSpanColumns,
|
|
47
|
-
customRowCopyFn
|
|
47
|
+
customRowCopyFn,
|
|
48
|
+
displayFnInDeleteModal
|
|
48
49
|
} = props;
|
|
49
50
|
const queryComposable = useTableQuery({
|
|
50
51
|
name,
|
|
@@ -96,6 +97,9 @@ export function useTable(props) {
|
|
|
96
97
|
} = dataComposable;
|
|
97
98
|
const rowSelectionComposable = useTableRowSelection(data, rowKey);
|
|
98
99
|
const { rowSelection, selectedIds, clearRowSelection: _clearRowSelection } = rowSelectionComposable;
|
|
100
|
+
const selectedModels = computed(
|
|
101
|
+
() => data.value.filter((row) => selectedIds.value.includes(row[rowKey]))
|
|
102
|
+
);
|
|
99
103
|
const whereQueryRef = useTemplateRef("proTableQueryWhere");
|
|
100
104
|
const onFilterClick = (field) => {
|
|
101
105
|
whereQueryOpen.value = true;
|
|
@@ -149,6 +153,8 @@ export function useTable(props) {
|
|
|
149
153
|
} = columnsComposable;
|
|
150
154
|
const rowActionsComposable = useTableRowActions({
|
|
151
155
|
rowKey,
|
|
156
|
+
tableName: name,
|
|
157
|
+
bizColumns,
|
|
152
158
|
disableRowActions,
|
|
153
159
|
disableRowUpdate,
|
|
154
160
|
disableRowCopy,
|
|
@@ -157,6 +163,7 @@ export function useTable(props) {
|
|
|
157
163
|
extraRowActions,
|
|
158
164
|
useApiGroup,
|
|
159
165
|
customRowCopyFn,
|
|
166
|
+
displayFnInDeleteModal,
|
|
160
167
|
fetchList
|
|
161
168
|
});
|
|
162
169
|
const { getRowActions, generateActionColumn } = rowActionsComposable;
|
|
@@ -287,6 +294,8 @@ export function useTable(props) {
|
|
|
287
294
|
fetchList,
|
|
288
295
|
onEditRowFromModal,
|
|
289
296
|
selectedIds: selectedIds.value,
|
|
297
|
+
selectedModels: selectedModels.value,
|
|
298
|
+
displayFnInDeleteModal,
|
|
290
299
|
disableCreation,
|
|
291
300
|
disableWhereQuery,
|
|
292
301
|
whereQueryProps: tblWhereQueryProps.value,
|
|
@@ -2,6 +2,8 @@ import type { VColumn } from '#v/types';
|
|
|
2
2
|
import type { DropdownMenuItem, TableRow } from '@nuxt/ui';
|
|
3
3
|
export declare function useTableRowActions<T>(props: {
|
|
4
4
|
rowKey: keyof T;
|
|
5
|
+
tableName?: string;
|
|
6
|
+
bizColumns?: VColumn<T>[];
|
|
5
7
|
disableRowActions?: boolean;
|
|
6
8
|
disableRowUpdate?: boolean;
|
|
7
9
|
disableRowCopy?: boolean;
|
|
@@ -10,6 +12,7 @@ export declare function useTableRowActions<T>(props: {
|
|
|
10
12
|
extraRowActions?: any[];
|
|
11
13
|
useApiGroup?: (...args: any[]) => any;
|
|
12
14
|
customRowCopyFn?: (...args: any[]) => any;
|
|
15
|
+
displayFnInDeleteModal?: (model: T) => string | undefined;
|
|
13
16
|
fetchList: () => Promise<void>;
|
|
14
17
|
}): {
|
|
15
18
|
getRowActions: (row: TableRow<T>) => DropdownMenuItem[];
|