elysia-rack 0.2.0 → 0.3.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/README.md +37 -15
- package/dist/Dashboard-4wv82gwx.js +212 -0
- package/dist/Dashboard-jkvfzyk2.js +210 -0
- package/dist/Dashboard-zhg2jtq5.js +211 -0
- package/dist/{Panel-fbp3wrsw.js → Panel-1qkzh8t7.js} +355 -311
- package/dist/Panel-7zpqz8gy.js +782 -0
- package/dist/Panel-9mmh3tbh.js +790 -0
- package/dist/Panel-ba0qzknj.js +789 -0
- package/dist/Panel-e6jyf4rc.js +789 -0
- package/dist/index-0dwhzk3j.js +145 -0
- package/dist/index-b8sq8rbd.js +19 -0
- package/dist/index-rg87f3v1.js +174 -0
- package/dist/panel-app.js +27 -11
- package/dist/panel.css +2 -1
- package/dist/rack/dashboard.d.ts +3 -0
- package/dist/rack/index.js +1 -0
- package/dist/rack/types/metadata.d.ts +2 -1
- package/dist/react/donate.d.ts +10 -0
- package/dist/react/index.js +6 -2
- package/dist/react/page/Dashboard.d.ts +2 -0
- package/dist/react/page/Panel.d.ts +2 -0
- package/dist/react/page/components/Icon.d.ts +10 -0
- package/dist/react/page/components/Masthead.d.ts +5 -4
- package/dist/react/types.d.ts +5 -0
- package/package.json +12 -3
- package/dist/Dashboard-2j561p7c.js +0 -225
- package/dist/Dashboard-5mt9hnbw.js +0 -252
- package/dist/Dashboard-s8nfyf7s.js +0 -39
- package/dist/Dashboard-xpstr7fr.js +0 -172
- package/dist/Panel-3yrk3krj.js +0 -914
- package/dist/Panel-b7jhgvnm.js +0 -916
- package/dist/Panel-pkvqf5v8.js +0 -912
- package/dist/index-tgk4jt4d.js +0 -63
- package/dist/index-zc7rgvmm.js +0 -13
package/dist/Panel-3yrk3krj.js
DELETED
|
@@ -1,914 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getRackTree
|
|
3
|
-
} from "./index-4wxvmd8a.js";
|
|
4
|
-
import"./index-37x76zdn.js";
|
|
5
|
-
|
|
6
|
-
// src/react/page/components/Breadcrumb.tsx
|
|
7
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
8
|
-
function Breadcrumb({ trail }) {
|
|
9
|
-
return /* @__PURE__ */ jsxDEV("nav", {
|
|
10
|
-
"aria-label": "Breadcrumb",
|
|
11
|
-
className: "pb-3 text-sm",
|
|
12
|
-
children: /* @__PURE__ */ jsxDEV("ol", {
|
|
13
|
-
className: "flex flex-wrap items-center gap-1.5",
|
|
14
|
-
children: trail.map((item, i) => {
|
|
15
|
-
const last = i === trail.length - 1;
|
|
16
|
-
return /* @__PURE__ */ jsxDEV("li", {
|
|
17
|
-
className: "flex items-center gap-1.5",
|
|
18
|
-
children: [
|
|
19
|
-
i > 0 ? /* @__PURE__ */ jsxDEV("span", {
|
|
20
|
-
"aria-hidden": "true",
|
|
21
|
-
className: "text-text-muted",
|
|
22
|
-
children: "/"
|
|
23
|
-
}, undefined, false, undefined, this) : null,
|
|
24
|
-
item.href && !last ? /* @__PURE__ */ jsxDEV("a", {
|
|
25
|
-
href: item.href,
|
|
26
|
-
className: "text-text-muted hover:text-foreground",
|
|
27
|
-
children: item.label
|
|
28
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
|
|
29
|
-
"aria-current": last ? "page" : undefined,
|
|
30
|
-
className: last ? "text-foreground font-semibold" : "text-text-muted",
|
|
31
|
-
children: item.label
|
|
32
|
-
}, undefined, false, undefined, this)
|
|
33
|
-
]
|
|
34
|
-
}, `${item.label}-${i}`, true, undefined, this);
|
|
35
|
-
})
|
|
36
|
-
}, undefined, false, undefined, this)
|
|
37
|
-
}, undefined, false, undefined, this);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// src/react/page/components/href.ts
|
|
41
|
-
function href(params, over = {}) {
|
|
42
|
-
const query = new URLSearchParams;
|
|
43
|
-
for (const [key, value] of Object.entries({ ...params, ...over })) {
|
|
44
|
-
if (value === undefined || value === null || value === "")
|
|
45
|
-
continue;
|
|
46
|
-
query.set(key, Array.isArray(value) ? value.join(",") : String(value));
|
|
47
|
-
}
|
|
48
|
-
const str = query.toString();
|
|
49
|
-
return str ? `?${str}` : "?";
|
|
50
|
-
}
|
|
51
|
-
function pageWindow(page, total) {
|
|
52
|
-
const keep = new Set([1, total, page - 1, page, page + 1]);
|
|
53
|
-
const sorted = [...keep].filter((p) => p >= 1 && p <= total).sort((a, b) => a - b);
|
|
54
|
-
const out = [];
|
|
55
|
-
let prev = 0;
|
|
56
|
-
for (const p of sorted) {
|
|
57
|
-
if (p - prev > 1)
|
|
58
|
-
out.push("…");
|
|
59
|
-
out.push(p);
|
|
60
|
-
prev = p;
|
|
61
|
-
}
|
|
62
|
-
return out;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// src/react/page/components/DataTable.tsx
|
|
66
|
-
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
67
|
-
function statusBadge(value) {
|
|
68
|
-
if (typeof value !== "string")
|
|
69
|
-
return null;
|
|
70
|
-
const text = value.toLowerCase();
|
|
71
|
-
if (text === "active")
|
|
72
|
-
return "bg-success-muted text-success-muted-foreground";
|
|
73
|
-
if (text === "archived")
|
|
74
|
-
return "bg-warning-muted text-warning-muted-foreground";
|
|
75
|
-
return "bg-badge-background text-badge-foreground";
|
|
76
|
-
}
|
|
77
|
-
function cell(value) {
|
|
78
|
-
if (value === null || value === undefined)
|
|
79
|
-
return "";
|
|
80
|
-
if (value instanceof Date)
|
|
81
|
-
return value.toLocaleString("en-US");
|
|
82
|
-
if (typeof value === "object")
|
|
83
|
-
return JSON.stringify(value);
|
|
84
|
-
return String(value);
|
|
85
|
-
}
|
|
86
|
-
function DataTable({
|
|
87
|
-
columns,
|
|
88
|
-
rows,
|
|
89
|
-
sortable,
|
|
90
|
-
params,
|
|
91
|
-
selectable,
|
|
92
|
-
editable,
|
|
93
|
-
primaryKey
|
|
94
|
-
}) {
|
|
95
|
-
const activeSort = typeof params.sort === "string" ? params.sort : "";
|
|
96
|
-
const activeOrder = params.order === "desc" ? "desc" : "asc";
|
|
97
|
-
const pk = primaryKey ?? "id";
|
|
98
|
-
const extra = (selectable ? 1 : 0) + (editable ? 1 : 0);
|
|
99
|
-
if (rows.length === 0)
|
|
100
|
-
return /* @__PURE__ */ jsxDEV2("div", {
|
|
101
|
-
className: "border-table-border overflow-x-auto rounded-md border",
|
|
102
|
-
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
103
|
-
className: "bg-table w-full border-collapse text-left text-sm",
|
|
104
|
-
"data-selectable": selectable ? true : undefined,
|
|
105
|
-
"data-editable": editable ? true : undefined,
|
|
106
|
-
"data-pk": primaryKey ?? "id",
|
|
107
|
-
children: /* @__PURE__ */ jsxDEV2("tbody", {
|
|
108
|
-
"data-panel-rows": true,
|
|
109
|
-
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
110
|
-
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
111
|
-
colSpan: columns.length + extra || 1,
|
|
112
|
-
className: "text-text-muted px-4 py-10 text-center",
|
|
113
|
-
children: "No records found."
|
|
114
|
-
}, undefined, false, undefined, this)
|
|
115
|
-
}, undefined, false, undefined, this)
|
|
116
|
-
}, undefined, false, undefined, this)
|
|
117
|
-
}, undefined, false, undefined, this)
|
|
118
|
-
}, undefined, false, undefined, this);
|
|
119
|
-
return /* @__PURE__ */ jsxDEV2("div", {
|
|
120
|
-
className: "border-table-border overflow-x-auto rounded-md border",
|
|
121
|
-
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
122
|
-
className: "bg-table w-full border-collapse text-left text-sm",
|
|
123
|
-
"data-selectable": selectable ? true : undefined,
|
|
124
|
-
"data-editable": editable ? true : undefined,
|
|
125
|
-
"data-pk": primaryKey ?? "id",
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsxDEV2("thead", {
|
|
128
|
-
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
129
|
-
className: "bg-table-header",
|
|
130
|
-
children: [
|
|
131
|
-
selectable ? /* @__PURE__ */ jsxDEV2("th", {
|
|
132
|
-
className: "border-table-border border-b px-4 py-2",
|
|
133
|
-
children: /* @__PURE__ */ jsxDEV2("input", {
|
|
134
|
-
type: "checkbox",
|
|
135
|
-
"data-select-all": true,
|
|
136
|
-
"aria-label": "Select all"
|
|
137
|
-
}, undefined, false, undefined, this)
|
|
138
|
-
}, undefined, false, undefined, this) : null,
|
|
139
|
-
columns.map((col) => /* @__PURE__ */ jsxDEV2("th", {
|
|
140
|
-
"data-col": col,
|
|
141
|
-
className: "border-table-border border-b px-4 py-2 text-xs font-bold tracking-wider uppercase",
|
|
142
|
-
children: sortable?.includes(col) ? /* @__PURE__ */ jsxDEV2("a", {
|
|
143
|
-
className: "text-link hover:text-link-hover",
|
|
144
|
-
"data-qlink": true,
|
|
145
|
-
"data-sort-link": col,
|
|
146
|
-
href: href(params, {
|
|
147
|
-
sort: col,
|
|
148
|
-
order: activeSort === col && activeOrder === "asc" ? "desc" : "asc"
|
|
149
|
-
}),
|
|
150
|
-
children: [
|
|
151
|
-
col,
|
|
152
|
-
/* @__PURE__ */ jsxDEV2("span", {
|
|
153
|
-
"data-sort-ind": true,
|
|
154
|
-
children: activeSort === col ? activeOrder === "asc" ? " ▲" : " ▼" : ""
|
|
155
|
-
}, undefined, false, undefined, this)
|
|
156
|
-
]
|
|
157
|
-
}, undefined, true, undefined, this) : col
|
|
158
|
-
}, col, false, undefined, this)),
|
|
159
|
-
editable ? /* @__PURE__ */ jsxDEV2("th", {
|
|
160
|
-
className: "border-table-border border-b px-4 py-2 text-xs font-bold tracking-wider uppercase",
|
|
161
|
-
children: "Actions"
|
|
162
|
-
}, undefined, false, undefined, this) : null
|
|
163
|
-
]
|
|
164
|
-
}, undefined, true, undefined, this)
|
|
165
|
-
}, undefined, false, undefined, this),
|
|
166
|
-
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
167
|
-
"data-panel-rows": true,
|
|
168
|
-
children: rows.map((row, i) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
169
|
-
className: "hover:bg-table-row-hover",
|
|
170
|
-
children: [
|
|
171
|
-
selectable ? /* @__PURE__ */ jsxDEV2("td", {
|
|
172
|
-
className: "border-table-border border-t px-4 py-2",
|
|
173
|
-
children: /* @__PURE__ */ jsxDEV2("input", {
|
|
174
|
-
type: "checkbox",
|
|
175
|
-
"data-select-row": true,
|
|
176
|
-
value: String(row[pk] ?? ""),
|
|
177
|
-
"aria-label": `Select row ${String(row[pk] ?? i)}`
|
|
178
|
-
}, undefined, false, undefined, this)
|
|
179
|
-
}, undefined, false, undefined, this) : null,
|
|
180
|
-
columns.map((col) => /* @__PURE__ */ jsxDEV2("td", {
|
|
181
|
-
className: "border-table-border border-t px-4 py-2",
|
|
182
|
-
children: col === "status" && statusBadge(row[col]) ? /* @__PURE__ */ jsxDEV2("span", {
|
|
183
|
-
className: `rounded-full px-2 py-0.5 text-xs font-semibold ${statusBadge(row[col]) ?? ""}`,
|
|
184
|
-
children: cell(row[col])
|
|
185
|
-
}, undefined, false, undefined, this) : cell(row[col])
|
|
186
|
-
}, col, false, undefined, this)),
|
|
187
|
-
editable ? /* @__PURE__ */ jsxDEV2("td", {
|
|
188
|
-
className: "border-table-border border-t px-4 py-2 whitespace-nowrap",
|
|
189
|
-
children: /* @__PURE__ */ jsxDEV2("div", {
|
|
190
|
-
className: "border-table-border inline-flex overflow-hidden rounded-md border",
|
|
191
|
-
children: [
|
|
192
|
-
/* @__PURE__ */ jsxDEV2("button", {
|
|
193
|
-
type: "button",
|
|
194
|
-
"data-edit-id": String(row[pk] ?? ""),
|
|
195
|
-
className: "text-link hover:bg-table-row-hover px-2 py-1 text-sm font-semibold",
|
|
196
|
-
children: "Edit"
|
|
197
|
-
}, undefined, false, undefined, this),
|
|
198
|
-
/* @__PURE__ */ jsxDEV2("button", {
|
|
199
|
-
type: "button",
|
|
200
|
-
"data-delete-id": String(row[pk] ?? ""),
|
|
201
|
-
className: "border-table-border text-destructive hover:bg-table-row-hover border-l px-2 py-1 text-sm font-semibold",
|
|
202
|
-
children: "Delete"
|
|
203
|
-
}, undefined, false, undefined, this)
|
|
204
|
-
]
|
|
205
|
-
}, undefined, true, undefined, this)
|
|
206
|
-
}, undefined, false, undefined, this) : null
|
|
207
|
-
]
|
|
208
|
-
}, i, true, undefined, this))
|
|
209
|
-
}, undefined, false, undefined, this)
|
|
210
|
-
]
|
|
211
|
-
}, undefined, true, undefined, this)
|
|
212
|
-
}, undefined, false, undefined, this);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// src/react/page/components/Masthead.tsx
|
|
216
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
217
|
-
function Masthead({ title, group, resource, total }) {
|
|
218
|
-
const today = new Date().toLocaleDateString("en-US", {
|
|
219
|
-
weekday: "long",
|
|
220
|
-
day: "numeric",
|
|
221
|
-
month: "long",
|
|
222
|
-
year: "numeric"
|
|
223
|
-
});
|
|
224
|
-
return /* @__PURE__ */ jsxDEV3("header", {
|
|
225
|
-
className: "bg-header text-header-foreground",
|
|
226
|
-
children: [
|
|
227
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
228
|
-
className: "flex items-center justify-between gap-4 py-2 text-xs tracking-widest text-text-muted uppercase",
|
|
229
|
-
children: [
|
|
230
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
231
|
-
children: today
|
|
232
|
-
}, undefined, false, undefined, this),
|
|
233
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
234
|
-
className: "hidden sm:inline",
|
|
235
|
-
children: "Daily Edition"
|
|
236
|
-
}, undefined, false, undefined, this),
|
|
237
|
-
/* @__PURE__ */ jsxDEV3("button", {
|
|
238
|
-
id: "koran-theme-toggle",
|
|
239
|
-
type: "button",
|
|
240
|
-
className: "border-border hover:bg-navigation-hover rounded-full border px-3 py-1 tracking-widest uppercase",
|
|
241
|
-
children: "◐ Theme"
|
|
242
|
-
}, undefined, false, undefined, this)
|
|
243
|
-
]
|
|
244
|
-
}, undefined, true, undefined, this),
|
|
245
|
-
/* @__PURE__ */ jsxDEV3("h1", {
|
|
246
|
-
className: "font-koran py-2 text-center text-5xl font-black tracking-tight",
|
|
247
|
-
children: title
|
|
248
|
-
}, undefined, false, undefined, this),
|
|
249
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
250
|
-
className: "flex items-center justify-center gap-2 pb-3 text-sm text-text-muted",
|
|
251
|
-
children: [
|
|
252
|
-
group ? /* @__PURE__ */ jsxDEV3("span", {
|
|
253
|
-
className: "uppercase",
|
|
254
|
-
children: group
|
|
255
|
-
}, undefined, false, undefined, this) : null,
|
|
256
|
-
group && (resource || total !== undefined) ? /* @__PURE__ */ jsxDEV3("span", {
|
|
257
|
-
"aria-hidden": "true",
|
|
258
|
-
children: "·"
|
|
259
|
-
}, undefined, false, undefined, this) : null,
|
|
260
|
-
resource ? /* @__PURE__ */ jsxDEV3("span", {
|
|
261
|
-
className: "font-mono text-xs",
|
|
262
|
-
children: [
|
|
263
|
-
"/",
|
|
264
|
-
resource
|
|
265
|
-
]
|
|
266
|
-
}, undefined, true, undefined, this) : null,
|
|
267
|
-
total !== undefined ? /* @__PURE__ */ jsxDEV3("span", {
|
|
268
|
-
children: [
|
|
269
|
-
total,
|
|
270
|
-
" records"
|
|
271
|
-
]
|
|
272
|
-
}, undefined, true, undefined, this) : null
|
|
273
|
-
]
|
|
274
|
-
}, undefined, true, undefined, this),
|
|
275
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
276
|
-
className: "koran-rule-double"
|
|
277
|
-
}, undefined, false, undefined, this)
|
|
278
|
-
]
|
|
279
|
-
}, undefined, true, undefined, this);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// src/react/page/components/Pagination.tsx
|
|
283
|
-
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
284
|
-
var pageClass = "border-border rounded-md border px-3 py-1 text-sm hover:bg-navigation-hover";
|
|
285
|
-
var currentClass = "bg-primary text-primary-foreground rounded-md px-3 py-1 text-sm font-bold";
|
|
286
|
-
var disabledClass = "border-border text-text-disabled rounded-md border px-3 py-1 text-sm";
|
|
287
|
-
function Pagination({ page, totalPages, total, limit, params }) {
|
|
288
|
-
const from = total === 0 ? 0 : (page - 1) * limit + 1;
|
|
289
|
-
const to = Math.min(page * limit, total);
|
|
290
|
-
return /* @__PURE__ */ jsxDEV4("nav", {
|
|
291
|
-
className: "flex flex-wrap items-center justify-between gap-3 py-4 text-sm",
|
|
292
|
-
children: [
|
|
293
|
-
/* @__PURE__ */ jsxDEV4("p", {
|
|
294
|
-
className: "text-text-muted",
|
|
295
|
-
"data-panel-count": true,
|
|
296
|
-
children: [
|
|
297
|
-
"Page ",
|
|
298
|
-
page,
|
|
299
|
-
" of ",
|
|
300
|
-
totalPages,
|
|
301
|
-
" — ",
|
|
302
|
-
from,
|
|
303
|
-
"–",
|
|
304
|
-
to,
|
|
305
|
-
" of ",
|
|
306
|
-
total,
|
|
307
|
-
" records"
|
|
308
|
-
]
|
|
309
|
-
}, undefined, true, undefined, this),
|
|
310
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
311
|
-
className: "flex items-center gap-1",
|
|
312
|
-
"data-panel-pages": true,
|
|
313
|
-
children: [
|
|
314
|
-
page > 1 ? /* @__PURE__ */ jsxDEV4("a", {
|
|
315
|
-
className: pageClass,
|
|
316
|
-
"data-qlink": true,
|
|
317
|
-
href: href(params, { page: page - 1 }),
|
|
318
|
-
children: "← Previous"
|
|
319
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("span", {
|
|
320
|
-
className: disabledClass,
|
|
321
|
-
children: "← Previous"
|
|
322
|
-
}, undefined, false, undefined, this),
|
|
323
|
-
pageWindow(page, totalPages).map((p, i) => p === "…" ? /* @__PURE__ */ jsxDEV4("span", {
|
|
324
|
-
className: "text-text-muted px-1",
|
|
325
|
-
children: "…"
|
|
326
|
-
}, `e${i}`, false, undefined, this) : p === page ? /* @__PURE__ */ jsxDEV4("span", {
|
|
327
|
-
className: currentClass,
|
|
328
|
-
children: p
|
|
329
|
-
}, p, false, undefined, this) : /* @__PURE__ */ jsxDEV4("a", {
|
|
330
|
-
className: pageClass,
|
|
331
|
-
"data-qlink": true,
|
|
332
|
-
href: href(params, { page: p }),
|
|
333
|
-
children: p
|
|
334
|
-
}, p, false, undefined, this)),
|
|
335
|
-
page < totalPages ? /* @__PURE__ */ jsxDEV4("a", {
|
|
336
|
-
className: pageClass,
|
|
337
|
-
"data-qlink": true,
|
|
338
|
-
href: href(params, { page: page + 1 }),
|
|
339
|
-
children: "Next →"
|
|
340
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("span", {
|
|
341
|
-
className: disabledClass,
|
|
342
|
-
children: "Next →"
|
|
343
|
-
}, undefined, false, undefined, this)
|
|
344
|
-
]
|
|
345
|
-
}, undefined, true, undefined, this)
|
|
346
|
-
]
|
|
347
|
-
}, undefined, true, undefined, this);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/react/page/components/Sidebar.tsx
|
|
351
|
-
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
352
|
-
function SidebarItemView({ item, depth = 0 }) {
|
|
353
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
354
|
-
return /* @__PURE__ */ jsxDEV5("li", {
|
|
355
|
-
children: [
|
|
356
|
-
/* @__PURE__ */ jsxDEV5("a", {
|
|
357
|
-
href: item.href,
|
|
358
|
-
"aria-current": item.active ? "page" : undefined,
|
|
359
|
-
className: item.active ? "bg-sidebar-primary text-sidebar-primary-foreground flex items-center gap-2 rounded-md px-2 py-1.5 text-sm font-semibold" : "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex items-center gap-2 rounded-md px-2 py-1.5 text-sm",
|
|
360
|
-
style: depth > 0 ? { paddingLeft: `${8 + depth * 12}px` } : undefined,
|
|
361
|
-
children: [
|
|
362
|
-
item.icon ? /* @__PURE__ */ jsxDEV5("span", {
|
|
363
|
-
"aria-hidden": "true",
|
|
364
|
-
children: item.icon
|
|
365
|
-
}, undefined, false, undefined, this) : null,
|
|
366
|
-
/* @__PURE__ */ jsxDEV5("span", {
|
|
367
|
-
children: item.label
|
|
368
|
-
}, undefined, false, undefined, this)
|
|
369
|
-
]
|
|
370
|
-
}, undefined, true, undefined, this),
|
|
371
|
-
hasChildren ? /* @__PURE__ */ jsxDEV5("ul", {
|
|
372
|
-
className: "border-sidebar-border mt-0.5 ml-2 flex flex-col gap-0.5 border-l py-1 pl-2",
|
|
373
|
-
children: item.children.map((child) => /* @__PURE__ */ jsxDEV5(SidebarItemView, {
|
|
374
|
-
item: child,
|
|
375
|
-
depth: depth + 1
|
|
376
|
-
}, child.id, false, undefined, this))
|
|
377
|
-
}, undefined, false, undefined, this) : null
|
|
378
|
-
]
|
|
379
|
-
}, undefined, true, undefined, this);
|
|
380
|
-
}
|
|
381
|
-
function hasActive(items) {
|
|
382
|
-
for (const it of items) {
|
|
383
|
-
if (it.active)
|
|
384
|
-
return true;
|
|
385
|
-
if (it.children && hasActive(it.children))
|
|
386
|
-
return true;
|
|
387
|
-
}
|
|
388
|
-
return false;
|
|
389
|
-
}
|
|
390
|
-
function Sidebar({ title, groups }) {
|
|
391
|
-
return /* @__PURE__ */ jsxDEV5("aside", {
|
|
392
|
-
className: "bg-sidebar text-sidebar-foreground border-sidebar-border min-h-0 w-64 shrink-0 overflow-y-auto rounded-lg border",
|
|
393
|
-
children: [
|
|
394
|
-
/* @__PURE__ */ jsxDEV5("div", {
|
|
395
|
-
className: "border-sidebar-border border-b px-4 py-3",
|
|
396
|
-
children: /* @__PURE__ */ jsxDEV5("p", {
|
|
397
|
-
className: "font-koran text-xl font-black tracking-tight",
|
|
398
|
-
children: title
|
|
399
|
-
}, undefined, false, undefined, this)
|
|
400
|
-
}, undefined, false, undefined, this),
|
|
401
|
-
/* @__PURE__ */ jsxDEV5("nav", {
|
|
402
|
-
className: "flex flex-col gap-4 p-3",
|
|
403
|
-
children: groups.map((group) => /* @__PURE__ */ jsxDEV5("section", {
|
|
404
|
-
children: /* @__PURE__ */ jsxDEV5("details", {
|
|
405
|
-
className: "group",
|
|
406
|
-
open: hasActive(group.items) || undefined,
|
|
407
|
-
children: [
|
|
408
|
-
/* @__PURE__ */ jsxDEV5("summary", {
|
|
409
|
-
className: "font-koran border-sidebar-border flex cursor-pointer list-none items-center justify-between border-b px-2 pb-1 text-base font-bold tracking-tight [&::-webkit-details-marker]:hidden",
|
|
410
|
-
children: [
|
|
411
|
-
/* @__PURE__ */ jsxDEV5("span", {
|
|
412
|
-
children: group.name
|
|
413
|
-
}, undefined, false, undefined, this),
|
|
414
|
-
/* @__PURE__ */ jsxDEV5("span", {
|
|
415
|
-
"aria-hidden": "true",
|
|
416
|
-
className: "text-text-muted text-xs transition group-open:rotate-180",
|
|
417
|
-
children: "▾"
|
|
418
|
-
}, undefined, false, undefined, this)
|
|
419
|
-
]
|
|
420
|
-
}, undefined, true, undefined, this),
|
|
421
|
-
/* @__PURE__ */ jsxDEV5("ul", {
|
|
422
|
-
className: "border-sidebar-border mt-1 ml-2 flex flex-col gap-0.5 border-l py-1 pl-2",
|
|
423
|
-
children: group.items.map((item) => /* @__PURE__ */ jsxDEV5(SidebarItemView, {
|
|
424
|
-
item
|
|
425
|
-
}, item.id, false, undefined, this))
|
|
426
|
-
}, undefined, false, undefined, this)
|
|
427
|
-
]
|
|
428
|
-
}, undefined, true, undefined, this)
|
|
429
|
-
}, group.name, false, undefined, this))
|
|
430
|
-
}, undefined, false, undefined, this)
|
|
431
|
-
]
|
|
432
|
-
}, undefined, true, undefined, this);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// src/react/page/components/Toolbar.tsx
|
|
436
|
-
import { jsxDEV as jsxDEV6, Fragment } from "react/jsx-dev-runtime";
|
|
437
|
-
var inputClass = "bg-input-background border-input text-foreground placeholder:text-form-placeholder rounded-md border px-3 py-1.5 text-sm";
|
|
438
|
-
var labelClass = "flex flex-col gap-1 text-xs font-semibold tracking-wider text-form-label uppercase";
|
|
439
|
-
function Toolbar({ searchable, filterable, sortable, params }) {
|
|
440
|
-
if (!searchable?.length && !filterable?.length && !sortable?.length)
|
|
441
|
-
return null;
|
|
442
|
-
return /* @__PURE__ */ jsxDEV6("form", {
|
|
443
|
-
method: "get",
|
|
444
|
-
action: "",
|
|
445
|
-
className: "flex flex-wrap items-end gap-3 py-4",
|
|
446
|
-
children: [
|
|
447
|
-
searchable && searchable.length > 0 ? /* @__PURE__ */ jsxDEV6("label", {
|
|
448
|
-
className: labelClass,
|
|
449
|
-
children: [
|
|
450
|
-
"Search",
|
|
451
|
-
/* @__PURE__ */ jsxDEV6("input", {
|
|
452
|
-
name: "search",
|
|
453
|
-
defaultValue: String(params.search ?? ""),
|
|
454
|
-
placeholder: searchable.join(", "),
|
|
455
|
-
className: inputClass
|
|
456
|
-
}, undefined, false, undefined, this)
|
|
457
|
-
]
|
|
458
|
-
}, undefined, true, undefined, this) : null,
|
|
459
|
-
(filterable ?? []).map((field) => /* @__PURE__ */ jsxDEV6("label", {
|
|
460
|
-
className: labelClass,
|
|
461
|
-
children: [
|
|
462
|
-
field,
|
|
463
|
-
/* @__PURE__ */ jsxDEV6("input", {
|
|
464
|
-
name: field,
|
|
465
|
-
defaultValue: String(params[field] ?? ""),
|
|
466
|
-
className: inputClass
|
|
467
|
-
}, undefined, false, undefined, this)
|
|
468
|
-
]
|
|
469
|
-
}, field, true, undefined, this)),
|
|
470
|
-
sortable && sortable.length > 0 ? /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
471
|
-
children: [
|
|
472
|
-
/* @__PURE__ */ jsxDEV6("label", {
|
|
473
|
-
className: labelClass,
|
|
474
|
-
children: [
|
|
475
|
-
"Sort",
|
|
476
|
-
/* @__PURE__ */ jsxDEV6("select", {
|
|
477
|
-
name: "sort",
|
|
478
|
-
defaultValue: String(params.sort ?? ""),
|
|
479
|
-
className: inputClass,
|
|
480
|
-
children: [
|
|
481
|
-
/* @__PURE__ */ jsxDEV6("option", {
|
|
482
|
-
value: "",
|
|
483
|
-
children: "—"
|
|
484
|
-
}, undefined, false, undefined, this),
|
|
485
|
-
sortable.map((field) => /* @__PURE__ */ jsxDEV6("option", {
|
|
486
|
-
value: field,
|
|
487
|
-
children: field
|
|
488
|
-
}, field, false, undefined, this))
|
|
489
|
-
]
|
|
490
|
-
}, undefined, true, undefined, this)
|
|
491
|
-
]
|
|
492
|
-
}, undefined, true, undefined, this),
|
|
493
|
-
/* @__PURE__ */ jsxDEV6("label", {
|
|
494
|
-
className: labelClass,
|
|
495
|
-
children: [
|
|
496
|
-
"Order",
|
|
497
|
-
/* @__PURE__ */ jsxDEV6("select", {
|
|
498
|
-
name: "order",
|
|
499
|
-
defaultValue: String(params.order ?? ""),
|
|
500
|
-
className: inputClass,
|
|
501
|
-
children: [
|
|
502
|
-
/* @__PURE__ */ jsxDEV6("option", {
|
|
503
|
-
value: "asc",
|
|
504
|
-
children: "Ascending"
|
|
505
|
-
}, undefined, false, undefined, this),
|
|
506
|
-
/* @__PURE__ */ jsxDEV6("option", {
|
|
507
|
-
value: "desc",
|
|
508
|
-
children: "Descending"
|
|
509
|
-
}, undefined, false, undefined, this)
|
|
510
|
-
]
|
|
511
|
-
}, undefined, true, undefined, this)
|
|
512
|
-
]
|
|
513
|
-
}, undefined, true, undefined, this)
|
|
514
|
-
]
|
|
515
|
-
}, undefined, true, undefined, this) : null,
|
|
516
|
-
/* @__PURE__ */ jsxDEV6("button", {
|
|
517
|
-
type: "submit",
|
|
518
|
-
className: "bg-primary text-primary-foreground rounded-md px-4 py-1.5 text-sm font-semibold",
|
|
519
|
-
children: "Apply"
|
|
520
|
-
}, undefined, false, undefined, this)
|
|
521
|
-
]
|
|
522
|
-
}, undefined, true, undefined, this);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// src/react/page/Panel.tsx
|
|
526
|
-
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
527
|
-
var inputClass2 = "bg-input-background border-input text-foreground rounded-md border px-3 py-1.5 text-sm font-normal normal-case";
|
|
528
|
-
var fieldLabelClass = "flex flex-col gap-1 text-xs font-semibold tracking-wider text-form-label uppercase";
|
|
529
|
-
function FieldInput({ field, required }) {
|
|
530
|
-
switch (field.kind) {
|
|
531
|
-
case "enum":
|
|
532
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
533
|
-
className: fieldLabelClass,
|
|
534
|
-
children: [
|
|
535
|
-
field.name,
|
|
536
|
-
/* @__PURE__ */ jsxDEV7("select", {
|
|
537
|
-
name: field.name,
|
|
538
|
-
required,
|
|
539
|
-
defaultValue: "",
|
|
540
|
-
className: inputClass2,
|
|
541
|
-
children: [
|
|
542
|
-
/* @__PURE__ */ jsxDEV7("option", {
|
|
543
|
-
value: "",
|
|
544
|
-
children: "—"
|
|
545
|
-
}, undefined, false, undefined, this),
|
|
546
|
-
(field.enumValues ?? []).map((v) => /* @__PURE__ */ jsxDEV7("option", {
|
|
547
|
-
value: v,
|
|
548
|
-
children: v
|
|
549
|
-
}, v, false, undefined, this))
|
|
550
|
-
]
|
|
551
|
-
}, undefined, true, undefined, this)
|
|
552
|
-
]
|
|
553
|
-
}, undefined, true, undefined, this);
|
|
554
|
-
case "boolean":
|
|
555
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
556
|
-
className: fieldLabelClass,
|
|
557
|
-
children: [
|
|
558
|
-
field.name,
|
|
559
|
-
/* @__PURE__ */ jsxDEV7("input", {
|
|
560
|
-
type: "checkbox",
|
|
561
|
-
name: field.name,
|
|
562
|
-
value: "true",
|
|
563
|
-
className: "h-4 w-4"
|
|
564
|
-
}, undefined, false, undefined, this)
|
|
565
|
-
]
|
|
566
|
-
}, undefined, true, undefined, this);
|
|
567
|
-
case "integer":
|
|
568
|
-
case "number":
|
|
569
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
570
|
-
className: fieldLabelClass,
|
|
571
|
-
children: [
|
|
572
|
-
field.name,
|
|
573
|
-
/* @__PURE__ */ jsxDEV7("input", {
|
|
574
|
-
type: "number",
|
|
575
|
-
step: field.kind === "number" ? "any" : "1",
|
|
576
|
-
name: field.name,
|
|
577
|
-
required,
|
|
578
|
-
className: inputClass2
|
|
579
|
-
}, undefined, false, undefined, this)
|
|
580
|
-
]
|
|
581
|
-
}, undefined, true, undefined, this);
|
|
582
|
-
case "date":
|
|
583
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
584
|
-
className: fieldLabelClass,
|
|
585
|
-
children: [
|
|
586
|
-
field.name,
|
|
587
|
-
/* @__PURE__ */ jsxDEV7("input", {
|
|
588
|
-
type: "datetime-local",
|
|
589
|
-
name: field.name,
|
|
590
|
-
required,
|
|
591
|
-
className: inputClass2
|
|
592
|
-
}, undefined, false, undefined, this)
|
|
593
|
-
]
|
|
594
|
-
}, undefined, true, undefined, this);
|
|
595
|
-
case "json":
|
|
596
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
597
|
-
className: fieldLabelClass,
|
|
598
|
-
children: [
|
|
599
|
-
field.name,
|
|
600
|
-
/* @__PURE__ */ jsxDEV7("textarea", {
|
|
601
|
-
name: field.name,
|
|
602
|
-
"data-json": true,
|
|
603
|
-
rows: 3,
|
|
604
|
-
placeholder: "{}",
|
|
605
|
-
className: `${inputClass2} font-mono`
|
|
606
|
-
}, undefined, false, undefined, this)
|
|
607
|
-
]
|
|
608
|
-
}, undefined, true, undefined, this);
|
|
609
|
-
default:
|
|
610
|
-
return /* @__PURE__ */ jsxDEV7("label", {
|
|
611
|
-
className: fieldLabelClass,
|
|
612
|
-
children: [
|
|
613
|
-
field.name,
|
|
614
|
-
/* @__PURE__ */ jsxDEV7("input", {
|
|
615
|
-
name: field.name,
|
|
616
|
-
required,
|
|
617
|
-
className: inputClass2
|
|
618
|
-
}, undefined, false, undefined, this)
|
|
619
|
-
]
|
|
620
|
-
}, undefined, true, undefined, this);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
function itemLabel(r) {
|
|
624
|
-
return r.metadata.pluralLabel ?? r.metadata.label ?? r.metadata.id;
|
|
625
|
-
}
|
|
626
|
-
function toSidebarItem(node, activeId) {
|
|
627
|
-
return {
|
|
628
|
-
id: node.metadata.id,
|
|
629
|
-
label: itemLabel(node),
|
|
630
|
-
icon: node.metadata.icon,
|
|
631
|
-
href: node.path,
|
|
632
|
-
active: node.metadata.id === activeId,
|
|
633
|
-
children: node.children.filter((c) => !c.metadata.hidden).map((c) => toSidebarItem(c, activeId))
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
function buildGroupsFromTree(tree, activeId) {
|
|
637
|
-
const byGroup = new Map;
|
|
638
|
-
for (const root of tree) {
|
|
639
|
-
if (root.metadata.hidden)
|
|
640
|
-
continue;
|
|
641
|
-
const name = root.metadata.group ?? "General";
|
|
642
|
-
let group = byGroup.get(name);
|
|
643
|
-
if (!group) {
|
|
644
|
-
group = { name, items: [] };
|
|
645
|
-
byGroup.set(name, group);
|
|
646
|
-
}
|
|
647
|
-
group.items.push(toSidebarItem(root, activeId));
|
|
648
|
-
}
|
|
649
|
-
return [...byGroup.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
650
|
-
}
|
|
651
|
-
async function Panel(props) {
|
|
652
|
-
const params = props.params ?? {};
|
|
653
|
-
const page = Math.max(Number(params.page ?? 1) || 1, 1);
|
|
654
|
-
const limit = Math.max(Number(params.limit ?? props.query?.pagination?.default ?? 20) || 1, 1);
|
|
655
|
-
let rows = [];
|
|
656
|
-
let total = 0;
|
|
657
|
-
if (props.load) {
|
|
658
|
-
try {
|
|
659
|
-
const result = await props.load(params);
|
|
660
|
-
rows = result.data;
|
|
661
|
-
total = result.total;
|
|
662
|
-
} catch {}
|
|
663
|
-
}
|
|
664
|
-
const columns = rows.length > 0 ? Object.keys(rows[0] ?? {}).filter((c) => c !== "deletedAt") : [];
|
|
665
|
-
const title = props.metadata?.pluralLabel ?? props.metadata?.label ?? props.resource ?? "Panel";
|
|
666
|
-
const totalPages = Math.max(1, Math.ceil(total / limit));
|
|
667
|
-
const pk = props.primaryKey ?? "id";
|
|
668
|
-
const deletedAt = props.deletedAtField ?? "deletedAt";
|
|
669
|
-
const fieldDefs = props.fields?.length ? props.fields.filter((f) => !f.autoIncrement && f.name !== deletedAt).map((f) => ({
|
|
670
|
-
name: f.name,
|
|
671
|
-
kind: f.kind,
|
|
672
|
-
nullable: f.nullable,
|
|
673
|
-
enumValues: f.enumValues
|
|
674
|
-
})) : columns.filter((c) => c !== deletedAt).map((name) => ({
|
|
675
|
-
name,
|
|
676
|
-
kind: "text",
|
|
677
|
-
nullable: name === pk
|
|
678
|
-
}));
|
|
679
|
-
const createFields = fieldDefs;
|
|
680
|
-
const editFields = fieldDefs.filter((f) => f.name !== pk);
|
|
681
|
-
const isRequired = (f) => !f.nullable && f.kind !== "boolean";
|
|
682
|
-
const canCreate = props.operations?.create !== false;
|
|
683
|
-
const canEdit = props.operations?.update !== false || props.operations?.replace !== false;
|
|
684
|
-
const canDelete = props.operations?.delete !== false;
|
|
685
|
-
const selectable = canEdit || canDelete;
|
|
686
|
-
const tree = getRackTree().filter((r) => !r.metadata.hidden);
|
|
687
|
-
const groups = buildGroupsFromTree(tree, props.resource);
|
|
688
|
-
const trail = [
|
|
689
|
-
{ label: "Dashboard", href: "/" },
|
|
690
|
-
...props.metadata?.group ? [{ label: props.metadata.group }] : [],
|
|
691
|
-
{ label: title }
|
|
692
|
-
];
|
|
693
|
-
return /* @__PURE__ */ jsxDEV7("div", {
|
|
694
|
-
className: "koran-paper font-koran-body text-foreground flex min-h-screen flex-col",
|
|
695
|
-
children: /* @__PURE__ */ jsxDEV7("div", {
|
|
696
|
-
className: "flex flex-1 gap-6 p-4 sm:p-6",
|
|
697
|
-
children: [
|
|
698
|
-
/* @__PURE__ */ jsxDEV7(Sidebar, {
|
|
699
|
-
title: "Panel",
|
|
700
|
-
groups
|
|
701
|
-
}, undefined, false, undefined, this),
|
|
702
|
-
/* @__PURE__ */ jsxDEV7("main", {
|
|
703
|
-
className: "flex min-w-0 flex-1 flex-col",
|
|
704
|
-
children: [
|
|
705
|
-
/* @__PURE__ */ jsxDEV7(Breadcrumb, {
|
|
706
|
-
trail
|
|
707
|
-
}, undefined, false, undefined, this),
|
|
708
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
709
|
-
className: "mx-auto w-full max-w-5xl px-4 pb-10 sm:px-6",
|
|
710
|
-
children: [
|
|
711
|
-
/* @__PURE__ */ jsxDEV7(Masthead, {
|
|
712
|
-
title,
|
|
713
|
-
group: props.metadata?.group,
|
|
714
|
-
resource: props.resource,
|
|
715
|
-
total
|
|
716
|
-
}, undefined, false, undefined, this),
|
|
717
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
718
|
-
"data-query-url": props.queryUrl,
|
|
719
|
-
children: [
|
|
720
|
-
/* @__PURE__ */ jsxDEV7(Toolbar, {
|
|
721
|
-
searchable: props.query?.searchable,
|
|
722
|
-
filterable: props.query?.filterable,
|
|
723
|
-
sortable: props.query?.sortable,
|
|
724
|
-
params
|
|
725
|
-
}, undefined, false, undefined, this),
|
|
726
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
727
|
-
className: "flex items-center justify-between gap-3 pb-3",
|
|
728
|
-
children: [
|
|
729
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
730
|
-
"data-bulk-bar": true,
|
|
731
|
-
style: { display: "none" },
|
|
732
|
-
className: "items-center gap-2",
|
|
733
|
-
children: [
|
|
734
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
735
|
-
"data-bulk-count": true,
|
|
736
|
-
className: "text-sm text-text-muted"
|
|
737
|
-
}, undefined, false, undefined, this),
|
|
738
|
-
canDelete ? /* @__PURE__ */ jsxDEV7("button", {
|
|
739
|
-
type: "button",
|
|
740
|
-
"data-bulk-delete": true,
|
|
741
|
-
className: "bg-destructive text-destructive-foreground rounded-md px-3 py-1.5 text-sm font-semibold",
|
|
742
|
-
children: "Delete selected"
|
|
743
|
-
}, undefined, false, undefined, this) : null,
|
|
744
|
-
canEdit ? /* @__PURE__ */ jsxDEV7("span", {
|
|
745
|
-
className: "inline-flex items-center gap-2",
|
|
746
|
-
children: [
|
|
747
|
-
/* @__PURE__ */ jsxDEV7("select", {
|
|
748
|
-
"data-bulk-field": true,
|
|
749
|
-
"aria-label": "Bulk field",
|
|
750
|
-
className: "bg-input-background border-input rounded-md border px-2 py-1.5 text-sm",
|
|
751
|
-
children: editFields.map((f) => /* @__PURE__ */ jsxDEV7("option", {
|
|
752
|
-
value: f.name,
|
|
753
|
-
children: f.name
|
|
754
|
-
}, f.name, false, undefined, this))
|
|
755
|
-
}, undefined, false, undefined, this),
|
|
756
|
-
/* @__PURE__ */ jsxDEV7("input", {
|
|
757
|
-
"data-bulk-value": true,
|
|
758
|
-
placeholder: "New value",
|
|
759
|
-
"aria-label": "Bulk value",
|
|
760
|
-
className: "bg-input-background border-input placeholder:text-form-placeholder rounded-md border px-2 py-1.5 text-sm"
|
|
761
|
-
}, undefined, false, undefined, this),
|
|
762
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
763
|
-
type: "button",
|
|
764
|
-
"data-bulk-apply": true,
|
|
765
|
-
className: "bg-secondary text-secondary-foreground rounded-md px-3 py-1.5 text-sm font-semibold",
|
|
766
|
-
children: "Apply"
|
|
767
|
-
}, undefined, false, undefined, this)
|
|
768
|
-
]
|
|
769
|
-
}, undefined, true, undefined, this) : null,
|
|
770
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
771
|
-
type: "button",
|
|
772
|
-
"data-bulk-clear": true,
|
|
773
|
-
className: "text-text-muted text-sm underline",
|
|
774
|
-
children: "Clear"
|
|
775
|
-
}, undefined, false, undefined, this)
|
|
776
|
-
]
|
|
777
|
-
}, undefined, true, undefined, this),
|
|
778
|
-
canCreate ? /* @__PURE__ */ jsxDEV7("button", {
|
|
779
|
-
type: "button",
|
|
780
|
-
"data-open-create": true,
|
|
781
|
-
className: "bg-primary text-primary-foreground ml-auto rounded-md px-4 py-1.5 text-sm font-semibold",
|
|
782
|
-
children: "+ New"
|
|
783
|
-
}, undefined, false, undefined, this) : null
|
|
784
|
-
]
|
|
785
|
-
}, undefined, true, undefined, this),
|
|
786
|
-
/* @__PURE__ */ jsxDEV7(DataTable, {
|
|
787
|
-
columns,
|
|
788
|
-
rows,
|
|
789
|
-
sortable: props.query?.sortable,
|
|
790
|
-
params,
|
|
791
|
-
selectable,
|
|
792
|
-
editable: canEdit || canDelete,
|
|
793
|
-
primaryKey: pk
|
|
794
|
-
}, undefined, false, undefined, this),
|
|
795
|
-
/* @__PURE__ */ jsxDEV7(Pagination, {
|
|
796
|
-
page,
|
|
797
|
-
totalPages,
|
|
798
|
-
total,
|
|
799
|
-
limit,
|
|
800
|
-
params
|
|
801
|
-
}, undefined, false, undefined, this),
|
|
802
|
-
/* @__PURE__ */ jsxDEV7("dialog", {
|
|
803
|
-
id: "rack-create",
|
|
804
|
-
className: "bg-card text-card-foreground rounded-lg border p-0",
|
|
805
|
-
children: /* @__PURE__ */ jsxDEV7("form", {
|
|
806
|
-
"data-create-form": true,
|
|
807
|
-
className: "flex min-w-80 flex-col gap-3 p-6",
|
|
808
|
-
children: [
|
|
809
|
-
/* @__PURE__ */ jsxDEV7("h2", {
|
|
810
|
-
className: "font-koran text-2xl font-bold",
|
|
811
|
-
children: "New record"
|
|
812
|
-
}, undefined, false, undefined, this),
|
|
813
|
-
createFields.length > 0 ? createFields.map((f) => /* @__PURE__ */ jsxDEV7(FieldInput, {
|
|
814
|
-
field: f,
|
|
815
|
-
required: isRequired(f)
|
|
816
|
-
}, f.name, false, undefined, this)) : /* @__PURE__ */ jsxDEV7("label", {
|
|
817
|
-
className: "flex flex-col gap-1 text-xs font-semibold tracking-wider text-form-label uppercase",
|
|
818
|
-
children: [
|
|
819
|
-
"JSON body",
|
|
820
|
-
/* @__PURE__ */ jsxDEV7("textarea", {
|
|
821
|
-
"data-create-json": true,
|
|
822
|
-
rows: 4,
|
|
823
|
-
placeholder: '{"name": "..."}',
|
|
824
|
-
className: "bg-input-background border-input text-foreground rounded-md border px-3 py-1.5 font-mono text-sm font-normal normal-case"
|
|
825
|
-
}, undefined, false, undefined, this)
|
|
826
|
-
]
|
|
827
|
-
}, undefined, true, undefined, this),
|
|
828
|
-
/* @__PURE__ */ jsxDEV7("p", {
|
|
829
|
-
"data-form-error": true,
|
|
830
|
-
className: "text-form-error text-sm"
|
|
831
|
-
}, undefined, false, undefined, this),
|
|
832
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
833
|
-
className: "flex justify-end gap-2",
|
|
834
|
-
children: [
|
|
835
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
836
|
-
type: "button",
|
|
837
|
-
"data-close": true,
|
|
838
|
-
className: "border-border rounded-md border px-4 py-1.5 text-sm",
|
|
839
|
-
children: "Cancel"
|
|
840
|
-
}, undefined, false, undefined, this),
|
|
841
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
842
|
-
type: "submit",
|
|
843
|
-
className: "bg-primary text-primary-foreground rounded-md px-4 py-1.5 text-sm font-semibold",
|
|
844
|
-
children: "Create"
|
|
845
|
-
}, undefined, false, undefined, this)
|
|
846
|
-
]
|
|
847
|
-
}, undefined, true, undefined, this)
|
|
848
|
-
]
|
|
849
|
-
}, undefined, true, undefined, this)
|
|
850
|
-
}, undefined, false, undefined, this),
|
|
851
|
-
/* @__PURE__ */ jsxDEV7("dialog", {
|
|
852
|
-
id: "rack-edit",
|
|
853
|
-
className: "bg-card text-card-foreground rounded-lg border p-0",
|
|
854
|
-
children: /* @__PURE__ */ jsxDEV7("form", {
|
|
855
|
-
"data-edit-form": true,
|
|
856
|
-
className: "flex min-w-80 flex-col gap-3 p-6",
|
|
857
|
-
children: [
|
|
858
|
-
/* @__PURE__ */ jsxDEV7("h2", {
|
|
859
|
-
className: "font-koran text-2xl font-bold",
|
|
860
|
-
children: [
|
|
861
|
-
"Edit record ",
|
|
862
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
863
|
-
"data-edit-id-label": true,
|
|
864
|
-
className: "text-text-muted text-lg"
|
|
865
|
-
}, undefined, false, undefined, this)
|
|
866
|
-
]
|
|
867
|
-
}, undefined, true, undefined, this),
|
|
868
|
-
editFields.map((f) => /* @__PURE__ */ jsxDEV7(FieldInput, {
|
|
869
|
-
field: f
|
|
870
|
-
}, f.name, false, undefined, this)),
|
|
871
|
-
/* @__PURE__ */ jsxDEV7("p", {
|
|
872
|
-
"data-form-error": true,
|
|
873
|
-
className: "text-form-error text-sm"
|
|
874
|
-
}, undefined, false, undefined, this),
|
|
875
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
876
|
-
className: "flex justify-end gap-2",
|
|
877
|
-
children: [
|
|
878
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
879
|
-
type: "button",
|
|
880
|
-
"data-close": true,
|
|
881
|
-
className: "border-border rounded-md border px-4 py-1.5 text-sm",
|
|
882
|
-
children: "Cancel"
|
|
883
|
-
}, undefined, false, undefined, this),
|
|
884
|
-
/* @__PURE__ */ jsxDEV7("button", {
|
|
885
|
-
type: "submit",
|
|
886
|
-
className: "bg-primary text-primary-foreground rounded-md px-4 py-1.5 text-sm font-semibold",
|
|
887
|
-
children: "Save"
|
|
888
|
-
}, undefined, false, undefined, this)
|
|
889
|
-
]
|
|
890
|
-
}, undefined, true, undefined, this)
|
|
891
|
-
]
|
|
892
|
-
}, undefined, true, undefined, this)
|
|
893
|
-
}, undefined, false, undefined, this),
|
|
894
|
-
/* @__PURE__ */ jsxDEV7("script", {
|
|
895
|
-
type: "module",
|
|
896
|
-
src: "/__rack/panel-app.js"
|
|
897
|
-
}, undefined, false, undefined, this)
|
|
898
|
-
]
|
|
899
|
-
}, undefined, true, undefined, this),
|
|
900
|
-
/* @__PURE__ */ jsxDEV7("footer", {
|
|
901
|
-
className: "border-border text-text-muted border-t pt-3 text-center text-xs tracking-widest uppercase",
|
|
902
|
-
children: "Printed by elysia-rack"
|
|
903
|
-
}, undefined, false, undefined, this)
|
|
904
|
-
]
|
|
905
|
-
}, undefined, true, undefined, this)
|
|
906
|
-
]
|
|
907
|
-
}, undefined, true, undefined, this)
|
|
908
|
-
]
|
|
909
|
-
}, undefined, true, undefined, this)
|
|
910
|
-
}, undefined, false, undefined, this);
|
|
911
|
-
}
|
|
912
|
-
export {
|
|
913
|
-
Panel as default
|
|
914
|
-
};
|