@htlkg/components 0.0.2 → 0.0.4
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 +52 -0
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js +367 -0
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map +1 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js +263 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js.map +1 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js +580 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js.map +1 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js +187 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js.map +1 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js +11 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js.map +1 -0
- package/dist/components.css +15 -0
- package/dist/composables/index.js +32 -573
- package/dist/composables/index.js.map +1 -1
- package/dist/data/index.js +18 -0
- package/dist/data/index.js.map +1 -0
- package/dist/domain/index.js +8 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/filterHelpers-DgRyoYSa.js +1386 -0
- package/dist/filterHelpers-DgRyoYSa.js.map +1 -0
- package/dist/forms/index.js +6 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index-DGO_pNgG.js +79 -0
- package/dist/index-DGO_pNgG.js.map +1 -0
- package/dist/index-QK97OdqQ.js +25 -0
- package/dist/index-QK97OdqQ.js.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/index.js +8 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/overlays/index.js +8 -0
- package/dist/overlays/index.js.map +1 -0
- package/dist/stores/index.js +14 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/useAdminPage-GhgXp0x8.js +1070 -0
- package/dist/useAdminPage-GhgXp0x8.js.map +1 -0
- package/dist/useTable-DutR1gkg.js +293 -0
- package/dist/useTable-DutR1gkg.js.map +1 -0
- package/package.json +43 -14
- package/src/composables/composables.md +109 -0
- package/src/composables/index.ts +69 -0
- package/src/composables/useAdminPage.ts +462 -0
- package/src/composables/useConfirmation.ts +358 -0
- package/src/composables/usePageContext.ts +171 -0
- package/src/composables/useStats.ts +361 -0
- package/src/composables/useTable.ts +26 -5
- package/src/composables/useWizard.ts +448 -0
- package/src/data/DataTable.vue +553 -0
- package/src/data/Table/Table.vue +295 -0
- package/src/data/columnHelpers.ts +503 -0
- package/src/data/data.md +106 -0
- package/src/data/filterHelpers.ts +358 -0
- package/src/data/index.ts +31 -0
- package/src/domain/domain.md +102 -0
- package/src/forms/JsonSchemaForm.vue +4 -1
- package/src/forms/forms.md +89 -0
- package/src/index.ts +4 -3
- package/src/navigation/navigation.md +80 -0
- package/src/overlays/overlays.md +86 -0
- package/src/stores/stores.md +82 -0
|
@@ -0,0 +1,1070 @@
|
|
|
1
|
+
import { ref, computed, inject, watch, onMounted } from "vue";
|
|
2
|
+
import { routes } from "@htlkg/core";
|
|
3
|
+
import { a as atom } from "./index-DGO_pNgG.js";
|
|
4
|
+
import { u as useStore } from "./index-QK97OdqQ.js";
|
|
5
|
+
function useModal(options = {}) {
|
|
6
|
+
const isOpen = ref(options.initialOpen ?? false);
|
|
7
|
+
function open() {
|
|
8
|
+
var _a;
|
|
9
|
+
isOpen.value = true;
|
|
10
|
+
(_a = options.onOpen) == null ? void 0 : _a.call(options);
|
|
11
|
+
}
|
|
12
|
+
function close() {
|
|
13
|
+
var _a;
|
|
14
|
+
isOpen.value = false;
|
|
15
|
+
(_a = options.onClose) == null ? void 0 : _a.call(options);
|
|
16
|
+
}
|
|
17
|
+
function toggle() {
|
|
18
|
+
if (isOpen.value) {
|
|
19
|
+
close();
|
|
20
|
+
} else {
|
|
21
|
+
open();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
isOpen,
|
|
26
|
+
open,
|
|
27
|
+
close,
|
|
28
|
+
toggle
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function useTabs(options) {
|
|
32
|
+
const tabs = ref(options.tabs);
|
|
33
|
+
const activeTab = ref(
|
|
34
|
+
options.initialTab || (tabs.value.length > 0 ? tabs.value[0].id : "")
|
|
35
|
+
);
|
|
36
|
+
const currentTabIndex = computed(
|
|
37
|
+
() => tabs.value.findIndex((tab) => tab.id === activeTab.value)
|
|
38
|
+
);
|
|
39
|
+
const isFirstTab = computed(() => currentTabIndex.value === 0);
|
|
40
|
+
const isLastTab = computed(
|
|
41
|
+
() => currentTabIndex.value === tabs.value.length - 1
|
|
42
|
+
);
|
|
43
|
+
function setActiveTab(tabId) {
|
|
44
|
+
var _a;
|
|
45
|
+
const tab = tabs.value.find((t) => t.id === tabId);
|
|
46
|
+
if (tab && !tab.disabled) {
|
|
47
|
+
activeTab.value = tabId;
|
|
48
|
+
(_a = options.onChange) == null ? void 0 : _a.call(options, tabId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function nextTab() {
|
|
52
|
+
if (!isLastTab.value) {
|
|
53
|
+
const nextIndex = currentTabIndex.value + 1;
|
|
54
|
+
const nextTab2 = tabs.value[nextIndex];
|
|
55
|
+
if (nextTab2 && !nextTab2.disabled) {
|
|
56
|
+
setActiveTab(nextTab2.id);
|
|
57
|
+
} else if (nextIndex < tabs.value.length - 1) {
|
|
58
|
+
activeTab.value = nextTab2.id;
|
|
59
|
+
nextTab2();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function previousTab() {
|
|
64
|
+
if (!isFirstTab.value) {
|
|
65
|
+
const prevIndex = currentTabIndex.value - 1;
|
|
66
|
+
const prevTab = tabs.value[prevIndex];
|
|
67
|
+
if (prevTab && !prevTab.disabled) {
|
|
68
|
+
setActiveTab(prevTab.id);
|
|
69
|
+
} else if (prevIndex > 0) {
|
|
70
|
+
activeTab.value = prevTab.id;
|
|
71
|
+
previousTab();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isTabActive(tabId) {
|
|
76
|
+
return activeTab.value === tabId;
|
|
77
|
+
}
|
|
78
|
+
function isTabDisabled(tabId) {
|
|
79
|
+
const tab = tabs.value.find((t) => t.id === tabId);
|
|
80
|
+
return (tab == null ? void 0 : tab.disabled) ?? false;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
activeTab,
|
|
84
|
+
tabs,
|
|
85
|
+
currentTabIndex,
|
|
86
|
+
isFirstTab,
|
|
87
|
+
isLastTab,
|
|
88
|
+
setActiveTab,
|
|
89
|
+
nextTab,
|
|
90
|
+
previousTab,
|
|
91
|
+
isTabActive,
|
|
92
|
+
isTabDisabled
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function useForm(options) {
|
|
96
|
+
const values = ref({ ...options.initialValues });
|
|
97
|
+
const errors = ref({});
|
|
98
|
+
const touched = ref({});
|
|
99
|
+
const isSubmitting = ref(false);
|
|
100
|
+
const isValid = computed(() => Object.keys(errors.value).length === 0);
|
|
101
|
+
function setFieldValue(field, value) {
|
|
102
|
+
values.value[field] = value;
|
|
103
|
+
}
|
|
104
|
+
function setFieldError(field, error) {
|
|
105
|
+
errors.value[field] = error;
|
|
106
|
+
}
|
|
107
|
+
function setFieldTouched(field, isTouched) {
|
|
108
|
+
touched.value[field] = isTouched;
|
|
109
|
+
}
|
|
110
|
+
async function validateField(field) {
|
|
111
|
+
var _a;
|
|
112
|
+
const rules = (_a = options.validationRules) == null ? void 0 : _a[field];
|
|
113
|
+
if (!rules || rules.length === 0) return true;
|
|
114
|
+
const value = values.value[field];
|
|
115
|
+
for (const rule of rules) {
|
|
116
|
+
const isValid2 = await rule.validate(value);
|
|
117
|
+
if (!isValid2) {
|
|
118
|
+
setFieldError(field, rule.message);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
delete errors.value[field];
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
async function validateForm() {
|
|
126
|
+
const fields = Object.keys(values.value);
|
|
127
|
+
const validationResults = await Promise.all(
|
|
128
|
+
fields.map((field) => validateField(field))
|
|
129
|
+
);
|
|
130
|
+
return validationResults.every((result) => result);
|
|
131
|
+
}
|
|
132
|
+
async function handleSubmit(event) {
|
|
133
|
+
var _a;
|
|
134
|
+
if (event) {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
}
|
|
137
|
+
if (isSubmitting.value) return;
|
|
138
|
+
for (const field of Object.keys(values.value)) {
|
|
139
|
+
setFieldTouched(field, true);
|
|
140
|
+
}
|
|
141
|
+
const isFormValid = await validateForm();
|
|
142
|
+
if (!isFormValid) return;
|
|
143
|
+
isSubmitting.value = true;
|
|
144
|
+
try {
|
|
145
|
+
await ((_a = options.onSubmit) == null ? void 0 : _a.call(options, values.value));
|
|
146
|
+
} finally {
|
|
147
|
+
isSubmitting.value = false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function resetForm() {
|
|
151
|
+
values.value = { ...options.initialValues };
|
|
152
|
+
errors.value = {};
|
|
153
|
+
touched.value = {};
|
|
154
|
+
isSubmitting.value = false;
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
values,
|
|
158
|
+
errors,
|
|
159
|
+
touched,
|
|
160
|
+
isSubmitting,
|
|
161
|
+
isValid,
|
|
162
|
+
setFieldValue,
|
|
163
|
+
setFieldError,
|
|
164
|
+
setFieldTouched,
|
|
165
|
+
validateField,
|
|
166
|
+
validateForm,
|
|
167
|
+
handleSubmit,
|
|
168
|
+
resetForm
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const required = (message = "This field is required") => ({
|
|
172
|
+
validate: (value) => {
|
|
173
|
+
if (value === null || value === void 0) return false;
|
|
174
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
175
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
176
|
+
return true;
|
|
177
|
+
},
|
|
178
|
+
message
|
|
179
|
+
});
|
|
180
|
+
const minLength = (min2, message) => ({
|
|
181
|
+
validate: (value) => {
|
|
182
|
+
if (!value) return true;
|
|
183
|
+
return value.length >= min2;
|
|
184
|
+
},
|
|
185
|
+
message: message || `Must be at least ${min2} characters`
|
|
186
|
+
});
|
|
187
|
+
const maxLength = (max2, message) => ({
|
|
188
|
+
validate: (value) => {
|
|
189
|
+
if (!value) return true;
|
|
190
|
+
return value.length <= max2;
|
|
191
|
+
},
|
|
192
|
+
message: message || `Must be at most ${max2} characters`
|
|
193
|
+
});
|
|
194
|
+
const email = (message = "Invalid email address") => ({
|
|
195
|
+
validate: (value) => {
|
|
196
|
+
if (!value) return true;
|
|
197
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
198
|
+
return emailRegex.test(value);
|
|
199
|
+
},
|
|
200
|
+
message
|
|
201
|
+
});
|
|
202
|
+
const pattern = (regex, message = "Invalid format") => ({
|
|
203
|
+
validate: (value) => {
|
|
204
|
+
if (!value) return true;
|
|
205
|
+
return regex.test(value);
|
|
206
|
+
},
|
|
207
|
+
message
|
|
208
|
+
});
|
|
209
|
+
const min = (minValue, message) => ({
|
|
210
|
+
validate: (value) => {
|
|
211
|
+
if (value === null || value === void 0) return true;
|
|
212
|
+
return value >= minValue;
|
|
213
|
+
},
|
|
214
|
+
message: message || `Must be at least ${minValue}`
|
|
215
|
+
});
|
|
216
|
+
const max = (maxValue, message) => ({
|
|
217
|
+
validate: (value) => {
|
|
218
|
+
if (value === null || value === void 0) return true;
|
|
219
|
+
return value <= maxValue;
|
|
220
|
+
},
|
|
221
|
+
message: message || `Must be at most ${maxValue}`
|
|
222
|
+
});
|
|
223
|
+
const custom = (validator, message) => ({
|
|
224
|
+
validate: validator,
|
|
225
|
+
message
|
|
226
|
+
});
|
|
227
|
+
function useFormValidation() {
|
|
228
|
+
return {
|
|
229
|
+
required,
|
|
230
|
+
minLength,
|
|
231
|
+
maxLength,
|
|
232
|
+
email,
|
|
233
|
+
pattern,
|
|
234
|
+
min,
|
|
235
|
+
max,
|
|
236
|
+
custom
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const notifications = ref([]);
|
|
240
|
+
function useNotifications() {
|
|
241
|
+
function addNotification(notification) {
|
|
242
|
+
const id = `notification-${Date.now()}-${Math.random()}`;
|
|
243
|
+
const newNotification = {
|
|
244
|
+
...notification,
|
|
245
|
+
id
|
|
246
|
+
};
|
|
247
|
+
notifications.value.push(newNotification);
|
|
248
|
+
if (notification.duration) {
|
|
249
|
+
setTimeout(() => {
|
|
250
|
+
removeNotification(id);
|
|
251
|
+
}, notification.duration);
|
|
252
|
+
}
|
|
253
|
+
return id;
|
|
254
|
+
}
|
|
255
|
+
function removeNotification(id) {
|
|
256
|
+
const index = notifications.value.findIndex((n) => n.id === id);
|
|
257
|
+
if (index !== -1) {
|
|
258
|
+
notifications.value.splice(index, 1);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function clearAll() {
|
|
262
|
+
notifications.value = [];
|
|
263
|
+
}
|
|
264
|
+
function info(message, duration = 3e3) {
|
|
265
|
+
return addNotification({ message, type: "info", duration });
|
|
266
|
+
}
|
|
267
|
+
function success(message, duration = 3e3) {
|
|
268
|
+
return addNotification({ message, type: "success", duration });
|
|
269
|
+
}
|
|
270
|
+
function warning(message, duration = 3e3) {
|
|
271
|
+
return addNotification({ message, type: "warning", duration });
|
|
272
|
+
}
|
|
273
|
+
function error(message, duration = 5e3) {
|
|
274
|
+
return addNotification({ message, type: "error", duration });
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
notifications,
|
|
278
|
+
addNotification,
|
|
279
|
+
removeNotification,
|
|
280
|
+
clearAll,
|
|
281
|
+
info,
|
|
282
|
+
success,
|
|
283
|
+
warning,
|
|
284
|
+
error
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
const PAGE_CONTEXT_KEY = Symbol("pageContext");
|
|
288
|
+
const $user = atom(null);
|
|
289
|
+
const $currentBrand = atom(null);
|
|
290
|
+
function setUser(user) {
|
|
291
|
+
$user.set(user);
|
|
292
|
+
}
|
|
293
|
+
function setCurrentBrand(brand) {
|
|
294
|
+
$currentBrand.set(brand);
|
|
295
|
+
}
|
|
296
|
+
function usePageContext() {
|
|
297
|
+
const injected = inject(PAGE_CONTEXT_KEY, null);
|
|
298
|
+
if (injected) {
|
|
299
|
+
return computed(() => injected);
|
|
300
|
+
}
|
|
301
|
+
const user = useStore($user);
|
|
302
|
+
const brand = useStore($currentBrand);
|
|
303
|
+
return computed(() => {
|
|
304
|
+
var _a, _b, _c;
|
|
305
|
+
return {
|
|
306
|
+
user: user.value,
|
|
307
|
+
brand: brand.value ?? void 0,
|
|
308
|
+
brandId: (_a = brand.value) == null ? void 0 : _a.id,
|
|
309
|
+
isAdmin: ((_b = user.value) == null ? void 0 : _b.isAdmin) ?? false,
|
|
310
|
+
isSuperAdmin: ((_c = user.value) == null ? void 0 : _c.isSuperAdmin) ?? false,
|
|
311
|
+
routes
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function useHasAccessToBrand(brandId) {
|
|
316
|
+
const context = usePageContext();
|
|
317
|
+
return computed(() => {
|
|
318
|
+
var _a;
|
|
319
|
+
const user = context.value.user;
|
|
320
|
+
if (!user) return false;
|
|
321
|
+
if (user.isAdmin || user.isSuperAdmin) return true;
|
|
322
|
+
return ((_a = user.brandIds) == null ? void 0 : _a.includes(brandId)) ?? false;
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
function useHasAccessToAccount(accountId) {
|
|
326
|
+
const context = usePageContext();
|
|
327
|
+
return computed(() => {
|
|
328
|
+
var _a;
|
|
329
|
+
const user = context.value.user;
|
|
330
|
+
if (!user) return false;
|
|
331
|
+
if (user.isAdmin || user.isSuperAdmin) return true;
|
|
332
|
+
return ((_a = user.accountIds) == null ? void 0 : _a.includes(accountId)) ?? false;
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
function useUserRoles() {
|
|
336
|
+
const context = usePageContext();
|
|
337
|
+
return computed(() => {
|
|
338
|
+
var _a;
|
|
339
|
+
return ((_a = context.value.user) == null ? void 0 : _a.roles) ?? [];
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function useHasRole(role) {
|
|
343
|
+
const roles = useUserRoles();
|
|
344
|
+
return computed(() => roles.value.includes(role));
|
|
345
|
+
}
|
|
346
|
+
function useWizard(options) {
|
|
347
|
+
const {
|
|
348
|
+
steps,
|
|
349
|
+
initialData = {},
|
|
350
|
+
onComplete,
|
|
351
|
+
onStepChange,
|
|
352
|
+
validateOnNext = true,
|
|
353
|
+
allowBackWithoutValidation = true
|
|
354
|
+
} = options;
|
|
355
|
+
const currentStepIndex = ref(0);
|
|
356
|
+
const data = ref({ ...initialData });
|
|
357
|
+
const isCompleting = ref(false);
|
|
358
|
+
const stepValidation = ref({});
|
|
359
|
+
const stepErrors = ref({});
|
|
360
|
+
const currentStep = computed(() => steps[currentStepIndex.value]);
|
|
361
|
+
const isFirstStep = computed(() => currentStepIndex.value === 0);
|
|
362
|
+
const isLastStep = computed(() => currentStepIndex.value === steps.length - 1);
|
|
363
|
+
const progress = computed(
|
|
364
|
+
() => Math.round((currentStepIndex.value + 1) / steps.length * 100)
|
|
365
|
+
);
|
|
366
|
+
const currentStepValid = computed(() => {
|
|
367
|
+
const step = currentStep.value;
|
|
368
|
+
if (!step) return false;
|
|
369
|
+
if (step.optional) return true;
|
|
370
|
+
return stepValidation.value[step.id] !== false;
|
|
371
|
+
});
|
|
372
|
+
const allStepsValid = computed(() => {
|
|
373
|
+
return steps.every((step) => {
|
|
374
|
+
if (step.optional) return true;
|
|
375
|
+
return stepValidation.value[step.id] === true;
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
const stepperSteps = computed(
|
|
379
|
+
() => steps.map((step, index) => {
|
|
380
|
+
let status;
|
|
381
|
+
if (index < currentStepIndex.value) {
|
|
382
|
+
status = stepValidation.value[step.id] === false ? "error" : "complete";
|
|
383
|
+
} else if (index === currentStepIndex.value) {
|
|
384
|
+
status = "current";
|
|
385
|
+
} else {
|
|
386
|
+
status = "upcoming";
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
id: step.id,
|
|
390
|
+
label: step.label,
|
|
391
|
+
status,
|
|
392
|
+
valid: stepValidation.value[step.id] ?? true
|
|
393
|
+
};
|
|
394
|
+
})
|
|
395
|
+
);
|
|
396
|
+
function getStepIndex(stepId) {
|
|
397
|
+
return steps.findIndex((s) => s.id === stepId);
|
|
398
|
+
}
|
|
399
|
+
function getStep(stepId) {
|
|
400
|
+
return steps.find((s) => s.id === stepId);
|
|
401
|
+
}
|
|
402
|
+
async function validateStep(stepIndex) {
|
|
403
|
+
const step = steps[stepIndex];
|
|
404
|
+
if (!step) return false;
|
|
405
|
+
if (step.optional) {
|
|
406
|
+
stepValidation.value[step.id] = true;
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
if (step.validate) {
|
|
410
|
+
try {
|
|
411
|
+
const result = await step.validate(data.value);
|
|
412
|
+
stepValidation.value[step.id] = result;
|
|
413
|
+
if (!result) {
|
|
414
|
+
stepErrors.value[step.id] = "Validation failed";
|
|
415
|
+
} else {
|
|
416
|
+
delete stepErrors.value[step.id];
|
|
417
|
+
}
|
|
418
|
+
return result;
|
|
419
|
+
} catch (error) {
|
|
420
|
+
stepValidation.value[step.id] = false;
|
|
421
|
+
stepErrors.value[step.id] = error instanceof Error ? error.message : "Validation error";
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (stepValidation.value[step.id] === void 0) {
|
|
426
|
+
stepValidation.value[step.id] = true;
|
|
427
|
+
}
|
|
428
|
+
return stepValidation.value[step.id] !== false;
|
|
429
|
+
}
|
|
430
|
+
function canGoToStep(targetIndex) {
|
|
431
|
+
if (targetIndex < 0 || targetIndex >= steps.length) return false;
|
|
432
|
+
if (targetIndex < currentStepIndex.value && allowBackWithoutValidation) {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
if (targetIndex > currentStepIndex.value && validateOnNext) {
|
|
436
|
+
for (let i = 0; i < targetIndex; i++) {
|
|
437
|
+
const step = steps[i];
|
|
438
|
+
if (!step.optional && stepValidation.value[step.id] === false) {
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
async function goToNext() {
|
|
446
|
+
if (isLastStep.value) return false;
|
|
447
|
+
if (validateOnNext) {
|
|
448
|
+
const isValid = await validateStep(currentStepIndex.value);
|
|
449
|
+
if (!isValid) return false;
|
|
450
|
+
}
|
|
451
|
+
const fromIndex = currentStepIndex.value;
|
|
452
|
+
currentStepIndex.value++;
|
|
453
|
+
onStepChange == null ? void 0 : onStepChange(fromIndex, currentStepIndex.value, data.value);
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
function goToPrevious() {
|
|
457
|
+
if (isFirstStep.value) return false;
|
|
458
|
+
const fromIndex = currentStepIndex.value;
|
|
459
|
+
currentStepIndex.value--;
|
|
460
|
+
onStepChange == null ? void 0 : onStepChange(fromIndex, currentStepIndex.value, data.value);
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
async function goToStep(targetIndex) {
|
|
464
|
+
if (!canGoToStep(targetIndex)) return false;
|
|
465
|
+
if (targetIndex > currentStepIndex.value && validateOnNext) {
|
|
466
|
+
const isValid = await validateStep(currentStepIndex.value);
|
|
467
|
+
if (!isValid) return false;
|
|
468
|
+
}
|
|
469
|
+
const fromIndex = currentStepIndex.value;
|
|
470
|
+
currentStepIndex.value = targetIndex;
|
|
471
|
+
onStepChange == null ? void 0 : onStepChange(fromIndex, currentStepIndex.value, data.value);
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
function updateData(newData) {
|
|
475
|
+
data.value = { ...data.value, ...newData };
|
|
476
|
+
}
|
|
477
|
+
function updateStepData(stepId, stepData) {
|
|
478
|
+
updateData(stepData);
|
|
479
|
+
delete stepErrors.value[stepId];
|
|
480
|
+
}
|
|
481
|
+
function setStepValid(stepId, valid) {
|
|
482
|
+
stepValidation.value[stepId] = valid;
|
|
483
|
+
if (valid) {
|
|
484
|
+
delete stepErrors.value[stepId];
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function setStepError(stepId, error) {
|
|
488
|
+
if (error) {
|
|
489
|
+
stepErrors.value[stepId] = error;
|
|
490
|
+
stepValidation.value[stepId] = false;
|
|
491
|
+
} else {
|
|
492
|
+
delete stepErrors.value[stepId];
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function resetStep(stepId) {
|
|
496
|
+
delete stepValidation.value[stepId];
|
|
497
|
+
delete stepErrors.value[stepId];
|
|
498
|
+
}
|
|
499
|
+
function reset() {
|
|
500
|
+
currentStepIndex.value = 0;
|
|
501
|
+
data.value = { ...initialData };
|
|
502
|
+
stepValidation.value = {};
|
|
503
|
+
stepErrors.value = {};
|
|
504
|
+
isCompleting.value = false;
|
|
505
|
+
}
|
|
506
|
+
async function complete() {
|
|
507
|
+
if (isCompleting.value) return false;
|
|
508
|
+
isCompleting.value = true;
|
|
509
|
+
try {
|
|
510
|
+
for (let i = 0; i < steps.length; i++) {
|
|
511
|
+
const isValid = await validateStep(i);
|
|
512
|
+
if (!isValid && !steps[i].optional) {
|
|
513
|
+
currentStepIndex.value = i;
|
|
514
|
+
isCompleting.value = false;
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (onComplete) {
|
|
519
|
+
await onComplete(data.value);
|
|
520
|
+
}
|
|
521
|
+
return true;
|
|
522
|
+
} catch (error) {
|
|
523
|
+
console.error("[useWizard] Completion error:", error);
|
|
524
|
+
return false;
|
|
525
|
+
} finally {
|
|
526
|
+
isCompleting.value = false;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
// State
|
|
531
|
+
currentStepIndex,
|
|
532
|
+
currentStep,
|
|
533
|
+
data,
|
|
534
|
+
isFirstStep,
|
|
535
|
+
isLastStep,
|
|
536
|
+
isCompleting,
|
|
537
|
+
stepErrors,
|
|
538
|
+
// Stepper integration
|
|
539
|
+
stepperSteps,
|
|
540
|
+
// Validation
|
|
541
|
+
stepValidation,
|
|
542
|
+
currentStepValid,
|
|
543
|
+
allStepsValid,
|
|
544
|
+
// Navigation
|
|
545
|
+
goToNext,
|
|
546
|
+
goToPrevious,
|
|
547
|
+
goToStep,
|
|
548
|
+
canGoToStep,
|
|
549
|
+
// Data management
|
|
550
|
+
updateData,
|
|
551
|
+
updateStepData,
|
|
552
|
+
setStepValid,
|
|
553
|
+
setStepError,
|
|
554
|
+
resetStep,
|
|
555
|
+
reset,
|
|
556
|
+
// Completion
|
|
557
|
+
complete,
|
|
558
|
+
// Utilities
|
|
559
|
+
getStepIndex,
|
|
560
|
+
getStep,
|
|
561
|
+
progress
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function useStats(options) {
|
|
565
|
+
const {
|
|
566
|
+
data,
|
|
567
|
+
loading,
|
|
568
|
+
definitions,
|
|
569
|
+
staggerDelay = 100,
|
|
570
|
+
initialDelay = 0,
|
|
571
|
+
previousData
|
|
572
|
+
} = options;
|
|
573
|
+
const loadingStates = ref(definitions.map(() => true));
|
|
574
|
+
let timers = [];
|
|
575
|
+
function clearTimers() {
|
|
576
|
+
timers.forEach((timer) => clearTimeout(timer));
|
|
577
|
+
timers = [];
|
|
578
|
+
}
|
|
579
|
+
function triggerStaggeredReveal() {
|
|
580
|
+
clearTimers();
|
|
581
|
+
loadingStates.value = definitions.map(() => true);
|
|
582
|
+
definitions.forEach((_, index) => {
|
|
583
|
+
const timer = setTimeout(() => {
|
|
584
|
+
loadingStates.value[index] = false;
|
|
585
|
+
}, initialDelay + staggerDelay * (index + 1));
|
|
586
|
+
timers.push(timer);
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
watch(
|
|
590
|
+
() => loading.value,
|
|
591
|
+
(isLoading, wasLoading) => {
|
|
592
|
+
if (wasLoading && !isLoading) {
|
|
593
|
+
triggerStaggeredReveal();
|
|
594
|
+
} else if (isLoading && !wasLoading) {
|
|
595
|
+
clearTimers();
|
|
596
|
+
loadingStates.value = definitions.map(() => true);
|
|
597
|
+
}
|
|
598
|
+
},
|
|
599
|
+
{ immediate: true }
|
|
600
|
+
);
|
|
601
|
+
if (!loading.value) {
|
|
602
|
+
triggerStaggeredReveal();
|
|
603
|
+
}
|
|
604
|
+
const stats = computed(() => {
|
|
605
|
+
const items = data.value;
|
|
606
|
+
const prevItems = previousData == null ? void 0 : previousData.value;
|
|
607
|
+
return definitions.map((def) => {
|
|
608
|
+
const stat = {
|
|
609
|
+
id: def.id,
|
|
610
|
+
name: def.name,
|
|
611
|
+
stat: def.compute(items),
|
|
612
|
+
icon: def.icon,
|
|
613
|
+
color: def.color ?? "gray"
|
|
614
|
+
};
|
|
615
|
+
if (def.computeChange) {
|
|
616
|
+
stat.change = def.computeChange(items, prevItems);
|
|
617
|
+
}
|
|
618
|
+
if (def.computeChangeType) {
|
|
619
|
+
stat.changeType = def.computeChangeType(items, prevItems);
|
|
620
|
+
}
|
|
621
|
+
if (def.showFooter !== void 0) {
|
|
622
|
+
stat.showFooter = def.showFooter;
|
|
623
|
+
}
|
|
624
|
+
if (def.actionText) {
|
|
625
|
+
stat.actionText = def.actionText;
|
|
626
|
+
}
|
|
627
|
+
return stat;
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
const statsWithLoading = computed(
|
|
631
|
+
() => stats.value.map((stat, index) => ({
|
|
632
|
+
...stat,
|
|
633
|
+
loading: loading.value || loadingStates.value[index]
|
|
634
|
+
}))
|
|
635
|
+
);
|
|
636
|
+
const allLoaded = computed(
|
|
637
|
+
() => !loading.value && loadingStates.value.every((s) => !s)
|
|
638
|
+
);
|
|
639
|
+
function getStat(id) {
|
|
640
|
+
return stats.value.find((s) => s.id === id);
|
|
641
|
+
}
|
|
642
|
+
function refreshAnimation() {
|
|
643
|
+
triggerStaggeredReveal();
|
|
644
|
+
}
|
|
645
|
+
return {
|
|
646
|
+
stats,
|
|
647
|
+
loadingStates,
|
|
648
|
+
statsWithLoading,
|
|
649
|
+
allLoaded,
|
|
650
|
+
refreshAnimation,
|
|
651
|
+
getStat
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
function countStat(id, name, icon, filter, options) {
|
|
655
|
+
return {
|
|
656
|
+
id,
|
|
657
|
+
name,
|
|
658
|
+
icon,
|
|
659
|
+
color: (options == null ? void 0 : options.color) ?? "gray",
|
|
660
|
+
compute: (items) => items.filter(filter).length
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
function sumStat(id, name, icon, getValue, options) {
|
|
664
|
+
return {
|
|
665
|
+
id,
|
|
666
|
+
name,
|
|
667
|
+
icon,
|
|
668
|
+
color: (options == null ? void 0 : options.color) ?? "gray",
|
|
669
|
+
compute: (items) => {
|
|
670
|
+
const sum = items.reduce((total, item) => total + getValue(item), 0);
|
|
671
|
+
return (options == null ? void 0 : options.format) ? options.format(sum) : sum.toLocaleString();
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function averageStat(id, name, icon, getValue, options) {
|
|
676
|
+
return {
|
|
677
|
+
id,
|
|
678
|
+
name,
|
|
679
|
+
icon,
|
|
680
|
+
color: (options == null ? void 0 : options.color) ?? "gray",
|
|
681
|
+
compute: (items) => {
|
|
682
|
+
if (items.length === 0) return "0";
|
|
683
|
+
const sum = items.reduce((total, item) => total + getValue(item), 0);
|
|
684
|
+
const avg = sum / items.length;
|
|
685
|
+
const formatted = avg.toFixed((options == null ? void 0 : options.decimals) ?? 1);
|
|
686
|
+
return (options == null ? void 0 : options.suffix) ? `${formatted}${options.suffix}` : formatted;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function percentageStat(id, name, icon, filter, options) {
|
|
691
|
+
return {
|
|
692
|
+
id,
|
|
693
|
+
name,
|
|
694
|
+
icon,
|
|
695
|
+
color: (options == null ? void 0 : options.color) ?? "gray",
|
|
696
|
+
compute: (items) => {
|
|
697
|
+
if (items.length === 0) return "0%";
|
|
698
|
+
const count = items.filter(filter).length;
|
|
699
|
+
const percentage = count / items.length * 100;
|
|
700
|
+
return `${percentage.toFixed((options == null ? void 0 : options.decimals) ?? 1)}%`;
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
function useConfirmation(options = {}) {
|
|
705
|
+
const {
|
|
706
|
+
defaultConfirmText = "Confirm",
|
|
707
|
+
defaultCancelText = "Cancel",
|
|
708
|
+
defaultVariant = "default"
|
|
709
|
+
} = options;
|
|
710
|
+
const isOpen = ref(false);
|
|
711
|
+
const isLoading = ref(false);
|
|
712
|
+
const config = ref({
|
|
713
|
+
title: "",
|
|
714
|
+
message: "",
|
|
715
|
+
confirmText: defaultConfirmText,
|
|
716
|
+
cancelText: defaultCancelText,
|
|
717
|
+
variant: defaultVariant
|
|
718
|
+
});
|
|
719
|
+
let pending = null;
|
|
720
|
+
function confirm(confirmConfig) {
|
|
721
|
+
config.value = {
|
|
722
|
+
...confirmConfig,
|
|
723
|
+
confirmText: confirmConfig.confirmText ?? defaultConfirmText,
|
|
724
|
+
cancelText: confirmConfig.cancelText ?? defaultCancelText,
|
|
725
|
+
variant: confirmConfig.variant ?? defaultVariant
|
|
726
|
+
};
|
|
727
|
+
isOpen.value = true;
|
|
728
|
+
isLoading.value = false;
|
|
729
|
+
return new Promise((resolve, reject) => {
|
|
730
|
+
pending = { resolve, reject };
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
function handleConfirm() {
|
|
734
|
+
if (pending) {
|
|
735
|
+
pending.resolve(true);
|
|
736
|
+
pending = null;
|
|
737
|
+
}
|
|
738
|
+
isOpen.value = false;
|
|
739
|
+
isLoading.value = false;
|
|
740
|
+
}
|
|
741
|
+
function handleCancel() {
|
|
742
|
+
if (pending) {
|
|
743
|
+
pending.resolve(false);
|
|
744
|
+
pending = null;
|
|
745
|
+
}
|
|
746
|
+
isOpen.value = false;
|
|
747
|
+
isLoading.value = false;
|
|
748
|
+
}
|
|
749
|
+
function close() {
|
|
750
|
+
if (pending) {
|
|
751
|
+
pending.resolve(false);
|
|
752
|
+
pending = null;
|
|
753
|
+
}
|
|
754
|
+
isOpen.value = false;
|
|
755
|
+
isLoading.value = false;
|
|
756
|
+
}
|
|
757
|
+
function confirmDelete(itemName, confirmConfig) {
|
|
758
|
+
return confirm({
|
|
759
|
+
title: "Delete Item",
|
|
760
|
+
message: `Are you sure you want to delete "${itemName}"? This action cannot be undone.`,
|
|
761
|
+
confirmText: "Delete",
|
|
762
|
+
cancelText: "Cancel",
|
|
763
|
+
variant: "danger",
|
|
764
|
+
...confirmConfig
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
function confirmBulkDelete(count, itemType = "items", confirmConfig) {
|
|
768
|
+
return confirm({
|
|
769
|
+
title: `Delete ${count} ${itemType}`,
|
|
770
|
+
message: `Are you sure you want to delete ${count} ${itemType}? This action cannot be undone.`,
|
|
771
|
+
confirmText: "Delete All",
|
|
772
|
+
cancelText: "Cancel",
|
|
773
|
+
variant: "danger",
|
|
774
|
+
...confirmConfig
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
function confirmDestructive(actionName, confirmConfig) {
|
|
778
|
+
return confirm({
|
|
779
|
+
title: `Confirm ${actionName}`,
|
|
780
|
+
message: `Are you sure you want to ${actionName.toLowerCase()}? This action cannot be undone.`,
|
|
781
|
+
confirmText: actionName,
|
|
782
|
+
cancelText: "Cancel",
|
|
783
|
+
variant: "danger",
|
|
784
|
+
...confirmConfig
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
async function confirmWithAction(confirmConfig, action) {
|
|
788
|
+
const confirmed = await confirm(confirmConfig);
|
|
789
|
+
if (!confirmed) {
|
|
790
|
+
return { confirmed: false };
|
|
791
|
+
}
|
|
792
|
+
isLoading.value = true;
|
|
793
|
+
try {
|
|
794
|
+
const result = await action();
|
|
795
|
+
isOpen.value = false;
|
|
796
|
+
isLoading.value = false;
|
|
797
|
+
return { confirmed: true, result };
|
|
798
|
+
} catch (error) {
|
|
799
|
+
isLoading.value = false;
|
|
800
|
+
return {
|
|
801
|
+
confirmed: true,
|
|
802
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const modalProps = computed(() => ({
|
|
807
|
+
title: config.value.title,
|
|
808
|
+
open: isOpen.value,
|
|
809
|
+
modalName: "confirmation-dialog",
|
|
810
|
+
actions: [
|
|
811
|
+
{
|
|
812
|
+
name: config.value.cancelText ?? defaultCancelText,
|
|
813
|
+
value: "cancel"
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
name: config.value.confirmText ?? defaultConfirmText,
|
|
817
|
+
value: "confirm"
|
|
818
|
+
}
|
|
819
|
+
]
|
|
820
|
+
}));
|
|
821
|
+
return {
|
|
822
|
+
// State
|
|
823
|
+
isOpen,
|
|
824
|
+
config,
|
|
825
|
+
isLoading,
|
|
826
|
+
// Core methods
|
|
827
|
+
confirm,
|
|
828
|
+
handleConfirm,
|
|
829
|
+
handleCancel,
|
|
830
|
+
close,
|
|
831
|
+
// Convenience methods
|
|
832
|
+
confirmDelete,
|
|
833
|
+
confirmBulkDelete,
|
|
834
|
+
confirmDestructive,
|
|
835
|
+
confirmWithAction,
|
|
836
|
+
// Modal props
|
|
837
|
+
modalProps
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
let globalConfirmation = null;
|
|
841
|
+
function useGlobalConfirmation() {
|
|
842
|
+
if (!globalConfirmation) {
|
|
843
|
+
globalConfirmation = useConfirmation();
|
|
844
|
+
}
|
|
845
|
+
return globalConfirmation;
|
|
846
|
+
}
|
|
847
|
+
function resetGlobalConfirmation() {
|
|
848
|
+
globalConfirmation = null;
|
|
849
|
+
}
|
|
850
|
+
function useAdminPage(options) {
|
|
851
|
+
const {
|
|
852
|
+
title,
|
|
853
|
+
subtitle,
|
|
854
|
+
description,
|
|
855
|
+
breadcrumbs: initialBreadcrumbs = [],
|
|
856
|
+
sidebarActive,
|
|
857
|
+
actions: initialActions = [],
|
|
858
|
+
loading: initialLoading = true,
|
|
859
|
+
loadingDelay = 200
|
|
860
|
+
} = options;
|
|
861
|
+
const context = usePageContext();
|
|
862
|
+
const loadingHeader = ref(initialLoading);
|
|
863
|
+
const loadingContent = ref(initialLoading);
|
|
864
|
+
const actions = ref([...initialActions]);
|
|
865
|
+
onMounted(() => {
|
|
866
|
+
if (initialLoading) {
|
|
867
|
+
setTimeout(() => {
|
|
868
|
+
loadingHeader.value = false;
|
|
869
|
+
}, loadingDelay);
|
|
870
|
+
setTimeout(() => {
|
|
871
|
+
loadingContent.value = false;
|
|
872
|
+
}, loadingDelay * 2);
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
const user = computed(() => context.value.user);
|
|
876
|
+
const brand = computed(() => context.value.brand);
|
|
877
|
+
const isAdmin = computed(() => {
|
|
878
|
+
var _a;
|
|
879
|
+
return ((_a = user.value) == null ? void 0 : _a.isAdmin) ?? false;
|
|
880
|
+
});
|
|
881
|
+
const isSuperAdmin = computed(() => {
|
|
882
|
+
var _a;
|
|
883
|
+
return ((_a = user.value) == null ? void 0 : _a.isSuperAdmin) ?? false;
|
|
884
|
+
});
|
|
885
|
+
const breadcrumbs = computed(() => [
|
|
886
|
+
...initialBreadcrumbs.map((b) => ({ ...b, current: false })),
|
|
887
|
+
{ name: title, current: true }
|
|
888
|
+
]);
|
|
889
|
+
const wrapperProps = computed(() => ({
|
|
890
|
+
currentPage: sidebarActive
|
|
891
|
+
}));
|
|
892
|
+
const headerProps = computed(() => ({
|
|
893
|
+
title,
|
|
894
|
+
subtitle,
|
|
895
|
+
description,
|
|
896
|
+
pages: breadcrumbs.value,
|
|
897
|
+
loading: loadingHeader.value
|
|
898
|
+
}));
|
|
899
|
+
function setLoading(loading) {
|
|
900
|
+
if (loading) {
|
|
901
|
+
loadingHeader.value = true;
|
|
902
|
+
loadingContent.value = true;
|
|
903
|
+
} else {
|
|
904
|
+
setTimeout(() => {
|
|
905
|
+
loadingHeader.value = false;
|
|
906
|
+
}, loadingDelay);
|
|
907
|
+
setTimeout(() => {
|
|
908
|
+
loadingContent.value = false;
|
|
909
|
+
}, loadingDelay * 2);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
function updateAction(id, updates) {
|
|
913
|
+
const index = actions.value.findIndex((a) => a.id === id);
|
|
914
|
+
if (index !== -1) {
|
|
915
|
+
actions.value[index] = { ...actions.value[index], ...updates };
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
function setActionLoading(id, loading) {
|
|
919
|
+
updateAction(id, { loading });
|
|
920
|
+
}
|
|
921
|
+
return {
|
|
922
|
+
// Page info
|
|
923
|
+
title,
|
|
924
|
+
subtitle,
|
|
925
|
+
description,
|
|
926
|
+
// Breadcrumbs
|
|
927
|
+
breadcrumbs,
|
|
928
|
+
// Loading
|
|
929
|
+
loadingHeader,
|
|
930
|
+
loadingContent,
|
|
931
|
+
setLoading,
|
|
932
|
+
// Context
|
|
933
|
+
user,
|
|
934
|
+
brand,
|
|
935
|
+
isAdmin,
|
|
936
|
+
isSuperAdmin,
|
|
937
|
+
// Actions
|
|
938
|
+
actions,
|
|
939
|
+
updateAction,
|
|
940
|
+
setActionLoading,
|
|
941
|
+
// Props
|
|
942
|
+
wrapperProps,
|
|
943
|
+
headerProps
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
function useListPage(options) {
|
|
947
|
+
const {
|
|
948
|
+
entityName,
|
|
949
|
+
onCreateClick,
|
|
950
|
+
createIcon,
|
|
951
|
+
hideCreate = false,
|
|
952
|
+
...pageOptions
|
|
953
|
+
} = options;
|
|
954
|
+
const actions = [];
|
|
955
|
+
if (!hideCreate && entityName) {
|
|
956
|
+
actions.push({
|
|
957
|
+
id: "create",
|
|
958
|
+
text: `Create ${entityName.charAt(0).toUpperCase() + entityName.slice(1)}`,
|
|
959
|
+
icon: createIcon,
|
|
960
|
+
color: "primary",
|
|
961
|
+
onClick: onCreateClick
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
return useAdminPage({
|
|
965
|
+
...pageOptions,
|
|
966
|
+
actions
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
function useDetailPage(options) {
|
|
970
|
+
const {
|
|
971
|
+
entityName,
|
|
972
|
+
onEditClick,
|
|
973
|
+
onDeleteClick,
|
|
974
|
+
editIcon,
|
|
975
|
+
deleteIcon,
|
|
976
|
+
hideEdit = false,
|
|
977
|
+
hideDelete = false,
|
|
978
|
+
...pageOptions
|
|
979
|
+
} = options;
|
|
980
|
+
const actions = [];
|
|
981
|
+
if (!hideEdit && onEditClick) {
|
|
982
|
+
actions.push({
|
|
983
|
+
id: "edit",
|
|
984
|
+
text: "Edit",
|
|
985
|
+
icon: editIcon,
|
|
986
|
+
color: "secondary",
|
|
987
|
+
onClick: onEditClick
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
if (!hideDelete && onDeleteClick) {
|
|
991
|
+
actions.push({
|
|
992
|
+
id: "delete",
|
|
993
|
+
text: "Delete",
|
|
994
|
+
icon: deleteIcon,
|
|
995
|
+
color: "danger",
|
|
996
|
+
onClick: onDeleteClick
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
return useAdminPage({
|
|
1000
|
+
...pageOptions,
|
|
1001
|
+
actions
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
function useFormPage(options) {
|
|
1005
|
+
const {
|
|
1006
|
+
onSaveClick,
|
|
1007
|
+
onCancelClick,
|
|
1008
|
+
saveText = "Save",
|
|
1009
|
+
cancelText = "Cancel",
|
|
1010
|
+
saveIcon,
|
|
1011
|
+
cancelIcon,
|
|
1012
|
+
hideSave = false,
|
|
1013
|
+
hideCancel = false,
|
|
1014
|
+
...pageOptions
|
|
1015
|
+
} = options;
|
|
1016
|
+
const actions = [];
|
|
1017
|
+
if (!hideCancel && onCancelClick) {
|
|
1018
|
+
actions.push({
|
|
1019
|
+
id: "cancel",
|
|
1020
|
+
text: cancelText,
|
|
1021
|
+
icon: cancelIcon,
|
|
1022
|
+
color: "secondary",
|
|
1023
|
+
onClick: onCancelClick
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
if (!hideSave && onSaveClick) {
|
|
1027
|
+
actions.push({
|
|
1028
|
+
id: "save",
|
|
1029
|
+
text: saveText,
|
|
1030
|
+
icon: saveIcon,
|
|
1031
|
+
color: "primary",
|
|
1032
|
+
onClick: onSaveClick
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
return useAdminPage({
|
|
1036
|
+
...pageOptions,
|
|
1037
|
+
actions
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
export {
|
|
1041
|
+
$user as $,
|
|
1042
|
+
PAGE_CONTEXT_KEY as P,
|
|
1043
|
+
useTabs as a,
|
|
1044
|
+
useForm as b,
|
|
1045
|
+
useFormValidation as c,
|
|
1046
|
+
useNotifications as d,
|
|
1047
|
+
usePageContext as e,
|
|
1048
|
+
useHasAccessToBrand as f,
|
|
1049
|
+
useHasAccessToAccount as g,
|
|
1050
|
+
useUserRoles as h,
|
|
1051
|
+
useHasRole as i,
|
|
1052
|
+
setCurrentBrand as j,
|
|
1053
|
+
$currentBrand as k,
|
|
1054
|
+
useWizard as l,
|
|
1055
|
+
useStats as m,
|
|
1056
|
+
countStat as n,
|
|
1057
|
+
sumStat as o,
|
|
1058
|
+
averageStat as p,
|
|
1059
|
+
percentageStat as q,
|
|
1060
|
+
useConfirmation as r,
|
|
1061
|
+
setUser as s,
|
|
1062
|
+
useGlobalConfirmation as t,
|
|
1063
|
+
useModal as u,
|
|
1064
|
+
resetGlobalConfirmation as v,
|
|
1065
|
+
useAdminPage as w,
|
|
1066
|
+
useListPage as x,
|
|
1067
|
+
useDetailPage as y,
|
|
1068
|
+
useFormPage as z
|
|
1069
|
+
};
|
|
1070
|
+
//# sourceMappingURL=useAdminPage-GhgXp0x8.js.map
|