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
package/dist/table/loader.js
CHANGED
|
@@ -38,11 +38,22 @@ async function loadTable({
|
|
|
38
38
|
const offset = Number(searchParams.get("offset") ?? "0");
|
|
39
39
|
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
40
40
|
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
41
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
42
|
+
const param = searchParams.get(key);
|
|
43
|
+
if (param) {
|
|
44
|
+
return (0, import_drizzle_orm.eq)(
|
|
45
|
+
repository.schema[key],
|
|
46
|
+
decodeURIComponent(param)
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return void 0;
|
|
50
|
+
}).filter(Boolean);
|
|
41
51
|
const whereClauses = (0, import_drizzle_orm.and)(
|
|
42
52
|
searchKey && query ? (0, import_drizzle_orm.ilike)(
|
|
43
53
|
repository.schema[searchKey],
|
|
44
54
|
`%${query}%`
|
|
45
55
|
) : void 0,
|
|
56
|
+
...filterWhere,
|
|
46
57
|
...where ?? []
|
|
47
58
|
);
|
|
48
59
|
const total = await repository.countTotal({ where: whereClauses });
|
|
@@ -53,6 +64,14 @@ async function loadTable({
|
|
|
53
64
|
offset,
|
|
54
65
|
where: whereClauses
|
|
55
66
|
});
|
|
67
|
+
const filters = Object.fromEntries(
|
|
68
|
+
await Promise.all(
|
|
69
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
70
|
+
const values = await repository.select(key);
|
|
71
|
+
return [key, values.filter(Boolean)];
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
);
|
|
56
75
|
return {
|
|
57
76
|
items,
|
|
58
77
|
total,
|
|
@@ -60,7 +79,8 @@ async function loadTable({
|
|
|
60
79
|
offset,
|
|
61
80
|
orderBy,
|
|
62
81
|
direction,
|
|
63
|
-
searchKey
|
|
82
|
+
searchKey,
|
|
83
|
+
filters
|
|
64
84
|
};
|
|
65
85
|
}
|
|
66
86
|
|
package/dist/table/loader.mjs
CHANGED
|
@@ -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
|
|
package/dist/table/page.js
CHANGED
|
@@ -43,7 +43,8 @@ function Table({
|
|
|
43
43
|
limit,
|
|
44
44
|
offset,
|
|
45
45
|
orderBy,
|
|
46
|
-
direction
|
|
46
|
+
direction,
|
|
47
|
+
filters
|
|
47
48
|
}) {
|
|
48
49
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
49
50
|
const sortedArray = [...data];
|
|
@@ -51,7 +52,10 @@ function Table({
|
|
|
51
52
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
52
53
|
"table",
|
|
53
54
|
{
|
|
54
|
-
className: (0, import_utils.cn)(
|
|
55
|
+
className: (0, import_utils.cn)(
|
|
56
|
+
className,
|
|
57
|
+
"text-[15px] border-separate border-spacing-0"
|
|
58
|
+
),
|
|
55
59
|
children: [
|
|
56
60
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: keys.map((key) => {
|
|
57
61
|
const value = columns[key];
|
|
@@ -68,8 +72,8 @@ function Table({
|
|
|
68
72
|
"button",
|
|
69
73
|
{
|
|
70
74
|
className: (0, import_utils.cn)(
|
|
71
|
-
orderBy === key ? "text-
|
|
72
|
-
"px-4
|
|
75
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
76
|
+
"px-4 flex items-center w-full"
|
|
73
77
|
),
|
|
74
78
|
onClick: () => {
|
|
75
79
|
let newDirection = "asc";
|
|
@@ -90,14 +94,59 @@ function Table({
|
|
|
90
94
|
}
|
|
91
95
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: reactNode });
|
|
92
96
|
}
|
|
93
|
-
|
|
97
|
+
const filter = filters[key];
|
|
98
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
99
|
+
"th",
|
|
100
|
+
{
|
|
101
|
+
className: (0, import_utils.cn)(
|
|
102
|
+
"py-4 border-y font-normal align-top"
|
|
103
|
+
),
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Head, {}),
|
|
106
|
+
filter && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-3 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
107
|
+
"select",
|
|
108
|
+
{
|
|
109
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
110
|
+
onChange: (e) => {
|
|
111
|
+
const value2 = e.target.value;
|
|
112
|
+
setSearchParams((prev) => {
|
|
113
|
+
if (value2) {
|
|
114
|
+
prev.set(
|
|
115
|
+
key,
|
|
116
|
+
encodeURIComponent(
|
|
117
|
+
value2
|
|
118
|
+
)
|
|
119
|
+
);
|
|
120
|
+
} else {
|
|
121
|
+
prev.delete(key);
|
|
122
|
+
}
|
|
123
|
+
return prev;
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\uC804\uCCB4" }),
|
|
128
|
+
filter.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
129
|
+
"option",
|
|
130
|
+
{
|
|
131
|
+
value: option,
|
|
132
|
+
children: option
|
|
133
|
+
},
|
|
134
|
+
option
|
|
135
|
+
))
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
) })
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
key
|
|
142
|
+
);
|
|
94
143
|
}) }) }),
|
|
95
144
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
|
|
96
145
|
sortedArray.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
97
146
|
"td",
|
|
98
147
|
{
|
|
99
148
|
colSpan: keys.length,
|
|
100
|
-
className: "px-4 h-
|
|
149
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
101
150
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
102
151
|
}
|
|
103
152
|
) }),
|
|
@@ -136,16 +185,7 @@ function Table({
|
|
|
136
185
|
var import_react_router2 = require("react-router");
|
|
137
186
|
function useTable() {
|
|
138
187
|
const { table } = (0, import_react_router2.useLoaderData)();
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
items,
|
|
142
|
-
total,
|
|
143
|
-
limit,
|
|
144
|
-
offset,
|
|
145
|
-
orderBy,
|
|
146
|
-
direction,
|
|
147
|
-
searchKey
|
|
148
|
-
};
|
|
188
|
+
return table;
|
|
149
189
|
}
|
|
150
190
|
|
|
151
191
|
// src/table/buttons.tsx
|
|
@@ -228,7 +268,16 @@ function TableForm({
|
|
|
228
268
|
primaryKey = "id"
|
|
229
269
|
}) {
|
|
230
270
|
const { pathname } = (0, import_react_router4.useLocation)();
|
|
231
|
-
const {
|
|
271
|
+
const {
|
|
272
|
+
items,
|
|
273
|
+
total,
|
|
274
|
+
limit,
|
|
275
|
+
offset,
|
|
276
|
+
orderBy,
|
|
277
|
+
direction,
|
|
278
|
+
searchKey,
|
|
279
|
+
filters
|
|
280
|
+
} = useTable();
|
|
232
281
|
const navigate = (0, import_react_router4.useNavigate)();
|
|
233
282
|
const search = (query) => {
|
|
234
283
|
const searchParams2 = new URLSearchParams(window.location.search);
|
|
@@ -241,7 +290,7 @@ function TableForm({
|
|
|
241
290
|
searchKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
242
291
|
"form",
|
|
243
292
|
{
|
|
244
|
-
className: "h-
|
|
293
|
+
className: "h-20 px-4 flex items-center border-t",
|
|
245
294
|
onSubmit: (e) => {
|
|
246
295
|
e.preventDefault();
|
|
247
296
|
const formData = new FormData(e.currentTarget);
|
|
@@ -278,7 +327,8 @@ function TableForm({
|
|
|
278
327
|
limit,
|
|
279
328
|
offset,
|
|
280
329
|
orderBy,
|
|
281
|
-
direction
|
|
330
|
+
direction,
|
|
331
|
+
filters
|
|
282
332
|
}
|
|
283
333
|
),
|
|
284
334
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
package/dist/table/page.mjs
CHANGED
|
@@ -19,7 +19,8 @@ function Table({
|
|
|
19
19
|
limit,
|
|
20
20
|
offset,
|
|
21
21
|
orderBy,
|
|
22
|
-
direction
|
|
22
|
+
direction,
|
|
23
|
+
filters
|
|
23
24
|
}) {
|
|
24
25
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
25
26
|
const sortedArray = [...data];
|
|
@@ -27,7 +28,10 @@ function Table({
|
|
|
27
28
|
return /* @__PURE__ */ jsxs(
|
|
28
29
|
"table",
|
|
29
30
|
{
|
|
30
|
-
className: cn(
|
|
31
|
+
className: cn(
|
|
32
|
+
className,
|
|
33
|
+
"text-[15px] border-separate border-spacing-0"
|
|
34
|
+
),
|
|
31
35
|
children: [
|
|
32
36
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: keys.map((key) => {
|
|
33
37
|
const value = columns[key];
|
|
@@ -44,8 +48,8 @@ function Table({
|
|
|
44
48
|
"button",
|
|
45
49
|
{
|
|
46
50
|
className: cn(
|
|
47
|
-
orderBy === key ? "text-
|
|
48
|
-
"px-4
|
|
51
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
52
|
+
"px-4 flex items-center w-full"
|
|
49
53
|
),
|
|
50
54
|
onClick: () => {
|
|
51
55
|
let newDirection = "asc";
|
|
@@ -66,14 +70,59 @@ function Table({
|
|
|
66
70
|
}
|
|
67
71
|
return /* @__PURE__ */ jsx(Fragment, { children: reactNode });
|
|
68
72
|
}
|
|
69
|
-
|
|
73
|
+
const filter = filters[key];
|
|
74
|
+
return /* @__PURE__ */ jsxs(
|
|
75
|
+
"th",
|
|
76
|
+
{
|
|
77
|
+
className: cn(
|
|
78
|
+
"py-4 border-y font-normal align-top"
|
|
79
|
+
),
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ jsx(Head, {}),
|
|
82
|
+
filter && /* @__PURE__ */ jsx("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs(
|
|
83
|
+
"select",
|
|
84
|
+
{
|
|
85
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
86
|
+
onChange: (e) => {
|
|
87
|
+
const value2 = e.target.value;
|
|
88
|
+
setSearchParams((prev) => {
|
|
89
|
+
if (value2) {
|
|
90
|
+
prev.set(
|
|
91
|
+
key,
|
|
92
|
+
encodeURIComponent(
|
|
93
|
+
value2
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
prev.delete(key);
|
|
98
|
+
}
|
|
99
|
+
return prev;
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
children: [
|
|
103
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "\uC804\uCCB4" }),
|
|
104
|
+
filter.map((option) => /* @__PURE__ */ jsx(
|
|
105
|
+
"option",
|
|
106
|
+
{
|
|
107
|
+
value: option,
|
|
108
|
+
children: option
|
|
109
|
+
},
|
|
110
|
+
option
|
|
111
|
+
))
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
) })
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
key
|
|
118
|
+
);
|
|
70
119
|
}) }) }),
|
|
71
120
|
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
72
121
|
sortedArray.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
73
122
|
"td",
|
|
74
123
|
{
|
|
75
124
|
colSpan: keys.length,
|
|
76
|
-
className: "px-4 h-
|
|
125
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
77
126
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
78
127
|
}
|
|
79
128
|
) }),
|
|
@@ -112,16 +161,7 @@ function Table({
|
|
|
112
161
|
import { useLoaderData } from "react-router";
|
|
113
162
|
function useTable() {
|
|
114
163
|
const { table } = useLoaderData();
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
items,
|
|
118
|
-
total,
|
|
119
|
-
limit,
|
|
120
|
-
offset,
|
|
121
|
-
orderBy,
|
|
122
|
-
direction,
|
|
123
|
-
searchKey
|
|
124
|
-
};
|
|
164
|
+
return table;
|
|
125
165
|
}
|
|
126
166
|
|
|
127
167
|
// src/table/buttons.tsx
|
|
@@ -204,7 +244,16 @@ function TableForm({
|
|
|
204
244
|
primaryKey = "id"
|
|
205
245
|
}) {
|
|
206
246
|
const { pathname } = useLocation2();
|
|
207
|
-
const {
|
|
247
|
+
const {
|
|
248
|
+
items,
|
|
249
|
+
total,
|
|
250
|
+
limit,
|
|
251
|
+
offset,
|
|
252
|
+
orderBy,
|
|
253
|
+
direction,
|
|
254
|
+
searchKey,
|
|
255
|
+
filters
|
|
256
|
+
} = useTable();
|
|
208
257
|
const navigate = useNavigate();
|
|
209
258
|
const search = (query) => {
|
|
210
259
|
const searchParams2 = new URLSearchParams(window.location.search);
|
|
@@ -217,7 +266,7 @@ function TableForm({
|
|
|
217
266
|
searchKey && /* @__PURE__ */ jsxs3(
|
|
218
267
|
"form",
|
|
219
268
|
{
|
|
220
|
-
className: "h-
|
|
269
|
+
className: "h-20 px-4 flex items-center border-t",
|
|
221
270
|
onSubmit: (e) => {
|
|
222
271
|
e.preventDefault();
|
|
223
272
|
const formData = new FormData(e.currentTarget);
|
|
@@ -254,7 +303,8 @@ function TableForm({
|
|
|
254
303
|
limit,
|
|
255
304
|
offset,
|
|
256
305
|
orderBy,
|
|
257
|
-
direction
|
|
306
|
+
direction,
|
|
307
|
+
filters
|
|
258
308
|
}
|
|
259
309
|
),
|
|
260
310
|
/* @__PURE__ */ jsx3(
|
|
@@ -21,20 +21,22 @@ interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSele
|
|
|
21
21
|
findAll: (options: FindAllOptions<T>) => Promise<TSelect[]>;
|
|
22
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
23
23
|
delete: (id: string) => Promise<void>;
|
|
24
|
+
select(key: keyof InferSelectModel<T>): Promise<InferSelectModel<T>[typeof key][]>;
|
|
24
25
|
}
|
|
25
26
|
type SchemaOf<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"]> = TDatabase["_"]["fullSchema"][TSchemaKey];
|
|
26
|
-
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"],
|
|
27
|
+
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>> {
|
|
27
28
|
db: TDatabase;
|
|
28
29
|
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
29
30
|
pk: TPrimaryKey;
|
|
30
31
|
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
31
|
-
find(id: string): Promise<
|
|
32
|
+
find(id: string): Promise<TSelect | undefined>;
|
|
32
33
|
countTotal({ where }: {
|
|
33
34
|
where?: SQL<unknown>;
|
|
34
35
|
}): Promise<number>;
|
|
35
|
-
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<
|
|
36
|
-
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<
|
|
36
|
+
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect[]>;
|
|
37
|
+
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect>;
|
|
37
38
|
delete(pk: string): Promise<void>;
|
|
39
|
+
select(key: keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[typeof key][]>;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SchemaOf, type SelectModelOf, type TableRepository };
|
|
@@ -21,20 +21,22 @@ interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSele
|
|
|
21
21
|
findAll: (options: FindAllOptions<T>) => Promise<TSelect[]>;
|
|
22
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
23
23
|
delete: (id: string) => Promise<void>;
|
|
24
|
+
select(key: keyof InferSelectModel<T>): Promise<InferSelectModel<T>[typeof key][]>;
|
|
24
25
|
}
|
|
25
26
|
type SchemaOf<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"]> = TDatabase["_"]["fullSchema"][TSchemaKey];
|
|
26
|
-
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"],
|
|
27
|
+
declare class BaseTableRepository<TDatabase extends NodePgDatabase<any>, TSchemaKey extends keyof TDatabase["_"]["fullSchema"], TSelect = InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>, TPrimaryKey extends keyof TSelect = "id" extends keyof TSelect ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>> {
|
|
27
28
|
db: TDatabase;
|
|
28
29
|
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
29
30
|
pk: TPrimaryKey;
|
|
30
31
|
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
31
|
-
find(id: string): Promise<
|
|
32
|
+
find(id: string): Promise<TSelect | undefined>;
|
|
32
33
|
countTotal({ where }: {
|
|
33
34
|
where?: SQL<unknown>;
|
|
34
35
|
}): Promise<number>;
|
|
35
|
-
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<
|
|
36
|
-
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<
|
|
36
|
+
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect[]>;
|
|
37
|
+
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<TSelect>;
|
|
37
38
|
delete(pk: string): Promise<void>;
|
|
39
|
+
select(key: keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[typeof key][]>;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SchemaOf, type SelectModelOf, type TableRepository };
|
package/dist/table/repository.js
CHANGED
|
@@ -69,6 +69,10 @@ var BaseTableRepository = class {
|
|
|
69
69
|
async delete(pk) {
|
|
70
70
|
await this.db.delete(this.schema).where((0, import_drizzle_orm.eq)(this.schema[this.pk], pk));
|
|
71
71
|
}
|
|
72
|
+
async select(key) {
|
|
73
|
+
const rows = await this.db.select({ value: this.schema[key] }).from(this.schema).groupBy(this.schema[key]);
|
|
74
|
+
return rows.map((row) => row.value);
|
|
75
|
+
}
|
|
72
76
|
};
|
|
73
77
|
// Annotate the CommonJS export names for ESM import in node:
|
|
74
78
|
0 && (module.exports = {
|
|
@@ -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
|
export {
|
|
55
59
|
BaseTableRepository
|
package/dist/table/table.d.mts
CHANGED
|
@@ -22,7 +22,10 @@ type OrderedTableProps<T> = DetailedHTMLProps<TableHTMLAttributes<HTMLTableEleme
|
|
|
22
22
|
offset?: number;
|
|
23
23
|
orderBy?: string;
|
|
24
24
|
direction?: string;
|
|
25
|
+
filters: {
|
|
26
|
+
[key: string]: unknown[];
|
|
27
|
+
};
|
|
25
28
|
};
|
|
26
|
-
declare function Table<T>({ className, data, columns, mapper: Mapper, getLink, limit, offset, orderBy, direction, }: OrderedTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
29
|
+
declare function Table<T>({ className, data, columns, mapper: Mapper, getLink, limit, offset, orderBy, direction, filters, }: OrderedTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
27
30
|
|
|
28
31
|
export { type OrderedTableProps, Table, type TableColumnOptions, type TableColumnProps };
|
package/dist/table/table.d.ts
CHANGED
|
@@ -22,7 +22,10 @@ type OrderedTableProps<T> = DetailedHTMLProps<TableHTMLAttributes<HTMLTableEleme
|
|
|
22
22
|
offset?: number;
|
|
23
23
|
orderBy?: string;
|
|
24
24
|
direction?: string;
|
|
25
|
+
filters: {
|
|
26
|
+
[key: string]: unknown[];
|
|
27
|
+
};
|
|
25
28
|
};
|
|
26
|
-
declare function Table<T>({ className, data, columns, mapper: Mapper, getLink, limit, offset, orderBy, direction, }: OrderedTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
29
|
+
declare function Table<T>({ className, data, columns, mapper: Mapper, getLink, limit, offset, orderBy, direction, filters, }: OrderedTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
27
30
|
|
|
28
31
|
export { type OrderedTableProps, Table, type TableColumnOptions, type TableColumnProps };
|
package/dist/table/table.js
CHANGED
|
@@ -36,7 +36,8 @@ function Table({
|
|
|
36
36
|
limit,
|
|
37
37
|
offset,
|
|
38
38
|
orderBy,
|
|
39
|
-
direction
|
|
39
|
+
direction,
|
|
40
|
+
filters
|
|
40
41
|
}) {
|
|
41
42
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
42
43
|
const sortedArray = [...data];
|
|
@@ -44,7 +45,10 @@ function Table({
|
|
|
44
45
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
45
46
|
"table",
|
|
46
47
|
{
|
|
47
|
-
className: (0, import_utils.cn)(
|
|
48
|
+
className: (0, import_utils.cn)(
|
|
49
|
+
className,
|
|
50
|
+
"text-[15px] border-separate border-spacing-0"
|
|
51
|
+
),
|
|
48
52
|
children: [
|
|
49
53
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: keys.map((key) => {
|
|
50
54
|
const value = columns[key];
|
|
@@ -61,8 +65,8 @@ function Table({
|
|
|
61
65
|
"button",
|
|
62
66
|
{
|
|
63
67
|
className: (0, import_utils.cn)(
|
|
64
|
-
orderBy === key ? "text-
|
|
65
|
-
"px-4
|
|
68
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
69
|
+
"px-4 flex items-center w-full"
|
|
66
70
|
),
|
|
67
71
|
onClick: () => {
|
|
68
72
|
let newDirection = "asc";
|
|
@@ -83,14 +87,59 @@ function Table({
|
|
|
83
87
|
}
|
|
84
88
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: reactNode });
|
|
85
89
|
}
|
|
86
|
-
|
|
90
|
+
const filter = filters[key];
|
|
91
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
92
|
+
"th",
|
|
93
|
+
{
|
|
94
|
+
className: (0, import_utils.cn)(
|
|
95
|
+
"py-4 border-y font-normal align-top"
|
|
96
|
+
),
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Head, {}),
|
|
99
|
+
filter && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-3 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
100
|
+
"select",
|
|
101
|
+
{
|
|
102
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
103
|
+
onChange: (e) => {
|
|
104
|
+
const value2 = e.target.value;
|
|
105
|
+
setSearchParams((prev) => {
|
|
106
|
+
if (value2) {
|
|
107
|
+
prev.set(
|
|
108
|
+
key,
|
|
109
|
+
encodeURIComponent(
|
|
110
|
+
value2
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
prev.delete(key);
|
|
115
|
+
}
|
|
116
|
+
return prev;
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\uC804\uCCB4" }),
|
|
121
|
+
filter.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
122
|
+
"option",
|
|
123
|
+
{
|
|
124
|
+
value: option,
|
|
125
|
+
children: option
|
|
126
|
+
},
|
|
127
|
+
option
|
|
128
|
+
))
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
) })
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
key
|
|
135
|
+
);
|
|
87
136
|
}) }) }),
|
|
88
137
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
|
|
89
138
|
sortedArray.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
90
139
|
"td",
|
|
91
140
|
{
|
|
92
141
|
colSpan: keys.length,
|
|
93
|
-
className: "px-4 h-
|
|
142
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
94
143
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
95
144
|
}
|
|
96
145
|
) }),
|