@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
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @htlkg/components
|
|
2
|
+
|
|
3
|
+
Vue 3 components with reactive state management for Hotelinking applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @htlkg/components
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Modules
|
|
12
|
+
|
|
13
|
+
### [Overlays](src/overlays/overlays.md)
|
|
14
|
+
Modal dialogs, notifications, alerts, and drawers.
|
|
15
|
+
|
|
16
|
+
### [Navigation](src/navigation/navigation.md)
|
|
17
|
+
Breadcrumbs, stepper, and tabs components.
|
|
18
|
+
|
|
19
|
+
### [Data](src/data/data.md)
|
|
20
|
+
Table, DataList, SearchableSelect, and Chart components.
|
|
21
|
+
|
|
22
|
+
### [Forms](src/forms/forms.md)
|
|
23
|
+
JsonSchemaForm and DateRange components.
|
|
24
|
+
|
|
25
|
+
### [Domain](src/domain/domain.md)
|
|
26
|
+
Domain-specific components: BrandCard, BrandSelector, ProductBadge, UserAvatar.
|
|
27
|
+
|
|
28
|
+
### [Composables](src/composables/composables.md)
|
|
29
|
+
Vue composables for component state management.
|
|
30
|
+
|
|
31
|
+
### [Stores](src/stores/stores.md)
|
|
32
|
+
Pinia stores for global component state.
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Import individual components
|
|
38
|
+
import { Alert, Modal, Table } from '@htlkg/components';
|
|
39
|
+
|
|
40
|
+
// Import from category
|
|
41
|
+
import { Alert, Modal } from '@htlkg/components/overlays';
|
|
42
|
+
import { Breadcrumbs, Stepper } from '@htlkg/components/navigation';
|
|
43
|
+
import { Table, DataList } from '@htlkg/components/data';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- v-model support for two-way binding
|
|
49
|
+
- TypeScript support with full type definitions
|
|
50
|
+
- Exposed methods for programmatic control
|
|
51
|
+
- Consistent API across all components
|
|
52
|
+
- Wraps @hotelinking/ui design system
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { defineComponent, computed, createElementBlock, openBlock, createElementVNode, Fragment, renderList, normalizeClass, createTextVNode, createCommentVNode, toDisplayString, renderSlot, createBlock, unref, createVNode, ref, withCtx } from "vue";
|
|
2
|
+
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.js";
|
|
3
|
+
import { uiStepsV4, uiBreadcrumbs, uiWrapper } from "@hotelinking/ui";
|
|
4
|
+
import { $user } from "./stores/index.js";
|
|
5
|
+
import { u as useStore } from "./index-QK97OdqQ.js";
|
|
6
|
+
const _hoisted_1$1 = { class: "tabs-wrapper" };
|
|
7
|
+
const _hoisted_2 = { class: "border-b border-gray-200" };
|
|
8
|
+
const _hoisted_3 = {
|
|
9
|
+
class: "-mb-px flex space-x-8",
|
|
10
|
+
"aria-label": "Tabs"
|
|
11
|
+
};
|
|
12
|
+
const _hoisted_4 = ["onClick", "aria-current"];
|
|
13
|
+
const _hoisted_5 = { class: "tabs-content mt-4" };
|
|
14
|
+
const _hoisted_6 = { key: 0 };
|
|
15
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
16
|
+
__name: "Tabs",
|
|
17
|
+
props: {
|
|
18
|
+
tabs: {},
|
|
19
|
+
modelValue: { default: "" }
|
|
20
|
+
},
|
|
21
|
+
emits: ["update:modelValue", "tab-change"],
|
|
22
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
23
|
+
const props = __props;
|
|
24
|
+
const emit = __emit;
|
|
25
|
+
const currentTab = computed({
|
|
26
|
+
get: () => props.modelValue || (props.tabs.length > 0 ? props.tabs[0].id : ""),
|
|
27
|
+
set: (value) => {
|
|
28
|
+
emit("update:modelValue", value);
|
|
29
|
+
emit("tab-change", value);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
__expose({
|
|
33
|
+
setActiveTab: (tabId) => {
|
|
34
|
+
currentTab.value = tabId;
|
|
35
|
+
},
|
|
36
|
+
getActiveTab: () => currentTab.value,
|
|
37
|
+
nextTab: () => {
|
|
38
|
+
const currentIndex = props.tabs.findIndex((t) => t.id === currentTab.value);
|
|
39
|
+
if (currentIndex < props.tabs.length - 1) {
|
|
40
|
+
currentTab.value = props.tabs[currentIndex + 1].id;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
previousTab: () => {
|
|
44
|
+
const currentIndex = props.tabs.findIndex((t) => t.id === currentTab.value);
|
|
45
|
+
if (currentIndex > 0) {
|
|
46
|
+
currentTab.value = props.tabs[currentIndex - 1].id;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return (_ctx, _cache) => {
|
|
51
|
+
return openBlock(), createElementBlock("div", _hoisted_1$1, [
|
|
52
|
+
createElementVNode("div", _hoisted_2, [
|
|
53
|
+
createElementVNode("nav", _hoisted_3, [
|
|
54
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab) => {
|
|
55
|
+
return openBlock(), createElementBlock("button", {
|
|
56
|
+
key: tab.id,
|
|
57
|
+
onClick: ($event) => currentTab.value = tab.id,
|
|
58
|
+
class: normalizeClass([
|
|
59
|
+
currentTab.value === tab.id ? "border-blue-500 text-blue-600" : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
|
|
60
|
+
"whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-colors"
|
|
61
|
+
]),
|
|
62
|
+
"aria-current": currentTab.value === tab.id ? "page" : void 0
|
|
63
|
+
}, [
|
|
64
|
+
createTextVNode(toDisplayString(tab.label) + " ", 1),
|
|
65
|
+
tab.count !== void 0 && tab.count > 0 ? (openBlock(), createElementBlock("span", {
|
|
66
|
+
key: 0,
|
|
67
|
+
class: normalizeClass([
|
|
68
|
+
currentTab.value === tab.id ? "bg-blue-100 text-blue-600" : "bg-gray-100 text-gray-900",
|
|
69
|
+
"ml-3 hidden rounded-full py-0.5 px-2.5 text-xs font-medium md:inline-block"
|
|
70
|
+
])
|
|
71
|
+
}, toDisplayString(tab.count), 3)) : createCommentVNode("", true)
|
|
72
|
+
], 10, _hoisted_4);
|
|
73
|
+
}), 128))
|
|
74
|
+
])
|
|
75
|
+
]),
|
|
76
|
+
createElementVNode("div", _hoisted_5, [
|
|
77
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab) => {
|
|
78
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
79
|
+
key: tab.id
|
|
80
|
+
}, [
|
|
81
|
+
currentTab.value === tab.id ? (openBlock(), createElementBlock("div", _hoisted_6, [
|
|
82
|
+
renderSlot(_ctx.$slots, tab.id, { activeTab: currentTab.value }, void 0, true)
|
|
83
|
+
])) : createCommentVNode("", true)
|
|
84
|
+
], 64);
|
|
85
|
+
}), 128))
|
|
86
|
+
])
|
|
87
|
+
]);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-c776bc53"]]);
|
|
92
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
93
|
+
__name: "Stepper",
|
|
94
|
+
props: {
|
|
95
|
+
steps: {},
|
|
96
|
+
currentStep: { default: 0 },
|
|
97
|
+
validateOnNext: { type: Boolean, default: false },
|
|
98
|
+
allowSkip: { type: Boolean, default: false }
|
|
99
|
+
},
|
|
100
|
+
emits: ["step-click", "step-completed", "step-current", "step-upcoming", "validation-failed", "update:currentStep"],
|
|
101
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
102
|
+
const props = __props;
|
|
103
|
+
const emit = __emit;
|
|
104
|
+
const uiSteps = computed(
|
|
105
|
+
() => props.steps.map((step, index) => ({
|
|
106
|
+
id: step.id || String(index + 1).padStart(2, "0"),
|
|
107
|
+
name: step.label,
|
|
108
|
+
status: step.status || (index < props.currentStep ? "complete" : index === props.currentStep ? "current" : "upcoming")
|
|
109
|
+
}))
|
|
110
|
+
);
|
|
111
|
+
function canNavigateToStep(targetIndex) {
|
|
112
|
+
if (props.allowSkip) return true;
|
|
113
|
+
if (!props.validateOnNext) return true;
|
|
114
|
+
if (targetIndex < props.currentStep) return true;
|
|
115
|
+
const currentStepData = props.steps[props.currentStep];
|
|
116
|
+
if (targetIndex > props.currentStep && currentStepData.valid === false) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
for (let i = props.currentStep; i < targetIndex; i++) {
|
|
120
|
+
if (props.steps[i].valid === false) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
function handleStepClick(step, index) {
|
|
127
|
+
const originalStep = props.steps[index];
|
|
128
|
+
if (!canNavigateToStep(index)) {
|
|
129
|
+
const currentStepData = props.steps[props.currentStep];
|
|
130
|
+
emit("validation-failed", currentStepData, props.currentStep);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
emit("step-click", originalStep, index);
|
|
134
|
+
emit("update:currentStep", index);
|
|
135
|
+
}
|
|
136
|
+
function handleStepCompleted(step) {
|
|
137
|
+
const index = uiSteps.value.findIndex((s) => s.id === step.id);
|
|
138
|
+
if (index !== -1) {
|
|
139
|
+
emit("step-completed", props.steps[index]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function handleStepCurrent(step) {
|
|
143
|
+
const index = uiSteps.value.findIndex((s) => s.id === step.id);
|
|
144
|
+
if (index !== -1) {
|
|
145
|
+
emit("step-current", props.steps[index]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function handleStepUpcoming(step) {
|
|
149
|
+
const index = uiSteps.value.findIndex((s) => s.id === step.id);
|
|
150
|
+
if (index !== -1) {
|
|
151
|
+
emit("step-upcoming", props.steps[index]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function goToStep(index) {
|
|
155
|
+
if (index < 0 || index >= props.steps.length) return false;
|
|
156
|
+
if (!canNavigateToStep(index)) {
|
|
157
|
+
const currentStepData = props.steps[props.currentStep];
|
|
158
|
+
emit("validation-failed", currentStepData, props.currentStep);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
emit("update:currentStep", index);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
function goToNext() {
|
|
165
|
+
return goToStep(props.currentStep + 1);
|
|
166
|
+
}
|
|
167
|
+
function goToPrevious() {
|
|
168
|
+
return goToStep(props.currentStep - 1);
|
|
169
|
+
}
|
|
170
|
+
function validateCurrentStep() {
|
|
171
|
+
const currentStepData = props.steps[props.currentStep];
|
|
172
|
+
return currentStepData.valid !== false;
|
|
173
|
+
}
|
|
174
|
+
__expose({
|
|
175
|
+
getCurrentStep: () => props.currentStep,
|
|
176
|
+
getSteps: () => props.steps,
|
|
177
|
+
goToStep,
|
|
178
|
+
goToNext,
|
|
179
|
+
goToPrevious,
|
|
180
|
+
validateCurrentStep,
|
|
181
|
+
canNavigateToStep
|
|
182
|
+
});
|
|
183
|
+
return (_ctx, _cache) => {
|
|
184
|
+
return openBlock(), createBlock(unref(uiStepsV4), {
|
|
185
|
+
steps: uiSteps.value,
|
|
186
|
+
onStepClick: handleStepClick,
|
|
187
|
+
onStepCompleted: handleStepCompleted,
|
|
188
|
+
onStepCurrent: handleStepCurrent,
|
|
189
|
+
onStepUpcoming: handleStepUpcoming
|
|
190
|
+
}, null, 8, ["steps"]);
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
const _hoisted_1 = { class: "breadcrumbs-wrapper" };
|
|
195
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
196
|
+
__name: "Breadcrumbs",
|
|
197
|
+
props: {
|
|
198
|
+
items: {},
|
|
199
|
+
loading: { type: Boolean, default: false }
|
|
200
|
+
},
|
|
201
|
+
emits: ["breadcrumb-click"],
|
|
202
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
203
|
+
const props = __props;
|
|
204
|
+
const emit = __emit;
|
|
205
|
+
const pagesConfig = computed(
|
|
206
|
+
() => props.items.map((item, index) => ({
|
|
207
|
+
name: item.label,
|
|
208
|
+
routeName: item.routeName,
|
|
209
|
+
current: item.current ?? index === props.items.length - 1
|
|
210
|
+
}))
|
|
211
|
+
);
|
|
212
|
+
function handleBreadcrumbClick(routeName) {
|
|
213
|
+
emit("breadcrumb-click", routeName);
|
|
214
|
+
}
|
|
215
|
+
__expose({
|
|
216
|
+
getItems: () => props.items
|
|
217
|
+
});
|
|
218
|
+
return (_ctx, _cache) => {
|
|
219
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
220
|
+
createVNode(unref(uiBreadcrumbs), {
|
|
221
|
+
pages: pagesConfig.value,
|
|
222
|
+
loading: __props.loading,
|
|
223
|
+
onBreadCrumbClicked: handleBreadcrumbClick
|
|
224
|
+
}, null, 8, ["pages", "loading"])
|
|
225
|
+
]);
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const Breadcrumbs = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-3137d38d"]]);
|
|
230
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
231
|
+
__name: "AdminWrapper",
|
|
232
|
+
props: {
|
|
233
|
+
sidebarLogo: {},
|
|
234
|
+
currentPage: { default: "dashboard" },
|
|
235
|
+
sidebarTitle: {},
|
|
236
|
+
sidebarItems: { default: () => [] },
|
|
237
|
+
topbarActions: { default: () => [] },
|
|
238
|
+
selectItems: { default: () => [] },
|
|
239
|
+
selectedItem: { default: () => ({ name: "", id: "" }) },
|
|
240
|
+
productsSidebar: { default: () => [] },
|
|
241
|
+
sidebarOpenByDefault: { type: Boolean, default: true }
|
|
242
|
+
},
|
|
243
|
+
emits: ["selectChanged"],
|
|
244
|
+
setup(__props, { emit: __emit }) {
|
|
245
|
+
const props = __props;
|
|
246
|
+
const emit = __emit;
|
|
247
|
+
const sidebarOpen = ref(props.sidebarOpenByDefault);
|
|
248
|
+
const user = useStore($user);
|
|
249
|
+
const topbarConfig = computed(() => {
|
|
250
|
+
var _a, _b, _c;
|
|
251
|
+
return {
|
|
252
|
+
logo: props.sidebarLogo,
|
|
253
|
+
accountLogo: ((_a = user.value) == null ? void 0 : _a.avatar) || "",
|
|
254
|
+
alerted: false,
|
|
255
|
+
profileMenu: [
|
|
256
|
+
{
|
|
257
|
+
name: "Profile",
|
|
258
|
+
id: "profile",
|
|
259
|
+
href: "/profile"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "Settings",
|
|
263
|
+
id: "settings",
|
|
264
|
+
href: "/settings"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "Logout",
|
|
268
|
+
id: "logout",
|
|
269
|
+
href: "#"
|
|
270
|
+
}
|
|
271
|
+
],
|
|
272
|
+
brand: {
|
|
273
|
+
name: ((_b = user.value) == null ? void 0 : _b.username) || "User",
|
|
274
|
+
description: ((_c = user.value) == null ? void 0 : _c.email) || ""
|
|
275
|
+
},
|
|
276
|
+
selectItems: props.selectItems,
|
|
277
|
+
selectedItem: props.selectedItem
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
const sidebarConfig = computed(() => {
|
|
281
|
+
const navigationItems = props.sidebarItems.map((item) => ({
|
|
282
|
+
name: item.name,
|
|
283
|
+
icon: item.icon,
|
|
284
|
+
id: item.id,
|
|
285
|
+
current: item.id === props.currentPage
|
|
286
|
+
}));
|
|
287
|
+
return {
|
|
288
|
+
navigation: navigationItems,
|
|
289
|
+
productsSidebar: props.productsSidebar,
|
|
290
|
+
logo: props.sidebarLogo
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
const handleSelectChanged = (item) => {
|
|
294
|
+
console.log("Select changed:", item);
|
|
295
|
+
if (!Array.isArray(item) && item.id) {
|
|
296
|
+
emit("selectChanged", { name: item.name, id: item.id });
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
const handleTopBarClick = (event) => {
|
|
300
|
+
let menuItem;
|
|
301
|
+
if (typeof event === "string") {
|
|
302
|
+
menuItem = event;
|
|
303
|
+
} else if (event && typeof event === "object") {
|
|
304
|
+
const eventObj = event;
|
|
305
|
+
menuItem = eventObj.name || eventObj.href;
|
|
306
|
+
}
|
|
307
|
+
console.log("Extracted menu item:", menuItem);
|
|
308
|
+
if (menuItem === "logout") {
|
|
309
|
+
handleLogout();
|
|
310
|
+
} else if (menuItem === "profile") {
|
|
311
|
+
window.location.href = "/profile";
|
|
312
|
+
} else if (menuItem === "settings") {
|
|
313
|
+
window.location.href = "/settings";
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
const handleSideBarClick = (itemId) => {
|
|
317
|
+
console.log("Sidebar click:", itemId);
|
|
318
|
+
const item = props.sidebarItems.find(
|
|
319
|
+
(i) => (i.id || i.name.toLowerCase()) === itemId
|
|
320
|
+
);
|
|
321
|
+
if (item == null ? void 0 : item.routeName) {
|
|
322
|
+
window.location.href = item.routeName;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const handleProductBarClick = (event) => {
|
|
326
|
+
console.log("Product bar click:", event);
|
|
327
|
+
};
|
|
328
|
+
const handleInputChanged = (event) => {
|
|
329
|
+
console.log("Input changed:", event);
|
|
330
|
+
};
|
|
331
|
+
const handleLogout = async () => {
|
|
332
|
+
try {
|
|
333
|
+
const { signOut } = await import("@htlkg/core/auth");
|
|
334
|
+
await signOut();
|
|
335
|
+
window.location.href = "/login";
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error("Logout error:", error);
|
|
338
|
+
window.location.href = "/login";
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
return (_ctx, _cache) => {
|
|
342
|
+
return openBlock(), createBlock(unref(uiWrapper), {
|
|
343
|
+
sidebar: sidebarConfig.value,
|
|
344
|
+
topbar: topbarConfig.value,
|
|
345
|
+
sidebarOpen: sidebarOpen.value,
|
|
346
|
+
onSelectChanged: handleSelectChanged,
|
|
347
|
+
onTopBarClick: handleTopBarClick,
|
|
348
|
+
onSideBarClick: handleSideBarClick,
|
|
349
|
+
onProductBarClick: handleProductBarClick,
|
|
350
|
+
onInputChanged: handleInputChanged,
|
|
351
|
+
onSidebarToggle: _cache[0] || (_cache[0] = (isOpen) => sidebarOpen.value = isOpen)
|
|
352
|
+
}, {
|
|
353
|
+
default: withCtx(() => [
|
|
354
|
+
renderSlot(_ctx.$slots, "default")
|
|
355
|
+
]),
|
|
356
|
+
_: 3
|
|
357
|
+
}, 8, ["sidebar", "topbar", "sidebarOpen"]);
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
export {
|
|
362
|
+
Breadcrumbs as B,
|
|
363
|
+
Tabs as T,
|
|
364
|
+
_sfc_main$2 as _,
|
|
365
|
+
_sfc_main as a
|
|
366
|
+
};
|
|
367
|
+
//# sourceMappingURL=AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js","sources":["../src/navigation/Tabs.vue","../src/navigation/Stepper.vue","../src/navigation/Breadcrumbs.vue","../src/navigation/AdminWrapper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { 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}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: ''\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [tabId: string];\n 'tab-change': [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\n\n// Expose methods for parent components\ndefineExpose({\n setActiveTab: (tabId: string) => { currentTab.value = tabId; },\n getActiveTab: () => currentTab.value,\n nextTab: () => {\n const currentIndex = props.tabs.findIndex(t => t.id === currentTab.value);\n if (currentIndex < props.tabs.length - 1) {\n currentTab.value = 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 currentTab.value = 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=\"currentTab = 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=\"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 } from \"vue\";\nimport { $user } from \"../stores/user\";\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\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\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// 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: [\n\t\t\t{\n\t\t\t\tname: \"Profile\",\n\t\t\t\tid: \"profile\",\n\t\t\t\thref: \"/profile\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"Settings\",\n\t\t\t\tid: \"settings\",\n\t\t\t\thref: \"/settings\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"Logout\",\n\t\t\t\tid: \"logout\",\n\t\t\t\thref: \"#\",\n\t\t\t},\n\t\t],\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 menuItem: string | undefined;\n\n\tif (typeof event === \"string\") {\n\t\tmenuItem = event;\n\t} else if (event && typeof event === \"object\") {\n\t\t// Check if it's an object with name or href property\n\t\tconst eventObj = event as Record<string, unknown>;\n\t\tmenuItem = (eventObj.name as string) || (eventObj.href as string);\n\t}\n\n\tconsole.log(\"Extracted menu item:\", menuItem);\n\n\t// The event is the menu item name\n\tif (menuItem === \"logout\") {\n\t\thandleLogout();\n\t} else if (menuItem === \"profile\") {\n\t\twindow.location.href = \"/profile\";\n\t} else if (menuItem === \"settings\") {\n\t\twindow.location.href = \"/settings\";\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 = async () => {\n\ttry {\n\t\t// Import logout from auth package\n\t\tconst { signOut } = await import('@htlkg/core/auth');\n\t\tawait signOut();\n\t\t// Redirect to login page\n\t\twindow.location.href = \"/login\";\n\t} catch (error) {\n\t\tconsole.error(\"Logout error:\", error);\n\t\t// Force redirect even if logout fails\n\t\twindow.location.href = \"/login\";\n\t}\n};\n</script>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_Fragment","_renderList","_normalizeClass","_toDisplayString","_renderSlot","_createBlock","_unref","_createVNode"],"mappings":"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"}
|