@htlkg/data 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/index.d.ts +702 -94
- package/dist/hooks/index.js +793 -56
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +802 -65
- package/dist/index.js.map +1 -1
- package/dist/mutations/index.js +4 -4
- package/dist/mutations/index.js.map +1 -1
- package/dist/queries/index.js +5 -5
- package/dist/queries/index.js.map +1 -1
- package/package.json +11 -12
- package/src/hooks/accounts/index.ts +2 -0
- package/src/hooks/{useAccounts.ts → accounts/useAccounts.ts} +48 -5
- package/src/hooks/accounts/usePaginatedAccounts.ts +166 -0
- package/src/hooks/brands/index.ts +2 -0
- package/src/hooks/{useBrands.ts → brands/useBrands.ts} +1 -1
- package/src/hooks/brands/usePaginatedBrands.ts +206 -0
- package/src/hooks/contacts/index.ts +2 -0
- package/src/hooks/contacts/useContacts.ts +176 -0
- package/src/hooks/contacts/usePaginatedContacts.ts +268 -0
- package/src/hooks/createPaginatedDataHook.ts +359 -0
- package/src/hooks/data-hook-errors.property.test.ts +4 -4
- package/src/hooks/data-hook-filters.property.test.ts +4 -4
- package/src/hooks/data-hooks.property.test.ts +4 -4
- package/src/hooks/index.ts +101 -8
- package/src/hooks/productInstances/index.ts +1 -0
- package/src/hooks/{useProductInstances.ts → productInstances/useProductInstances.ts} +9 -6
- package/src/hooks/products/index.ts +1 -0
- package/src/hooks/{useProducts.ts → products/useProducts.ts} +4 -5
- package/src/hooks/reservations/index.ts +2 -0
- package/src/hooks/reservations/usePaginatedReservations.ts +258 -0
- package/src/hooks/{useReservations.ts → reservations/useReservations.ts} +65 -10
- package/src/hooks/users/index.ts +2 -0
- package/src/hooks/users/usePaginatedUsers.ts +213 -0
- package/src/hooks/{useUsers.ts → users/useUsers.ts} +1 -1
- package/src/mutations/accounts/accounts.test.ts +287 -0
- package/src/mutations/{accounts.ts → accounts/accounts.ts} +2 -2
- package/src/mutations/accounts/index.ts +1 -0
- package/src/mutations/brands/brands.test.ts +292 -0
- package/src/mutations/{brands.ts → brands/brands.ts} +2 -2
- package/src/mutations/brands/index.ts +1 -0
- package/src/mutations/reservations/index.ts +1 -0
- package/src/mutations/{reservations.test.ts → reservations/reservations.test.ts} +1 -1
- package/src/mutations/{reservations.ts → reservations/reservations.ts} +2 -2
- package/src/mutations/users/index.ts +1 -0
- package/src/mutations/users/users.test.ts +289 -0
- package/src/mutations/{users.ts → users/users.ts} +2 -2
- package/src/queries/accounts/accounts.test.ts +228 -0
- package/src/queries/accounts/index.ts +1 -0
- package/src/queries/brands/brands.test.ts +288 -0
- package/src/queries/brands/index.ts +1 -0
- package/src/queries/products/index.ts +1 -0
- package/src/queries/products/products.test.ts +347 -0
- package/src/queries/reservations/index.ts +1 -0
- package/src/queries/users/index.ts +1 -0
- package/src/queries/users/users.test.ts +301 -0
- /package/src/queries/{accounts.ts → accounts/accounts.ts} +0 -0
- /package/src/queries/{brands.ts → brands/brands.ts} +0 -0
- /package/src/queries/{products.ts → products/products.ts} +0 -0
- /package/src/queries/{reservations.test.ts → reservations/reservations.test.ts} +0 -0
- /package/src/queries/{reservations.ts → reservations/reservations.ts} +0 -0
- /package/src/queries/{users.ts → users/users.ts} +0 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paginated Data Hook Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates reusable Vue composables for fetching paginated data from GraphQL models.
|
|
5
|
+
* Supports cursor-based pagination (nextToken) for efficient handling of large datasets.
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - Server-side pagination with nextToken
|
|
9
|
+
* - loadMore() for infinite scroll/pagination
|
|
10
|
+
* - hasMore indicator
|
|
11
|
+
* - Independent pagination state per hook instance
|
|
12
|
+
* - Built-in support for active/deleted filtering
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { ref, computed, onMounted, type Ref, type ComputedRef } from "vue";
|
|
16
|
+
import { query, hasErrors, getErrorMessage } from "../client/proxy";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Filter for active items (not deleted)
|
|
20
|
+
* Uses OR condition because deletedAt can be:
|
|
21
|
+
* - Missing (attributeExists: false)
|
|
22
|
+
* - Explicitly null (eq: null)
|
|
23
|
+
*/
|
|
24
|
+
export const ACTIVE_FILTER = {
|
|
25
|
+
or: [{ deletedAt: { attributeExists: false } }, { deletedAt: { eq: null } }],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Filter for deleted items
|
|
30
|
+
* Uses gt: "" to match only actual timestamp strings (not null or missing)
|
|
31
|
+
*/
|
|
32
|
+
export const DELETED_FILTER = {
|
|
33
|
+
deletedAt: { gt: "" },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Configuration options for creating a paginated data hook
|
|
38
|
+
*/
|
|
39
|
+
export interface CreatePaginatedDataHookOptions<T, TOptions extends PaginatedHookOptions = PaginatedHookOptions> {
|
|
40
|
+
/** The GraphQL model name (e.g., 'Account', 'User', 'Brand') */
|
|
41
|
+
model: string;
|
|
42
|
+
/** Default page size */
|
|
43
|
+
defaultPageSize?: number;
|
|
44
|
+
/** Selection set for the query (fields to fetch) */
|
|
45
|
+
selectionSet?: string[];
|
|
46
|
+
/** Transform function to apply to fetched data */
|
|
47
|
+
transform?: (item: any) => T;
|
|
48
|
+
/** Build filter from hook options */
|
|
49
|
+
buildFilter?: (options: TOptions) => any;
|
|
50
|
+
/** Plural name for the data property (e.g., 'accounts', 'users') */
|
|
51
|
+
dataPropertyName?: string;
|
|
52
|
+
/** Base filter to always apply (e.g., for active/deleted variants) */
|
|
53
|
+
baseFilter?: any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Base options available to paginated hooks
|
|
58
|
+
*/
|
|
59
|
+
export interface PaginatedHookOptions {
|
|
60
|
+
/** Additional filter criteria (merged with baseFilter) */
|
|
61
|
+
filter?: any;
|
|
62
|
+
/** Page size (default: 25) */
|
|
63
|
+
pageSize?: number;
|
|
64
|
+
/** Auto-fetch on mount (default: true) */
|
|
65
|
+
autoFetch?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Pagination state
|
|
70
|
+
*/
|
|
71
|
+
export interface PaginationState {
|
|
72
|
+
/** Current nextToken for fetching next page */
|
|
73
|
+
nextToken: string | null;
|
|
74
|
+
/** Whether there are more items to load */
|
|
75
|
+
hasMore: boolean;
|
|
76
|
+
/** Total items loaded so far */
|
|
77
|
+
loadedCount: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Return type for paginated data hooks
|
|
82
|
+
*/
|
|
83
|
+
export interface PaginatedDataHookReturn<T> {
|
|
84
|
+
/** Reactive array of data (accumulated across pages) */
|
|
85
|
+
data: Ref<T[]>;
|
|
86
|
+
/** Loading state (true during any fetch) */
|
|
87
|
+
loading: Ref<boolean>;
|
|
88
|
+
/** Loading state for initial fetch */
|
|
89
|
+
initialLoading: Ref<boolean>;
|
|
90
|
+
/** Loading state for loadMore */
|
|
91
|
+
loadingMore: Ref<boolean>;
|
|
92
|
+
/** Error state */
|
|
93
|
+
error: Ref<Error | null>;
|
|
94
|
+
/** Pagination state */
|
|
95
|
+
pagination: Ref<PaginationState>;
|
|
96
|
+
/** Whether there are more items to load */
|
|
97
|
+
hasMore: ComputedRef<boolean>;
|
|
98
|
+
/** Load next page of data */
|
|
99
|
+
loadMore: () => Promise<void>;
|
|
100
|
+
/** Refetch data (resets to first page) */
|
|
101
|
+
refetch: () => Promise<void>;
|
|
102
|
+
/** Reset data and pagination state */
|
|
103
|
+
reset: () => void;
|
|
104
|
+
/** Update search filter and refetch from server (searches ALL data) */
|
|
105
|
+
setSearchFilter: (filter: any) => Promise<void>;
|
|
106
|
+
/** Current search filter */
|
|
107
|
+
searchFilter: Ref<any>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Creates a reusable paginated data hook for a specific model
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* // Create a hook for active brands
|
|
116
|
+
* export const useActiveBrands = createPaginatedDataHook<Brand>({
|
|
117
|
+
* model: 'Brand',
|
|
118
|
+
* dataPropertyName: 'brands',
|
|
119
|
+
* baseFilter: ACTIVE_FILTER,
|
|
120
|
+
* selectionSet: ['id', 'name', 'status', 'accountId', 'account.name'],
|
|
121
|
+
* });
|
|
122
|
+
*
|
|
123
|
+
* // Usage in component
|
|
124
|
+
* const { brands, loading, hasMore, loadMore, refetch } = useActiveBrands({
|
|
125
|
+
* pageSize: 25,
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example With custom filter builder
|
|
130
|
+
* ```typescript
|
|
131
|
+
* interface UseBrandsOptions extends PaginatedHookOptions {
|
|
132
|
+
* accountId?: string;
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* export const useActiveBrands = createPaginatedDataHook<Brand, UseBrandsOptions>({
|
|
136
|
+
* model: 'Brand',
|
|
137
|
+
* dataPropertyName: 'brands',
|
|
138
|
+
* baseFilter: ACTIVE_FILTER,
|
|
139
|
+
* buildFilter: (options) => {
|
|
140
|
+
* if (options.accountId) {
|
|
141
|
+
* return { accountId: { eq: options.accountId } };
|
|
142
|
+
* }
|
|
143
|
+
* return undefined;
|
|
144
|
+
* },
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export function createPaginatedDataHook<T, TOptions extends PaginatedHookOptions = PaginatedHookOptions>(
|
|
149
|
+
config: CreatePaginatedDataHookOptions<T, TOptions>,
|
|
150
|
+
) {
|
|
151
|
+
const {
|
|
152
|
+
model,
|
|
153
|
+
defaultPageSize = 25,
|
|
154
|
+
selectionSet,
|
|
155
|
+
transform,
|
|
156
|
+
buildFilter,
|
|
157
|
+
dataPropertyName = "data",
|
|
158
|
+
baseFilter,
|
|
159
|
+
} = config;
|
|
160
|
+
|
|
161
|
+
return function usePaginatedData(
|
|
162
|
+
options: TOptions = {} as TOptions,
|
|
163
|
+
): PaginatedDataHookReturn<T> & Record<string, any> {
|
|
164
|
+
const { filter: additionalFilter, pageSize = defaultPageSize, autoFetch = true } = options;
|
|
165
|
+
|
|
166
|
+
// State
|
|
167
|
+
const data = ref<T[]>([]) as Ref<T[]>;
|
|
168
|
+
const loading = ref(false);
|
|
169
|
+
const initialLoading = ref(false);
|
|
170
|
+
const loadingMore = ref(false);
|
|
171
|
+
const error = ref<Error | null>(null);
|
|
172
|
+
const pagination = ref<PaginationState>({
|
|
173
|
+
nextToken: null,
|
|
174
|
+
hasMore: true,
|
|
175
|
+
loadedCount: 0,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Dynamic search filter (for server-side filtering)
|
|
179
|
+
const searchFilter = ref<any>(null);
|
|
180
|
+
|
|
181
|
+
// Computed
|
|
182
|
+
const hasMore = computed(() => pagination.value.hasMore);
|
|
183
|
+
|
|
184
|
+
// Build combined filter
|
|
185
|
+
const getFilter = () => {
|
|
186
|
+
const filters: any[] = [];
|
|
187
|
+
|
|
188
|
+
// Add base filter (e.g., active/deleted)
|
|
189
|
+
if (baseFilter) {
|
|
190
|
+
filters.push(baseFilter);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Add custom filter from buildFilter
|
|
194
|
+
if (buildFilter) {
|
|
195
|
+
const customFilter = buildFilter(options);
|
|
196
|
+
if (customFilter) {
|
|
197
|
+
filters.push(customFilter);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Add additional filter from options
|
|
202
|
+
if (additionalFilter && Object.keys(additionalFilter).length > 0) {
|
|
203
|
+
filters.push(additionalFilter);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Add dynamic search filter (for server-side search)
|
|
207
|
+
if (searchFilter.value && Object.keys(searchFilter.value).length > 0) {
|
|
208
|
+
filters.push(searchFilter.value);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Combine filters with AND
|
|
212
|
+
if (filters.length === 0) {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
if (filters.length === 1) {
|
|
216
|
+
return filters[0];
|
|
217
|
+
}
|
|
218
|
+
return { and: filters };
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Fetch function
|
|
222
|
+
async function fetchPage(nextToken?: string | null, append: boolean = false) {
|
|
223
|
+
if (!append) {
|
|
224
|
+
initialLoading.value = true;
|
|
225
|
+
} else {
|
|
226
|
+
loadingMore.value = true;
|
|
227
|
+
}
|
|
228
|
+
loading.value = true;
|
|
229
|
+
error.value = null;
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
const queryOptions: Record<string, any> = {
|
|
233
|
+
limit: pageSize,
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const filter = getFilter();
|
|
237
|
+
if (filter) {
|
|
238
|
+
queryOptions.filter = filter;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (nextToken) {
|
|
242
|
+
queryOptions.nextToken = nextToken;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (selectionSet) {
|
|
246
|
+
queryOptions.selectionSet = selectionSet;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const response = await query(model, "list", queryOptions);
|
|
250
|
+
|
|
251
|
+
if (hasErrors(response)) {
|
|
252
|
+
throw new Error(getErrorMessage(response) || `Failed to fetch ${model}`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const items = response.data || [];
|
|
256
|
+
const transformedItems = transform ? items.map(transform) : items;
|
|
257
|
+
|
|
258
|
+
if (append) {
|
|
259
|
+
data.value = [...data.value, ...transformedItems];
|
|
260
|
+
} else {
|
|
261
|
+
data.value = transformedItems;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Update pagination state
|
|
265
|
+
// Note: Amplify returns nextToken in the response
|
|
266
|
+
const responseNextToken = (response as any).nextToken;
|
|
267
|
+
pagination.value = {
|
|
268
|
+
nextToken: responseNextToken || null,
|
|
269
|
+
hasMore: !!responseNextToken,
|
|
270
|
+
loadedCount: data.value.length,
|
|
271
|
+
};
|
|
272
|
+
} catch (e) {
|
|
273
|
+
error.value = e as Error;
|
|
274
|
+
console.error(`[use${model}] Error fetching ${model}:`, e);
|
|
275
|
+
} finally {
|
|
276
|
+
loading.value = false;
|
|
277
|
+
initialLoading.value = false;
|
|
278
|
+
loadingMore.value = false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Load more function
|
|
283
|
+
async function loadMore() {
|
|
284
|
+
if (loadingMore.value || !pagination.value.hasMore) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
await fetchPage(pagination.value.nextToken, true);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Refetch (reset to first page)
|
|
291
|
+
async function refetch() {
|
|
292
|
+
pagination.value = {
|
|
293
|
+
nextToken: null,
|
|
294
|
+
hasMore: true,
|
|
295
|
+
loadedCount: 0,
|
|
296
|
+
};
|
|
297
|
+
await fetchPage(null, false);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Reset state
|
|
301
|
+
function reset() {
|
|
302
|
+
data.value = [];
|
|
303
|
+
error.value = null;
|
|
304
|
+
searchFilter.value = null;
|
|
305
|
+
pagination.value = {
|
|
306
|
+
nextToken: null,
|
|
307
|
+
hasMore: true,
|
|
308
|
+
loadedCount: 0,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Set search filter and refetch from server (searches ALL data)
|
|
313
|
+
async function setSearchFilter(filter: any) {
|
|
314
|
+
searchFilter.value = filter;
|
|
315
|
+
// Reset pagination and fetch with new filter
|
|
316
|
+
pagination.value = {
|
|
317
|
+
nextToken: null,
|
|
318
|
+
hasMore: true,
|
|
319
|
+
loadedCount: 0,
|
|
320
|
+
};
|
|
321
|
+
await fetchPage(null, false);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Auto-fetch on mount if enabled
|
|
325
|
+
if (autoFetch) {
|
|
326
|
+
onMounted(() => {
|
|
327
|
+
fetchPage(null, false);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Build return object
|
|
332
|
+
const result: PaginatedDataHookReturn<T> & Record<string, any> = {
|
|
333
|
+
data,
|
|
334
|
+
loading,
|
|
335
|
+
initialLoading,
|
|
336
|
+
loadingMore,
|
|
337
|
+
error,
|
|
338
|
+
pagination,
|
|
339
|
+
hasMore,
|
|
340
|
+
loadMore,
|
|
341
|
+
refetch,
|
|
342
|
+
reset,
|
|
343
|
+
setSearchFilter,
|
|
344
|
+
searchFilter,
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// Add data property with custom name for backwards compatibility
|
|
348
|
+
if (dataPropertyName !== "data") {
|
|
349
|
+
result[dataPropertyName] = data;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return result;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Type helper to extract the return type of a created paginated hook
|
|
358
|
+
*/
|
|
359
|
+
export type InferPaginatedHookReturn<THook extends (...args: any[]) => any> = ReturnType<THook>;
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
11
11
|
import * as fc from "fast-check";
|
|
12
|
-
import { useBrands } from "./useBrands";
|
|
13
|
-
import { useAccounts } from "./useAccounts";
|
|
14
|
-
import { useUsers } from "./useUsers";
|
|
15
|
-
import { useProducts } from "./useProducts";
|
|
12
|
+
import { useBrands } from "./brands/useBrands";
|
|
13
|
+
import { useAccounts } from "./accounts/useAccounts";
|
|
14
|
+
import { useUsers } from "./users/useUsers";
|
|
15
|
+
import { useProducts } from "./products/useProducts";
|
|
16
16
|
|
|
17
17
|
// Create separate mock functions for each model
|
|
18
18
|
const mockBrandList = vi.fn();
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
11
11
|
import * as fc from "fast-check";
|
|
12
|
-
import { useBrands } from "./useBrands";
|
|
13
|
-
import { useAccounts } from "./useAccounts";
|
|
14
|
-
import { useUsers } from "./useUsers";
|
|
15
|
-
import { useProducts } from "./useProducts";
|
|
12
|
+
import { useBrands } from "./brands/useBrands";
|
|
13
|
+
import { useAccounts } from "./accounts/useAccounts";
|
|
14
|
+
import { useUsers } from "./users/useUsers";
|
|
15
|
+
import { useProducts } from "./products/useProducts";
|
|
16
16
|
import type { Brand, Account, Product } from "@htlkg/core/types";
|
|
17
17
|
|
|
18
18
|
// Create separate mock functions for each model
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
11
11
|
import * as fc from "fast-check";
|
|
12
12
|
import { ref, isRef, isReactive, computed } from "vue";
|
|
13
|
-
import { useBrands } from "./useBrands";
|
|
14
|
-
import { useAccounts } from "./useAccounts";
|
|
15
|
-
import { useUsers } from "./useUsers";
|
|
16
|
-
import { useProducts } from "./useProducts";
|
|
13
|
+
import { useBrands } from "./brands/useBrands";
|
|
14
|
+
import { useAccounts } from "./accounts/useAccounts";
|
|
15
|
+
import { useUsers } from "./users/useUsers";
|
|
16
|
+
import { useProducts } from "./products/useProducts";
|
|
17
17
|
|
|
18
18
|
// Mock the client module
|
|
19
19
|
vi.mock("../client", () => ({
|
package/src/hooks/index.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Data Hooks for @htlkg/data
|
|
3
3
|
*
|
|
4
4
|
* Vue composables for fetching and managing data with reactive state.
|
|
5
|
+
* Organized by entity type in subfolders for better maintainability.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
// Hook factory for creating custom data hooks
|
|
@@ -14,11 +15,103 @@ export {
|
|
|
14
15
|
type InferHookReturn,
|
|
15
16
|
} from "./createDataHook";
|
|
16
17
|
|
|
17
|
-
//
|
|
18
|
-
export {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
// Paginated hook factory for large datasets
|
|
19
|
+
export {
|
|
20
|
+
createPaginatedDataHook,
|
|
21
|
+
ACTIVE_FILTER,
|
|
22
|
+
DELETED_FILTER,
|
|
23
|
+
type CreatePaginatedDataHookOptions,
|
|
24
|
+
type PaginatedHookOptions,
|
|
25
|
+
type PaginationState,
|
|
26
|
+
type PaginatedDataHookReturn,
|
|
27
|
+
type InferPaginatedHookReturn,
|
|
28
|
+
} from "./createPaginatedDataHook";
|
|
29
|
+
|
|
30
|
+
// ============================================
|
|
31
|
+
// BRAND HOOKS
|
|
32
|
+
// ============================================
|
|
33
|
+
export {
|
|
34
|
+
useBrands,
|
|
35
|
+
useActiveBrands,
|
|
36
|
+
useDeletedBrands,
|
|
37
|
+
type UseBrandsOptions,
|
|
38
|
+
type UseBrandsReturn,
|
|
39
|
+
type BrandWithCounts,
|
|
40
|
+
type UsePaginatedBrandsOptions,
|
|
41
|
+
type UsePaginatedBrandsReturn,
|
|
42
|
+
} from "./brands";
|
|
43
|
+
|
|
44
|
+
// ============================================
|
|
45
|
+
// USER HOOKS
|
|
46
|
+
// ============================================
|
|
47
|
+
export {
|
|
48
|
+
useUsers,
|
|
49
|
+
useActiveUsers,
|
|
50
|
+
useDeletedUsers,
|
|
51
|
+
type UseUsersOptions,
|
|
52
|
+
type UseUsersReturn,
|
|
53
|
+
type UserWithRelations,
|
|
54
|
+
type UsePaginatedUsersOptions,
|
|
55
|
+
type UsePaginatedUsersReturn,
|
|
56
|
+
} from "./users";
|
|
57
|
+
|
|
58
|
+
// ============================================
|
|
59
|
+
// ACCOUNT HOOKS
|
|
60
|
+
// ============================================
|
|
61
|
+
export {
|
|
62
|
+
useAccounts,
|
|
63
|
+
useActiveAccounts,
|
|
64
|
+
useDeletedAccounts,
|
|
65
|
+
type UseAccountsOptions,
|
|
66
|
+
type UseAccountsReturn,
|
|
67
|
+
type AccountWithBrands,
|
|
68
|
+
type AccountWithBrands as PaginatedAccountWithBrands,
|
|
69
|
+
type UsePaginatedAccountsOptions,
|
|
70
|
+
type UsePaginatedAccountsReturn,
|
|
71
|
+
} from "./accounts";
|
|
72
|
+
|
|
73
|
+
// ============================================
|
|
74
|
+
// RESERVATION HOOKS
|
|
75
|
+
// ============================================
|
|
76
|
+
export {
|
|
77
|
+
useReservations,
|
|
78
|
+
useActiveReservations,
|
|
79
|
+
useDeletedReservations,
|
|
80
|
+
type UseReservationsOptions,
|
|
81
|
+
type UseReservationsReturn,
|
|
82
|
+
type ReservationWithRelations,
|
|
83
|
+
type UsePaginatedReservationsOptions,
|
|
84
|
+
type UsePaginatedReservationsReturn,
|
|
85
|
+
} from "./reservations";
|
|
86
|
+
|
|
87
|
+
// ============================================
|
|
88
|
+
// PRODUCT HOOKS
|
|
89
|
+
// ============================================
|
|
90
|
+
export {
|
|
91
|
+
useProducts,
|
|
92
|
+
type UseProductsOptions,
|
|
93
|
+
type UseProductsReturn,
|
|
94
|
+
} from "./products";
|
|
95
|
+
|
|
96
|
+
// ============================================
|
|
97
|
+
// PRODUCT INSTANCE HOOKS
|
|
98
|
+
// ============================================
|
|
99
|
+
export {
|
|
100
|
+
useProductInstances,
|
|
101
|
+
type UseProductInstancesOptions,
|
|
102
|
+
type UseProductInstancesReturn,
|
|
103
|
+
} from "./productInstances";
|
|
104
|
+
|
|
105
|
+
// ============================================
|
|
106
|
+
// CONTACT HOOKS
|
|
107
|
+
// ============================================
|
|
108
|
+
export {
|
|
109
|
+
useContacts,
|
|
110
|
+
useActiveContacts,
|
|
111
|
+
useDeletedContacts,
|
|
112
|
+
type UseContactsOptions,
|
|
113
|
+
type UseContactsReturn,
|
|
114
|
+
type ContactWithRelations,
|
|
115
|
+
type UsePaginatedContactsOptions,
|
|
116
|
+
type UsePaginatedContactsReturn,
|
|
117
|
+
} from "./contacts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useProductInstances";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ProductInstance Hooks
|
|
3
3
|
*
|
|
4
|
-
* Vue
|
|
4
|
+
* Vue composables for fetching and managing product instance data with reactive state.
|
|
5
5
|
* Provides loading states, error handling, refetch capabilities, and CRUD operations.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Ref, ComputedRef } from "vue";
|
|
9
9
|
import type { ProductInstance } from "@htlkg/core/types";
|
|
10
|
-
import { createDataHook, type BaseHookOptions } from "
|
|
11
|
-
import { getSharedClient } from "
|
|
10
|
+
import { createDataHook, type BaseHookOptions } from "../createDataHook";
|
|
11
|
+
import { getSharedClient } from "../../client";
|
|
12
12
|
import {
|
|
13
13
|
createProductInstance,
|
|
14
14
|
updateProductInstance,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
toggleProductInstanceEnabled,
|
|
17
17
|
type CreateProductInstanceInput,
|
|
18
18
|
type UpdateProductInstanceInput,
|
|
19
|
-
} from "
|
|
19
|
+
} from "../../mutations/productInstances";
|
|
20
20
|
|
|
21
21
|
export interface UseProductInstancesOptions extends BaseHookOptions {
|
|
22
22
|
/** Filter criteria for product instances */
|
|
@@ -102,7 +102,7 @@ const useProductInstancesInternal = createDataHook<
|
|
|
102
102
|
*
|
|
103
103
|
* @example
|
|
104
104
|
* ```typescript
|
|
105
|
-
* import { useProductInstances } from '@htlkg/data/hooks';
|
|
105
|
+
* import { useProductInstances } from '@htlkg/data/hooks/productInstances';
|
|
106
106
|
*
|
|
107
107
|
* const { instances, loading, error, refetch } = useProductInstances();
|
|
108
108
|
* ```
|
|
@@ -172,3 +172,6 @@ export function useProductInstances(options: UseProductInstancesOptions = {}): U
|
|
|
172
172
|
toggleEnabled,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
// Re-export types for convenience
|
|
177
|
+
export type { CreateProductInstanceInput, UpdateProductInstanceInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useProducts";
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Product Hooks
|
|
3
3
|
*
|
|
4
|
-
* Vue
|
|
5
|
-
* Provides loading states, error handling, and refetch capabilities.
|
|
4
|
+
* Vue composables for fetching and managing product data with reactive state.
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
import type { Ref, ComputedRef } from "vue";
|
|
9
8
|
import type { Product } from "@htlkg/core/types";
|
|
10
|
-
import { createDataHook, type BaseHookOptions } from "
|
|
9
|
+
import { createDataHook, type BaseHookOptions } from "../createDataHook";
|
|
11
10
|
|
|
12
11
|
export interface UseProductsOptions extends BaseHookOptions {
|
|
13
12
|
/** Filter criteria for products */
|
|
@@ -63,7 +62,7 @@ const useProductsInternal = createDataHook<Product, UseProductsOptions, { active
|
|
|
63
62
|
*
|
|
64
63
|
* @example
|
|
65
64
|
* ```typescript
|
|
66
|
-
* import { useProducts } from '@htlkg/data/hooks';
|
|
65
|
+
* import { useProducts } from '@htlkg/data/hooks/products';
|
|
67
66
|
*
|
|
68
67
|
* const { products, loading, error, refetch } = useProducts();
|
|
69
68
|
* ```
|