@htlkg/components 0.0.13 → 0.0.15
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/{AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js → AdminWrapper.vue_vue_type_script_setup_true_lang-DgzX2LI3.js} +75 -24
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-DgzX2LI3.js.map +1 -0
- package/dist/components.css +2 -2
- package/dist/composables/index.js +26 -25
- package/dist/index-QK97OdqQ.js.map +1 -1
- package/dist/index.js +27 -26
- package/dist/navigation/index.js +1 -1
- package/dist/{useAdminPage-AgWRvw6o.js → useAdminPage-DjONnrbe.js} +96 -36
- package/dist/useAdminPage-DjONnrbe.js.map +1 -0
- package/package.json +3 -3
- package/src/composables/index.ts +1 -0
- package/src/composables/useIntersectionObserver.ts +89 -0
- package/src/composables/useTabs.ts +47 -8
- package/src/navigation/AdminWrapper/AdminWrapper.vue +68 -20
- package/src/navigation/Tabs/Tabs.vue +33 -8
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js.map +0 -1
- package/dist/useAdminPage-AgWRvw6o.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createElementVNode, Fragment, renderList, normalizeClass, createTextVNode, createCommentVNode, toDisplayString, renderSlot, createBlock, unref, createVNode,
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createElementVNode, Fragment, renderList, normalizeClass, createTextVNode, createCommentVNode, toDisplayString, withDirectives, renderSlot, vShow, createBlock, unref, createVNode, onMounted, onUnmounted, withCtx } from "vue";
|
|
2
2
|
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.js";
|
|
3
3
|
import { uiStepsV4, uiBreadcrumbs, uiWrapper } from "@hotelinking/ui";
|
|
4
4
|
import { $user } from "./stores/index.js";
|
|
@@ -16,9 +16,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
16
16
|
__name: "Tabs",
|
|
17
17
|
props: {
|
|
18
18
|
tabs: {},
|
|
19
|
-
modelValue: { default: "" }
|
|
19
|
+
modelValue: { default: "" },
|
|
20
|
+
lazy: { type: Boolean, default: false }
|
|
20
21
|
},
|
|
21
|
-
emits: ["update:modelValue", "tab-change"],
|
|
22
|
+
emits: ["update:modelValue", "tab-change", "lazy-load"],
|
|
22
23
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
23
24
|
const props = __props;
|
|
24
25
|
const emit = __emit;
|
|
@@ -29,21 +30,37 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
29
30
|
emit("tab-change", value);
|
|
30
31
|
}
|
|
31
32
|
});
|
|
33
|
+
const visitedTabs = ref(/* @__PURE__ */ new Set([currentTab.value]));
|
|
34
|
+
function selectTab(tabId) {
|
|
35
|
+
const isFirstVisit = !visitedTabs.value.has(tabId);
|
|
36
|
+
visitedTabs.value.add(tabId);
|
|
37
|
+
currentTab.value = tabId;
|
|
38
|
+
if (isFirstVisit && props.lazy) {
|
|
39
|
+
emit("lazy-load", tabId);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function shouldRender(tabId) {
|
|
43
|
+
if (!props.lazy) {
|
|
44
|
+
return currentTab.value === tabId;
|
|
45
|
+
}
|
|
46
|
+
return visitedTabs.value.has(tabId);
|
|
47
|
+
}
|
|
32
48
|
__expose({
|
|
33
49
|
setActiveTab: (tabId) => {
|
|
34
|
-
|
|
50
|
+
selectTab(tabId);
|
|
35
51
|
},
|
|
36
52
|
getActiveTab: () => currentTab.value,
|
|
53
|
+
isTabLoaded: (tabId) => visitedTabs.value.has(tabId),
|
|
37
54
|
nextTab: () => {
|
|
38
55
|
const currentIndex = props.tabs.findIndex((t) => t.id === currentTab.value);
|
|
39
56
|
if (currentIndex < props.tabs.length - 1) {
|
|
40
|
-
|
|
57
|
+
selectTab(props.tabs[currentIndex + 1].id);
|
|
41
58
|
}
|
|
42
59
|
},
|
|
43
60
|
previousTab: () => {
|
|
44
61
|
const currentIndex = props.tabs.findIndex((t) => t.id === currentTab.value);
|
|
45
62
|
if (currentIndex > 0) {
|
|
46
|
-
|
|
63
|
+
selectTab(props.tabs[currentIndex - 1].id);
|
|
47
64
|
}
|
|
48
65
|
}
|
|
49
66
|
});
|
|
@@ -54,7 +71,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
54
71
|
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab) => {
|
|
55
72
|
return openBlock(), createElementBlock("button", {
|
|
56
73
|
key: tab.id,
|
|
57
|
-
onClick: ($event) =>
|
|
74
|
+
onClick: ($event) => selectTab(tab.id),
|
|
58
75
|
class: normalizeClass([
|
|
59
76
|
currentTab.value === tab.id ? "border-blue-500 text-blue-600" : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
|
|
60
77
|
"whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-colors"
|
|
@@ -78,9 +95,11 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
78
95
|
return openBlock(), createElementBlock(Fragment, {
|
|
79
96
|
key: tab.id
|
|
80
97
|
}, [
|
|
81
|
-
|
|
98
|
+
shouldRender(tab.id) ? withDirectives((openBlock(), createElementBlock("div", _hoisted_6, [
|
|
82
99
|
renderSlot(_ctx.$slots, tab.id, { activeTab: currentTab.value }, void 0, true)
|
|
83
|
-
]))
|
|
100
|
+
], 512)), [
|
|
101
|
+
[vShow, currentTab.value === tab.id]
|
|
102
|
+
]) : createCommentVNode("", true)
|
|
84
103
|
], 64);
|
|
85
104
|
}), 128))
|
|
86
105
|
])
|
|
@@ -88,7 +107,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
88
107
|
};
|
|
89
108
|
}
|
|
90
109
|
});
|
|
91
|
-
const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-
|
|
110
|
+
const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-50d39e08"]]);
|
|
92
111
|
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
93
112
|
__name: "Stepper",
|
|
94
113
|
props: {
|
|
@@ -250,7 +269,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
250
269
|
const defaultProfileMenu = [
|
|
251
270
|
{ name: "Profile", id: "profile", href: "/admin/user" },
|
|
252
271
|
{ name: "Settings", id: "settings", href: "/admin/settings" },
|
|
253
|
-
|
|
272
|
+
// Direct link to server-side logout - no JavaScript needed
|
|
273
|
+
{ name: "Logout", id: "logout", href: "/logout" }
|
|
254
274
|
];
|
|
255
275
|
const topbarConfig = computed(() => {
|
|
256
276
|
var _a, _b, _c;
|
|
@@ -300,14 +320,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
300
320
|
handleLogout();
|
|
301
321
|
return;
|
|
302
322
|
}
|
|
303
|
-
if (menuItemHref && menuItemHref !== "#") {
|
|
304
|
-
window.location.href = menuItemHref;
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
323
|
const profileMenu = topbarConfig.value.profileMenu;
|
|
308
324
|
const menuItem = profileMenu.find((item) => item.id === menuItemId || item.name === menuItemId);
|
|
309
325
|
if ((menuItem == null ? void 0 : menuItem.href) && menuItem.href !== "#") {
|
|
310
326
|
window.location.href = menuItem.href;
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (menuItemHref && menuItemHref !== "#") {
|
|
330
|
+
window.location.href = menuItemHref;
|
|
311
331
|
}
|
|
312
332
|
};
|
|
313
333
|
const handleSideBarClick = (itemId) => {
|
|
@@ -325,16 +345,47 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
325
345
|
const handleInputChanged = (event) => {
|
|
326
346
|
console.log("Input changed:", event);
|
|
327
347
|
};
|
|
328
|
-
const handleLogout =
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
348
|
+
const handleLogout = () => {
|
|
349
|
+
window.location.href = "/logout";
|
|
350
|
+
};
|
|
351
|
+
const handleProfileLinkClick = (event) => {
|
|
352
|
+
var _a;
|
|
353
|
+
const target = event.target;
|
|
354
|
+
const link = target.closest("a[href]");
|
|
355
|
+
if (!link) return;
|
|
356
|
+
const href = link.getAttribute("href");
|
|
357
|
+
if (!href) return;
|
|
358
|
+
const profileMenu = topbarConfig.value.profileMenu;
|
|
359
|
+
const linkText = (_a = link.textContent) == null ? void 0 : _a.trim().toLowerCase();
|
|
360
|
+
if (href === "#" && linkText === "logout") {
|
|
361
|
+
event.preventDefault();
|
|
362
|
+
event.stopPropagation();
|
|
363
|
+
handleLogout();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const pathMappings = {};
|
|
367
|
+
for (const item of profileMenu) {
|
|
368
|
+
if (item.id === "settings" || item.name === "Settings") {
|
|
369
|
+
pathMappings["/settings"] = item.href;
|
|
370
|
+
}
|
|
371
|
+
if (item.id === "profile" || item.name === "Profile") {
|
|
372
|
+
pathMappings["/profile"] = item.href;
|
|
373
|
+
pathMappings["/user"] = item.href;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const redirectTo = pathMappings[href];
|
|
377
|
+
if (redirectTo && redirectTo !== "#" && redirectTo !== href) {
|
|
378
|
+
event.preventDefault();
|
|
379
|
+
event.stopPropagation();
|
|
380
|
+
window.location.href = redirectTo;
|
|
336
381
|
}
|
|
337
382
|
};
|
|
383
|
+
onMounted(() => {
|
|
384
|
+
document.addEventListener("click", handleProfileLinkClick, true);
|
|
385
|
+
});
|
|
386
|
+
onUnmounted(() => {
|
|
387
|
+
document.removeEventListener("click", handleProfileLinkClick, true);
|
|
388
|
+
});
|
|
338
389
|
return (_ctx, _cache) => {
|
|
339
390
|
return openBlock(), createBlock(unref(uiWrapper), {
|
|
340
391
|
sidebar: sidebarConfig.value,
|
|
@@ -361,4 +412,4 @@ export {
|
|
|
361
412
|
_sfc_main$2 as _,
|
|
362
413
|
_sfc_main as a
|
|
363
414
|
};
|
|
364
|
-
//# sourceMappingURL=AdminWrapper.vue_vue_type_script_setup_true_lang-
|
|
415
|
+
//# sourceMappingURL=AdminWrapper.vue_vue_type_script_setup_true_lang-DgzX2LI3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminWrapper.vue_vue_type_script_setup_true_lang-DgzX2LI3.js","sources":["../src/navigation/Tabs/Tabs.vue","../src/navigation/Stepper/Stepper.vue","../src/navigation/Breadcrumbs/Breadcrumbs.vue","../src/navigation/AdminWrapper/AdminWrapper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\n\nexport interface Tab {\n id: string;\n label: string;\n count?: number;\n}\n\ninterface Props {\n tabs: Tab[];\n modelValue?: string;\n /** When true, tab content is only rendered after first activation but stays alive once loaded */\n lazy?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: '',\n lazy: false,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [tabId: string];\n 'tab-change': [tabId: string];\n 'lazy-load': [tabId: string];\n}>();\n\n// Internal state synced with v-model\nconst currentTab = computed({\n get: () => props.modelValue || (props.tabs.length > 0 ? props.tabs[0].id : ''),\n set: (value: string) => {\n emit('update:modelValue', value);\n emit('tab-change', value);\n }\n});\n\n// Track visited tabs for lazy rendering\nconst visitedTabs = ref<Set<string>>(new Set([currentTab.value]));\n\nfunction selectTab(tabId: string) {\n const isFirstVisit = !visitedTabs.value.has(tabId);\n visitedTabs.value.add(tabId);\n currentTab.value = tabId;\n\n if (isFirstVisit && props.lazy) {\n emit('lazy-load', tabId);\n }\n}\n\nfunction shouldRender(tabId: string): boolean {\n if (!props.lazy) {\n // Non-lazy: standard v-if, only render active tab\n return currentTab.value === tabId;\n }\n // Lazy: render if ever visited\n return visitedTabs.value.has(tabId);\n}\n\n// Expose methods for parent components\ndefineExpose({\n setActiveTab: (tabId: string) => { selectTab(tabId); },\n getActiveTab: () => currentTab.value,\n isTabLoaded: (tabId: string) => visitedTabs.value.has(tabId),\n nextTab: () => {\n const currentIndex = props.tabs.findIndex(t => t.id === currentTab.value);\n if (currentIndex < props.tabs.length - 1) {\n selectTab(props.tabs[currentIndex + 1].id);\n }\n },\n previousTab: () => {\n const currentIndex = props.tabs.findIndex(t => t.id === currentTab.value);\n if (currentIndex > 0) {\n selectTab(props.tabs[currentIndex - 1].id);\n }\n }\n});\n</script>\n\n<template>\n <div class=\"tabs-wrapper\">\n <div class=\"border-b border-gray-200\">\n <nav class=\"-mb-px flex space-x-8\" aria-label=\"Tabs\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n @click=\"selectTab(tab.id)\"\n :class=\"[\n currentTab === tab.id\n ? 'border-blue-500 text-blue-600'\n : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700',\n 'whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-colors'\n ]\"\n :aria-current=\"currentTab === tab.id ? 'page' : undefined\"\n >\n {{ tab.label }}\n <span\n v-if=\"tab.count !== undefined && tab.count > 0\"\n :class=\"[\n currentTab === tab.id\n ? 'bg-blue-100 text-blue-600'\n : 'bg-gray-100 text-gray-900',\n 'ml-3 hidden rounded-full py-0.5 px-2.5 text-xs font-medium md:inline-block'\n ]\"\n >\n {{ tab.count }}\n </span>\n </button>\n </nav>\n </div>\n\n <div class=\"tabs-content mt-4\">\n <template v-for=\"tab in tabs\" :key=\"tab.id\">\n <div v-if=\"shouldRender(tab.id)\" v-show=\"currentTab === tab.id\">\n <slot :name=\"tab.id\" :active-tab=\"currentTab\" />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.tabs-wrapper {\n width: 100%;\n}\n\n.tabs-content {\n margin-top: 1rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiStepsV4 } from '@hotelinking/ui';\n\nexport interface Step {\n id?: string | number;\n label: string;\n status?: 'complete' | 'current' | 'upcoming';\n valid?: boolean; // Validation state for the step\n}\n\ninterface Props {\n steps: Step[];\n currentStep?: number;\n validateOnNext?: boolean; // Enable validation when moving forward\n allowSkip?: boolean; // Allow skipping to any step regardless of validation\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n currentStep: 0,\n validateOnNext: false,\n allowSkip: false\n});\n\nconst emit = defineEmits<{\n 'step-click': [step: Step, index: number];\n 'step-completed': [step: Step];\n 'step-current': [step: Step];\n 'step-upcoming': [step: Step];\n 'validation-failed': [step: Step, index: number];\n 'update:currentStep': [index: number]; // v-model support\n}>();\n\n// Transform steps to uiStepsV4 format\nconst uiSteps = computed(() =>\n props.steps.map((step, index) => ({\n id: step.id || String(index + 1).padStart(2, '0'),\n name: step.label,\n status: step.status || (\n index < props.currentStep ? 'complete' :\n index === props.currentStep ? 'current' :\n 'upcoming'\n )\n }))\n);\n\n// Check if navigation to a step is allowed\nfunction canNavigateToStep(targetIndex: number): boolean {\n if (props.allowSkip) return true;\n if (!props.validateOnNext) return true;\n if (targetIndex < props.currentStep) return true;\n\n const currentStepData = props.steps[props.currentStep];\n if (targetIndex > props.currentStep && currentStepData.valid === false) {\n return false;\n }\n\n for (let i = props.currentStep; i < targetIndex; i++) {\n if (props.steps[i].valid === false) {\n return false;\n }\n }\n\n return true;\n}\n\n// Handle uiStepsV4 events\nfunction handleStepClick(step: any, index: number) {\n const originalStep = props.steps[index];\n \n if (!canNavigateToStep(index)) {\n const currentStepData = props.steps[props.currentStep];\n emit('validation-failed', currentStepData, props.currentStep);\n return;\n }\n\n emit('step-click', originalStep, index);\n emit('update:currentStep', index);\n}\n\nfunction handleStepCompleted(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-completed', props.steps[index]);\n }\n}\n\nfunction handleStepCurrent(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-current', props.steps[index]);\n }\n}\n\nfunction handleStepUpcoming(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-upcoming', props.steps[index]);\n }\n}\n\n// Public methods for programmatic navigation\nfunction goToStep(index: number): boolean {\n if (index < 0 || index >= props.steps.length) return false;\n if (!canNavigateToStep(index)) {\n const currentStepData = props.steps[props.currentStep];\n emit('validation-failed', currentStepData, props.currentStep);\n return false;\n }\n emit('update:currentStep', index);\n return true;\n}\n\nfunction goToNext(): boolean {\n return goToStep(props.currentStep + 1);\n}\n\nfunction goToPrevious(): boolean {\n return goToStep(props.currentStep - 1);\n}\n\nfunction validateCurrentStep(): boolean {\n const currentStepData = props.steps[props.currentStep];\n return currentStepData.valid !== false;\n}\n\ndefineExpose({\n getCurrentStep: () => props.currentStep,\n getSteps: () => props.steps,\n goToStep,\n goToNext,\n goToPrevious,\n validateCurrentStep,\n canNavigateToStep\n});\n</script>\n\n<template>\n <uiStepsV4\n :steps=\"uiSteps\"\n @stepClick=\"handleStepClick\"\n @stepCompleted=\"handleStepCompleted\"\n @stepCurrent=\"handleStepCurrent\"\n @stepUpcoming=\"handleStepUpcoming\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiBreadcrumbs } from '@hotelinking/ui';\n\nexport interface BreadcrumbItem {\n label: string;\n routeName: string;\n current?: boolean;\n}\n\ninterface Props {\n items: BreadcrumbItem[];\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n loading: false\n});\n\nconst emit = defineEmits<{\n 'breadcrumb-click': [routeName: string];\n}>();\n\n// Convert items to uiBreadcrumbs format\nconst pagesConfig = computed(() =>\n props.items.map((item, index) => ({\n name: item.label,\n routeName: item.routeName,\n current: item.current ?? (index === props.items.length - 1)\n }))\n);\n\n// Handle breadcrumb click\nfunction handleBreadcrumbClick(routeName: string) {\n emit('breadcrumb-click', routeName);\n}\n\n// Expose methods for parent components\ndefineExpose({\n getItems: () => props.items\n});\n</script>\n\n<template>\n <div class=\"breadcrumbs-wrapper\">\n <uiBreadcrumbs\n :pages=\"pagesConfig\"\n :loading=\"loading\"\n @bread-crumb-clicked=\"handleBreadcrumbClick\"\n />\n </div>\n</template>\n\n<style scoped>\n.breadcrumbs-wrapper {\n width: 100%;\n}\n</style>\n","/**\n * Admin Wrapper Component\n * \n * Wraps uiWrapper from @hotelinking/ui with sidebar, topbar, and content area.\n */\n\n<template>\n <uiWrapper \n :sidebar=\"sidebarConfig as any\" \n :topbar=\"topbarConfig as any\"\n :sidebarOpen=\"sidebarOpen\"\n @selectChanged=\"handleSelectChanged\"\n @topBarClick=\"handleTopBarClick\"\n @sideBarClick=\"handleSideBarClick\"\n @productBarClick=\"handleProductBarClick\"\n @inputChanged=\"handleInputChanged\"\n @sidebarToggle=\"(isOpen: boolean) => sidebarOpen = isOpen\"\n >\n <slot></slot>\n </uiWrapper>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SelectItemType } from \"@hotelinking/ui\";\nimport { uiWrapper } from \"@hotelinking/ui\";\nimport { useStore } from \"@nanostores/vue\";\nimport { computed, ref, onMounted, onUnmounted } from \"vue\";\nimport { $user } from \"../../stores/user\";\n\n// Profile menu item interface\ninterface ProfileMenuItem {\n\tname: string;\n\tid: string;\n\thref: string;\n}\n\n// Props interface (user is now from nanostore)\ninterface Props {\n\tsidebarLogo: string;\n\tcurrentPage?: string;\n\tsidebarTitle?: string;\n\tsidebarItems?: Array<{\n\t\tname: string;\n\t\ticon?: string;\n\t\tid: string;\n\t\trouteName: string;\n\t}>;\n\ttopbarActions?: Array<{\n\t\tname: string;\n\t\tevent: string;\n\t\ticon: string;\n\t}>;\n\tselectItems?: Array<{\n\t\tname: string;\n\t\tid: string;\n\t}>;\n\tselectedItem?: {\n\t\tname: string;\n\t\tid: string;\n\t};\n\tproductsSidebar?: Array<{\n\t\tname: string;\n\t\ticon: string;\n\t\tactive?: boolean;\n\t}>;\n\tprofileMenuItems?: ProfileMenuItem[];\n\tsidebarOpenByDefault?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n\tcurrentPage: \"dashboard\",\n\tsidebarItems: () => [],\n\ttopbarActions: () => [],\n\tselectItems: () => [],\n\tselectedItem: () => ({ name: \"\", id: \"\" }),\n\tproductsSidebar: () => [],\n\tprofileMenuItems: () => [],\n\tsidebarOpenByDefault: true,\n});\n\n// Emit events\nconst emit = defineEmits<{\n\tselectChanged: [item: { name: string; id: string }];\n}>();\n\n// Reactive state\nconst sidebarOpen = ref(props.sidebarOpenByDefault);\n\n// Get user from nanostore (no props needed!)\nconst user = useStore($user);\n\n// Default profile menu items (used when none provided via props)\nconst defaultProfileMenu: ProfileMenuItem[] = [\n\t{ name: \"Profile\", id: \"profile\", href: \"/admin/user\" },\n\t{ name: \"Settings\", id: \"settings\", href: \"/admin/settings\" },\n\t// Direct link to server-side logout - no JavaScript needed\n\t{ name: \"Logout\", id: \"logout\", href: \"/logout\" },\n];\n\n// Computed properties for UI configuration\nconst topbarConfig = computed(() => {\n\treturn {\n\t\tlogo: props.sidebarLogo,\n\t\taccountLogo: user.value?.avatar || \"\",\n\t\talerted: false,\n\t\tprofileMenu: props.profileMenuItems.length > 0\n\t\t\t? props.profileMenuItems\n\t\t\t: defaultProfileMenu,\n\t\tbrand: {\n\t\t\tname: user.value?.username || \"User\",\n\t\t\tdescription: user.value?.email || \"\",\n\t\t},\n\t\tselectItems: props.selectItems,\n\t\tselectedItem: props.selectedItem,\n\t};\n});\n\nconst sidebarConfig = computed(() => {\n\t// Add current attribute dynamically based on currentPage\n\tconst navigationItems = props.sidebarItems.map((item) => ({\n\t\tname: item.name,\n\t\ticon: item.icon,\n\t\tid: item.id,\n\t\tcurrent: item.id === props.currentPage,\n\t}));\n\n\treturn {\n\t\tnavigation: navigationItems,\n\t\tproductsSidebar: props.productsSidebar,\n\t\tlogo: props.sidebarLogo,\n\t};\n});\n\n// Event handlers\nconst handleSelectChanged = (item: SelectItemType | SelectItemType[]) => {\n\tconsole.log(\"Select changed:\", item);\n\t// Emit to parent component\n\tif (!Array.isArray(item) && item.id) {\n\t\temit(\"selectChanged\", { name: item.name, id: item.id });\n\t}\n};\n\nconst handleTopBarClick = (event: unknown) => {\n\t// Handle different possible event formats\n\tlet menuItemId: string | undefined;\n\tlet menuItemHref: string | undefined;\n\n\tif (typeof event === \"string\") {\n\t\tmenuItemId = event;\n\t} else if (event && typeof event === \"object\") {\n\t\tconst eventObj = event as Record<string, unknown>;\n\t\tmenuItemId = (eventObj.id as string) || (eventObj.name as string);\n\t\tmenuItemHref = eventObj.href as string;\n\t}\n\n\t// Handle logout separately\n\tif (menuItemId === \"logout\") {\n\t\thandleLogout();\n\t\treturn;\n\t}\n\n\t// First, look up href from our profileMenu configuration (takes priority)\n\tconst profileMenu = topbarConfig.value.profileMenu;\n\tconst menuItem = profileMenu.find((item) => item.id === menuItemId || item.name === menuItemId);\n\tif (menuItem?.href && menuItem.href !== \"#\") {\n\t\twindow.location.href = menuItem.href;\n\t\treturn;\n\t}\n\n\t// Fallback: use href from event object if not found in our config\n\tif (menuItemHref && menuItemHref !== \"#\") {\n\t\twindow.location.href = menuItemHref;\n\t}\n};\n\nconst handleSideBarClick = (itemId: string) => {\n\tconsole.log(\"Sidebar click:\", itemId);\n\n\t// Find the item by id to get the routeName\n\tconst item = props.sidebarItems.find(\n\t\t(i) => (i.id || i.name.toLowerCase()) === itemId,\n\t);\n\n\tif (item?.routeName) {\n\t\twindow.location.href = item.routeName;\n\t}\n};\n\nconst handleProductBarClick = (event: unknown) => {\n\tconsole.log(\"Product bar click:\", event);\n};\n\nconst handleInputChanged = (event: unknown) => {\n\tconsole.log(\"Input changed:\", event);\n};\n\nconst handleLogout = () => {\n\t// Navigate to server-side logout page\n\t// This is the most reliable approach because:\n\t// 1. Server can properly clear HttpOnly cookies via Set-Cookie headers\n\t// 2. Browser applies Set-Cookie headers from navigation responses (not fetch)\n\t// 3. Redirect happens server-side after cookies are cleared\n\twindow.location.href = \"/logout\";\n};\n\n// Intercept profile menu link clicks to use our configured hrefs\n// The uiWrapper may render links with default hrefs that don't include /admin prefix\nconst handleProfileLinkClick = (event: MouseEvent) => {\n\tconst target = event.target as HTMLElement;\n\tconst link = target.closest('a[href]') as HTMLAnchorElement | null;\n\n\tif (!link) return;\n\n\tconst href = link.getAttribute('href');\n\tif (!href) return;\n\n\t// Check if this is a profile menu link that needs redirection\n\tconst profileMenu = topbarConfig.value.profileMenu;\n\n\t// Handle logout link specifically (href=\"#\" with text \"Logout\")\n\tconst linkText = link.textContent?.trim().toLowerCase();\n\tif (href === '#' && linkText === 'logout') {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\thandleLogout();\n\t\treturn;\n\t}\n\n\t// Map of default paths to our configured paths\n\tconst pathMappings: Record<string, string | undefined> = {};\n\tfor (const item of profileMenu) {\n\t\t// Map common default paths to our configured hrefs\n\t\tif (item.id === 'settings' || item.name === 'Settings') {\n\t\t\tpathMappings['/settings'] = item.href;\n\t\t}\n\t\tif (item.id === 'profile' || item.name === 'Profile') {\n\t\t\tpathMappings['/profile'] = item.href;\n\t\t\tpathMappings['/user'] = item.href;\n\t\t}\n\t}\n\n\tconst redirectTo = pathMappings[href];\n\tif (redirectTo && redirectTo !== '#' && redirectTo !== href) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\twindow.location.href = redirectTo;\n\t}\n};\n\nonMounted(() => {\n\tdocument.addEventListener('click', handleProfileLinkClick, true);\n});\n\nonUnmounted(() => {\n\tdocument.removeEventListener('click', handleProfileLinkClick, true);\n});\n</script>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_Fragment","_renderList","_normalizeClass","_toDisplayString","_renderSlot","_createBlock","_unref","_createVNode"],"mappings":"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"}
|
package/dist/components.css
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import { u } from "../useTable-DutR1gkg.js";
|
|
2
|
-
import {
|
|
2
|
+
import { m, $, P, r, p, t, x, l, s, q, y, v, A, c, B, d, w, i, h, k, b, e, z, u as u2, f, g, o, a, j, n } from "../useAdminPage-DjONnrbe.js";
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
m as $currentBrand,
|
|
5
5
|
$ as $user,
|
|
6
6
|
P as PAGE_CONTEXT_KEY,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
r as averageStat,
|
|
8
|
+
p as countStat,
|
|
9
|
+
t as percentageStat,
|
|
10
|
+
x as resetGlobalConfirmation,
|
|
11
|
+
l as setCurrentBrand,
|
|
12
12
|
s as setUser,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
13
|
+
q as sumStat,
|
|
14
|
+
y as useAdminPage,
|
|
15
|
+
v as useConfirmation,
|
|
16
|
+
A as useDetailPage,
|
|
17
|
+
c as useForm,
|
|
18
|
+
B as useFormPage,
|
|
19
|
+
d as useFormValidation,
|
|
20
|
+
w as useGlobalConfirmation,
|
|
21
|
+
i as useHasAccessToAccount,
|
|
22
|
+
h as useHasAccessToBrand,
|
|
23
|
+
k as useHasRole,
|
|
24
|
+
b as useIntersectionObserver,
|
|
25
|
+
e as useJsonForm,
|
|
26
|
+
z as useListPage,
|
|
26
27
|
u2 as useModal,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
f as useNotifications,
|
|
29
|
+
g as usePageContext,
|
|
30
|
+
o as useStats,
|
|
30
31
|
u as useTable,
|
|
31
32
|
a as useTabs,
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
j as useUserRoles,
|
|
34
|
+
n as useWizard
|
|
34
35
|
};
|
|
35
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-QK97OdqQ.js","sources":["../../../node_modules/.pnpm/@nanostores+vue@1.0.1_@nanostores+logger@1.0.0_nanostores@1.1.0__@vue+devtools-api@8.0.
|
|
1
|
+
{"version":3,"file":"index-QK97OdqQ.js","sources":["../../../node_modules/.pnpm/@nanostores+vue@1.0.1_@nanostores+logger@1.0.0_nanostores@1.1.0__@vue+devtools-api@8.0._c092e7f7f0c6a3dca73b1ea880aefdb3/node_modules/@nanostores/vue/use-store/index.js"],"sourcesContent":["import {\n getCurrentInstance,\n getCurrentScope,\n onScopeDispose,\n readonly,\n shallowRef\n} from 'vue'\n\nexport function registerStore(store) {\n let instance = getCurrentInstance()\n if (instance && instance.proxy) {\n let vm = instance.proxy\n let cache = '_nanostores' in vm ? vm._nanostores : (vm._nanostores = [])\n cache.push(store)\n }\n}\n\nexport function useStore(store) {\n let state = shallowRef()\n\n let unsubscribe = store.subscribe(value => {\n state.value = value\n })\n\n getCurrentScope() && onScopeDispose(unsubscribe)\n\n if (process.env.NODE_ENV !== 'production') {\n registerStore(store)\n return readonly(state)\n }\n return state\n}\n"],"names":[],"mappings":";AAQO,SAAS,cAAc,OAAO;AACnC,MAAI,WAAW,mBAAkB;AACjC,MAAI,YAAY,SAAS,OAAO;AAC9B,QAAI,KAAK,SAAS;AAClB,QAAI,QAAQ,iBAAiB,KAAK,GAAG,cAAe,GAAG,cAAc,CAAA;AACrE,UAAM,KAAK,KAAK;AAAA,EAClB;AACF;AAEO,SAAS,SAAS,OAAO;AAC9B,MAAI,QAAQ,WAAU;AAEtB,MAAI,cAAc,MAAM,UAAU,WAAS;AACzC,UAAM,QAAQ;AAAA,EAChB,CAAC;AAED,kBAAe,KAAM,eAAe,WAAW;AAE/C,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,kBAAc,KAAK;AACnB,WAAO,SAAS,KAAK;AAAA,EACvB;AACA,SAAO;AACT;","x_google_ignoreList":[0]}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { j, _, k, i, T, h, c, d, a, b, f, g, s, e } from "./filterHelpers-DpHSlTuh.js";
|
|
2
2
|
import { a as a2, _ as _2 } from "./DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js";
|
|
3
|
-
import { a as a3, B, _ as _3, T as T2 } from "./AdminWrapper.vue_vue_type_script_setup_true_lang-
|
|
3
|
+
import { a as a3, B, _ as _3, T as T2 } from "./AdminWrapper.vue_vue_type_script_setup_true_lang-DgzX2LI3.js";
|
|
4
4
|
import { c as c2, a as a4, _ as _4, b as b2 } from "./Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js";
|
|
5
5
|
import { a as a5, _ as _5, c as c3, b as b3 } from "./ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js";
|
|
6
6
|
import { u } from "./useTable-DutR1gkg.js";
|
|
7
|
-
import {
|
|
7
|
+
import { m, $, P, r, p, t, x, l, s as s2, q, y, v, A, c as c4, B as B2, d as d2, w, i as i2, h as h2, k as k2, b as b4, e as e2, z, u as u2, f as f2, g as g2, o, a as a6, j as j2, n } from "./useAdminPage-DjONnrbe.js";
|
|
8
8
|
export {
|
|
9
|
-
|
|
9
|
+
m as $currentBrand,
|
|
10
10
|
$ as $user,
|
|
11
11
|
a3 as AdminWrapper,
|
|
12
12
|
c2 as Alert,
|
|
@@ -28,41 +28,42 @@ export {
|
|
|
28
28
|
T as Table,
|
|
29
29
|
T2 as Tabs,
|
|
30
30
|
b3 as UserAvatar,
|
|
31
|
-
|
|
31
|
+
r as averageStat,
|
|
32
32
|
h as booleanOptions,
|
|
33
33
|
c as columns,
|
|
34
|
-
|
|
34
|
+
p as countStat,
|
|
35
35
|
d as createFilterGroup,
|
|
36
36
|
a as createStatusColorFn,
|
|
37
37
|
b as filterPresets,
|
|
38
38
|
f as filters,
|
|
39
39
|
g as getStatusColor,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
t as percentageStat,
|
|
41
|
+
x as resetGlobalConfirmation,
|
|
42
|
+
l as setCurrentBrand,
|
|
43
43
|
s2 as setUser,
|
|
44
44
|
s as statusColors,
|
|
45
45
|
e as statusOptions,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
q as sumStat,
|
|
47
|
+
y as useAdminPage,
|
|
48
|
+
v as useConfirmation,
|
|
49
|
+
A as useDetailPage,
|
|
50
|
+
c4 as useForm,
|
|
51
|
+
B2 as useFormPage,
|
|
52
|
+
d2 as useFormValidation,
|
|
53
|
+
w as useGlobalConfirmation,
|
|
54
|
+
i2 as useHasAccessToAccount,
|
|
55
|
+
h2 as useHasAccessToBrand,
|
|
56
|
+
k2 as useHasRole,
|
|
57
|
+
b4 as useIntersectionObserver,
|
|
58
|
+
e2 as useJsonForm,
|
|
59
|
+
z as useListPage,
|
|
59
60
|
u2 as useModal,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
f2 as useNotifications,
|
|
62
|
+
g2 as usePageContext,
|
|
63
|
+
o as useStats,
|
|
63
64
|
u as useTable,
|
|
64
65
|
a6 as useTabs,
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
j2 as useUserRoles,
|
|
67
|
+
n as useWizard
|
|
67
68
|
};
|
|
68
69
|
//# sourceMappingURL=index.js.map
|
package/dist/navigation/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref, computed, watch,
|
|
1
|
+
import { ref, computed, watch, onUnmounted, onMounted, inject } from "vue";
|
|
2
2
|
import { routes } from "@htlkg/core";
|
|
3
3
|
import { a as atom } from "./index-DGO_pNgG.js";
|
|
4
4
|
import { u as useStore } from "./index-QK97OdqQ.js";
|
|
@@ -40,9 +40,9 @@ function useModal(options = {}) {
|
|
|
40
40
|
}
|
|
41
41
|
function useTabs(options) {
|
|
42
42
|
const tabs = ref(options.tabs);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
);
|
|
43
|
+
const initialTabId = options.initialTab || (tabs.value.length > 0 ? tabs.value[0].id : "");
|
|
44
|
+
const activeTab = ref(initialTabId);
|
|
45
|
+
const visitedTabs = ref(/* @__PURE__ */ new Set([initialTabId]));
|
|
46
46
|
const currentTabIndex = computed(
|
|
47
47
|
() => tabs.value.findIndex((tab) => tab.id === activeTab.value)
|
|
48
48
|
);
|
|
@@ -51,22 +51,28 @@ function useTabs(options) {
|
|
|
51
51
|
() => currentTabIndex.value === tabs.value.length - 1
|
|
52
52
|
);
|
|
53
53
|
function setActiveTab(tabId) {
|
|
54
|
-
var _a;
|
|
54
|
+
var _a, _b;
|
|
55
55
|
const tab = tabs.value.find((t) => t.id === tabId);
|
|
56
56
|
if (tab && !tab.disabled) {
|
|
57
|
+
const isFirstVisit = !visitedTabs.value.has(tabId);
|
|
57
58
|
activeTab.value = tabId;
|
|
59
|
+
visitedTabs.value.add(tabId);
|
|
58
60
|
(_a = options.onChange) == null ? void 0 : _a.call(options, tabId);
|
|
61
|
+
if (isFirstVisit && tab.lazy) {
|
|
62
|
+
(_b = options.onLazyLoad) == null ? void 0 : _b.call(options, tabId);
|
|
63
|
+
}
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
function nextTab() {
|
|
62
67
|
if (!isLastTab.value) {
|
|
63
68
|
const nextIndex = currentTabIndex.value + 1;
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
setActiveTab(
|
|
69
|
+
const nextTabItem = tabs.value[nextIndex];
|
|
70
|
+
if (nextTabItem && !nextTabItem.disabled) {
|
|
71
|
+
setActiveTab(nextTabItem.id);
|
|
67
72
|
} else if (nextIndex < tabs.value.length - 1) {
|
|
68
|
-
activeTab.value =
|
|
69
|
-
|
|
73
|
+
activeTab.value = nextTabItem.id;
|
|
74
|
+
visitedTabs.value.add(nextTabItem.id);
|
|
75
|
+
nextTab();
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
}
|
|
@@ -78,6 +84,7 @@ function useTabs(options) {
|
|
|
78
84
|
setActiveTab(prevTab.id);
|
|
79
85
|
} else if (prevIndex > 0) {
|
|
80
86
|
activeTab.value = prevTab.id;
|
|
87
|
+
visitedTabs.value.add(prevTab.id);
|
|
81
88
|
previousTab();
|
|
82
89
|
}
|
|
83
90
|
}
|
|
@@ -89,6 +96,16 @@ function useTabs(options) {
|
|
|
89
96
|
const tab = tabs.value.find((t) => t.id === tabId);
|
|
90
97
|
return (tab == null ? void 0 : tab.disabled) ?? false;
|
|
91
98
|
}
|
|
99
|
+
function isTabLoaded(tabId) {
|
|
100
|
+
const tab = tabs.value.find((t) => t.id === tabId);
|
|
101
|
+
if (!(tab == null ? void 0 : tab.lazy)) return true;
|
|
102
|
+
return visitedTabs.value.has(tabId);
|
|
103
|
+
}
|
|
104
|
+
function shouldRenderTab(tabId) {
|
|
105
|
+
const tab = tabs.value.find((t) => t.id === tabId);
|
|
106
|
+
if (!(tab == null ? void 0 : tab.lazy)) return activeTab.value === tabId;
|
|
107
|
+
return visitedTabs.value.has(tabId);
|
|
108
|
+
}
|
|
92
109
|
return {
|
|
93
110
|
activeTab,
|
|
94
111
|
tabs,
|
|
@@ -99,7 +116,49 @@ function useTabs(options) {
|
|
|
99
116
|
nextTab,
|
|
100
117
|
previousTab,
|
|
101
118
|
isTabActive,
|
|
102
|
-
isTabDisabled
|
|
119
|
+
isTabDisabled,
|
|
120
|
+
isTabLoaded,
|
|
121
|
+
shouldRenderTab,
|
|
122
|
+
visitedTabs
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function useIntersectionObserver(target, options = {}) {
|
|
126
|
+
const { root = null, rootMargin = "0px", threshold = 0, once = true } = options;
|
|
127
|
+
const isVisible = ref(false);
|
|
128
|
+
let observer = null;
|
|
129
|
+
function cleanup() {
|
|
130
|
+
if (observer) {
|
|
131
|
+
observer.disconnect();
|
|
132
|
+
observer = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function observe(el) {
|
|
136
|
+
cleanup();
|
|
137
|
+
if (!el || typeof IntersectionObserver === "undefined") {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
observer = new IntersectionObserver(
|
|
141
|
+
(entries) => {
|
|
142
|
+
const entry = entries[0];
|
|
143
|
+
if (entry) {
|
|
144
|
+
isVisible.value = entry.isIntersecting;
|
|
145
|
+
if (entry.isIntersecting && once) {
|
|
146
|
+
cleanup();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{ root, rootMargin, threshold }
|
|
151
|
+
);
|
|
152
|
+
observer.observe(el);
|
|
153
|
+
}
|
|
154
|
+
const stopWatch = watch(target, (el) => observe(el), { immediate: true });
|
|
155
|
+
onUnmounted(() => {
|
|
156
|
+
stopWatch();
|
|
157
|
+
cleanup();
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
isVisible,
|
|
161
|
+
stop: cleanup
|
|
103
162
|
};
|
|
104
163
|
}
|
|
105
164
|
function useForm(options) {
|
|
@@ -1162,33 +1221,34 @@ function useFormPage(options) {
|
|
|
1162
1221
|
}
|
|
1163
1222
|
export {
|
|
1164
1223
|
$user as $,
|
|
1165
|
-
|
|
1224
|
+
useDetailPage as A,
|
|
1225
|
+
useFormPage as B,
|
|
1166
1226
|
PAGE_CONTEXT_KEY as P,
|
|
1167
1227
|
useTabs as a,
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1228
|
+
useIntersectionObserver as b,
|
|
1229
|
+
useForm as c,
|
|
1230
|
+
useFormValidation as d,
|
|
1231
|
+
useJsonForm as e,
|
|
1232
|
+
useNotifications as f,
|
|
1233
|
+
usePageContext as g,
|
|
1234
|
+
useHasAccessToBrand as h,
|
|
1235
|
+
useHasAccessToAccount as i,
|
|
1236
|
+
useUserRoles as j,
|
|
1237
|
+
useHasRole as k,
|
|
1238
|
+
setCurrentBrand as l,
|
|
1239
|
+
$currentBrand as m,
|
|
1240
|
+
useWizard as n,
|
|
1241
|
+
useStats as o,
|
|
1242
|
+
countStat as p,
|
|
1243
|
+
sumStat as q,
|
|
1244
|
+
averageStat as r,
|
|
1185
1245
|
setUser as s,
|
|
1186
|
-
|
|
1246
|
+
percentageStat as t,
|
|
1187
1247
|
useModal as u,
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1248
|
+
useConfirmation as v,
|
|
1249
|
+
useGlobalConfirmation as w,
|
|
1250
|
+
resetGlobalConfirmation as x,
|
|
1251
|
+
useAdminPage as y,
|
|
1252
|
+
useListPage as z
|
|
1193
1253
|
};
|
|
1194
|
-
//# sourceMappingURL=useAdminPage-
|
|
1254
|
+
//# sourceMappingURL=useAdminPage-DjONnrbe.js.map
|