dn-react-router-toolkit 0.8.0 → 0.9.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.
Files changed (71) hide show
  1. package/dist/api/index.js +13 -4
  2. package/dist/api/index.mjs +14 -5
  3. package/dist/api/item_api_handler.d.mts +4 -2
  4. package/dist/api/item_api_handler.d.ts +4 -2
  5. package/dist/api/item_api_handler.js +13 -4
  6. package/dist/api/item_api_handler.mjs +14 -5
  7. package/dist/crud/index.d.mts +0 -20
  8. package/dist/crud/index.d.ts +0 -20
  9. package/dist/crud/index.js +12 -8508
  10. package/dist/crud/index.mjs +0 -8516
  11. package/dist/post/index.js +67 -7705
  12. package/dist/post/index.mjs +54 -7717
  13. package/dist/post/post_form_page.js +67 -7705
  14. package/dist/post/post_form_page.mjs +54 -7717
  15. package/dist/table/index.d.mts +1 -3
  16. package/dist/table/index.d.ts +1 -3
  17. package/dist/table/index.js +83 -76
  18. package/dist/table/index.mjs +84 -74
  19. package/dist/table/load_table.d.mts +8 -2
  20. package/dist/table/load_table.d.ts +8 -2
  21. package/dist/table/load_table.js +23 -3
  22. package/dist/table/load_table.mjs +24 -3
  23. package/dist/table/loader.d.mts +3 -0
  24. package/dist/table/loader.d.ts +3 -0
  25. package/dist/table/loader.js +23 -3
  26. package/dist/table/loader.mjs +24 -3
  27. package/dist/table/repository.d.mts +6 -4
  28. package/dist/table/repository.d.ts +6 -4
  29. package/dist/table/repository.js +4 -0
  30. package/dist/table/repository.mjs +4 -0
  31. package/dist/table/table.d.mts +5 -2
  32. package/dist/table/table.d.ts +5 -2
  33. package/dist/table/table.js +38 -6
  34. package/dist/table/table.mjs +38 -6
  35. package/dist/table/table_form.d.mts +2 -2
  36. package/dist/table/table_form.d.ts +2 -2
  37. package/dist/table/table_form.js +52 -19
  38. package/dist/table/table_form.mjs +52 -19
  39. package/dist/table/use_table.d.mts +3 -3
  40. package/dist/table/use_table.d.ts +3 -3
  41. package/dist/table/use_table.js +1 -10
  42. package/dist/table/use_table.mjs +1 -10
  43. package/package.json +1 -1
  44. package/dist/crud/crud_loader.d.mts +0 -26
  45. package/dist/crud/crud_loader.d.ts +0 -26
  46. package/dist/crud/crud_loader.js +0 -322
  47. package/dist/crud/crud_loader.mjs +0 -307
  48. package/dist/crud/crud_page.d.mts +0 -32
  49. package/dist/crud/crud_page.d.ts +0 -32
  50. package/dist/crud/crud_page.js +0 -726
  51. package/dist/crud/crud_page.mjs +0 -708
  52. package/dist/crud/generate_handlers.d.mts +0 -16
  53. package/dist/crud/generate_handlers.d.ts +0 -16
  54. package/dist/crud/generate_handlers.js +0 -39
  55. package/dist/crud/generate_handlers.mjs +0 -14
  56. package/dist/crud/generate_pages.d.mts +0 -19
  57. package/dist/crud/generate_pages.d.ts +0 -19
  58. package/dist/crud/generate_pages.js +0 -55
  59. package/dist/crud/generate_pages.mjs +0 -30
  60. package/dist/crud/generate_routes.d.mts +0 -5
  61. package/dist/crud/generate_routes.d.ts +0 -5
  62. package/dist/crud/generate_routes.js +0 -7639
  63. package/dist/crud/generate_routes.mjs +0 -7627
  64. package/dist/table/item_loader.d.mts +0 -14
  65. package/dist/table/item_loader.d.ts +0 -14
  66. package/dist/table/item_loader.js +0 -43
  67. package/dist/table/item_loader.mjs +0 -18
  68. package/dist/table/page.d.mts +0 -16
  69. package/dist/table/page.d.ts +0 -16
  70. package/dist/table/page.js +0 -325
  71. package/dist/table/page.mjs +0 -300
