dn-react-router-toolkit 0.7.15 → 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/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 +13 -6
- package/dist/api/index.mjs +14 -7
- package/dist/api/item_api_handler.d.mts +8 -5
- package/dist/api/item_api_handler.d.ts +8 -5
- package/dist/api/item_api_handler.js +13 -5
- package/dist/api/item_api_handler.mjs +14 -6
- package/dist/crud/crud_loader.d.mts +6 -5
- package/dist/crud/crud_loader.d.ts +6 -5
- package/dist/crud/crud_loader.js +79 -38
- package/dist/crud/crud_loader.mjs +81 -39
- package/dist/crud/crud_page.d.mts +3 -2
- package/dist/crud/crud_page.d.ts +3 -2
- package/dist/crud/crud_page.js +279 -201
- package/dist/crud/crud_page.mjs +277 -205
- 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 +338 -219
- package/dist/crud/index.mjs +346 -232
- package/dist/post/index.js +71 -64
- package/dist/post/index.mjs +76 -74
- package/dist/post/post_form_page.js +71 -64
- package/dist/post/post_form_page.mjs +76 -74
- package/dist/table/index.d.mts +7 -3
- package/dist/table/index.d.ts +7 -3
- package/dist/table/index.js +233 -111
- package/dist/table/index.mjs +230 -116
- 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 +36 -0
- package/dist/table/load_table.d.ts +36 -0
- package/dist/table/load_table.js +87 -0
- package/dist/table/load_table.mjs +66 -0
- package/dist/table/loader.d.mts +10 -15
- package/dist/table/loader.d.ts +10 -15
- package/dist/table/loader.js +67 -31
- package/dist/table/loader.mjs +67 -32
- package/dist/table/page.d.mts +6 -16
- package/dist/table/page.d.ts +6 -16
- package/dist/table/page.js +247 -169
- package/dist/table/page.mjs +248 -176
- package/dist/table/repository.d.mts +14 -10
- package/dist/table/repository.d.ts +14 -10
- package/dist/table/repository.js +5 -1
- package/dist/table/repository.mjs +5 -1
- 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 +13 -0
- package/dist/table/table_form.d.ts +13 -0
- package/dist/table/table_form.js +345 -0
- package/dist/table/table_form.mjs +320 -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 +34 -0
- package/dist/table/use_table.mjs +9 -0
- package/package.json +2 -2
package/dist/crud/index.mjs
CHANGED
|
@@ -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
|
}
|
|
@@ -7977,48 +7977,83 @@ function CrudForm({
|
|
|
7977
7977
|
] });
|
|
7978
7978
|
}
|
|
7979
7979
|
|
|
7980
|
-
// src/table/
|
|
7980
|
+
// src/table/load_table.tsx
|
|
7981
7981
|
import {
|
|
7982
7982
|
and,
|
|
7983
|
+
eq,
|
|
7983
7984
|
ilike
|
|
7984
7985
|
} from "drizzle-orm";
|
|
7986
|
+
async function loadTable({
|
|
7987
|
+
request,
|
|
7988
|
+
repository,
|
|
7989
|
+
options
|
|
7990
|
+
}) {
|
|
7991
|
+
const searchParams = new URL(request.url).searchParams;
|
|
7992
|
+
const { where, searchKey, defaultOrderBy, defaultDirection } = options;
|
|
7993
|
+
const query = searchParams.get("query") ?? void 0;
|
|
7994
|
+
const limit = Number(searchParams.get("limit") ?? "20");
|
|
7995
|
+
const offset = Number(searchParams.get("offset") ?? "0");
|
|
7996
|
+
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
7997
|
+
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
7998
|
+
const filterWhere = Object.entries(options.filters ?? {}).map(([key, value]) => {
|
|
7999
|
+
const param = searchParams.get(key);
|
|
8000
|
+
if (param) {
|
|
8001
|
+
return eq(
|
|
8002
|
+
repository.schema[key],
|
|
8003
|
+
decodeURIComponent(param)
|
|
8004
|
+
);
|
|
8005
|
+
}
|
|
8006
|
+
return void 0;
|
|
8007
|
+
}).filter(Boolean);
|
|
8008
|
+
const whereClauses = and(
|
|
8009
|
+
searchKey && query ? ilike(
|
|
8010
|
+
repository.schema[searchKey],
|
|
8011
|
+
`%${query}%`
|
|
8012
|
+
) : void 0,
|
|
8013
|
+
...filterWhere,
|
|
8014
|
+
...where ?? []
|
|
8015
|
+
);
|
|
8016
|
+
const total = await repository.countTotal({ where: whereClauses });
|
|
8017
|
+
const items = await repository.findAll({
|
|
8018
|
+
orderBy,
|
|
8019
|
+
direction,
|
|
8020
|
+
limit,
|
|
8021
|
+
offset,
|
|
8022
|
+
where: whereClauses
|
|
8023
|
+
});
|
|
8024
|
+
const filters = Object.fromEntries(
|
|
8025
|
+
await Promise.all(
|
|
8026
|
+
Object.keys(options.filters ?? {}).map(async (key) => {
|
|
8027
|
+
const values = await repository.select(key);
|
|
8028
|
+
return [key, values.filter(Boolean)];
|
|
8029
|
+
})
|
|
8030
|
+
)
|
|
8031
|
+
);
|
|
8032
|
+
return {
|
|
8033
|
+
items,
|
|
8034
|
+
total,
|
|
8035
|
+
limit,
|
|
8036
|
+
offset,
|
|
8037
|
+
orderBy,
|
|
8038
|
+
direction,
|
|
8039
|
+
searchKey,
|
|
8040
|
+
filters
|
|
8041
|
+
};
|
|
8042
|
+
}
|
|
8043
|
+
|
|
8044
|
+
// src/table/loader.tsx
|
|
7985
8045
|
function tableLoader({
|
|
7986
8046
|
repository,
|
|
7987
|
-
|
|
8047
|
+
options
|
|
7988
8048
|
}) {
|
|
7989
8049
|
return async ({ request }) => {
|
|
7990
|
-
const
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
const offset = Number(searchParams.get("offset") ?? "0");
|
|
7995
|
-
const orderBy = searchParams.get("orderBy") ?? defaultOrderBy;
|
|
7996
|
-
const direction = searchParams.get("direction") ?? defaultDirection;
|
|
7997
|
-
const whereClauses = and(
|
|
7998
|
-
searchKey && query ? ilike(
|
|
7999
|
-
repository.schema[searchKey],
|
|
8000
|
-
`%${query}%`
|
|
8001
|
-
) : void 0,
|
|
8002
|
-
...where ?? []
|
|
8003
|
-
);
|
|
8004
|
-
const total = await repository.countTotal({ where: whereClauses });
|
|
8005
|
-
const items = await repository.findAll({
|
|
8006
|
-
orderBy,
|
|
8007
|
-
direction,
|
|
8008
|
-
limit,
|
|
8009
|
-
offset,
|
|
8010
|
-
where: whereClauses
|
|
8050
|
+
const table = await loadTable({
|
|
8051
|
+
request,
|
|
8052
|
+
repository,
|
|
8053
|
+
options
|
|
8011
8054
|
});
|
|
8012
8055
|
return {
|
|
8013
|
-
table
|
|
8014
|
-
items,
|
|
8015
|
-
total,
|
|
8016
|
-
limit,
|
|
8017
|
-
offset,
|
|
8018
|
-
orderBy,
|
|
8019
|
-
direction,
|
|
8020
|
-
searchKey
|
|
8021
|
-
}
|
|
8056
|
+
table
|
|
8022
8057
|
};
|
|
8023
8058
|
};
|
|
8024
8059
|
}
|
|
@@ -8051,7 +8086,6 @@ import {
|
|
|
8051
8086
|
import {
|
|
8052
8087
|
and as and2
|
|
8053
8088
|
} from "drizzle-orm";
|
|
8054
|
-
import "react-router";
|
|
8055
8089
|
import { v4 } from "uuid";
|
|
8056
8090
|
function apiHandler({
|
|
8057
8091
|
withAuthAction,
|
|
@@ -8139,22 +8173,30 @@ function apiHandler({
|
|
|
8139
8173
|
}
|
|
8140
8174
|
|
|
8141
8175
|
// src/api/item_api_handler.ts
|
|
8142
|
-
import { UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
|
|
8143
|
-
import "react-router";
|
|
8176
|
+
import { FORBIDDEN, NOT_FOUND, UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
|
|
8144
8177
|
function itemApiHandler({
|
|
8145
8178
|
withAuthAction,
|
|
8146
|
-
repository
|
|
8179
|
+
repository,
|
|
8180
|
+
isOwnedBy,
|
|
8181
|
+
roles
|
|
8147
8182
|
}) {
|
|
8148
8183
|
const loader = async ({ request }) => {
|
|
8149
8184
|
return {};
|
|
8150
8185
|
};
|
|
8151
8186
|
const action = withAuthAction((auth) => async ({ params, request }) => {
|
|
8152
|
-
if (!auth || auth.role
|
|
8153
|
-
|
|
8187
|
+
if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
|
|
8188
|
+
throw UNAUTHORIZED2();
|
|
8189
|
+
}
|
|
8190
|
+
const itemId = params.itemId;
|
|
8191
|
+
const existing = await repository.find(itemId);
|
|
8192
|
+
if (!existing) {
|
|
8193
|
+
throw NOT_FOUND();
|
|
8194
|
+
}
|
|
8195
|
+
if (isOwnedBy && !isOwnedBy(existing, auth)) {
|
|
8196
|
+
throw FORBIDDEN();
|
|
8154
8197
|
}
|
|
8155
8198
|
switch (request.method) {
|
|
8156
8199
|
case "DELETE": {
|
|
8157
|
-
const itemId = params.itemId;
|
|
8158
8200
|
await repository.delete(itemId);
|
|
8159
8201
|
return {};
|
|
8160
8202
|
}
|
|
@@ -8232,96 +8274,20 @@ function crudHandler({
|
|
|
8232
8274
|
}
|
|
8233
8275
|
|
|
8234
8276
|
// src/crud/crud_page.tsx
|
|
8235
|
-
import { useLoaderData as useLoaderData2, useLocation as
|
|
8277
|
+
import { useLoaderData as useLoaderData2, useLocation as useLocation4 } from "react-router";
|
|
8236
8278
|
|
|
8237
8279
|
// src/table/page.tsx
|
|
8238
|
-
import {
|
|
8239
|
-
Link as Link3,
|
|
8240
|
-
useLoaderData,
|
|
8241
|
-
useLocation as useLocation2,
|
|
8242
|
-
useNavigate as useNavigate2,
|
|
8243
|
-
useSearchParams as useSearchParams3
|
|
8244
|
-
} from "react-router";
|
|
8245
|
-
import { GoSearch } from "react-icons/go";
|
|
8280
|
+
import { Link as Link3, useLocation as useLocation3 } from "react-router";
|
|
8246
8281
|
|
|
8247
|
-
// src/table/
|
|
8248
|
-
import {
|
|
8249
|
-
import {
|
|
8250
|
-
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
8251
|
-
function TablePageButtons({
|
|
8252
|
-
MAX_PAGES_TO_SHOW,
|
|
8253
|
-
total,
|
|
8254
|
-
limit,
|
|
8255
|
-
offset
|
|
8256
|
-
}) {
|
|
8257
|
-
const pages = Math.ceil(total / limit);
|
|
8258
|
-
const { pathname } = useLocation();
|
|
8259
|
-
const [searchParams] = useSearchParams();
|
|
8260
|
-
const currentPage = Math.floor(offset / limit) + 1;
|
|
8261
|
-
const startButton = (Math.ceil(currentPage / MAX_PAGES_TO_SHOW) - 1) * MAX_PAGES_TO_SHOW;
|
|
8262
|
-
const endButton = Math.min(startButton + MAX_PAGES_TO_SHOW - 1, pages);
|
|
8263
|
-
return /* @__PURE__ */ jsx7(Fragment3, { children: pages > 1 && /* @__PURE__ */ jsxs3("div", { className: "flex justify-center items-center my-8 gap-4 text-neutral-400", children: [
|
|
8264
|
-
startButton > 1 && /* @__PURE__ */ jsx7(
|
|
8265
|
-
Link,
|
|
8266
|
-
{
|
|
8267
|
-
to: (() => {
|
|
8268
|
-
searchParams.set(
|
|
8269
|
-
"offset",
|
|
8270
|
-
String((startButton - 1) * limit)
|
|
8271
|
-
);
|
|
8272
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
8273
|
-
})(),
|
|
8274
|
-
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
8275
|
-
children: "\uC774\uC804"
|
|
8276
|
-
}
|
|
8277
|
-
),
|
|
8278
|
-
Array.from({
|
|
8279
|
-
length: Math.min(
|
|
8280
|
-
MAX_PAGES_TO_SHOW,
|
|
8281
|
-
pages - startButton
|
|
8282
|
-
)
|
|
8283
|
-
}).map((_, index2) => {
|
|
8284
|
-
return /* @__PURE__ */ jsx7(
|
|
8285
|
-
Link,
|
|
8286
|
-
{
|
|
8287
|
-
to: (() => {
|
|
8288
|
-
searchParams.set(
|
|
8289
|
-
"offset",
|
|
8290
|
-
String((startButton + index2) * limit)
|
|
8291
|
-
);
|
|
8292
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
8293
|
-
})(),
|
|
8294
|
-
className: cn2(
|
|
8295
|
-
"w-6 block text-center transition-colors",
|
|
8296
|
-
currentPage === startButton + index2 + 1 ? "font-bold text-primary" : "hover:text-primary"
|
|
8297
|
-
),
|
|
8298
|
-
children: startButton + index2 + 1
|
|
8299
|
-
},
|
|
8300
|
-
index2
|
|
8301
|
-
);
|
|
8302
|
-
}),
|
|
8303
|
-
endButton < pages && /* @__PURE__ */ jsx7(
|
|
8304
|
-
Link,
|
|
8305
|
-
{
|
|
8306
|
-
to: (() => {
|
|
8307
|
-
searchParams.set(
|
|
8308
|
-
"offset",
|
|
8309
|
-
String((endButton + 1) * limit)
|
|
8310
|
-
);
|
|
8311
|
-
return `${pathname}?${searchParams.toString()}`;
|
|
8312
|
-
})(),
|
|
8313
|
-
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
8314
|
-
children: "\uB2E4\uC74C"
|
|
8315
|
-
}
|
|
8316
|
-
)
|
|
8317
|
-
] }) });
|
|
8318
|
-
}
|
|
8282
|
+
// src/table/table_form.tsx
|
|
8283
|
+
import { useLocation as useLocation2, useNavigate as useNavigate2, useSearchParams as useSearchParams3 } from "react-router";
|
|
8284
|
+
import { GoSearch } from "react-icons/go";
|
|
8319
8285
|
|
|
8320
8286
|
// src/table/table.tsx
|
|
8321
|
-
import { cn as
|
|
8287
|
+
import { cn as cn2 } from "dn-react-toolkit/utils";
|
|
8322
8288
|
import { GoArrowDown, GoArrowUp } from "react-icons/go";
|
|
8323
|
-
import { Link
|
|
8324
|
-
import { Fragment as
|
|
8289
|
+
import { Link, useSearchParams } from "react-router";
|
|
8290
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
8325
8291
|
function Table({
|
|
8326
8292
|
className = "min-w-full whitespace-nowrap",
|
|
8327
8293
|
data,
|
|
@@ -8331,17 +8297,21 @@ function Table({
|
|
|
8331
8297
|
limit,
|
|
8332
8298
|
offset,
|
|
8333
8299
|
orderBy,
|
|
8334
|
-
direction
|
|
8300
|
+
direction,
|
|
8301
|
+
filters
|
|
8335
8302
|
}) {
|
|
8336
8303
|
const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
|
|
8337
8304
|
const sortedArray = [...data];
|
|
8338
|
-
const [_, setSearchParams] =
|
|
8339
|
-
return /* @__PURE__ */
|
|
8305
|
+
const [_, setSearchParams] = useSearchParams();
|
|
8306
|
+
return /* @__PURE__ */ jsxs3(
|
|
8340
8307
|
"table",
|
|
8341
8308
|
{
|
|
8342
|
-
className:
|
|
8309
|
+
className: cn2(
|
|
8310
|
+
className,
|
|
8311
|
+
"text-[15px] border-separate border-spacing-0"
|
|
8312
|
+
),
|
|
8343
8313
|
children: [
|
|
8344
|
-
/* @__PURE__ */
|
|
8314
|
+
/* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsx7("tr", { children: keys.map((key) => {
|
|
8345
8315
|
const value = columns[key];
|
|
8346
8316
|
function getReactNode() {
|
|
8347
8317
|
if (value && typeof value === "object" && "label" in value) {
|
|
@@ -8352,12 +8322,12 @@ function Table({
|
|
|
8352
8322
|
function Head() {
|
|
8353
8323
|
const reactNode = getReactNode();
|
|
8354
8324
|
if (typeof reactNode === "string") {
|
|
8355
|
-
return /* @__PURE__ */
|
|
8325
|
+
return /* @__PURE__ */ jsxs3(
|
|
8356
8326
|
"button",
|
|
8357
8327
|
{
|
|
8358
|
-
className:
|
|
8359
|
-
orderBy === key ? "text-
|
|
8360
|
-
"px-4
|
|
8328
|
+
className: cn2(
|
|
8329
|
+
orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
|
|
8330
|
+
"px-4 flex items-center w-full"
|
|
8361
8331
|
),
|
|
8362
8332
|
onClick: () => {
|
|
8363
8333
|
let newDirection = "asc";
|
|
@@ -8371,25 +8341,70 @@ function Table({
|
|
|
8371
8341
|
},
|
|
8372
8342
|
children: [
|
|
8373
8343
|
reactNode,
|
|
8374
|
-
orderBy === key && /* @__PURE__ */
|
|
8344
|
+
orderBy === key && /* @__PURE__ */ jsx7("div", { className: "ml-0.5", children: direction === "asc" ? /* @__PURE__ */ jsx7(GoArrowUp, {}) : /* @__PURE__ */ jsx7(GoArrowDown, {}) })
|
|
8375
8345
|
]
|
|
8376
8346
|
}
|
|
8377
8347
|
);
|
|
8378
8348
|
}
|
|
8379
|
-
return /* @__PURE__ */
|
|
8349
|
+
return /* @__PURE__ */ jsx7(Fragment3, { children: reactNode });
|
|
8380
8350
|
}
|
|
8381
|
-
|
|
8351
|
+
const filter = filters[key];
|
|
8352
|
+
return /* @__PURE__ */ jsxs3(
|
|
8353
|
+
"th",
|
|
8354
|
+
{
|
|
8355
|
+
className: cn2(
|
|
8356
|
+
"py-4 border-y font-normal align-top"
|
|
8357
|
+
),
|
|
8358
|
+
children: [
|
|
8359
|
+
/* @__PURE__ */ jsx7(Head, {}),
|
|
8360
|
+
filter && /* @__PURE__ */ jsx7("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs3(
|
|
8361
|
+
"select",
|
|
8362
|
+
{
|
|
8363
|
+
className: "w-full h-10 px-1.5 border rounded-full outline-none",
|
|
8364
|
+
onChange: (e) => {
|
|
8365
|
+
const value2 = e.target.value;
|
|
8366
|
+
setSearchParams((prev) => {
|
|
8367
|
+
if (value2) {
|
|
8368
|
+
prev.set(
|
|
8369
|
+
key,
|
|
8370
|
+
encodeURIComponent(
|
|
8371
|
+
value2
|
|
8372
|
+
)
|
|
8373
|
+
);
|
|
8374
|
+
} else {
|
|
8375
|
+
prev.delete(key);
|
|
8376
|
+
}
|
|
8377
|
+
return prev;
|
|
8378
|
+
});
|
|
8379
|
+
},
|
|
8380
|
+
children: [
|
|
8381
|
+
/* @__PURE__ */ jsx7("option", { value: "", children: "\uC804\uCCB4" }),
|
|
8382
|
+
filter.map((option) => /* @__PURE__ */ jsx7(
|
|
8383
|
+
"option",
|
|
8384
|
+
{
|
|
8385
|
+
value: option,
|
|
8386
|
+
children: option
|
|
8387
|
+
},
|
|
8388
|
+
option
|
|
8389
|
+
))
|
|
8390
|
+
]
|
|
8391
|
+
}
|
|
8392
|
+
) })
|
|
8393
|
+
]
|
|
8394
|
+
},
|
|
8395
|
+
key
|
|
8396
|
+
);
|
|
8382
8397
|
}) }) }),
|
|
8383
|
-
/* @__PURE__ */
|
|
8384
|
-
sortedArray.length === 0 && /* @__PURE__ */
|
|
8398
|
+
/* @__PURE__ */ jsxs3("tbody", { children: [
|
|
8399
|
+
sortedArray.length === 0 && /* @__PURE__ */ jsx7("tr", { children: /* @__PURE__ */ jsx7(
|
|
8385
8400
|
"td",
|
|
8386
8401
|
{
|
|
8387
8402
|
colSpan: keys.length,
|
|
8388
|
-
className: "px-4 h-
|
|
8403
|
+
className: "px-4 h-20 text-gray-400 text-center",
|
|
8389
8404
|
children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
8390
8405
|
}
|
|
8391
8406
|
) }),
|
|
8392
|
-
sortedArray.map((item, i) => /* @__PURE__ */
|
|
8407
|
+
sortedArray.map((item, i) => /* @__PURE__ */ jsx7("tr", { className: "hover:bg-gray-50 transition-colors", children: keys.map((key, i2) => {
|
|
8393
8408
|
const value = item[key];
|
|
8394
8409
|
function Content() {
|
|
8395
8410
|
if (key in columns) {
|
|
@@ -8397,22 +8412,22 @@ function Table({
|
|
|
8397
8412
|
if (column && typeof column === "object" && "mapper" in column) {
|
|
8398
8413
|
const mapper = column.mapper;
|
|
8399
8414
|
if (mapper) {
|
|
8400
|
-
return /* @__PURE__ */
|
|
8415
|
+
return /* @__PURE__ */ jsx7(Fragment3, { children: mapper(item) });
|
|
8401
8416
|
}
|
|
8402
8417
|
}
|
|
8403
8418
|
}
|
|
8404
|
-
return /* @__PURE__ */
|
|
8419
|
+
return /* @__PURE__ */ jsx7(Fragment3, { children: String(value) });
|
|
8405
8420
|
}
|
|
8406
|
-
const linkedContent = getLink ? /* @__PURE__ */
|
|
8407
|
-
|
|
8421
|
+
const linkedContent = getLink ? /* @__PURE__ */ jsx7(
|
|
8422
|
+
Link,
|
|
8408
8423
|
{
|
|
8409
8424
|
to: getLink(item),
|
|
8410
8425
|
className: "block content-center px-4 w-full h-full",
|
|
8411
|
-
children: /* @__PURE__ */
|
|
8426
|
+
children: /* @__PURE__ */ jsx7(Content, {})
|
|
8412
8427
|
}
|
|
8413
|
-
) : /* @__PURE__ */
|
|
8414
|
-
const cell = Mapper ? /* @__PURE__ */
|
|
8415
|
-
return /* @__PURE__ */
|
|
8428
|
+
) : /* @__PURE__ */ jsx7(Content, {});
|
|
8429
|
+
const cell = Mapper ? /* @__PURE__ */ jsx7(Mapper, { item, index: i2, children: linkedContent }) : linkedContent;
|
|
8430
|
+
return /* @__PURE__ */ jsx7("td", { className: "px-0 h-14 border-b", children: cell }, key);
|
|
8416
8431
|
}) }, i))
|
|
8417
8432
|
] })
|
|
8418
8433
|
]
|
|
@@ -8420,8 +8435,170 @@ function Table({
|
|
|
8420
8435
|
);
|
|
8421
8436
|
}
|
|
8422
8437
|
|
|
8423
|
-
// src/table/
|
|
8438
|
+
// src/table/use_table.tsx
|
|
8439
|
+
import { useLoaderData } from "react-router";
|
|
8440
|
+
function useTable() {
|
|
8441
|
+
const { table } = useLoaderData();
|
|
8442
|
+
return table;
|
|
8443
|
+
}
|
|
8444
|
+
|
|
8445
|
+
// src/table/buttons.tsx
|
|
8446
|
+
import { cn as cn3 } from "dn-react-toolkit/utils";
|
|
8447
|
+
import { Link as Link2, useLocation, useSearchParams as useSearchParams2 } from "react-router";
|
|
8448
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
8449
|
+
function TablePageButtons({
|
|
8450
|
+
MAX_PAGES_TO_SHOW,
|
|
8451
|
+
total,
|
|
8452
|
+
limit,
|
|
8453
|
+
offset
|
|
8454
|
+
}) {
|
|
8455
|
+
const pages = Math.ceil(total / limit);
|
|
8456
|
+
const { pathname } = useLocation();
|
|
8457
|
+
const [searchParams] = useSearchParams2();
|
|
8458
|
+
const currentPage = Math.floor(offset / limit) + 1;
|
|
8459
|
+
const startButton = (Math.ceil(currentPage / MAX_PAGES_TO_SHOW) - 1) * MAX_PAGES_TO_SHOW;
|
|
8460
|
+
const endButton = Math.min(startButton + MAX_PAGES_TO_SHOW - 1, pages);
|
|
8461
|
+
return /* @__PURE__ */ jsx8(Fragment4, { children: pages > 1 && /* @__PURE__ */ jsxs4("div", { className: "flex justify-center items-center my-8 gap-4 text-neutral-400", children: [
|
|
8462
|
+
startButton > 1 && /* @__PURE__ */ jsx8(
|
|
8463
|
+
Link2,
|
|
8464
|
+
{
|
|
8465
|
+
to: (() => {
|
|
8466
|
+
searchParams.set(
|
|
8467
|
+
"offset",
|
|
8468
|
+
String((startButton - 1) * limit)
|
|
8469
|
+
);
|
|
8470
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
8471
|
+
})(),
|
|
8472
|
+
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
8473
|
+
children: "\uC774\uC804"
|
|
8474
|
+
}
|
|
8475
|
+
),
|
|
8476
|
+
Array.from({
|
|
8477
|
+
length: Math.min(
|
|
8478
|
+
MAX_PAGES_TO_SHOW,
|
|
8479
|
+
pages - startButton
|
|
8480
|
+
)
|
|
8481
|
+
}).map((_, index2) => {
|
|
8482
|
+
return /* @__PURE__ */ jsx8(
|
|
8483
|
+
Link2,
|
|
8484
|
+
{
|
|
8485
|
+
to: (() => {
|
|
8486
|
+
searchParams.set(
|
|
8487
|
+
"offset",
|
|
8488
|
+
String((startButton + index2) * limit)
|
|
8489
|
+
);
|
|
8490
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
8491
|
+
})(),
|
|
8492
|
+
className: cn3(
|
|
8493
|
+
"w-6 block text-center transition-colors",
|
|
8494
|
+
currentPage === startButton + index2 + 1 ? "font-bold text-primary" : "hover:text-primary"
|
|
8495
|
+
),
|
|
8496
|
+
children: startButton + index2 + 1
|
|
8497
|
+
},
|
|
8498
|
+
index2
|
|
8499
|
+
);
|
|
8500
|
+
}),
|
|
8501
|
+
endButton < pages && /* @__PURE__ */ jsx8(
|
|
8502
|
+
Link2,
|
|
8503
|
+
{
|
|
8504
|
+
to: (() => {
|
|
8505
|
+
searchParams.set(
|
|
8506
|
+
"offset",
|
|
8507
|
+
String((endButton + 1) * limit)
|
|
8508
|
+
);
|
|
8509
|
+
return `${pathname}?${searchParams.toString()}`;
|
|
8510
|
+
})(),
|
|
8511
|
+
className: "w-10 block text-center transition-colors hover:text-primary",
|
|
8512
|
+
children: "\uB2E4\uC74C"
|
|
8513
|
+
}
|
|
8514
|
+
)
|
|
8515
|
+
] }) });
|
|
8516
|
+
}
|
|
8517
|
+
|
|
8518
|
+
// src/table/table_form.tsx
|
|
8424
8519
|
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
8520
|
+
function TableForm({
|
|
8521
|
+
columns,
|
|
8522
|
+
primaryKey = "id"
|
|
8523
|
+
}) {
|
|
8524
|
+
const { pathname } = useLocation2();
|
|
8525
|
+
const {
|
|
8526
|
+
items,
|
|
8527
|
+
total,
|
|
8528
|
+
limit,
|
|
8529
|
+
offset,
|
|
8530
|
+
orderBy,
|
|
8531
|
+
direction,
|
|
8532
|
+
searchKey,
|
|
8533
|
+
filters
|
|
8534
|
+
} = useTable();
|
|
8535
|
+
const navigate = useNavigate2();
|
|
8536
|
+
const search = (query) => {
|
|
8537
|
+
const searchParams2 = new URLSearchParams(window.location.search);
|
|
8538
|
+
searchParams2.set("query", query);
|
|
8539
|
+
searchParams2.set("offset", "0");
|
|
8540
|
+
navigate(`${pathname}?${searchParams2.toString()}`);
|
|
8541
|
+
};
|
|
8542
|
+
const [searchParams] = useSearchParams3();
|
|
8543
|
+
return /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
8544
|
+
searchKey && /* @__PURE__ */ jsxs5(
|
|
8545
|
+
"form",
|
|
8546
|
+
{
|
|
8547
|
+
className: "h-20 px-4 flex items-center border-t",
|
|
8548
|
+
onSubmit: (e) => {
|
|
8549
|
+
e.preventDefault();
|
|
8550
|
+
const formData = new FormData(e.currentTarget);
|
|
8551
|
+
const query = formData.get("query");
|
|
8552
|
+
search(query);
|
|
8553
|
+
},
|
|
8554
|
+
children: [
|
|
8555
|
+
/* @__PURE__ */ jsx9(
|
|
8556
|
+
"button",
|
|
8557
|
+
{
|
|
8558
|
+
type: "submit",
|
|
8559
|
+
className: "w-10 h-10 flex justify-center items-center",
|
|
8560
|
+
children: /* @__PURE__ */ jsx9(GoSearch, { className: "text-xl mr-4" })
|
|
8561
|
+
}
|
|
8562
|
+
),
|
|
8563
|
+
/* @__PURE__ */ jsx9(
|
|
8564
|
+
"input",
|
|
8565
|
+
{
|
|
8566
|
+
className: "outline-none h-full flex-1",
|
|
8567
|
+
placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
|
|
8568
|
+
name: "query",
|
|
8569
|
+
defaultValue: searchParams.get("query") ?? ""
|
|
8570
|
+
}
|
|
8571
|
+
)
|
|
8572
|
+
]
|
|
8573
|
+
}
|
|
8574
|
+
),
|
|
8575
|
+
/* @__PURE__ */ jsx9(
|
|
8576
|
+
Table,
|
|
8577
|
+
{
|
|
8578
|
+
data: items,
|
|
8579
|
+
columns,
|
|
8580
|
+
getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
|
|
8581
|
+
limit,
|
|
8582
|
+
offset,
|
|
8583
|
+
orderBy,
|
|
8584
|
+
direction,
|
|
8585
|
+
filters
|
|
8586
|
+
}
|
|
8587
|
+
),
|
|
8588
|
+
/* @__PURE__ */ jsx9(
|
|
8589
|
+
TablePageButtons,
|
|
8590
|
+
{
|
|
8591
|
+
total,
|
|
8592
|
+
limit,
|
|
8593
|
+
offset,
|
|
8594
|
+
MAX_PAGES_TO_SHOW: 10
|
|
8595
|
+
}
|
|
8596
|
+
)
|
|
8597
|
+
] });
|
|
8598
|
+
}
|
|
8599
|
+
|
|
8600
|
+
// src/table/page.tsx
|
|
8601
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
8425
8602
|
function createTablePage({
|
|
8426
8603
|
name,
|
|
8427
8604
|
columns,
|
|
@@ -8430,88 +8607,25 @@ function createTablePage({
|
|
|
8430
8607
|
return function TablePage({
|
|
8431
8608
|
header: Header
|
|
8432
8609
|
}) {
|
|
8433
|
-
const { pathname } =
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
const navigate = useNavigate2();
|
|
8437
|
-
const search = (query) => {
|
|
8438
|
-
const searchParams2 = new URLSearchParams(window.location.search);
|
|
8439
|
-
searchParams2.set("query", query);
|
|
8440
|
-
searchParams2.set("offset", "0");
|
|
8441
|
-
navigate(`${pathname}?${searchParams2.toString()}`);
|
|
8442
|
-
};
|
|
8443
|
-
const [searchParams] = useSearchParams3();
|
|
8444
|
-
return /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
8445
|
-
/* @__PURE__ */ jsx9(
|
|
8610
|
+
const { pathname } = useLocation3();
|
|
8611
|
+
return /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
8612
|
+
/* @__PURE__ */ jsx10(
|
|
8446
8613
|
Header,
|
|
8447
8614
|
{
|
|
8448
8615
|
title: name,
|
|
8449
|
-
actions: /* @__PURE__ */
|
|
8616
|
+
actions: /* @__PURE__ */ jsxs6(Link3, { to: `${pathname}/new`, className: "button-primary", children: [
|
|
8450
8617
|
name,
|
|
8451
8618
|
" \uCD94\uAC00"
|
|
8452
8619
|
] })
|
|
8453
8620
|
}
|
|
8454
8621
|
),
|
|
8455
|
-
/* @__PURE__ */
|
|
8456
|
-
searchKey && /* @__PURE__ */ jsxs5(
|
|
8457
|
-
"form",
|
|
8458
|
-
{
|
|
8459
|
-
className: "h-18 px-4 flex items-center border-t",
|
|
8460
|
-
onSubmit: (e) => {
|
|
8461
|
-
e.preventDefault();
|
|
8462
|
-
const formData = new FormData(e.currentTarget);
|
|
8463
|
-
const query = formData.get("query");
|
|
8464
|
-
search(query);
|
|
8465
|
-
},
|
|
8466
|
-
children: [
|
|
8467
|
-
/* @__PURE__ */ jsx9(
|
|
8468
|
-
"button",
|
|
8469
|
-
{
|
|
8470
|
-
type: "submit",
|
|
8471
|
-
className: "w-10 h-10 flex justify-center items-center",
|
|
8472
|
-
children: /* @__PURE__ */ jsx9(GoSearch, { className: "text-xl mr-4" })
|
|
8473
|
-
}
|
|
8474
|
-
),
|
|
8475
|
-
/* @__PURE__ */ jsx9(
|
|
8476
|
-
"input",
|
|
8477
|
-
{
|
|
8478
|
-
className: "outline-none h-full flex-1",
|
|
8479
|
-
placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
|
|
8480
|
-
name: "query",
|
|
8481
|
-
defaultValue: searchParams.get("query") ?? ""
|
|
8482
|
-
}
|
|
8483
|
-
)
|
|
8484
|
-
]
|
|
8485
|
-
}
|
|
8486
|
-
),
|
|
8487
|
-
/* @__PURE__ */ jsx9(
|
|
8488
|
-
Table,
|
|
8489
|
-
{
|
|
8490
|
-
data: items,
|
|
8491
|
-
columns,
|
|
8492
|
-
getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
|
|
8493
|
-
limit,
|
|
8494
|
-
offset,
|
|
8495
|
-
orderBy,
|
|
8496
|
-
direction
|
|
8497
|
-
}
|
|
8498
|
-
),
|
|
8499
|
-
/* @__PURE__ */ jsx9(
|
|
8500
|
-
TablePageButtons,
|
|
8501
|
-
{
|
|
8502
|
-
total,
|
|
8503
|
-
limit,
|
|
8504
|
-
offset,
|
|
8505
|
-
MAX_PAGES_TO_SHOW: 10
|
|
8506
|
-
}
|
|
8507
|
-
)
|
|
8508
|
-
] })
|
|
8622
|
+
/* @__PURE__ */ jsx10("div", { className: "max-w-7xl mx-auto w-full overflow-auto", children: /* @__PURE__ */ jsx10(TableForm, { columns, primaryKey }) })
|
|
8509
8623
|
] });
|
|
8510
8624
|
};
|
|
8511
8625
|
}
|
|
8512
8626
|
|
|
8513
8627
|
// src/crud/crud_page.tsx
|
|
8514
|
-
import { jsx as
|
|
8628
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
8515
8629
|
function crudPage({
|
|
8516
8630
|
name,
|
|
8517
8631
|
primaryKey,
|
|
@@ -8522,16 +8636,16 @@ function crudPage({
|
|
|
8522
8636
|
const create = (prefix2) => {
|
|
8523
8637
|
return function Page() {
|
|
8524
8638
|
const data = useLoaderData2();
|
|
8525
|
-
const { pathname } =
|
|
8639
|
+
const { pathname } = useLocation4();
|
|
8526
8640
|
if (pathname === prefix2) {
|
|
8527
8641
|
const Component = createTablePage({
|
|
8528
8642
|
...tablePageOptions,
|
|
8529
8643
|
name
|
|
8530
8644
|
});
|
|
8531
|
-
return /* @__PURE__ */
|
|
8645
|
+
return /* @__PURE__ */ jsx11(Component, { header });
|
|
8532
8646
|
}
|
|
8533
8647
|
if (pathname.startsWith(prefix2)) {
|
|
8534
|
-
return /* @__PURE__ */
|
|
8648
|
+
return /* @__PURE__ */ jsx11(
|
|
8535
8649
|
CrudFormProvider,
|
|
8536
8650
|
{
|
|
8537
8651
|
item: data?.item,
|
|
@@ -8539,7 +8653,7 @@ function crudPage({
|
|
|
8539
8653
|
name,
|
|
8540
8654
|
columns: formOptions.columns,
|
|
8541
8655
|
primaryKey,
|
|
8542
|
-
children: formOptions.form ? /* @__PURE__ */
|
|
8656
|
+
children: formOptions.form ? /* @__PURE__ */ jsx11(FormDelegate, { component: formOptions.form }) : /* @__PURE__ */ jsx11(CrudForm, { AdminHeader: header })
|
|
8543
8657
|
}
|
|
8544
8658
|
);
|
|
8545
8659
|
}
|
|
@@ -8554,7 +8668,7 @@ function FormDelegate({
|
|
|
8554
8668
|
component: Component
|
|
8555
8669
|
}) {
|
|
8556
8670
|
const form = useFormContext();
|
|
8557
|
-
return /* @__PURE__ */
|
|
8671
|
+
return /* @__PURE__ */ jsx11(Component, { form });
|
|
8558
8672
|
}
|
|
8559
8673
|
|
|
8560
8674
|
// src/crud/generate_handlers.ts
|
|
@@ -8570,15 +8684,15 @@ var generateHandlers = (handlers) => {
|
|
|
8570
8684
|
};
|
|
8571
8685
|
|
|
8572
8686
|
// src/crud/generate_pages.tsx
|
|
8573
|
-
import { useLocation as
|
|
8574
|
-
import { jsx as
|
|
8687
|
+
import { useLocation as useLocation5 } from "react-router";
|
|
8688
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
8575
8689
|
var generatePages = (pages) => {
|
|
8576
8690
|
function Page() {
|
|
8577
|
-
const { pathname } =
|
|
8691
|
+
const { pathname } = useLocation5();
|
|
8578
8692
|
for (const route2 of Object.keys(pages)) {
|
|
8579
8693
|
if (pathname.startsWith(route2)) {
|
|
8580
8694
|
const Page2 = pages[route2].create(route2);
|
|
8581
|
-
return /* @__PURE__ */
|
|
8695
|
+
return /* @__PURE__ */ jsx12(Page2, {});
|
|
8582
8696
|
}
|
|
8583
8697
|
}
|
|
8584
8698
|
}
|