@openway/ui 1.0.1 → 1.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/dist/query.d.cts CHANGED
@@ -1,7 +1,8 @@
1
- import { QueryFunctionContext, UseQueryOptions, UseQueryResult, UseInfiniteQueryOptions, InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
1
+ import { QueryFunctionContext, UseQueryOptions, UseQueryResult, UseInfiniteQueryOptions, InfiniteData, UseInfiniteQueryResult, QueryKey, InvalidateQueryFilters, DefaultError, UseMutationOptions, InvalidateOptions, UseMutationResult } from '@tanstack/react-query';
2
2
  import { RowData, SortingState, ColumnFiltersState, PaginationState, OnChangeFn } from '@tanstack/react-table';
3
3
  import { ReactNode } from 'react';
4
- import { b as SelectOptionItem, U as UseInfiniteScrollOptions } from './useInfiniteScroll-DAlgjUN4.cjs';
4
+ import { d as SelectOptionItem, U as UseInfiniteScrollOptions, a as ToastOptions, o as AlertVariant } from './useInfiniteScroll-C5t7bvLu.cjs';
5
+ import 'sonner';
5
6
  import '@floating-ui/react';
6
7
 
7
8
  /**
@@ -77,6 +78,12 @@ interface UseTableQueryOptions<TData extends RowData = RowData, TResponse = unkn
77
78
  * @default true
78
79
  */
79
80
  autoResetPageIndex?: boolean;
81
+ /**
82
+ * Thời gian trì hoãn debounce (ms) khi thay đổi bộ lọc hoặc tìm kiếm.
83
+ * Mặc định là 300ms. Đặt 0 để tắt debounce.
84
+ * @default 300
85
+ */
86
+ debounceMs?: number;
80
87
  /**
81
88
  * Các tùy chọn nâng cao truyền trực tiếp cho hook `useQuery` của TanStack Query
82
89
  * (ví dụ: `staleTime`, `gcTime`, `refetchOnWindowFocus`, `enabled`...).
@@ -99,6 +106,7 @@ interface UseTableQueryReturn<TData extends RowData = RowData, TResponse = unkno
99
106
  manualPagination: true;
100
107
  manualSorting: true;
101
108
  manualFiltering: true;
109
+ debounceMs?: number;
102
110
  pagination: PaginationState;
103
111
  onPaginationChange: OnChangeFn<PaginationState>;
104
112
  sorting: SortingState;
@@ -306,4 +314,126 @@ interface UseSelectInfiniteQueryReturn<TData = unknown, TResponse = unknown, TFi
306
314
  */
307
315
  declare function useSelectInfiniteQuery<TData = unknown, TResponse = unknown, TPageParam = number, TFilters extends Record<string, unknown> = Record<string, unknown>, TError = Error>({ queryKey, queryFn, initialPageParam, getNextPageParam, getPreviousPageParam, selectOptions, mapOption, debounceMs, initialSearch, initialFilters, initialOptions, skeletonLines, skeletonHeight, renderLoadingMore, endMessage, scrollOptions, queryOptions, }: UseSelectInfiniteQueryOptions<TData, TResponse, TPageParam, TFilters, TError>): UseSelectInfiniteQueryReturn<TData, TResponse, TFilters, TError>;
308
316
 
309
- export { type SelectQueryParams, type TableQueryParams, type UseSelectInfiniteQueryOptions, type UseSelectInfiniteQueryReturn, type UseTableQueryOptions, type UseTableQueryReturn, useSelectInfiniteQuery, useTableQuery };
317
+ /**
318
+ * Mục tiêu invalidate cache: có thể là QueryKey (readonly unknown[]) hoặc InvalidateQueryFilters.
319
+ */
320
+ type InvalidateQueryTarget = QueryKey | InvalidateQueryFilters;
321
+ /**
322
+ * Tùy chọn cấu hình Toast cho hook `useMutationApp`.
323
+ */
324
+ interface UseMutationAppToastOptions<TData, TError, TVariables> {
325
+ /**
326
+ * Nội dung thông báo khi đang thực thi mutation (loading spinner, không tự đóng).
327
+ * Có thể là ReactNode hoặc một hàm nhận vào `variables`.
328
+ */
329
+ loading?: ReactNode | ((variables: TVariables) => ReactNode);
330
+ /**
331
+ * Nội dung thông báo khi mutation hoàn tất thành công.
332
+ * Có thể là ReactNode hoặc một hàm nhận vào `(data, variables)`.
333
+ */
334
+ success?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
335
+ /**
336
+ * Tiêu đề thông báo khi mutation thất bại.
337
+ * - `true`: Hiển thị tiêu đề lỗi mặc định ("Đã xảy ra lỗi").
338
+ * - `false`: Không hiển thị toast lỗi.
339
+ * - `ReactNode`: Tiêu đề lỗi cố định.
340
+ * - `(error, variables) => ReactNode`: Hàm tạo tiêu đề lỗi linh hoạt.
341
+ * @default true
342
+ */
343
+ error?: boolean | ReactNode | ((error: TError, variables: TVariables) => ReactNode);
344
+ /**
345
+ * Nội dung mô tả chi tiết (description) cho thông báo khi đang loading.
346
+ */
347
+ loadingDescription?: ReactNode | ((variables: TVariables) => ReactNode);
348
+ /**
349
+ * Nội dung mô tả chi tiết (description) cho thông báo thành công.
350
+ */
351
+ successDescription?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
352
+ /**
353
+ * Nội dung mô tả chi tiết (description) cho thông báo lỗi.
354
+ * Nếu không truyền, tự động trích xuất thông điệp từ API/Error qua `extractErrorMessage`.
355
+ */
356
+ errorDescription?: ReactNode | ((error: TError, variables: TVariables) => ReactNode);
357
+ /**
358
+ * Tùy chọn cấu hình bổ sung cho Toast (duration, position, size, radius, closable...).
359
+ */
360
+ options?: ToastOptions;
361
+ /**
362
+ * Kiểu hiển thị Toast: "soft" | "solid" | "outline".
363
+ * @default "soft"
364
+ */
365
+ variant?: AlertVariant;
366
+ }
367
+ /**
368
+ * Các tùy chọn cấu hình cho hook `useMutationApp`.
369
+ */
370
+ interface UseMutationAppOptions<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends Omit<UseMutationOptions<TData, TError, TVariables, TContext>, "mutationFn"> {
371
+ /**
372
+ * Hàm gọi API hoặc thực hiện tác vụ bất đồng bộ.
373
+ */
374
+ mutationFn?: (variables: TVariables) => Promise<TData>;
375
+ /**
376
+ * Khóa truy vấn hoặc danh sách khóa truy vấn cần tự động làm mới (invalidate) khi mutation thành công.
377
+ * Hỗ trợ:
378
+ * - Một QueryKey đơn: `["teachers"]` hoặc `["users", 1]`
379
+ * - Danh sách nhiều QueryKey: `[["teachers"], ["classes"]]`
380
+ * - Bộ lọc nâng cao InvalidateQueryFilters: `{ queryKey: ["teachers"], exact: true }`
381
+ * - Danh sách bộ lọc: `[{ queryKey: ["teachers"] }, { queryKey: ["classes"] }]`
382
+ * - Hàm trả về động: `(data, variables) => [["teachers"], ["classes", variables.classId]]`
383
+ */
384
+ invalidateQueries?: InvalidateQueryTarget | InvalidateQueryTarget[] | ((data: TData, variables: TVariables) => InvalidateQueryTarget | InvalidateQueryTarget[] | void | null | undefined);
385
+ /**
386
+ * Tùy chọn InvalidateOptions bổ sung truyền cho `queryClient.invalidateQueries`
387
+ * (ví dụ: `throwOnError`, `cancelRefetch`).
388
+ */
389
+ invalidateOptions?: InvalidateOptions;
390
+ /**
391
+ * Cấu hình hiển thị thông báo Toast.
392
+ * - `false`: Tắt toàn bộ thông báo Toast.
393
+ * - `true`: Bật Toast với cấu hình mặc định (tự động báo lỗi nếu có).
394
+ * - `object`: Cấu hình chi tiết `loading`, `success`, `error`.
395
+ */
396
+ toast?: boolean | UseMutationAppToastOptions<TData, TError, TVariables>;
397
+ /**
398
+ * Shortcut cấu hình nhanh thông báo thành công.
399
+ */
400
+ successMessage?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
401
+ /**
402
+ * Shortcut cấu hình nhanh thông báo lỗi.
403
+ */
404
+ errorMessage?: ReactNode | ((error: TError, variables: TVariables) => ReactNode);
405
+ /**
406
+ * Shortcut cấu hình nhanh thông báo loading.
407
+ */
408
+ loadingMessage?: ReactNode | ((variables: TVariables) => ReactNode);
409
+ }
410
+ /**
411
+ * Kết quả trả về từ hook `useMutationApp`.
412
+ */
413
+ type UseMutationAppReturn<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> = UseMutationResult<TData, TError, TVariables, TContext> & {
414
+ /**
415
+ * Bí danh (alias) của `isPending`, tương thích ngược với thói quen sử dụng `isLoading` của TanStack Query v4.
416
+ */
417
+ isLoading: boolean;
418
+ };
419
+ /**
420
+ * Hàm hỗ trợ tự động trích xuất thông điệp lỗi (error message) từ nhiều định dạng lỗi phổ biến:
421
+ * - Axios Error response (`error.response?.data?.message`, `error.response?.data?.error`...)
422
+ * - Fetch API response / HTTP status
423
+ * - Standard JS Error (`error.message`)
424
+ * - String error
425
+ */
426
+ declare function extractErrorMessage(error: unknown, fallback?: string): string;
427
+ /**
428
+ * Hook `useMutationApp` - Tối ưu hóa tác vụ Mutation cho ứng dụng với TanStack Query v5 & `@openway/ui`.
429
+ *
430
+ * Tính năng chính:
431
+ * - **Tự động hóa Toast**: Hiển thị Toast loading khi xử lý, tự động cập nhật Toast success/error mượt mà.
432
+ * - **Tự động bóc tách lỗi**: Bóc tách thông điệp lỗi chính xác từ Axios / API response qua `extractErrorMessage`.
433
+ * - **Tự động Invalidate Cache**: Refresh tự động các query liên quan (như DataTable, Select) khi hoàn tất.
434
+ * - **Bổ sung `isLoading`**: Cung cấp alias `isLoading` cho `isPending`, thuận tiện khi code giao diện.
435
+ * - **Giữ trọn vẹn sức mạnh của TanStack Query**: Hỗ trợ đầy đủ `onMutate`, `onSuccess`, `onError`, `onSettled`.
436
+ */
437
+ declare function useMutationApp<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown>(options: UseMutationAppOptions<TData, TError, TVariables, TContext>): UseMutationAppReturn<TData, TError, TVariables, TContext>;
438
+
439
+ export { type InvalidateQueryTarget, type SelectQueryParams, type TableQueryParams, type UseMutationAppOptions, type UseMutationAppReturn, type UseMutationAppToastOptions, type UseSelectInfiniteQueryOptions, type UseSelectInfiniteQueryReturn, type UseTableQueryOptions, type UseTableQueryReturn, extractErrorMessage, useMutationApp, useSelectInfiniteQuery, useTableQuery };
package/dist/query.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { QueryFunctionContext, UseQueryOptions, UseQueryResult, UseInfiniteQueryOptions, InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
1
+ import { QueryFunctionContext, UseQueryOptions, UseQueryResult, UseInfiniteQueryOptions, InfiniteData, UseInfiniteQueryResult, QueryKey, InvalidateQueryFilters, DefaultError, UseMutationOptions, InvalidateOptions, UseMutationResult } from '@tanstack/react-query';
2
2
  import { RowData, SortingState, ColumnFiltersState, PaginationState, OnChangeFn } from '@tanstack/react-table';
3
3
  import { ReactNode } from 'react';
4
- import { b as SelectOptionItem, U as UseInfiniteScrollOptions } from './useInfiniteScroll-DAlgjUN4.js';
4
+ import { d as SelectOptionItem, U as UseInfiniteScrollOptions, a as ToastOptions, o as AlertVariant } from './useInfiniteScroll-C5t7bvLu.js';
5
+ import 'sonner';
5
6
  import '@floating-ui/react';
6
7
 
7
8
  /**
@@ -77,6 +78,12 @@ interface UseTableQueryOptions<TData extends RowData = RowData, TResponse = unkn
77
78
  * @default true
78
79
  */
79
80
  autoResetPageIndex?: boolean;
81
+ /**
82
+ * Thời gian trì hoãn debounce (ms) khi thay đổi bộ lọc hoặc tìm kiếm.
83
+ * Mặc định là 300ms. Đặt 0 để tắt debounce.
84
+ * @default 300
85
+ */
86
+ debounceMs?: number;
80
87
  /**
81
88
  * Các tùy chọn nâng cao truyền trực tiếp cho hook `useQuery` của TanStack Query
82
89
  * (ví dụ: `staleTime`, `gcTime`, `refetchOnWindowFocus`, `enabled`...).
@@ -99,6 +106,7 @@ interface UseTableQueryReturn<TData extends RowData = RowData, TResponse = unkno
99
106
  manualPagination: true;
100
107
  manualSorting: true;
101
108
  manualFiltering: true;
109
+ debounceMs?: number;
102
110
  pagination: PaginationState;
103
111
  onPaginationChange: OnChangeFn<PaginationState>;
104
112
  sorting: SortingState;
@@ -306,4 +314,126 @@ interface UseSelectInfiniteQueryReturn<TData = unknown, TResponse = unknown, TFi
306
314
  */
307
315
  declare function useSelectInfiniteQuery<TData = unknown, TResponse = unknown, TPageParam = number, TFilters extends Record<string, unknown> = Record<string, unknown>, TError = Error>({ queryKey, queryFn, initialPageParam, getNextPageParam, getPreviousPageParam, selectOptions, mapOption, debounceMs, initialSearch, initialFilters, initialOptions, skeletonLines, skeletonHeight, renderLoadingMore, endMessage, scrollOptions, queryOptions, }: UseSelectInfiniteQueryOptions<TData, TResponse, TPageParam, TFilters, TError>): UseSelectInfiniteQueryReturn<TData, TResponse, TFilters, TError>;
308
316
 
309
- export { type SelectQueryParams, type TableQueryParams, type UseSelectInfiniteQueryOptions, type UseSelectInfiniteQueryReturn, type UseTableQueryOptions, type UseTableQueryReturn, useSelectInfiniteQuery, useTableQuery };
317
+ /**
318
+ * Mục tiêu invalidate cache: có thể là QueryKey (readonly unknown[]) hoặc InvalidateQueryFilters.
319
+ */
320
+ type InvalidateQueryTarget = QueryKey | InvalidateQueryFilters;
321
+ /**
322
+ * Tùy chọn cấu hình Toast cho hook `useMutationApp`.
323
+ */
324
+ interface UseMutationAppToastOptions<TData, TError, TVariables> {
325
+ /**
326
+ * Nội dung thông báo khi đang thực thi mutation (loading spinner, không tự đóng).
327
+ * Có thể là ReactNode hoặc một hàm nhận vào `variables`.
328
+ */
329
+ loading?: ReactNode | ((variables: TVariables) => ReactNode);
330
+ /**
331
+ * Nội dung thông báo khi mutation hoàn tất thành công.
332
+ * Có thể là ReactNode hoặc một hàm nhận vào `(data, variables)`.
333
+ */
334
+ success?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
335
+ /**
336
+ * Tiêu đề thông báo khi mutation thất bại.
337
+ * - `true`: Hiển thị tiêu đề lỗi mặc định ("Đã xảy ra lỗi").
338
+ * - `false`: Không hiển thị toast lỗi.
339
+ * - `ReactNode`: Tiêu đề lỗi cố định.
340
+ * - `(error, variables) => ReactNode`: Hàm tạo tiêu đề lỗi linh hoạt.
341
+ * @default true
342
+ */
343
+ error?: boolean | ReactNode | ((error: TError, variables: TVariables) => ReactNode);
344
+ /**
345
+ * Nội dung mô tả chi tiết (description) cho thông báo khi đang loading.
346
+ */
347
+ loadingDescription?: ReactNode | ((variables: TVariables) => ReactNode);
348
+ /**
349
+ * Nội dung mô tả chi tiết (description) cho thông báo thành công.
350
+ */
351
+ successDescription?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
352
+ /**
353
+ * Nội dung mô tả chi tiết (description) cho thông báo lỗi.
354
+ * Nếu không truyền, tự động trích xuất thông điệp từ API/Error qua `extractErrorMessage`.
355
+ */
356
+ errorDescription?: ReactNode | ((error: TError, variables: TVariables) => ReactNode);
357
+ /**
358
+ * Tùy chọn cấu hình bổ sung cho Toast (duration, position, size, radius, closable...).
359
+ */
360
+ options?: ToastOptions;
361
+ /**
362
+ * Kiểu hiển thị Toast: "soft" | "solid" | "outline".
363
+ * @default "soft"
364
+ */
365
+ variant?: AlertVariant;
366
+ }
367
+ /**
368
+ * Các tùy chọn cấu hình cho hook `useMutationApp`.
369
+ */
370
+ interface UseMutationAppOptions<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends Omit<UseMutationOptions<TData, TError, TVariables, TContext>, "mutationFn"> {
371
+ /**
372
+ * Hàm gọi API hoặc thực hiện tác vụ bất đồng bộ.
373
+ */
374
+ mutationFn?: (variables: TVariables) => Promise<TData>;
375
+ /**
376
+ * Khóa truy vấn hoặc danh sách khóa truy vấn cần tự động làm mới (invalidate) khi mutation thành công.
377
+ * Hỗ trợ:
378
+ * - Một QueryKey đơn: `["teachers"]` hoặc `["users", 1]`
379
+ * - Danh sách nhiều QueryKey: `[["teachers"], ["classes"]]`
380
+ * - Bộ lọc nâng cao InvalidateQueryFilters: `{ queryKey: ["teachers"], exact: true }`
381
+ * - Danh sách bộ lọc: `[{ queryKey: ["teachers"] }, { queryKey: ["classes"] }]`
382
+ * - Hàm trả về động: `(data, variables) => [["teachers"], ["classes", variables.classId]]`
383
+ */
384
+ invalidateQueries?: InvalidateQueryTarget | InvalidateQueryTarget[] | ((data: TData, variables: TVariables) => InvalidateQueryTarget | InvalidateQueryTarget[] | void | null | undefined);
385
+ /**
386
+ * Tùy chọn InvalidateOptions bổ sung truyền cho `queryClient.invalidateQueries`
387
+ * (ví dụ: `throwOnError`, `cancelRefetch`).
388
+ */
389
+ invalidateOptions?: InvalidateOptions;
390
+ /**
391
+ * Cấu hình hiển thị thông báo Toast.
392
+ * - `false`: Tắt toàn bộ thông báo Toast.
393
+ * - `true`: Bật Toast với cấu hình mặc định (tự động báo lỗi nếu có).
394
+ * - `object`: Cấu hình chi tiết `loading`, `success`, `error`.
395
+ */
396
+ toast?: boolean | UseMutationAppToastOptions<TData, TError, TVariables>;
397
+ /**
398
+ * Shortcut cấu hình nhanh thông báo thành công.
399
+ */
400
+ successMessage?: ReactNode | ((data: TData, variables: TVariables) => ReactNode);
401
+ /**
402
+ * Shortcut cấu hình nhanh thông báo lỗi.
403
+ */
404
+ errorMessage?: ReactNode | ((error: TError, variables: TVariables) => ReactNode);
405
+ /**
406
+ * Shortcut cấu hình nhanh thông báo loading.
407
+ */
408
+ loadingMessage?: ReactNode | ((variables: TVariables) => ReactNode);
409
+ }
410
+ /**
411
+ * Kết quả trả về từ hook `useMutationApp`.
412
+ */
413
+ type UseMutationAppReturn<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> = UseMutationResult<TData, TError, TVariables, TContext> & {
414
+ /**
415
+ * Bí danh (alias) của `isPending`, tương thích ngược với thói quen sử dụng `isLoading` của TanStack Query v4.
416
+ */
417
+ isLoading: boolean;
418
+ };
419
+ /**
420
+ * Hàm hỗ trợ tự động trích xuất thông điệp lỗi (error message) từ nhiều định dạng lỗi phổ biến:
421
+ * - Axios Error response (`error.response?.data?.message`, `error.response?.data?.error`...)
422
+ * - Fetch API response / HTTP status
423
+ * - Standard JS Error (`error.message`)
424
+ * - String error
425
+ */
426
+ declare function extractErrorMessage(error: unknown, fallback?: string): string;
427
+ /**
428
+ * Hook `useMutationApp` - Tối ưu hóa tác vụ Mutation cho ứng dụng với TanStack Query v5 & `@openway/ui`.
429
+ *
430
+ * Tính năng chính:
431
+ * - **Tự động hóa Toast**: Hiển thị Toast loading khi xử lý, tự động cập nhật Toast success/error mượt mà.
432
+ * - **Tự động bóc tách lỗi**: Bóc tách thông điệp lỗi chính xác từ Axios / API response qua `extractErrorMessage`.
433
+ * - **Tự động Invalidate Cache**: Refresh tự động các query liên quan (như DataTable, Select) khi hoàn tất.
434
+ * - **Bổ sung `isLoading`**: Cung cấp alias `isLoading` cho `isPending`, thuận tiện khi code giao diện.
435
+ * - **Giữ trọn vẹn sức mạnh của TanStack Query**: Hỗ trợ đầy đủ `onMutate`, `onSuccess`, `onError`, `onSettled`.
436
+ */
437
+ declare function useMutationApp<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown>(options: UseMutationAppOptions<TData, TError, TVariables, TContext>): UseMutationAppReturn<TData, TError, TVariables, TContext>;
438
+
439
+ export { type InvalidateQueryTarget, type SelectQueryParams, type TableQueryParams, type UseMutationAppOptions, type UseMutationAppReturn, type UseMutationAppToastOptions, type UseSelectInfiniteQueryOptions, type UseSelectInfiniteQueryReturn, type UseTableQueryOptions, type UseTableQueryReturn, extractErrorMessage, useMutationApp, useSelectInfiniteQuery, useTableQuery };
package/dist/query.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import{c as J,g as W,l as j}from"./chunk-CJQNI3QX.js";import{useCallback as S,useMemo as N,useState as G}from"react";import{useQuery as $,keepPreviousData as ee}from"@tanstack/react-query";function te(n){if(!n)return[];if(Array.isArray(n))return n;if(typeof n=="object"){let e=n;if(Array.isArray(e.data))return e.data;if(Array.isArray(e.items))return e.items;if(Array.isArray(e.rows))return e.rows;if(Array.isArray(e.results))return e.results}return[]}function ne(n){if(!n)return 0;if(Array.isArray(n))return n.length;if(typeof n=="object"){let e=n,R=e.total??e.rowCount??e.totalCount??e.count;if(typeof R=="number")return R;if(typeof R=="string"){let m=Number(R);if(!isNaN(m))return m}}return 0}function B(n,e){return typeof n=="function"?n(e):n}function re(n){let{queryKey:e,queryFn:R,selectData:m=te,selectRowCount:q=ne,initialPagination:d,initialSorting:b,initialColumnFilters:k,initialGlobalFilter:x,autoResetPageIndex:g=!0,queryOptions:D}=n,[y,c]=G({pageIndex:d?.pageIndex??0,pageSize:d?.pageSize??j}),[h,w]=G(b??[]),[T,E]=G(k??[]),[C,Q]=G(x??""),P=N(()=>{let a={page:y.pageIndex+1,pageSize:y.pageSize},r=h[0];if(r&&(a.sortBy=r.id,a.sortOrder=r.desc?"desc":"asc"),T.length>0){let z={};T.forEach(Z=>{z[Z.id]=Z.value}),a.filters=z}return a},[y.pageIndex,y.pageSize,h,T]),v=N(()=>[...e,P],[e,P]),p=$({queryKey:v,queryFn:a=>R(P,a),placeholderData:ee,...D}),L=N(()=>p.data?m(p.data):[],[p.data,m]),o=N(()=>p.data?q(p.data):0,[p.data,q]),F=S(a=>{c(r=>B(a,r))},[]),I=S(a=>{w(r=>B(a,r)),g&&c(r=>r.pageIndex===0?r:{...r,pageIndex:0})},[g]),A=S(a=>{E(r=>B(a,r)),g&&c(r=>r.pageIndex===0?r:{...r,pageIndex:0})},[g]),O=S(a=>{Q(a),g&&c(r=>r.pageIndex===0?r:{...r,pageIndex:0})},[g]),M=S(()=>{c({pageIndex:d?.pageIndex??0,pageSize:d?.pageSize??j}),w(b??[]),E(k??[]),Q(x??"")},[d,b,k,x]),Y=S(a=>{c(r=>({...r,pageIndex:Math.max(0,a-1)}))},[]),s=S(a=>{c({pageIndex:0,pageSize:a})},[]),f=S(a=>{O(a)},[O]),{isLoading:i,isRefetching:l,refetch:t}=p,u=S(()=>{t()},[t]);return{tableProps:N(()=>({data:L,rowCount:o,isLoading:i,isRefresh:l&&!i,onRefresh:u,manualPagination:!0,manualSorting:!0,manualFiltering:!0,pagination:y,onPaginationChange:F,sorting:h,onSortingChange:I,columnFilters:T,onColumnFiltersChange:A,globalFilter:C,onGlobalFilterChange:O}),[L,o,i,l,u,y,F,h,I,T,A,C,O]),query:p,queryParams:P,resetAll:M,setPage:Y,setPageSize:s,setGlobalFilter:f,setSorting:w,setColumnFilters:E}}import{useCallback as H,useMemo as _,useState as X}from"react";import{useInfiniteQuery as ae}from"@tanstack/react-query";import{jsx as K}from"react/jsx-runtime";function V(n){if(!n)return[];if(Array.isArray(n))return n;if(typeof n!="object")return[];let e=n;return Array.isArray(e.data)?e.data:Array.isArray(e.items)?e.items:Array.isArray(e.options)?e.options:Array.isArray(e.results)?e.results:Array.isArray(e.rows)?e.rows:[]}var oe={};function se({queryKey:n,queryFn:e,initialPageParam:R=1,getNextPageParam:m,getPreviousPageParam:q,selectOptions:d,mapOption:b,debounceMs:k=300,initialSearch:x="",initialFilters:g=oe,initialOptions:D,skeletonLines:y=2,skeletonHeight:c="1.75rem",renderLoadingMore:h,endMessage:w,scrollOptions:T,queryOptions:E}){let[C,Q]=X(x),[P,v]=X(g),p=_(()=>[...n,{search:C,filters:P}],[n,C,P]),L=H((s,f,i,l)=>{if(m)return m(s,f,i,l);if(!s||typeof s!="object")return;let t=s;if(typeof t.nextPage=="number"||typeof t.nextPage=="string")return t.nextPage;if(typeof t.next_page=="number"||typeof t.next_page=="string")return t.next_page;if(typeof t.nextCursor=="string"||typeof t.nextCursor=="number")return t.nextCursor;if(typeof t.next_cursor=="string"||typeof t.next_cursor=="number")return t.next_cursor;if(!(t.hasMore===!1||t.has_more===!1||t.hasNextPage===!1)&&typeof i=="number"){if(V(s).length===0)return;let U=typeof t.total=="number"?t.total:typeof t.totalCount=="number"?t.totalCount:typeof t.count=="number"?t.count:void 0;return U!==void 0&&f.reduce((r,z)=>r+V(z).length,0)>=U?void 0:i+1}},[m]),o=ae({queryKey:p,queryFn:s=>e({pageParam:s.pageParam,search:C,filters:P},s),initialPageParam:R,getNextPageParam:L,getPreviousPageParam:q,...E}),F=_(()=>{let s=o.data?.pages??[],f=[],i=new Set;if(D&&D.length>0)for(let l of D)i.has(l.value)||(i.add(l.value),f.push(l));for(let l of s){let t=[];if(d)t=d(l);else{let u=V(l);b?t=u.map((U,a)=>b(U,a)):t=u}for(let u of t)u&&u.value!==void 0&&!i.has(u.value)&&(i.add(u.value),f.push(u))}return f},[o.data?.pages,d,b,D]),{sentinelRef:I}=J({onLoadMore:()=>{o.hasNextPage&&!o.isFetchingNextPage&&o.fetchNextPage()},hasMore:!!o.hasNextPage,isLoading:o.isFetchingNextPage||o.isLoading,disabled:o.isError,rootMargin:T?.rootMargin??"80px",threshold:T?.threshold??0,root:T?.root}),A=H((s,f)=>{Q(s),v(f)},[]),O=H(()=>{Q(x),v(g)},[x,g]),M=_(()=>F.length===0?null:o.isFetchingNextPage?K("div",{ref:I,className:"p-1 space-y-1 w-full",children:h?h():K(W,{lines:y,height:c,gap:"0.25rem",radius:"sm",className:"p-0.5"})}):o.hasNextPage?K("div",{ref:I,className:"h-1 w-full","aria-hidden":"true"}):w?K("div",{className:"py-2 px-1 text-center text-xs text-neutral-400 dark:text-neutral-500",children:w}):null,[F.length,o.isFetchingNextPage,o.hasNextPage,I,h,y,c,w]);return{selectProps:_(()=>({options:F,isLoading:o.isLoading,searchMode:"server",debounceMs:k,onSearch:A,listFooter:M}),[F,o.isLoading,k,A,M]),query:o,options:F,search:C,setSearch:Q,filters:P,setFilters:v,sentinelRef:I,reset:O}}export{se as useSelectInfiniteQuery,re as useTableQuery};
2
+ import{m as q,n as ne,o as re,s as ae,x as H}from"./chunk-XM7AABEU.js";import{useCallback as N,useMemo as z,useState as j}from"react";import{useQuery as ue,keepPreviousData as le}from"@tanstack/react-query";function ce(e){if(!e)return[];if(Array.isArray(e))return e;if(typeof e=="object"){let t=e;if(Array.isArray(t.data))return t.data;if(Array.isArray(t.items))return t.items;if(Array.isArray(t.rows))return t.rows;if(Array.isArray(t.results))return t.results}return[]}function pe(e){if(!e)return 0;if(Array.isArray(e))return e.length;if(typeof e=="object"){let t=e,a=t.total??t.rowCount??t.totalCount??t.count;if(typeof a=="number")return a;if(typeof a=="string"){let s=Number(a);if(!isNaN(s))return s}}return 0}function Z(e,t){return typeof e=="function"?e(t):e}function ge(e){let{queryKey:t,queryFn:a,selectData:s=ce,selectRowCount:S=pe,initialPagination:r,initialSorting:p,initialColumnFilters:x,initialGlobalFilter:A,autoResetPageIndex:D=!0,debounceMs:w=300,queryOptions:M}=e,[F,y]=j({pageIndex:r?.pageIndex??0,pageSize:r?.pageSize??H}),[Q,v]=j(p??[]),[i,P]=j(x??[]),[C,b]=j(A??""),[O,U]=j(i.length),V=i.length<O;i.length!==O&&U(i.length);let n=i.length===0||V?0:w,l=ne(i,n),g=z(()=>{let f={page:F.pageIndex+1,pageSize:F.pageSize},u=Q[0];if(u&&(f.sortBy=u.id,f.sortOrder=u.desc?"desc":"asc"),l.length>0){let ee={};l.forEach(te=>{ee[te.id]=te.value}),f.filters=ee}return f},[F.pageIndex,F.pageSize,Q,l]),T=z(()=>[...t,g],[t,g]),c=ue({queryKey:T,queryFn:f=>a(g,f),placeholderData:le,...M}),m=z(()=>c.data?s(c.data):[],[c.data,s]),I=z(()=>c.data?S(c.data):0,[c.data,S]),d=N(f=>{y(u=>Z(f,u))},[]),h=N(f=>{v(u=>Z(f,u)),D&&y(u=>u.pageIndex===0?u:{...u,pageIndex:0})},[D]),k=N(f=>{P(u=>Z(f,u)),D&&y(u=>u.pageIndex===0?u:{...u,pageIndex:0})},[D]),R=N(f=>{b(f),D&&y(u=>u.pageIndex===0?u:{...u,pageIndex:0})},[D]),o=N(()=>{y({pageIndex:r?.pageIndex??0,pageSize:r?.pageSize??H}),v(p??[]),P(x??[]),b(A??"")},[r,p,x,A]),E=N(f=>{y(u=>({...u,pageIndex:Math.max(0,f-1)}))},[]),L=N(f=>{y({pageIndex:0,pageSize:f})},[]),_=N(f=>{R(f)},[R]),{isLoading:K,isRefetching:G,refetch:X}=c,$=N(()=>{X()},[X]);return{tableProps:z(()=>({data:m,rowCount:I,isLoading:K,isRefresh:G&&!K,onRefresh:$,manualPagination:!0,manualSorting:!0,manualFiltering:!0,debounceMs:w,pagination:F,onPaginationChange:d,sorting:Q,onSortingChange:h,columnFilters:i,onColumnFiltersChange:k,globalFilter:C,onGlobalFilterChange:R}),[m,I,K,G,$,w,F,d,Q,h,i,k,C,R]),query:c,queryParams:g,resetAll:o,setPage:E,setPageSize:L,setGlobalFilter:_,setSorting:v,setColumnFilters:P}}import{useCallback as J,useMemo as B,useState as oe}from"react";import{useInfiniteQuery as fe}from"@tanstack/react-query";import{jsx as Y}from"react/jsx-runtime";function W(e){if(!e)return[];if(Array.isArray(e))return e;if(typeof e!="object")return[];let t=e;return Array.isArray(t.data)?t.data:Array.isArray(t.items)?t.items:Array.isArray(t.options)?t.options:Array.isArray(t.results)?t.results:Array.isArray(t.rows)?t.rows:[]}var de={};function ye({queryKey:e,queryFn:t,initialPageParam:a=1,getNextPageParam:s,getPreviousPageParam:S,selectOptions:r,mapOption:p,debounceMs:x=300,initialSearch:A="",initialFilters:D=de,initialOptions:w,skeletonLines:M=2,skeletonHeight:F="1.75rem",renderLoadingMore:y,endMessage:Q,scrollOptions:v,queryOptions:i}){let[P,C]=oe(A),[b,O]=oe(D),U=B(()=>[...e,{search:P,filters:b}],[e,P,b]),V=J((d,h,k,R)=>{if(s)return s(d,h,k,R);if(!d||typeof d!="object")return;let o=d;if(typeof o.nextPage=="number"||typeof o.nextPage=="string")return o.nextPage;if(typeof o.next_page=="number"||typeof o.next_page=="string")return o.next_page;if(typeof o.nextCursor=="string"||typeof o.nextCursor=="number")return o.nextCursor;if(typeof o.next_cursor=="string"||typeof o.next_cursor=="number")return o.next_cursor;if(!(o.hasMore===!1||o.has_more===!1||o.hasNextPage===!1)&&typeof k=="number"){if(W(d).length===0)return;let L=typeof o.total=="number"?o.total:typeof o.totalCount=="number"?o.totalCount:typeof o.count=="number"?o.count:void 0;return L!==void 0&&h.reduce((K,G)=>K+W(G).length,0)>=L?void 0:k+1}},[s]),n=fe({queryKey:U,queryFn:d=>t({pageParam:d.pageParam,search:P,filters:b},d),initialPageParam:a,getNextPageParam:V,getPreviousPageParam:S,...i}),l=B(()=>{let d=n.data?.pages??[],h=[],k=new Set;if(w&&w.length>0)for(let R of w)k.has(R.value)||(k.add(R.value),h.push(R));for(let R of d){let o=[];if(r)o=r(R);else{let E=W(R);p?o=E.map((L,_)=>p(L,_)):o=E}for(let E of o)E&&E.value!==void 0&&!k.has(E.value)&&(k.add(E.value),h.push(E))}return h},[n.data?.pages,r,p,w]),{sentinelRef:g}=re({onLoadMore:()=>{n.hasNextPage&&!n.isFetchingNextPage&&n.fetchNextPage()},hasMore:!!n.hasNextPage,isLoading:n.isFetchingNextPage||n.isLoading,disabled:n.isError,rootMargin:v?.rootMargin??"80px",threshold:v?.threshold??0,root:v?.root}),T=J((d,h)=>{C(d),O(h)},[]),c=J(()=>{C(A),O(D)},[A,D]),m=B(()=>l.length===0?null:n.isFetchingNextPage?Y("div",{ref:g,className:"p-1 space-y-1 w-full",children:y?y():Y(ae,{lines:M,height:F,gap:"0.25rem",radius:"sm",className:"p-0.5"})}):n.hasNextPage?Y("div",{ref:g,className:"h-1 w-full","aria-hidden":"true"}):Q?Y("div",{className:"py-2 px-1 text-center text-xs text-neutral-400",children:Q}):null,[l.length,n.isFetchingNextPage,n.hasNextPage,g,y,M,F,Q]);return{selectProps:B(()=>({options:l,isLoading:n.isLoading,searchMode:"server",debounceMs:x,onSearch:T,listFooter:m}),[l,n.isLoading,x,T,m]),query:n,options:l,search:P,setSearch:C,filters:b,setFilters:O,sentinelRef:g,reset:c}}import{useRef as Te}from"react";import{useMutation as me,useQueryClient as Pe}from"@tanstack/react-query";function se(e,t="\u0110\xE3 x\u1EA3y ra l\u1ED7i. Vui l\xF2ng th\u1EED l\u1EA1i sau."){if(!e)return t;if(typeof e=="string"&&e.trim())return e;if(typeof e=="object"&&e!==null){let a=e;if(a.response&&typeof a.response=="object"&&a.response!==null){let s=a.response,S=typeof s.status=="number"?s.status:void 0;if(s.data&&typeof s.data=="object"&&s.data!==null){let r=s.data;if(typeof r.message=="string"&&r.message.trim())return r.message;if(typeof r.error=="string"&&r.error.trim())return r.error;if(typeof r.detail=="string"&&r.detail.trim())return r.detail;if(typeof r.title=="string"&&r.title.trim())return r.title;if(Array.isArray(r.message)&&r.message.length>0){let p=r.message[0];if(typeof p=="string")return p}if(Array.isArray(r.errors)&&r.errors.length>0){let p=r.errors[0];if(typeof p=="string")return p;if(typeof p=="object"&&p!==null){let x=p;if(typeof x.message=="string"&&x.message.trim())return x.message}}}if(S)switch(S){case 400:return"D\u1EEF li\u1EC7u y\xEAu c\u1EA7u kh\xF4ng h\u1EE3p l\u1EC7 (400).";case 401:return"Phi\xEAn l\xE0m vi\u1EC7c \u0111\xE3 h\u1EBFt h\u1EA1n ho\u1EB7c ch\u01B0a \u0111\u0103ng nh\u1EADp (401).";case 403:return"B\u1EA1n kh\xF4ng c\xF3 quy\u1EC1n th\u1EF1c hi\u1EC7n thao t\xE1c n\xE0y (403).";case 404:return"Kh\xF4ng t\xECm th\u1EA5y d\u1EEF li\u1EC7u y\xEAu c\u1EA7u (404).";case 409:return"D\u1EEF li\u1EC7u b\u1ECB tr\xF9ng l\u1EB7p ho\u1EB7c xung \u0111\u1ED9t (409).";case 422:return"D\u1EEF li\u1EC7u g\u1EEDi l\xEAn kh\xF4ng \u0111\xFAng \u0111\u1ECBnh d\u1EA1ng (422).";case 500:return"L\u1ED7i m\xE1y ch\u1EE7 n\u1ED9i b\u1ED9. Vui l\xF2ng th\u1EED l\u1EA1i sau (500).";case 502:case 503:case 504:return"Kh\xF4ng th\u1EC3 k\u1EBFt n\u1ED1i \u0111\u1EBFn m\xE1y ch\u1EE7. Vui l\xF2ng th\u1EED l\u1EA1i sau."}}if(typeof a.message=="string"&&a.message.trim())return a.message;if(typeof a.error=="string"&&a.error.trim())return a.error;if(typeof a.detail=="string"&&a.detail.trim())return a.detail}return t}function be(e,t){return e?Array.isArray(e)?e.length===0?[]:e.every(s=>Array.isArray(s)||typeof s=="object"&&s!==null&&"queryKey"in s)?e.map(s=>Array.isArray(s)?{filters:{queryKey:s},options:t}:{filters:s,options:t}):[{filters:{queryKey:e},options:t}]:typeof e=="object"&&e!==null&&"queryKey"in e?[{filters:e,options:t}]:[]:[]}function he(e){let t=Pe(),a=Te([]),{mutationFn:s,invalidateQueries:S,invalidateOptions:r,toast:p=!0,successMessage:x,errorMessage:A,loadingMessage:D,onMutate:w,onSuccess:M,onError:F,onSettled:y,...Q}=e,v=p!==!1,i=typeof p=="object"&&p!==null?{...p}:{},P=D??i.loading,C=x??i.success,b=A??i.error??!0,O=i.variant??"soft",U=i.options,V=me({...Q,mutationFn:s,onMutate:async(n,l)=>{let g;if(v&&P){let T=typeof P=="function"?P(n):P,c=typeof i.loadingDescription=="function"?i.loadingDescription(n):i.loadingDescription;g=q.loading(T,c,{...U,variant:O}),a.current.push(g)}try{if(w)return await w(n,l)}catch(T){throw g&&(q.dismiss(g),a.current=a.current.filter(c=>c!==g)),T}},onSuccess:async(n,l,g,T)=>{let c=a.current.shift();if(c&&q.dismiss(c),v&&C){let m=typeof C=="function"?C(n,l):C,I=typeof i.successDescription=="function"?i.successDescription(n,l):i.successDescription;q.success(m,I,{...U,variant:O})}if(S){let m=typeof S=="function"?S(n,l):S,I=be(m,r);I.length>0&&await Promise.all(I.map(({filters:d,options:h})=>t.invalidateQueries(d,h)))}M&&await M(n,l,g,T)},onError:async(n,l,g,T)=>{let c=a.current.shift();if(c&&q.dismiss(c),v&&b!==!1){let m;typeof b=="function"?m=b(n,l):b===!0?m="\u0110\xE3 x\u1EA3y ra l\u1ED7i":m=b;let I=typeof i.errorDescription=="function"?i.errorDescription(n,l):i.errorDescription,d=I!==void 0?I||void 0:se(n);q.error(m,d,{...U,variant:O})}F&&await F(n,l,g,T)},onSettled:async(n,l,g,T,c)=>{y&&await y(n,l,g,T,c)}});return{...V,isLoading:V.isPending}}export{se as extractErrorMessage,he as useMutationApp,ye as useSelectInfiniteQuery,ge as useTableQuery};
3
3
  //# sourceMappingURL=query.js.map