@@ -1,12 +1,10 @@
1
1
  export { BaseTableRepository, ColumnOf, FindAllOptions, InsertModelOf, SchemaOf, SelectModelOf, TableRepository } from './repository.mjs';
2
2
  export { TablePageButtons } from './buttons.mjs';
3
- export { TableItemLoaderOptions, tableItemloader } from './item_loader.mjs';
4
3
  export { tableLoader } from './loader.mjs';
5
- export { createTablePage } from './page.mjs';
6
4
  export { OrderedTableProps, Table, TableColumnOptions, TableColumnProps } from './table.mjs';
7
5
  export { TableLoaderOptions, loadTable } from './load_table.mjs';
8
6
  export { LoadedModel, TableForm, TablePageOptions } from './table_form.mjs';
9
- export { LoadedTable, useTable } from './use_table.mjs';
7
+ export { TableLoaderData, useTable } from './use_table.mjs';
10
8
  import 'drizzle-orm';
11
9
  import 'drizzle-orm/node-postgres';
12
10
  import 'drizzle-orm/pg-core';
@@ -1,12 +1,10 @@
1
1
  export { BaseTableRepository, ColumnOf, FindAllOptions, InsertModelOf, SchemaOf, SelectModelOf, TableRepository } from './repository.js';
2
2
  export { TablePageButtons } from './buttons.js';
3
- export { TableItemLoaderOptions, tableItemloader } from './item_loader.js';
4
3
  export { tableLoader } from './loader.js';
5
- export { createTablePage } from './page.js';
6
4
  export { OrderedTableProps, Table, TableColumnOptions, TableColumnProps } from './table.js';
7
5
  export { TableLoaderOptions, loadTable } from './load_table.js';
8
6
  export { LoadedModel, TableForm, TablePageOptions } from './table_form.js';
9
- export { LoadedTable, useTable } from './use_table.js';
7
+ export { TableLoaderData, useTable } from './use_table.js';
10
8
  import 'drizzle-orm';
11
9
  import 'drizzle-orm/node-postgres';
12
10
  import 'drizzle-orm/pg-core';
@@ -24,9 +24,7 @@ __export(table_exports, {
24
24
  Table: () => Table,
25
25
  TableForm: () => TableForm,
26
26
  TablePageButtons: () => TablePageButtons,
27
- createTablePage: () => createTablePage,
28
27
  loadTable: () => loadTable,
29
- tableItemloader: () => tableItemloader,
30
28
  tableLoader: () => tableLoader,
31
29
  useTable: () => useTable
32
30
  });
@@ -79,6 +77,10 @@ var BaseTableRepository = class {
79
77
  async delete(pk) {
80
78
  await this.db.delete(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk));
81
79
  }
80
+ async select(key) {
81
+ const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
82
+ return rows.map((row) => row.value);
83
+ }
82
84
  };
83
85
 
84
86
  // src/table/buttons.tsx
@@ -154,22 +156,6 @@ function TablePageButtons({
154
156
  ] }) });
155
157
  }
156
158
 
157
- // src/table/item_loader.tsx
158
- var tableItemloader = ({
159
- repository
160
- }) => {
161
- return async (args) => {
162
- const { params } = args;
163
- if (params["itemId"] === "new") {
164
- return { item: void 0 };
165
- }
166
- const item = params["itemId"] ? await repository.find(params["itemId"]) : void 0;
167
- return {
168
- item
169
- };
170
- };
171
- };
172
-
173
159
  // src/table/load_table.tsx
