@thebes/cadmea 1.0.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/LICENSE +21 -0
- package/README.md +133 -0
- package/dist/RichTextEditor-BPilh7Pw.js +36 -0
- package/dist/RichTextEditor-BPilh7Pw.js.map +1 -0
- package/dist/RichTextEditor-DcLqdFY7.js +15 -0
- package/dist/RichTextEditor-DcLqdFY7.js.map +1 -0
- package/dist/index/index.d.ts +147 -0
- package/dist/index/index.js +740 -0
- package/dist/index/index.js.map +1 -0
- package/dist/index/server.js +508 -0
- package/dist/index/server.js.map +1 -0
- package/dist/tanstack-start/index.d.ts +180 -0
- package/dist/tanstack-start/index.js +897 -0
- package/dist/tanstack-start/index.js.map +1 -0
- package/dist/tanstack-start/server.js +730 -0
- package/dist/tanstack-start/server.js.map +1 -0
- package/package.json +138 -0
|
@@ -0,0 +1,897 @@
|
|
|
1
|
+
import { className, createComponent, delegateEvents, effect, insert, memo, setAttribute, template } from "solid-js/web";
|
|
2
|
+
import { createMutation, createQuery, useQueryClient } from "@tanstack/solid-query";
|
|
3
|
+
import { For, Show, Suspense, createEffect, createSignal, lazy } from "solid-js";
|
|
4
|
+
import { Link, useBlocker } from "@tanstack/solid-router";
|
|
5
|
+
//#region src/CollectionEdit.tsx
|
|
6
|
+
var _tmpl$$4 = /*#__PURE__*/ template(`<p class="text-sm text-error"role=alert>`), _tmpl$2$3 = /*#__PURE__*/ template(`<span class="loading loading-spinner loading-sm">`), _tmpl$3$1 = /*#__PURE__*/ template(`<button type=button class="btn flex-1">`), _tmpl$4$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-primary flex-1">`), _tmpl$5$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline flex-1">`), _tmpl$6$1 = /*#__PURE__*/ template(`<form class="flex flex-col gap-4"><div class="bg-base-100 sticky bottom-0 flex gap-2 border-t py-3">`), _tmpl$7$1 = /*#__PURE__*/ template(`<span class=text-error> *`), _tmpl$8$1 = /*#__PURE__*/ template(`<div class=form-control><label class=label>`), _tmpl$9$1 = /*#__PURE__*/ template(`<button type=submit class="btn btn-primary flex-1">`), _tmpl$0$1 = /*#__PURE__*/ template(`<input class=input type=text>`), _tmpl$1$1 = /*#__PURE__*/ template(`<select class=select>`), _tmpl$10$1 = /*#__PURE__*/ template(`<option>`), _tmpl$11$1 = /*#__PURE__*/ template(`<input class=input type=number>`), _tmpl$12$1 = /*#__PURE__*/ template(`<input class=input type=text readonly>`), _tmpl$13$1 = /*#__PURE__*/ template(`<input class=checkbox type=checkbox>`), _tmpl$14 = /*#__PURE__*/ template(`<p class="text-sm opacity-70 break-all">`), _tmpl$15 = /*#__PURE__*/ template(`<p class="text-sm text-error">`), _tmpl$16 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2"><input class=file-input type=file>`), _tmpl$17 = /*#__PURE__*/ template(`<select class=select><option value>—`), _tmpl$18 = /*#__PURE__*/ template(`<div class="flex flex-col gap-3"><button type=button class="btn btn-outline btn-sm self-start">Add `), _tmpl$19 = /*#__PURE__*/ template(`<div class="card bg-base-200 flex flex-col gap-2 p-3"><button type=button class="btn btn-error btn-outline btn-sm self-start">Remove`);
|
|
7
|
+
const RichTextEditor = lazy(() => import("../RichTextEditor-BPilh7Pw.js").then((mod) => ({ default: mod.RichTextEditor })));
|
|
8
|
+
function editableFields(config) {
|
|
9
|
+
return Object.entries(config.fields).filter(([key]) => key !== "id");
|
|
10
|
+
}
|
|
11
|
+
function CollectionEdit(props) {
|
|
12
|
+
const initialSnapshot = JSON.stringify(props.initialValues ?? {});
|
|
13
|
+
const [values, setValues] = createSignal(props.initialValues ?? {});
|
|
14
|
+
createEffect(() => {
|
|
15
|
+
props.onDirtyChange?.(JSON.stringify(values()) !== initialSnapshot);
|
|
16
|
+
});
|
|
17
|
+
function setField(key, value) {
|
|
18
|
+
setValues((prev) => ({
|
|
19
|
+
...prev,
|
|
20
|
+
[key]: value
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
function editablePayload() {
|
|
24
|
+
return Object.fromEntries(Object.entries(values()).filter(([key]) => props.config.fields[key]?.type !== "date"));
|
|
25
|
+
}
|
|
26
|
+
function handleSubmit(event) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
props.onSubmit(editablePayload());
|
|
29
|
+
}
|
|
30
|
+
const ctx = {
|
|
31
|
+
onUploadFile: props.onUploadFile,
|
|
32
|
+
relationshipOptions: props.relationshipOptions
|
|
33
|
+
};
|
|
34
|
+
const versioned = () => props.config.versions?.drafts && props.draftActions;
|
|
35
|
+
return (() => {
|
|
36
|
+
var _el$ = _tmpl$6$1(), _el$3 = _el$.firstChild;
|
|
37
|
+
_el$.addEventListener("submit", handleSubmit);
|
|
38
|
+
insert(_el$, createComponent(Show, {
|
|
39
|
+
get when() {
|
|
40
|
+
return props.error;
|
|
41
|
+
},
|
|
42
|
+
get children() {
|
|
43
|
+
var _el$2 = _tmpl$$4();
|
|
44
|
+
insert(_el$2, () => props.error);
|
|
45
|
+
return _el$2;
|
|
46
|
+
}
|
|
47
|
+
}), _el$3);
|
|
48
|
+
insert(_el$, createComponent(For, {
|
|
49
|
+
get each() {
|
|
50
|
+
return editableFields(props.config);
|
|
51
|
+
},
|
|
52
|
+
children: ([key, field]) => (() => {
|
|
53
|
+
var _el$0 = _tmpl$8$1(), _el$1 = _el$0.firstChild;
|
|
54
|
+
setAttribute(_el$1, "for", key);
|
|
55
|
+
insert(_el$1, key, null);
|
|
56
|
+
insert(_el$1, createComponent(Show, {
|
|
57
|
+
get when() {
|
|
58
|
+
return field.required;
|
|
59
|
+
},
|
|
60
|
+
get children() {
|
|
61
|
+
return _tmpl$7$1();
|
|
62
|
+
}
|
|
63
|
+
}), null);
|
|
64
|
+
insert(_el$0, () => renderInput(key, field, values()[key], setField, ctx), null);
|
|
65
|
+
return _el$0;
|
|
66
|
+
})()
|
|
67
|
+
}), _el$3);
|
|
68
|
+
insert(_el$3, createComponent(Show, {
|
|
69
|
+
get when() {
|
|
70
|
+
return versioned();
|
|
71
|
+
},
|
|
72
|
+
get fallback() {
|
|
73
|
+
return createComponent(Show, {
|
|
74
|
+
get when() {
|
|
75
|
+
return props.capabilities?.canUpdate !== false;
|
|
76
|
+
},
|
|
77
|
+
get children() {
|
|
78
|
+
var _el$11 = _tmpl$9$1();
|
|
79
|
+
insert(_el$11, createComponent(Show, {
|
|
80
|
+
get when() {
|
|
81
|
+
return props.saving;
|
|
82
|
+
},
|
|
83
|
+
get fallback() {
|
|
84
|
+
return props.submitLabel ?? "Save";
|
|
85
|
+
},
|
|
86
|
+
get children() {
|
|
87
|
+
return _tmpl$2$3();
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
effect(() => _el$11.disabled = props.saving);
|
|
91
|
+
return _el$11;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
get children() {
|
|
96
|
+
return [
|
|
97
|
+
(() => {
|
|
98
|
+
var _el$4 = _tmpl$3$1();
|
|
99
|
+
_el$4.$$click = () => void props.draftActions?.onSaveDraft(editablePayload());
|
|
100
|
+
insert(_el$4, createComponent(Show, {
|
|
101
|
+
get when() {
|
|
102
|
+
return props.draftActions?.saving;
|
|
103
|
+
},
|
|
104
|
+
get fallback() {
|
|
105
|
+
return props.draftActions?.saveDraftLabel ?? "Save draft";
|
|
106
|
+
},
|
|
107
|
+
get children() {
|
|
108
|
+
return _tmpl$2$3();
|
|
109
|
+
}
|
|
110
|
+
}));
|
|
111
|
+
effect(() => _el$4.disabled = props.draftActions?.saving);
|
|
112
|
+
return _el$4;
|
|
113
|
+
})(),
|
|
114
|
+
(() => {
|
|
115
|
+
var _el$6 = _tmpl$4$1();
|
|
116
|
+
_el$6.$$click = () => void props.draftActions?.onPublish?.();
|
|
117
|
+
insert(_el$6, createComponent(Show, {
|
|
118
|
+
get when() {
|
|
119
|
+
return props.draftActions?.publishing;
|
|
120
|
+
},
|
|
121
|
+
get fallback() {
|
|
122
|
+
return props.draftActions?.publishLabel ?? "Publish";
|
|
123
|
+
},
|
|
124
|
+
get children() {
|
|
125
|
+
return _tmpl$2$3();
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
128
|
+
effect(() => _el$6.disabled = !props.draftActions?.canPublish || props.draftActions?.publishing);
|
|
129
|
+
return _el$6;
|
|
130
|
+
})(),
|
|
131
|
+
createComponent(Show, {
|
|
132
|
+
get when() {
|
|
133
|
+
return props.draftActions?.onPreview;
|
|
134
|
+
},
|
|
135
|
+
get children() {
|
|
136
|
+
var _el$8 = _tmpl$5$1();
|
|
137
|
+
_el$8.$$click = () => void props.draftActions?.onPreview?.();
|
|
138
|
+
insert(_el$8, createComponent(Show, {
|
|
139
|
+
get when() {
|
|
140
|
+
return props.draftActions?.previewing;
|
|
141
|
+
},
|
|
142
|
+
get fallback() {
|
|
143
|
+
return props.draftActions?.previewLabel ?? "Preview";
|
|
144
|
+
},
|
|
145
|
+
get children() {
|
|
146
|
+
return _tmpl$2$3();
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
149
|
+
effect(() => _el$8.disabled = !props.draftActions?.canPreview || props.draftActions?.previewing);
|
|
150
|
+
return _el$8;
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
}));
|
|
156
|
+
return _el$;
|
|
157
|
+
})();
|
|
158
|
+
}
|
|
159
|
+
function renderInput(key, field, value, setField, ctx) {
|
|
160
|
+
switch (field.type) {
|
|
161
|
+
case "text": return (() => {
|
|
162
|
+
var _el$13 = _tmpl$0$1();
|
|
163
|
+
_el$13.$$input = (e) => setField(key, e.currentTarget.value);
|
|
164
|
+
setAttribute(_el$13, "id", key);
|
|
165
|
+
_el$13.value = value ?? "";
|
|
166
|
+
effect(() => _el$13.required = field.required);
|
|
167
|
+
return _el$13;
|
|
168
|
+
})();
|
|
169
|
+
case "select": return (() => {
|
|
170
|
+
var _el$14 = _tmpl$1$1();
|
|
171
|
+
_el$14.addEventListener("change", (e) => setField(key, e.currentTarget.value));
|
|
172
|
+
setAttribute(_el$14, "id", key);
|
|
173
|
+
_el$14.value = value ?? "";
|
|
174
|
+
insert(_el$14, createComponent(For, {
|
|
175
|
+
get each() {
|
|
176
|
+
return field.options;
|
|
177
|
+
},
|
|
178
|
+
children: (option) => (() => {
|
|
179
|
+
var _el$15 = _tmpl$10$1();
|
|
180
|
+
_el$15.value = option;
|
|
181
|
+
insert(_el$15, option);
|
|
182
|
+
return _el$15;
|
|
183
|
+
})()
|
|
184
|
+
}));
|
|
185
|
+
effect(() => _el$14.required = field.required);
|
|
186
|
+
return _el$14;
|
|
187
|
+
})();
|
|
188
|
+
case "number": return (() => {
|
|
189
|
+
var _el$16 = _tmpl$11$1();
|
|
190
|
+
_el$16.$$input = (e) => setField(key, e.currentTarget.valueAsNumber);
|
|
191
|
+
setAttribute(_el$16, "id", key);
|
|
192
|
+
_el$16.value = value ?? "";
|
|
193
|
+
effect(() => _el$16.required = field.required);
|
|
194
|
+
return _el$16;
|
|
195
|
+
})();
|
|
196
|
+
case "date": return (() => {
|
|
197
|
+
var _el$17 = _tmpl$12$1();
|
|
198
|
+
setAttribute(_el$17, "id", key);
|
|
199
|
+
effect(() => _el$17.value = formatDateValue(value));
|
|
200
|
+
return _el$17;
|
|
201
|
+
})();
|
|
202
|
+
case "checkbox": return (() => {
|
|
203
|
+
var _el$18 = _tmpl$13$1();
|
|
204
|
+
_el$18.addEventListener("change", (e) => setField(key, e.currentTarget.checked));
|
|
205
|
+
setAttribute(_el$18, "id", key);
|
|
206
|
+
_el$18.checked = value ?? false;
|
|
207
|
+
return _el$18;
|
|
208
|
+
})();
|
|
209
|
+
case "upload": return renderUploadInput(key, field, value, setField, ctx);
|
|
210
|
+
case "relationship": return renderRelationshipInput(key, field, value, setField, ctx);
|
|
211
|
+
case "array": return renderArrayInput(key, field, value, setField, ctx);
|
|
212
|
+
case "richText": return createComponent(Suspense, {
|
|
213
|
+
get fallback() {
|
|
214
|
+
return _tmpl$2$3();
|
|
215
|
+
},
|
|
216
|
+
get children() {
|
|
217
|
+
return createComponent(RichTextEditor, {
|
|
218
|
+
id: key,
|
|
219
|
+
content: value,
|
|
220
|
+
onChange: (doc) => setField(key, doc)
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
default: return null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function renderUploadInput(key, field, value, setField, ctx) {
|
|
228
|
+
const [uploading, setUploading] = createSignal(false);
|
|
229
|
+
const [uploadError, setUploadError] = createSignal();
|
|
230
|
+
async function handleFileChange(e) {
|
|
231
|
+
const file = e.currentTarget.files?.[0];
|
|
232
|
+
if (!file) return;
|
|
233
|
+
if (!ctx.onUploadFile) {
|
|
234
|
+
setUploadError("No upload handler configured for this form.");
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
setUploading(true);
|
|
238
|
+
setUploadError(void 0);
|
|
239
|
+
try {
|
|
240
|
+
const { url } = await ctx.onUploadFile(file);
|
|
241
|
+
setField(key, url);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
setUploadError(err instanceof Error ? err.message : "Upload failed");
|
|
244
|
+
} finally {
|
|
245
|
+
setUploading(false);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return (() => {
|
|
249
|
+
var _el$20 = _tmpl$16(), _el$22 = _el$20.firstChild;
|
|
250
|
+
insert(_el$20, createComponent(Show, {
|
|
251
|
+
when: value,
|
|
252
|
+
get children() {
|
|
253
|
+
var _el$21 = _tmpl$14();
|
|
254
|
+
insert(_el$21, value);
|
|
255
|
+
return _el$21;
|
|
256
|
+
}
|
|
257
|
+
}), _el$22);
|
|
258
|
+
_el$22.addEventListener("change", handleFileChange);
|
|
259
|
+
setAttribute(_el$22, "id", key);
|
|
260
|
+
insert(_el$20, createComponent(Show, {
|
|
261
|
+
get when() {
|
|
262
|
+
return uploading();
|
|
263
|
+
},
|
|
264
|
+
get children() {
|
|
265
|
+
return _tmpl$2$3();
|
|
266
|
+
}
|
|
267
|
+
}), null);
|
|
268
|
+
insert(_el$20, createComponent(Show, {
|
|
269
|
+
get when() {
|
|
270
|
+
return uploadError();
|
|
271
|
+
},
|
|
272
|
+
get children() {
|
|
273
|
+
var _el$24 = _tmpl$15();
|
|
274
|
+
insert(_el$24, uploadError);
|
|
275
|
+
return _el$24;
|
|
276
|
+
}
|
|
277
|
+
}), null);
|
|
278
|
+
effect((_p$) => {
|
|
279
|
+
var _v$ = field.required && !value, _v$2 = uploading();
|
|
280
|
+
_v$ !== _p$.e && (_el$22.required = _p$.e = _v$);
|
|
281
|
+
_v$2 !== _p$.t && (_el$22.disabled = _p$.t = _v$2);
|
|
282
|
+
return _p$;
|
|
283
|
+
}, {
|
|
284
|
+
e: void 0,
|
|
285
|
+
t: void 0
|
|
286
|
+
});
|
|
287
|
+
return _el$20;
|
|
288
|
+
})();
|
|
289
|
+
}
|
|
290
|
+
function renderRelationshipInput(key, field, value, setField, ctx) {
|
|
291
|
+
if (field.hasMany) return null;
|
|
292
|
+
const options = ctx.relationshipOptions?.[field.relationTo] ?? [];
|
|
293
|
+
return (() => {
|
|
294
|
+
var _el$25 = _tmpl$17();
|
|
295
|
+
_el$25.firstChild;
|
|
296
|
+
_el$25.addEventListener("change", (e) => setField(key, e.currentTarget.value === "" ? null : Number(e.currentTarget.value)));
|
|
297
|
+
setAttribute(_el$25, "id", key);
|
|
298
|
+
insert(_el$25, createComponent(For, {
|
|
299
|
+
each: options,
|
|
300
|
+
children: (option) => (() => {
|
|
301
|
+
var _el$27 = _tmpl$10$1();
|
|
302
|
+
insert(_el$27, () => option.label);
|
|
303
|
+
effect(() => _el$27.value = option.id);
|
|
304
|
+
return _el$27;
|
|
305
|
+
})()
|
|
306
|
+
}), null);
|
|
307
|
+
effect(() => _el$25.required = field.required);
|
|
308
|
+
effect(() => _el$25.value = value != null ? String(value) : "");
|
|
309
|
+
return _el$25;
|
|
310
|
+
})();
|
|
311
|
+
}
|
|
312
|
+
function renderArrayInput(key, field, value, setField, ctx) {
|
|
313
|
+
const items = () => Array.isArray(value) ? value : [];
|
|
314
|
+
function updateItem(index, itemKey, itemValue) {
|
|
315
|
+
const next = items().slice();
|
|
316
|
+
next[index] = {
|
|
317
|
+
...next[index],
|
|
318
|
+
[itemKey]: itemValue
|
|
319
|
+
};
|
|
320
|
+
setField(key, next);
|
|
321
|
+
}
|
|
322
|
+
function addItem() {
|
|
323
|
+
setField(key, [...items(), {}]);
|
|
324
|
+
}
|
|
325
|
+
function removeItem(index) {
|
|
326
|
+
setField(key, items().filter((_, i) => i !== index));
|
|
327
|
+
}
|
|
328
|
+
function fieldsForItem(item) {
|
|
329
|
+
const base = Object.entries(field.fields);
|
|
330
|
+
const discriminator = field.discriminator;
|
|
331
|
+
if (!discriminator) return base;
|
|
332
|
+
const variantValue = item[discriminator.key];
|
|
333
|
+
const variantFields = typeof variantValue === "string" ? discriminator.variants[variantValue] : void 0;
|
|
334
|
+
return variantFields ? [...base, ...Object.entries(variantFields)] : base;
|
|
335
|
+
}
|
|
336
|
+
return (() => {
|
|
337
|
+
var _el$28 = _tmpl$18(), _el$29 = _el$28.firstChild;
|
|
338
|
+
_el$29.firstChild;
|
|
339
|
+
insert(_el$28, createComponent(For, {
|
|
340
|
+
get each() {
|
|
341
|
+
return items();
|
|
342
|
+
},
|
|
343
|
+
children: (item, index) => (() => {
|
|
344
|
+
var _el$31 = _tmpl$19(), _el$32 = _el$31.firstChild;
|
|
345
|
+
insert(_el$31, createComponent(For, {
|
|
346
|
+
get each() {
|
|
347
|
+
return fieldsForItem(item);
|
|
348
|
+
},
|
|
349
|
+
children: ([itemKey, itemField]) => {
|
|
350
|
+
const inputId = `${key}.${index()}.${itemKey}`;
|
|
351
|
+
return (() => {
|
|
352
|
+
var _el$33 = _tmpl$8$1(), _el$34 = _el$33.firstChild;
|
|
353
|
+
setAttribute(_el$34, "for", inputId);
|
|
354
|
+
insert(_el$34, itemKey, null);
|
|
355
|
+
insert(_el$34, createComponent(Show, {
|
|
356
|
+
get when() {
|
|
357
|
+
return itemField.required;
|
|
358
|
+
},
|
|
359
|
+
get children() {
|
|
360
|
+
return _tmpl$7$1();
|
|
361
|
+
}
|
|
362
|
+
}), null);
|
|
363
|
+
insert(_el$33, () => renderInput(inputId, itemField, item[itemKey], (_, v) => updateItem(index(), itemKey, v), ctx), null);
|
|
364
|
+
return _el$33;
|
|
365
|
+
})();
|
|
366
|
+
}
|
|
367
|
+
}), _el$32);
|
|
368
|
+
_el$32.$$click = () => removeItem(index());
|
|
369
|
+
return _el$31;
|
|
370
|
+
})()
|
|
371
|
+
}), _el$29);
|
|
372
|
+
_el$29.$$click = addItem;
|
|
373
|
+
insert(_el$29, key, null);
|
|
374
|
+
return _el$28;
|
|
375
|
+
})();
|
|
376
|
+
}
|
|
377
|
+
function formatDateValue(value) {
|
|
378
|
+
if (!value) return "—";
|
|
379
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
380
|
+
return Number.isNaN(date.getTime()) ? "—" : date.toLocaleString();
|
|
381
|
+
}
|
|
382
|
+
delegateEvents(["click", "input"]);
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/tanstack-start/create.tsx
|
|
385
|
+
var _tmpl$$3 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`);
|
|
386
|
+
/**
|
|
387
|
+
* Builds a create-page component for a collection. See
|
|
388
|
+
* `createCollectionListPage`'s doc comment for the same rationale on
|
|
389
|
+
* keeping navigation in the route file rather than this package.
|
|
390
|
+
*/
|
|
391
|
+
function createCollectionCreatePage(options) {
|
|
392
|
+
return function CollectionCreatePage() {
|
|
393
|
+
const queryClient = useQueryClient();
|
|
394
|
+
const [error, setError] = createSignal();
|
|
395
|
+
const create = createMutation(() => ({
|
|
396
|
+
mutationFn: options.createFn,
|
|
397
|
+
onSuccess: (created) => {
|
|
398
|
+
queryClient.invalidateQueries({ queryKey: options.invalidateQueryKey });
|
|
399
|
+
options.onCreated?.(created);
|
|
400
|
+
},
|
|
401
|
+
onError: (e) => setError(e.message)
|
|
402
|
+
}));
|
|
403
|
+
return (() => {
|
|
404
|
+
var _el$ = _tmpl$$3(), _el$2 = _el$.firstChild;
|
|
405
|
+
insert(_el$2, () => options.label ?? `New ${options.collection.slug}`);
|
|
406
|
+
insert(_el$, createComponent(CollectionEdit, {
|
|
407
|
+
get config() {
|
|
408
|
+
return options.collection;
|
|
409
|
+
},
|
|
410
|
+
get submitLabel() {
|
|
411
|
+
return options.submitLabel ?? "Create";
|
|
412
|
+
},
|
|
413
|
+
get error() {
|
|
414
|
+
return error();
|
|
415
|
+
},
|
|
416
|
+
onSubmit: (values) => create.mutate(values),
|
|
417
|
+
get onUploadFile() {
|
|
418
|
+
return options.onUploadFile;
|
|
419
|
+
}
|
|
420
|
+
}), null);
|
|
421
|
+
return _el$;
|
|
422
|
+
})();
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region src/tanstack-start/edit.tsx
|
|
427
|
+
var _tmpl$$2 = /*#__PURE__*/ template(`<button type=button class="btn btn-error btn-outline btn-sm self-start">`), _tmpl$2$2 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`);
|
|
428
|
+
/**
|
|
429
|
+
* Builds an edit-page component for a collection — fetch, update, and
|
|
430
|
+
* delete, all wired together, plus a router-level unsaved-changes guard
|
|
431
|
+
* (`useBlocker`) driven by `CollectionEdit`'s `onDirtyChange`. See
|
|
432
|
+
* `createCollectionListPage`'s doc comment for the rationale on keeping
|
|
433
|
+
* navigation in the route file.
|
|
434
|
+
*/
|
|
435
|
+
function createCollectionEditPage(options) {
|
|
436
|
+
return function CollectionEditPage() {
|
|
437
|
+
const queryClient = useQueryClient();
|
|
438
|
+
const [error, setError] = createSignal();
|
|
439
|
+
const [dirty, setDirty] = createSignal(false);
|
|
440
|
+
const [latestDraftId, setLatestDraftId] = createSignal();
|
|
441
|
+
useBlocker({
|
|
442
|
+
shouldBlockFn: () => dirty(),
|
|
443
|
+
enableBeforeUnload: () => dirty()
|
|
444
|
+
});
|
|
445
|
+
const row = createQuery(() => ({
|
|
446
|
+
queryKey: options.queryKey(),
|
|
447
|
+
queryFn: options.queryFn
|
|
448
|
+
}));
|
|
449
|
+
const update = createMutation(() => ({
|
|
450
|
+
mutationFn: options.updateFn,
|
|
451
|
+
onSuccess: () => {
|
|
452
|
+
setError(void 0);
|
|
453
|
+
queryClient.invalidateQueries({ queryKey: options.invalidateQueryKey });
|
|
454
|
+
},
|
|
455
|
+
onError: (e) => setError(e.message)
|
|
456
|
+
}));
|
|
457
|
+
const remove = createMutation(() => ({
|
|
458
|
+
mutationFn: options.deleteFn,
|
|
459
|
+
onSuccess: () => {
|
|
460
|
+
queryClient.invalidateQueries({ queryKey: options.invalidateQueryKey });
|
|
461
|
+
options.onDeleted?.();
|
|
462
|
+
},
|
|
463
|
+
onError: (e) => setError(e.message)
|
|
464
|
+
}));
|
|
465
|
+
const saveDraft = createMutation(() => ({
|
|
466
|
+
mutationFn: (values) => options.draftActions?.saveDraftFn(values) ?? Promise.reject(/* @__PURE__ */ new Error("No draftActions configured")),
|
|
467
|
+
onSuccess: (draft) => {
|
|
468
|
+
setError(void 0);
|
|
469
|
+
setLatestDraftId(draft.id);
|
|
470
|
+
},
|
|
471
|
+
onError: (e) => setError(e.message)
|
|
472
|
+
}));
|
|
473
|
+
const publish = createMutation(() => ({
|
|
474
|
+
mutationFn: () => {
|
|
475
|
+
const versionId = latestDraftId();
|
|
476
|
+
if (versionId === void 0 || !options.draftActions) return Promise.reject(/* @__PURE__ */ new Error("No draft saved yet"));
|
|
477
|
+
return options.draftActions.publishFn(versionId);
|
|
478
|
+
},
|
|
479
|
+
onSuccess: () => {
|
|
480
|
+
setError(void 0);
|
|
481
|
+
queryClient.invalidateQueries({ queryKey: options.invalidateQueryKey });
|
|
482
|
+
},
|
|
483
|
+
onError: (e) => setError(e.message)
|
|
484
|
+
}));
|
|
485
|
+
const preview = createMutation(() => ({
|
|
486
|
+
mutationFn: () => {
|
|
487
|
+
const versionId = latestDraftId();
|
|
488
|
+
if (versionId === void 0 || !options.draftActions?.previewFn) return Promise.reject(/* @__PURE__ */ new Error("No draft saved yet"));
|
|
489
|
+
return options.draftActions.previewFn(versionId);
|
|
490
|
+
},
|
|
491
|
+
onSuccess: ({ url }) => {
|
|
492
|
+
setError(void 0);
|
|
493
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
494
|
+
},
|
|
495
|
+
onError: (e) => setError(e.message)
|
|
496
|
+
}));
|
|
497
|
+
return (() => {
|
|
498
|
+
var _el$ = _tmpl$2$2(), _el$2 = _el$.firstChild;
|
|
499
|
+
insert(_el$2, () => options.label ?? `Edit ${options.collection.slug}`);
|
|
500
|
+
insert(_el$, createComponent(Show, {
|
|
501
|
+
get when() {
|
|
502
|
+
return row.data;
|
|
503
|
+
},
|
|
504
|
+
get children() {
|
|
505
|
+
return createComponent(CollectionEdit, {
|
|
506
|
+
get config() {
|
|
507
|
+
return options.collection;
|
|
508
|
+
},
|
|
509
|
+
get initialValues() {
|
|
510
|
+
return row.data ?? void 0;
|
|
511
|
+
},
|
|
512
|
+
get submitLabel() {
|
|
513
|
+
return options.submitLabel ?? "Save changes";
|
|
514
|
+
},
|
|
515
|
+
get error() {
|
|
516
|
+
return error();
|
|
517
|
+
},
|
|
518
|
+
get saving() {
|
|
519
|
+
return update.isPending;
|
|
520
|
+
},
|
|
521
|
+
onSubmit: (values) => update.mutate(values),
|
|
522
|
+
get onUploadFile() {
|
|
523
|
+
return options.onUploadFile;
|
|
524
|
+
},
|
|
525
|
+
onDirtyChange: setDirty,
|
|
526
|
+
get capabilities() {
|
|
527
|
+
return options.capabilities?.();
|
|
528
|
+
},
|
|
529
|
+
get draftActions() {
|
|
530
|
+
return memo(() => !!options.draftActions)() && {
|
|
531
|
+
onSaveDraft: (values) => saveDraft.mutate(values),
|
|
532
|
+
onPublish: () => publish.mutate(),
|
|
533
|
+
onPreview: options.draftActions.previewFn ? () => preview.mutate() : void 0,
|
|
534
|
+
saving: saveDraft.isPending,
|
|
535
|
+
publishing: publish.isPending,
|
|
536
|
+
previewing: preview.isPending,
|
|
537
|
+
canPublish: latestDraftId() !== void 0,
|
|
538
|
+
canPreview: latestDraftId() !== void 0,
|
|
539
|
+
saveDraftLabel: options.draftActions.saveDraftLabel,
|
|
540
|
+
publishLabel: options.draftActions.publishLabel,
|
|
541
|
+
previewLabel: options.draftActions.previewLabel
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}), null);
|
|
547
|
+
insert(_el$, createComponent(Show, {
|
|
548
|
+
get when() {
|
|
549
|
+
return options.capabilities?.()?.canDelete !== false;
|
|
550
|
+
},
|
|
551
|
+
get children() {
|
|
552
|
+
var _el$3 = _tmpl$$2();
|
|
553
|
+
_el$3.$$click = () => remove.mutate();
|
|
554
|
+
insert(_el$3, () => options.deleteLabel ?? `Delete ${options.collection.slug}`);
|
|
555
|
+
return _el$3;
|
|
556
|
+
}
|
|
557
|
+
}), null);
|
|
558
|
+
return _el$;
|
|
559
|
+
})();
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
delegateEvents(["click"]);
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region src/CollectionList.tsx
|
|
565
|
+
var _tmpl$$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline btn-sm">`), _tmpl$2$1 = /*#__PURE__*/ template(`<div class=join><select aria-label="Sort by"class="select select-sm join-item"></select><select aria-label="Sort direction"class="select select-sm join-item"><option value=asc>Ascending</option><option value=desc>Descending`), _tmpl$3 = /*#__PURE__*/ template(`<th>`), _tmpl$4 = /*#__PURE__*/ template(`<table class="table hidden md:table"><thead><tr></tr></thead><tbody>`), _tmpl$5 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2 md:hidden">`), _tmpl$6 = /*#__PURE__*/ template(`<div class="bg-base-100 sticky bottom-0 flex items-center justify-between gap-2 border-t py-2"><button type=button class="btn btn-sm">Prev</button><span class="text-sm opacity-70">Page </span><button type=button class="btn btn-sm">Next`), _tmpl$7 = /*#__PURE__*/ template(`<div class="flex flex-col gap-3"><div class="flex flex-wrap items-center justify-between gap-2">`), _tmpl$8 = /*#__PURE__*/ template(`<option>`), _tmpl$9 = /*#__PURE__*/ template(`<p class="text-sm opacity-70">No <!> yet.`), _tmpl$0 = /*#__PURE__*/ template(`<td><input type=checkbox class="checkbox checkbox-sm">`), _tmpl$1 = /*#__PURE__*/ template(`<tr>`), _tmpl$10 = /*#__PURE__*/ template(`<td>`), _tmpl$11 = /*#__PURE__*/ template(`<input type=checkbox class="checkbox checkbox-sm mt-1">`), _tmpl$12 = /*#__PURE__*/ template(`<div class="card bg-base-200 cursor-pointer p-3"role=button tabindex=0><div class="flex items-start gap-3"><div class="flex flex-1 flex-col gap-1">`), _tmpl$13 = /*#__PURE__*/ template(`<div class="flex justify-between gap-2 text-sm"><span class=opacity-60></span><span class=text-right>`);
|
|
566
|
+
function listableFields(config) {
|
|
567
|
+
const excluded = new Set([
|
|
568
|
+
"richText",
|
|
569
|
+
"array",
|
|
570
|
+
"relationship"
|
|
571
|
+
]);
|
|
572
|
+
return Object.entries(config.fields).filter(([key, field]) => key !== "id" && !excluded.has(field.type));
|
|
573
|
+
}
|
|
574
|
+
function formatCellValue(value) {
|
|
575
|
+
if (value === null || value === void 0) return "—";
|
|
576
|
+
if (value instanceof Date) return value.toLocaleDateString();
|
|
577
|
+
return String(value);
|
|
578
|
+
}
|
|
579
|
+
function rowId(row) {
|
|
580
|
+
return typeof row.id === "number" ? row.id : void 0;
|
|
581
|
+
}
|
|
582
|
+
function CollectionList(props) {
|
|
583
|
+
const columns = () => listableFields(props.config);
|
|
584
|
+
const [selectMode, setSelectMode] = createSignal(false);
|
|
585
|
+
function toggleSelected(id) {
|
|
586
|
+
const next = new Set(props.selectedIds ?? []);
|
|
587
|
+
if (next.has(id)) next.delete(id);
|
|
588
|
+
else next.add(id);
|
|
589
|
+
props.onSelectionChange?.(next);
|
|
590
|
+
}
|
|
591
|
+
function handleRowActivate(row) {
|
|
592
|
+
if (selectMode()) {
|
|
593
|
+
const id = rowId(row);
|
|
594
|
+
if (id !== void 0) toggleSelected(id);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
props.onRowClick?.(row);
|
|
598
|
+
}
|
|
599
|
+
return (() => {
|
|
600
|
+
var _el$ = _tmpl$7(), _el$2 = _el$.firstChild;
|
|
601
|
+
insert(_el$2, createComponent(Show, {
|
|
602
|
+
get when() {
|
|
603
|
+
return props.selectable;
|
|
604
|
+
},
|
|
605
|
+
get children() {
|
|
606
|
+
var _el$3 = _tmpl$$1();
|
|
607
|
+
_el$3.$$click = () => setSelectMode((v) => !v);
|
|
608
|
+
insert(_el$3, () => selectMode() ? "Done" : "Select");
|
|
609
|
+
return _el$3;
|
|
610
|
+
}
|
|
611
|
+
}), null);
|
|
612
|
+
insert(_el$2, createComponent(Show, {
|
|
613
|
+
get when() {
|
|
614
|
+
return props.onSortChange;
|
|
615
|
+
},
|
|
616
|
+
get children() {
|
|
617
|
+
var _el$4 = _tmpl$2$1(), _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling;
|
|
618
|
+
_el$5.addEventListener("change", (e) => props.onSortChange?.(e.currentTarget.value, props.sortDirection ?? "asc"));
|
|
619
|
+
insert(_el$5, createComponent(For, {
|
|
620
|
+
get each() {
|
|
621
|
+
return columns();
|
|
622
|
+
},
|
|
623
|
+
children: ([key]) => (() => {
|
|
624
|
+
var _el$16 = _tmpl$8();
|
|
625
|
+
_el$16.value = key;
|
|
626
|
+
insert(_el$16, key);
|
|
627
|
+
return _el$16;
|
|
628
|
+
})()
|
|
629
|
+
}));
|
|
630
|
+
_el$6.addEventListener("change", (e) => props.onSortChange?.(props.sortField ?? columns()[0]?.[0] ?? "", e.currentTarget.value));
|
|
631
|
+
effect(() => _el$5.value = props.sortField ?? "");
|
|
632
|
+
effect(() => _el$6.value = props.sortDirection ?? "asc");
|
|
633
|
+
return _el$4;
|
|
634
|
+
}
|
|
635
|
+
}), null);
|
|
636
|
+
insert(_el$, createComponent(Show, {
|
|
637
|
+
get when() {
|
|
638
|
+
return props.rows.length > 0;
|
|
639
|
+
},
|
|
640
|
+
get fallback() {
|
|
641
|
+
return (() => {
|
|
642
|
+
var _el$17 = _tmpl$9(), _el$20 = _el$17.firstChild.nextSibling;
|
|
643
|
+
_el$20.nextSibling;
|
|
644
|
+
insert(_el$17, () => props.config.slug, _el$20);
|
|
645
|
+
return _el$17;
|
|
646
|
+
})();
|
|
647
|
+
},
|
|
648
|
+
get children() {
|
|
649
|
+
return [(() => {
|
|
650
|
+
var _el$7 = _tmpl$4(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$1 = _el$8.nextSibling;
|
|
651
|
+
insert(_el$9, createComponent(Show, {
|
|
652
|
+
get when() {
|
|
653
|
+
return selectMode();
|
|
654
|
+
},
|
|
655
|
+
get children() {
|
|
656
|
+
return _tmpl$3();
|
|
657
|
+
}
|
|
658
|
+
}), null);
|
|
659
|
+
insert(_el$9, createComponent(For, {
|
|
660
|
+
get each() {
|
|
661
|
+
return columns();
|
|
662
|
+
},
|
|
663
|
+
children: ([key]) => (() => {
|
|
664
|
+
var _el$21 = _tmpl$3();
|
|
665
|
+
insert(_el$21, key);
|
|
666
|
+
return _el$21;
|
|
667
|
+
})()
|
|
668
|
+
}), null);
|
|
669
|
+
insert(_el$1, createComponent(For, {
|
|
670
|
+
get each() {
|
|
671
|
+
return props.rows;
|
|
672
|
+
},
|
|
673
|
+
children: (row) => (() => {
|
|
674
|
+
var _el$22 = _tmpl$1();
|
|
675
|
+
_el$22.$$click = () => handleRowActivate(row);
|
|
676
|
+
insert(_el$22, createComponent(Show, {
|
|
677
|
+
get when() {
|
|
678
|
+
return selectMode();
|
|
679
|
+
},
|
|
680
|
+
get children() {
|
|
681
|
+
var _el$23 = _tmpl$0(), _el$24 = _el$23.firstChild;
|
|
682
|
+
_el$24.addEventListener("change", () => {
|
|
683
|
+
const id = rowId(row);
|
|
684
|
+
if (id !== void 0) toggleSelected(id);
|
|
685
|
+
});
|
|
686
|
+
_el$24.$$click = (e) => e.stopPropagation();
|
|
687
|
+
effect(() => _el$24.checked = rowId(row) !== void 0 && (props.selectedIds?.has(rowId(row)) ?? false));
|
|
688
|
+
return _el$23;
|
|
689
|
+
}
|
|
690
|
+
}), null);
|
|
691
|
+
insert(_el$22, createComponent(For, {
|
|
692
|
+
get each() {
|
|
693
|
+
return columns();
|
|
694
|
+
},
|
|
695
|
+
children: ([key]) => (() => {
|
|
696
|
+
var _el$25 = _tmpl$10();
|
|
697
|
+
insert(_el$25, () => formatCellValue(row[key]));
|
|
698
|
+
return _el$25;
|
|
699
|
+
})()
|
|
700
|
+
}), null);
|
|
701
|
+
effect(() => className(_el$22, props.onRowClick || selectMode() ? "cursor-pointer hover" : void 0));
|
|
702
|
+
return _el$22;
|
|
703
|
+
})()
|
|
704
|
+
}));
|
|
705
|
+
return _el$7;
|
|
706
|
+
})(), (() => {
|
|
707
|
+
var _el$10 = _tmpl$5();
|
|
708
|
+
insert(_el$10, createComponent(For, {
|
|
709
|
+
get each() {
|
|
710
|
+
return props.rows;
|
|
711
|
+
},
|
|
712
|
+
children: (row) => (() => {
|
|
713
|
+
var _el$26 = _tmpl$12(), _el$27 = _el$26.firstChild, _el$29 = _el$27.firstChild;
|
|
714
|
+
_el$26.$$keydown = (e) => {
|
|
715
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
716
|
+
e.preventDefault();
|
|
717
|
+
handleRowActivate(row);
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
_el$26.$$click = () => handleRowActivate(row);
|
|
721
|
+
insert(_el$27, createComponent(Show, {
|
|
722
|
+
get when() {
|
|
723
|
+
return selectMode();
|
|
724
|
+
},
|
|
725
|
+
get children() {
|
|
726
|
+
var _el$28 = _tmpl$11();
|
|
727
|
+
_el$28.addEventListener("change", () => {
|
|
728
|
+
const id = rowId(row);
|
|
729
|
+
if (id !== void 0) toggleSelected(id);
|
|
730
|
+
});
|
|
731
|
+
_el$28.$$click = (e) => e.stopPropagation();
|
|
732
|
+
effect(() => _el$28.checked = rowId(row) !== void 0 && (props.selectedIds?.has(rowId(row)) ?? false));
|
|
733
|
+
return _el$28;
|
|
734
|
+
}
|
|
735
|
+
}), _el$29);
|
|
736
|
+
insert(_el$29, createComponent(For, {
|
|
737
|
+
get each() {
|
|
738
|
+
return columns();
|
|
739
|
+
},
|
|
740
|
+
children: ([key]) => (() => {
|
|
741
|
+
var _el$30 = _tmpl$13(), _el$31 = _el$30.firstChild, _el$32 = _el$31.nextSibling;
|
|
742
|
+
insert(_el$31, key);
|
|
743
|
+
insert(_el$32, () => formatCellValue(row[key]));
|
|
744
|
+
return _el$30;
|
|
745
|
+
})()
|
|
746
|
+
}));
|
|
747
|
+
return _el$26;
|
|
748
|
+
})()
|
|
749
|
+
}));
|
|
750
|
+
return _el$10;
|
|
751
|
+
})()];
|
|
752
|
+
}
|
|
753
|
+
}), null);
|
|
754
|
+
insert(_el$, createComponent(Show, {
|
|
755
|
+
get when() {
|
|
756
|
+
return memo(() => props.page !== void 0)() && props.pageSize !== void 0;
|
|
757
|
+
},
|
|
758
|
+
get children() {
|
|
759
|
+
var _el$11 = _tmpl$6(), _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling;
|
|
760
|
+
_el$13.firstChild;
|
|
761
|
+
var _el$15 = _el$13.nextSibling;
|
|
762
|
+
_el$12.$$click = () => props.onPageChange?.((props.page ?? 1) - 1);
|
|
763
|
+
insert(_el$13, () => props.page, null);
|
|
764
|
+
_el$15.$$click = () => props.onPageChange?.((props.page ?? 1) + 1);
|
|
765
|
+
effect((_p$) => {
|
|
766
|
+
var _v$ = (props.page ?? 1) <= 1, _v$2 = props.totalCount !== void 0 ? (props.page ?? 1) * (props.pageSize ?? 0) >= props.totalCount : props.rows.length < (props.pageSize ?? 0);
|
|
767
|
+
_v$ !== _p$.e && (_el$12.disabled = _p$.e = _v$);
|
|
768
|
+
_v$2 !== _p$.t && (_el$15.disabled = _p$.t = _v$2);
|
|
769
|
+
return _p$;
|
|
770
|
+
}, {
|
|
771
|
+
e: void 0,
|
|
772
|
+
t: void 0
|
|
773
|
+
});
|
|
774
|
+
return _el$11;
|
|
775
|
+
}
|
|
776
|
+
}), null);
|
|
777
|
+
return _el$;
|
|
778
|
+
})();
|
|
779
|
+
}
|
|
780
|
+
delegateEvents(["click", "keydown"]);
|
|
781
|
+
//#endregion
|
|
782
|
+
//#region src/tanstack-start/list.tsx
|
|
783
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><div class="flex items-center justify-between"><h1 class="text-xl font-semibold">`), _tmpl$2 = /*#__PURE__*/ template(`<div class="loading loading-spinner">`);
|
|
784
|
+
/**
|
|
785
|
+
* Builds a list-view page component for a collection — paginated/sortable
|
|
786
|
+
* query, loading state, and the generic table/card list, wired together.
|
|
787
|
+
* The returned component is meant to be passed directly as a route's
|
|
788
|
+
* `component`:
|
|
789
|
+
*
|
|
790
|
+
* ```tsx
|
|
791
|
+
* export const Route = createFileRoute('/admin/pages/')({
|
|
792
|
+
* component: createCollectionListPage({
|
|
793
|
+
* collection: pagesCollection,
|
|
794
|
+
* label: 'Pages',
|
|
795
|
+
* queryKey: ['pages'],
|
|
796
|
+
* queryFn: (params) => getPages({ data: params }),
|
|
797
|
+
* newHref: '/admin/pages/new',
|
|
798
|
+
* newLabel: 'New page',
|
|
799
|
+
* onRowClick: (row) => navigate({ to: '/admin/pages/$pageId', params: { pageId: String(row.id) } }),
|
|
800
|
+
* }),
|
|
801
|
+
* })
|
|
802
|
+
* ```
|
|
803
|
+
*
|
|
804
|
+
* Navigation stays in the route file (via `onRowClick`/`newHref` as plain
|
|
805
|
+
* strings) rather than this package calling `useNavigate()` itself —
|
|
806
|
+
* TanStack Router's route-typing is generated per-app, so a generic
|
|
807
|
+
* package can't produce a correctly-typed `navigate()` call for routes
|
|
808
|
+
* it doesn't know about.
|
|
809
|
+
*/
|
|
810
|
+
function createCollectionListPage(options) {
|
|
811
|
+
return function CollectionListPage() {
|
|
812
|
+
const pageSize = options.pageSize ?? 20;
|
|
813
|
+
const [page, setPage] = createSignal(1);
|
|
814
|
+
const [sortField, setSortField] = createSignal(void 0);
|
|
815
|
+
const [sortDirection, setSortDirection] = createSignal("asc");
|
|
816
|
+
const result = createQuery(() => ({
|
|
817
|
+
queryKey: [
|
|
818
|
+
...options.queryKey,
|
|
819
|
+
page(),
|
|
820
|
+
sortField(),
|
|
821
|
+
sortDirection()
|
|
822
|
+
],
|
|
823
|
+
queryFn: () => options.queryFn({
|
|
824
|
+
page: page(),
|
|
825
|
+
pageSize,
|
|
826
|
+
sortField: sortField(),
|
|
827
|
+
sortDirection: sortDirection()
|
|
828
|
+
})
|
|
829
|
+
}));
|
|
830
|
+
function handleSortChange(field, direction) {
|
|
831
|
+
setSortField(field);
|
|
832
|
+
setSortDirection(direction);
|
|
833
|
+
setPage(1);
|
|
834
|
+
}
|
|
835
|
+
return (() => {
|
|
836
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild;
|
|
837
|
+
insert(_el$3, () => options.label ?? options.collection.slug);
|
|
838
|
+
insert(_el$2, createComponent(Show, {
|
|
839
|
+
get when() {
|
|
840
|
+
return memo(() => !!options.newHref)() && options.capabilities?.()?.canCreate !== false;
|
|
841
|
+
},
|
|
842
|
+
get children() {
|
|
843
|
+
return createComponent(Link, {
|
|
844
|
+
get to() {
|
|
845
|
+
return options.newHref;
|
|
846
|
+
},
|
|
847
|
+
"class": "btn btn-primary btn-sm",
|
|
848
|
+
get children() {
|
|
849
|
+
return options.newLabel ?? `New ${options.collection.slug}`;
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
}), null);
|
|
854
|
+
insert(_el$, createComponent(Show, {
|
|
855
|
+
get when() {
|
|
856
|
+
return !result.isLoading;
|
|
857
|
+
},
|
|
858
|
+
get fallback() {
|
|
859
|
+
return _tmpl$2();
|
|
860
|
+
},
|
|
861
|
+
get children() {
|
|
862
|
+
return createComponent(CollectionList, {
|
|
863
|
+
get config() {
|
|
864
|
+
return options.collection;
|
|
865
|
+
},
|
|
866
|
+
get rows() {
|
|
867
|
+
return result.data?.rows ?? [];
|
|
868
|
+
},
|
|
869
|
+
get onRowClick() {
|
|
870
|
+
return options.onRowClick;
|
|
871
|
+
},
|
|
872
|
+
get page() {
|
|
873
|
+
return page();
|
|
874
|
+
},
|
|
875
|
+
pageSize,
|
|
876
|
+
get totalCount() {
|
|
877
|
+
return result.data?.total;
|
|
878
|
+
},
|
|
879
|
+
onPageChange: setPage,
|
|
880
|
+
get sortField() {
|
|
881
|
+
return sortField();
|
|
882
|
+
},
|
|
883
|
+
get sortDirection() {
|
|
884
|
+
return sortDirection();
|
|
885
|
+
},
|
|
886
|
+
onSortChange: handleSortChange
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
}), null);
|
|
890
|
+
return _el$;
|
|
891
|
+
})();
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
//#endregion
|
|
895
|
+
export { createCollectionCreatePage, createCollectionEditPage, createCollectionListPage };
|
|
896
|
+
|
|
897
|
+
//# sourceMappingURL=index.js.map
|