dn-react-router-toolkit 0.7.14 → 0.8.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/api/create_api_handler.d.mts +5 -4
- package/dist/api/create_api_handler.d.ts +5 -4
- package/dist/api/create_api_handler.js +0 -1
- package/dist/api/create_api_handler.mjs +0 -1
- package/dist/api/index.d.mts +1 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +0 -2
- package/dist/api/index.mjs +0 -2
- package/dist/api/item_api_handler.d.mts +5 -4
- package/dist/api/item_api_handler.d.ts +5 -4
- package/dist/api/item_api_handler.js +0 -1
- package/dist/api/item_api_handler.mjs +0 -1
- package/dist/auth/cookie_manager.d.mts +2 -1
- package/dist/auth/cookie_manager.d.ts +2 -1
- package/dist/auth/cookie_manager.js +9 -3
- package/dist/auth/cookie_manager.mjs +9 -3
- package/dist/auth/index.js +9 -3
- package/dist/auth/index.mjs +9 -3
- package/dist/crud/crud_form.js +1 -1
- package/dist/crud/crud_form.mjs +1 -1
- package/dist/crud/crud_loader.d.mts +6 -5
- package/dist/crud/crud_loader.d.ts +6 -5
- package/dist/crud/crud_loader.js +46 -34
- package/dist/crud/crud_loader.mjs +46 -34
- package/dist/crud/crud_page.d.mts +3 -2
- package/dist/crud/crud_page.d.ts +3 -2
- package/dist/crud/crud_page.js +226 -198
- package/dist/crud/crud_page.mjs +224 -202
- package/dist/crud/generate_handlers.d.mts +3 -2
- package/dist/crud/generate_handlers.d.ts +3 -2
- package/dist/crud/generate_pages.d.mts +2 -1
- package/dist/crud/generate_pages.d.ts +2 -1
- package/dist/crud/index.d.mts +5 -3
- package/dist/crud/index.d.ts +5 -3
- package/dist/crud/index.js +246 -206
- package/dist/crud/index.mjs +252 -218
- package/dist/post/index.js +65 -58
- package/dist/post/index.mjs +68 -67
- package/dist/post/post_form_page.js +65 -58
- package/dist/post/post_form_page.mjs +68 -67
- package/dist/table/index.d.mts +7 -3
- package/dist/table/index.d.ts +7 -3
- package/dist/table/index.js +153 -105
- package/dist/table/index.mjs +149 -110
- package/dist/table/item_loader.d.mts +5 -4
- package/dist/table/item_loader.d.ts +5 -4
- package/dist/table/load_table.d.mts +30 -0
- package/dist/table/load_table.d.ts +30 -0
- package/dist/table/load_table.js +67 -0
- package/dist/table/load_table.mjs +45 -0
- package/dist/table/loader.d.mts +7 -15
- package/dist/table/loader.d.ts +7 -15
- package/dist/table/loader.js +47 -31
- package/dist/table/loader.mjs +46 -32
- package/dist/table/page.d.mts +6 -16
- package/dist/table/page.d.ts +6 -16
- package/dist/table/page.js +193 -165
- package/dist/table/page.mjs +194 -172
- package/dist/table/repository.d.mts +13 -11
- package/dist/table/repository.d.ts +13 -11
- package/dist/table/repository.js +1 -1
- package/dist/table/repository.mjs +1 -1
- package/dist/table/table_form.d.mts +13 -0
- package/dist/table/table_form.d.ts +13 -0
- package/dist/table/table_form.js +295 -0
- package/dist/table/table_form.mjs +270 -0
- package/dist/table/use_table.d.mts +4 -0
- package/dist/table/use_table.d.ts +4 -0
- package/dist/table/use_table.js +43 -0
- package/dist/table/use_table.mjs +18 -0
- package/package.json +3 -3
package/dist/table/page.mjs
CHANGED
|
@@ -1,91 +1,15 @@
|
|
|
1
1
|
// src/table/page.tsx
|
|
2
|
-
import {
|
|
3
|
-
Link as Link3,
|
|
4
|
-
useLoaderData,
|
|
5
|
-
useLocation as useLocation2,
|
|
6
|
-
useNavigate,
|
|
7
|
-
useSearchParams as useSearchParams3
|
|
8
|
-
} from "react-router";
|
|
9
|
-
import { GoSearch } from "react-icons/go";
|
|
2
|
+
import { Link as Link3, useLocation as useLocation3 } from "react-router";
|
|
10
3
|
|
|
11
|
-
// src/table/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
-
function TablePageButtons({
|
|
16
|
-
MAX_PAGES_TO_SHOW,
|
|
17
|
-
total,
|
|
18
|
-
limit,
|
|
19
|
-
offset
|
|
20
|
-
}) {
|
|
21
|
-
const pages = Math.ceil(total / limit);
|
|
22
|
-
const { pathname } = useLocation();
|
|
23
|
-
const [searchParams] = useSearchParams();
|
|
24
|
-
const currentPage = Math.floor(offset / limit) + 1;
|
|
25
|
-
const startButton = (Math.ceil(currentPage / MAX_PAGES_TO_SHOW) - 1) * MAX_PAGES_TO_SHOW;
|
|
26
|
-
const endButton = Math.min(startButton + MAX_PAGES_TO_SHOW - 1, pages);
|
|
27
|
-
return /* @__PURE__ */ jsx(Fragment, { children: pages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center my-8 gap-4 text-neutral-400", children: [
|
|
28
|
-
startButton > 1 && /* @__PURE__ */ jsx(
|
|
29
|
-
Link,
|
|
30
|
-
{
|
|
31
|
-
to: (() => {
|
|
32
|
-
searchParams.set(
|
|
33
|
-
"offset",
|
|
34
|
-
String((startButton - 1) * limit)
|
|
35
|
-
);
|
|
36
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
37
|
-
})(),
|
|
38
|
-
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
39
|
-
children: "\uC774\uC804"
|
|
40
|
-
}
|
|
41
|
-
),
|
|
42
|
-
Array.from({
|
|
43
|
-
length: Math.min(
|
|
44
|
-
MAX_PAGES_TO_SHOW,
|
|
45
|
-
pages - startButton
|
|
46
|
-
)
|
|
47
|
-
}).map((_, index) => {
|
|
48
|
-
return /* @__PURE__ */ jsx(
|
|
49
|
-
Link,
|
|
50
|
-
{
|
|
51
|
-
to: (() => {
|
|
52
|
-
searchParams.set(
|
|
53
|
-
"offset",
|
|
54
|
-
String((startButton + index) * limit)
|
|
55
|
-
);
|
|
56
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
57
|
-
})(),
|
|
58
|
-
className: cn(
|
|
59
|
-
"w-6 block text-center transition-colors",
|
|
60
|
-
currentPage === startButton + index + 1 ? "font-bold text-primary" : "hover:text-primary"
|
|
61
|
-
),
|
|
62
|
-
children: startButton + index + 1
|
|
63
|
-
},
|
|
64
|
-
index
|
|
65
|
-
);
|
|
66
|
-
}),
|
|
67
|
-
endButton < pages && /* @__PURE__ */ jsx(
|
|
68
|
-
Link,
|
|
69
|
-
{
|
|
70
|
-
to: (() => {
|
|
71
|
-
searchParams.set(
|
|
72
|
-
"offset",
|
|
73
|
-
String((endButton + 1) * limit)
|
|
74
|
-
);
|
|
75
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
76
|
-
})(),
|
|
77
|
-
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
78
|
-
children: "\uB2E4\uC74C"
|
|
79
|
-
}
|
|
80
|
-
)
|
|
81
|
-
] }) });
|
|
82
|
-
}
|
|
4
|
+
// src/table/table_form.tsx
|
|
5
|
+
import { useLocation as useLocation2, useNavigate, useSearchParams as useSearchParams3 } from "react-router";
|
|
6
|
+
import { GoSearch } from "react-icons/go";
|
|
83
7
|
|
|
84
8
|
// src/table/table.tsx
|
|
85
|
-
import { cn
|
|
9
|
+
import { cn } from "dn-react-toolkit/utils";
|
|
86
10
|
import { GoArrowDown, GoArrowUp } from "react-icons/go";
|
|
87
|
-
import { Link
|
|
88
|
-
import { Fragment
|
|
11
|
+
import { Link, useSearchParams } from "react-router";
|
|
12
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
89
13
|
function Table({
|
|
90
14
|
className = "min-w-full whitespace-nowrap",
|
|
91
15
|
data,
|
|
@@ -99,13 +23,13 @@ function Table({
|
|
|
99
23
|
}) {
|
|
100
24
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
101
25
|
const sortedArray = [...data];
|
|
102
|
-
const [_, setSearchParams] =
|
|
103
|
-
return /* @__PURE__ */
|
|
26
|
+
const [_, setSearchParams] = useSearchParams();
|
|
27
|
+
return /* @__PURE__ */ jsxs(
|
|
104
28
|
"table",
|
|
105
29
|
{
|
|
106
|
-
className:
|
|
30
|
+
className: cn(className, "text-[15px] border-separate border-spacing-0"),
|
|
107
31
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
32
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: keys.map((key) => {
|
|
109
33
|
const value = columns[key];
|
|
110
34
|
function getReactNode() {
|
|
111
35
|
if (value && typeof value === "object" && "label" in value) {
|
|
@@ -116,10 +40,10 @@ function Table({
|
|
|
116
40
|
function Head() {
|
|
117
41
|
const reactNode = getReactNode();
|
|
118
42
|
if (typeof reactNode === "string") {
|
|
119
|
-
return /* @__PURE__ */
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
120
44
|
"button",
|
|
121
45
|
{
|
|
122
|
-
className:
|
|
46
|
+
className: cn(
|
|
123
47
|
orderBy === key ? "text-neutral-900 font-medium" : "text-neutral-500",
|
|
124
48
|
"px-4 h-14 flex items-center w-full"
|
|
125
49
|
),
|
|
@@ -135,17 +59,17 @@ function Table({
|
|
|
135
59
|
},
|
|
136
60
|
children: [
|
|
137
61
|
reactNode,
|
|
138
|
-
orderBy === key && /* @__PURE__ */
|
|
62
|
+
orderBy === key && /* @__PURE__ */ jsx("div", { className: "ml-0.5", children: direction === "asc" ? /* @__PURE__ */ jsx(GoArrowUp, {}) : /* @__PURE__ */ jsx(GoArrowDown, {}) })
|
|
139
63
|
]
|
|
140
64
|
}
|
|
141
65
|
);
|
|
142
66
|
}
|
|
143
|
-
return /* @__PURE__ */
|
|
67
|
+
return /* @__PURE__ */ jsx(Fragment, { children: reactNode });
|
|
144
68
|
}
|
|
145
|
-
return /* @__PURE__ */
|
|
69
|
+
return /* @__PURE__ */ jsx("th", { className: cn("border-y font-normal"), children: /* @__PURE__ */ jsx(Head, {}) }, key);
|
|
146
70
|
}) }) }),
|
|
147
|
-
/* @__PURE__ */
|
|
148
|
-
sortedArray.length === 0 && /* @__PURE__ */
|
|
71
|
+
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
72
|
+
sortedArray.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
149
73
|
"td",
|
|
150
74
|
{
|
|
151
75
|
colSpan: keys.length,
|
|
@@ -153,7 +77,7 @@ function Table({
|
|
|
153
77
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
154
78
|
}
|
|
155
79
|
) }),
|
|
156
|
-
sortedArray.map((item, i) => /* @__PURE__ */
|
|
80
|
+
sortedArray.map((item, i) => /* @__PURE__ */ jsx("tr", { className: "hover:bg-gray-50 transition-colors", children: keys.map((key, i2) => {
|
|
157
81
|
const value = item[key];
|
|
158
82
|
function Content() {
|
|
159
83
|
if (key in columns) {
|
|
@@ -161,22 +85,22 @@ function Table({
|
|
|
161
85
|
if (column && typeof column === "object" && "mapper" in column) {
|
|
162
86
|
const mapper = column.mapper;
|
|
163
87
|
if (mapper) {
|
|
164
|
-
return /* @__PURE__ */
|
|
88
|
+
return /* @__PURE__ */ jsx(Fragment, { children: mapper(item) });
|
|
165
89
|
}
|
|
166
90
|
}
|
|
167
91
|
}
|
|
168
|
-
return /* @__PURE__ */
|
|
92
|
+
return /* @__PURE__ */ jsx(Fragment, { children: String(value) });
|
|
169
93
|
}
|
|
170
|
-
const linkedContent = getLink ? /* @__PURE__ */
|
|
171
|
-
|
|
94
|
+
const linkedContent = getLink ? /* @__PURE__ */ jsx(
|
|
95
|
+
Link,
|
|
172
96
|
{
|
|
173
97
|
to: getLink(item),
|
|
174
98
|
className: "block content-center px-4 w-full h-full",
|
|
175
|
-
children: /* @__PURE__ */
|
|
99
|
+
children: /* @__PURE__ */ jsx(Content, {})
|
|
176
100
|
}
|
|
177
|
-
) : /* @__PURE__ */
|
|
178
|
-
const cell = Mapper ? /* @__PURE__ */
|
|
179
|
-
return /* @__PURE__ */
|
|
101
|
+
) : /* @__PURE__ */ jsx(Content, {});
|
|
102
|
+
const cell = Mapper ? /* @__PURE__ */ jsx(Mapper, { item, index: i2, children: linkedContent }) : linkedContent;
|
|
103
|
+
return /* @__PURE__ */ jsx("td", { className: "px-0 h-14 border-b", children: cell }, key);
|
|
180
104
|
}) }, i))
|
|
181
105
|
] })
|
|
182
106
|
]
|
|
@@ -184,8 +108,169 @@ function Table({
|
|
|
184
108
|
);
|
|
185
109
|
}
|
|
186
110
|
|
|
187
|
-
// src/table/
|
|
111
|
+
// src/table/use_table.tsx
|
|
112
|
+
import { useLoaderData } from "react-router";
|
|
113
|
+
function useTable() {
|
|
114
|
+
const { table } = useLoaderData();
|
|
115
|
+
const { items, total, limit, offset, orderBy, direction, searchKey } = table;
|
|
116
|
+
return {
|
|
117
|
+
items,
|
|
118
|
+
total,
|
|
119
|
+
limit,
|
|
120
|
+
offset,
|
|
121
|
+
orderBy,
|
|
122
|
+
direction,
|
|
123
|
+
searchKey
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/table/buttons.tsx
|
|
128
|
+
import { cn as cn2 } from "dn-react-toolkit/utils";
|
|
129
|
+
import { Link as Link2, useLocation, useSearchParams as useSearchParams2 } from "react-router";
|
|
130
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
131
|
+
function TablePageButtons({
|
|
132
|
+
MAX_PAGES_TO_SHOW,
|
|
133
|
+
total,
|
|
134
|
+
limit,
|
|
135
|
+
offset
|
|
136
|
+
}) {
|
|
137
|
+
const pages = Math.ceil(total / limit);
|
|
138
|
+
const { pathname } = useLocation();
|
|
139
|
+
const [searchParams] = useSearchParams2();
|
|
140
|
+
const currentPage = Math.floor(offset / limit) + 1;
|
|
141
|
+
const startButton = (Math.ceil(currentPage / MAX_PAGES_TO_SHOW) - 1) * MAX_PAGES_TO_SHOW;
|
|
142
|
+
const endButton = Math.min(startButton + MAX_PAGES_TO_SHOW - 1, pages);
|
|
143
|
+
return /* @__PURE__ */ jsx2(Fragment2, { children: pages > 1 && /* @__PURE__ */ jsxs2("div", { className: "flex justify-center items-center my-8 gap-4 text-neutral-400", children: [
|
|
144
|
+
startButton > 1 && /* @__PURE__ */ jsx2(
|
|
145
|
+
Link2,
|
|
146
|
+
{
|
|
147
|
+
to: (() => {
|
|
148
|
+
searchParams.set(
|
|
149
|
+
"offset",
|
|
150
|
+
String((startButton - 1) * limit)
|
|
151
|
+
);
|
|
152
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
153
|
+
})(),
|
|
154
|
+
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
155
|
+
children: "\uC774\uC804"
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
Array.from({
|
|
159
|
+
length: Math.min(
|
|
160
|
+
MAX_PAGES_TO_SHOW,
|
|
161
|
+
pages - startButton
|
|
162
|
+
)
|
|
163
|
+
}).map((_, index) => {
|
|
164
|
+
return /* @__PURE__ */ jsx2(
|
|
165
|
+
Link2,
|
|
166
|
+
{
|
|
167
|
+
to: (() => {
|
|
168
|
+
searchParams.set(
|
|
169
|
+
"offset",
|
|
170
|
+
String((startButton + index) * limit)
|
|
171
|
+
);
|
|
172
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
173
|
+
})(),
|
|
174
|
+
className: cn2(
|
|
175
|
+
"w-6 block text-center transition-colors",
|
|
176
|
+
currentPage === startButton + index + 1 ? "font-bold text-primary" : "hover:text-primary"
|
|
177
|
+
),
|
|
178
|
+
children: startButton + index + 1
|
|
179
|
+
},
|
|
180
|
+
index
|
|
181
|
+
);
|
|
182
|
+
}),
|
|
183
|
+
endButton < pages && /* @__PURE__ */ jsx2(
|
|
184
|
+
Link2,
|
|
185
|
+
{
|
|
186
|
+
to: (() => {
|
|
187
|
+
searchParams.set(
|
|
188
|
+
"offset",
|
|
189
|
+
String((endButton + 1) * limit)
|
|
190
|
+
);
|
|
191
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
192
|
+
})(),
|
|
193
|
+
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
194
|
+
children: "\uB2E4\uC74C"
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
] }) });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/table/table_form.tsx
|
|
188
201
|
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
202
|
+
function TableForm({
|
|
203
|
+
columns,
|
|
204
|
+
primaryKey = "id"
|
|
205
|
+
}) {
|
|
206
|
+
const { pathname } = useLocation2();
|
|
207
|
+
const { items, total, limit, offset, orderBy, direction, searchKey } = useTable();
|
|
208
|
+
const navigate = useNavigate();
|
|
209
|
+
const search = (query) => {
|
|
210
|
+
const searchParams2 = new URLSearchParams(window.location.search);
|
|
211
|
+
searchParams2.set("query", query);
|
|
212
|
+
searchParams2.set("offset", "0");
|
|
213
|
+
navigate(`${pathname}?${searchParams2.toString()}`);
|
|
214
|
+
};
|
|
215
|
+
const [searchParams] = useSearchParams3();
|
|
216
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
217
|
+
searchKey && /* @__PURE__ */ jsxs3(
|
|
218
|
+
"form",
|
|
219
|
+
{
|
|
220
|
+
className: "h-18 px-4 flex items-center border-t",
|
|
221
|
+
onSubmit: (e) => {
|
|
222
|
+
e.preventDefault();
|
|
223
|
+
const formData = new FormData(e.currentTarget);
|
|
224
|
+
const query = formData.get("query");
|
|
225
|
+
search(query);
|
|
226
|
+
},
|
|
227
|
+
children: [
|
|
228
|
+
/* @__PURE__ */ jsx3(
|
|
229
|
+
"button",
|
|
230
|
+
{
|
|
231
|
+
type: "submit",
|
|
232
|
+
className: "w-10 h-10 flex justify-center items-center",
|
|
233
|
+
children: /* @__PURE__ */ jsx3(GoSearch, { className: "text-xl mr-4" })
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
/* @__PURE__ */ jsx3(
|
|
237
|
+
"input",
|
|
238
|
+
{
|
|
239
|
+
className: "outline-none h-full flex-1",
|
|
240
|
+
placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
|
|
241
|
+
name: "query",
|
|
242
|
+
defaultValue: searchParams.get("query") ?? ""
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
),
|
|
248
|
+
/* @__PURE__ */ jsx3(
|
|
249
|
+
Table,
|
|
250
|
+
{
|
|
251
|
+
data: items,
|
|
252
|
+
columns,
|
|
253
|
+
getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
|
|
254
|
+
limit,
|
|
255
|
+
offset,
|
|
256
|
+
orderBy,
|
|
257
|
+
direction
|
|
258
|
+
}
|
|
259
|
+
),
|
|
260
|
+
/* @__PURE__ */ jsx3(
|
|
261
|
+
TablePageButtons,
|
|
262
|
+
{
|
|
263
|
+
total,
|
|
264
|
+
limit,
|
|
265
|
+
offset,
|
|
266
|
+
MAX_PAGES_TO_SHOW: 10
|
|
267
|
+
}
|
|
268
|
+
)
|
|
269
|
+
] });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// src/table/page.tsx
|
|
273
|
+
import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
189
274
|
function createTablePage({
|
|
190
275
|
name,
|
|
191
276
|
columns,
|
|
@@ -194,82 +279,19 @@ function createTablePage({
|
|
|
194
279
|
return function TablePage({
|
|
195
280
|
header: Header
|
|
196
281
|
}) {
|
|
197
|
-
const { pathname } =
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const navigate = useNavigate();
|
|
201
|
-
const search = (query) => {
|
|
202
|
-
const searchParams2 = new URLSearchParams(window.location.search);
|
|
203
|
-
searchParams2.set("query", query);
|
|
204
|
-
searchParams2.set("offset", "0");
|
|
205
|
-
navigate(`${pathname}?${searchParams2.toString()}`);
|
|
206
|
-
};
|
|
207
|
-
const [searchParams] = useSearchParams3();
|
|
208
|
-
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
209
|
-
/* @__PURE__ */ jsx3(
|
|
282
|
+
const { pathname } = useLocation3();
|
|
283
|
+
return /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
284
|
+
/* @__PURE__ */ jsx4(
|
|
210
285
|
Header,
|
|
211
286
|
{
|
|
212
287
|
title: name,
|
|
213
|
-
actions: /* @__PURE__ */
|
|
288
|
+
actions: /* @__PURE__ */ jsxs4(Link3, { to: `${pathname}/new`, className: "button-primary", children: [
|
|
214
289
|
name,
|
|
215
290
|
" \uCD94\uAC00"
|
|
216
291
|
] })
|
|
217
292
|
}
|
|
218
293
|
),
|
|
219
|
-
/* @__PURE__ */
|
|
220
|
-
searchKey && /* @__PURE__ */ jsxs3(
|
|
221
|
-
"form",
|
|
222
|
-
{
|
|
223
|
-
className: "h-18 px-4 flex items-center border-t",
|
|
224
|
-
onSubmit: (e) => {
|
|
225
|
-
e.preventDefault();
|
|
226
|
-
const formData = new FormData(e.currentTarget);
|
|
227
|
-
const query = formData.get("query");
|
|
228
|
-
search(query);
|
|
229
|
-
},
|
|
230
|
-
children: [
|
|
231
|
-
/* @__PURE__ */ jsx3(
|
|
232
|
-
"button",
|
|
233
|
-
{
|
|
234
|
-
type: "submit",
|
|
235
|
-
className: "w-10 h-10 flex justify-center items-center",
|
|
236
|
-
children: /* @__PURE__ */ jsx3(GoSearch, { className: "text-xl mr-4" })
|
|
237
|
-
}
|
|
238
|
-
),
|
|
239
|
-
/* @__PURE__ */ jsx3(
|
|
240
|
-
"input",
|
|
241
|
-
{
|
|
242
|
-
className: "outline-none h-full flex-1",
|
|
243
|
-
placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
|
|
244
|
-
name: "query",
|
|
245
|
-
defaultValue: searchParams.get("query") ?? ""
|
|
246
|
-
}
|
|
247
|
-
)
|
|
248
|
-
]
|
|
249
|
-
}
|
|
250
|
-
),
|
|
251
|
-
/* @__PURE__ */ jsx3(
|
|
252
|
-
Table,
|
|
253
|
-
{
|
|
254
|
-
data: items,
|
|
255
|
-
columns,
|
|
256
|
-
getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
|
|
257
|
-
limit,
|
|
258
|
-
offset,
|
|
259
|
-
orderBy,
|
|
260
|
-
direction
|
|
261
|
-
}
|
|
262
|
-
),
|
|
263
|
-
/* @__PURE__ */ jsx3(
|
|
264
|
-
TablePageButtons,
|
|
265
|
-
{
|
|
266
|
-
total,
|
|
267
|
-
limit,
|
|
268
|
-
offset,
|
|
269
|
-
MAX_PAGES_TO_SHOW: 10
|
|
270
|
-
}
|
|
271
|
-
)
|
|
272
|
-
] })
|
|
294
|
+
/* @__PURE__ */ jsx4("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: /* @__PURE__ */ jsx4(TableForm, { columns, primaryKey }) })
|
|
273
295
|
] });
|
|
274
296
|
};
|
|
275
297
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InferSelectModel, SQL, InferInsertModel } from 'drizzle-orm';
|
|
2
|
+
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
2
3
|
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
4
|
|
|
4
|
-
type FindAllOptions<T extends
|
|
5
|
+
type FindAllOptions<T extends PgTableWithColumns<any>> = {
|
|
5
6
|
orderBy?: keyof InferSelectModel<T>;
|
|
6
7
|
direction?: "asc" | "desc";
|
|
7
8
|
limit?: number;
|
|
@@ -11,7 +12,7 @@ type FindAllOptions<T extends Table> = {
|
|
|
11
12
|
type ColumnOf<T> = T extends PgTableWithColumns<infer TConfig> ? keyof TConfig["columns"] : never;
|
|
12
13
|
type SelectModelOf<T> = T extends TableRepository<infer TSelect, any> ? TSelect : never;
|
|
13
14
|
type InsertModelOf<T> = T extends TableRepository<any, infer TInsert> ? TInsert : never;
|
|
14
|
-
interface TableRepository<T extends
|
|
15
|
+
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T>> {
|
|
15
16
|
schema: T;
|
|
16
17
|
find: (id: string) => Promise<TSelect | undefined>;
|
|
17
18
|
countTotal: (options: {
|
|
@@ -21,18 +22,19 @@ interface TableRepository<T extends Table, TSelect = any> {
|
|
|
21
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
22
23
|
delete: (id: string) => Promise<void>;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
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"], TPrimaryKey extends keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> = "id" extends keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>> {
|
|
27
|
+
db: TDatabase;
|
|
28
|
+
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
27
29
|
pk: TPrimaryKey;
|
|
28
|
-
constructor(db:
|
|
29
|
-
find(id: string): Promise<
|
|
30
|
+
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
31
|
+
find(id: string): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> | undefined>;
|
|
30
32
|
countTotal({ where }: {
|
|
31
33
|
where?: SQL<unknown>;
|
|
32
34
|
}): Promise<number>;
|
|
33
|
-
findAll(options: FindAllOptions<
|
|
34
|
-
save(values: InferInsertModel<
|
|
35
|
+
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[]>;
|
|
36
|
+
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>>;
|
|
35
37
|
delete(pk: string): Promise<void>;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SelectModelOf, type TableRepository };
|
|
40
|
+
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SchemaOf, type SelectModelOf, type TableRepository };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InferSelectModel, SQL, InferInsertModel } from 'drizzle-orm';
|
|
2
|
+
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
2
3
|
import { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
4
|
|
|
4
|
-
type FindAllOptions<T extends
|
|
5
|
+
type FindAllOptions<T extends PgTableWithColumns<any>> = {
|
|
5
6
|
orderBy?: keyof InferSelectModel<T>;
|
|
6
7
|
direction?: "asc" | "desc";
|
|
7
8
|
limit?: number;
|
|
@@ -11,7 +12,7 @@ type FindAllOptions<T extends Table> = {
|
|
|
11
12
|
type ColumnOf<T> = T extends PgTableWithColumns<infer TConfig> ? keyof TConfig["columns"] : never;
|
|
12
13
|
type SelectModelOf<T> = T extends TableRepository<infer TSelect, any> ? TSelect : never;
|
|
13
14
|
type InsertModelOf<T> = T extends TableRepository<any, infer TInsert> ? TInsert : never;
|
|
14
|
-
interface TableRepository<T extends
|
|
15
|
+
interface TableRepository<T extends PgTableWithColumns<any>, TSelect = InferSelectModel<T>> {
|
|
15
16
|
schema: T;
|
|
16
17
|
find: (id: string) => Promise<TSelect | undefined>;
|
|
17
18
|
countTotal: (options: {
|
|
@@ -21,18 +22,19 @@ interface TableRepository<T extends Table, TSelect = any> {
|
|
|
21
22
|
save: (values: InferInsertModel<T>) => Promise<TSelect>;
|
|
22
23
|
delete: (id: string) => Promise<void>;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
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"], TPrimaryKey extends keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> = "id" extends keyof InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> ? "id" : never> implements TableRepository<SchemaOf<TDatabase, TSchemaKey>> {
|
|
27
|
+
db: TDatabase;
|
|
28
|
+
schema: SchemaOf<TDatabase, TSchemaKey>;
|
|
27
29
|
pk: TPrimaryKey;
|
|
28
|
-
constructor(db:
|
|
29
|
-
find(id: string): Promise<
|
|
30
|
+
constructor(db: TDatabase, schema: TSchemaKey, pk?: TPrimaryKey);
|
|
31
|
+
find(id: string): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>> | undefined>;
|
|
30
32
|
countTotal({ where }: {
|
|
31
33
|
where?: SQL<unknown>;
|
|
32
34
|
}): Promise<number>;
|
|
33
|
-
findAll(options: FindAllOptions<
|
|
34
|
-
save(values: InferInsertModel<
|
|
35
|
+
findAll(options: FindAllOptions<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>[]>;
|
|
36
|
+
save(values: InferInsertModel<SchemaOf<TDatabase, TSchemaKey>>): Promise<InferSelectModel<SchemaOf<TDatabase, TSchemaKey>>>;
|
|
35
37
|
delete(pk: string): Promise<void>;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SelectModelOf, type TableRepository };
|
|
40
|
+
export { BaseTableRepository, type ColumnOf, type FindAllOptions, type InsertModelOf, type SchemaOf, type SelectModelOf, type TableRepository };
|
package/dist/table/repository.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TableColumnOptions } from './table.mjs';
|
|
3
|
+
import { LoadedTable } from './use_table.mjs';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
type TablePageOptions<TModel> = {
|
|
7
|
+
columns: TableColumnOptions<TModel>;
|
|
8
|
+
primaryKey?: keyof TModel;
|
|
9
|
+
};
|
|
10
|
+
type LoadedModel<T extends (...args: any) => any> = LoadedTable<T>["items"][number];
|
|
11
|
+
declare function TableForm<T extends (...args: any) => any>({ columns, primaryKey, }: TablePageOptions<LoadedModel<T>>): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { type LoadedModel, TableForm, type TablePageOptions };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TableColumnOptions } from './table.js';
|
|
3
|
+
import { LoadedTable } from './use_table.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
type TablePageOptions<TModel> = {
|
|
7
|
+
columns: TableColumnOptions<TModel>;
|
|
8
|
+
primaryKey?: keyof TModel;
|
|
9
|
+
};
|
|
10
|
+
type LoadedModel<T extends (...args: any) => any> = LoadedTable<T>["items"][number];
|
|
11
|
+
declare function TableForm<T extends (...args: any) => any>({ columns, primaryKey, }: TablePageOptions<LoadedModel<T>>): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { type LoadedModel, TableForm, type TablePageOptions };
|