174
160
  var import_drizzle_orm2 = require("drizzle-orm");
175
161
  async function loadTable({
@@ -180,16 +166,27 @@ async function loadTable({
180
166
  const searchParams = new URL(request.url).searchParams;
181
167
  const { where, searchKey, defaultOrderBy, defaultDirection } = options;
182
168
  const query = searchParams.get("query") ?? void 0;
183
- const limit = Number(searchParams.get("limit") ?? "20");
169
+ const limit = Number(searchParams.get("limit") ?? "10");
184
170
  const offset = Number(searchParams.get("offset") ?? "0");
185
171
  const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
186
172
  const direction = searchParams.get("direction") ?? defaultDirection;
173
+ const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
174
+ const param = searchParams.get(key);
175
+ if (param) {
176
+ return (0, import_drizzle_orm2.eq)(
177
+ repository.schema[key],
178
+ decodeURIComponent(param)
179
+ );
180
+ }
181
+ return void 0;
182
+ }).filter(Boolean);
187
183
  const whereClauses = (0, import_drizzle_orm2.and)(
188
184
  searchKey && query ? (0, import_drizzle_orm2.ilike)(
189
185
  repository.schema[searchKey],
190
186
  `%${query}%`
191
187
  ) : void 0,
192
- ...where ?? []
188
+ ...filterWhere,
189
+ where
193
190
  );
194
191
  const total = await repository.countTotal({ where: whereClauses });
195
192
  const items = await repository.findAll({
@@ -199,6 +196,14 @@ async function loadTable({
199
196
  offset,
200
197
  where: whereClauses
201
198
  });
199
+ const filters = Object.fromEntries(
200
+ await Promise.all(
201
+ Object.keys(options.filters ?? {}).map(async (key) => {
202
+ const values = await repository.select(key);
203
+ return [key, values.filter(Boolean)];
204
+ })
205
+ )
206
+ );
202
207
  return {
203
208
  items,
204
209
  total,
@@ -206,7 +211,8 @@ async function loadTable({
206
211
  offset,
207
212
  orderBy,
208
213
  direction,
209
- searchKey
214
+ searchKey,
215
+ filters
210
216
  };
211
217
  }
212
218
 
@@ -227,13 +233,6 @@ function tableLoader({
227
233
  };
228
234
  }
229
235
 
230
- // src/table/page.tsx
231
- var import_react_router5 = require("react-router");
232
-
233
- // src/table/table_form.tsx
234
- var import_react_router4 = require("react-router");
235
- var import_go2 = require("react-icons/go");
236
-
237
236
  // src/table/table.tsx
238
237
  var import_utils2 = require("dn-react-toolkit/utils");
239
238
  var import_go = require("react-icons/go");
@@ -248,7 +247,8 @@ function Table({
248
247
  limit,
249
248
  offset,
250
249
  orderBy,
251
- direction
250
+ direction,
251
+ filters
252
252
  }) {
253
253
  const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
254
254
  const sortedArray = [...data];
@@ -273,8 +273,8 @@ function Table({
273
273
  "button",
274
274
  {
275
275
  className: (0, import_utils2.cn)(
276
- orderBy === key ? "text-neutral-900 font-medium" : "text-neutral-500",
277
- "px-4 h-14 flex items-center w-full"
276
+ orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
277
+ "px-4 flex items-center w-full"
278
278
  ),
279
279
  onClick: () => {
280
280
  let newDirection = "asc";
@@ -295,14 +295,45 @@ function Table({
295
295
  }
296
296
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: reactNode });
297
297
  }
298
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { className: (0, import_utils2.cn)("border-y font-normal"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Head, {}) }, key);
298
+ const filter = filters?.[key];
299
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
300
+ "th",
301
+ {
302
+ className: (0, import_utils2.cn)("py-4 border-y font-normal align-top"),
303
+ children: [
304
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Head, {}),
305
+ filter && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "px-3 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
306
+ "select",
307
+ {
308
+ className: "w-full h-10 px-1.5 border rounded-full outline-none",
309
+ onChange: (e) => {
310
+ const value2 = e.target.value;
311
+ setSearchParams((prev) => {
312
+ if (value2) {
313
+ prev.set(key, encodeURIComponent(value2));
314
+ } else {
315
+ prev.delete(key);
316
+ }
317
+ return prev;
318
+ });
319
+ },
320
+ children: [
321
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "", children: "\uC804\uCCB4" }),
322
+ filter.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: option, children: option }, option))
323
+ ]
324
+ }
325
+ ) })
326
+ ]
327
+ },
328
+ key
329
+ );
299
330
  }) }) }),
