@m5kdev/frontend 0.20.51 → 0.21.0
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/src/index.d.mts +25 -0
- package/dist/src/index.d.ts +25 -0
- package/dist/src/index.js +83 -0
- package/dist/src/index.mjs +25 -0
- package/dist/src/modules/auth/auth.client.d.mts +708 -0
- package/dist/src/modules/auth/auth.client.d.mts.map +1 -0
- package/dist/src/modules/auth/auth.client.d.ts +708 -0
- package/dist/src/modules/auth/auth.client.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.client.js +72 -0
- package/dist/src/modules/auth/auth.client.js.map +1 -0
- package/dist/src/modules/auth/auth.client.mjs +71 -0
- package/dist/src/modules/auth/auth.client.mjs.map +1 -0
- package/dist/src/modules/auth/auth.context.d.mts +15 -0
- package/dist/src/modules/auth/auth.context.d.mts.map +1 -0
- package/dist/src/modules/auth/auth.context.d.ts +15 -0
- package/dist/src/modules/auth/auth.context.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.context.js +13 -0
- package/dist/src/modules/auth/auth.context.js.map +1 -0
- package/dist/src/modules/auth/auth.context.mjs +13 -0
- package/dist/src/modules/auth/auth.context.mjs.map +1 -0
- package/dist/src/modules/auth/auth.lib.d.mts +1251 -1380
- package/dist/src/modules/auth/auth.lib.d.mts.map +1 -1
- package/dist/src/modules/auth/auth.lib.d.ts +1251 -1380
- package/dist/src/modules/auth/auth.lib.d.ts.map +1 -1
- package/dist/src/modules/auth/auth.lib.js +18 -63
- package/dist/src/modules/auth/auth.lib.js.map +1 -1
- package/dist/src/modules/auth/auth.lib.mjs +10 -64
- package/dist/src/modules/auth/auth.lib.mjs.map +1 -1
- package/dist/src/modules/auth/components/AuthProvider.d.mts +9 -10
- package/dist/src/modules/auth/components/AuthProvider.d.mts.map +1 -1
- package/dist/src/modules/auth/components/AuthProvider.d.ts +9 -10
- package/dist/src/modules/auth/components/AuthProvider.d.ts.map +1 -1
- package/dist/src/modules/auth/components/AuthProvider.js +20 -42
- package/dist/src/modules/auth/components/AuthProvider.js.map +1 -1
- package/dist/src/modules/auth/components/AuthProvider.mjs +22 -43
- package/dist/src/modules/auth/components/AuthProvider.mjs.map +1 -1
- package/dist/src/modules/auth/hooks/useAuth.d.mts.map +1 -1
- package/dist/src/modules/auth/hooks/useAuth.d.ts.map +1 -1
- package/dist/src/modules/auth/hooks/useAuth.js +5 -3
- package/dist/src/modules/auth/hooks/useAuth.js.map +1 -1
- package/dist/src/modules/auth/hooks/useAuth.mjs +3 -1
- package/dist/src/modules/auth/hooks/useAuth.mjs.map +1 -1
- package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts +10 -19
- package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts.map +1 -1
- package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts +10 -19
- package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts.map +1 -1
- package/dist/src/modules/auth/hooks/useAuthAdmin.js +20 -12
- package/dist/src/modules/auth/hooks/useAuthAdmin.js.map +1 -1
- package/dist/src/modules/auth/hooks/useAuthAdmin.mjs +14 -6
- package/dist/src/modules/auth/hooks/useAuthAdmin.mjs.map +1 -1
- package/dist/src/modules/auth/hooks/useAuthClient.d.mts +707 -0
- package/dist/src/modules/auth/hooks/useAuthClient.d.mts.map +1 -0
- package/dist/src/modules/auth/hooks/useAuthClient.d.ts +707 -0
- package/dist/src/modules/auth/hooks/useAuthClient.d.ts.map +1 -0
- package/dist/src/modules/auth/hooks/useAuthClient.js +12 -0
- package/dist/src/modules/auth/hooks/useAuthClient.js.map +1 -0
- package/dist/src/modules/auth/hooks/useAuthClient.mjs +11 -0
- package/dist/src/modules/auth/hooks/useAuthClient.mjs.map +1 -0
- package/dist/src/modules/auth/hooks/useMemberInvite.js +3 -2
- package/dist/src/modules/auth/hooks/useMemberInvite.js.map +1 -1
- package/dist/src/modules/auth/hooks/useMemberInvite.mjs +2 -1
- package/dist/src/modules/auth/hooks/useMemberInvite.mjs.map +1 -1
- package/dist/src/modules/auth/hooks/useOrganizationAccess.d.mts +1 -1
- package/dist/src/modules/auth/hooks/useOrganizationAccess.d.ts +1 -1
- package/dist/src/modules/auth/hooks/useSession.d.mts +4 -37
- package/dist/src/modules/auth/hooks/useSession.d.mts.map +1 -1
- package/dist/src/modules/auth/hooks/useSession.d.ts +4 -37
- package/dist/src/modules/auth/hooks/useSession.d.ts.map +1 -1
- package/dist/src/modules/auth/hooks/useSession.js +3 -2
- package/dist/src/modules/auth/hooks/useSession.js.map +1 -1
- package/dist/src/modules/auth/hooks/useSession.mjs +3 -2
- package/dist/src/modules/auth/hooks/useSession.mjs.map +1 -1
- package/dist/src/modules/billing/components/BillingProvider.d.mts +1 -1
- package/dist/src/modules/billing/components/BillingProvider.d.mts.map +1 -1
- package/dist/src/modules/billing/components/BillingProvider.d.ts +1 -1
- package/dist/src/modules/billing/components/BillingProvider.d.ts.map +1 -1
- package/dist/src/modules/file/hooks/useS3Upload.d.mts +15 -2
- package/dist/src/modules/file/hooks/useS3Upload.d.mts.map +1 -1
- package/dist/src/modules/file/hooks/useS3Upload.d.ts +15 -2
- package/dist/src/modules/file/hooks/useS3Upload.d.ts.map +1 -1
- package/dist/src/modules/file/hooks/useS3Upload.js +29 -4
- package/dist/src/modules/file/hooks/useS3Upload.js.map +1 -1
- package/dist/src/modules/file/hooks/useS3Upload.mjs +29 -5
- package/dist/src/modules/file/hooks/useS3Upload.mjs.map +1 -1
- package/dist/src/modules/file/hooks/useUpload.d.mts +6 -4
- package/dist/src/modules/file/hooks/useUpload.d.mts.map +1 -1
- package/dist/src/modules/file/hooks/useUpload.d.ts +6 -4
- package/dist/src/modules/file/hooks/useUpload.d.ts.map +1 -1
- package/dist/src/modules/file/hooks/useUpload.js +10 -7
- package/dist/src/modules/file/hooks/useUpload.js.map +1 -1
- package/dist/src/modules/file/hooks/useUpload.mjs +10 -7
- package/dist/src/modules/file/hooks/useUpload.mjs.map +1 -1
- package/dist/src/modules/table/hooks/useQueryWithParams.d.mts +2 -2
- package/dist/src/modules/table/hooks/useQueryWithParams.d.mts.map +1 -1
- package/dist/src/modules/table/hooks/useQueryWithParams.d.ts +2 -2
- package/dist/src/modules/table/hooks/useQueryWithParams.d.ts.map +1 -1
- package/dist/src/modules/table/hooks/useQueryWithParams.js.map +1 -1
- package/dist/src/modules/table/hooks/useQueryWithParams.mjs.map +1 -1
- package/dist/src/modules/table/hooks/useTableQueryParams.d.mts +7 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.d.mts.map +1 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.d.ts +7 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.d.ts.map +1 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.js +95 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.js.map +1 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.mjs +94 -0
- package/dist/src/modules/table/hooks/useTableQueryParams.mjs.map +1 -0
- package/dist/src/modules/table/queryParams.d.mts +34 -0
- package/dist/src/modules/table/queryParams.d.mts.map +1 -0
- package/dist/src/modules/table/queryParams.d.ts +34 -0
- package/dist/src/modules/table/queryParams.d.ts.map +1 -0
- package/dist/src/modules/table/{hooks/useNuqsQueryParams.js → queryParams.js} +14 -130
- package/dist/src/modules/table/queryParams.js.map +1 -0
- package/dist/src/modules/table/{hooks/useNuqsQueryParams.mjs → queryParams.mjs} +10 -130
- package/dist/src/modules/table/queryParams.mjs.map +1 -0
- package/dist/src/utils/date.d.mts +1 -1
- package/package.json +24 -6
- package/dist/src/modules/table/hooks/useDateRangeFilter.d.mts +0 -34
- package/dist/src/modules/table/hooks/useDateRangeFilter.d.mts.map +0 -1
- package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts +0 -34
- package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts.map +0 -1
- package/dist/src/modules/table/hooks/useDateRangeFilter.js +0 -30
- package/dist/src/modules/table/hooks/useDateRangeFilter.js.map +0 -1
- package/dist/src/modules/table/hooks/useDateRangeFilter.mjs +0 -29
- package/dist/src/modules/table/hooks/useDateRangeFilter.mjs.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsQueryParams.d.mts +0 -34
- package/dist/src/modules/table/hooks/useNuqsQueryParams.d.mts.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts +0 -34
- package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsQueryParams.js.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsQueryParams.mjs.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsTable.d.mts +0 -46
- package/dist/src/modules/table/hooks/useNuqsTable.d.mts.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsTable.d.ts +0 -46
- package/dist/src/modules/table/hooks/useNuqsTable.d.ts.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsTable.js +0 -58
- package/dist/src/modules/table/hooks/useNuqsTable.js.map +0 -1
- package/dist/src/modules/table/hooks/useNuqsTable.mjs +0 -58
- package/dist/src/modules/table/hooks/useNuqsTable.mjs.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { QueryFilter, QueryFilters } from "@m5kdev/commons/modules/schemas/query.schema";
|
|
2
|
+
import { GroupingState, PaginationState, SortingState, Updater } from "@tanstack/react-table";
|
|
3
|
+
|
|
4
|
+
//#region src/modules/table/queryParams.d.ts
|
|
5
|
+
declare function serializeFiltersParam(rows: string[][]): string;
|
|
6
|
+
declare function parseFiltersParam(value: string): string[][] | null;
|
|
7
|
+
/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
|
|
8
|
+
declare function encodeFilterToTuple(filter: QueryFilter): string[];
|
|
9
|
+
declare function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null;
|
|
10
|
+
declare function decodeFilterTuples(rows: readonly string[][]): QueryFilters;
|
|
11
|
+
type Order = "asc" | "desc";
|
|
12
|
+
type Granularity = "daily" | "weekly" | "monthly" | "yearly";
|
|
13
|
+
interface QueryParamsState {
|
|
14
|
+
/** Global search string; absent when not set. */
|
|
15
|
+
q: string | null;
|
|
16
|
+
setQ: (value: string | null) => void;
|
|
17
|
+
filters?: QueryFilters;
|
|
18
|
+
setFilters?: (filters: QueryFilters) => void;
|
|
19
|
+
granularity?: Granularity;
|
|
20
|
+
setGranularity?: (value: Granularity) => void;
|
|
21
|
+
sort?: string;
|
|
22
|
+
order?: Order | null;
|
|
23
|
+
setSorting?: (updater: Updater<SortingState>) => void;
|
|
24
|
+
sorting?: SortingState;
|
|
25
|
+
page?: number;
|
|
26
|
+
limit?: number;
|
|
27
|
+
setPagination?: (updater: Updater<PaginationState>) => void;
|
|
28
|
+
pagination?: PaginationState;
|
|
29
|
+
grouping: GroupingState;
|
|
30
|
+
setGrouping: (updater: Updater<GroupingState>) => void;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { Granularity, Order, QueryParamsState, decodeFilterTuples, decodeTupleToFilter, encodeFilterToTuple, parseFiltersParam, serializeFiltersParam };
|
|
34
|
+
//# sourceMappingURL=queryParams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryParams.d.ts","names":[],"sources":["../../../../src/modules/table/queryParams.ts"],"mappings":";;;;iBAyDgB,qBAAA,CAAsB,IAAA;AAAA,iBAOtB,iBAAA,CAAkB,KAAA;AAPlC;AAAA,iBAoGgB,mBAAA,CAAoB,MAAA,EAAQ,WAAA;AAAA,iBAmB5B,mBAAA,CAAoB,KAAA,sBAA2B,WAAA;AAAA,iBAmC/C,kBAAA,CAAmB,IAAA,wBAA4B,YAAA;AAAA,KAQnD,KAAA;AAAA,KAEA,WAAA;AAAA,UAEK,gBAAA;;EAEf,CAAA;EACA,IAAA,GAAO,KAAA;EACP,OAAA,GAAU,YAAA;EACV,UAAA,IAAc,OAAA,EAAS,YAAA;EACvB,WAAA,GAAc,WAAA;EACd,cAAA,IAAkB,KAAA,EAAO,WAAA;EACzB,IAAA;EACA,KAAA,GAAQ,KAAA;EACR,UAAA,IAAc,OAAA,EAAS,OAAA,CAAQ,YAAA;EAC/B,OAAA,GAAU,YAAA;EACV,IAAA;EACA,KAAA;EACA,aAAA,IAAiB,OAAA,EAAS,OAAA,CAAQ,eAAA;EAClC,UAAA,GAAa,eAAA;EACb,QAAA,EAAU,aAAA;EACV,WAAA,GAAc,OAAA,EAAS,OAAA,CAAQ,aAAA;AAAA"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let react = require("react");
|
|
3
2
|
let _m5kdev_commons_modules_schemas_query_schema = require("@m5kdev/commons/modules/schemas/query.schema");
|
|
4
|
-
let nuqs = require("nuqs");
|
|
5
3
|
let zod = require("zod");
|
|
6
|
-
//#region src/modules/table/
|
|
7
|
-
/** Each row: [columnId, type, method, value, valueTo?, endColumnId?]
|
|
4
|
+
//#region src/modules/table/queryParams.ts
|
|
5
|
+
/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */
|
|
8
6
|
const filtersRawSchema = zod.z.array(zod.z.array(zod.z.string()).min(4).max(6));
|
|
9
7
|
/** Escape `\`, `|`, `;` so we can split filters without JSON quotes/brackets. */
|
|
10
8
|
function escapeFilterField(raw) {
|
|
@@ -67,12 +65,6 @@ function parseFiltersParam(value) {
|
|
|
67
65
|
const parsed = filtersRawSchema.safeParse(rows);
|
|
68
66
|
return parsed.success ? parsed.data : null;
|
|
69
67
|
}
|
|
70
|
-
const parseAsFilterTuples = (0, nuqs.createParser)({
|
|
71
|
-
parse: (value) => parseFiltersParam(value),
|
|
72
|
-
serialize: (rows) => serializeFiltersParam(rows),
|
|
73
|
-
eq: (a, b) => JSON.stringify(a) === JSON.stringify(b)
|
|
74
|
-
}).withDefault([]);
|
|
75
|
-
const parseAsGrouping = (0, nuqs.parseAsArrayOf)(nuqs.parseAsString).withDefault([]);
|
|
76
68
|
const NULLISH_METHODS = new Set([
|
|
77
69
|
"isEmpty",
|
|
78
70
|
"isNotEmpty",
|
|
@@ -117,7 +109,7 @@ function decodeFilterValue(type, method, valueStr) {
|
|
|
117
109
|
default: return valueStr;
|
|
118
110
|
}
|
|
119
111
|
}
|
|
120
|
-
/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot
|
|
112
|
+
/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
|
|
121
113
|
function encodeFilterToTuple(filter) {
|
|
122
114
|
const tuple = [
|
|
123
115
|
filter.columnId,
|
|
@@ -153,124 +145,16 @@ function decodeTupleToFilter(parts) {
|
|
|
153
145
|
const parsed = _m5kdev_commons_modules_schemas_query_schema.filterSchema.safeParse(candidate);
|
|
154
146
|
return parsed.success ? parsed.data : null;
|
|
155
147
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const useNuqsQueryParams = (prefix) => {
|
|
162
|
-
const k = (name) => prefix ? `${prefix}_${name}` : name;
|
|
163
|
-
const [sort, setSort] = (0, nuqs.useQueryState)(k("s"), nuqs.parseAsString.withDefault(""));
|
|
164
|
-
const [order, setOrder] = (0, nuqs.useQueryState)(k("o"), (0, nuqs.parseAsStringLiteral)(["asc", "desc"]));
|
|
165
|
-
const [page, setPage] = (0, nuqs.useQueryState)(k("p"), nuqs.parseAsInteger.withDefault(1));
|
|
166
|
-
const [limit, setLimit] = (0, nuqs.useQueryState)(k("l"), nuqs.parseAsInteger.withDefault(10));
|
|
167
|
-
const [qRaw, setQRaw] = (0, nuqs.useQueryState)(k("q"), nuqs.parseAsString);
|
|
168
|
-
const [filtersRaw, setFiltersRaw] = (0, nuqs.useQueryState)(k("f"), parseAsFilterTuples);
|
|
169
|
-
const filters = (0, react.useMemo)(() => {
|
|
170
|
-
const decoded = filtersRaw.map((row) => decodeTupleToFilter(row)).filter((f) => f != null);
|
|
171
|
-
const parsed = _m5kdev_commons_modules_schemas_query_schema.filtersSchema.safeParse(decoded);
|
|
172
|
-
return parsed.success ? parsed.data : [];
|
|
173
|
-
}, [filtersRaw]);
|
|
174
|
-
const setFilters = (0, react.useCallback)((next) => {
|
|
175
|
-
setFiltersRaw(next.length === 0 ? null : next.map(encodeFilterToTuple));
|
|
176
|
-
}, [setFiltersRaw]);
|
|
177
|
-
const setQ = (0, react.useCallback)((value) => {
|
|
178
|
-
setQRaw(value === "" || value == null ? null : value);
|
|
179
|
-
}, [setQRaw]);
|
|
180
|
-
const [granularity, setGranularity] = (0, nuqs.useQueryState)(k("r"), (0, nuqs.parseAsStringLiteral)([
|
|
181
|
-
"daily",
|
|
182
|
-
"weekly",
|
|
183
|
-
"monthly",
|
|
184
|
-
"yearly"
|
|
185
|
-
]).withDefault("daily"));
|
|
186
|
-
const [groupingRaw, setGroupingRaw] = (0, nuqs.useQueryState)(k("g"), parseAsGrouping);
|
|
187
|
-
const grouping = groupingRaw;
|
|
188
|
-
const setGrouping = (0, react.useCallback)((updater) => {
|
|
189
|
-
const next = typeof updater === "function" ? updater(groupingRaw) : updater;
|
|
190
|
-
setGroupingRaw(next.length > 0 ? next : null);
|
|
191
|
-
}, [groupingRaw, setGroupingRaw]);
|
|
192
|
-
const sorting = (0, react.useMemo)(() => {
|
|
193
|
-
if (!sort) return [];
|
|
194
|
-
return [{
|
|
195
|
-
id: sort,
|
|
196
|
-
desc: (order ?? "asc") === "desc"
|
|
197
|
-
}];
|
|
198
|
-
}, [sort, order]);
|
|
199
|
-
const pagination = (0, react.useMemo)(() => ({
|
|
200
|
-
pageIndex: page - 1,
|
|
201
|
-
pageSize: limit
|
|
202
|
-
}), [page, limit]);
|
|
203
|
-
const setSorting = (0, react.useCallback)((updater) => {
|
|
204
|
-
const first = (typeof updater === "function" ? updater(sort ? [{
|
|
205
|
-
id: sort,
|
|
206
|
-
desc: (order ?? "asc") === "desc"
|
|
207
|
-
}] : []) : updater)[0];
|
|
208
|
-
if (!first || !first.id) {
|
|
209
|
-
setSort("");
|
|
210
|
-
setOrder(null);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
setSort(first.id);
|
|
214
|
-
setOrder(first.desc ? "desc" : "asc");
|
|
215
|
-
}, [
|
|
216
|
-
sort,
|
|
217
|
-
order,
|
|
218
|
-
setSort,
|
|
219
|
-
setOrder
|
|
220
|
-
]);
|
|
221
|
-
(0, react.useEffect)(() => {
|
|
222
|
-
if (sort && !order) setOrder("asc");
|
|
223
|
-
}, [
|
|
224
|
-
sort,
|
|
225
|
-
order,
|
|
226
|
-
setOrder
|
|
227
|
-
]);
|
|
228
|
-
const setPagination = (0, react.useCallback)((updater) => {
|
|
229
|
-
const currentState = {
|
|
230
|
-
pageIndex: page - 1,
|
|
231
|
-
pageSize: limit
|
|
232
|
-
};
|
|
233
|
-
const next = typeof updater === "function" ? updater(currentState) : updater;
|
|
234
|
-
setPage((next.pageIndex ?? 0) + 1);
|
|
235
|
-
setLimit(next.pageSize ?? 10);
|
|
236
|
-
}, [page, limit]);
|
|
237
|
-
return (0, react.useMemo)(() => ({
|
|
238
|
-
q: qRaw,
|
|
239
|
-
setQ,
|
|
240
|
-
filters,
|
|
241
|
-
setFilters,
|
|
242
|
-
granularity,
|
|
243
|
-
setGranularity,
|
|
244
|
-
sort,
|
|
245
|
-
order,
|
|
246
|
-
setSorting,
|
|
247
|
-
sorting,
|
|
248
|
-
page,
|
|
249
|
-
limit,
|
|
250
|
-
setPagination,
|
|
251
|
-
pagination,
|
|
252
|
-
grouping,
|
|
253
|
-
setGrouping
|
|
254
|
-
}), [
|
|
255
|
-
qRaw,
|
|
256
|
-
setQ,
|
|
257
|
-
filters,
|
|
258
|
-
setFilters,
|
|
259
|
-
granularity,
|
|
260
|
-
setGranularity,
|
|
261
|
-
sort,
|
|
262
|
-
order,
|
|
263
|
-
setSorting,
|
|
264
|
-
sorting,
|
|
265
|
-
page,
|
|
266
|
-
limit,
|
|
267
|
-
setPagination,
|
|
268
|
-
pagination,
|
|
269
|
-
grouping,
|
|
270
|
-
setGrouping
|
|
271
|
-
]);
|
|
272
|
-
};
|
|
148
|
+
function decodeFilterTuples(rows) {
|
|
149
|
+
const decoded = rows.map((row) => decodeTupleToFilter(row)).filter((filter) => filter != null);
|
|
150
|
+
const parsed = _m5kdev_commons_modules_schemas_query_schema.filtersSchema.safeParse(decoded);
|
|
151
|
+
return parsed.success ? parsed.data : [];
|
|
152
|
+
}
|
|
273
153
|
//#endregion
|
|
274
|
-
exports.
|
|
154
|
+
exports.decodeFilterTuples = decodeFilterTuples;
|
|
155
|
+
exports.decodeTupleToFilter = decodeTupleToFilter;
|
|
156
|
+
exports.encodeFilterToTuple = encodeFilterToTuple;
|
|
157
|
+
exports.parseFiltersParam = parseFiltersParam;
|
|
158
|
+
exports.serializeFiltersParam = serializeFiltersParam;
|
|
275
159
|
|
|
276
|
-
//# sourceMappingURL=
|
|
160
|
+
//# sourceMappingURL=queryParams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryParams.js","names":["z","filterSchema","filtersSchema"],"sources":["../../../../src/modules/table/queryParams.ts"],"sourcesContent":["import type { QueryFilter, QueryFilters } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { filterSchema, filtersSchema } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { GroupingState, PaginationState, SortingState, Updater } from \"@tanstack/react-table\";\r\nimport { z } from \"zod\";\r\n\r\n/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */\r\nconst filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));\r\n\r\n/** Escape `\\`, `|`, `;` so we can split filters without JSON quotes/brackets. */\r\nfunction escapeFilterField(raw: string): string {\r\n return raw.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\").replace(/;/g, \"\\\\;\");\r\n}\r\n\r\nfunction unescapeFilterField(encoded: string): string {\r\n let out = \"\";\r\n for (let i = 0; i < encoded.length; i++) {\r\n const c = encoded[i];\r\n if (c === \"\\\\\" && i + 1 < encoded.length) {\r\n const next = encoded[i + 1];\r\n if (next === \"\\\\\" || next === \"|\" || next === \";\") {\r\n out += next;\r\n i++;\r\n continue;\r\n }\r\n }\r\n out += c;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Split on `delimiter` only when not escaped as `\\` + delimiter.\r\n */\r\nfunction splitByEscapedDelimiter(s: string, delimiter: string): string[] {\r\n if (delimiter.length !== 1) {\r\n throw new Error(\"splitByEscapedDelimiter expects a single-character delimiter\");\r\n }\r\n const parts: string[] = [];\r\n let buf = \"\";\r\n for (let i = 0; i < s.length; i++) {\r\n const c = s[i];\r\n if (c === \"\\\\\" && i + 1 < s.length) {\r\n buf += c + s[i + 1];\r\n i++;\r\n continue;\r\n }\r\n if (c === delimiter) {\r\n parts.push(unescapeFilterField(buf));\r\n buf = \"\";\r\n continue;\r\n }\r\n buf += c;\r\n }\r\n parts.push(unescapeFilterField(buf));\r\n return parts;\r\n}\r\n\r\nexport function serializeFiltersParam(rows: string[][]): string {\r\n if (rows.length === 0) {\r\n return \"\";\r\n }\r\n return rows.map((row) => row.map(escapeFilterField).join(\"|\")).join(\";\");\r\n}\r\n\r\nexport function parseFiltersParam(value: string): string[][] | null {\r\n const trimmed = value.trim();\r\n if (trimmed === \"\") {\r\n return [];\r\n }\r\n const rowStrings = splitByEscapedDelimiter(trimmed, \";\");\r\n const rows: string[][] = [];\r\n for (const row of rowStrings) {\r\n if (row === \"\") {\r\n continue;\r\n }\r\n const fields = splitByEscapedDelimiter(row, \"|\");\r\n if (fields.length >= 4 && fields.length <= 6) {\r\n rows.push(fields);\r\n }\r\n }\r\n const parsed = filtersRawSchema.safeParse(rows);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nconst NULLISH_METHODS: ReadonlySet<QueryFilter[\"method\"]> = new Set([\r\n \"isEmpty\",\r\n \"isNotEmpty\",\r\n \"is_null\",\r\n \"is_not_null\",\r\n]);\r\n\r\nfunction encodeFilterValue(filter: QueryFilter): string {\r\n if (NULLISH_METHODS.has(filter.method)) {\r\n return typeof filter.value === \"string\" ? filter.value : \"\";\r\n }\r\n const { type, method, value } = filter;\r\n switch (type) {\r\n case \"number\":\r\n return String(value as number);\r\n case \"boolean\":\r\n return (value as boolean) ? \"true\" : \"false\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\" && Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n if (Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n default:\r\n return String(value);\r\n }\r\n}\r\n\r\nfunction decodeFilterValue(\r\n type: QueryFilter[\"type\"],\r\n method: QueryFilter[\"method\"],\r\n valueStr: string\r\n): QueryFilter[\"value\"] {\r\n if (NULLISH_METHODS.has(method)) {\r\n return valueStr;\r\n }\r\n switch (type) {\r\n case \"number\": {\r\n const n = Number.parseFloat(valueStr);\r\n return Number.isNaN(n) ? 0 : n;\r\n }\r\n case \"boolean\":\r\n return valueStr === \"true\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\") {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n return Array.isArray(parsed) ? parsed.map(String) : [];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n if (valueStr.startsWith(\"[\")) {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n if (Array.isArray(parsed)) {\r\n return parsed.map(String);\r\n }\r\n } catch {\r\n /* use raw string */\r\n }\r\n }\r\n return valueStr;\r\n default:\r\n return valueStr;\r\n }\r\n}\r\n\r\n/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be \"\"). */\r\nexport function encodeFilterToTuple(filter: QueryFilter): string[] {\r\n const tuple: string[] = [filter.columnId, filter.type, filter.method, encodeFilterValue(filter)];\r\n const hasValueTo = filter.valueTo != null && filter.valueTo !== \"\";\r\n const hasEndColumnId = filter.endColumnId != null && filter.endColumnId !== \"\";\r\n\r\n if (hasValueTo && filter.valueTo != null) {\r\n tuple.push(filter.valueTo);\r\n }\r\n\r\n if (hasEndColumnId && filter.endColumnId != null) {\r\n if (!hasValueTo) {\r\n tuple.push(\"\");\r\n }\r\n tuple.push(filter.endColumnId);\r\n }\r\n\r\n return tuple;\r\n}\r\n\r\nexport function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null {\r\n if (parts.length < 4 || parts.length > 6) {\r\n return null;\r\n }\r\n\r\n const [columnId, typeStr, methodStr, valueStr, valueToStr, endColumnIdStr] = parts;\r\n\r\n const typeParsed = filterSchema.shape.type.safeParse(typeStr);\r\n const methodParsed = filterSchema.shape.method.safeParse(methodStr);\r\n if (!typeParsed.success || !methodParsed.success) {\r\n return null;\r\n }\r\n\r\n const type = typeParsed.data;\r\n const method = methodParsed.data;\r\n const value = decodeFilterValue(type, method, valueStr);\r\n\r\n const candidate: QueryFilter = {\r\n columnId,\r\n type,\r\n method,\r\n value,\r\n };\r\n\r\n if (valueToStr !== undefined) {\r\n candidate.valueTo = valueToStr;\r\n }\r\n if (endColumnIdStr !== undefined) {\r\n candidate.endColumnId = endColumnIdStr;\r\n }\r\n\r\n const parsed = filterSchema.safeParse(candidate);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nexport function decodeFilterTuples(rows: readonly string[][]): QueryFilters {\r\n const decoded = rows\r\n .map((row) => decodeTupleToFilter(row))\r\n .filter((filter): filter is QueryFilter => filter != null);\r\n const parsed = filtersSchema.safeParse(decoded);\r\n return parsed.success ? parsed.data : [];\r\n}\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport type Granularity = \"daily\" | \"weekly\" | \"monthly\" | \"yearly\";\r\n\r\nexport interface QueryParamsState {\r\n /** Global search string; absent when not set. */\r\n q: string | null;\r\n setQ: (value: string | null) => void;\r\n filters?: QueryFilters;\r\n setFilters?: (filters: QueryFilters) => void;\r\n granularity?: Granularity;\r\n setGranularity?: (value: Granularity) => void;\r\n sort?: string;\r\n order?: Order | null;\r\n setSorting?: (updater: Updater<SortingState>) => void;\r\n sorting?: SortingState;\r\n page?: number;\r\n limit?: number;\r\n setPagination?: (updater: Updater<PaginationState>) => void;\r\n pagination?: PaginationState;\r\n grouping: GroupingState;\r\n setGrouping: (updater: Updater<GroupingState>) => void;\r\n}\r\n"],"mappings":";;;;;AAMA,MAAM,mBAAmBA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;;AAGnE,SAAS,kBAAkB,KAAqB;AAC9C,QAAO,IAAI,QAAQ,OAAO,OAAO,CAAC,QAAQ,OAAO,MAAM,CAAC,QAAQ,MAAM,MAAM;;AAG9E,SAAS,oBAAoB,SAAyB;CACpD,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,IAAI,QAAQ;AAClB,MAAI,MAAM,QAAQ,IAAI,IAAI,QAAQ,QAAQ;GACxC,MAAM,OAAO,QAAQ,IAAI;AACzB,OAAI,SAAS,QAAQ,SAAS,OAAO,SAAS,KAAK;AACjD,WAAO;AACP;AACA;;;AAGJ,SAAO;;AAET,QAAO;;;;;AAMT,SAAS,wBAAwB,GAAW,WAA6B;AACvE,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,MAAM,+DAA+D;CAEjF,MAAM,QAAkB,EAAE;CAC1B,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;EACjC,MAAM,IAAI,EAAE;AACZ,MAAI,MAAM,QAAQ,IAAI,IAAI,EAAE,QAAQ;AAClC,UAAO,IAAI,EAAE,IAAI;AACjB;AACA;;AAEF,MAAI,MAAM,WAAW;AACnB,SAAM,KAAK,oBAAoB,IAAI,CAAC;AACpC,SAAM;AACN;;AAEF,SAAO;;AAET,OAAM,KAAK,oBAAoB,IAAI,CAAC;AACpC,QAAO;;AAGT,SAAgB,sBAAsB,MAA0B;AAC9D,KAAI,KAAK,WAAW,EAClB,QAAO;AAET,QAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,kBAAkB,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI;;AAG1E,SAAgB,kBAAkB,OAAkC;CAClE,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,YAAY,GACd,QAAO,EAAE;CAEX,MAAM,aAAa,wBAAwB,SAAS,IAAI;CACxD,MAAM,OAAmB,EAAE;AAC3B,MAAK,MAAM,OAAO,YAAY;AAC5B,MAAI,QAAQ,GACV;EAEF,MAAM,SAAS,wBAAwB,KAAK,IAAI;AAChD,MAAI,OAAO,UAAU,KAAK,OAAO,UAAU,EACzC,MAAK,KAAK,OAAO;;CAGrB,MAAM,SAAS,iBAAiB,UAAU,KAAK;AAC/C,QAAO,OAAO,UAAU,OAAO,OAAO;;AAGxC,MAAM,kBAAsD,IAAI,IAAI;CAClE;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,kBAAkB,QAA6B;AACtD,KAAI,gBAAgB,IAAI,OAAO,OAAO,CACpC,QAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;CAE3D,MAAM,EAAE,MAAM,QAAQ,UAAU;AAChC,SAAQ,MAAR;EACE,KAAK,SACH,QAAO,OAAO,MAAgB;EAChC,KAAK,UACH,QAAQ,QAAoB,SAAS;EACvC,KAAK;EACL,KAAK;AACH,OAAI,WAAW,WAAW,MAAM,QAAQ,MAAM,CAC5C,QAAO,KAAK,UAAU,MAAM;AAE9B,OAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,KAAK,UAAU,MAAM;AAE9B,UAAO,OAAO,MAAM;EACtB,QACE,QAAO,OAAO,MAAM;;;AAI1B,SAAS,kBACP,MACA,QACA,UACsB;AACtB,KAAI,gBAAgB,IAAI,OAAO,CAC7B,QAAO;AAET,SAAQ,MAAR;EACE,KAAK,UAAU;GACb,MAAM,IAAI,OAAO,WAAW,SAAS;AACrC,UAAO,OAAO,MAAM,EAAE,GAAG,IAAI;;EAE/B,KAAK,UACH,QAAO,aAAa;EACtB,KAAK;EACL,KAAK;AACH,OAAI,WAAW,QACb,KAAI;IACF,MAAM,SAAS,KAAK,MAAM,SAAS;AACnC,WAAO,MAAM,QAAQ,OAAO,GAAG,OAAO,IAAI,OAAO,GAAG,EAAE;WAChD;AACN,WAAO,EAAE;;AAGb,OAAI,SAAS,WAAW,IAAI,CAC1B,KAAI;IACF,MAAM,SAAS,KAAK,MAAM,SAAS;AACnC,QAAI,MAAM,QAAQ,OAAO,CACvB,QAAO,OAAO,IAAI,OAAO;WAErB;AAIV,UAAO;EACT,QACE,QAAO;;;;AAKb,SAAgB,oBAAoB,QAA+B;CACjE,MAAM,QAAkB;EAAC,OAAO;EAAU,OAAO;EAAM,OAAO;EAAQ,kBAAkB,OAAO;EAAC;CAChG,MAAM,aAAa,OAAO,WAAW,QAAQ,OAAO,YAAY;CAChE,MAAM,iBAAiB,OAAO,eAAe,QAAQ,OAAO,gBAAgB;AAE5E,KAAI,cAAc,OAAO,WAAW,KAClC,OAAM,KAAK,OAAO,QAAQ;AAG5B,KAAI,kBAAkB,OAAO,eAAe,MAAM;AAChD,MAAI,CAAC,WACH,OAAM,KAAK,GAAG;AAEhB,QAAM,KAAK,OAAO,YAAY;;AAGhC,QAAO;;AAGT,SAAgB,oBAAoB,OAA8C;AAChF,KAAI,MAAM,SAAS,KAAK,MAAM,SAAS,EACrC,QAAO;CAGT,MAAM,CAAC,UAAU,SAAS,WAAW,UAAU,YAAY,kBAAkB;CAE7E,MAAM,aAAaC,6CAAAA,aAAa,MAAM,KAAK,UAAU,QAAQ;CAC7D,MAAM,eAAeA,6CAAAA,aAAa,MAAM,OAAO,UAAU,UAAU;AACnE,KAAI,CAAC,WAAW,WAAW,CAAC,aAAa,QACvC,QAAO;CAGT,MAAM,OAAO,WAAW;CACxB,MAAM,SAAS,aAAa;CAG5B,MAAM,YAAyB;EAC7B;EACA;EACA;EACA,OANY,kBAAkB,MAAM,QAAQ,SAAS;EAOtD;AAED,KAAI,eAAe,KAAA,EACjB,WAAU,UAAU;AAEtB,KAAI,mBAAmB,KAAA,EACrB,WAAU,cAAc;CAG1B,MAAM,SAASA,6CAAAA,aAAa,UAAU,UAAU;AAChD,QAAO,OAAO,UAAU,OAAO,OAAO;;AAGxC,SAAgB,mBAAmB,MAAyC;CAC1E,MAAM,UAAU,KACb,KAAK,QAAQ,oBAAoB,IAAI,CAAC,CACtC,QAAQ,WAAkC,UAAU,KAAK;CAC5D,MAAM,SAASC,6CAAAA,cAAc,UAAU,QAAQ;AAC/C,QAAO,OAAO,UAAU,OAAO,OAAO,EAAE"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo } from "react";
|
|
2
1
|
import { filterSchema, filtersSchema } from "@m5kdev/commons/modules/schemas/query.schema";
|
|
3
|
-
import { createParser, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringLiteral, useQueryState } from "nuqs";
|
|
4
2
|
import { z } from "zod";
|
|
5
|
-
//#region src/modules/table/
|
|
6
|
-
/** Each row: [columnId, type, method, value, valueTo?, endColumnId?]
|
|
3
|
+
//#region src/modules/table/queryParams.ts
|
|
4
|
+
/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */
|
|
7
5
|
const filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));
|
|
8
6
|
/** Escape `\`, `|`, `;` so we can split filters without JSON quotes/brackets. */
|
|
9
7
|
function escapeFilterField(raw) {
|
|
@@ -66,12 +64,6 @@ function parseFiltersParam(value) {
|
|
|
66
64
|
const parsed = filtersRawSchema.safeParse(rows);
|
|
67
65
|
return parsed.success ? parsed.data : null;
|
|
68
66
|
}
|
|
69
|
-
const parseAsFilterTuples = createParser({
|
|
70
|
-
parse: (value) => parseFiltersParam(value),
|
|
71
|
-
serialize: (rows) => serializeFiltersParam(rows),
|
|
72
|
-
eq: (a, b) => JSON.stringify(a) === JSON.stringify(b)
|
|
73
|
-
}).withDefault([]);
|
|
74
|
-
const parseAsGrouping = parseAsArrayOf(parseAsString).withDefault([]);
|
|
75
67
|
const NULLISH_METHODS = new Set([
|
|
76
68
|
"isEmpty",
|
|
77
69
|
"isNotEmpty",
|
|
@@ -116,7 +108,7 @@ function decodeFilterValue(type, method, valueStr) {
|
|
|
116
108
|
default: return valueStr;
|
|
117
109
|
}
|
|
118
110
|
}
|
|
119
|
-
/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot
|
|
111
|
+
/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
|
|
120
112
|
function encodeFilterToTuple(filter) {
|
|
121
113
|
const tuple = [
|
|
122
114
|
filter.columnId,
|
|
@@ -152,124 +144,12 @@ function decodeTupleToFilter(parts) {
|
|
|
152
144
|
const parsed = filterSchema.safeParse(candidate);
|
|
153
145
|
return parsed.success ? parsed.data : null;
|
|
154
146
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const useNuqsQueryParams = (prefix) => {
|
|
161
|
-
const k = (name) => prefix ? `${prefix}_${name}` : name;
|
|
162
|
-
const [sort, setSort] = useQueryState(k("s"), parseAsString.withDefault(""));
|
|
163
|
-
const [order, setOrder] = useQueryState(k("o"), parseAsStringLiteral(["asc", "desc"]));
|
|
164
|
-
const [page, setPage] = useQueryState(k("p"), parseAsInteger.withDefault(1));
|
|
165
|
-
const [limit, setLimit] = useQueryState(k("l"), parseAsInteger.withDefault(10));
|
|
166
|
-
const [qRaw, setQRaw] = useQueryState(k("q"), parseAsString);
|
|
167
|
-
const [filtersRaw, setFiltersRaw] = useQueryState(k("f"), parseAsFilterTuples);
|
|
168
|
-
const filters = useMemo(() => {
|
|
169
|
-
const decoded = filtersRaw.map((row) => decodeTupleToFilter(row)).filter((f) => f != null);
|
|
170
|
-
const parsed = filtersSchema.safeParse(decoded);
|
|
171
|
-
return parsed.success ? parsed.data : [];
|
|
172
|
-
}, [filtersRaw]);
|
|
173
|
-
const setFilters = useCallback((next) => {
|
|
174
|
-
setFiltersRaw(next.length === 0 ? null : next.map(encodeFilterToTuple));
|
|
175
|
-
}, [setFiltersRaw]);
|
|
176
|
-
const setQ = useCallback((value) => {
|
|
177
|
-
setQRaw(value === "" || value == null ? null : value);
|
|
178
|
-
}, [setQRaw]);
|
|
179
|
-
const [granularity, setGranularity] = useQueryState(k("r"), parseAsStringLiteral([
|
|
180
|
-
"daily",
|
|
181
|
-
"weekly",
|
|
182
|
-
"monthly",
|
|
183
|
-
"yearly"
|
|
184
|
-
]).withDefault("daily"));
|
|
185
|
-
const [groupingRaw, setGroupingRaw] = useQueryState(k("g"), parseAsGrouping);
|
|
186
|
-
const grouping = groupingRaw;
|
|
187
|
-
const setGrouping = useCallback((updater) => {
|
|
188
|
-
const next = typeof updater === "function" ? updater(groupingRaw) : updater;
|
|
189
|
-
setGroupingRaw(next.length > 0 ? next : null);
|
|
190
|
-
}, [groupingRaw, setGroupingRaw]);
|
|
191
|
-
const sorting = useMemo(() => {
|
|
192
|
-
if (!sort) return [];
|
|
193
|
-
return [{
|
|
194
|
-
id: sort,
|
|
195
|
-
desc: (order ?? "asc") === "desc"
|
|
196
|
-
}];
|
|
197
|
-
}, [sort, order]);
|
|
198
|
-
const pagination = useMemo(() => ({
|
|
199
|
-
pageIndex: page - 1,
|
|
200
|
-
pageSize: limit
|
|
201
|
-
}), [page, limit]);
|
|
202
|
-
const setSorting = useCallback((updater) => {
|
|
203
|
-
const first = (typeof updater === "function" ? updater(sort ? [{
|
|
204
|
-
id: sort,
|
|
205
|
-
desc: (order ?? "asc") === "desc"
|
|
206
|
-
}] : []) : updater)[0];
|
|
207
|
-
if (!first || !first.id) {
|
|
208
|
-
setSort("");
|
|
209
|
-
setOrder(null);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
setSort(first.id);
|
|
213
|
-
setOrder(first.desc ? "desc" : "asc");
|
|
214
|
-
}, [
|
|
215
|
-
sort,
|
|
216
|
-
order,
|
|
217
|
-
setSort,
|
|
218
|
-
setOrder
|
|
219
|
-
]);
|
|
220
|
-
useEffect(() => {
|
|
221
|
-
if (sort && !order) setOrder("asc");
|
|
222
|
-
}, [
|
|
223
|
-
sort,
|
|
224
|
-
order,
|
|
225
|
-
setOrder
|
|
226
|
-
]);
|
|
227
|
-
const setPagination = useCallback((updater) => {
|
|
228
|
-
const currentState = {
|
|
229
|
-
pageIndex: page - 1,
|
|
230
|
-
pageSize: limit
|
|
231
|
-
};
|
|
232
|
-
const next = typeof updater === "function" ? updater(currentState) : updater;
|
|
233
|
-
setPage((next.pageIndex ?? 0) + 1);
|
|
234
|
-
setLimit(next.pageSize ?? 10);
|
|
235
|
-
}, [page, limit]);
|
|
236
|
-
return useMemo(() => ({
|
|
237
|
-
q: qRaw,
|
|
238
|
-
setQ,
|
|
239
|
-
filters,
|
|
240
|
-
setFilters,
|
|
241
|
-
granularity,
|
|
242
|
-
setGranularity,
|
|
243
|
-
sort,
|
|
244
|
-
order,
|
|
245
|
-
setSorting,
|
|
246
|
-
sorting,
|
|
247
|
-
page,
|
|
248
|
-
limit,
|
|
249
|
-
setPagination,
|
|
250
|
-
pagination,
|
|
251
|
-
grouping,
|
|
252
|
-
setGrouping
|
|
253
|
-
}), [
|
|
254
|
-
qRaw,
|
|
255
|
-
setQ,
|
|
256
|
-
filters,
|
|
257
|
-
setFilters,
|
|
258
|
-
granularity,
|
|
259
|
-
setGranularity,
|
|
260
|
-
sort,
|
|
261
|
-
order,
|
|
262
|
-
setSorting,
|
|
263
|
-
sorting,
|
|
264
|
-
page,
|
|
265
|
-
limit,
|
|
266
|
-
setPagination,
|
|
267
|
-
pagination,
|
|
268
|
-
grouping,
|
|
269
|
-
setGrouping
|
|
270
|
-
]);
|
|
271
|
-
};
|
|
147
|
+
function decodeFilterTuples(rows) {
|
|
148
|
+
const decoded = rows.map((row) => decodeTupleToFilter(row)).filter((filter) => filter != null);
|
|
149
|
+
const parsed = filtersSchema.safeParse(decoded);
|
|
150
|
+
return parsed.success ? parsed.data : [];
|
|
151
|
+
}
|
|
272
152
|
//#endregion
|
|
273
|
-
export {
|
|
153
|
+
export { decodeFilterTuples, decodeTupleToFilter, encodeFilterToTuple, parseFiltersParam, serializeFiltersParam };
|
|
274
154
|
|
|
275
|
-
//# sourceMappingURL=
|
|
155
|
+
//# sourceMappingURL=queryParams.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryParams.mjs","names":[],"sources":["../../../../src/modules/table/queryParams.ts"],"sourcesContent":["import type { QueryFilter, QueryFilters } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { filterSchema, filtersSchema } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { GroupingState, PaginationState, SortingState, Updater } from \"@tanstack/react-table\";\r\nimport { z } from \"zod\";\r\n\r\n/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */\r\nconst filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));\r\n\r\n/** Escape `\\`, `|`, `;` so we can split filters without JSON quotes/brackets. */\r\nfunction escapeFilterField(raw: string): string {\r\n return raw.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\").replace(/;/g, \"\\\\;\");\r\n}\r\n\r\nfunction unescapeFilterField(encoded: string): string {\r\n let out = \"\";\r\n for (let i = 0; i < encoded.length; i++) {\r\n const c = encoded[i];\r\n if (c === \"\\\\\" && i + 1 < encoded.length) {\r\n const next = encoded[i + 1];\r\n if (next === \"\\\\\" || next === \"|\" || next === \";\") {\r\n out += next;\r\n i++;\r\n continue;\r\n }\r\n }\r\n out += c;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Split on `delimiter` only when not escaped as `\\` + delimiter.\r\n */\r\nfunction splitByEscapedDelimiter(s: string, delimiter: string): string[] {\r\n if (delimiter.length !== 1) {\r\n throw new Error(\"splitByEscapedDelimiter expects a single-character delimiter\");\r\n }\r\n const parts: string[] = [];\r\n let buf = \"\";\r\n for (let i = 0; i < s.length; i++) {\r\n const c = s[i];\r\n if (c === \"\\\\\" && i + 1 < s.length) {\r\n buf += c + s[i + 1];\r\n i++;\r\n continue;\r\n }\r\n if (c === delimiter) {\r\n parts.push(unescapeFilterField(buf));\r\n buf = \"\";\r\n continue;\r\n }\r\n buf += c;\r\n }\r\n parts.push(unescapeFilterField(buf));\r\n return parts;\r\n}\r\n\r\nexport function serializeFiltersParam(rows: string[][]): string {\r\n if (rows.length === 0) {\r\n return \"\";\r\n }\r\n return rows.map((row) => row.map(escapeFilterField).join(\"|\")).join(\";\");\r\n}\r\n\r\nexport function parseFiltersParam(value: string): string[][] | null {\r\n const trimmed = value.trim();\r\n if (trimmed === \"\") {\r\n return [];\r\n }\r\n const rowStrings = splitByEscapedDelimiter(trimmed, \";\");\r\n const rows: string[][] = [];\r\n for (const row of rowStrings) {\r\n if (row === \"\") {\r\n continue;\r\n }\r\n const fields = splitByEscapedDelimiter(row, \"|\");\r\n if (fields.length >= 4 && fields.length <= 6) {\r\n rows.push(fields);\r\n }\r\n }\r\n const parsed = filtersRawSchema.safeParse(rows);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nconst NULLISH_METHODS: ReadonlySet<QueryFilter[\"method\"]> = new Set([\r\n \"isEmpty\",\r\n \"isNotEmpty\",\r\n \"is_null\",\r\n \"is_not_null\",\r\n]);\r\n\r\nfunction encodeFilterValue(filter: QueryFilter): string {\r\n if (NULLISH_METHODS.has(filter.method)) {\r\n return typeof filter.value === \"string\" ? filter.value : \"\";\r\n }\r\n const { type, method, value } = filter;\r\n switch (type) {\r\n case \"number\":\r\n return String(value as number);\r\n case \"boolean\":\r\n return (value as boolean) ? \"true\" : \"false\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\" && Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n if (Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n default:\r\n return String(value);\r\n }\r\n}\r\n\r\nfunction decodeFilterValue(\r\n type: QueryFilter[\"type\"],\r\n method: QueryFilter[\"method\"],\r\n valueStr: string\r\n): QueryFilter[\"value\"] {\r\n if (NULLISH_METHODS.has(method)) {\r\n return valueStr;\r\n }\r\n switch (type) {\r\n case \"number\": {\r\n const n = Number.parseFloat(valueStr);\r\n return Number.isNaN(n) ? 0 : n;\r\n }\r\n case \"boolean\":\r\n return valueStr === \"true\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\") {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n return Array.isArray(parsed) ? parsed.map(String) : [];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n if (valueStr.startsWith(\"[\")) {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n if (Array.isArray(parsed)) {\r\n return parsed.map(String);\r\n }\r\n } catch {\r\n /* use raw string */\r\n }\r\n }\r\n return valueStr;\r\n default:\r\n return valueStr;\r\n }\r\n}\r\n\r\n/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be \"\"). */\r\nexport function encodeFilterToTuple(filter: QueryFilter): string[] {\r\n const tuple: string[] = [filter.columnId, filter.type, filter.method, encodeFilterValue(filter)];\r\n const hasValueTo = filter.valueTo != null && filter.valueTo !== \"\";\r\n const hasEndColumnId = filter.endColumnId != null && filter.endColumnId !== \"\";\r\n\r\n if (hasValueTo && filter.valueTo != null) {\r\n tuple.push(filter.valueTo);\r\n }\r\n\r\n if (hasEndColumnId && filter.endColumnId != null) {\r\n if (!hasValueTo) {\r\n tuple.push(\"\");\r\n }\r\n tuple.push(filter.endColumnId);\r\n }\r\n\r\n return tuple;\r\n}\r\n\r\nexport function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null {\r\n if (parts.length < 4 || parts.length > 6) {\r\n return null;\r\n }\r\n\r\n const [columnId, typeStr, methodStr, valueStr, valueToStr, endColumnIdStr] = parts;\r\n\r\n const typeParsed = filterSchema.shape.type.safeParse(typeStr);\r\n const methodParsed = filterSchema.shape.method.safeParse(methodStr);\r\n if (!typeParsed.success || !methodParsed.success) {\r\n return null;\r\n }\r\n\r\n const type = typeParsed.data;\r\n const method = methodParsed.data;\r\n const value = decodeFilterValue(type, method, valueStr);\r\n\r\n const candidate: QueryFilter = {\r\n columnId,\r\n type,\r\n method,\r\n value,\r\n };\r\n\r\n if (valueToStr !== undefined) {\r\n candidate.valueTo = valueToStr;\r\n }\r\n if (endColumnIdStr !== undefined) {\r\n candidate.endColumnId = endColumnIdStr;\r\n }\r\n\r\n const parsed = filterSchema.safeParse(candidate);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nexport function decodeFilterTuples(rows: readonly string[][]): QueryFilters {\r\n const decoded = rows\r\n .map((row) => decodeTupleToFilter(row))\r\n .filter((filter): filter is QueryFilter => filter != null);\r\n const parsed = filtersSchema.safeParse(decoded);\r\n return parsed.success ? parsed.data : [];\r\n}\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport type Granularity = \"daily\" | \"weekly\" | \"monthly\" | \"yearly\";\r\n\r\nexport interface QueryParamsState {\r\n /** Global search string; absent when not set. */\r\n q: string | null;\r\n setQ: (value: string | null) => void;\r\n filters?: QueryFilters;\r\n setFilters?: (filters: QueryFilters) => void;\r\n granularity?: Granularity;\r\n setGranularity?: (value: Granularity) => void;\r\n sort?: string;\r\n order?: Order | null;\r\n setSorting?: (updater: Updater<SortingState>) => void;\r\n sorting?: SortingState;\r\n page?: number;\r\n limit?: number;\r\n setPagination?: (updater: Updater<PaginationState>) => void;\r\n pagination?: PaginationState;\r\n grouping: GroupingState;\r\n setGrouping: (updater: Updater<GroupingState>) => void;\r\n}\r\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CalendarDate } from "@internationalized/date";
|
|
2
1
|
import { QueryFilter } from "@m5kdev/commons/modules/schemas/query.schema";
|
|
2
|
+
import { CalendarDate } from "@internationalized/date";
|
|
3
3
|
import { DateValue } from "@react-types/calendar";
|
|
4
4
|
import { RangeValue } from "@react-types/shared";
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m5kdev/frontend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,12 +21,10 @@
|
|
|
21
21
|
"@trpc/tanstack-react-query": "11.4.3",
|
|
22
22
|
"better-auth": "1.4.18",
|
|
23
23
|
"luxon": "3.7.1",
|
|
24
|
-
"nuqs": "2.4.3",
|
|
25
|
-
"posthog-js": "1.258.2",
|
|
26
24
|
"react": "19.2.1",
|
|
27
25
|
"react-dom": "19.2.1",
|
|
28
26
|
"zod": "4.2.1",
|
|
29
|
-
"@m5kdev/commons": "0.
|
|
27
|
+
"@m5kdev/commons": "0.21.0"
|
|
30
28
|
},
|
|
31
29
|
"peerDependencies": {
|
|
32
30
|
"@trpc/server": "11.4.3"
|
|
@@ -41,10 +39,20 @@
|
|
|
41
39
|
"tsdown": "0.21.7",
|
|
42
40
|
"typescript": "6.0.3",
|
|
43
41
|
"vite": "7.0.4",
|
|
44
|
-
"@m5kdev/
|
|
45
|
-
"@m5kdev/
|
|
42
|
+
"@m5kdev/config": "0.21.0",
|
|
43
|
+
"@m5kdev/backend": "0.21.0"
|
|
46
44
|
},
|
|
47
45
|
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"import": {
|
|
48
|
+
"types": "./dist/src/index.d.mts",
|
|
49
|
+
"default": "./dist/src/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./dist/src/index.d.ts",
|
|
53
|
+
"default": "./dist/src/index.js"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
48
56
|
"./modules/app/components/*": {
|
|
49
57
|
"import": {
|
|
50
58
|
"types": "./dist/src/modules/app/components/*.d.mts",
|
|
@@ -154,6 +162,16 @@
|
|
|
154
162
|
"types": "./dist/src/utils/*.d.ts",
|
|
155
163
|
"default": "./dist/src/utils/*.js"
|
|
156
164
|
}
|
|
165
|
+
},
|
|
166
|
+
"./modules/table/queryParams": {
|
|
167
|
+
"import": {
|
|
168
|
+
"types": "./dist/src/modules/table/queryParams.d.mts",
|
|
169
|
+
"default": "./dist/src/modules/table/queryParams.mjs"
|
|
170
|
+
},
|
|
171
|
+
"require": {
|
|
172
|
+
"types": "./dist/src/modules/table/queryParams.d.ts",
|
|
173
|
+
"default": "./dist/src/modules/table/queryParams.js"
|
|
174
|
+
}
|
|
157
175
|
}
|
|
158
176
|
},
|
|
159
177
|
"scripts": {
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { NuqsQueryParams } from "./useNuqsQueryParams.mjs";
|
|
2
|
-
import { UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
|
|
3
|
-
|
|
4
|
-
//#region src/modules/table/hooks/useDateRangeFilter.d.ts
|
|
5
|
-
interface DateRangeFilterReturn<TData> {
|
|
6
|
-
params: NuqsQueryParams;
|
|
7
|
-
query: UseQueryResult<TData>;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Flexible query options type that accepts both standard TanStack Query options
|
|
11
|
-
* and tRPC's queryOptions function return type.
|
|
12
|
-
* Uses permissive generics to handle type differences between TanStack Query and tRPC.
|
|
13
|
-
*/
|
|
14
|
-
type QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;
|
|
15
|
-
/**
|
|
16
|
-
* Function type that accepts both standard query options functions and tRPC's queryOptions.
|
|
17
|
-
* tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).
|
|
18
|
-
*/
|
|
19
|
-
type GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;
|
|
20
|
-
interface DateRangeFilterOptions<TInput, TData> {
|
|
21
|
-
getQueryOptions: GetQueryOptionsFn<TInput, TData>;
|
|
22
|
-
queryParams?: TInput;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Hook for charts with URL-synced query parameters and data fetching
|
|
26
|
-
* Similar to useNuqsTable but without rowSelection (not needed for charts)
|
|
27
|
-
*/
|
|
28
|
-
declare const useDateRangeFilter: <TInput, TData>({
|
|
29
|
-
getQueryOptions,
|
|
30
|
-
queryParams
|
|
31
|
-
}: DateRangeFilterOptions<TInput, TData>) => DateRangeFilterReturn<TData>;
|
|
32
|
-
//#endregion
|
|
33
|
-
export { DateRangeFilterOptions, DateRangeFilterReturn, useDateRangeFilter };
|
|
34
|
-
//# sourceMappingURL=useDateRangeFilter.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useDateRangeFilter.d.mts","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"mappings":";;;;UAIiB,qBAAA;EACf,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA,CAAe,KAAA;AAAA;;;;;;KASnB,gBAAA,UAA0B,eAAA,CAAgB,KAAA,OAAY,KAAA;;;;;KAOtD,iBAAA,mBAAoC,KAAA,EAAO,MAAA,KAAW,IAAA,YAAgB,gBAAA,CAAiB,KAAA;AAAA,UAE3E,sBAAA;EACf,eAAA,EAAiB,iBAAA,CAAkB,MAAA,EAAQ,KAAA;EAC3C,WAAA,GAAc,MAAA;AAAA;;;;;cAOH,kBAAA;EAAqC,eAAA;EAAA;AAAA,GAG/C,sBAAA,CAAuB,MAAA,EAAQ,KAAA,MAAS,qBAAA,CAAsB,KAAA"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { NuqsQueryParams } from "./useNuqsQueryParams.js";
|
|
2
|
-
import { UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
|
|
3
|
-
|
|
4
|
-
//#region src/modules/table/hooks/useDateRangeFilter.d.ts
|
|
5
|
-
interface DateRangeFilterReturn<TData> {
|
|
6
|
-
params: NuqsQueryParams;
|
|
7
|
-
query: UseQueryResult<TData>;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Flexible query options type that accepts both standard TanStack Query options
|
|
11
|
-
* and tRPC's queryOptions function return type.
|
|
12
|
-
* Uses permissive generics to handle type differences between TanStack Query and tRPC.
|
|
13
|
-
*/
|
|
14
|
-
type QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;
|
|
15
|
-
/**
|
|
16
|
-
* Function type that accepts both standard query options functions and tRPC's queryOptions.
|
|
17
|
-
* tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).
|
|
18
|
-
*/
|
|
19
|
-
type GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;
|
|
20
|
-
interface DateRangeFilterOptions<TInput, TData> {
|
|
21
|
-
getQueryOptions: GetQueryOptionsFn<TInput, TData>;
|
|
22
|
-
queryParams?: TInput;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Hook for charts with URL-synced query parameters and data fetching
|
|
26
|
-
* Similar to useNuqsTable but without rowSelection (not needed for charts)
|
|
27
|
-
*/
|
|
28
|
-
declare const useDateRangeFilter: <TInput, TData>({
|
|
29
|
-
getQueryOptions,
|
|
30
|
-
queryParams
|
|
31
|
-
}: DateRangeFilterOptions<TInput, TData>) => DateRangeFilterReturn<TData>;
|
|
32
|
-
//#endregion
|
|
33
|
-
export { DateRangeFilterOptions, DateRangeFilterReturn, useDateRangeFilter };
|
|
34
|
-
//# sourceMappingURL=useDateRangeFilter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useDateRangeFilter.d.ts","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"mappings":";;;;UAIiB,qBAAA;EACf,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA,CAAe,KAAA;AAAA;;;;;;KASnB,gBAAA,UAA0B,eAAA,CAAgB,KAAA,OAAY,KAAA;;;;;KAOtD,iBAAA,mBAAoC,KAAA,EAAO,MAAA,KAAW,IAAA,YAAgB,gBAAA,CAAiB,KAAA;AAAA,UAE3E,sBAAA;EACf,eAAA,EAAiB,iBAAA,CAAkB,MAAA,EAAQ,KAAA;EAC3C,WAAA,GAAc,MAAA;AAAA;;;;;cAOH,kBAAA;EAAqC,eAAA;EAAA;AAAA,GAG/C,sBAAA,CAAuB,MAAA,EAAQ,KAAA,MAAS,qBAAA,CAAsB,KAAA"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_src_modules_table_hooks_useNuqsQueryParams = require("./useNuqsQueryParams.js");
|
|
3
|
-
const require_src_modules_table_hooks_useQueryWithParams = require("./useQueryWithParams.js");
|
|
4
|
-
//#region src/modules/table/hooks/useDateRangeFilter.ts
|
|
5
|
-
/**
|
|
6
|
-
* Hook for charts with URL-synced query parameters and data fetching
|
|
7
|
-
* Similar to useNuqsTable but without rowSelection (not needed for charts)
|
|
8
|
-
*/
|
|
9
|
-
const useDateRangeFilter = ({ getQueryOptions, queryParams = {} }) => {
|
|
10
|
-
const nuqs = require_src_modules_table_hooks_useNuqsQueryParams.useNuqsQueryParams();
|
|
11
|
-
return {
|
|
12
|
-
params: nuqs,
|
|
13
|
-
query: require_src_modules_table_hooks_useQueryWithParams.useQueryWithParams({
|
|
14
|
-
getQueryOptions,
|
|
15
|
-
queryParams,
|
|
16
|
-
queryState: {
|
|
17
|
-
filters: nuqs.filters,
|
|
18
|
-
q: nuqs.q,
|
|
19
|
-
sort: nuqs.sort,
|
|
20
|
-
order: nuqs.order,
|
|
21
|
-
page: nuqs.page,
|
|
22
|
-
limit: nuqs.limit
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
//#endregion
|
|
28
|
-
exports.useDateRangeFilter = useDateRangeFilter;
|
|
29
|
-
|
|
30
|
-
//# sourceMappingURL=useDateRangeFilter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useDateRangeFilter.js","names":["useNuqsQueryParams","useQueryWithParams"],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"sourcesContent":["import type { UseQueryOptions, UseQueryResult } from \"@tanstack/react-query\";\r\nimport { type NuqsQueryParams, useNuqsQueryParams } from \"./useNuqsQueryParams\";\r\nimport { useQueryWithParams } from \"./useQueryWithParams\";\r\n\r\nexport interface DateRangeFilterReturn<TData> {\r\n params: NuqsQueryParams;\r\n query: UseQueryResult<TData>;\r\n}\r\n\r\n/**\r\n * Flexible query options type that accepts both standard TanStack Query options\r\n * and tRPC's queryOptions function return type.\r\n * Uses permissive generics to handle type differences between TanStack Query and tRPC.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;\r\n\r\n/**\r\n * Function type that accepts both standard query options functions and tRPC's queryOptions.\r\n * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;\r\n\r\nexport interface DateRangeFilterOptions<TInput, TData> {\r\n getQueryOptions: GetQueryOptionsFn<TInput, TData>;\r\n queryParams?: TInput;\r\n}\r\n\r\n/**\r\n * Hook for charts with URL-synced query parameters and data fetching\r\n * Similar to useNuqsTable but without rowSelection (not needed for charts)\r\n */\r\nexport const useDateRangeFilter = <TInput, TData>({\r\n getQueryOptions,\r\n queryParams = {} as TInput,\r\n}: DateRangeFilterOptions<TInput, TData>): DateRangeFilterReturn<TData> => {\r\n const nuqs = useNuqsQueryParams();\r\n\r\n const queryResult = useQueryWithParams({\r\n getQueryOptions,\r\n queryParams,\r\n queryState: {\r\n filters: nuqs.filters,\r\n q: nuqs.q,\r\n sort: nuqs.sort,\r\n order: nuqs.order,\r\n page: nuqs.page,\r\n limit: nuqs.limit,\r\n },\r\n });\r\n\r\n return {\r\n params: nuqs,\r\n query: queryResult,\r\n };\r\n};\r\n"],"mappings":";;;;;;;;AAiCA,MAAa,sBAAqC,EAChD,iBACA,cAAc,EAAE,OACyD;CACzE,MAAM,OAAOA,mDAAAA,oBAAoB;AAejC,QAAO;EACL,QAAQ;EACR,OAfkBC,mDAAAA,mBAAmB;GACrC;GACA;GACA,YAAY;IACV,SAAS,KAAK;IACd,GAAG,KAAK;IACR,MAAM,KAAK;IACX,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,KAAK;IACb;GACF,CAAC;EAKD"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useNuqsQueryParams } from "./useNuqsQueryParams.mjs";
|
|
2
|
-
import { useQueryWithParams } from "./useQueryWithParams.mjs";
|
|
3
|
-
//#region src/modules/table/hooks/useDateRangeFilter.ts
|
|
4
|
-
/**
|
|
5
|
-
* Hook for charts with URL-synced query parameters and data fetching
|
|
6
|
-
* Similar to useNuqsTable but without rowSelection (not needed for charts)
|
|
7
|
-
*/
|
|
8
|
-
const useDateRangeFilter = ({ getQueryOptions, queryParams = {} }) => {
|
|
9
|
-
const nuqs = useNuqsQueryParams();
|
|
10
|
-
return {
|
|
11
|
-
params: nuqs,
|
|
12
|
-
query: useQueryWithParams({
|
|
13
|
-
getQueryOptions,
|
|
14
|
-
queryParams,
|
|
15
|
-
queryState: {
|
|
16
|
-
filters: nuqs.filters,
|
|
17
|
-
q: nuqs.q,
|
|
18
|
-
sort: nuqs.sort,
|
|
19
|
-
order: nuqs.order,
|
|
20
|
-
page: nuqs.page,
|
|
21
|
-
limit: nuqs.limit
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
//#endregion
|
|
27
|
-
export { useDateRangeFilter };
|
|
28
|
-
|
|
29
|
-
//# sourceMappingURL=useDateRangeFilter.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useDateRangeFilter.mjs","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"sourcesContent":["import type { UseQueryOptions, UseQueryResult } from \"@tanstack/react-query\";\r\nimport { type NuqsQueryParams, useNuqsQueryParams } from \"./useNuqsQueryParams\";\r\nimport { useQueryWithParams } from \"./useQueryWithParams\";\r\n\r\nexport interface DateRangeFilterReturn<TData> {\r\n params: NuqsQueryParams;\r\n query: UseQueryResult<TData>;\r\n}\r\n\r\n/**\r\n * Flexible query options type that accepts both standard TanStack Query options\r\n * and tRPC's queryOptions function return type.\r\n * Uses permissive generics to handle type differences between TanStack Query and tRPC.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;\r\n\r\n/**\r\n * Function type that accepts both standard query options functions and tRPC's queryOptions.\r\n * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;\r\n\r\nexport interface DateRangeFilterOptions<TInput, TData> {\r\n getQueryOptions: GetQueryOptionsFn<TInput, TData>;\r\n queryParams?: TInput;\r\n}\r\n\r\n/**\r\n * Hook for charts with URL-synced query parameters and data fetching\r\n * Similar to useNuqsTable but without rowSelection (not needed for charts)\r\n */\r\nexport const useDateRangeFilter = <TInput, TData>({\r\n getQueryOptions,\r\n queryParams = {} as TInput,\r\n}: DateRangeFilterOptions<TInput, TData>): DateRangeFilterReturn<TData> => {\r\n const nuqs = useNuqsQueryParams();\r\n\r\n const queryResult = useQueryWithParams({\r\n getQueryOptions,\r\n queryParams,\r\n queryState: {\r\n filters: nuqs.filters,\r\n q: nuqs.q,\r\n sort: nuqs.sort,\r\n order: nuqs.order,\r\n page: nuqs.page,\r\n limit: nuqs.limit,\r\n },\r\n });\r\n\r\n return {\r\n params: nuqs,\r\n query: queryResult,\r\n };\r\n};\r\n"],"mappings":";;;;;;;AAiCA,MAAa,sBAAqC,EAChD,iBACA,cAAc,EAAE,OACyD;CACzE,MAAM,OAAO,oBAAoB;AAejC,QAAO;EACL,QAAQ;EACR,OAfkB,mBAAmB;GACrC;GACA;GACA,YAAY;IACV,SAAS,KAAK;IACd,GAAG,KAAK;IACR,MAAM,KAAK;IACX,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,KAAK;IACb;GACF,CAAC;EAKD"}
|