@htlkg/components 0.0.2 → 0.0.3
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/composables/index.js +196 -4
- package/dist/composables/index.js.map +1 -1
- package/package.json +7 -4
- package/src/composables/composables.md +109 -0
- package/src/composables/index.ts +17 -0
- package/src/composables/usePageContext.ts +171 -0
- package/src/composables/useTable.ts +26 -5
- package/src/data/DataTable.vue +553 -0
- package/src/data/Table/Table.vue +295 -0
- package/src/data/columnHelpers.ts +334 -0
- package/src/data/data.md +106 -0
- package/src/data/index.ts +20 -0
- package/src/domain/domain.md +102 -0
- 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
|
|
@@ -26,9 +26,10 @@ function useTable(options) {
|
|
|
26
26
|
const activeFilters = ref([]);
|
|
27
27
|
const hiddenColumns = ref([]);
|
|
28
28
|
const filteredItems = computed(() => {
|
|
29
|
-
|
|
29
|
+
const filters = Array.isArray(activeFilters.value) ? activeFilters.value : [];
|
|
30
|
+
if (filters.length === 0) return items.value;
|
|
30
31
|
return items.value.filter((item) => {
|
|
31
|
-
return
|
|
32
|
+
return filters.every((filter) => {
|
|
32
33
|
const { category, operator, value } = filter;
|
|
33
34
|
if (value === void 0 || value === null || value === "") return true;
|
|
34
35
|
const itemValue = item[category];
|
|
@@ -162,7 +163,21 @@ function useTable(options) {
|
|
|
162
163
|
return selectedItemIds.value.has(id);
|
|
163
164
|
}
|
|
164
165
|
function applyFilters(filters) {
|
|
165
|
-
|
|
166
|
+
if (Array.isArray(filters)) {
|
|
167
|
+
activeFilters.value = filters;
|
|
168
|
+
} else if (filters && typeof filters === "object") {
|
|
169
|
+
if ("filters" in filters && Array.isArray(filters.filters)) {
|
|
170
|
+
activeFilters.value = filters.filters;
|
|
171
|
+
} else {
|
|
172
|
+
activeFilters.value = Object.entries(filters).filter(([_, value]) => value !== void 0 && value !== null && value !== "").map(([key, value]) => ({
|
|
173
|
+
category: key,
|
|
174
|
+
operator: "contains",
|
|
175
|
+
value
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
activeFilters.value = [];
|
|
180
|
+
}
|
|
166
181
|
currentPage.value = 1;
|
|
167
182
|
}
|
|
168
183
|
function clearFilters() {
|
|
@@ -564,12 +579,189 @@ function useNotifications() {
|
|
|
564
579
|
error
|
|
565
580
|
};
|
|
566
581
|
}
|
|
582
|
+
|
|
583
|
+
// src/composables/usePageContext.ts
|
|
584
|
+
import { computed as computed4, inject } from "vue";
|
|
585
|
+
|
|
586
|
+
// ../../node_modules/.pnpm/@nanostores+vue@1.0.1_@nanostores+logger@1.0.0_nanostores@1.1.0__nanostores@1.1.0_vue@3.5.25_typescript@5.9.3_/node_modules/@nanostores/vue/use-store/index.js
|
|
587
|
+
import {
|
|
588
|
+
getCurrentInstance,
|
|
589
|
+
getCurrentScope,
|
|
590
|
+
onScopeDispose,
|
|
591
|
+
readonly,
|
|
592
|
+
shallowRef
|
|
593
|
+
} from "vue";
|
|
594
|
+
function registerStore(store) {
|
|
595
|
+
let instance = getCurrentInstance();
|
|
596
|
+
if (instance && instance.proxy) {
|
|
597
|
+
let vm = instance.proxy;
|
|
598
|
+
let cache = "_nanostores" in vm ? vm._nanostores : vm._nanostores = [];
|
|
599
|
+
cache.push(store);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
function useStore(store) {
|
|
603
|
+
let state = shallowRef();
|
|
604
|
+
let unsubscribe = store.subscribe((value) => {
|
|
605
|
+
state.value = value;
|
|
606
|
+
});
|
|
607
|
+
getCurrentScope() && onScopeDispose(unsubscribe);
|
|
608
|
+
if (process.env.NODE_ENV !== "production") {
|
|
609
|
+
registerStore(store);
|
|
610
|
+
return readonly(state);
|
|
611
|
+
}
|
|
612
|
+
return state;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js
|
|
616
|
+
var clean = /* @__PURE__ */ Symbol("clean");
|
|
617
|
+
|
|
618
|
+
// ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js
|
|
619
|
+
var listenerQueue = [];
|
|
620
|
+
var lqIndex = 0;
|
|
621
|
+
var QUEUE_ITEMS_PER_LISTENER = 4;
|
|
622
|
+
var epoch = 0;
|
|
623
|
+
var atom = /* @__NO_SIDE_EFFECTS__ */ (initialValue) => {
|
|
624
|
+
let listeners = [];
|
|
625
|
+
let $atom = {
|
|
626
|
+
get() {
|
|
627
|
+
if (!$atom.lc) {
|
|
628
|
+
$atom.listen(() => {
|
|
629
|
+
})();
|
|
630
|
+
}
|
|
631
|
+
return $atom.value;
|
|
632
|
+
},
|
|
633
|
+
lc: 0,
|
|
634
|
+
listen(listener) {
|
|
635
|
+
$atom.lc = listeners.push(listener);
|
|
636
|
+
return () => {
|
|
637
|
+
for (let i = lqIndex + QUEUE_ITEMS_PER_LISTENER; i < listenerQueue.length; ) {
|
|
638
|
+
if (listenerQueue[i] === listener) {
|
|
639
|
+
listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER);
|
|
640
|
+
} else {
|
|
641
|
+
i += QUEUE_ITEMS_PER_LISTENER;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
let index = listeners.indexOf(listener);
|
|
645
|
+
if (~index) {
|
|
646
|
+
listeners.splice(index, 1);
|
|
647
|
+
if (!--$atom.lc) $atom.off();
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
},
|
|
651
|
+
notify(oldValue, changedKey) {
|
|
652
|
+
epoch++;
|
|
653
|
+
let runListenerQueue = !listenerQueue.length;
|
|
654
|
+
for (let listener of listeners) {
|
|
655
|
+
listenerQueue.push(listener, $atom.value, oldValue, changedKey);
|
|
656
|
+
}
|
|
657
|
+
if (runListenerQueue) {
|
|
658
|
+
for (lqIndex = 0; lqIndex < listenerQueue.length; lqIndex += QUEUE_ITEMS_PER_LISTENER) {
|
|
659
|
+
listenerQueue[lqIndex](
|
|
660
|
+
listenerQueue[lqIndex + 1],
|
|
661
|
+
listenerQueue[lqIndex + 2],
|
|
662
|
+
listenerQueue[lqIndex + 3]
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
listenerQueue.length = 0;
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
/* It will be called on last listener unsubscribing.
|
|
669
|
+
We will redefine it in onMount and onStop. */
|
|
670
|
+
off() {
|
|
671
|
+
},
|
|
672
|
+
set(newValue) {
|
|
673
|
+
let oldValue = $atom.value;
|
|
674
|
+
if (oldValue !== newValue) {
|
|
675
|
+
$atom.value = newValue;
|
|
676
|
+
$atom.notify(oldValue);
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
subscribe(listener) {
|
|
680
|
+
let unbind = $atom.listen(listener);
|
|
681
|
+
listener($atom.value);
|
|
682
|
+
return unbind;
|
|
683
|
+
},
|
|
684
|
+
value: initialValue
|
|
685
|
+
};
|
|
686
|
+
if (process.env.NODE_ENV !== "production") {
|
|
687
|
+
$atom[clean] = () => {
|
|
688
|
+
listeners = [];
|
|
689
|
+
$atom.lc = 0;
|
|
690
|
+
$atom.off();
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
return $atom;
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/composables/usePageContext.ts
|
|
697
|
+
import { routes } from "@htlkg/core";
|
|
698
|
+
var PAGE_CONTEXT_KEY = /* @__PURE__ */ Symbol("pageContext");
|
|
699
|
+
var $user = atom(null);
|
|
700
|
+
var $currentBrand = atom(null);
|
|
701
|
+
function setUser(user) {
|
|
702
|
+
$user.set(user);
|
|
703
|
+
}
|
|
704
|
+
function setCurrentBrand(brand) {
|
|
705
|
+
$currentBrand.set(brand);
|
|
706
|
+
}
|
|
707
|
+
function usePageContext() {
|
|
708
|
+
const injected = inject(PAGE_CONTEXT_KEY, null);
|
|
709
|
+
if (injected) {
|
|
710
|
+
return computed4(() => injected);
|
|
711
|
+
}
|
|
712
|
+
const user = useStore($user);
|
|
713
|
+
const brand = useStore($currentBrand);
|
|
714
|
+
return computed4(() => ({
|
|
715
|
+
user: user.value,
|
|
716
|
+
brand: brand.value ?? void 0,
|
|
717
|
+
brandId: brand.value?.id,
|
|
718
|
+
isAdmin: user.value?.isAdmin ?? false,
|
|
719
|
+
isSuperAdmin: user.value?.isSuperAdmin ?? false,
|
|
720
|
+
routes
|
|
721
|
+
}));
|
|
722
|
+
}
|
|
723
|
+
function useHasAccessToBrand(brandId) {
|
|
724
|
+
const context = usePageContext();
|
|
725
|
+
return computed4(() => {
|
|
726
|
+
const user = context.value.user;
|
|
727
|
+
if (!user) return false;
|
|
728
|
+
if (user.isAdmin || user.isSuperAdmin) return true;
|
|
729
|
+
return user.brandIds?.includes(brandId) ?? false;
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
function useHasAccessToAccount(accountId) {
|
|
733
|
+
const context = usePageContext();
|
|
734
|
+
return computed4(() => {
|
|
735
|
+
const user = context.value.user;
|
|
736
|
+
if (!user) return false;
|
|
737
|
+
if (user.isAdmin || user.isSuperAdmin) return true;
|
|
738
|
+
return user.accountIds?.includes(accountId) ?? false;
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
function useUserRoles() {
|
|
742
|
+
const context = usePageContext();
|
|
743
|
+
return computed4(() => context.value.user?.roles ?? []);
|
|
744
|
+
}
|
|
745
|
+
function useHasRole(role) {
|
|
746
|
+
const roles = useUserRoles();
|
|
747
|
+
return computed4(() => roles.value.includes(role));
|
|
748
|
+
}
|
|
567
749
|
export {
|
|
750
|
+
$currentBrand,
|
|
751
|
+
$user,
|
|
752
|
+
PAGE_CONTEXT_KEY,
|
|
753
|
+
setCurrentBrand,
|
|
754
|
+
setUser,
|
|
568
755
|
useForm,
|
|
569
756
|
useFormValidation,
|
|
757
|
+
useHasAccessToAccount,
|
|
758
|
+
useHasAccessToBrand,
|
|
759
|
+
useHasRole,
|
|
570
760
|
useModal,
|
|
571
761
|
useNotifications,
|
|
762
|
+
usePageContext,
|
|
572
763
|
useTable,
|
|
573
|
-
useTabs
|
|
764
|
+
useTabs,
|
|
765
|
+
useUserRoles
|
|
574
766
|
};
|
|
575
767
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/composables/useTable.ts","../../src/composables/useModal.ts","../../src/composables/useTabs.ts","../../src/composables/useForm.ts","../../src/composables/useFormValidation.ts","../../src/composables/useNotifications.ts"],"sourcesContent":["import { ref, computed, unref, type Ref, type ComputedRef, type MaybeRef } from 'vue';\n\nexport interface SmartFilter {\n category: string;\n operator: string;\n value: any;\n}\n\nexport interface UseTableOptions<T> {\n items: MaybeRef<T[]>; // Accept both arrays and refs/computed\n pageSize?: number;\n sortKey?: string;\n sortOrder?: 'asc' | 'desc';\n idKey?: string; // Key to use for item identification (default: 'id')\n}\n\nexport interface UseTableReturn<T> {\n // Pagination\n currentPage: Ref<number>;\n pageSize: Ref<number>;\n totalPages: ComputedRef<number>;\n totalItems: ComputedRef<number>;\n paginatedItems: ComputedRef<T[]>;\n \n // Sorting\n sortKey: Ref<string>;\n sortOrder: Ref<'asc' | 'desc'>;\n sortedItems: ComputedRef<T[]>;\n \n // Selection\n selectedItems: Ref<T[]>;\n selectedItemIds: Ref<Set<string | number>>;\n allSelected: ComputedRef<boolean>;\n someSelected: ComputedRef<boolean>;\n \n // Filtering\n activeFilters: Ref<SmartFilter[]>;\n filteredItems: ComputedRef<T[]>;\n \n // Column visibility\n hiddenColumns: Ref<number[]>;\n \n // Reset state\n resetSelected: Ref<boolean>;\n \n // Methods - Pagination\n setPage: (page: number) => void;\n setPageSize: (size: number) => void;\n \n // Methods - Sorting\n setSorting: (key: string, order?: 'asc' | 'desc') => void;\n handleOrderBy: (event: { value: string; orderDirection: 'asc' | 'desc' }) => void;\n \n // Methods - Selection\n selectItem: (item: T) => void;\n deselectItem: (item: T) => void;\n selectAll: () => void;\n selectAllOnPage: () => void;\n clearSelection: () => void;\n isSelected: (item: T) => boolean;\n \n // Methods - Filtering\n applyFilters: (filters: SmartFilter[]) => void;\n clearFilters: () => void;\n removeFilter: (index: number) => void;\n \n // Methods - Column visibility\n toggleColumn: (index: number) => void;\n showColumn: (index: number) => void;\n hideColumn: (index: number) => void;\n \n // Event handlers for uiTable\n handlePageChange: (page: number) => void;\n handlePageSizeChange: (size: number | string) => void;\n handleSmartFiltersApplied: (filters: SmartFilter[]) => void;\n handleSmartFiltersCleared: () => void;\n handleSmartFilterDeleted: (index: number) => void;\n handleColumnsVisibilityChanged: (event: { index: number; hidden: boolean }) => void;\n handleModalAction: (event: { modal: string; action: string }) => void;\n}\n\nexport function useTable<T extends Record<string, any>>(\n options: UseTableOptions<T>\n): UseTableReturn<T> {\n const idKey = options.idKey ?? 'id';\n \n // Create a reactive reference to items with safety check\n const items = computed(() => {\n try {\n const unwrapped = unref(options.items);\n // Ensure we always return an array\n if (!unwrapped) return [];\n if (!Array.isArray(unwrapped)) {\n console.warn('useTable: items is not an array', unwrapped);\n return [];\n }\n return unwrapped;\n } catch (error) {\n console.error('useTable: Error unwrapping items', error);\n return [];\n }\n });\n \n // State - Pagination\n const currentPage = ref(1);\n const pageSize = ref(options.pageSize ?? 10);\n \n // State - Sorting\n const sortKey = ref(options.sortKey ?? '');\n const sortOrder = ref<'asc' | 'desc'>(options.sortOrder ?? 'asc');\n \n // State - Selection\n const selectedItems = ref<T[]>([]) as Ref<T[]>;\n const selectedItemIds = ref<Set<string | number>>(new Set());\n const resetSelected = ref(false);\n \n // State - Filtering\n const activeFilters = ref<SmartFilter[]>([]);\n \n // State - Column visibility\n const hiddenColumns = ref<number[]>([]);\n\n // Computed - Filtering\n const filteredItems = computed(() => {\n if (activeFilters.value.length === 0) return items.value;\n\n return items.value.filter(item => {\n // All filters must pass (AND logic by default)\n return activeFilters.value.every(filter => {\n const { category, operator, value } = filter;\n \n if (value === undefined || value === null || value === '') return true;\n \n const itemValue = item[category];\n \n // Handle different operators\n switch (operator) {\n case 'contains':\n return String(itemValue).toLowerCase().includes(String(value).toLowerCase());\n case 'is':\n case '=':\n return itemValue === value;\n case '>':\n case 'greater':\n return Number(itemValue) > Number(value);\n case '<':\n case 'less':\n return Number(itemValue) < Number(value);\n case '>=':\n case 'greaterOrEqual':\n return Number(itemValue) >= Number(value);\n case '<=':\n case 'lessOrEqual':\n return Number(itemValue) <= Number(value);\n default:\n return String(itemValue).toLowerCase().includes(String(value).toLowerCase());\n }\n });\n });\n });\n\n // Computed - Sorting\n const sortedItems = computed(() => {\n if (!sortKey.value) return filteredItems.value;\n\n return [...filteredItems.value].sort((a, b) => {\n const aVal = a[sortKey.value];\n const bVal = b[sortKey.value];\n const order = sortOrder.value === 'asc' ? 1 : -1;\n\n if (aVal === bVal) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n // Handle different types\n if (typeof aVal === 'string' && typeof bVal === 'string') {\n return aVal.localeCompare(bVal) * order;\n }\n\n return aVal > bVal ? order : -order;\n });\n });\n\n // Computed - Pagination\n const paginatedItems = computed(() => {\n const start = (currentPage.value - 1) * pageSize.value;\n const end = start + pageSize.value;\n return sortedItems.value.slice(start, end);\n });\n\n const totalPages = computed(() =>\n Math.ceil(sortedItems.value.length / pageSize.value)\n );\n\n const totalItems = computed(() => sortedItems.value.length);\n\n // Computed - Selection\n const allSelected = computed(() => {\n if (items.value.length === 0) return false;\n return selectedItemIds.value.size === items.value.length;\n });\n\n const someSelected = computed(() => {\n return selectedItemIds.value.size > 0 && !allSelected.value;\n });\n\n // Methods - Pagination\n function setPage(page: number) {\n if (page >= 1 && page <= totalPages.value) {\n currentPage.value = page;\n }\n }\n\n function setPageSize(size: number) {\n pageSize.value = size;\n currentPage.value = 1; // Reset to first page\n }\n\n function handlePageChange(page: number) {\n setPage(page);\n }\n\n function handlePageSizeChange(size: number | string) {\n const numSize = typeof size === 'string' ? parseInt(size) : size;\n setPageSize(numSize);\n }\n\n // Methods - Sorting\n function setSorting(key: string, order: 'asc' | 'desc' = 'asc') {\n if (sortKey.value === key) {\n // Toggle order if same key\n sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';\n } else {\n sortKey.value = key;\n sortOrder.value = order;\n }\n }\n\n function handleOrderBy(event: { value: string; orderDirection: 'asc' | 'desc' }) {\n sortKey.value = event.value;\n sortOrder.value = event.orderDirection;\n }\n\n // Methods - Selection\n function getItemId(item: T): string | number {\n return item[idKey];\n }\n\n function selectItem(item: T) {\n const id = getItemId(item);\n if (!selectedItemIds.value.has(id)) {\n selectedItemIds.value.add(id);\n (selectedItems.value as T[]).push(item);\n }\n }\n\n function deselectItem(item: T) {\n const id = getItemId(item);\n if (selectedItemIds.value.has(id)) {\n selectedItemIds.value.delete(id);\n const index = (selectedItems.value as T[]).findIndex(i => getItemId(i) === id);\n if (index !== -1) {\n (selectedItems.value as T[]).splice(index, 1);\n }\n }\n }\n\n function selectAll() {\n selectedItemIds.value.clear();\n (selectedItems.value as T[]).length = 0;\n \n items.value.forEach(item => {\n const id = getItemId(item);\n selectedItemIds.value.add(id);\n (selectedItems.value as T[]).push(item);\n });\n }\n\n function selectAllOnPage() {\n paginatedItems.value.forEach(item => {\n selectItem(item);\n });\n }\n\n function clearSelection() {\n selectedItemIds.value.clear();\n (selectedItems.value as T[]).length = 0;\n resetSelected.value = true;\n setTimeout(() => {\n resetSelected.value = false;\n }, 100);\n }\n\n function isSelected(item: T): boolean {\n const id = getItemId(item);\n return selectedItemIds.value.has(id);\n }\n\n // Methods - Filtering\n function applyFilters(filters: SmartFilter[]) {\n activeFilters.value = filters;\n currentPage.value = 1; // Reset to first page when filters change\n }\n\n function clearFilters() {\n activeFilters.value = [];\n currentPage.value = 1;\n }\n\n function removeFilter(index: number) {\n if (index >= 0 && index < activeFilters.value.length) {\n activeFilters.value.splice(index, 1);\n currentPage.value = 1;\n }\n }\n\n function handleSmartFiltersApplied(filters: SmartFilter[]) {\n applyFilters(filters);\n }\n\n function handleSmartFiltersCleared() {\n clearFilters();\n }\n\n function handleSmartFilterDeleted(index: number) {\n removeFilter(index);\n }\n\n // Methods - Column visibility\n function toggleColumn(index: number) {\n const hiddenIndex = hiddenColumns.value.indexOf(index);\n if (hiddenIndex > -1) {\n hiddenColumns.value.splice(hiddenIndex, 1);\n } else {\n hiddenColumns.value.push(index);\n }\n }\n\n function showColumn(index: number) {\n const hiddenIndex = hiddenColumns.value.indexOf(index);\n if (hiddenIndex > -1) {\n hiddenColumns.value.splice(hiddenIndex, 1);\n }\n }\n\n function hideColumn(index: number) {\n if (!hiddenColumns.value.includes(index)) {\n hiddenColumns.value.push(index);\n }\n }\n\n function handleColumnsVisibilityChanged(event: { index: number; hidden: boolean }) {\n if (event.hidden) {\n hideColumn(event.index);\n } else {\n showColumn(event.index);\n }\n }\n\n // Methods - Modal actions\n function handleModalAction(event: { modal: string; action: string }) {\n if (event.modal === 'selectAllItemsModal' || event.modal.includes('selectAll')) {\n if (event.action === 'selectAll') {\n selectAll();\n } else if (event.action === 'close') {\n selectAllOnPage();\n }\n }\n }\n\n return {\n // Pagination\n currentPage,\n pageSize,\n totalPages,\n totalItems,\n paginatedItems,\n \n // Sorting\n sortKey,\n sortOrder,\n sortedItems,\n \n // Selection\n selectedItems,\n selectedItemIds,\n allSelected,\n someSelected,\n \n // Filtering\n activeFilters,\n filteredItems,\n \n // Column visibility\n hiddenColumns,\n \n // Reset state\n resetSelected,\n \n // Methods - Pagination\n setPage,\n setPageSize,\n handlePageChange,\n handlePageSizeChange,\n \n // Methods - Sorting\n setSorting,\n handleOrderBy,\n \n // Methods - Selection\n selectItem,\n deselectItem,\n selectAll,\n selectAllOnPage,\n clearSelection,\n isSelected,\n \n // Methods - Filtering\n applyFilters,\n clearFilters,\n removeFilter,\n handleSmartFiltersApplied,\n handleSmartFiltersCleared,\n handleSmartFilterDeleted,\n \n // Methods - Column visibility\n toggleColumn,\n showColumn,\n hideColumn,\n handleColumnsVisibilityChanged,\n \n // Methods - Modal actions\n handleModalAction,\n };\n}\n","import { ref, type Ref } from 'vue';\n\nexport interface UseModalOptions {\n initialOpen?: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseModalReturn {\n isOpen: Ref<boolean>;\n open: () => void;\n close: () => void;\n toggle: () => void;\n}\n\nexport function useModal(options: UseModalOptions = {}): UseModalReturn {\n const isOpen = ref(options.initialOpen ?? false);\n\n function open() {\n isOpen.value = true;\n options.onOpen?.();\n }\n\n function close() {\n isOpen.value = false;\n options.onClose?.();\n }\n\n function toggle() {\n if (isOpen.value) {\n close();\n } else {\n open();\n }\n }\n\n return {\n isOpen,\n open,\n close,\n toggle\n };\n}\n","import { ref, computed, type Ref, type ComputedRef } from 'vue';\n\nexport interface Tab {\n id: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface UseTabsOptions {\n tabs: Tab[];\n initialTab?: string;\n onChange?: (tabId: string) => void;\n}\n\nexport interface UseTabsReturn {\n activeTab: Ref<string>;\n tabs: Ref<Tab[]>;\n currentTabIndex: ComputedRef<number>;\n isFirstTab: ComputedRef<boolean>;\n isLastTab: ComputedRef<boolean>;\n setActiveTab: (tabId: string) => void;\n nextTab: () => void;\n previousTab: () => void;\n isTabActive: (tabId: string) => boolean;\n isTabDisabled: (tabId: string) => boolean;\n}\n\nexport function useTabs(options: UseTabsOptions): UseTabsReturn {\n const tabs = ref(options.tabs);\n const activeTab = ref(\n options.initialTab || (tabs.value.length > 0 ? tabs.value[0].id : '')\n );\n\n const currentTabIndex = computed(() =>\n tabs.value.findIndex(tab => tab.id === activeTab.value)\n );\n\n const isFirstTab = computed(() => currentTabIndex.value === 0);\n\n const isLastTab = computed(() =>\n currentTabIndex.value === tabs.value.length - 1\n );\n\n function setActiveTab(tabId: string) {\n const tab = tabs.value.find(t => t.id === tabId);\n if (tab && !tab.disabled) {\n activeTab.value = tabId;\n options.onChange?.(tabId);\n }\n }\n\n function nextTab() {\n if (!isLastTab.value) {\n const nextIndex = currentTabIndex.value + 1;\n const nextTab = tabs.value[nextIndex];\n if (nextTab && !nextTab.disabled) {\n setActiveTab(nextTab.id);\n } else if (nextIndex < tabs.value.length - 1) {\n // Skip disabled tab and try next\n activeTab.value = nextTab.id;\n nextTab();\n }\n }\n }\n\n function previousTab() {\n if (!isFirstTab.value) {\n const prevIndex = currentTabIndex.value - 1;\n const prevTab = tabs.value[prevIndex];\n if (prevTab && !prevTab.disabled) {\n setActiveTab(prevTab.id);\n } else if (prevIndex > 0) {\n // Skip disabled tab and try previous\n activeTab.value = prevTab.id;\n previousTab();\n }\n }\n }\n\n function isTabActive(tabId: string): boolean {\n return activeTab.value === tabId;\n }\n\n function isTabDisabled(tabId: string): boolean {\n const tab = tabs.value.find(t => t.id === tabId);\n return tab?.disabled ?? false;\n }\n\n return {\n activeTab,\n tabs,\n currentTabIndex,\n isFirstTab,\n isLastTab,\n setActiveTab,\n nextTab,\n previousTab,\n isTabActive,\n isTabDisabled\n };\n}\n","import { ref, computed, type Ref, type ComputedRef } from 'vue';\n\nexport interface ValidationRule<T = any> {\n validate: (value: T) => boolean | Promise<boolean>;\n message: string;\n}\n\nexport interface FieldConfig {\n rules?: ValidationRule[];\n initialValue?: any;\n}\n\nexport interface UseFormOptions<T extends Record<string, any>> {\n initialValues: T;\n validationRules?: Partial<Record<keyof T, ValidationRule[]>>;\n onSubmit?: (values: T) => void | Promise<void>;\n}\n\nexport interface UseFormReturn<T extends Record<string, any>> {\n values: Ref<T>;\n errors: Ref<Partial<Record<keyof T, string>>>;\n touched: Ref<Partial<Record<keyof T, boolean>>>;\n isSubmitting: Ref<boolean>;\n isValid: ComputedRef<boolean>;\n setFieldValue: (field: keyof T, value: any) => void;\n setFieldError: (field: keyof T, error: string) => void;\n setFieldTouched: (field: keyof T, touched: boolean) => void;\n validateField: (field: keyof T) => Promise<boolean>;\n validateForm: () => Promise<boolean>;\n handleSubmit: (event?: Event) => Promise<void>;\n resetForm: () => void;\n}\n\nexport function useForm<T extends Record<string, any>>(\n options: UseFormOptions<T>\n): UseFormReturn<T> {\n const values = ref<T>({ ...options.initialValues }) as Ref<T>;\n const errors = ref<Partial<Record<keyof T, string>>>({});\n const touched = ref<Partial<Record<keyof T, boolean>>>({});\n const isSubmitting = ref(false);\n\n const isValid = computed(() => Object.keys(errors.value).length === 0);\n\n function setFieldValue(field: keyof T, value: any) {\n values.value[field] = value;\n }\n\n function setFieldError(field: keyof T, error: string) {\n errors.value[field] = error;\n }\n\n function setFieldTouched(field: keyof T, isTouched: boolean) {\n touched.value[field] = isTouched;\n }\n\n async function validateField(field: keyof T): Promise<boolean> {\n const rules = options.validationRules?.[field];\n if (!rules || rules.length === 0) return true;\n\n const value = values.value[field];\n\n for (const rule of rules) {\n const isValid = await rule.validate(value);\n if (!isValid) {\n setFieldError(field, rule.message);\n return false;\n }\n }\n\n // Clear error if validation passed\n delete errors.value[field];\n return true;\n }\n\n async function validateForm(): Promise<boolean> {\n const fields = Object.keys(values.value) as Array<keyof T>;\n const validationResults = await Promise.all(\n fields.map(field => validateField(field))\n );\n\n return validationResults.every(result => result);\n }\n\n async function handleSubmit(event?: Event) {\n if (event) {\n event.preventDefault();\n }\n\n if (isSubmitting.value) return;\n\n // Mark all fields as touched\n for (const field of Object.keys(values.value) as Array<keyof T>) {\n setFieldTouched(field, true);\n }\n\n // Validate form\n const isFormValid = await validateForm();\n if (!isFormValid) return;\n\n // Submit form\n isSubmitting.value = true;\n try {\n await options.onSubmit?.(values.value);\n } finally {\n isSubmitting.value = false;\n }\n }\n\n function resetForm() {\n values.value = { ...options.initialValues };\n errors.value = {};\n touched.value = {};\n isSubmitting.value = false;\n }\n\n return {\n values,\n errors,\n touched,\n isSubmitting,\n isValid,\n setFieldValue,\n setFieldError,\n setFieldTouched,\n validateField,\n validateForm,\n handleSubmit,\n resetForm\n };\n}\n","import type { ValidationRule } from './useForm';\n\n// Common validation rules\nexport const required = (message = 'This field is required'): ValidationRule => ({\n validate: (value: any) => {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n return true;\n },\n message\n});\n\nexport const minLength = (min: number, message?: string): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true; // Let required handle empty values\n return value.length >= min;\n },\n message: message || `Must be at least ${min} characters`\n});\n\nexport const maxLength = (max: number, message?: string): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n return value.length <= max;\n },\n message: message || `Must be at most ${max} characters`\n});\n\nexport const email = (message = 'Invalid email address'): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(value);\n },\n message\n});\n\nexport const pattern = (regex: RegExp, message = 'Invalid format'): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n return regex.test(value);\n },\n message\n});\n\nexport const min = (minValue: number, message?: string): ValidationRule => ({\n validate: (value: number) => {\n if (value === null || value === undefined) return true;\n return value >= minValue;\n },\n message: message || `Must be at least ${minValue}`\n});\n\nexport const max = (maxValue: number, message?: string): ValidationRule => ({\n validate: (value: number) => {\n if (value === null || value === undefined) return true;\n return value <= maxValue;\n },\n message: message || `Must be at most ${maxValue}`\n});\n\nexport const custom = (\n validator: (value: any) => boolean | Promise<boolean>,\n message: string\n): ValidationRule => ({\n validate: validator,\n message\n});\n\n// Composable for form validation\nexport function useFormValidation() {\n return {\n required,\n minLength,\n maxLength,\n email,\n pattern,\n min,\n max,\n custom\n };\n}\n","import { ref, type Ref } from 'vue';\n\nexport interface Notification {\n id: string;\n message: string;\n type: 'info' | 'success' | 'warning' | 'error';\n duration?: number;\n}\n\nexport interface UseNotificationsReturn {\n notifications: Ref<Notification[]>;\n addNotification: (notification: Omit<Notification, 'id'>) => string;\n removeNotification: (id: string) => void;\n clearAll: () => void;\n info: (message: string, duration?: number) => string;\n success: (message: string, duration?: number) => string;\n warning: (message: string, duration?: number) => string;\n error: (message: string, duration?: number) => string;\n}\n\n// Global notifications state\nconst notifications = ref<Notification[]>([]);\n\nexport function useNotifications(): UseNotificationsReturn {\n function addNotification(notification: Omit<Notification, 'id'>): string {\n const id = `notification-${Date.now()}-${Math.random()}`;\n const newNotification: Notification = {\n ...notification,\n id\n };\n\n notifications.value.push(newNotification);\n\n // Auto-remove after duration\n if (notification.duration) {\n setTimeout(() => {\n removeNotification(id);\n }, notification.duration);\n }\n\n return id;\n }\n\n function removeNotification(id: string) {\n const index = notifications.value.findIndex(n => n.id === id);\n if (index !== -1) {\n notifications.value.splice(index, 1);\n }\n }\n\n function clearAll() {\n notifications.value = [];\n }\n\n function info(message: string, duration = 3000): string {\n return addNotification({ message, type: 'info', duration });\n }\n\n function success(message: string, duration = 3000): string {\n return addNotification({ message, type: 'success', duration });\n }\n\n function warning(message: string, duration = 3000): string {\n return addNotification({ message, type: 'warning', duration });\n }\n\n function error(message: string, duration = 5000): string {\n return addNotification({ message, type: 'error', duration });\n }\n\n return {\n notifications,\n addNotification,\n removeNotification,\n clearAll,\n info,\n success,\n warning,\n error\n };\n}\n"],"mappings":"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","names":["ref","ref","computed","nextTab","ref","computed","isValid","min","max","ref"]}
|
|
1
|
+
{"version":3,"sources":["../../src/composables/useTable.ts","../../src/composables/useModal.ts","../../src/composables/useTabs.ts","../../src/composables/useForm.ts","../../src/composables/useFormValidation.ts","../../src/composables/useNotifications.ts","../../src/composables/usePageContext.ts","../../../../node_modules/.pnpm/@nanostores+vue@1.0.1_@nanostores+logger@1.0.0_nanostores@1.1.0__nanostores@1.1.0_vue@3.5.25_typescript@5.9.3_/node_modules/@nanostores/vue/use-store/index.js","../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js","../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js"],"sourcesContent":["import { ref, computed, unref, type Ref, type ComputedRef, type MaybeRef } from 'vue';\n\nexport interface SmartFilter {\n category: string;\n operator: string;\n value: any;\n}\n\nexport interface UseTableOptions<T> {\n items: MaybeRef<T[]>; // Accept both arrays and refs/computed\n pageSize?: number;\n sortKey?: string;\n sortOrder?: 'asc' | 'desc';\n idKey?: string; // Key to use for item identification (default: 'id')\n}\n\nexport interface UseTableReturn<T> {\n // Pagination\n currentPage: Ref<number>;\n pageSize: Ref<number>;\n totalPages: ComputedRef<number>;\n totalItems: ComputedRef<number>;\n paginatedItems: ComputedRef<T[]>;\n \n // Sorting\n sortKey: Ref<string>;\n sortOrder: Ref<'asc' | 'desc'>;\n sortedItems: ComputedRef<T[]>;\n \n // Selection\n selectedItems: Ref<T[]>;\n selectedItemIds: Ref<Set<string | number>>;\n allSelected: ComputedRef<boolean>;\n someSelected: ComputedRef<boolean>;\n \n // Filtering\n activeFilters: Ref<SmartFilter[]>;\n filteredItems: ComputedRef<T[]>;\n \n // Column visibility\n hiddenColumns: Ref<number[]>;\n \n // Reset state\n resetSelected: Ref<boolean>;\n \n // Methods - Pagination\n setPage: (page: number) => void;\n setPageSize: (size: number) => void;\n \n // Methods - Sorting\n setSorting: (key: string, order?: 'asc' | 'desc') => void;\n handleOrderBy: (event: { value: string; orderDirection: 'asc' | 'desc' }) => void;\n \n // Methods - Selection\n selectItem: (item: T) => void;\n deselectItem: (item: T) => void;\n selectAll: () => void;\n selectAllOnPage: () => void;\n clearSelection: () => void;\n isSelected: (item: T) => boolean;\n \n // Methods - Filtering\n applyFilters: (filters: SmartFilter[]) => void;\n clearFilters: () => void;\n removeFilter: (index: number) => void;\n \n // Methods - Column visibility\n toggleColumn: (index: number) => void;\n showColumn: (index: number) => void;\n hideColumn: (index: number) => void;\n \n // Event handlers for uiTable\n handlePageChange: (page: number) => void;\n handlePageSizeChange: (size: number | string) => void;\n handleSmartFiltersApplied: (filters: SmartFilter[]) => void;\n handleSmartFiltersCleared: () => void;\n handleSmartFilterDeleted: (index: number) => void;\n handleColumnsVisibilityChanged: (event: { index: number; hidden: boolean }) => void;\n handleModalAction: (event: { modal: string; action: string }) => void;\n}\n\nexport function useTable<T extends Record<string, any>>(\n options: UseTableOptions<T>\n): UseTableReturn<T> {\n const idKey = options.idKey ?? 'id';\n \n // Create a reactive reference to items with safety check\n const items = computed(() => {\n try {\n const unwrapped = unref(options.items);\n // Ensure we always return an array\n if (!unwrapped) return [];\n if (!Array.isArray(unwrapped)) {\n console.warn('useTable: items is not an array', unwrapped);\n return [];\n }\n return unwrapped;\n } catch (error) {\n console.error('useTable: Error unwrapping items', error);\n return [];\n }\n });\n \n // State - Pagination\n const currentPage = ref(1);\n const pageSize = ref(options.pageSize ?? 10);\n \n // State - Sorting\n const sortKey = ref(options.sortKey ?? '');\n const sortOrder = ref<'asc' | 'desc'>(options.sortOrder ?? 'asc');\n \n // State - Selection\n const selectedItems = ref<T[]>([]) as Ref<T[]>;\n const selectedItemIds = ref<Set<string | number>>(new Set());\n const resetSelected = ref(false);\n \n // State - Filtering\n const activeFilters = ref<SmartFilter[]>([]);\n \n // State - Column visibility\n const hiddenColumns = ref<number[]>([]);\n\n // Computed - Filtering\n const filteredItems = computed(() => {\n // Ensure activeFilters is always an array\n const filters = Array.isArray(activeFilters.value) ? activeFilters.value : [];\n if (filters.length === 0) return items.value;\n\n return items.value.filter(item => {\n // All filters must pass (AND logic by default)\n return filters.every(filter => {\n const { category, operator, value } = filter;\n \n if (value === undefined || value === null || value === '') return true;\n \n const itemValue = item[category];\n \n // Handle different operators\n switch (operator) {\n case 'contains':\n return String(itemValue).toLowerCase().includes(String(value).toLowerCase());\n case 'is':\n case '=':\n return itemValue === value;\n case '>':\n case 'greater':\n return Number(itemValue) > Number(value);\n case '<':\n case 'less':\n return Number(itemValue) < Number(value);\n case '>=':\n case 'greaterOrEqual':\n return Number(itemValue) >= Number(value);\n case '<=':\n case 'lessOrEqual':\n return Number(itemValue) <= Number(value);\n default:\n return String(itemValue).toLowerCase().includes(String(value).toLowerCase());\n }\n });\n });\n });\n\n // Computed - Sorting\n const sortedItems = computed(() => {\n if (!sortKey.value) return filteredItems.value;\n\n return [...filteredItems.value].sort((a, b) => {\n const aVal = a[sortKey.value];\n const bVal = b[sortKey.value];\n const order = sortOrder.value === 'asc' ? 1 : -1;\n\n if (aVal === bVal) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n // Handle different types\n if (typeof aVal === 'string' && typeof bVal === 'string') {\n return aVal.localeCompare(bVal) * order;\n }\n\n return aVal > bVal ? order : -order;\n });\n });\n\n // Computed - Pagination\n const paginatedItems = computed(() => {\n const start = (currentPage.value - 1) * pageSize.value;\n const end = start + pageSize.value;\n return sortedItems.value.slice(start, end);\n });\n\n const totalPages = computed(() =>\n Math.ceil(sortedItems.value.length / pageSize.value)\n );\n\n const totalItems = computed(() => sortedItems.value.length);\n\n // Computed - Selection\n const allSelected = computed(() => {\n if (items.value.length === 0) return false;\n return selectedItemIds.value.size === items.value.length;\n });\n\n const someSelected = computed(() => {\n return selectedItemIds.value.size > 0 && !allSelected.value;\n });\n\n // Methods - Pagination\n function setPage(page: number) {\n if (page >= 1 && page <= totalPages.value) {\n currentPage.value = page;\n }\n }\n\n function setPageSize(size: number) {\n pageSize.value = size;\n currentPage.value = 1; // Reset to first page\n }\n\n function handlePageChange(page: number) {\n setPage(page);\n }\n\n function handlePageSizeChange(size: number | string) {\n const numSize = typeof size === 'string' ? parseInt(size) : size;\n setPageSize(numSize);\n }\n\n // Methods - Sorting\n function setSorting(key: string, order: 'asc' | 'desc' = 'asc') {\n if (sortKey.value === key) {\n // Toggle order if same key\n sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';\n } else {\n sortKey.value = key;\n sortOrder.value = order;\n }\n }\n\n function handleOrderBy(event: { value: string; orderDirection: 'asc' | 'desc' }) {\n sortKey.value = event.value;\n sortOrder.value = event.orderDirection;\n }\n\n // Methods - Selection\n function getItemId(item: T): string | number {\n return item[idKey];\n }\n\n function selectItem(item: T) {\n const id = getItemId(item);\n if (!selectedItemIds.value.has(id)) {\n selectedItemIds.value.add(id);\n (selectedItems.value as T[]).push(item);\n }\n }\n\n function deselectItem(item: T) {\n const id = getItemId(item);\n if (selectedItemIds.value.has(id)) {\n selectedItemIds.value.delete(id);\n const index = (selectedItems.value as T[]).findIndex(i => getItemId(i) === id);\n if (index !== -1) {\n (selectedItems.value as T[]).splice(index, 1);\n }\n }\n }\n\n function selectAll() {\n selectedItemIds.value.clear();\n (selectedItems.value as T[]).length = 0;\n \n items.value.forEach(item => {\n const id = getItemId(item);\n selectedItemIds.value.add(id);\n (selectedItems.value as T[]).push(item);\n });\n }\n\n function selectAllOnPage() {\n paginatedItems.value.forEach(item => {\n selectItem(item);\n });\n }\n\n function clearSelection() {\n selectedItemIds.value.clear();\n (selectedItems.value as T[]).length = 0;\n resetSelected.value = true;\n setTimeout(() => {\n resetSelected.value = false;\n }, 100);\n }\n\n function isSelected(item: T): boolean {\n const id = getItemId(item);\n return selectedItemIds.value.has(id);\n }\n\n // Methods - Filtering\n function applyFilters(filters: SmartFilter[] | Record<string, any>) {\n // Handle various filter formats from UI components\n if (Array.isArray(filters)) {\n activeFilters.value = filters;\n } else if (filters && typeof filters === 'object') {\n // Handle object format like { filters: [...] } or extract values\n if ('filters' in filters && Array.isArray(filters.filters)) {\n activeFilters.value = filters.filters;\n } else {\n // Convert object to SmartFilter array\n activeFilters.value = Object.entries(filters)\n .filter(([_, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => ({\n category: key,\n operator: 'contains',\n value,\n }));\n }\n } else {\n activeFilters.value = [];\n }\n currentPage.value = 1; // Reset to first page when filters change\n }\n\n function clearFilters() {\n activeFilters.value = [];\n currentPage.value = 1;\n }\n\n function removeFilter(index: number) {\n if (index >= 0 && index < activeFilters.value.length) {\n activeFilters.value.splice(index, 1);\n currentPage.value = 1;\n }\n }\n\n function handleSmartFiltersApplied(filters: SmartFilter[] | Record<string, any>) {\n applyFilters(filters);\n }\n\n function handleSmartFiltersCleared() {\n clearFilters();\n }\n\n function handleSmartFilterDeleted(index: number) {\n removeFilter(index);\n }\n\n // Methods - Column visibility\n function toggleColumn(index: number) {\n const hiddenIndex = hiddenColumns.value.indexOf(index);\n if (hiddenIndex > -1) {\n hiddenColumns.value.splice(hiddenIndex, 1);\n } else {\n hiddenColumns.value.push(index);\n }\n }\n\n function showColumn(index: number) {\n const hiddenIndex = hiddenColumns.value.indexOf(index);\n if (hiddenIndex > -1) {\n hiddenColumns.value.splice(hiddenIndex, 1);\n }\n }\n\n function hideColumn(index: number) {\n if (!hiddenColumns.value.includes(index)) {\n hiddenColumns.value.push(index);\n }\n }\n\n function handleColumnsVisibilityChanged(event: { index: number; hidden: boolean }) {\n if (event.hidden) {\n hideColumn(event.index);\n } else {\n showColumn(event.index);\n }\n }\n\n // Methods - Modal actions\n function handleModalAction(event: { modal: string; action: string }) {\n if (event.modal === 'selectAllItemsModal' || event.modal.includes('selectAll')) {\n if (event.action === 'selectAll') {\n selectAll();\n } else if (event.action === 'close') {\n selectAllOnPage();\n }\n }\n }\n\n return {\n // Pagination\n currentPage,\n pageSize,\n totalPages,\n totalItems,\n paginatedItems,\n \n // Sorting\n sortKey,\n sortOrder,\n sortedItems,\n \n // Selection\n selectedItems,\n selectedItemIds,\n allSelected,\n someSelected,\n \n // Filtering\n activeFilters,\n filteredItems,\n \n // Column visibility\n hiddenColumns,\n \n // Reset state\n resetSelected,\n \n // Methods - Pagination\n setPage,\n setPageSize,\n handlePageChange,\n handlePageSizeChange,\n \n // Methods - Sorting\n setSorting,\n handleOrderBy,\n \n // Methods - Selection\n selectItem,\n deselectItem,\n selectAll,\n selectAllOnPage,\n clearSelection,\n isSelected,\n \n // Methods - Filtering\n applyFilters,\n clearFilters,\n removeFilter,\n handleSmartFiltersApplied,\n handleSmartFiltersCleared,\n handleSmartFilterDeleted,\n \n // Methods - Column visibility\n toggleColumn,\n showColumn,\n hideColumn,\n handleColumnsVisibilityChanged,\n \n // Methods - Modal actions\n handleModalAction,\n };\n}\n","import { ref, type Ref } from 'vue';\n\nexport interface UseModalOptions {\n initialOpen?: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseModalReturn {\n isOpen: Ref<boolean>;\n open: () => void;\n close: () => void;\n toggle: () => void;\n}\n\nexport function useModal(options: UseModalOptions = {}): UseModalReturn {\n const isOpen = ref(options.initialOpen ?? false);\n\n function open() {\n isOpen.value = true;\n options.onOpen?.();\n }\n\n function close() {\n isOpen.value = false;\n options.onClose?.();\n }\n\n function toggle() {\n if (isOpen.value) {\n close();\n } else {\n open();\n }\n }\n\n return {\n isOpen,\n open,\n close,\n toggle\n };\n}\n","import { ref, computed, type Ref, type ComputedRef } from 'vue';\n\nexport interface Tab {\n id: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface UseTabsOptions {\n tabs: Tab[];\n initialTab?: string;\n onChange?: (tabId: string) => void;\n}\n\nexport interface UseTabsReturn {\n activeTab: Ref<string>;\n tabs: Ref<Tab[]>;\n currentTabIndex: ComputedRef<number>;\n isFirstTab: ComputedRef<boolean>;\n isLastTab: ComputedRef<boolean>;\n setActiveTab: (tabId: string) => void;\n nextTab: () => void;\n previousTab: () => void;\n isTabActive: (tabId: string) => boolean;\n isTabDisabled: (tabId: string) => boolean;\n}\n\nexport function useTabs(options: UseTabsOptions): UseTabsReturn {\n const tabs = ref(options.tabs);\n const activeTab = ref(\n options.initialTab || (tabs.value.length > 0 ? tabs.value[0].id : '')\n );\n\n const currentTabIndex = computed(() =>\n tabs.value.findIndex(tab => tab.id === activeTab.value)\n );\n\n const isFirstTab = computed(() => currentTabIndex.value === 0);\n\n const isLastTab = computed(() =>\n currentTabIndex.value === tabs.value.length - 1\n );\n\n function setActiveTab(tabId: string) {\n const tab = tabs.value.find(t => t.id === tabId);\n if (tab && !tab.disabled) {\n activeTab.value = tabId;\n options.onChange?.(tabId);\n }\n }\n\n function nextTab() {\n if (!isLastTab.value) {\n const nextIndex = currentTabIndex.value + 1;\n const nextTab = tabs.value[nextIndex];\n if (nextTab && !nextTab.disabled) {\n setActiveTab(nextTab.id);\n } else if (nextIndex < tabs.value.length - 1) {\n // Skip disabled tab and try next\n activeTab.value = nextTab.id;\n nextTab();\n }\n }\n }\n\n function previousTab() {\n if (!isFirstTab.value) {\n const prevIndex = currentTabIndex.value - 1;\n const prevTab = tabs.value[prevIndex];\n if (prevTab && !prevTab.disabled) {\n setActiveTab(prevTab.id);\n } else if (prevIndex > 0) {\n // Skip disabled tab and try previous\n activeTab.value = prevTab.id;\n previousTab();\n }\n }\n }\n\n function isTabActive(tabId: string): boolean {\n return activeTab.value === tabId;\n }\n\n function isTabDisabled(tabId: string): boolean {\n const tab = tabs.value.find(t => t.id === tabId);\n return tab?.disabled ?? false;\n }\n\n return {\n activeTab,\n tabs,\n currentTabIndex,\n isFirstTab,\n isLastTab,\n setActiveTab,\n nextTab,\n previousTab,\n isTabActive,\n isTabDisabled\n };\n}\n","import { ref, computed, type Ref, type ComputedRef } from 'vue';\n\nexport interface ValidationRule<T = any> {\n validate: (value: T) => boolean | Promise<boolean>;\n message: string;\n}\n\nexport interface FieldConfig {\n rules?: ValidationRule[];\n initialValue?: any;\n}\n\nexport interface UseFormOptions<T extends Record<string, any>> {\n initialValues: T;\n validationRules?: Partial<Record<keyof T, ValidationRule[]>>;\n onSubmit?: (values: T) => void | Promise<void>;\n}\n\nexport interface UseFormReturn<T extends Record<string, any>> {\n values: Ref<T>;\n errors: Ref<Partial<Record<keyof T, string>>>;\n touched: Ref<Partial<Record<keyof T, boolean>>>;\n isSubmitting: Ref<boolean>;\n isValid: ComputedRef<boolean>;\n setFieldValue: (field: keyof T, value: any) => void;\n setFieldError: (field: keyof T, error: string) => void;\n setFieldTouched: (field: keyof T, touched: boolean) => void;\n validateField: (field: keyof T) => Promise<boolean>;\n validateForm: () => Promise<boolean>;\n handleSubmit: (event?: Event) => Promise<void>;\n resetForm: () => void;\n}\n\nexport function useForm<T extends Record<string, any>>(\n options: UseFormOptions<T>\n): UseFormReturn<T> {\n const values = ref<T>({ ...options.initialValues }) as Ref<T>;\n const errors = ref<Partial<Record<keyof T, string>>>({});\n const touched = ref<Partial<Record<keyof T, boolean>>>({});\n const isSubmitting = ref(false);\n\n const isValid = computed(() => Object.keys(errors.value).length === 0);\n\n function setFieldValue(field: keyof T, value: any) {\n values.value[field] = value;\n }\n\n function setFieldError(field: keyof T, error: string) {\n errors.value[field] = error;\n }\n\n function setFieldTouched(field: keyof T, isTouched: boolean) {\n touched.value[field] = isTouched;\n }\n\n async function validateField(field: keyof T): Promise<boolean> {\n const rules = options.validationRules?.[field];\n if (!rules || rules.length === 0) return true;\n\n const value = values.value[field];\n\n for (const rule of rules) {\n const isValid = await rule.validate(value);\n if (!isValid) {\n setFieldError(field, rule.message);\n return false;\n }\n }\n\n // Clear error if validation passed\n delete errors.value[field];\n return true;\n }\n\n async function validateForm(): Promise<boolean> {\n const fields = Object.keys(values.value) as Array<keyof T>;\n const validationResults = await Promise.all(\n fields.map(field => validateField(field))\n );\n\n return validationResults.every(result => result);\n }\n\n async function handleSubmit(event?: Event) {\n if (event) {\n event.preventDefault();\n }\n\n if (isSubmitting.value) return;\n\n // Mark all fields as touched\n for (const field of Object.keys(values.value) as Array<keyof T>) {\n setFieldTouched(field, true);\n }\n\n // Validate form\n const isFormValid = await validateForm();\n if (!isFormValid) return;\n\n // Submit form\n isSubmitting.value = true;\n try {\n await options.onSubmit?.(values.value);\n } finally {\n isSubmitting.value = false;\n }\n }\n\n function resetForm() {\n values.value = { ...options.initialValues };\n errors.value = {};\n touched.value = {};\n isSubmitting.value = false;\n }\n\n return {\n values,\n errors,\n touched,\n isSubmitting,\n isValid,\n setFieldValue,\n setFieldError,\n setFieldTouched,\n validateField,\n validateForm,\n handleSubmit,\n resetForm\n };\n}\n","import type { ValidationRule } from './useForm';\n\n// Common validation rules\nexport const required = (message = 'This field is required'): ValidationRule => ({\n validate: (value: any) => {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n return true;\n },\n message\n});\n\nexport const minLength = (min: number, message?: string): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true; // Let required handle empty values\n return value.length >= min;\n },\n message: message || `Must be at least ${min} characters`\n});\n\nexport const maxLength = (max: number, message?: string): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n return value.length <= max;\n },\n message: message || `Must be at most ${max} characters`\n});\n\nexport const email = (message = 'Invalid email address'): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(value);\n },\n message\n});\n\nexport const pattern = (regex: RegExp, message = 'Invalid format'): ValidationRule => ({\n validate: (value: string) => {\n if (!value) return true;\n return regex.test(value);\n },\n message\n});\n\nexport const min = (minValue: number, message?: string): ValidationRule => ({\n validate: (value: number) => {\n if (value === null || value === undefined) return true;\n return value >= minValue;\n },\n message: message || `Must be at least ${minValue}`\n});\n\nexport const max = (maxValue: number, message?: string): ValidationRule => ({\n validate: (value: number) => {\n if (value === null || value === undefined) return true;\n return value <= maxValue;\n },\n message: message || `Must be at most ${maxValue}`\n});\n\nexport const custom = (\n validator: (value: any) => boolean | Promise<boolean>,\n message: string\n): ValidationRule => ({\n validate: validator,\n message\n});\n\n// Composable for form validation\nexport function useFormValidation() {\n return {\n required,\n minLength,\n maxLength,\n email,\n pattern,\n min,\n max,\n custom\n };\n}\n","import { ref, type Ref } from 'vue';\n\nexport interface Notification {\n id: string;\n message: string;\n type: 'info' | 'success' | 'warning' | 'error';\n duration?: number;\n}\n\nexport interface UseNotificationsReturn {\n notifications: Ref<Notification[]>;\n addNotification: (notification: Omit<Notification, 'id'>) => string;\n removeNotification: (id: string) => void;\n clearAll: () => void;\n info: (message: string, duration?: number) => string;\n success: (message: string, duration?: number) => string;\n warning: (message: string, duration?: number) => string;\n error: (message: string, duration?: number) => string;\n}\n\n// Global notifications state\nconst notifications = ref<Notification[]>([]);\n\nexport function useNotifications(): UseNotificationsReturn {\n function addNotification(notification: Omit<Notification, 'id'>): string {\n const id = `notification-${Date.now()}-${Math.random()}`;\n const newNotification: Notification = {\n ...notification,\n id\n };\n\n notifications.value.push(newNotification);\n\n // Auto-remove after duration\n if (notification.duration) {\n setTimeout(() => {\n removeNotification(id);\n }, notification.duration);\n }\n\n return id;\n }\n\n function removeNotification(id: string) {\n const index = notifications.value.findIndex(n => n.id === id);\n if (index !== -1) {\n notifications.value.splice(index, 1);\n }\n }\n\n function clearAll() {\n notifications.value = [];\n }\n\n function info(message: string, duration = 3000): string {\n return addNotification({ message, type: 'info', duration });\n }\n\n function success(message: string, duration = 3000): string {\n return addNotification({ message, type: 'success', duration });\n }\n\n function warning(message: string, duration = 3000): string {\n return addNotification({ message, type: 'warning', duration });\n }\n\n function error(message: string, duration = 5000): string {\n return addNotification({ message, type: 'error', duration });\n }\n\n return {\n notifications,\n addNotification,\n removeNotification,\n clearAll,\n info,\n success,\n warning,\n error\n };\n}\n","/**\n * Page Context Composable\n *\n * Provides access to common page context data (user, brand, routes)\n * within Vue components, without prop drilling.\n */\n\nimport { computed, inject, type InjectionKey, type ComputedRef } from \"vue\";\nimport { useStore } from \"@nanostores/vue\";\nimport { atom } from \"nanostores\";\nimport { routes, type Routes } from \"@htlkg/core\";\n\n/**\n * User information from authentication\n */\nexport interface PageUser {\n\tusername: string;\n\temail?: string;\n\tisAdmin: boolean;\n\tisSuperAdmin: boolean;\n\tbrandIds?: number[];\n\taccountIds?: number[];\n\troles?: string[];\n}\n\n/**\n * Brand context for brand-scoped pages\n */\nexport interface PageBrand {\n\tid: number;\n\tname: string;\n\tlogo?: string;\n}\n\n/**\n * Full page context\n */\nexport interface PageContext {\n\tuser: PageUser | null;\n\tbrand?: PageBrand;\n\tbrandId?: number;\n\tisAdmin: boolean;\n\tisSuperAdmin: boolean;\n\troutes: Routes;\n}\n\n/**\n * Injection key for providing page context\n */\nexport const PAGE_CONTEXT_KEY: InjectionKey<PageContext> = Symbol(\"pageContext\");\n\n/**\n * Nanostore for user state (set by AdminLayout)\n */\nexport const $user = atom<PageUser | null>(null);\n\n/**\n * Nanostore for current brand (set by BrandLayout)\n */\nexport const $currentBrand = atom<PageBrand | null>(null);\n\n/**\n * Set user in the store (called from layout)\n */\nexport function setUser(user: PageUser | null): void {\n\t$user.set(user);\n}\n\n/**\n * Set current brand in the store (called from layout)\n */\nexport function setCurrentBrand(brand: PageBrand | null): void {\n\t$currentBrand.set(brand);\n}\n\n/**\n * Get page context within a Vue component\n *\n * This composable provides access to:\n * - Current user information\n * - Current brand (if in brand context)\n * - Admin/superadmin status\n * - Type-safe routes\n *\n * @example\n * ```vue\n * <script setup>\n * import { usePageContext } from '@htlkg/components';\n *\n * const { user, isAdmin, routes } = usePageContext();\n *\n * function goToAccounts() {\n * window.location.href = routes.admin.accounts();\n * }\n * </script>\n * ```\n *\n * @example With provider pattern\n * ```vue\n * // In parent component\n * import { provide, PAGE_CONTEXT_KEY } from '@htlkg/components';\n * provide(PAGE_CONTEXT_KEY, { user, brand, isAdmin: true, routes });\n *\n * // In child component\n * const context = usePageContext();\n * ```\n */\nexport function usePageContext(): ComputedRef<PageContext> {\n\t// Try injection first (from provider)\n\tconst injected = inject(PAGE_CONTEXT_KEY, null);\n\tif (injected) {\n\t\treturn computed(() => injected);\n\t}\n\n\t// Fallback to nanostores\n\tconst user = useStore($user);\n\tconst brand = useStore($currentBrand);\n\n\treturn computed(() => ({\n\t\tuser: user.value,\n\t\tbrand: brand.value ?? undefined,\n\t\tbrandId: brand.value?.id,\n\t\tisAdmin: user.value?.isAdmin ?? false,\n\t\tisSuperAdmin: user.value?.isSuperAdmin ?? false,\n\t\troutes,\n\t}));\n}\n\n/**\n * Check if user has access to a specific brand\n */\nexport function useHasAccessToBrand(brandId: number): ComputedRef<boolean> {\n\tconst context = usePageContext();\n\n\treturn computed(() => {\n\t\tconst user = context.value.user;\n\t\tif (!user) return false;\n\t\tif (user.isAdmin || user.isSuperAdmin) return true;\n\t\treturn user.brandIds?.includes(brandId) ?? false;\n\t});\n}\n\n/**\n * Check if user has access to a specific account\n */\nexport function useHasAccessToAccount(accountId: number): ComputedRef<boolean> {\n\tconst context = usePageContext();\n\n\treturn computed(() => {\n\t\tconst user = context.value.user;\n\t\tif (!user) return false;\n\t\tif (user.isAdmin || user.isSuperAdmin) return true;\n\t\treturn user.accountIds?.includes(accountId) ?? false;\n\t});\n}\n\n/**\n * Get user roles\n */\nexport function useUserRoles(): ComputedRef<string[]> {\n\tconst context = usePageContext();\n\treturn computed(() => context.value.user?.roles ?? []);\n}\n\n/**\n * Check if user has a specific role\n */\nexport function useHasRole(role: string): ComputedRef<boolean> {\n\tconst roles = useUserRoles();\n\treturn computed(() => roles.value.includes(role));\n}\n","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","import { cleanTasks } from '../task/index.js'\n\nexport let clean = Symbol('clean')\n\nexport let cleanStores = (...stores) => {\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'cleanStores() can be used only during development or tests'\n )\n }\n cleanTasks()\n for (let $store of stores) {\n if ($store) {\n if ($store.mocked) delete $store.mocked\n if ($store[clean]) $store[clean]()\n }\n }\n}\n","import { clean } from '../clean-stores/index.js'\n\nlet listenerQueue = []\nlet lqIndex = 0\nconst QUEUE_ITEMS_PER_LISTENER = 4\nexport let epoch = 0\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const atom = initialValue => {\n let listeners = []\n let $atom = {\n get() {\n if (!$atom.lc) {\n $atom.listen(() => {})()\n }\n return $atom.value\n },\n lc: 0,\n listen(listener) {\n $atom.lc = listeners.push(listener)\n\n return () => {\n for (\n let i = lqIndex + QUEUE_ITEMS_PER_LISTENER;\n i < listenerQueue.length;\n\n ) {\n if (listenerQueue[i] === listener) {\n listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER)\n } else {\n i += QUEUE_ITEMS_PER_LISTENER\n }\n }\n\n let index = listeners.indexOf(listener)\n if (~index) {\n listeners.splice(index, 1)\n if (!--$atom.lc) $atom.off()\n }\n }\n },\n notify(oldValue, changedKey) {\n epoch++\n let runListenerQueue = !listenerQueue.length\n for (let listener of listeners) {\n listenerQueue.push(listener, $atom.value, oldValue, changedKey)\n }\n\n if (runListenerQueue) {\n for (\n lqIndex = 0;\n lqIndex < listenerQueue.length;\n lqIndex += QUEUE_ITEMS_PER_LISTENER\n ) {\n listenerQueue[lqIndex](\n listenerQueue[lqIndex + 1],\n listenerQueue[lqIndex + 2],\n listenerQueue[lqIndex + 3]\n )\n }\n listenerQueue.length = 0\n }\n },\n /* It will be called on last listener unsubscribing.\n We will redefine it in onMount and onStop. */\n off() {},\n set(newValue) {\n let oldValue = $atom.value\n if (oldValue !== newValue) {\n $atom.value = newValue\n $atom.notify(oldValue)\n }\n },\n subscribe(listener) {\n let unbind = $atom.listen(listener)\n listener($atom.value)\n return unbind\n },\n value: initialValue\n }\n\n if (process.env.NODE_ENV !== 'production') {\n $atom[clean] = () => {\n listeners = []\n $atom.lc = 0\n $atom.off()\n }\n }\n\n return $atom\n}\n\nexport const readonlyType = store => store\n"],"mappings":"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","names":["ref","ref","computed","nextTab","ref","computed","isValid","min","max","ref","computed","computed"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@htlkg/components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.ts",
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
"./navigation": "./src/navigation/index.ts",
|
|
10
10
|
"./overlays": "./src/overlays/index.ts",
|
|
11
11
|
"./domain": "./src/domain/index.ts",
|
|
12
|
-
"./composables":
|
|
12
|
+
"./composables": {
|
|
13
|
+
"import": "./dist/composables/index.js",
|
|
14
|
+
"types": "./src/composables/index.ts"
|
|
15
|
+
}
|
|
13
16
|
},
|
|
14
17
|
"files": [
|
|
15
18
|
"src",
|
|
@@ -20,8 +23,8 @@
|
|
|
20
23
|
"ajv": "^8.17.1",
|
|
21
24
|
"ajv-formats": "^3.0.1",
|
|
22
25
|
"vue": "^3.5.22",
|
|
23
|
-
"@htlkg/core": "0.0.
|
|
24
|
-
"@htlkg/data": "0.0.
|
|
26
|
+
"@htlkg/core": "0.0.3",
|
|
27
|
+
"@htlkg/data": "0.0.3"
|
|
25
28
|
},
|
|
26
29
|
"publishConfig": {
|
|
27
30
|
"access": "restricted"
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Composables Module
|
|
2
|
+
|
|
3
|
+
Vue composables for component state management.
|
|
4
|
+
|
|
5
|
+
## Available Composables
|
|
6
|
+
|
|
7
|
+
### useModal
|
|
8
|
+
|
|
9
|
+
Manage modal state.
|
|
10
|
+
|
|
11
|
+
```vue
|
|
12
|
+
<script setup>
|
|
13
|
+
import { useModal } from '@htlkg/components/composables';
|
|
14
|
+
|
|
15
|
+
const { isOpen, open, close, toggle } = useModal();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<button @click="open">Open Modal</button>
|
|
20
|
+
<Modal v-model:open="isOpen" @close="close" />
|
|
21
|
+
</template>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### useTable
|
|
25
|
+
|
|
26
|
+
Manage table state (pagination, sorting, selection).
|
|
27
|
+
|
|
28
|
+
```vue
|
|
29
|
+
<script setup>
|
|
30
|
+
import { useTable } from '@htlkg/components/composables';
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
currentPage,
|
|
34
|
+
pageSize,
|
|
35
|
+
sortBy,
|
|
36
|
+
sortOrder,
|
|
37
|
+
selectedRows,
|
|
38
|
+
setPage,
|
|
39
|
+
setSort,
|
|
40
|
+
toggleSelection,
|
|
41
|
+
clearSelection,
|
|
42
|
+
} = useTable({
|
|
43
|
+
initialPage: 1,
|
|
44
|
+
initialPageSize: 10,
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### useForm
|
|
50
|
+
|
|
51
|
+
Manage form state and validation.
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<script setup>
|
|
55
|
+
import { useForm } from '@htlkg/components/composables';
|
|
56
|
+
|
|
57
|
+
const {
|
|
58
|
+
values,
|
|
59
|
+
errors,
|
|
60
|
+
isValid,
|
|
61
|
+
isDirty,
|
|
62
|
+
setValue,
|
|
63
|
+
validate,
|
|
64
|
+
reset,
|
|
65
|
+
submit,
|
|
66
|
+
} = useForm({
|
|
67
|
+
initialValues: { name: '', email: '' },
|
|
68
|
+
validationSchema: schema,
|
|
69
|
+
});
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### useNotification
|
|
74
|
+
|
|
75
|
+
Manage notifications.
|
|
76
|
+
|
|
77
|
+
```vue
|
|
78
|
+
<script setup>
|
|
79
|
+
import { useNotification } from '@htlkg/components/composables';
|
|
80
|
+
|
|
81
|
+
const { show, success, error, warning, info, clear } = useNotification();
|
|
82
|
+
|
|
83
|
+
const handleSave = async () => {
|
|
84
|
+
try {
|
|
85
|
+
await save();
|
|
86
|
+
success('Saved successfully');
|
|
87
|
+
} catch (e) {
|
|
88
|
+
error('Failed to save');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
</script>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### useLoading
|
|
95
|
+
|
|
96
|
+
Manage loading states.
|
|
97
|
+
|
|
98
|
+
```vue
|
|
99
|
+
<script setup>
|
|
100
|
+
import { useLoading } from '@htlkg/components/composables';
|
|
101
|
+
|
|
102
|
+
const { isLoading, start, stop, wrap } = useLoading();
|
|
103
|
+
|
|
104
|
+
const fetchData = wrap(async () => {
|
|
105
|
+
const data = await api.fetch();
|
|
106
|
+
return data;
|
|
107
|
+
});
|
|
108
|
+
</script>
|
|
109
|
+
```
|
package/src/composables/index.ts
CHANGED
|
@@ -4,3 +4,20 @@ export { useTabs, type UseTabsOptions, type UseTabsReturn, type Tab } from './us
|
|
|
4
4
|
export { useForm, type UseFormOptions, type UseFormReturn, type ValidationRule, type FieldConfig } from './useForm';
|
|
5
5
|
export { useFormValidation } from './useFormValidation';
|
|
6
6
|
export { useNotifications, type Notification, type UseNotificationsReturn } from './useNotifications';
|
|
7
|
+
|
|
8
|
+
// Page context
|
|
9
|
+
export {
|
|
10
|
+
usePageContext,
|
|
11
|
+
useHasAccessToBrand,
|
|
12
|
+
useHasAccessToAccount,
|
|
13
|
+
useUserRoles,
|
|
14
|
+
useHasRole,
|
|
15
|
+
setUser,
|
|
16
|
+
setCurrentBrand,
|
|
17
|
+
$user,
|
|
18
|
+
$currentBrand,
|
|
19
|
+
PAGE_CONTEXT_KEY,
|
|
20
|
+
type PageContext,
|
|
21
|
+
type PageUser,
|
|
22
|
+
type PageBrand,
|
|
23
|
+
} from './usePageContext';
|