300
331
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tbody", { children: [
301
332
  sortedArray.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
302
333
  "td",
303
334
  {
304
335
  colSpan: keys.length,
305
- className: "px-4 h-14 text-neutral-400 text-center",
336
+ className: "px-4 h-20 text-gray-400 text-center",
306
337
  children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
307
338
  }
308
339
  ) }),
@@ -327,7 +358,7 @@ function Table({
327
358
  className: "block content-center px-4 w-full h-full",
328
359
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Content, {})
329
360
  }
330
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Content, {});
361
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "px-4 w-full h-full content-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Content, {}) });
331
362
  const cell = Mapper ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Mapper, { item, index: i2, children: linkedContent }) : linkedContent;
332
363
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "px-0 h-14 border-b", children: cell }, key);
333
364
  }) }, i))
@@ -337,20 +368,15 @@ function Table({
337
368
  );
338
369
  }
339
370
 
371
+ // src/table/table_form.tsx
372
+ var import_react_router4 = require("react-router");
373
+ var import_go2 = require("react-icons/go");
374
+
340
375
  // src/table/use_table.tsx
341
376
  var import_react_router3 = require("react-router");
342
377
  function useTable() {
343
378
  const { table } = (0, import_react_router3.useLoaderData)();
344
- const { items, total, limit, offset, orderBy, direction, searchKey } = table;
345
- return {
346
- items,
347
- total,
348
- limit,
349
- offset,
350
- orderBy,
351
- direction,
352
- searchKey
353
- };
379
+ return table;
354
380
  }
355
381
 
356
382
  // src/table/table_form.tsx
@@ -360,7 +386,16 @@ function TableForm({
360
386
  primaryKey = "id"
361
387
  }) {
362
388
  const { pathname } = (0, import_react_router4.useLocation)();
363
- const { items, total, limit, offset, orderBy, direction, searchKey } = useTable();
389
+ const {
390
+ items,
391
+ total,
392
+ limit,
393
+ offset,
394
+ orderBy,
395
+ direction,
396
+ searchKey,
397
+ filters
398
+ } = useTable();
364
399
  const navigate = (0, import_react_router4.useNavigate)();
365
400
  const search = (query) => {
366
401
  const searchParams2 = new URLSearchParams(window.location.search);
@@ -373,7 +408,7 @@ function TableForm({
373
408
  searchKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
374
409
  "form",
375
410
  {
376
- className: "h-18 px-4 flex items-center border-t",
411
+ className: "h-20 px-4 flex items-center border-t",
377
412
  onSubmit: (e) => {
378
413
  e.preventDefault();
379
414
  const formData = new FormData(e.currentTarget);
@@ -410,7 +445,8 @@ function TableForm({
410
445
  limit,
411
446
  offset,
412
447
  orderBy,
413
- direction
448
+ direction,
449
+ filters
414
450
  }
415
451
  ),
416
452
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -424,42 +460,13 @@ function TableForm({
424
460
  )
425
461
  ] });
426
462
  }
427
-
428
- // src/table/page.tsx
429
- var import_jsx_runtime4 = require("react/jsx-runtime");
430
- function createTablePage({
431
- name,
432
- columns,
433
- primaryKey = "id"
434
- }) {
435
- return function TablePage({
436
- header: Header
437
- }) {
438
- const { pathname } = (0, import_react_router5.useLocation)();
439
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
440
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
441
- Header,
442
- {
443
- title: name,
444
- actions: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_router5.Link, { to: `${pathname}/new`, className: "button-primary", children: [
445
- name,
446
- " \uCD94\uAC00"
447
- ] })
448
- }
449
- ),
450
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TableForm, { columns, primaryKey }) })
451
- ] });
452
- };
453
- }
454
463
  // Annotate the CommonJS export names for ESM import in node:
