dn-react-router-toolkit 0.8.0 → 0.8.1
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/api/index.js +13 -4
- package/dist/api/index.mjs +14 -5
- package/dist/api/item_api_handler.d.mts +4 -2
- package/dist/api/item_api_handler.d.ts +4 -2
- package/dist/api/item_api_handler.js +13 -4
- package/dist/api/item_api_handler.mjs +14 -5
- package/dist/crud/crud_loader.js +34 -5
- package/dist/crud/crud_loader.mjs +36 -6
- package/dist/crud/crud_page.js +69 -19
- package/dist/crud/crud_page.mjs +69 -19
- package/dist/crud/index.js +109 -30
- package/dist/crud/index.mjs +111 -31
- package/dist/post/index.js +6 -6
- package/dist/post/index.mjs +8 -7
- package/dist/post/post_form_page.js +6 -6
- package/dist/post/post_form_page.mjs +8 -7
- package/dist/table/index.d.mts +1 -1
- package/dist/table/index.d.ts +1 -1
- package/dist/table/index.js +94 -20
- package/dist/table/index.mjs +95 -20
- package/dist/table/load_table.d.mts +7 -1
- package/dist/table/load_table.d.ts +7 -1
- package/dist/table/load_table.js +21 -1
- package/dist/table/load_table.mjs +22 -1
- package/dist/table/loader.d.mts +3 -0
- package/dist/table/loader.d.ts +3 -0
- package/dist/table/loader.js +21 -1
- package/dist/table/loader.mjs +22 -1
- package/dist/table/page.js +69 -19
- package/dist/table/page.mjs +69 -19
- package/dist/table/repository.d.mts +6 -4
- package/dist/table/repository.d.ts +6 -4
- package/dist/table/repository.js +4 -0
- package/dist/table/repository.mjs +4 -0
- package/dist/table/table.d.mts +4 -1
- package/dist/table/table.d.ts +4 -1
- package/dist/table/table.js +55 -6
- package/dist/table/table.mjs +55 -6
- package/dist/table/table_form.d.mts +2 -2
- package/dist/table/table_form.d.ts +2 -2
- package/dist/table/table_form.js +69 -19
- package/dist/table/table_form.mjs +69 -19
- package/dist/table/use_table.d.mts +3 -3
- package/dist/table/use_table.d.ts +3 -3
- package/dist/table/use_table.js +1 -10
- package/dist/table/use_table.mjs +1 -10
- package/package.json +2 -2
|
@@ -6510,10 +6510,10 @@ var require_listCacheClear = __commonJS({
|
|
|
6510
6510
|
var require_eq = __commonJS({
|
|
6511
6511
|
"node_modules/lodash/eq.js"(exports, module) {
|
|
6512
6512
|
"use strict";
|
|
6513
|
-
function
|
|
6513
|
+
function eq2(value, other) {
|
|
6514
6514
|
return value === other || value !== value && other !== other;
|
|
6515
6515
|
}
|
|
6516
|
-
module.exports =
|
|
6516
|
+
module.exports = eq2;
|
|
6517
6517
|
}
|
|
6518
6518
|
});
|
|
6519
6519
|
|
|
@@ -6521,11 +6521,11 @@ var require_eq = __commonJS({
|
|
|
6521
6521
|
var require_assocIndexOf = __commonJS({
|
|
6522
6522
|
"node_modules/lodash/_assocIndexOf.js"(exports, module) {
|
|
6523
6523
|
"use strict";
|
|
6524
|
-
var
|
|
6524
|
+
var eq2 = require_eq();
|
|
6525
6525
|
function assocIndexOf(array, key) {
|
|
6526
6526
|
var length = array.length;
|
|
6527
6527
|
while (length--) {
|
|
6528
|
-
if (
|
|
6528
|
+
if (eq2(array[length][0], key)) {
|
|
6529
6529
|
return length;
|
|
6530
6530
|
}
|
|
6531
6531
|
}
|
|
@@ -6983,12 +6983,12 @@ var require_assignValue = __commonJS({
|
|
|
6983
6983
|
"node_modules/lodash/_assignValue.js"(exports, module) {
|
|
6984
6984
|
"use strict";
|
|
6985
6985
|
var baseAssignValue = require_baseAssignValue();
|
|
6986
|
-
var
|
|
6986
|
+
var eq2 = require_eq();
|
|
6987
6987
|
var objectProto = Object.prototype;
|
|
6988
6988
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
6989
6989
|
function assignValue(object, key, value) {
|
|
6990
6990
|
var objValue = object[key];
|
|
6991
|
-
if (!(hasOwnProperty.call(object, key) &&
|
|
6991
|
+
if (!(hasOwnProperty.call(object, key) && eq2(objValue, value)) || value === void 0 && !(key in object)) {
|
|
6992
6992
|
baseAssignValue(object, key, value);
|
|
6993
6993
|
}
|
|
6994
6994
|
}
|
|
@@ -7940,6 +7940,7 @@ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-run
|
|
|
7940
7940
|
// src/table/load_table.tsx
|
|
7941
7941
|
import {
|
|
7942
7942
|
and,
|
|
7943
|
+
eq,
|
|
7943
7944
|
ilike
|
|
7944
7945
|
} from "drizzle-orm";
|
|
7945
7946
|
|
|
@@ -7958,7 +7959,7 @@ import {
|
|
|
7958
7959
|
import { v4 } from "uuid";
|
|
7959
7960
|
|
|
7960
7961
|
// src/api/item_api_handler.ts
|
|
7961
|
-
import { UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
|
|
7962
|
+
import { FORBIDDEN, NOT_FOUND, UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
|
|
7962
7963
|
|
|
7963
7964
|
// src/crud/crud_page.tsx
|
|
7964
7965
|
import { useLoaderData as useLoaderData2, useLocation as useLocation4 } from "react-router";
|
package/dist/table/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ export { createTablePage } from './page.mjs';
|
|
|
6
6
|
export { OrderedTableProps, Table, TableColumnOptions, TableColumnProps } from './table.mjs';
|
|
7
7
|
export { TableLoaderOptions, loadTable } from './load_table.mjs';
|
|
8
8
|
export { LoadedModel, TableForm, TablePageOptions } from './table_form.mjs';
|
|
9
|
-
export {
|
|
9
|
+
export { TableLoaderData, useTable } from './use_table.mjs';
|
|
10
10
|
import 'drizzle-orm';
|
|
11
11
|
import 'drizzle-orm/node-postgres';
|
|
12
12
|
import 'drizzle-orm/pg-core';
|
package/dist/table/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { createTablePage } from './page.js';
|
|
|
6
6
|
export { OrderedTableProps, Table, TableColumnOptions, TableColumnProps } from './table.js';
|
|
7
7
|
export { TableLoaderOptions, loadTable } from './load_table.js';
|
|
8
8
|
export { LoadedModel, TableForm, TablePageOptions } from './table_form.js';
|
|
9
|
-
export {
|
|
9
|
+
export { TableLoaderData, useTable } from './use_table.js';
|
|
10
10
|
import 'drizzle-orm';
|
|
11
11
|
import 'drizzle-orm/node-postgres';
|
|
12
12
|
import 'drizzle-orm/pg-core';
|
package/dist/table/index.js
CHANGED
|
@@ -79,6 +79,10 @@ var BaseTableRepository = class {
|
|
|
79
79
|
async delete(pk) {
|
|
80
80
|
await this.db.delete(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk));
|
|
81
81
|
}
|
|
82
|
+
async select(key) {
|
|
83
|
+
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
84
|
+
return rows.map((row) => row.value);
|
|
85
|
+
}
|
|
82
86
|
};
|
|
83
87
|
|
|
84
88
|
// src/table/buttons.tsx
|
|
@@ -184,11 +188,22 @@ async function loadTable({
|
|
|
184
188
|
const offset = Number(searchParams.get("offset") ?? "0");
|
|
185
189
|
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
186
190
|
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
191
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
192
|
+
const param = searchParams.get(key);
|
|
193
|
+
if (param) {
|
|
194
|
+
return (0, import_drizzle_orm2.eq)(
|
|
195
|
+
repository.schema[key],
|
|
196
|
+
decodeURIComponent(param)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
}).filter(Boolean);
|
|
187
201
|
const whereClauses = (0, import_drizzle_orm2.and)(
|
|
188
202
|
searchKey && query ? (0, import_drizzle_orm2.ilike)(
|
|
189
203
|
repository.schema[searchKey],
|
|
190
204
|
`%${query}%`
|
|
191
205
|
) : void 0,
|
|
206
|
+
...filterWhere,
|
|
192
207
|
...where ?? []
|
|
193
208
|
);
|
|
194
209
|
const total = await repository.countTotal({ where: whereClauses });
|
|
@@ -199,6 +214,14 @@ async function loadTable({
|
|
|
199
214
|
offset,
|
|
200
215
|
where: whereClauses
|
|
201
216
|
});
|
|
217
|
+
const filters = Object.fromEntries(
|
|
218
|
+
await Promise.all(
|
|
219
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
220
|
+
const values = await repository.select(key);
|
|
221
|
+
return [key, values.filter(Boolean)];
|
|
222
|
+
})
|
|
223
|
+
)
|
|
224
|
+
);
|
|
202
225
|
return {
|
|
203
226
|
items,
|
|
204
227
|
total,
|
|
@@ -206,7 +229,8 @@ async function loadTable({
|
|
|
206
229
|
offset,
|
|
207
230
|
orderBy,
|
|
208
231
|
direction,
|
|
209
|
-
searchKey
|
|
232
|
+
searchKey,
|
|
233
|
+
filters
|
|
210
234
|
};
|
|
211
235
|
}
|
|
212
236
|
|
|
@@ -248,7 +272,8 @@ function Table({
|
|
|
248
272
|
limit,
|
|
249
273
|
offset,
|
|
250
274
|
orderBy,
|
|
251
|
-
direction
|
|
275
|
+
direction,
|
|
276
|
+
filters
|
|
252
277
|
}) {
|
|
253
278
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
254
279
|
const sortedArray = [...data];
|
|
@@ -256,7 +281,10 @@ function Table({
|
|
|
256
281
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
257
282
|
"table",
|
|
258
283
|
{
|
|
259
|
-
className: (0, import_utils2.cn)(
|
|
284
|
+
className: (0, import_utils2.cn)(
|
|
285
|
+
className,
|
|
286
|
+
"text-[15px] border-separate border-spacing-0"
|
|
287
|
+
),
|
|
260
288
|
children: [
|
|
261
289
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: keys.map((key) => {
|
|
262
290
|
const value = columns[key];
|
|
@@ -273,8 +301,8 @@ function Table({
|
|
|
273
301
|
"button",
|
|
274
302
|
{
|
|
275
303
|
className: (0, import_utils2.cn)(
|
|
276
|
-
orderBy === key ? "text-
|
|
277
|
-
"px-4
|
|
304
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
305
|
+
"px-4 flex items-center w-full"
|
|
278
306
|
),
|
|
279
307
|
onClick: () => {
|
|
280
308
|
let newDirection = "asc";
|
|
@@ -295,14 +323,59 @@ function Table({
|
|
|
295
323
|
}
|
|
296
324
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: reactNode });
|
|
297
325
|
}
|
|
298
|
-
|
|
326
|
+
const filter = filters[key];
|
|
327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
328
|
+
"th",
|
|
329
|
+
{
|
|
330
|
+
className: (0, import_utils2.cn)(
|
|
331
|
+
"py-4 border-y font-normal align-top"
|
|
332
|
+
),
|
|
333
|
+
children: [
|
|
334
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Head, {}),
|
|
335
|
+
filter && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "px-3 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
336
|
+
"select",
|
|
337
|
+
{
|
|
338
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
339
|
+
onChange: (e) => {
|
|
340
|
+
const value2 = e.target.value;
|
|
341
|
+
setSearchParams((prev) => {
|
|
342
|
+
if (value2) {
|
|
343
|
+
prev.set(
|
|
344
|
+
key,
|
|
345
|
+
encodeURIComponent(
|
|
346
|
+
value2
|
|
347
|
+
)
|
|
348
|
+
);
|
|
349
|
+
} else {
|
|
350
|
+
prev.delete(key);
|
|
351
|
+
}
|
|
352
|
+
return prev;
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
children: [
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "", children: "\uC804\uCCB4" }),
|
|
357
|
+
filter.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
358
|
+
"option",
|
|
359
|
+
{
|
|
360
|
+
value: option,
|
|
361
|
+
children: option
|
|
362
|
+
},
|
|
363
|
+
option
|
|
364
|
+
))
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
) })
|
|
368
|
+
]
|
|
369
|
+
},
|
|
370
|
+
key
|
|
371
|
+
);
|
|
299
372
|
}) }) }),
|
|
300
373
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tbody", { children: [
|
|
301
374
|
sortedArray.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
302
375
|
"td",
|
|
303
376
|
{
|
|
304
377
|
colSpan: keys.length,
|
|
305
|
-
className: "px-4 h-
|
|
378
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
306
379
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
307
380
|
}
|
|
308
381
|
) }),
|
|
@@ -341,16 +414,7 @@ function Table({
|
|
|
341
414
|
var import_react_router3 = require("react-router");
|
|
342
415
|
function useTable() {
|
|
343
416
|
const { table } = (0, import_react_router3.useLoaderData)();
|
|
344
|
-
|
|
345
|
-
return {
|
|
346
|
-
items,
|
|
347
|
-
total,
|
|
348
|
-
limit,
|
|
349
|
-
offset,
|
|
350
|
-
orderBy,
|
|
351
|
-
direction,
|
|
352
|
-
searchKey
|
|
353
|
-
};
|
|
417
|
+
return table;
|
|
354
418
|
}
|
|
355
419
|
|
|
356
420
|
// src/table/table_form.tsx
|
|
@@ -360,7 +424,16 @@ function TableForm({
|
|
|
360
424
|
primaryKey = "id"
|
|
361
425
|
}) {
|
|
362
426
|
const { pathname } = (0, import_react_router4.useLocation)();
|
|
363
|
-
const {
|
|
427
|
+
const {
|
|
428
|
+
items,
|
|
429
|
+
total,
|
|
430
|
+
limit,
|
|
431
|
+
offset,
|
|
432
|
+
orderBy,
|
|
433
|
+
direction,
|
|
434
|
+
searchKey,
|
|
435
|
+
filters
|
|
436
|
+
} = useTable();
|
|
364
437
|
const navigate = (0, import_react_router4.useNavigate)();
|
|
365
438
|
const search = (query) => {
|
|
366
439
|
const searchParams2 = new URLSearchParams(window.location.search);
|
|
@@ -373,7 +446,7 @@ function TableForm({
|
|
|
373
446
|
searchKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
374
447
|
"form",
|
|
375
448
|
{
|
|
376
|
-
className: "h-
|
|
449
|
+
className: "h-20 px-4 flex items-center border-t",
|
|
377
450
|
onSubmit: (e) => {
|
|
378
451
|
e.preventDefault();
|
|
379
452
|
const formData = new FormData(e.currentTarget);
|
|
@@ -410,7 +483,8 @@ function TableForm({
|
|
|
410
483
|
limit,
|
|
411
484
|
offset,
|
|
412
485
|
orderBy,
|
|
413
|
-
direction
|
|
486
|
+
direction,
|
|
487
|
+
filters
|
|
414
488
|
}
|
|
415
489
|
),
|
|
416
490
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
package/dist/table/index.mjs
CHANGED
|
@@ -50,6 +50,10 @@ var BaseTableRepository = class {
|
|
|
50
50
|
async delete(pk) {
|
|
51
51
|
await this.db.delete(this.schema).where(eq(this.schema[this.pk], pk));
|
|
52
52
|
}
|
|
53
|
+
async select(key) {
|
|
54
|
+
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
55
|
+
return rows.map((row) => row.value);
|
|
56
|
+
}
|
|
53
57
|
};
|
|
54
58
|
|
|
55
59
|
// src/table/buttons.tsx
|
|
@@ -144,6 +148,7 @@ var tableItemloader = ({
|
|
|
144
148
|
// src/table/load_table.tsx
|
|
145
149
|
import {
|
|
146
150
|
and,
|
|
151
|
+
eq as eq2,
|
|
147
152
|
ilike
|
|
148
153
|
} from "drizzle-orm";
|
|
149
154
|
async function loadTable({
|
|
@@ -158,11 +163,22 @@ async function loadTable({
|
|
|
158
163
|
const offset = Number(searchParams.get("offset") ?? "0");
|
|
159
164
|
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
160
165
|
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
166
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
167
|
+
const param = searchParams.get(key);
|
|
168
|
+
if (param) {
|
|
169
|
+
return eq2(
|
|
170
|
+
repository.schema[key],
|
|
171
|
+
decodeURIComponent(param)
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return void 0;
|
|
175
|
+
}).filter(Boolean);
|
|
161
176
|
const whereClauses = and(
|
|
162
177
|
searchKey && query ? ilike(
|
|
163
178
|
repository.schema[searchKey],
|
|
164
179
|
`%${query}%`
|
|
165
180
|
) : void 0,
|
|
181
|
+
...filterWhere,
|
|
166
182
|
...where ?? []
|
|
167
183
|
);
|
|
168
184
|
const total = await repository.countTotal({ where: whereClauses });
|
|
@@ -173,6 +189,14 @@ async function loadTable({
|
|
|
173
189
|
offset,
|
|
174
190
|
where: whereClauses
|
|
175
191
|
});
|
|
192
|
+
const filters = Object.fromEntries(
|
|
193
|
+
await Promise.all(
|
|
194
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
195
|
+
const values = await repository.select(key);
|
|
196
|
+
return [key, values.filter(Boolean)];
|
|
197
|
+
})
|
|
198
|
+
)
|
|
199
|
+
);
|
|
176
200
|
return {
|
|
177
201
|
items,
|
|
178
202
|
total,
|
|
@@ -180,7 +204,8 @@ async function loadTable({
|
|
|
180
204
|
offset,
|
|
181
205
|
orderBy,
|
|
182
206
|
direction,
|
|
183
|
-
searchKey
|
|
207
|
+
searchKey,
|
|
208
|
+
filters
|
|
184
209
|
};
|
|
185
210
|
}
|
|
186
211
|
|
|
@@ -222,7 +247,8 @@ function Table({
|
|
|
222
247
|
limit,
|
|
223
248
|
offset,
|
|
224
249
|
orderBy,
|
|
225
|
-
direction
|
|
250
|
+
direction,
|
|
251
|
+
filters
|
|
226
252
|
}) {
|
|
227
253
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
228
254
|
const sortedArray = [...data];
|
|
@@ -230,7 +256,10 @@ function Table({
|
|
|
230
256
|
return /* @__PURE__ */ jsxs2(
|
|
231
257
|
"table",
|
|
232
258
|
{
|
|
233
|
-
className: cn2(
|
|
259
|
+
className: cn2(
|
|
260
|
+
className,
|
|
261
|
+
"text-[15px] border-separate border-spacing-0"
|
|
262
|
+
),
|
|
234
263
|
children: [
|
|
235
264
|
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: keys.map((key) => {
|
|
236
265
|
const value = columns[key];
|
|
@@ -247,8 +276,8 @@ function Table({
|
|
|
247
276
|
"button",
|
|
248
277
|
{
|
|
249
278
|
className: cn2(
|
|
250
|
-
orderBy === key ? "text-
|
|
251
|
-
"px-4
|
|
279
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
280
|
+
"px-4 flex items-center w-full"
|
|
252
281
|
),
|
|
253
282
|
onClick: () => {
|
|
254
283
|
let newDirection = "asc";
|
|
@@ -269,14 +298,59 @@ function Table({
|
|
|
269
298
|
}
|
|
270
299
|
return /* @__PURE__ */ jsx2(Fragment2, { children: reactNode });
|
|
271
300
|
}
|
|
272
|
-
|
|
301
|
+
const filter = filters[key];
|
|
302
|
+
return /* @__PURE__ */ jsxs2(
|
|
303
|
+
"th",
|
|
304
|
+
{
|
|
305
|
+
className: cn2(
|
|
306
|
+
"py-4 border-y font-normal align-top"
|
|
307
|
+
),
|
|
308
|
+
children: [
|
|
309
|
+
/* @__PURE__ */ jsx2(Head, {}),
|
|
310
|
+
filter && /* @__PURE__ */ jsx2("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs2(
|
|
311
|
+
"select",
|
|
312
|
+
{
|
|
313
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
314
|
+
onChange: (e) => {
|
|
315
|
+
const value2 = e.target.value;
|
|
316
|
+
setSearchParams((prev) => {
|
|
317
|
+
if (value2) {
|
|
318
|
+
prev.set(
|
|
319
|
+
key,
|
|
320
|
+
encodeURIComponent(
|
|
321
|
+
value2
|
|
322
|
+
)
|
|
323
|
+
);
|
|
324
|
+
} else {
|
|
325
|
+
prev.delete(key);
|
|
326
|
+
}
|
|
327
|
+
return prev;
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
children: [
|
|
331
|
+
/* @__PURE__ */ jsx2("option", { value: "", children: "\uC804\uCCB4" }),
|
|
332
|
+
filter.map((option) => /* @__PURE__ */ jsx2(
|
|
333
|
+
"option",
|
|
334
|
+
{
|
|
335
|
+
value: option,
|
|
336
|
+
children: option
|
|
337
|
+
},
|
|
338
|
+
option
|
|
339
|
+
))
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
) })
|
|
343
|
+
]
|
|
344
|
+
},
|
|
345
|
+
key
|
|
346
|
+
);
|
|
273
347
|
}) }) }),
|
|
274
348
|
/* @__PURE__ */ jsxs2("tbody", { children: [
|
|
275
349
|
sortedArray.length === 0 && /* @__PURE__ */ jsx2("tr", { children: /* @__PURE__ */ jsx2(
|
|
276
350
|
"td",
|
|
277
351
|
{
|
|
278
352
|
colSpan: keys.length,
|
|
279
|
-
className: "px-4 h-
|
|
353
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
280
354
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
281
355
|
}
|
|
282
356
|
) }),
|
|
@@ -315,16 +389,7 @@ function Table({
|
|
|
315
389
|
import { useLoaderData } from "react-router";
|
|
316
390
|
function useTable() {
|
|
317
391
|
const { table } = useLoaderData();
|
|
318
|
-
|
|
319
|
-
return {
|
|
320
|
-
items,
|
|
321
|
-
total,
|
|
322
|
-
limit,
|
|
323
|
-
offset,
|
|
324
|
-
orderBy,
|
|
325
|
-
direction,
|
|
326
|
-
searchKey
|
|
327
|
-
};
|
|
392
|
+
return table;
|
|
328
393
|
}
|
|
329
394
|
|
|
330
395
|
// src/table/table_form.tsx
|
|
@@ -334,7 +399,16 @@ function TableForm({
|
|
|
334
399
|
primaryKey = "id"
|
|
335
400
|
}) {
|
|
336
401
|
const { pathname } = useLocation2();
|
|
337
|
-
const {
|
|
402
|
+
const {
|
|
403
|
+
items,
|
|
404
|
+
total,
|
|
405
|
+
limit,
|
|
406
|
+
offset,
|
|
407
|
+
orderBy,
|
|
408
|
+
direction,
|
|
409
|
+
searchKey,
|
|
410
|
+
filters
|
|
411
|
+
} = useTable();
|
|
338
412
|
const navigate = useNavigate();
|
|
339
413
|
const search = (query) => {
|
|
340
414
|
const searchParams2 = new URLSearchParams(window.location.search);
|
|
@@ -347,7 +421,7 @@ function TableForm({
|
|
|
347
421
|
searchKey && /* @__PURE__ */ jsxs3(
|
|
348
422
|
"form",
|
|
349
423
|
{
|
|
350
|
-
className: "h-
|
|
424
|
+
className: "h-20 px-4 flex items-center border-t",
|
|
351
425
|
onSubmit: (e) => {
|
|
352
426
|
e.preventDefault();
|
|
353
427
|
const formData = new FormData(e.currentTarget);
|
|
@@ -384,7 +458,8 @@ function TableForm({
|
|
|
384
458
|
limit,
|
|
385
459
|
offset,
|
|
386
460
|
orderBy,
|
|
387
|
-
direction
|
|
461
|
+
direction,
|
|
462
|
+
filters
|
|
388
463
|
}
|
|
389
464
|
),
|
|
390
465
|
/* @__PURE__ */ jsx3(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SQLWrapper, InferSelectModel } from 'drizzle-orm';
|
|
2
|
-
import { TableRepository, ColumnOf } from './repository.mjs';
|
|
3
2
|
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { TableRepository, ColumnOf } from './repository.mjs';
|
|
4
4
|
import 'drizzle-orm/node-postgres';
|
|
5
5
|
|
|
6
6
|
type TableOptions<T extends PgTableWithColumns<any>> = {
|
|
@@ -8,6 +8,9 @@ type TableOptions<T extends PgTableWithColumns<any>> = {
|
|
|
8
8
|
searchKey?: ColumnOf<T>;
|
|
9
9
|
defaultOrderBy: keyof InferSelectModel<T>;
|
|
10
10
|
defaultDirection: "asc" | "desc";
|
|
11
|
+
filters?: {
|
|
12
|
+
[key in keyof InferSelectModel<T>]?: "auto";
|
|
13
|
+
};
|
|
11
14
|
};
|
|
12
15
|
type TableLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
13
16
|
repository: TableRepository<T, TSelect>;
|
|
@@ -25,6 +28,9 @@ declare function loadTable<T extends PgTableWithColumns<any>, TSelect>({ request
|
|
|
25
28
|
orderBy: keyof T["_"]["columns"] & string;
|
|
26
29
|
direction: "asc" | "desc";
|
|
27
30
|
searchKey: ColumnOf<T> | undefined;
|
|
31
|
+
filters: {
|
|
32
|
+
[k: string]: unknown[];
|
|
33
|
+
};
|
|
28
34
|
}>;
|
|
29
35
|
|
|
30
36
|
export { type TableLoaderOptions, loadTable };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SQLWrapper, InferSelectModel } from 'drizzle-orm';
|
|
2
|
-
import { TableRepository, ColumnOf } from './repository.js';
|
|
3
2
|
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { TableRepository, ColumnOf } from './repository.js';
|
|
4
4
|
import 'drizzle-orm/node-postgres';
|
|
5
5
|
|
|
6
6
|
type TableOptions<T extends PgTableWithColumns<any>> = {
|
|
@@ -8,6 +8,9 @@ type TableOptions<T extends PgTableWithColumns<any>> = {
|
|
|
8
8
|
searchKey?: ColumnOf<T>;
|
|
9
9
|
defaultOrderBy: keyof InferSelectModel<T>;
|
|
10
10
|
defaultDirection: "asc" | "desc";
|
|
11
|
+
filters?: {
|
|
12
|
+
[key in keyof InferSelectModel<T>]?: "auto";
|
|
13
|
+
};
|
|
11
14
|
};
|
|
12
15
|
type TableLoaderOptions<T extends PgTableWithColumns<any>, TSelect> = {
|
|
13
16
|
repository: TableRepository<T, TSelect>;
|
|
@@ -25,6 +28,9 @@ declare function loadTable<T extends PgTableWithColumns<any>, TSelect>({ request
|
|
|
25
28
|
orderBy: keyof T["_"]["columns"] & string;
|
|
26
29
|
direction: "asc" | "desc";
|
|
27
30
|
searchKey: ColumnOf<T> | undefined;
|
|
31
|
+
filters: {
|
|
32
|
+
[k: string]: unknown[];
|
|
33
|
+
};
|
|
28
34
|
}>;
|
|
29
35
|
|
|
30
36
|
export { type TableLoaderOptions, loadTable };
|
package/dist/table/load_table.js
CHANGED
|
@@ -36,11 +36,22 @@ async function loadTable({
|
|
|
36
36
|
const offset = Number(searchParams.get("offset") ?? "0");
|
|
37
37
|
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
38
38
|
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
39
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
40
|
+
const param = searchParams.get(key);
|
|
41
|
+
if (param) {
|
|
42
|
+
return (0, import_drizzle_orm.eq)(
|
|
43
|
+
repository.schema[key],
|
|
44
|
+
decodeURIComponent(param)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return void 0;
|
|
48
|
+
}).filter(Boolean);
|
|
39
49
|
const whereClauses = (0, import_drizzle_orm.and)(
|
|
40
50
|
searchKey && query ? (0, import_drizzle_orm.ilike)(
|
|
41
51
|
repository.schema[searchKey],
|
|
42
52
|
`%${query}%`
|
|
43
53
|
) : void 0,
|
|
54
|
+
...filterWhere,
|
|
44
55
|
...where ?? []
|
|
45
56
|
);
|
|
46
57
|
const total = await repository.countTotal({ where: whereClauses });
|
|
@@ -51,6 +62,14 @@ async function loadTable({
|
|
|
51
62
|
offset,
|
|
52
63
|
where: whereClauses
|
|
53
64
|
});
|
|
65
|
+
const filters = Object.fromEntries(
|
|
66
|
+
await Promise.all(
|
|
67
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
68
|
+
const values = await repository.select(key);
|
|
69
|
+
return [key, values.filter(Boolean)];
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
);
|
|
54
73
|
return {
|
|
55
74
|
items,
|
|
56
75
|
total,
|
|
@@ -58,7 +77,8 @@ async function loadTable({
|
|
|
58
77
|
offset,
|
|
59
78
|
orderBy,
|
|
60
79
|
direction,
|
|
61
|
-
searchKey
|
|
80
|
+
searchKey,
|
|
81
|
+
filters
|
|
62
82
|
};
|
|
63
83
|
}
|
|
64
84
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/table/load_table.tsx
|
|
2
2
|
import {
|
|
3
3
|
and,
|
|
4
|
+
eq,
|
|
4
5
|
ilike
|
|
5
6
|
} from "drizzle-orm";
|
|
6
7
|
async function loadTable({
|
|
@@ -15,11 +16,22 @@ async function loadTable({
|
|
|
15
16
|
const offset = Number(searchParams.get("offset") ?? "0");
|
|
16
17
|
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
17
18
|
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
19
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
20
|
+
const param = searchParams.get(key);
|
|
21
|
+
if (param) {
|
|
22
|
+
return eq(
|
|
23
|
+
repository.schema[key],
|
|
24
|
+
decodeURIComponent(param)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return void 0;
|
|
28
|
+
}).filter(Boolean);
|
|
18
29
|
const whereClauses = and(
|
|
19
30
|
searchKey && query ? ilike(
|
|
20
31
|
repository.schema[searchKey],
|
|
21
32
|
`%${query}%`
|
|
22
33
|
) : void 0,
|
|
34
|
+
...filterWhere,
|
|
23
35
|
...where ?? []
|
|
24
36
|
);
|
|
25
37
|
const total = await repository.countTotal({ where: whereClauses });
|
|
@@ -30,6 +42,14 @@ async function loadTable({
|
|
|
30
42
|
offset,
|
|
31
43
|
where: whereClauses
|
|
32
44
|
});
|
|
45
|
+
const filters = Object.fromEntries(
|
|
46
|
+
await Promise.all(
|
|
47
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
48
|
+
const values = await repository.select(key);
|
|
49
|
+
return [key, values.filter(Boolean)];
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
);
|
|
33
53
|
return {
|
|
34
54
|
items,
|
|
35
55
|
total,
|
|
@@ -37,7 +57,8 @@ async function loadTable({
|
|
|
37
57
|
offset,
|
|
38
58
|
orderBy,
|
|
39
59
|
direction,
|
|
40
|
-
searchKey
|
|
60
|
+
searchKey,
|
|
61
|
+
filters
|
|
41
62
|
};
|
|
42
63
|
}
|
|
43
64
|
export {
|
package/dist/table/loader.d.mts
CHANGED
|
@@ -14,6 +14,9 @@ declare function tableLoader<T extends PgTableWithColumns<any>, TSelect>({ repos
|
|
|
14
14
|
orderBy: keyof T["_"]["columns"] & string;
|
|
15
15
|
direction: "asc" | "desc";
|
|
16
16
|
searchKey: ColumnOf<T> | undefined;
|
|
17
|
+
filters: {
|
|
18
|
+
[k: string]: unknown[];
|
|
19
|
+
};
|
|
17
20
|
};
|
|
18
21
|
}>;
|
|
19
22
|
|
package/dist/table/loader.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ declare function tableLoader<T extends PgTableWithColumns<any>, TSelect>({ repos
|
|
|
14
14
|
orderBy: keyof T["_"]["columns"] & string;
|
|
15
15
|
direction: "asc" | "desc";
|
|
16
16
|
searchKey: ColumnOf<T> | undefined;
|
|
17
|
+
filters: {
|
|
18
|
+
[k: string]: unknown[];
|
|
19
|
+
};
|
|
17
20
|
};
|
|
18
21
|
}>;
|
|
19
22
|
|