455
464
  0 && (module.exports = {
456
465
  BaseTableRepository,
457
466
  Table,
458
467
  TableForm,
459
468
  TablePageButtons,
460
- createTablePage,
461
469
  loadTable,
462
- tableItemloader,
463
470
  tableLoader,
464
471
  useTable
465
472
  });
@@ -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
@@ -125,25 +129,10 @@ function TablePageButtons({
125
129
  ] }) });
126
130
  }
127
131
 
128
- // src/table/item_loader.tsx
129
- var tableItemloader = ({
130
- repository
131
- }) => {
132
- return async (args) => {
133
- const { params } = args;
134
- if (params["itemId"] === "new") {
135
- return { item: void 0 };
136
- }
137
- const item = params["itemId"] ? await repository.find(params["itemId"]) : void 0;
138
- return {
139
- item
140
- };
141
- };
142
- };
143
-
144
132
  // src/table/load_table.tsx
145
133
  import {
146
134
  and,
135
+ eq as eq2,
147
136
  ilike
148
137
  } from "drizzle-orm";
149
138
  async function loadTable({
@@ -154,16 +143,27 @@ async function loadTable({
154
143
  const searchParams = new URL(request.url).searchParams;
155
144
  const { where, searchKey, defaultOrderBy, defaultDirection } = options;
156
145
  const query = searchParams.get("query") ?? void 0;
157
- const limit = Number(searchParams.get("limit") ?? "20");
146
+ const limit = Number(searchParams.get("limit") ?? "10");
158
147
  const offset = Number(searchParams.get("offset") ?? "0");
159
148
  const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
160
149
  const direction = searchParams.get("direction") ?? defaultDirection;
150
+ const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
151
+ const param = searchParams.get(key);
152
+ if (param) {
153
+ return eq2(
154
+ repository.schema[key],
155
+ decodeURIComponent(param)
156
+ );
157
+ }
158
+ return void 0;
159
+ }).filter(Boolean);
161
160
  const whereClauses = and(
162
161
  searchKey && query ? ilike(
163
162
  repository.schema[searchKey],
164
163
  `%${query}%`
165
164
  ) : void 0,
166
- ...where ?? []
165
+ ...filterWhere,
166
+ where
167
167
  );
168
168
  const total = await repository.countTotal({ where: whereClauses });
169
169
  const items = await repository.findAll({
@@ -173,6 +173,14 @@ async function loadTable({
173
173
  offset,
174
174
  where: whereClauses
175
175
  });
176
+ const filters = Object.fromEntries(
177
+ await Promise.all(
178
+ Object.keys(options.filters ?? {}).map(async (key) => {
179
+ const values = await repository.select(key);
180
+ return [key, values.filter(Boolean)];
181
+ })
182
+ )
183
+ );
176
184
  return {
177
185
  items,
178
186
  total,
@@ -180,7 +188,8 @@ async function loadTable({
180
188
  offset,
181
189
  orderBy,
182
190
  direction,
183
- searchKey
191
+ searchKey,
192
+ filters
184
193
  };
185
194
  }
186
195
 
@@ -201,13 +210,6 @@ function tableLoader({
201
210
  };
202
211
  }
203
212
 
204
- // src/table/page.tsx
205
- import { Link as Link3, useLocation as useLocation3 } from "react-router";
206
-
207
- // src/table/table_form.tsx
208
- import { useLocation as useLocation2, useNavigate, useSearchParams as useSearchParams3 } from "react-router";
209
- import { GoSearch } from "react-icons/go";
210
-
211
213
  // src/table/table.tsx
212
214
  import { cn as cn2 } from "dn-react-toolkit/utils";
213
215
  import { GoArrowDown, GoArrowUp } from "react-icons/go";
@@ -222,7 +224,8 @@ function Table({
222
224
  limit,
223
225
  offset,
224
226
  orderBy,
225
- direction
227
+ direction,
228
+ filters
226
229
  }) {
227
230
  const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
228
231
  const sortedArray = [...data];
@@ -247,8 +250,8 @@ function Table({
247
250
  "button",
248
251
  {
249
252
  className: cn2(
250
- orderBy === key ? "text-neutral-900 font-medium" : "text-neutral-500",
251
- "px-4 h-14 flex items-center w-full"
253
+ orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
254
+ "px-4 flex items-center w-full"
252
255
  ),
253
256
  onClick: () => {
254
257
  let newDirection = "asc";
@@ -269,14 +272,45 @@ function Table({
269
272
  }
270
273
  return /* @__PURE__ */ jsx2(Fragment2, { children: reactNode });
271
274
  }
272
- return /* @__PURE__ */ jsx2("th", { className: cn2("border-y font-normal"), children: /* @__PURE__ */ jsx2(Head, {}) }, key);
275
+ const filter = filters?.[key];
276
+ return /* @__PURE__ */ jsxs2(
277
+ "th",
278
+ {
279
+ className: cn2("py-4 border-y font-normal align-top"),
280
+ children: [
281
+ /* @__PURE__ */ jsx2(Head, {}),
282
+ filter && /* @__PURE__ */ jsx2("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs2(
283
+ "select",
284
+ {
285
+ className: "w-full h-10 px-1.5 border rounded-full outline-none",
286
+ onChange: (e) => {
287
+ const value2 = e.target.value;
288
+ setSearchParams((prev) => {
289
+ if (value2) {
290
+ prev.set(key, encodeURIComponent(value2));
291
+ } else {
292
+ prev.delete(key);
293
+ }
294
+ return prev;
295
+ });
296
+ },
297
+ children: [
298
+ /* @__PURE__ */ jsx2("option", { value: "", children: "\uC804\uCCB4" }),
299
+ filter.map((option) => /* @__PURE__ */ jsx2("option", { value: option, children: option }, option))
300
+ ]
301
+ }
302
+ ) })
303
+ ]
304
+ },
305
+ key
306
+ );
273
307
  }) }) }),
274
308
  /* @__PURE__ */ jsxs2("tbody", { children: [
275
309
  sortedArray.length === 0 && /* @__PURE__ */ jsx2("tr", { children: /* @__PURE__ */ jsx2(
276
310
  "td",
277
311
  {
278
312
  colSpan: keys.length,
279
- className: "px-4 h-14 text-neutral-400 text-center",
313
+ className: "px-4 h-20 text-gray-400 text-center",
280
314
  children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
281
315
  }
282
316
  ) }),
@@ -301,7 +335,7 @@ function Table({
301
335
  className: "block content-center px-4 w-full h-full",
302
336
  children: /* @__PURE__ */ jsx2(Content, {})
303
337
  }
304
- ) : /* @__PURE__ */ jsx2(Content, {});
338
+ ) : /* @__PURE__ */ jsx2("div", { className: "px-4 w-full h-full content-center", children: /* @__PURE__ */ jsx2(Content, {}) });
305
339
  const cell = Mapper ? /* @__PURE__ */ jsx2(Mapper, { item, index: i2, children: linkedContent }) : linkedContent;
306
340
  return /* @__PURE__ */ jsx2("td", { className: "px-0 h-14 border-b", children: cell }, key);
307
341
  }) }, i))
@@ -311,20 +345,15 @@ function Table({
311
345
  );
312
346
  }
313
347
 
348
+ // src/table/table_form.tsx
349
+ import { useLocation as useLocation2, useNavigate, useSearchParams as useSearchParams3 } from "react-router";
350
+ import { GoSearch } from "react-icons/go";
351
+
314
352
  // src/table/use_table.tsx
315
353
  import { useLoaderData } from "react-router";
316
354
  function useTable() {
317
355
  const { table } = useLoaderData();
318
- const { items, total, limit, offset, orderBy, direction, searchKey } = table;
319
- return {
320
- items,
321
- total,
322
- limit,
323
- offset,
324
- orderBy,
325
- direction,
326
- searchKey
327
- };
356
+ return table;
328
357
  }
329
358
 
330
359
  // src/table/table_form.tsx
@@ -334,7 +363,16 @@ function TableForm({
334
363
  primaryKey = "id"
335
364
  }) {
336
365
  const { pathname } = useLocation2();
337
- const { items, total, limit, offset, orderBy, direction, searchKey } = useTable();
366
+ const {
367
+ items,
368
+ total,
369
+ limit,
370
+ offset,
371
+ orderBy,
372
+ direction,
373
+ searchKey,
374
+ filters
375
+ } = useTable();
338
376
  const navigate = useNavigate();
339
377
  const search = (query) => {
340
378
  const searchParams2 = new URLSearchParams(window.location.search);
@@ -347,7 +385,7 @@ function TableForm({
347
385
  searchKey && /* @__PURE__ */ jsxs3(
348
386
  "form",
349
387
  {
350
- className: "h-18 px-4 flex items-center border-t",
388
+ className: "h-20 px-4 flex items-center border-t",
351
389
  onSubmit: (e) => {
352
390
  e.preventDefault();
353
391
  const formData = new FormData(e.currentTarget);
@@ -384,7 +422,8 @@ function TableForm({
384
422
  limit,
385
423
  offset,
386
424
  orderBy,
387
- direction
425
+ direction,
426
+ filters
388
427
  }
389
428
  ),
390
429
  /* @__PURE__ */ jsx3(
@@ -398,41 +437,12 @@ function TableForm({
398
437
  )
399
438
  ] });
400
439
  }
401
-
402
- // src/table/page.tsx
403
- import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
404
- function createTablePage({
405
- name,
406
- columns,
407
- primaryKey = "id"
408
- }) {
409
- return function TablePage({
410
- header: Header
411
- }) {
412
- const { pathname } = useLocation3();
413
- return /* @__PURE__ */ jsxs4(Fragment4, { children: [
414
- /* @__PURE__ */ jsx4(
415
- Header,
416
- {
417
- title: name,
418
- actions: /* @__PURE__ */ jsxs4(Link3, { to: `${pathname}/new`, className: "button-primary", children: [
419
- name,
420
- " \uCD94\uAC00"
421
- ] })
422
- }
423
- ),
424
- /* @__PURE__ */ jsx4("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: /* @__PURE__ */ jsx4(TableForm, { columns, primaryKey }) })
425
- ] });
426
- };
427
- }
428
440
  export {
429
441
  BaseTableRepository,
430
442
  Table,
431
443
  TableForm,
432
444
  TablePageButtons,
433
- createTablePage,
434
445
  loadTable,
435
- tableItemloader,
436
446
  tableLoader,
437
447
  useTable
438
448
  };
@@ -1,13 +1,16 @@
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>> = {
7
- where?: SQLWrapper[];
7
+ where?: SQLWrapper;
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,13 +1,16 @@
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>> = {
7
- where?: SQLWrapper[];
7
+ where?: SQLWrapper;
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 };