@duke333/builder-ui 0.2.3 → 0.2.4
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/{BuilderAdminPages-DrOrFyIX.d.ts → BuilderAdminPages-DwwdA8Dv.d.ts} +12 -0
- package/dist/{RuntimeEntryDialog-Bw741XbS.d.ts → RuntimeEntryDialog-B4TbF8os.d.ts} +1 -1
- package/dist/admin/index.d.ts +2 -2
- package/dist/admin/index.js +45 -4
- package/dist/admin/index.js.map +1 -1
- package/dist/api/index.d.ts +14 -0
- package/dist/api/index.js +19 -2
- package/dist/api/index.js.map +1 -1
- package/dist/components/index.d.ts +4 -3
- package/dist/components/index.js +31 -12
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.js +30 -3
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +142 -22
- package/dist/index.js +998 -532
- package/dist/index.js.map +1 -1
- package/dist/integration/index.d.ts +1 -1
- package/dist/integration/index.js +94 -9
- package/dist/integration/index.js.map +1 -1
- package/dist/runtime/index.d.ts +16 -26
- package/dist/runtime/index.js +41 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtimeUtils-CCtLyIf1.d.ts +33 -0
- package/dist/styles.css +155 -0
- package/dist/styles.css.map +1 -1
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -29,7 +29,8 @@ function createBuilderApiClient(rootTransport, options = {}) {
|
|
|
29
29
|
get: (value, requestOptions) => rootTransport.get(path(value), requestOptions),
|
|
30
30
|
post: (value, body, requestOptions) => rootTransport.post(path(value), body, requestOptions),
|
|
31
31
|
patch: (value, body, requestOptions) => rootTransport.patch(path(value), body, requestOptions),
|
|
32
|
-
delete: (value, requestOptions) => rootTransport.delete(path(value), requestOptions)
|
|
32
|
+
delete: (value, requestOptions) => rootTransport.delete(path(value), requestOptions),
|
|
33
|
+
upload: rootTransport.upload ? (value, body, requestOptions) => rootTransport.upload(path(value), body, requestOptions) : void 0
|
|
33
34
|
};
|
|
34
35
|
return {
|
|
35
36
|
listBuilderForms: (query) => transport.get("/builder/forms", {
|
|
@@ -104,7 +105,23 @@ function createBuilderApiClient(rootTransport, options = {}) {
|
|
|
104
105
|
),
|
|
105
106
|
deleteBuilderViewEntry: (viewId, id) => transport.delete(
|
|
106
107
|
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries/${encodeURIComponent(id)}`
|
|
107
|
-
)
|
|
108
|
+
),
|
|
109
|
+
presignRuntimeBuilderFile: (context, fieldKey, input) => {
|
|
110
|
+
const owner = context.viewId ? `views/${encodeURIComponent(context.viewId)}` : `forms/${encodeURIComponent(context.formId ?? "")}`;
|
|
111
|
+
return transport.post(
|
|
112
|
+
`/builder/runtime/${owner}/fields/${encodeURIComponent(fieldKey)}/files/presign`,
|
|
113
|
+
input
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
uploadRuntimeBuilderFile: (context, fieldKey, file) => {
|
|
117
|
+
if (!transport.upload) throw new Error("Builder transport server file upload \u0434\u044D\u043C\u0436\u0438\u0445\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
118
|
+
const owner = context.viewId ? `views/${encodeURIComponent(context.viewId)}` : `forms/${encodeURIComponent(context.formId ?? "")}`;
|
|
119
|
+
return transport.upload(
|
|
120
|
+
`/builder/runtime/${owner}/fields/${encodeURIComponent(fieldKey)}/files/upload`,
|
|
121
|
+
file,
|
|
122
|
+
{ contentType: file.type }
|
|
123
|
+
);
|
|
124
|
+
}
|
|
108
125
|
};
|
|
109
126
|
}
|
|
110
127
|
|
|
@@ -136,12 +153,30 @@ function createBuilderKeys() {
|
|
|
136
153
|
}
|
|
137
154
|
function createBuilderHooks(client) {
|
|
138
155
|
const builderKeys = createBuilderKeys();
|
|
156
|
+
function isRuntimeEntryListCache(value) {
|
|
157
|
+
return typeof value === "object" && value !== null && "items" in value && Array.isArray(value.items) && "total" in value;
|
|
158
|
+
}
|
|
159
|
+
function replaceCachedRuntimeViewEntry(queryClient, viewId, entry) {
|
|
160
|
+
queryClient.setQueriesData(
|
|
161
|
+
{ queryKey: [...builderKeys.runtimeView(viewId), "entries"] },
|
|
162
|
+
(current) => {
|
|
163
|
+
if (!isRuntimeEntryListCache(current)) return current;
|
|
164
|
+
return {
|
|
165
|
+
...current,
|
|
166
|
+
items: current.items.map((item) => item.id === entry.id ? entry : item)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
}
|
|
139
171
|
function invalidateRuntimeViewEntries(queryClient, viewId) {
|
|
140
172
|
return Promise.all([
|
|
141
173
|
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeView(viewId) }),
|
|
142
174
|
queryClient.invalidateQueries({ queryKey: [...builderKeys.runtimeView(viewId), "entries"] })
|
|
143
175
|
]);
|
|
144
176
|
}
|
|
177
|
+
function invalidateAllRuntimeViewEntries(queryClient) {
|
|
178
|
+
return queryClient.invalidateQueries({ queryKey: ["builder", "runtime", "view"] });
|
|
179
|
+
}
|
|
145
180
|
function useBuilderDbTables() {
|
|
146
181
|
return useQuery({ queryKey: builderKeys.dbTables(), queryFn: client.listBuilderDbTables });
|
|
147
182
|
}
|
|
@@ -352,14 +387,20 @@ function createBuilderHooks(client) {
|
|
|
352
387
|
viewId,
|
|
353
388
|
input
|
|
354
389
|
),
|
|
355
|
-
onSuccess: () =>
|
|
390
|
+
onSuccess: (entry) => {
|
|
391
|
+
replaceCachedRuntimeViewEntry(queryClient, viewId, entry);
|
|
392
|
+
return invalidateRuntimeViewEntries(queryClient, viewId);
|
|
393
|
+
}
|
|
356
394
|
});
|
|
357
395
|
}
|
|
358
396
|
function useCreateCompositeBuilderViewEntry(viewId) {
|
|
359
397
|
const queryClient = useQueryClient();
|
|
360
398
|
return useMutation({
|
|
361
399
|
mutationFn: (input) => client.createCompositeBuilderViewEntry(viewId, input),
|
|
362
|
-
onSuccess: () =>
|
|
400
|
+
onSuccess: (entry) => {
|
|
401
|
+
replaceCachedRuntimeViewEntry(queryClient, viewId, entry);
|
|
402
|
+
return invalidateAllRuntimeViewEntries(queryClient);
|
|
403
|
+
}
|
|
363
404
|
});
|
|
364
405
|
}
|
|
365
406
|
function useUpdateCompositeBuilderViewEntry(viewId) {
|
|
@@ -369,7 +410,10 @@ function createBuilderHooks(client) {
|
|
|
369
410
|
id,
|
|
370
411
|
input
|
|
371
412
|
}) => client.updateCompositeBuilderViewEntry(viewId, id, input),
|
|
372
|
-
onSuccess: () =>
|
|
413
|
+
onSuccess: (entry) => {
|
|
414
|
+
replaceCachedRuntimeViewEntry(queryClient, viewId, entry);
|
|
415
|
+
return invalidateAllRuntimeViewEntries(queryClient);
|
|
416
|
+
}
|
|
373
417
|
});
|
|
374
418
|
}
|
|
375
419
|
function useDeleteBuilderViewEntry(id) {
|
|
@@ -470,11 +514,49 @@ function builderErrorMessage(error, fallback) {
|
|
|
470
514
|
}
|
|
471
515
|
|
|
472
516
|
// src/ready/BuilderRuntimeComponents.tsx
|
|
473
|
-
import { useMemo as useMemo4, useState as
|
|
517
|
+
import { useMemo as useMemo4, useRef as useRef7, useState as useState6 } from "react";
|
|
474
518
|
import { FormProvider as FormProvider2, useForm as useForm2 } from "react-hook-form";
|
|
475
519
|
|
|
520
|
+
// src/richText.ts
|
|
521
|
+
var emptyDocument = { type: "doc", content: [{ type: "paragraph" }] };
|
|
522
|
+
function isRichTextDocument(value) {
|
|
523
|
+
return typeof value === "object" && value !== null && "type" in value && value.type === "doc";
|
|
524
|
+
}
|
|
525
|
+
function plainTextDocument(value) {
|
|
526
|
+
const lines = value.split(/\r?\n/);
|
|
527
|
+
return {
|
|
528
|
+
type: "doc",
|
|
529
|
+
content: lines.map(
|
|
530
|
+
(line) => line ? { type: "paragraph", content: [{ type: "text", text: line }] } : { type: "paragraph" }
|
|
531
|
+
)
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function toRichTextDocument(value) {
|
|
535
|
+
if (isRichTextDocument(value)) return value;
|
|
536
|
+
if (typeof value !== "string" || !value.trim()) return emptyDocument;
|
|
537
|
+
try {
|
|
538
|
+
const parsed = JSON.parse(value);
|
|
539
|
+
if (isRichTextDocument(parsed)) return parsed;
|
|
540
|
+
} catch {
|
|
541
|
+
}
|
|
542
|
+
return plainTextDocument(value);
|
|
543
|
+
}
|
|
544
|
+
function collectPlainText(node, output) {
|
|
545
|
+
if (node.type === "text" && typeof node.text === "string") output.push(node.text);
|
|
546
|
+
if (node.type === "hardBreak") output.push("\n");
|
|
547
|
+
for (const child of node.content ?? []) collectPlainText(child, output);
|
|
548
|
+
if (["paragraph", "heading", "listItem", "blockquote"].includes(node.type)) output.push("\n");
|
|
549
|
+
}
|
|
550
|
+
function richTextToPlainText(value) {
|
|
551
|
+
const output = [];
|
|
552
|
+
for (const node of toRichTextDocument(value).content ?? []) collectPlainText(node, output);
|
|
553
|
+
return output.join("").replace(/\n{3,}/g, "\n\n").trim();
|
|
554
|
+
}
|
|
555
|
+
|
|
476
556
|
// src/runtime/runtimeUtils.ts
|
|
477
557
|
function emptyFieldValue(field) {
|
|
558
|
+
if (field.defaultValue !== void 0) return field.defaultValue;
|
|
559
|
+
if (field.type === "file" && field.multiple) return [];
|
|
478
560
|
return field.type === "checkbox" ? false : "";
|
|
479
561
|
}
|
|
480
562
|
function createBuilderFormDefaultValues(schema) {
|
|
@@ -500,19 +582,277 @@ function formatBuilderRuntimeValue(value, locale = "mn-MN") {
|
|
|
500
582
|
}
|
|
501
583
|
|
|
502
584
|
// src/ready/ReadyFields.tsx
|
|
503
|
-
import { useRef as
|
|
504
|
-
import { useFormContext, useWatch } from "react-hook-form";
|
|
585
|
+
import { useRef as useRef4 } from "react";
|
|
586
|
+
import { useFormContext as useFormContext3, useWatch as useWatch3 } from "react-hook-form";
|
|
587
|
+
|
|
588
|
+
// src/ready/ReadyFileField.tsx
|
|
589
|
+
import { useId, useRef as useRef2, useState as useState2 } from "react";
|
|
590
|
+
import {
|
|
591
|
+
useFormContext,
|
|
592
|
+
useWatch
|
|
593
|
+
} from "react-hook-form";
|
|
505
594
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
595
|
+
function acceptedTypes(field) {
|
|
596
|
+
return field.contentKind === "image" ? "image/jpeg,image/png,image/webp,image/gif" : "application/pdf";
|
|
597
|
+
}
|
|
598
|
+
function urlsFrom(value) {
|
|
599
|
+
if (typeof value === "string" && value) return [value];
|
|
600
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
601
|
+
}
|
|
602
|
+
function ReadyFileField({ field, formId, viewId, name }) {
|
|
603
|
+
const { client, notify } = useBuilderRuntime();
|
|
604
|
+
const form = useFormContext();
|
|
605
|
+
const inputId = useId();
|
|
606
|
+
const inputRef = useRef2(null);
|
|
607
|
+
const [uploading, setUploading] = useState2(false);
|
|
608
|
+
const value = useWatch({ control: form.control, name });
|
|
609
|
+
const urls = urlsFrom(value);
|
|
610
|
+
const error = form.getFieldState(name, form.formState).error;
|
|
611
|
+
const setUrls = (next) => form.setValue(
|
|
612
|
+
name,
|
|
613
|
+
field.multiple ? next : next[0] ?? "",
|
|
614
|
+
{ shouldDirty: true, shouldValidate: true }
|
|
615
|
+
);
|
|
616
|
+
async function upload(files) {
|
|
617
|
+
if (!files?.length || !field.storage || !field.contentKind || !formId && !viewId) return;
|
|
618
|
+
const selected = Array.from(files);
|
|
619
|
+
if (!field.multiple) selected.splice(1);
|
|
620
|
+
setUploading(true);
|
|
621
|
+
try {
|
|
622
|
+
const uploaded = [];
|
|
623
|
+
for (const file of selected) {
|
|
624
|
+
if (field.maxBytes && file.size > field.maxBytes) throw new Error("\u0424\u0430\u0439\u043B \u0437\u04E9\u0432\u0448\u04E9\u04E9\u0440\u04E9\u0433\u0434\u0441\u04E9\u043D \u0445\u044D\u043C\u0436\u044D\u044D\u043D\u044D\u044D\u0441 \u0442\u043E\u043C \u0431\u0430\u0439\u043D\u0430");
|
|
625
|
+
const context = viewId ? { viewId } : { formId };
|
|
626
|
+
if (field.storage === "s3") {
|
|
627
|
+
const presign = await client.presignRuntimeBuilderFile(context, field.key, { contentType: file.type, contentLength: file.size });
|
|
628
|
+
const response = await fetch(presign.uploadUrl, { method: "PUT", body: file, headers: { "Content-Type": file.type }, credentials: "omit" });
|
|
629
|
+
if (!response.ok) throw new Error("S3 upload \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439 \u0431\u043E\u043B\u043B\u043E\u043E");
|
|
630
|
+
uploaded.push(presign.url);
|
|
631
|
+
} else {
|
|
632
|
+
uploaded.push((await client.uploadRuntimeBuilderFile(context, field.key, file)).url);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
setUrls(field.multiple ? [...urls, ...uploaded] : uploaded);
|
|
636
|
+
} catch (cause) {
|
|
637
|
+
notify({ type: "error", message: builderErrorMessage(cause, "\u0424\u0430\u0439\u043B upload \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439 \u0431\u043E\u043B\u043B\u043E\u043E") });
|
|
638
|
+
} finally {
|
|
639
|
+
setUploading(false);
|
|
640
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const chooseLabel = field.contentKind === "image" ? field.multiple ? "\u0417\u0443\u0440\u0430\u0433 \u043D\u044D\u043C\u044D\u0445" : "\u0417\u0443\u0440\u0430\u0433 \u0441\u043E\u043D\u0433\u043E\u0445" : "\u0424\u0430\u0439\u043B \u0441\u043E\u043D\u0433\u043E\u0445";
|
|
644
|
+
return /* @__PURE__ */ jsxs2("div", { className: "builder-field", children: [
|
|
645
|
+
/* @__PURE__ */ jsxs2("label", { className: "builder-field__label", htmlFor: inputId, children: [
|
|
646
|
+
field.label,
|
|
647
|
+
field.required ? /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: " *" }) : null
|
|
648
|
+
] }),
|
|
649
|
+
/* @__PURE__ */ jsx2(
|
|
650
|
+
"input",
|
|
651
|
+
{
|
|
652
|
+
className: "builder-file-input",
|
|
653
|
+
ref: inputRef,
|
|
654
|
+
id: inputId,
|
|
655
|
+
type: "file",
|
|
656
|
+
accept: acceptedTypes(field),
|
|
657
|
+
multiple: field.multiple,
|
|
658
|
+
disabled: field.disabled || uploading || !formId && !viewId,
|
|
659
|
+
onChange: (event) => void upload(event.target.files)
|
|
660
|
+
}
|
|
661
|
+
),
|
|
662
|
+
/* @__PURE__ */ jsx2(
|
|
663
|
+
"button",
|
|
664
|
+
{
|
|
665
|
+
className: "builder-button builder-button--secondary builder-file-choose",
|
|
666
|
+
disabled: field.disabled || uploading || !formId && !viewId,
|
|
667
|
+
onClick: () => inputRef.current?.click(),
|
|
668
|
+
type: "button",
|
|
669
|
+
children: uploading ? "Upload \u0445\u0438\u0439\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" : chooseLabel
|
|
670
|
+
}
|
|
671
|
+
),
|
|
672
|
+
urls.length > 0 ? /* @__PURE__ */ jsx2("div", { className: "builder-file-list", "data-kind": field.contentKind, children: urls.map((url, index) => /* @__PURE__ */ jsxs2("div", { className: "builder-file-item", children: [
|
|
673
|
+
field.contentKind === "image" ? /* @__PURE__ */ jsx2(
|
|
674
|
+
"a",
|
|
675
|
+
{
|
|
676
|
+
"aria-label": `${field.label} ${index + 1}-\u0433 \u043D\u044D\u044D\u0445`,
|
|
677
|
+
className: "builder-file-preview",
|
|
678
|
+
href: url,
|
|
679
|
+
rel: "noreferrer",
|
|
680
|
+
target: "_blank",
|
|
681
|
+
children: /* @__PURE__ */ jsx2("img", { alt: "", src: url })
|
|
682
|
+
}
|
|
683
|
+
) : /* @__PURE__ */ jsxs2("a", { className: "builder-file-document", href: url, rel: "noreferrer", target: "_blank", children: [
|
|
684
|
+
"\u0424\u0430\u0439\u043B ",
|
|
685
|
+
index + 1
|
|
686
|
+
] }),
|
|
687
|
+
/* @__PURE__ */ jsx2(
|
|
688
|
+
"button",
|
|
689
|
+
{
|
|
690
|
+
"aria-label": `${field.label} ${index + 1}-\u0433 \u0445\u0430\u0441\u0430\u0445`,
|
|
691
|
+
className: "builder-file-remove",
|
|
692
|
+
disabled: field.disabled || uploading,
|
|
693
|
+
onClick: () => setUrls(urls.filter((item) => item !== url)),
|
|
694
|
+
type: "button",
|
|
695
|
+
children: "\xD7"
|
|
696
|
+
}
|
|
697
|
+
)
|
|
698
|
+
] }, url)) }) : null,
|
|
699
|
+
uploading ? /* @__PURE__ */ jsx2("small", { children: "Upload \u0445\u0438\u0439\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" }) : null,
|
|
700
|
+
typeof error?.message === "string" ? /* @__PURE__ */ jsx2("small", { className: "builder-field__error", children: error.message }) : null
|
|
701
|
+
] });
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// src/ready/ReadyRichTextField.tsx
|
|
705
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
706
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
707
|
+
import { useEffect, useRef as useRef3 } from "react";
|
|
708
|
+
import { useFormContext as useFormContext2, useWatch as useWatch2 } from "react-hook-form";
|
|
709
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
710
|
+
function ToolbarButton({ active = false, children, disabled = false, onClick, title }) {
|
|
711
|
+
return /* @__PURE__ */ jsx3(
|
|
712
|
+
"button",
|
|
713
|
+
{
|
|
714
|
+
"aria-pressed": active,
|
|
715
|
+
className: "builder-richtext__button",
|
|
716
|
+
disabled,
|
|
717
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
718
|
+
onClick,
|
|
719
|
+
title,
|
|
720
|
+
type: "button",
|
|
721
|
+
children
|
|
722
|
+
}
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
function ReadyRichTextField({ field, name }) {
|
|
726
|
+
const form = useFormContext2();
|
|
727
|
+
const value = useWatch2({ control: form.control, name });
|
|
728
|
+
const lastValue = useRef3(value);
|
|
729
|
+
const editor = useEditor({
|
|
730
|
+
content: toRichTextDocument(value),
|
|
731
|
+
extensions: [StarterKit.configure({ heading: { levels: [2, 3] } })],
|
|
732
|
+
immediatelyRender: false,
|
|
733
|
+
editable: !field.disabled,
|
|
734
|
+
editorProps: {
|
|
735
|
+
attributes: {
|
|
736
|
+
class: "builder-richtext__content",
|
|
737
|
+
"data-placeholder": field.placeholder ?? "\u0422\u0430\u0439\u043B\u0431\u0430\u0440 \u0431\u0438\u0447\u0438\u0445"
|
|
738
|
+
}
|
|
739
|
+
},
|
|
740
|
+
onUpdate: ({ editor: instance }) => {
|
|
741
|
+
const next = JSON.stringify(instance.getJSON());
|
|
742
|
+
lastValue.current = next;
|
|
743
|
+
form.setValue(name, next, {
|
|
744
|
+
shouldDirty: true,
|
|
745
|
+
shouldValidate: true
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
form.register(name, { required: field.required ? `${field.label} \u0448\u0430\u0430\u0440\u0434\u043B\u0430\u0433\u0430\u0442\u0430\u0439` : false });
|
|
750
|
+
useEffect(() => {
|
|
751
|
+
if (!editor || value === lastValue.current) return;
|
|
752
|
+
editor.commands.setContent(toRichTextDocument(value), { emitUpdate: false });
|
|
753
|
+
lastValue.current = value;
|
|
754
|
+
}, [editor, value]);
|
|
755
|
+
const error = form.getFieldState(name, form.formState).error;
|
|
756
|
+
return /* @__PURE__ */ jsxs3("div", { className: "builder-field", children: [
|
|
757
|
+
/* @__PURE__ */ jsxs3("span", { className: "builder-field__label", children: [
|
|
758
|
+
field.label,
|
|
759
|
+
field.required ? /* @__PURE__ */ jsx3("span", { "aria-hidden": "true", children: " *" }) : null
|
|
760
|
+
] }),
|
|
761
|
+
/* @__PURE__ */ jsxs3("div", { className: "builder-richtext", children: [
|
|
762
|
+
/* @__PURE__ */ jsxs3("div", { "aria-label": `${field.label} formatting`, className: "builder-richtext__toolbar", role: "toolbar", children: [
|
|
763
|
+
/* @__PURE__ */ jsx3(
|
|
764
|
+
ToolbarButton,
|
|
765
|
+
{
|
|
766
|
+
active: editor?.isActive("heading", { level: 2 }),
|
|
767
|
+
disabled: !editor || field.disabled,
|
|
768
|
+
onClick: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
769
|
+
title: "\u0413\u0430\u0440\u0447\u0438\u0433",
|
|
770
|
+
children: "H2"
|
|
771
|
+
}
|
|
772
|
+
),
|
|
773
|
+
/* @__PURE__ */ jsx3(
|
|
774
|
+
ToolbarButton,
|
|
775
|
+
{
|
|
776
|
+
active: editor?.isActive("bold"),
|
|
777
|
+
disabled: !editor || field.disabled,
|
|
778
|
+
onClick: () => editor?.chain().focus().toggleBold().run(),
|
|
779
|
+
title: "\u0422\u043E\u0434",
|
|
780
|
+
children: "B"
|
|
781
|
+
}
|
|
782
|
+
),
|
|
783
|
+
/* @__PURE__ */ jsx3(
|
|
784
|
+
ToolbarButton,
|
|
785
|
+
{
|
|
786
|
+
active: editor?.isActive("italic"),
|
|
787
|
+
disabled: !editor || field.disabled,
|
|
788
|
+
onClick: () => editor?.chain().focus().toggleItalic().run(),
|
|
789
|
+
title: "\u041D\u0430\u043B\u0443\u0443",
|
|
790
|
+
children: "I"
|
|
791
|
+
}
|
|
792
|
+
),
|
|
793
|
+
/* @__PURE__ */ jsx3(
|
|
794
|
+
ToolbarButton,
|
|
795
|
+
{
|
|
796
|
+
active: editor?.isActive("bulletList"),
|
|
797
|
+
disabled: !editor || field.disabled,
|
|
798
|
+
onClick: () => editor?.chain().focus().toggleBulletList().run(),
|
|
799
|
+
title: "Bullet \u0436\u0430\u0433\u0441\u0430\u0430\u043B\u0442",
|
|
800
|
+
children: "\u2022"
|
|
801
|
+
}
|
|
802
|
+
),
|
|
803
|
+
/* @__PURE__ */ jsx3(
|
|
804
|
+
ToolbarButton,
|
|
805
|
+
{
|
|
806
|
+
active: editor?.isActive("orderedList"),
|
|
807
|
+
disabled: !editor || field.disabled,
|
|
808
|
+
onClick: () => editor?.chain().focus().toggleOrderedList().run(),
|
|
809
|
+
title: "\u0414\u0443\u0433\u0430\u0430\u0440\u0442\u0430\u0439 \u0436\u0430\u0433\u0441\u0430\u0430\u043B\u0442",
|
|
810
|
+
children: "1."
|
|
811
|
+
}
|
|
812
|
+
),
|
|
813
|
+
/* @__PURE__ */ jsx3(
|
|
814
|
+
ToolbarButton,
|
|
815
|
+
{
|
|
816
|
+
disabled: !editor || field.disabled || !editor.can().undo(),
|
|
817
|
+
onClick: () => editor?.chain().focus().undo().run(),
|
|
818
|
+
title: "\u0411\u0443\u0446\u0430\u0430\u0445",
|
|
819
|
+
children: "\u21B6"
|
|
820
|
+
}
|
|
821
|
+
),
|
|
822
|
+
/* @__PURE__ */ jsx3(
|
|
823
|
+
ToolbarButton,
|
|
824
|
+
{
|
|
825
|
+
disabled: !editor || field.disabled || !editor.can().redo(),
|
|
826
|
+
onClick: () => editor?.chain().focus().redo().run(),
|
|
827
|
+
title: "\u0414\u0430\u0445\u0438\u043D \u0445\u0438\u0439\u0445",
|
|
828
|
+
children: "\u21B7"
|
|
829
|
+
}
|
|
830
|
+
)
|
|
831
|
+
] }),
|
|
832
|
+
/* @__PURE__ */ jsx3(EditorContent, { editor })
|
|
833
|
+
] }),
|
|
834
|
+
field.description ? /* @__PURE__ */ jsx3("small", { className: "builder-field__description", children: field.description }) : null,
|
|
835
|
+
typeof error?.message === "string" ? /* @__PURE__ */ jsx3("small", { className: "builder-field__error", children: error.message }) : null
|
|
836
|
+
] });
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// src/ready/ReadyFields.tsx
|
|
840
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
506
841
|
function inputType(field) {
|
|
507
842
|
if (field.type === "date") return "date";
|
|
508
843
|
if (field.type === "number" || field.type === "money") return "number";
|
|
509
844
|
return "text";
|
|
510
845
|
}
|
|
511
|
-
function ReadyField({
|
|
846
|
+
function ReadyField({
|
|
847
|
+
field,
|
|
848
|
+
formId,
|
|
849
|
+
viewId,
|
|
850
|
+
parentValues
|
|
851
|
+
}) {
|
|
512
852
|
const { hooks, notify } = useBuilderRuntime();
|
|
513
|
-
const form =
|
|
514
|
-
const values =
|
|
515
|
-
const timer =
|
|
853
|
+
const form = useFormContext3();
|
|
854
|
+
const values = useWatch3({ control: form.control, name: "values" }) ?? {};
|
|
855
|
+
const timer = useRef4(null);
|
|
516
856
|
const source = field.optionsSource;
|
|
517
857
|
const dependencyValue = source?.filterBy ? values[source.filterBy.valueFromField] : void 0;
|
|
518
858
|
const depends = source?.filterBy && dependencyValue != null ? { [source.filterBy.valueFromField]: String(dependencyValue) } : void 0;
|
|
@@ -525,6 +865,12 @@ function ReadyField({ field, formId, viewId }) {
|
|
|
525
865
|
const trigger = hooks.useRunRuntimeBuilderFieldTrigger();
|
|
526
866
|
const name = `values.${field.key}`;
|
|
527
867
|
if (field.hidden) return null;
|
|
868
|
+
if (field.type === "file") {
|
|
869
|
+
return /* @__PURE__ */ jsx4(ReadyFileField, { field, formId, viewId, name });
|
|
870
|
+
}
|
|
871
|
+
if (field.type === "richtext") {
|
|
872
|
+
return /* @__PURE__ */ jsx4(ReadyRichTextField, { field, name });
|
|
873
|
+
}
|
|
528
874
|
const runTrigger = (event, value) => {
|
|
529
875
|
const definition = field.triggers.find((item) => item.enabled && item.event === event);
|
|
530
876
|
if (!definition) return;
|
|
@@ -535,7 +881,7 @@ function ReadyField({ field, formId, viewId }) {
|
|
|
535
881
|
viewId,
|
|
536
882
|
fieldKey: field.key,
|
|
537
883
|
event,
|
|
538
|
-
input: { value, values: form.getValues("values") }
|
|
884
|
+
input: { value, values: form.getValues("values"), parentValues }
|
|
539
885
|
});
|
|
540
886
|
for (const [key, patchedValue] of Object.entries(response.valuesPatch)) {
|
|
541
887
|
form.setValue(`values.${key}`, patchedValue, { shouldDirty: true, shouldValidate: true });
|
|
@@ -563,41 +909,47 @@ function ReadyField({ field, formId, viewId }) {
|
|
|
563
909
|
});
|
|
564
910
|
const error = form.formState.errors.values?.[field.key];
|
|
565
911
|
const options = source ? optionsQuery.data ?? [] : field.options ?? [];
|
|
566
|
-
return /* @__PURE__ */
|
|
567
|
-
/* @__PURE__ */
|
|
912
|
+
return /* @__PURE__ */ jsxs4("label", { className: "builder-field", children: [
|
|
913
|
+
/* @__PURE__ */ jsxs4("span", { className: "builder-field__label", children: [
|
|
568
914
|
field.label,
|
|
569
|
-
field.required ? /* @__PURE__ */
|
|
915
|
+
field.required ? /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: " *" }) : null
|
|
570
916
|
] }),
|
|
571
|
-
field.type === "textarea" ? /* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
options.map((option) => /* @__PURE__ */
|
|
574
|
-
] }) : field.type === "checkbox" ? /* @__PURE__ */
|
|
575
|
-
field.description ? /* @__PURE__ */
|
|
576
|
-
typeof error?.message === "string" ? /* @__PURE__ */
|
|
917
|
+
field.type === "textarea" ? /* @__PURE__ */ jsx4("textarea", { className: "builder-input builder-textarea", placeholder: field.placeholder, disabled: field.disabled, ...registration }) : field.type === "select" ? /* @__PURE__ */ jsxs4("select", { className: "builder-input", disabled: field.disabled || optionsQuery.isPending, ...registration, children: [
|
|
918
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: field.placeholder ?? "\u0421\u043E\u043D\u0433\u043E\u0445" }),
|
|
919
|
+
options.map((option) => /* @__PURE__ */ jsx4("option", { value: option.value, children: option.label }, option.value))
|
|
920
|
+
] }) : field.type === "checkbox" ? /* @__PURE__ */ jsx4("input", { className: "builder-checkbox", type: "checkbox", disabled: field.disabled, ...registration }) : /* @__PURE__ */ jsx4("input", { className: "builder-input", type: inputType(field), placeholder: field.placeholder, disabled: field.disabled, ...registration }),
|
|
921
|
+
field.description ? /* @__PURE__ */ jsx4("small", { className: "builder-field__description", children: field.description }) : null,
|
|
922
|
+
typeof error?.message === "string" ? /* @__PURE__ */ jsx4("small", { className: "builder-field__error", children: error.message }) : null
|
|
577
923
|
] });
|
|
578
924
|
}
|
|
579
|
-
function ReadyFields({
|
|
925
|
+
function ReadyFields({
|
|
926
|
+
formId,
|
|
927
|
+
viewId,
|
|
928
|
+
schema,
|
|
929
|
+
parentValues,
|
|
930
|
+
extraItems = []
|
|
931
|
+
}) {
|
|
580
932
|
const fields = new Map(schema.fields.map((field) => [field.key, field]));
|
|
581
933
|
const rendered = /* @__PURE__ */ new Set();
|
|
582
|
-
return /* @__PURE__ */
|
|
583
|
-
schema.layout?.groups.map((group) => /* @__PURE__ */
|
|
584
|
-
group.title ? /* @__PURE__ */
|
|
585
|
-
/* @__PURE__ */
|
|
934
|
+
return /* @__PURE__ */ jsxs4("div", { className: "builder-form-fields", children: [
|
|
935
|
+
schema.layout?.groups.map((group) => /* @__PURE__ */ jsxs4("fieldset", { className: "builder-fieldset", children: [
|
|
936
|
+
group.title ? /* @__PURE__ */ jsx4("legend", { children: group.title }) : null,
|
|
937
|
+
/* @__PURE__ */ jsx4("div", { className: "builder-form-grid", children: group.fields.map((item) => {
|
|
586
938
|
const field = fields.get(item.key);
|
|
587
939
|
if (!field) return null;
|
|
588
940
|
rendered.add(field.key);
|
|
589
|
-
return /* @__PURE__ */
|
|
941
|
+
return /* @__PURE__ */ jsx4("div", { style: { gridColumn: `span ${item.span}` }, children: /* @__PURE__ */ jsx4(ReadyField, { field, formId, viewId, parentValues }) }, field.key);
|
|
590
942
|
}) })
|
|
591
943
|
] }, group.id)),
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
extraItems.map((item) => /* @__PURE__ */
|
|
944
|
+
/* @__PURE__ */ jsx4("div", { className: "builder-form-grid", children: schema.fields.filter((field) => !rendered.has(field.key)).map((field) => /* @__PURE__ */ jsx4("div", { style: { gridColumn: "span 12" }, children: /* @__PURE__ */ jsx4(ReadyField, { field, formId, viewId, parentValues }) }, field.key)) }),
|
|
945
|
+
extraItems.map((item) => /* @__PURE__ */ jsx4("div", { children: item.render() }, item.key))
|
|
594
946
|
] });
|
|
595
947
|
}
|
|
596
948
|
|
|
597
949
|
// src/ready/ReadyOverlay.tsx
|
|
598
|
-
import { useEffect, useId, useRef as
|
|
950
|
+
import { useEffect as useEffect2, useId as useId2, useRef as useRef5, useState as useState3 } from "react";
|
|
599
951
|
import { createPortal } from "react-dom";
|
|
600
|
-
import { jsx as
|
|
952
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
601
953
|
function ReadyOverlay({
|
|
602
954
|
open,
|
|
603
955
|
presentation = "dialog",
|
|
@@ -606,15 +958,15 @@ function ReadyOverlay({
|
|
|
606
958
|
onClose,
|
|
607
959
|
children
|
|
608
960
|
}) {
|
|
609
|
-
const panelRef =
|
|
610
|
-
const onCloseRef =
|
|
611
|
-
const [portalRoot, setPortalRoot] =
|
|
961
|
+
const panelRef = useRef5(null);
|
|
962
|
+
const onCloseRef = useRef5(onClose);
|
|
963
|
+
const [portalRoot, setPortalRoot] = useState3(null);
|
|
612
964
|
onCloseRef.current = onClose;
|
|
613
|
-
const titleId =
|
|
614
|
-
|
|
965
|
+
const titleId = useId2();
|
|
966
|
+
useEffect2(() => {
|
|
615
967
|
setPortalRoot(document.body);
|
|
616
968
|
}, []);
|
|
617
|
-
|
|
969
|
+
useEffect2(() => {
|
|
618
970
|
if (!open || !portalRoot) return;
|
|
619
971
|
const previous = document.activeElement;
|
|
620
972
|
panelRef.current?.focus();
|
|
@@ -648,7 +1000,7 @@ function ReadyOverlay({
|
|
|
648
1000
|
}, [open, portalRoot]);
|
|
649
1001
|
if (!open || !portalRoot) return null;
|
|
650
1002
|
return createPortal(
|
|
651
|
-
/* @__PURE__ */
|
|
1003
|
+
/* @__PURE__ */ jsx5("div", { className: "builder-overlay", role: "presentation", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ jsxs5(
|
|
652
1004
|
"div",
|
|
653
1005
|
{
|
|
654
1006
|
ref: panelRef,
|
|
@@ -658,14 +1010,14 @@ function ReadyOverlay({
|
|
|
658
1010
|
"aria-labelledby": titleId,
|
|
659
1011
|
tabIndex: -1,
|
|
660
1012
|
children: [
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
description ? /* @__PURE__ */
|
|
1013
|
+
/* @__PURE__ */ jsxs5("header", { className: "builder-overlay__header", children: [
|
|
1014
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1015
|
+
/* @__PURE__ */ jsx5("h2", { id: titleId, className: "builder-title", children: title }),
|
|
1016
|
+
description ? /* @__PURE__ */ jsx5("p", { className: "builder-description", children: description }) : null
|
|
665
1017
|
] }),
|
|
666
|
-
/* @__PURE__ */
|
|
1018
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: "builder-icon-button", "aria-label": "\u0425\u0430\u0430\u0445", onClick: onClose, children: "\xD7" })
|
|
667
1019
|
] }),
|
|
668
|
-
/* @__PURE__ */
|
|
1020
|
+
/* @__PURE__ */ jsx5("div", { className: "builder-overlay__body", children })
|
|
669
1021
|
]
|
|
670
1022
|
}
|
|
671
1023
|
) }),
|
|
@@ -681,29 +1033,29 @@ function ReadyConfirmDialog({
|
|
|
681
1033
|
onClose,
|
|
682
1034
|
onConfirm
|
|
683
1035
|
}) {
|
|
684
|
-
return /* @__PURE__ */
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
1036
|
+
return /* @__PURE__ */ jsx5(ReadyOverlay, { open, title, description, onClose, children: /* @__PURE__ */ jsxs5("div", { className: "builder-actions", children: [
|
|
1037
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: "builder-button builder-button--ghost", onClick: onClose, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
1038
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: "builder-button builder-button--danger", disabled: isPending, onClick: onConfirm, children: isPending ? "\u0422\u04AF\u0440 \u0445\u04AF\u043B\u044D\u044D\u043D\u044D \u04AF\u04AF\u2026" : confirmLabel })
|
|
687
1039
|
] }) });
|
|
688
1040
|
}
|
|
689
1041
|
function ReadyErrorState({ title, description }) {
|
|
690
|
-
return /* @__PURE__ */
|
|
691
|
-
/* @__PURE__ */
|
|
692
|
-
/* @__PURE__ */
|
|
1042
|
+
return /* @__PURE__ */ jsxs5("div", { className: "builder-state builder-state--error", role: "alert", children: [
|
|
1043
|
+
/* @__PURE__ */ jsx5("strong", { children: title }),
|
|
1044
|
+
/* @__PURE__ */ jsx5("span", { children: description })
|
|
693
1045
|
] });
|
|
694
1046
|
}
|
|
695
1047
|
|
|
696
1048
|
// src/ready/ReadySubform.tsx
|
|
697
|
-
import { useEffect as
|
|
698
|
-
import { FormProvider, useForm } from "react-hook-form";
|
|
1049
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef6, useState as useState5 } from "react";
|
|
1050
|
+
import { FormProvider, useForm, useFormContext as useFormContext4, useWatch as useWatch4 } from "react-hook-form";
|
|
699
1051
|
|
|
700
1052
|
// src/ready/ReadyTable.tsx
|
|
701
|
-
import { useMemo as useMemo2, useState as
|
|
702
|
-
import { jsx as
|
|
1053
|
+
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
1054
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
703
1055
|
function useReadyTableState({ pageSize = 20 } = {}) {
|
|
704
|
-
const [page, setPage] =
|
|
705
|
-
const [search, setSearchValue] =
|
|
706
|
-
const [sort, setSort] =
|
|
1056
|
+
const [page, setPage] = useState4(1);
|
|
1057
|
+
const [search, setSearchValue] = useState4("");
|
|
1058
|
+
const [sort, setSort] = useState4();
|
|
707
1059
|
return {
|
|
708
1060
|
query: { page, pageSize, search: search || void 0, sort },
|
|
709
1061
|
page,
|
|
@@ -722,7 +1074,7 @@ function useReadyTableState({ pageSize = 20 } = {}) {
|
|
|
722
1074
|
};
|
|
723
1075
|
}
|
|
724
1076
|
function useReadyTable(args) {
|
|
725
|
-
const [selectedIds, setSelectedIds] =
|
|
1077
|
+
const [selectedIds, setSelectedIds] = useState4([]);
|
|
726
1078
|
return useMemo2(
|
|
727
1079
|
() => ({
|
|
728
1080
|
...args,
|
|
@@ -756,14 +1108,14 @@ function ReadyDataGrid({
|
|
|
756
1108
|
selectable = false
|
|
757
1109
|
}) {
|
|
758
1110
|
const totalPages = Math.max(1, Math.ceil(controller.rowCount / controller.state.pageSize));
|
|
759
|
-
return /* @__PURE__ */
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
title ? /* @__PURE__ */
|
|
763
|
-
description ? /* @__PURE__ */
|
|
1111
|
+
return /* @__PURE__ */ jsxs6("section", { className: "builder-card builder-grid", "aria-busy": isLoading || void 0, children: [
|
|
1112
|
+
/* @__PURE__ */ jsxs6("header", { className: "builder-grid__header", children: [
|
|
1113
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1114
|
+
title ? /* @__PURE__ */ jsx6("h2", { className: "builder-title", children: title }) : null,
|
|
1115
|
+
description ? /* @__PURE__ */ jsx6("p", { className: "builder-description", children: description }) : null
|
|
764
1116
|
] }),
|
|
765
|
-
/* @__PURE__ */
|
|
766
|
-
/* @__PURE__ */
|
|
1117
|
+
/* @__PURE__ */ jsxs6("div", { className: "builder-grid__toolbar", children: [
|
|
1118
|
+
/* @__PURE__ */ jsx6(
|
|
767
1119
|
"input",
|
|
768
1120
|
{
|
|
769
1121
|
className: "builder-input builder-grid__search",
|
|
@@ -777,19 +1129,19 @@ function ReadyDataGrid({
|
|
|
777
1129
|
toolbarExtra
|
|
778
1130
|
] })
|
|
779
1131
|
] }),
|
|
780
|
-
/* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
selectable ? /* @__PURE__ */
|
|
784
|
-
controller.columns.map((column) => /* @__PURE__ */
|
|
1132
|
+
/* @__PURE__ */ jsxs6("div", { className: "builder-table-wrap", children: [
|
|
1133
|
+
/* @__PURE__ */ jsxs6("table", { className: "builder-table", children: [
|
|
1134
|
+
/* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsxs6("tr", { children: [
|
|
1135
|
+
selectable ? /* @__PURE__ */ jsx6("th", { "aria-label": "\u0421\u043E\u043D\u0433\u043E\u043B\u0442" }) : null,
|
|
1136
|
+
controller.columns.map((column) => /* @__PURE__ */ jsx6("th", { className: `builder-align-${column.align}`, children: column.sortable ? /* @__PURE__ */ jsx6("button", { type: "button", className: "builder-sort", onClick: () => controller.state.toggleSort(column.key), children: column.label }) : column.label }, column.key))
|
|
785
1137
|
] }) }),
|
|
786
|
-
/* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ jsx6("tbody", { children: controller.data.map((entry) => /* @__PURE__ */ jsxs6(
|
|
787
1139
|
"tr",
|
|
788
1140
|
{
|
|
789
1141
|
className: onRowClick ? "builder-row-clickable" : void 0,
|
|
790
1142
|
onClick: (event) => onRowClick?.(entry, event),
|
|
791
1143
|
children: [
|
|
792
|
-
selectable ? /* @__PURE__ */
|
|
1144
|
+
selectable ? /* @__PURE__ */ jsx6("td", { children: /* @__PURE__ */ jsx6(
|
|
793
1145
|
"input",
|
|
794
1146
|
{
|
|
795
1147
|
type: "checkbox",
|
|
@@ -799,31 +1151,31 @@ function ReadyDataGrid({
|
|
|
799
1151
|
onChange: () => controller.toggleSelected(entry.id)
|
|
800
1152
|
}
|
|
801
1153
|
) }) : null,
|
|
802
|
-
controller.columns.map((column) => /* @__PURE__ */
|
|
1154
|
+
controller.columns.map((column) => /* @__PURE__ */ jsx6("td", { className: `builder-align-${column.align}`, children: cellValue(entry, column) }, column.key))
|
|
803
1155
|
]
|
|
804
1156
|
},
|
|
805
1157
|
entry.id
|
|
806
1158
|
)) })
|
|
807
1159
|
] }),
|
|
808
|
-
isLoading ? /* @__PURE__ */
|
|
809
|
-
!isLoading && controller.data.length === 0 ? /* @__PURE__ */
|
|
810
|
-
/* @__PURE__ */
|
|
811
|
-
emptyDescription ? /* @__PURE__ */
|
|
1160
|
+
isLoading ? /* @__PURE__ */ jsx6("div", { className: "builder-state", children: "\u0423\u043D\u0448\u0438\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" }) : null,
|
|
1161
|
+
!isLoading && controller.data.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "builder-state", children: [
|
|
1162
|
+
/* @__PURE__ */ jsx6("strong", { children: emptyTitle }),
|
|
1163
|
+
emptyDescription ? /* @__PURE__ */ jsx6("span", { children: emptyDescription }) : null
|
|
812
1164
|
] }) : null
|
|
813
1165
|
] }),
|
|
814
|
-
/* @__PURE__ */
|
|
815
|
-
/* @__PURE__ */
|
|
1166
|
+
/* @__PURE__ */ jsxs6("footer", { className: "builder-pagination", children: [
|
|
1167
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
816
1168
|
controller.rowCount,
|
|
817
1169
|
" \u043C\u04E9\u0440"
|
|
818
1170
|
] }),
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */
|
|
1171
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1172
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--ghost", disabled: controller.state.page <= 1, onClick: () => controller.state.setPage(controller.state.page - 1), children: "\u04E8\u043C\u043D\u04E9\u0445" }),
|
|
1173
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
822
1174
|
controller.state.page,
|
|
823
1175
|
" / ",
|
|
824
1176
|
totalPages
|
|
825
1177
|
] }),
|
|
826
|
-
/* @__PURE__ */
|
|
1178
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--ghost", disabled: controller.state.page >= totalPages, onClick: () => controller.state.setPage(controller.state.page + 1), children: "\u0414\u0430\u0440\u0430\u0430\u0445" })
|
|
827
1179
|
] })
|
|
828
1180
|
] })
|
|
829
1181
|
] });
|
|
@@ -833,7 +1185,7 @@ function readyColumns(columns) {
|
|
|
833
1185
|
}
|
|
834
1186
|
|
|
835
1187
|
// src/ready/ReadySubform.tsx
|
|
836
|
-
import { jsx as
|
|
1188
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
837
1189
|
function linkedValue(entry, field) {
|
|
838
1190
|
if (!entry) return void 0;
|
|
839
1191
|
const value = field === "id" ? entry.id : entry.values[field];
|
|
@@ -847,7 +1199,7 @@ function makeDraftEntry(viewId, values, editing) {
|
|
|
847
1199
|
return {
|
|
848
1200
|
id: editing?.id ?? (globalThis.crypto?.randomUUID?.() ?? `draft-${Date.now()}`),
|
|
849
1201
|
viewId,
|
|
850
|
-
values: editing ? values.values : { ...values.values, _draftNew: true },
|
|
1202
|
+
values: editing ? { ...values.values, _draftDirty: true } : { ...values.values, _draftNew: true },
|
|
851
1203
|
version: editing?.version ?? 0,
|
|
852
1204
|
createdAt: editing?.createdAt ?? now,
|
|
853
1205
|
updatedAt: now
|
|
@@ -855,9 +1207,12 @@ function makeDraftEntry(viewId, values, editing) {
|
|
|
855
1207
|
}
|
|
856
1208
|
function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
857
1209
|
const { hooks, notify } = useBuilderRuntime();
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
const
|
|
1210
|
+
const parentForm = useFormContext4();
|
|
1211
|
+
const watchedParentValues = useWatch4({ control: parentForm.control, name: "values" });
|
|
1212
|
+
const parentValues = watchedParentValues && typeof watchedParentValues === "object" && !Array.isArray(watchedParentValues) ? watchedParentValues : void 0;
|
|
1213
|
+
const [open, setOpen] = useState5(false);
|
|
1214
|
+
const [editing, setEditing] = useState5(null);
|
|
1215
|
+
const initialized = useRef6(false);
|
|
861
1216
|
const parentValue = linkedValue(parentEntry, subform.parentField);
|
|
862
1217
|
const viewQuery = hooks.useRuntimeBuilderView(subform.viewId, Boolean(subform.viewId));
|
|
863
1218
|
const tableState = useReadyTableState({ pageSize: 100 });
|
|
@@ -868,7 +1223,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
|
868
1223
|
const entriesQuery = hooks.useBuilderViewEntries(subform.viewId, filterQuery, Boolean(parentValue));
|
|
869
1224
|
const view = viewQuery.data;
|
|
870
1225
|
const source = view?.list?.source?.type === "dbTable" ? view.list.source.tableName : void 0;
|
|
871
|
-
|
|
1226
|
+
useEffect3(() => {
|
|
872
1227
|
if (initialized.current || !view || !entriesQuery.data || !parentValue) return;
|
|
873
1228
|
initialized.current = true;
|
|
874
1229
|
onRowsChange({ key: subform.key, dataKey: dataKey(view.id, source), rows: entriesQuery.data.items });
|
|
@@ -888,7 +1243,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
|
888
1243
|
sortable: false,
|
|
889
1244
|
hidden: false,
|
|
890
1245
|
align: "right",
|
|
891
|
-
render: (row) => /* @__PURE__ */
|
|
1246
|
+
render: (row) => /* @__PURE__ */ jsx7("button", { type: "button", className: "builder-link builder-link--danger", onClick: (event) => {
|
|
892
1247
|
event.stopPropagation();
|
|
893
1248
|
removeRow(row);
|
|
894
1249
|
}, children: "\u0423\u0441\u0442\u0433\u0430\u0445" })
|
|
@@ -922,12 +1277,12 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
|
922
1277
|
close();
|
|
923
1278
|
});
|
|
924
1279
|
if (viewQuery.isError) {
|
|
925
|
-
return /* @__PURE__ */
|
|
1280
|
+
return /* @__PURE__ */ jsx7("div", { className: "builder-state builder-state--error", children: builderErrorMessage(viewQuery.error, `${subform.label} \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439`) });
|
|
926
1281
|
}
|
|
927
|
-
return /* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
/* @__PURE__ */
|
|
930
|
-
/* @__PURE__ */
|
|
1282
|
+
return /* @__PURE__ */ jsxs7("section", { className: "builder-subform", children: [
|
|
1283
|
+
/* @__PURE__ */ jsxs7("div", { className: "builder-subform__header", children: [
|
|
1284
|
+
/* @__PURE__ */ jsx7("strong", { children: subform.label }),
|
|
1285
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", className: "builder-button builder-button--secondary", disabled: !view?.form, onClick: () => {
|
|
931
1286
|
setEditing(null);
|
|
932
1287
|
setOpen(true);
|
|
933
1288
|
}, children: [
|
|
@@ -935,7 +1290,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
|
935
1290
|
subform.buttonLabel ?? "\u041D\u044D\u043C\u044D\u0445"
|
|
936
1291
|
] })
|
|
937
1292
|
] }),
|
|
938
|
-
visibleRows.length > 0 || Boolean(parentValue) && entriesQuery.isPending ? /* @__PURE__ */
|
|
1293
|
+
visibleRows.length > 0 || Boolean(parentValue) && entriesQuery.isPending ? /* @__PURE__ */ jsx7(
|
|
939
1294
|
ReadyDataGrid,
|
|
940
1295
|
{
|
|
941
1296
|
controller: table,
|
|
@@ -947,26 +1302,34 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
|
947
1302
|
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430"
|
|
948
1303
|
}
|
|
949
1304
|
) : null,
|
|
950
|
-
view?.form ? /* @__PURE__ */
|
|
951
|
-
/* @__PURE__ */
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1305
|
+
view?.form ? /* @__PURE__ */ jsx7(ReadyOverlay, { open, presentation: subform.presentation, title: subform.label, description: view.title, onClose: close, children: /* @__PURE__ */ jsx7(FormProvider, { ...form, children: /* @__PURE__ */ jsxs7("form", { className: "builder-form", onSubmit: save, noValidate: true, children: [
|
|
1306
|
+
/* @__PURE__ */ jsx7(
|
|
1307
|
+
ReadyFields,
|
|
1308
|
+
{
|
|
1309
|
+
formId: view.form.id,
|
|
1310
|
+
viewId: view.id,
|
|
1311
|
+
schema: view.form.schema,
|
|
1312
|
+
parentValues
|
|
1313
|
+
}
|
|
1314
|
+
),
|
|
1315
|
+
/* @__PURE__ */ jsxs7("div", { className: "builder-actions", children: [
|
|
1316
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "builder-button builder-button--ghost", onClick: close, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
1317
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", className: "builder-button builder-button--primary", children: editing ? "\u0428\u0438\u043D\u044D\u0447\u043B\u044D\u0445" : "\u041D\u044D\u043C\u044D\u0445" })
|
|
955
1318
|
] })
|
|
956
1319
|
] }) }) }) : null
|
|
957
1320
|
] });
|
|
958
1321
|
}
|
|
959
1322
|
|
|
960
1323
|
// src/ready/BuilderRuntimeComponents.tsx
|
|
961
|
-
import { jsx as
|
|
1324
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
962
1325
|
function DefaultBuilderForm({ formId }) {
|
|
963
1326
|
const { hooks, notify } = useBuilderRuntime();
|
|
964
1327
|
const query = hooks.useRuntimeBuilderForm(formId);
|
|
965
1328
|
const save = hooks.useSaveRuntimeBuilderFormEntry(formId);
|
|
966
1329
|
const defaults = useMemo4(() => createBuilderFormDefaultValues(query.data?.schema), [query.data]);
|
|
967
1330
|
const form = useForm2({ defaultValues: defaults, values: query.data ? defaults : void 0 });
|
|
968
|
-
if (query.isError) return /* @__PURE__ */
|
|
969
|
-
if (!query.data) return /* @__PURE__ */
|
|
1331
|
+
if (query.isError) return /* @__PURE__ */ jsx8(ReadyErrorState, { title: "Form \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(query.error, `\xAB${formId}\xBB form \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
1332
|
+
if (!query.data) return /* @__PURE__ */ jsx8("div", { className: "builder-state", children: "Form \u0443\u043D\u0448\u0438\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" });
|
|
970
1333
|
const submit = form.handleSubmit(async (input) => {
|
|
971
1334
|
try {
|
|
972
1335
|
await save.mutateAsync(input);
|
|
@@ -976,12 +1339,12 @@ function DefaultBuilderForm({ formId }) {
|
|
|
976
1339
|
notify({ type: "error", message: builderErrorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430") });
|
|
977
1340
|
}
|
|
978
1341
|
});
|
|
979
|
-
return /* @__PURE__ */
|
|
980
|
-
/* @__PURE__ */
|
|
981
|
-
query.data.description ? /* @__PURE__ */
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
984
|
-
/* @__PURE__ */
|
|
1342
|
+
return /* @__PURE__ */ jsxs8("section", { className: "builder-card", children: [
|
|
1343
|
+
/* @__PURE__ */ jsx8("h2", { className: "builder-title", children: query.data.title }),
|
|
1344
|
+
query.data.description ? /* @__PURE__ */ jsx8("p", { className: "builder-description", children: query.data.description }) : null,
|
|
1345
|
+
/* @__PURE__ */ jsx8(FormProvider2, { ...form, children: /* @__PURE__ */ jsxs8("form", { className: "builder-form", onSubmit: submit, noValidate: true, children: [
|
|
1346
|
+
/* @__PURE__ */ jsx8(ReadyFields, { formId, schema: query.data.schema }),
|
|
1347
|
+
/* @__PURE__ */ jsx8("div", { className: "builder-actions", children: /* @__PURE__ */ jsx8("button", { className: "builder-button builder-button--primary", type: "submit", disabled: save.isPending, children: save.isPending ? "\u0425\u0430\u0434\u0433\u0430\u043B\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" : "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" }) })
|
|
985
1348
|
] }) })
|
|
986
1349
|
] });
|
|
987
1350
|
}
|
|
@@ -997,8 +1360,8 @@ function DefaultBuilderGrid({ listId }) {
|
|
|
997
1360
|
state,
|
|
998
1361
|
getRowId: (row) => row.id
|
|
999
1362
|
});
|
|
1000
|
-
if (listQuery.isError) return /* @__PURE__ */
|
|
1001
|
-
return /* @__PURE__ */
|
|
1363
|
+
if (listQuery.isError) return /* @__PURE__ */ jsx8(ReadyErrorState, { title: "Grid \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(listQuery.error, `\xAB${listId}\xBB list \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
1364
|
+
return /* @__PURE__ */ jsx8(ReadyDataGrid, { title: listQuery.data?.title ?? "Grid", description: listQuery.data?.description, controller: table, isLoading: listQuery.isPending || entriesQuery.isPending });
|
|
1002
1365
|
}
|
|
1003
1366
|
function dbTableName(view) {
|
|
1004
1367
|
if (view.list?.source?.type === "dbTable") return view.list.source.tableName;
|
|
@@ -1009,9 +1372,16 @@ function childPayload(row, includeIdentity) {
|
|
|
1009
1372
|
const values = Object.fromEntries(Object.entries(row.values).filter(([key]) => key === "_delete" || !key.startsWith("_")));
|
|
1010
1373
|
return includeIdentity && row.values._draftNew !== true ? { id: row.id, version: row.version, ...values } : values;
|
|
1011
1374
|
}
|
|
1375
|
+
function hasSubformChange(row) {
|
|
1376
|
+
return row.values._delete === true || row.values._draftNew === true || row.values._draftDirty === true;
|
|
1377
|
+
}
|
|
1378
|
+
function changedSubformPayloads(rows, includeIdentity) {
|
|
1379
|
+
return rows.filter(hasSubformChange).filter((row) => includeIdentity || row.values._delete !== true).map((row) => childPayload(row, includeIdentity));
|
|
1380
|
+
}
|
|
1012
1381
|
function BuilderEntryEditor({ view, editing, open, onClose }) {
|
|
1013
1382
|
const { hooks, notify } = useBuilderRuntime();
|
|
1014
|
-
const [subforms, setSubforms] =
|
|
1383
|
+
const [subforms, setSubforms] = useState6({});
|
|
1384
|
+
const isSubmittingRef = useRef7(false);
|
|
1015
1385
|
const save = hooks.useSaveBuilderViewEntry(view.id);
|
|
1016
1386
|
const createComposite = hooks.useCreateCompositeBuilderViewEntry(view.id);
|
|
1017
1387
|
const updateComposite = hooks.useUpdateCompositeBuilderViewEntry(view.id);
|
|
@@ -1022,11 +1392,13 @@ function BuilderEntryEditor({ view, editing, open, onClose }) {
|
|
|
1022
1392
|
onClose();
|
|
1023
1393
|
};
|
|
1024
1394
|
const submit = form.handleSubmit(async (input) => {
|
|
1395
|
+
if (isSubmittingRef.current) return;
|
|
1396
|
+
isSubmittingRef.current = true;
|
|
1025
1397
|
try {
|
|
1026
1398
|
const mainKey = dbTableName(view);
|
|
1027
|
-
const
|
|
1028
|
-
if (
|
|
1029
|
-
const children = Object.fromEntries(Object.values(subforms).map((item) => [item.dataKey, item.rows
|
|
1399
|
+
const hasSubformChanges = Object.values(subforms).some((item) => item.rows.some(hasSubformChange));
|
|
1400
|
+
if (hasSubformChanges && mainKey) {
|
|
1401
|
+
const children = Object.fromEntries(Object.values(subforms).map((item) => [item.dataKey, changedSubformPayloads(item.rows, Boolean(editing))]));
|
|
1030
1402
|
if (editing) {
|
|
1031
1403
|
await updateComposite.mutateAsync({ id: editing.id, input: { data: { [mainKey]: { id: editing.id, version: input.version, ...input.values }, ...children } } });
|
|
1032
1404
|
} else {
|
|
@@ -1039,24 +1411,26 @@ function BuilderEntryEditor({ view, editing, open, onClose }) {
|
|
|
1039
1411
|
close();
|
|
1040
1412
|
} catch (error) {
|
|
1041
1413
|
notify({ type: "error", message: builderErrorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430") });
|
|
1414
|
+
} finally {
|
|
1415
|
+
isSubmittingRef.current = false;
|
|
1042
1416
|
}
|
|
1043
1417
|
});
|
|
1044
1418
|
const saving = save.isPending || createComposite.isPending || updateComposite.isPending;
|
|
1045
1419
|
const updateRows = ({ key, dataKey: dataKey2, rows }) => setSubforms((current) => ({ ...current, [key]: { dataKey: dataKey2, rows } }));
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
view.form.schema.subforms.map((subform) => /* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ jsx8(ReadyOverlay, { open, presentation: view.form?.schema.presentation, title: editing ? "\u041C\u04E9\u0440 \u0437\u0430\u0441\u0430\u0445" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0445", description: view.title, onClose: close, children: view.form ? /* @__PURE__ */ jsx8(FormProvider2, { ...form, children: /* @__PURE__ */ jsxs8("form", { className: "builder-form", onSubmit: submit, noValidate: true, children: [
|
|
1421
|
+
/* @__PURE__ */ jsx8(ReadyFields, { formId: view.form.id, viewId: view.id, schema: view.form.schema }),
|
|
1422
|
+
view.form.schema.subforms.map((subform) => /* @__PURE__ */ jsx8(ReadySubform, { subform, parentEntry: editing, rows: subforms[subform.key]?.rows ?? [], onRowsChange: updateRows }, subform.key)),
|
|
1423
|
+
/* @__PURE__ */ jsxs8("div", { className: "builder-actions builder-actions--sticky", children: [
|
|
1424
|
+
/* @__PURE__ */ jsx8("button", { type: "button", className: "builder-button builder-button--ghost", onClick: close, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
1425
|
+
/* @__PURE__ */ jsx8("button", { type: "submit", className: "builder-button builder-button--primary", disabled: saving, children: saving ? "\u0425\u0430\u0434\u0433\u0430\u043B\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" : "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" })
|
|
1052
1426
|
] })
|
|
1053
|
-
] }) }) : /* @__PURE__ */
|
|
1427
|
+
] }) }) : /* @__PURE__ */ jsx8(ReadyErrorState, { title: "Form \u0445\u043E\u043B\u0431\u043E\u043E\u0433\u04AF\u0439", description: "\u042D\u043D\u044D view-\u0434 form \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430." }) });
|
|
1054
1428
|
}
|
|
1055
1429
|
function DefaultBuilderView({ viewId }) {
|
|
1056
1430
|
const { hooks, notify } = useBuilderRuntime();
|
|
1057
|
-
const [editing, setEditing] =
|
|
1058
|
-
const [editorOpen, setEditorOpen] =
|
|
1059
|
-
const [pendingDelete, setPendingDelete] =
|
|
1431
|
+
const [editing, setEditing] = useState6(null);
|
|
1432
|
+
const [editorOpen, setEditorOpen] = useState6(false);
|
|
1433
|
+
const [pendingDelete, setPendingDelete] = useState6(null);
|
|
1060
1434
|
const viewQuery = hooks.useRuntimeBuilderView(viewId);
|
|
1061
1435
|
const state = useReadyTableState();
|
|
1062
1436
|
const entriesQuery = hooks.useBuilderViewEntries(viewId, state.query);
|
|
@@ -1071,13 +1445,13 @@ function DefaultBuilderView({ viewId }) {
|
|
|
1071
1445
|
sortable: false,
|
|
1072
1446
|
hidden: false,
|
|
1073
1447
|
align: "right",
|
|
1074
|
-
render: (entry) => /* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1448
|
+
render: (entry) => /* @__PURE__ */ jsxs8("div", { className: "builder-row-actions", "data-builder-row-action": true, children: [
|
|
1449
|
+
/* @__PURE__ */ jsx8("button", { type: "button", className: "builder-button builder-button--ghost", onClick: (event) => {
|
|
1076
1450
|
event.stopPropagation();
|
|
1077
1451
|
setEditing(entry);
|
|
1078
1452
|
setEditorOpen(true);
|
|
1079
1453
|
}, children: "\u0417\u0430\u0441\u0430\u0445" }),
|
|
1080
|
-
/* @__PURE__ */
|
|
1454
|
+
/* @__PURE__ */ jsx8("button", { type: "button", className: "builder-button builder-button--danger", onClick: (event) => {
|
|
1081
1455
|
event.stopPropagation();
|
|
1082
1456
|
setPendingDelete(entry);
|
|
1083
1457
|
}, children: "\u0423\u0441\u0442\u0433\u0430\u0445" })
|
|
@@ -1086,9 +1460,9 @@ function DefaultBuilderView({ viewId }) {
|
|
|
1086
1460
|
return result;
|
|
1087
1461
|
}, [view]);
|
|
1088
1462
|
const table = useReadyTable({ columns, data: entriesQuery.data?.items ?? [], rowCount: entriesQuery.data?.total ?? 0, state, getRowId: (row) => row.id });
|
|
1089
|
-
if (viewQuery.isError) return /* @__PURE__ */
|
|
1090
|
-
return /* @__PURE__ */
|
|
1091
|
-
/* @__PURE__ */
|
|
1463
|
+
if (viewQuery.isError) return /* @__PURE__ */ jsx8(ReadyErrorState, { title: "View \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(viewQuery.error, `\xAB${viewId}\xBB view \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
1464
|
+
return /* @__PURE__ */ jsxs8("div", { className: "builder-runtime", children: [
|
|
1465
|
+
/* @__PURE__ */ jsx8(
|
|
1092
1466
|
ReadyDataGrid,
|
|
1093
1467
|
{
|
|
1094
1468
|
title: view?.title ?? "View",
|
|
@@ -1099,14 +1473,14 @@ function DefaultBuilderView({ viewId }) {
|
|
|
1099
1473
|
setEditing(entry);
|
|
1100
1474
|
setEditorOpen(true);
|
|
1101
1475
|
},
|
|
1102
|
-
toolbarExtra: /* @__PURE__ */
|
|
1476
|
+
toolbarExtra: /* @__PURE__ */ jsx8("button", { type: "button", className: "builder-button builder-button--primary", disabled: !view?.form, onClick: () => {
|
|
1103
1477
|
setEditing(null);
|
|
1104
1478
|
setEditorOpen(true);
|
|
1105
1479
|
}, children: "+ \u041D\u044D\u043C\u044D\u0445" })
|
|
1106
1480
|
}
|
|
1107
1481
|
),
|
|
1108
|
-
view ? /* @__PURE__ */
|
|
1109
|
-
/* @__PURE__ */
|
|
1482
|
+
view ? /* @__PURE__ */ jsx8(BuilderEntryEditor, { view, editing, open: editorOpen, onClose: () => setEditorOpen(false) }) : null,
|
|
1483
|
+
/* @__PURE__ */ jsx8(
|
|
1110
1484
|
ReadyConfirmDialog,
|
|
1111
1485
|
{
|
|
1112
1486
|
open: Boolean(pendingDelete),
|
|
@@ -1131,17 +1505,52 @@ function DefaultBuilderView({ viewId }) {
|
|
|
1131
1505
|
function BuilderForm(props) {
|
|
1132
1506
|
const { components } = useBuilderRuntime();
|
|
1133
1507
|
const Component = components.Form;
|
|
1134
|
-
return Component ? /* @__PURE__ */
|
|
1508
|
+
return Component ? /* @__PURE__ */ jsx8(Component, { ...props }) : /* @__PURE__ */ jsx8(DefaultBuilderForm, { ...props });
|
|
1135
1509
|
}
|
|
1136
1510
|
function BuilderGrid(props) {
|
|
1137
1511
|
const { components } = useBuilderRuntime();
|
|
1138
1512
|
const Component = components.Grid;
|
|
1139
|
-
return Component ? /* @__PURE__ */
|
|
1513
|
+
return Component ? /* @__PURE__ */ jsx8(Component, { ...props }) : /* @__PURE__ */ jsx8(DefaultBuilderGrid, { ...props });
|
|
1140
1514
|
}
|
|
1141
1515
|
function BuilderView(props) {
|
|
1142
1516
|
const { components } = useBuilderRuntime();
|
|
1143
1517
|
const Component = components.View;
|
|
1144
|
-
return Component ? /* @__PURE__ */
|
|
1518
|
+
return Component ? /* @__PURE__ */ jsx8(Component, { ...props }) : /* @__PURE__ */ jsx8(DefaultBuilderView, { ...props });
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// src/RichTextContent.tsx
|
|
1522
|
+
import { Fragment } from "react";
|
|
1523
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1524
|
+
function renderChildren(node) {
|
|
1525
|
+
return (node.content ?? []).map((child, index) => renderNode(child, index));
|
|
1526
|
+
}
|
|
1527
|
+
function renderText(node, key) {
|
|
1528
|
+
let value = node.text ?? "";
|
|
1529
|
+
for (const mark of node.marks ?? []) {
|
|
1530
|
+
if (mark.type === "bold") value = /* @__PURE__ */ jsx9("strong", { children: value });
|
|
1531
|
+
if (mark.type === "italic") value = /* @__PURE__ */ jsx9("em", { children: value });
|
|
1532
|
+
if (mark.type === "strike") value = /* @__PURE__ */ jsx9("s", { children: value });
|
|
1533
|
+
}
|
|
1534
|
+
return /* @__PURE__ */ jsx9(Fragment, { children: value }, key);
|
|
1535
|
+
}
|
|
1536
|
+
function renderNode(node, key) {
|
|
1537
|
+
if (node.type === "text") return renderText(node, key);
|
|
1538
|
+
if (node.type === "hardBreak") return /* @__PURE__ */ jsx9("br", {}, key);
|
|
1539
|
+
if (node.type === "paragraph") return /* @__PURE__ */ jsx9("p", { children: renderChildren(node) }, key);
|
|
1540
|
+
if (node.type === "heading") {
|
|
1541
|
+
const level = node.attrs?.level;
|
|
1542
|
+
if (level === 3) return /* @__PURE__ */ jsx9("h3", { children: renderChildren(node) }, key);
|
|
1543
|
+
return /* @__PURE__ */ jsx9("h2", { children: renderChildren(node) }, key);
|
|
1544
|
+
}
|
|
1545
|
+
if (node.type === "bulletList") return /* @__PURE__ */ jsx9("ul", { children: renderChildren(node) }, key);
|
|
1546
|
+
if (node.type === "orderedList") return /* @__PURE__ */ jsx9("ol", { children: renderChildren(node) }, key);
|
|
1547
|
+
if (node.type === "listItem") return /* @__PURE__ */ jsx9("li", { children: renderChildren(node) }, key);
|
|
1548
|
+
if (node.type === "blockquote") return /* @__PURE__ */ jsx9("blockquote", { children: renderChildren(node) }, key);
|
|
1549
|
+
return /* @__PURE__ */ jsx9(Fragment, { children: renderChildren(node) }, key);
|
|
1550
|
+
}
|
|
1551
|
+
function RichTextContent({ className, value }) {
|
|
1552
|
+
const document2 = toRichTextDocument(value);
|
|
1553
|
+
return /* @__PURE__ */ jsx9("div", { className, children: (document2.content ?? []).map((node, index) => renderNode(node, index)) });
|
|
1145
1554
|
}
|
|
1146
1555
|
|
|
1147
1556
|
// src/admin/editorState.ts
|
|
@@ -1189,7 +1598,7 @@ function clampLayoutSpan(span, columns) {
|
|
|
1189
1598
|
return Math.max(1, Math.min(columns, Math.trunc(span)));
|
|
1190
1599
|
}
|
|
1191
1600
|
function builderFormEditorDefaultSpan(field) {
|
|
1192
|
-
if (field.type === "textarea" || field.type === "checkbox") return 12;
|
|
1601
|
+
if (field.type === "textarea" || field.type === "richtext" || field.type === "checkbox") return 12;
|
|
1193
1602
|
return 6;
|
|
1194
1603
|
}
|
|
1195
1604
|
function builderFormEditorDefaultLayoutGroups(fields, subforms = []) {
|
|
@@ -1256,6 +1665,10 @@ function builderFormEditorValuesFromEntity(form, emptyValues) {
|
|
|
1256
1665
|
required: field.required,
|
|
1257
1666
|
hidden: field.hidden ?? false,
|
|
1258
1667
|
disabled: field.disabled ?? false,
|
|
1668
|
+
storage: field.storage ?? "s3",
|
|
1669
|
+
contentKind: field.contentKind ?? "image",
|
|
1670
|
+
multiple: field.multiple ?? false,
|
|
1671
|
+
maxMegabytes: field.maxBytes ? field.maxBytes / (1024 * 1024) : 10,
|
|
1259
1672
|
placeholder: field.placeholder ?? "",
|
|
1260
1673
|
optionsText: builderEditorOptionsToText(field.options),
|
|
1261
1674
|
optionsMode: field.optionsSource?.type === "dbTable" ? "table" : "static",
|
|
@@ -1338,6 +1751,10 @@ function builderFormEditorFieldsFromTable(table) {
|
|
|
1338
1751
|
required: !column.nullable,
|
|
1339
1752
|
hidden: false,
|
|
1340
1753
|
disabled: false,
|
|
1754
|
+
storage: "s3",
|
|
1755
|
+
contentKind: "image",
|
|
1756
|
+
multiple: false,
|
|
1757
|
+
maxMegabytes: 10,
|
|
1341
1758
|
placeholder: column.label,
|
|
1342
1759
|
optionsText: "",
|
|
1343
1760
|
optionsMode: "static",
|
|
@@ -1374,6 +1791,10 @@ function builderFormEditorInputFromValues(values) {
|
|
|
1374
1791
|
required: field.required,
|
|
1375
1792
|
hidden: field.hidden,
|
|
1376
1793
|
disabled: field.disabled,
|
|
1794
|
+
storage: field.type === "file" ? field.storage : void 0,
|
|
1795
|
+
contentKind: field.type === "file" ? field.contentKind : void 0,
|
|
1796
|
+
multiple: field.type === "file" ? field.multiple : void 0,
|
|
1797
|
+
maxBytes: field.type === "file" && typeof field.maxMegabytes === "number" && field.maxMegabytes > 0 ? Math.round(field.maxMegabytes * 1024 * 1024) : void 0,
|
|
1377
1798
|
placeholder: field.placeholder?.trim() || field.label,
|
|
1378
1799
|
options: field.type === "select" && field.optionsMode === "static" ? builderEditorTextToOptions(field.optionsText) : void 0,
|
|
1379
1800
|
optionsSource: field.type === "select" && field.optionsMode === "table" && field.optionsTable !== BUILDER_EDITOR_NONE_VALUE && field.optionsValueField !== BUILDER_EDITOR_NONE_VALUE && field.optionsLabelField !== BUILDER_EDITOR_NONE_VALUE ? {
|
|
@@ -1464,7 +1885,7 @@ function builderViewEditorInputFromValues(values, parseTriggers) {
|
|
|
1464
1885
|
}
|
|
1465
1886
|
|
|
1466
1887
|
// src/admin/BuilderDefaultEditorBodies.tsx
|
|
1467
|
-
import { jsx as
|
|
1888
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1468
1889
|
var styles = {
|
|
1469
1890
|
page: {
|
|
1470
1891
|
display: "grid",
|
|
@@ -1585,7 +2006,7 @@ var styles = {
|
|
|
1585
2006
|
}
|
|
1586
2007
|
};
|
|
1587
2008
|
function optionItems(options) {
|
|
1588
|
-
return options.map((option) => /* @__PURE__ */
|
|
2009
|
+
return options.map((option) => /* @__PURE__ */ jsx10("option", { value: option.value, children: option.label }, option.value));
|
|
1589
2010
|
}
|
|
1590
2011
|
function createBuilderDefaultFormEditorBody(options) {
|
|
1591
2012
|
return function BuilderDefaultFormEditorBody({
|
|
@@ -1603,63 +2024,63 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1603
2024
|
isSaving,
|
|
1604
2025
|
importFieldsFromTable
|
|
1605
2026
|
}) {
|
|
1606
|
-
return /* @__PURE__ */
|
|
1607
|
-
/* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1610
|
-
/* @__PURE__ */
|
|
2027
|
+
return /* @__PURE__ */ jsxs9("div", { style: styles.page, children: [
|
|
2028
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.header, children: [
|
|
2029
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2030
|
+
/* @__PURE__ */ jsx10("h1", { style: styles.title, children: formId ? "Edit Dynamic Form" : "New Dynamic Form" }),
|
|
2031
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Configure fields, source mapping, layout, and triggers." })
|
|
1611
2032
|
] }),
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
/* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
2033
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.actions, children: [
|
|
2034
|
+
/* @__PURE__ */ jsx10("a", { href: options.backHref, style: styles.button, children: "Cancel" }),
|
|
2035
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", disabled: isSaving, style: styles.primaryButton, children: isSaving ? "Saving..." : "Save" })
|
|
1615
2036
|
] })
|
|
1616
2037
|
] }),
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
2038
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2039
|
+
/* @__PURE__ */ jsx10("div", { style: styles.sectionHeader, children: /* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Details" }) }),
|
|
2040
|
+
/* @__PURE__ */ jsxs9("div", { style: { ...styles.grid, ...styles.twoColumn }, children: [
|
|
2041
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2042
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Title" }),
|
|
2043
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("title", { required: true }) })
|
|
1623
2044
|
] }),
|
|
1624
|
-
/* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
2045
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2046
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Description" }),
|
|
2047
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("description") })
|
|
1627
2048
|
] }),
|
|
1628
|
-
/* @__PURE__ */
|
|
1629
|
-
/* @__PURE__ */
|
|
1630
|
-
/* @__PURE__ */
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2050
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Presentation" }),
|
|
2051
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register("presentation"), children: [
|
|
2052
|
+
/* @__PURE__ */ jsx10("option", { value: "dialog", children: "Dialog" }),
|
|
2053
|
+
/* @__PURE__ */ jsx10("option", { value: "drawer", children: "Drawer" })
|
|
1633
2054
|
] })
|
|
1634
2055
|
] }),
|
|
1635
|
-
/* @__PURE__ */
|
|
1636
|
-
/* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
1638
|
-
/* @__PURE__ */
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
/* @__PURE__ */
|
|
2056
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2057
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Datasource" }),
|
|
2058
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register("sourceType"), children: [
|
|
2059
|
+
/* @__PURE__ */ jsx10("option", { value: "none", children: "None" }),
|
|
2060
|
+
/* @__PURE__ */ jsx10("option", { value: "dbTable", children: "DB table" }),
|
|
2061
|
+
/* @__PURE__ */ jsx10("option", { value: "apiEndpoint", children: "API endpoint" })
|
|
1641
2062
|
] })
|
|
1642
2063
|
] }),
|
|
1643
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
1644
|
-
/* @__PURE__ */
|
|
1645
|
-
/* @__PURE__ */
|
|
2064
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2065
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Table" }),
|
|
2066
|
+
/* @__PURE__ */ jsxs9(
|
|
1646
2067
|
"select",
|
|
1647
2068
|
{
|
|
1648
2069
|
style: styles.input,
|
|
1649
2070
|
value: sourceTable,
|
|
1650
2071
|
...form.register("sourceTable"),
|
|
1651
2072
|
children: [
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
tables.map((table) => /* @__PURE__ */
|
|
2073
|
+
/* @__PURE__ */ jsx10("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
|
|
2074
|
+
tables.map((table) => /* @__PURE__ */ jsx10("option", { value: table.name, children: table.label ?? table.name }, table.name))
|
|
1654
2075
|
]
|
|
1655
2076
|
}
|
|
1656
2077
|
)
|
|
1657
2078
|
] }) : null,
|
|
1658
|
-
sourceType === "apiEndpoint" ? /* @__PURE__ */
|
|
1659
|
-
/* @__PURE__ */
|
|
1660
|
-
/* @__PURE__ */
|
|
2079
|
+
sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2080
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "API base path" }),
|
|
2081
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("apiBasePath") })
|
|
1661
2082
|
] }) : null,
|
|
1662
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
2083
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsx10("div", { style: { ...styles.field, justifyContent: "end" }, children: /* @__PURE__ */ jsx10(
|
|
1663
2084
|
"button",
|
|
1664
2085
|
{
|
|
1665
2086
|
type: "button",
|
|
@@ -1671,13 +2092,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1671
2092
|
) }) : null
|
|
1672
2093
|
] })
|
|
1673
2094
|
] }),
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
1676
|
-
/* @__PURE__ */
|
|
1677
|
-
/* @__PURE__ */
|
|
1678
|
-
/* @__PURE__ */
|
|
2095
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2096
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2097
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2098
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Fields" }),
|
|
2099
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Runtime form inputs." })
|
|
1679
2100
|
] }),
|
|
1680
|
-
/* @__PURE__ */
|
|
2101
|
+
/* @__PURE__ */ jsx10(
|
|
1681
2102
|
"button",
|
|
1682
2103
|
{
|
|
1683
2104
|
type: "button",
|
|
@@ -1695,18 +2116,18 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1695
2116
|
}
|
|
1696
2117
|
)
|
|
1697
2118
|
] }),
|
|
1698
|
-
fieldArray.fields.map((field, index) => /* @__PURE__ */
|
|
1699
|
-
/* @__PURE__ */
|
|
1700
|
-
/* @__PURE__ */
|
|
1701
|
-
/* @__PURE__ */
|
|
2119
|
+
fieldArray.fields.map((field, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2120
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2121
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Key" }),
|
|
2122
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`fields.${index}.key`) })
|
|
1702
2123
|
] }),
|
|
1703
|
-
/* @__PURE__ */
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
/* @__PURE__ */
|
|
2124
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2125
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Label" }),
|
|
2126
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`fields.${index}.label`) })
|
|
1706
2127
|
] }),
|
|
1707
|
-
/* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
/* @__PURE__ */
|
|
2128
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2129
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Type" }),
|
|
2130
|
+
/* @__PURE__ */ jsx10(
|
|
1710
2131
|
"select",
|
|
1711
2132
|
{
|
|
1712
2133
|
style: styles.input,
|
|
@@ -1715,27 +2136,51 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1715
2136
|
}
|
|
1716
2137
|
)
|
|
1717
2138
|
] }),
|
|
1718
|
-
/* @__PURE__ */
|
|
1719
|
-
/* @__PURE__ */
|
|
2139
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2140
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`fields.${index}.required`) }),
|
|
1720
2141
|
"Required"
|
|
1721
2142
|
] }),
|
|
1722
|
-
/* @__PURE__ */
|
|
1723
|
-
/* @__PURE__ */
|
|
2143
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2144
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`fields.${index}.hidden`) }),
|
|
1724
2145
|
"Hidden"
|
|
1725
2146
|
] }),
|
|
1726
|
-
/* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
2147
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2148
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`fields.${index}.disabled`) }),
|
|
1728
2149
|
"Disabled"
|
|
1729
2150
|
] }),
|
|
1730
|
-
/* @__PURE__ */
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
|
|
2151
|
+
fields[index]?.type === "file" ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
2152
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2153
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Storage" }),
|
|
2154
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register(`fields.${index}.storage`), children: [
|
|
2155
|
+
/* @__PURE__ */ jsx10("option", { value: "s3", children: "S3" }),
|
|
2156
|
+
/* @__PURE__ */ jsx10("option", { value: "server", children: "Server" })
|
|
2157
|
+
] })
|
|
2158
|
+
] }),
|
|
2159
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2160
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Content type" }),
|
|
2161
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register(`fields.${index}.contentKind`), children: [
|
|
2162
|
+
/* @__PURE__ */ jsx10("option", { value: "image", children: "Image" }),
|
|
2163
|
+
/* @__PURE__ */ jsx10("option", { value: "file", children: "File" })
|
|
2164
|
+
] })
|
|
2165
|
+
] }),
|
|
2166
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2167
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`fields.${index}.multiple`) }),
|
|
2168
|
+
"Multiple"
|
|
2169
|
+
] }),
|
|
2170
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2171
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Max size (MB)" }),
|
|
2172
|
+
/* @__PURE__ */ jsx10("input", { type: "number", min: "1", max: "100", style: styles.input, ...form.register(`fields.${index}.maxMegabytes`, { valueAsNumber: true }) })
|
|
2173
|
+
] })
|
|
2174
|
+
] }) : null,
|
|
2175
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2176
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Placeholder" }),
|
|
2177
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`fields.${index}.placeholder`) })
|
|
1733
2178
|
] }),
|
|
1734
|
-
/* @__PURE__ */
|
|
1735
|
-
/* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
2179
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2180
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Static options" }),
|
|
2181
|
+
/* @__PURE__ */ jsx10("textarea", { style: styles.textarea, ...form.register(`fields.${index}.optionsText`) })
|
|
1737
2182
|
] }),
|
|
1738
|
-
/* @__PURE__ */
|
|
2183
|
+
/* @__PURE__ */ jsx10("div", { style: styles.actions, children: /* @__PURE__ */ jsx10(
|
|
1739
2184
|
"button",
|
|
1740
2185
|
{
|
|
1741
2186
|
type: "button",
|
|
@@ -1747,13 +2192,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1747
2192
|
) })
|
|
1748
2193
|
] }, field.id))
|
|
1749
2194
|
] }),
|
|
1750
|
-
/* @__PURE__ */
|
|
1751
|
-
/* @__PURE__ */
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
/* @__PURE__ */
|
|
1754
|
-
/* @__PURE__ */
|
|
2195
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2196
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2197
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2198
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Layout" }),
|
|
2199
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Default layout can be regenerated from current fields." })
|
|
1755
2200
|
] }),
|
|
1756
|
-
/* @__PURE__ */
|
|
2201
|
+
/* @__PURE__ */ jsx10(
|
|
1757
2202
|
"button",
|
|
1758
2203
|
{
|
|
1759
2204
|
type: "button",
|
|
@@ -1765,14 +2210,14 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1765
2210
|
}
|
|
1766
2211
|
)
|
|
1767
2212
|
] }),
|
|
1768
|
-
form.watch("layoutGroups").map((group, groupIndex) => /* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
1770
|
-
/* @__PURE__ */
|
|
1771
|
-
/* @__PURE__ */
|
|
2213
|
+
form.watch("layoutGroups").map((group, groupIndex) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2214
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2215
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Group title" }),
|
|
2216
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`layoutGroups.${groupIndex}.title`) })
|
|
1772
2217
|
] }),
|
|
1773
|
-
/* @__PURE__ */
|
|
1774
|
-
/* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
2218
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2219
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Columns" }),
|
|
2220
|
+
/* @__PURE__ */ jsxs9(
|
|
1776
2221
|
"select",
|
|
1777
2222
|
{
|
|
1778
2223
|
style: styles.input,
|
|
@@ -1783,16 +2228,16 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1783
2228
|
{ shouldDirty: true }
|
|
1784
2229
|
),
|
|
1785
2230
|
children: [
|
|
1786
|
-
/* @__PURE__ */
|
|
1787
|
-
/* @__PURE__ */
|
|
1788
|
-
/* @__PURE__ */
|
|
2231
|
+
/* @__PURE__ */ jsx10("option", { value: 6, children: "6" }),
|
|
2232
|
+
/* @__PURE__ */ jsx10("option", { value: 8, children: "8" }),
|
|
2233
|
+
/* @__PURE__ */ jsx10("option", { value: 12, children: "12" })
|
|
1789
2234
|
]
|
|
1790
2235
|
}
|
|
1791
2236
|
)
|
|
1792
2237
|
] }),
|
|
1793
|
-
/* @__PURE__ */
|
|
1794
|
-
/* @__PURE__ */
|
|
1795
|
-
/* @__PURE__ */
|
|
2238
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2239
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Fields" }),
|
|
2240
|
+
/* @__PURE__ */ jsx10(
|
|
1796
2241
|
"input",
|
|
1797
2242
|
{
|
|
1798
2243
|
style: styles.input,
|
|
@@ -1803,13 +2248,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1803
2248
|
] })
|
|
1804
2249
|
] }, group.id))
|
|
1805
2250
|
] }),
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
1808
|
-
/* @__PURE__ */
|
|
1809
|
-
/* @__PURE__ */
|
|
1810
|
-
/* @__PURE__ */
|
|
2251
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2252
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2253
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2254
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Subforms" }),
|
|
2255
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Optional nested runtime view bindings." })
|
|
1811
2256
|
] }),
|
|
1812
|
-
/* @__PURE__ */
|
|
2257
|
+
/* @__PURE__ */ jsx10(
|
|
1813
2258
|
"button",
|
|
1814
2259
|
{
|
|
1815
2260
|
type: "button",
|
|
@@ -1828,56 +2273,56 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1828
2273
|
}
|
|
1829
2274
|
)
|
|
1830
2275
|
] }),
|
|
1831
|
-
subformArray.fields.map((subform, index) => /* @__PURE__ */
|
|
1832
|
-
/* @__PURE__ */
|
|
1833
|
-
/* @__PURE__ */
|
|
1834
|
-
/* @__PURE__ */
|
|
2276
|
+
subformArray.fields.map((subform, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2277
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2278
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Key" }),
|
|
2279
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`subforms.${index}.key`) })
|
|
1835
2280
|
] }),
|
|
1836
|
-
/* @__PURE__ */
|
|
1837
|
-
/* @__PURE__ */
|
|
1838
|
-
/* @__PURE__ */
|
|
2281
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2282
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Label" }),
|
|
2283
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`subforms.${index}.label`) })
|
|
1839
2284
|
] }),
|
|
1840
|
-
/* @__PURE__ */
|
|
1841
|
-
/* @__PURE__ */
|
|
1842
|
-
/* @__PURE__ */
|
|
2285
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2286
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "View ID" }),
|
|
2287
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`subforms.${index}.viewId`) })
|
|
1843
2288
|
] }),
|
|
1844
|
-
/* @__PURE__ */
|
|
1845
|
-
/* @__PURE__ */
|
|
1846
|
-
/* @__PURE__ */
|
|
2289
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2290
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Parent field" }),
|
|
2291
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`subforms.${index}.parentField`) })
|
|
1847
2292
|
] }),
|
|
1848
|
-
/* @__PURE__ */
|
|
1849
|
-
/* @__PURE__ */
|
|
1850
|
-
/* @__PURE__ */
|
|
2293
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2294
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Child field" }),
|
|
2295
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`subforms.${index}.childField`) })
|
|
1851
2296
|
] }),
|
|
1852
|
-
/* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
2297
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2298
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Presentation" }),
|
|
2299
|
+
/* @__PURE__ */ jsxs9(
|
|
1855
2300
|
"select",
|
|
1856
2301
|
{
|
|
1857
2302
|
style: styles.input,
|
|
1858
2303
|
...form.register(`subforms.${index}.presentation`),
|
|
1859
2304
|
children: [
|
|
1860
|
-
/* @__PURE__ */
|
|
1861
|
-
/* @__PURE__ */
|
|
2305
|
+
/* @__PURE__ */ jsx10("option", { value: "dialog", children: "Dialog" }),
|
|
2306
|
+
/* @__PURE__ */ jsx10("option", { value: "drawer", children: "Drawer" })
|
|
1862
2307
|
]
|
|
1863
2308
|
}
|
|
1864
2309
|
)
|
|
1865
2310
|
] }),
|
|
1866
|
-
/* @__PURE__ */
|
|
2311
|
+
/* @__PURE__ */ jsx10("button", { type: "button", style: styles.button, onClick: () => subformArray.remove(index), children: "Remove" })
|
|
1867
2312
|
] }, subform.id))
|
|
1868
2313
|
] }),
|
|
1869
|
-
/* @__PURE__ */
|
|
1870
|
-
/* @__PURE__ */
|
|
1871
|
-
/* @__PURE__ */
|
|
1872
|
-
/* @__PURE__ */
|
|
1873
|
-
/* @__PURE__ */
|
|
2314
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2315
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2316
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2317
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Form Triggers" }),
|
|
2318
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Optional API callbacks for lifecycle events." })
|
|
1874
2319
|
] }),
|
|
1875
|
-
/* @__PURE__ */
|
|
2320
|
+
/* @__PURE__ */ jsx10("button", { type: "button", style: styles.button, onClick: () => triggerArray.append(emptyTrigger), children: "Add trigger" })
|
|
1876
2321
|
] }),
|
|
1877
|
-
triggerArray.fields.map((trigger, index) => /* @__PURE__ */
|
|
1878
|
-
/* @__PURE__ */
|
|
1879
|
-
/* @__PURE__ */
|
|
1880
|
-
/* @__PURE__ */
|
|
2322
|
+
triggerArray.fields.map((trigger, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2323
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2324
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Event" }),
|
|
2325
|
+
/* @__PURE__ */ jsx10(
|
|
1881
2326
|
"select",
|
|
1882
2327
|
{
|
|
1883
2328
|
style: styles.input,
|
|
@@ -1888,19 +2333,19 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
1888
2333
|
}
|
|
1889
2334
|
)
|
|
1890
2335
|
] }),
|
|
1891
|
-
/* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
2336
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2337
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Route" }),
|
|
2338
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`triggers.${index}.route`) })
|
|
1894
2339
|
] }),
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
2340
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2341
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`triggers.${index}.enabled`) }),
|
|
1897
2342
|
"Enabled"
|
|
1898
2343
|
] }),
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
/* @__PURE__ */
|
|
2344
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2345
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`triggers.${index}.blocking`) }),
|
|
1901
2346
|
"Blocking"
|
|
1902
2347
|
] }),
|
|
1903
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ jsx10("button", { type: "button", style: styles.button, onClick: () => triggerArray.remove(index), children: "Remove" })
|
|
1904
2349
|
] }, trigger.id))
|
|
1905
2350
|
] })
|
|
1906
2351
|
] });
|
|
@@ -1923,56 +2368,56 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
1923
2368
|
}) {
|
|
1924
2369
|
const selectedTable = tables.find((table) => table.name === sourceTable);
|
|
1925
2370
|
const orderByColumns = selectedTable?.columns.filter((column) => column.sortable) ?? [];
|
|
1926
|
-
return /* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
1929
|
-
/* @__PURE__ */
|
|
1930
|
-
/* @__PURE__ */
|
|
2371
|
+
return /* @__PURE__ */ jsxs9("div", { style: styles.page, children: [
|
|
2372
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.header, children: [
|
|
2373
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2374
|
+
/* @__PURE__ */ jsx10("h1", { style: styles.title, children: listId ? "Edit Dynamic List" : "New Dynamic List" }),
|
|
2375
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Configure list columns, source mapping, and triggers." })
|
|
1931
2376
|
] }),
|
|
1932
|
-
/* @__PURE__ */
|
|
1933
|
-
/* @__PURE__ */
|
|
1934
|
-
/* @__PURE__ */
|
|
2377
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.actions, children: [
|
|
2378
|
+
/* @__PURE__ */ jsx10("a", { href: options.backHref, style: styles.button, children: "Cancel" }),
|
|
2379
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", disabled: isSaving, style: styles.primaryButton, children: isSaving ? "Saving..." : "Save" })
|
|
1935
2380
|
] })
|
|
1936
2381
|
] }),
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
1940
|
-
/* @__PURE__ */
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
2382
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2383
|
+
/* @__PURE__ */ jsx10("div", { style: styles.sectionHeader, children: /* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Details" }) }),
|
|
2384
|
+
/* @__PURE__ */ jsxs9("div", { style: { ...styles.grid, ...styles.twoColumn }, children: [
|
|
2385
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2386
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Title" }),
|
|
2387
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("title", { required: true }) })
|
|
1943
2388
|
] }),
|
|
1944
|
-
/* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
2389
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2390
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Description" }),
|
|
2391
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("description") })
|
|
1947
2392
|
] }),
|
|
1948
|
-
/* @__PURE__ */
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
/* @__PURE__ */
|
|
1952
|
-
/* @__PURE__ */
|
|
1953
|
-
/* @__PURE__ */
|
|
2393
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2394
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Datasource" }),
|
|
2395
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register("sourceType"), children: [
|
|
2396
|
+
/* @__PURE__ */ jsx10("option", { value: "none", children: "None" }),
|
|
2397
|
+
/* @__PURE__ */ jsx10("option", { value: "dbTable", children: "DB table" }),
|
|
2398
|
+
/* @__PURE__ */ jsx10("option", { value: "apiEndpoint", children: "API endpoint" })
|
|
1954
2399
|
] })
|
|
1955
2400
|
] }),
|
|
1956
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
1957
|
-
/* @__PURE__ */
|
|
1958
|
-
/* @__PURE__ */
|
|
2401
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2402
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Table" }),
|
|
2403
|
+
/* @__PURE__ */ jsxs9(
|
|
1959
2404
|
"select",
|
|
1960
2405
|
{
|
|
1961
2406
|
style: styles.input,
|
|
1962
2407
|
value: sourceTable,
|
|
1963
2408
|
...form.register("sourceTable"),
|
|
1964
2409
|
children: [
|
|
1965
|
-
/* @__PURE__ */
|
|
1966
|
-
tables.map((table) => /* @__PURE__ */
|
|
2410
|
+
/* @__PURE__ */ jsx10("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
|
|
2411
|
+
tables.map((table) => /* @__PURE__ */ jsx10("option", { value: table.name, children: table.label ?? table.name }, table.name))
|
|
1967
2412
|
]
|
|
1968
2413
|
}
|
|
1969
2414
|
)
|
|
1970
2415
|
] }) : null,
|
|
1971
|
-
sourceType === "apiEndpoint" ? /* @__PURE__ */
|
|
1972
|
-
/* @__PURE__ */
|
|
1973
|
-
/* @__PURE__ */
|
|
2416
|
+
sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2417
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "API base path" }),
|
|
2418
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register("apiBasePath") })
|
|
1974
2419
|
] }) : null,
|
|
1975
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
2420
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsx10("div", { style: { ...styles.field, justifyContent: "end" }, children: /* @__PURE__ */ jsx10(
|
|
1976
2421
|
"button",
|
|
1977
2422
|
{
|
|
1978
2423
|
type: "button",
|
|
@@ -1984,13 +2429,13 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
1984
2429
|
) }) : null
|
|
1985
2430
|
] })
|
|
1986
2431
|
] }),
|
|
1987
|
-
/* @__PURE__ */
|
|
1988
|
-
/* @__PURE__ */
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
/* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
2432
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2433
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2434
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2435
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Default ordering" }),
|
|
2436
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Rules are applied from top to bottom." })
|
|
1992
2437
|
] }),
|
|
1993
|
-
/* @__PURE__ */
|
|
2438
|
+
/* @__PURE__ */ jsx10(
|
|
1994
2439
|
"button",
|
|
1995
2440
|
{
|
|
1996
2441
|
type: "button",
|
|
@@ -2004,17 +2449,17 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2004
2449
|
}
|
|
2005
2450
|
)
|
|
2006
2451
|
] }),
|
|
2007
|
-
orderByArray.fields.length === 0 ? /* @__PURE__ */
|
|
2008
|
-
orderByArray.fields.map((rule, index) => /* @__PURE__ */
|
|
2009
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
2010
|
-
/* @__PURE__ */
|
|
2011
|
-
/* @__PURE__ */
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
orderByColumns.map((column) => /* @__PURE__ */
|
|
2452
|
+
orderByArray.fields.length === 0 ? /* @__PURE__ */ jsx10("div", { style: styles.grid, children: /* @__PURE__ */ jsx10("p", { style: styles.description, children: "Automatic ordering is used." }) }) : null,
|
|
2453
|
+
orderByArray.fields.map((rule, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2454
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2455
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Order by field" }),
|
|
2456
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register(`orderBy.${index}.field`), children: [
|
|
2457
|
+
/* @__PURE__ */ jsx10("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select field" }),
|
|
2458
|
+
orderByColumns.map((column) => /* @__PURE__ */ jsx10("option", { value: column.name, children: column.label }, column.name))
|
|
2014
2459
|
] })
|
|
2015
|
-
] }) : /* @__PURE__ */
|
|
2016
|
-
/* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2460
|
+
] }) : /* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2461
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Order by field" }),
|
|
2462
|
+
/* @__PURE__ */ jsx10(
|
|
2018
2463
|
"input",
|
|
2019
2464
|
{
|
|
2020
2465
|
style: styles.input,
|
|
@@ -2023,15 +2468,15 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2023
2468
|
}
|
|
2024
2469
|
)
|
|
2025
2470
|
] }),
|
|
2026
|
-
/* @__PURE__ */
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
/* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
/* @__PURE__ */
|
|
2471
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2472
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Direction" }),
|
|
2473
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register(`orderBy.${index}.direction`), children: [
|
|
2474
|
+
/* @__PURE__ */ jsx10("option", { value: "asc", children: "Ascending" }),
|
|
2475
|
+
/* @__PURE__ */ jsx10("option", { value: "desc", children: "Descending" })
|
|
2031
2476
|
] })
|
|
2032
2477
|
] }),
|
|
2033
|
-
/* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2478
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.actions, children: [
|
|
2479
|
+
/* @__PURE__ */ jsx10(
|
|
2035
2480
|
"button",
|
|
2036
2481
|
{
|
|
2037
2482
|
type: "button",
|
|
@@ -2041,7 +2486,7 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2041
2486
|
children: "Move up"
|
|
2042
2487
|
}
|
|
2043
2488
|
),
|
|
2044
|
-
/* @__PURE__ */
|
|
2489
|
+
/* @__PURE__ */ jsx10(
|
|
2045
2490
|
"button",
|
|
2046
2491
|
{
|
|
2047
2492
|
type: "button",
|
|
@@ -2051,7 +2496,7 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2051
2496
|
children: "Move down"
|
|
2052
2497
|
}
|
|
2053
2498
|
),
|
|
2054
|
-
/* @__PURE__ */
|
|
2499
|
+
/* @__PURE__ */ jsx10(
|
|
2055
2500
|
"button",
|
|
2056
2501
|
{
|
|
2057
2502
|
type: "button",
|
|
@@ -2063,13 +2508,13 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2063
2508
|
] })
|
|
2064
2509
|
] }, rule.id))
|
|
2065
2510
|
] }),
|
|
2066
|
-
/* @__PURE__ */
|
|
2067
|
-
/* @__PURE__ */
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2070
|
-
/* @__PURE__ */
|
|
2511
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2512
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2513
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2514
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "Columns" }),
|
|
2515
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Runtime list columns." })
|
|
2071
2516
|
] }),
|
|
2072
|
-
/* @__PURE__ */
|
|
2517
|
+
/* @__PURE__ */ jsx10(
|
|
2073
2518
|
"button",
|
|
2074
2519
|
{
|
|
2075
2520
|
type: "button",
|
|
@@ -2083,44 +2528,44 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2083
2528
|
}
|
|
2084
2529
|
)
|
|
2085
2530
|
] }),
|
|
2086
|
-
columnArray.fields.map((column, index) => /* @__PURE__ */
|
|
2087
|
-
/* @__PURE__ */
|
|
2088
|
-
/* @__PURE__ */
|
|
2089
|
-
/* @__PURE__ */
|
|
2531
|
+
columnArray.fields.map((column, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2532
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2533
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Key" }),
|
|
2534
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`columns.${index}.key`) })
|
|
2090
2535
|
] }),
|
|
2091
|
-
/* @__PURE__ */
|
|
2092
|
-
/* @__PURE__ */
|
|
2093
|
-
/* @__PURE__ */
|
|
2536
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2537
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Label" }),
|
|
2538
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`columns.${index}.label`) })
|
|
2094
2539
|
] }),
|
|
2095
|
-
/* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2097
|
-
/* @__PURE__ */
|
|
2098
|
-
/* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2540
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2541
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Align" }),
|
|
2542
|
+
/* @__PURE__ */ jsxs9("select", { style: styles.input, ...form.register(`columns.${index}.align`), children: [
|
|
2543
|
+
/* @__PURE__ */ jsx10("option", { value: "left", children: "Left" }),
|
|
2544
|
+
/* @__PURE__ */ jsx10("option", { value: "right", children: "Right" })
|
|
2100
2545
|
] })
|
|
2101
2546
|
] }),
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2547
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2548
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`columns.${index}.sortable`) }),
|
|
2104
2549
|
"Sortable"
|
|
2105
2550
|
] }),
|
|
2106
|
-
/* @__PURE__ */
|
|
2107
|
-
/* @__PURE__ */
|
|
2551
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2552
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`columns.${index}.hidden`) }),
|
|
2108
2553
|
"Hidden"
|
|
2109
2554
|
] })
|
|
2110
2555
|
] }, column.id))
|
|
2111
2556
|
] }),
|
|
2112
|
-
/* @__PURE__ */
|
|
2113
|
-
/* @__PURE__ */
|
|
2114
|
-
/* @__PURE__ */
|
|
2115
|
-
/* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2557
|
+
/* @__PURE__ */ jsxs9("section", { style: styles.section, children: [
|
|
2558
|
+
/* @__PURE__ */ jsxs9("div", { style: styles.sectionHeader, children: [
|
|
2559
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2560
|
+
/* @__PURE__ */ jsx10("h2", { style: styles.sectionTitle, children: "List Triggers" }),
|
|
2561
|
+
/* @__PURE__ */ jsx10("p", { style: styles.description, children: "Optional API callbacks for list lifecycle events." })
|
|
2117
2562
|
] }),
|
|
2118
|
-
/* @__PURE__ */
|
|
2563
|
+
/* @__PURE__ */ jsx10("button", { type: "button", style: styles.button, onClick: () => triggerArray.append(emptyTrigger), children: "Add trigger" })
|
|
2119
2564
|
] }),
|
|
2120
|
-
triggerArray.fields.map((trigger, index) => /* @__PURE__ */
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
2123
|
-
/* @__PURE__ */
|
|
2565
|
+
triggerArray.fields.map((trigger, index) => /* @__PURE__ */ jsxs9("div", { style: styles.row, children: [
|
|
2566
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2567
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Event" }),
|
|
2568
|
+
/* @__PURE__ */ jsx10(
|
|
2124
2569
|
"select",
|
|
2125
2570
|
{
|
|
2126
2571
|
style: styles.input,
|
|
@@ -2131,19 +2576,19 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2131
2576
|
}
|
|
2132
2577
|
)
|
|
2133
2578
|
] }),
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
2579
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.field, children: [
|
|
2580
|
+
/* @__PURE__ */ jsx10("span", { style: styles.label, children: "Route" }),
|
|
2581
|
+
/* @__PURE__ */ jsx10("input", { style: styles.input, ...form.register(`triggers.${index}.route`) })
|
|
2137
2582
|
] }),
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2583
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2584
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`triggers.${index}.enabled`) }),
|
|
2140
2585
|
"Enabled"
|
|
2141
2586
|
] }),
|
|
2142
|
-
/* @__PURE__ */
|
|
2143
|
-
/* @__PURE__ */
|
|
2587
|
+
/* @__PURE__ */ jsxs9("label", { style: styles.checkboxField, children: [
|
|
2588
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", ...form.register(`triggers.${index}.blocking`) }),
|
|
2144
2589
|
"Blocking"
|
|
2145
2590
|
] }),
|
|
2146
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ jsx10("button", { type: "button", style: styles.button, onClick: () => triggerArray.remove(index), children: "Remove" })
|
|
2147
2592
|
] }, trigger.id))
|
|
2148
2593
|
] })
|
|
2149
2594
|
] });
|
|
@@ -2151,8 +2596,8 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
2151
2596
|
}
|
|
2152
2597
|
|
|
2153
2598
|
// src/admin/BuilderDefaultEntityManager.tsx
|
|
2154
|
-
import { useMemo as useMemo5, useState as
|
|
2155
|
-
import { jsx as
|
|
2599
|
+
import { useMemo as useMemo5, useState as useState7 } from "react";
|
|
2600
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2156
2601
|
var styles2 = {
|
|
2157
2602
|
page: {
|
|
2158
2603
|
display: "grid",
|
|
@@ -2248,7 +2693,7 @@ var styles2 = {
|
|
|
2248
2693
|
};
|
|
2249
2694
|
function createBuilderDefaultEntityManagerComponent(deps) {
|
|
2250
2695
|
return function BuilderDefaultEntityManager() {
|
|
2251
|
-
const [state, setState] =
|
|
2696
|
+
const [state, setState] = useState7({
|
|
2252
2697
|
page: 1,
|
|
2253
2698
|
pageSize: 20,
|
|
2254
2699
|
search: ""
|
|
@@ -2269,16 +2714,16 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
2269
2714
|
if (!window.confirm(deps.labels.deleteConfirm(entity))) return;
|
|
2270
2715
|
await remove.mutateAsync(entity.id);
|
|
2271
2716
|
};
|
|
2272
|
-
return /* @__PURE__ */
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2717
|
+
return /* @__PURE__ */ jsxs10("section", { style: styles2.page, children: [
|
|
2718
|
+
/* @__PURE__ */ jsxs10("div", { style: styles2.header, children: [
|
|
2719
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
2720
|
+
/* @__PURE__ */ jsx11("h1", { style: styles2.title, children: deps.labels.title }),
|
|
2721
|
+
/* @__PURE__ */ jsx11("p", { style: styles2.description, children: deps.labels.description })
|
|
2277
2722
|
] }),
|
|
2278
|
-
deps.createHref ? /* @__PURE__ */
|
|
2723
|
+
deps.createHref ? /* @__PURE__ */ jsx11("a", { href: deps.createHref, style: styles2.primaryButton, children: deps.labels.addLabel }) : null
|
|
2279
2724
|
] }),
|
|
2280
|
-
/* @__PURE__ */
|
|
2281
|
-
/* @__PURE__ */
|
|
2725
|
+
/* @__PURE__ */ jsxs10("div", { style: styles2.card, children: [
|
|
2726
|
+
/* @__PURE__ */ jsx11("div", { style: styles2.toolbar, children: /* @__PURE__ */ jsx11(
|
|
2282
2727
|
"input",
|
|
2283
2728
|
{
|
|
2284
2729
|
style: styles2.input,
|
|
@@ -2287,21 +2732,21 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
2287
2732
|
onChange: (event) => setState((current) => ({ ...current, page: 1, search: event.target.value }))
|
|
2288
2733
|
}
|
|
2289
2734
|
) }),
|
|
2290
|
-
/* @__PURE__ */
|
|
2291
|
-
/* @__PURE__ */
|
|
2292
|
-
/* @__PURE__ */
|
|
2293
|
-
/* @__PURE__ */
|
|
2294
|
-
/* @__PURE__ */
|
|
2295
|
-
/* @__PURE__ */
|
|
2735
|
+
/* @__PURE__ */ jsx11("div", { style: styles2.tableWrap, children: /* @__PURE__ */ jsxs10("table", { style: styles2.table, children: [
|
|
2736
|
+
/* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
|
|
2737
|
+
/* @__PURE__ */ jsx11("th", { style: styles2.th, children: deps.labels.title }),
|
|
2738
|
+
/* @__PURE__ */ jsx11("th", { style: styles2.th, children: "Detail" }),
|
|
2739
|
+
/* @__PURE__ */ jsx11("th", { style: styles2.th, children: "Description" }),
|
|
2740
|
+
/* @__PURE__ */ jsx11("th", { style: { ...styles2.th, textAlign: "right" }, children: "Actions" })
|
|
2296
2741
|
] }) }),
|
|
2297
|
-
/* @__PURE__ */
|
|
2298
|
-
/* @__PURE__ */
|
|
2299
|
-
/* @__PURE__ */
|
|
2300
|
-
/* @__PURE__ */
|
|
2301
|
-
/* @__PURE__ */
|
|
2302
|
-
deps.runtimeHref ? /* @__PURE__ */
|
|
2303
|
-
/* @__PURE__ */
|
|
2304
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ jsx11("tbody", { children: items.map((entity) => /* @__PURE__ */ jsxs10("tr", { children: [
|
|
2743
|
+
/* @__PURE__ */ jsx11("td", { style: styles2.td, children: /* @__PURE__ */ jsx11("a", { href: deps.editHref(entity), children: entity.title }) }),
|
|
2744
|
+
/* @__PURE__ */ jsx11("td", { style: styles2.td, children: deps.getDetail?.(entity) ?? "-" }),
|
|
2745
|
+
/* @__PURE__ */ jsx11("td", { style: styles2.td, children: entity.description || "-" }),
|
|
2746
|
+
/* @__PURE__ */ jsx11("td", { style: styles2.td, children: /* @__PURE__ */ jsxs10("div", { style: styles2.actions, children: [
|
|
2747
|
+
deps.runtimeHref ? /* @__PURE__ */ jsx11("a", { href: deps.runtimeHref(entity), style: styles2.button, children: deps.labels.runtimeLabel }) : null,
|
|
2748
|
+
/* @__PURE__ */ jsx11("a", { href: deps.editHref(entity), style: styles2.button, children: deps.labels.editLabel }),
|
|
2749
|
+
/* @__PURE__ */ jsx11(
|
|
2305
2750
|
"button",
|
|
2306
2751
|
{
|
|
2307
2752
|
type: "button",
|
|
@@ -2310,7 +2755,7 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
2310
2755
|
children: deps.labels.replicateLabel
|
|
2311
2756
|
}
|
|
2312
2757
|
),
|
|
2313
|
-
/* @__PURE__ */
|
|
2758
|
+
/* @__PURE__ */ jsx11(
|
|
2314
2759
|
"button",
|
|
2315
2760
|
{
|
|
2316
2761
|
type: "button",
|
|
@@ -2323,11 +2768,11 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
2323
2768
|
] }) })
|
|
2324
2769
|
] }, entity.id)) })
|
|
2325
2770
|
] }) }),
|
|
2326
|
-
query.isPending ? /* @__PURE__ */
|
|
2327
|
-
query.isError ? /* @__PURE__ */
|
|
2328
|
-
!query.isPending && !query.isError && items.length === 0 ? /* @__PURE__ */
|
|
2329
|
-
/* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2771
|
+
query.isPending ? /* @__PURE__ */ jsx11("div", { style: styles2.empty, children: "Loading..." }) : null,
|
|
2772
|
+
query.isError ? /* @__PURE__ */ jsx11("div", { style: styles2.empty, children: "Failed to load." }) : null,
|
|
2773
|
+
!query.isPending && !query.isError && items.length === 0 ? /* @__PURE__ */ jsxs10("div", { style: styles2.empty, children: [
|
|
2774
|
+
/* @__PURE__ */ jsx11("strong", { children: deps.labels.emptyTitle }),
|
|
2775
|
+
/* @__PURE__ */ jsx11("div", { children: deps.labels.emptyDescription })
|
|
2331
2776
|
] }) : null
|
|
2332
2777
|
] })
|
|
2333
2778
|
] });
|
|
@@ -2335,9 +2780,9 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
2335
2780
|
}
|
|
2336
2781
|
|
|
2337
2782
|
// src/admin/BuilderDefaultViewEditorPage.tsx
|
|
2338
|
-
import { useEffect as
|
|
2783
|
+
import { useEffect as useEffect4 } from "react";
|
|
2339
2784
|
import { useForm as useForm3 } from "react-hook-form";
|
|
2340
|
-
import { Fragment, jsx as
|
|
2785
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2341
2786
|
var styles3 = {
|
|
2342
2787
|
page: {
|
|
2343
2788
|
display: "grid",
|
|
@@ -2454,7 +2899,7 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
2454
2899
|
permissionWrite: defaultPermission
|
|
2455
2900
|
}
|
|
2456
2901
|
});
|
|
2457
|
-
|
|
2902
|
+
useEffect4(() => {
|
|
2458
2903
|
if (viewId && !view.data) return;
|
|
2459
2904
|
form.reset(
|
|
2460
2905
|
builderViewEditorValuesFromEntity(
|
|
@@ -2485,64 +2930,64 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
2485
2930
|
}
|
|
2486
2931
|
});
|
|
2487
2932
|
if (viewId && view.isPending) {
|
|
2488
|
-
return /* @__PURE__ */
|
|
2933
|
+
return /* @__PURE__ */ jsx12("div", { style: styles3.state, children: "Loading..." });
|
|
2489
2934
|
}
|
|
2490
2935
|
if (viewId && view.isError) {
|
|
2491
|
-
return /* @__PURE__ */
|
|
2936
|
+
return /* @__PURE__ */ jsx12("div", { style: styles3.state, children: "Failed to load view." });
|
|
2492
2937
|
}
|
|
2493
|
-
return /* @__PURE__ */
|
|
2494
|
-
/* @__PURE__ */
|
|
2495
|
-
/* @__PURE__ */
|
|
2496
|
-
/* @__PURE__ */
|
|
2497
|
-
/* @__PURE__ */
|
|
2938
|
+
return /* @__PURE__ */ jsxs11("form", { onSubmit, noValidate: true, style: styles3.page, children: [
|
|
2939
|
+
/* @__PURE__ */ jsxs11("div", { style: styles3.header, children: [
|
|
2940
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
2941
|
+
/* @__PURE__ */ jsx12("h1", { style: styles3.title, children: viewId ? "Edit Dynamic View" : "New Dynamic View" }),
|
|
2942
|
+
/* @__PURE__ */ jsx12("p", { style: styles3.description, children: "Connect a form and list into a runtime screen." })
|
|
2498
2943
|
] }),
|
|
2499
|
-
/* @__PURE__ */
|
|
2500
|
-
/* @__PURE__ */
|
|
2501
|
-
/* @__PURE__ */
|
|
2944
|
+
/* @__PURE__ */ jsxs11("div", { style: styles3.actions, children: [
|
|
2945
|
+
/* @__PURE__ */ jsx12("a", { href: options.backHref, style: styles3.button, children: "Cancel" }),
|
|
2946
|
+
/* @__PURE__ */ jsx12("button", { type: "submit", disabled: save.isPending, style: styles3.primaryButton, children: save.isPending ? "Saving..." : "Save" })
|
|
2502
2947
|
] })
|
|
2503
2948
|
] }),
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
/* @__PURE__ */
|
|
2949
|
+
/* @__PURE__ */ jsx12("section", { style: styles3.section, children: /* @__PURE__ */ jsxs11("div", { style: styles3.grid, children: [
|
|
2950
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2951
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Title" }),
|
|
2952
|
+
/* @__PURE__ */ jsx12("input", { style: styles3.input, ...form.register("title", { required: true }) })
|
|
2508
2953
|
] }),
|
|
2509
|
-
/* @__PURE__ */
|
|
2510
|
-
/* @__PURE__ */
|
|
2511
|
-
/* @__PURE__ */
|
|
2954
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2955
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Description" }),
|
|
2956
|
+
/* @__PURE__ */ jsx12("input", { style: styles3.input, ...form.register("description") })
|
|
2512
2957
|
] }),
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2516
|
-
/* @__PURE__ */
|
|
2517
|
-
(forms.data ?? []).map((item) => /* @__PURE__ */
|
|
2958
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2959
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Form" }),
|
|
2960
|
+
/* @__PURE__ */ jsxs11("select", { style: styles3.input, ...form.register("formId"), children: [
|
|
2961
|
+
/* @__PURE__ */ jsx12("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "No form" }),
|
|
2962
|
+
(forms.data ?? []).map((item) => /* @__PURE__ */ jsx12("option", { value: item.id, children: item.title }, item.id))
|
|
2518
2963
|
] })
|
|
2519
2964
|
] }),
|
|
2520
|
-
/* @__PURE__ */
|
|
2521
|
-
/* @__PURE__ */
|
|
2522
|
-
/* @__PURE__ */
|
|
2523
|
-
/* @__PURE__ */
|
|
2524
|
-
(lists.data ?? []).map((item) => /* @__PURE__ */
|
|
2965
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2966
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "List" }),
|
|
2967
|
+
/* @__PURE__ */ jsxs11("select", { style: styles3.input, ...form.register("listId"), children: [
|
|
2968
|
+
/* @__PURE__ */ jsx12("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "No list" }),
|
|
2969
|
+
(lists.data ?? []).map((item) => /* @__PURE__ */ jsx12("option", { value: item.id, children: item.title }, item.id))
|
|
2525
2970
|
] })
|
|
2526
2971
|
] }),
|
|
2527
|
-
showPermissions ? /* @__PURE__ */
|
|
2528
|
-
/* @__PURE__ */
|
|
2529
|
-
/* @__PURE__ */
|
|
2530
|
-
/* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2532
|
-
options.permissionOptions.map((permission) => /* @__PURE__ */
|
|
2972
|
+
showPermissions ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
2973
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2974
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Read permission" }),
|
|
2975
|
+
/* @__PURE__ */ jsxs11("select", { style: styles3.input, ...form.register("permissionRead"), children: [
|
|
2976
|
+
/* @__PURE__ */ jsx12("option", { value: "", children: "Authenticated users" }),
|
|
2977
|
+
options.permissionOptions.map((permission) => /* @__PURE__ */ jsx12("option", { value: permission.value, children: permission.label }, permission.value))
|
|
2533
2978
|
] })
|
|
2534
2979
|
] }),
|
|
2535
|
-
/* @__PURE__ */
|
|
2536
|
-
/* @__PURE__ */
|
|
2537
|
-
/* @__PURE__ */
|
|
2538
|
-
/* @__PURE__ */
|
|
2539
|
-
options.permissionOptions.map((permission) => /* @__PURE__ */
|
|
2980
|
+
/* @__PURE__ */ jsxs11("label", { style: styles3.field, children: [
|
|
2981
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Write permission" }),
|
|
2982
|
+
/* @__PURE__ */ jsxs11("select", { style: styles3.input, ...form.register("permissionWrite"), children: [
|
|
2983
|
+
/* @__PURE__ */ jsx12("option", { value: "", children: "Authenticated users" }),
|
|
2984
|
+
options.permissionOptions.map((permission) => /* @__PURE__ */ jsx12("option", { value: permission.value, children: permission.label }, permission.value))
|
|
2540
2985
|
] })
|
|
2541
2986
|
] })
|
|
2542
2987
|
] }) : null,
|
|
2543
|
-
/* @__PURE__ */
|
|
2544
|
-
/* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
2988
|
+
/* @__PURE__ */ jsxs11("label", { style: { ...styles3.field, gridColumn: "1 / -1" }, children: [
|
|
2989
|
+
/* @__PURE__ */ jsx12("span", { style: styles3.label, children: "Triggers JSON" }),
|
|
2990
|
+
/* @__PURE__ */ jsx12("textarea", { style: styles3.textarea, ...form.register("triggersText") })
|
|
2546
2991
|
] })
|
|
2547
2992
|
] }) })
|
|
2548
2993
|
] });
|
|
@@ -2550,14 +2995,14 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
2550
2995
|
}
|
|
2551
2996
|
|
|
2552
2997
|
// src/admin/BuilderEditorPage.tsx
|
|
2553
|
-
import { useEffect as
|
|
2998
|
+
import { useEffect as useEffect5 } from "react";
|
|
2554
2999
|
import {
|
|
2555
3000
|
FormProvider as FormProvider3,
|
|
2556
3001
|
useFieldArray,
|
|
2557
3002
|
useForm as useForm4,
|
|
2558
|
-
useWatch as
|
|
3003
|
+
useWatch as useWatch5
|
|
2559
3004
|
} from "react-hook-form";
|
|
2560
|
-
import { jsx as
|
|
3005
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2561
3006
|
function createBuilderFormEditorPageComponent(deps) {
|
|
2562
3007
|
return function BuilderFormEditorPage({ formId }) {
|
|
2563
3008
|
const Body = deps.Body;
|
|
@@ -2571,11 +3016,11 @@ function createBuilderFormEditorPageComponent(deps) {
|
|
|
2571
3016
|
const fieldArray = useFieldArray({ control: form.control, name: "fields" });
|
|
2572
3017
|
const subformArray = useFieldArray({ control: form.control, name: "subforms" });
|
|
2573
3018
|
const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
|
|
2574
|
-
const fields =
|
|
2575
|
-
const subforms =
|
|
2576
|
-
const sourceType =
|
|
2577
|
-
const sourceTable =
|
|
2578
|
-
|
|
3019
|
+
const fields = useWatch5({ control: form.control, name: "fields" }) ?? [];
|
|
3020
|
+
const subforms = useWatch5({ control: form.control, name: "subforms" }) ?? [];
|
|
3021
|
+
const sourceType = useWatch5({ control: form.control, name: "sourceType" });
|
|
3022
|
+
const sourceTable = useWatch5({ control: form.control, name: "sourceTable" });
|
|
3023
|
+
useEffect5(() => {
|
|
2579
3024
|
if (formId && !entityQuery.data) return;
|
|
2580
3025
|
form.reset(builderFormEditorValuesFromEntity(entityQuery.data ?? null, deps.emptyValues));
|
|
2581
3026
|
}, [entityQuery.data, form, formId]);
|
|
@@ -2598,12 +3043,12 @@ function createBuilderFormEditorPageComponent(deps) {
|
|
|
2598
3043
|
}
|
|
2599
3044
|
});
|
|
2600
3045
|
if (formId && entityQuery.isPending) {
|
|
2601
|
-
return /* @__PURE__ */
|
|
3046
|
+
return /* @__PURE__ */ jsx13("div", { className: "text-muted-foreground text-sm", children: deps.states.loading });
|
|
2602
3047
|
}
|
|
2603
3048
|
if (formId && entityQuery.isError) {
|
|
2604
|
-
return /* @__PURE__ */
|
|
3049
|
+
return /* @__PURE__ */ jsx13("div", { className: "text-destructive text-sm", children: deps.states.error });
|
|
2605
3050
|
}
|
|
2606
|
-
return /* @__PURE__ */
|
|
3051
|
+
return /* @__PURE__ */ jsx13(FormProvider3, { ...form, children: /* @__PURE__ */ jsx13("form", { onSubmit, noValidate: true, className: "space-y-6", children: /* @__PURE__ */ jsx13(
|
|
2607
3052
|
Body,
|
|
2608
3053
|
{
|
|
2609
3054
|
formId,
|
|
@@ -2637,9 +3082,9 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
2637
3082
|
const columnArray = useFieldArray({ control: form.control, name: "columns" });
|
|
2638
3083
|
const orderByArray = useFieldArray({ control: form.control, name: "orderBy" });
|
|
2639
3084
|
const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
|
|
2640
|
-
const sourceType =
|
|
2641
|
-
const sourceTable =
|
|
2642
|
-
|
|
3085
|
+
const sourceType = useWatch5({ control: form.control, name: "sourceType" });
|
|
3086
|
+
const sourceTable = useWatch5({ control: form.control, name: "sourceTable" });
|
|
3087
|
+
useEffect5(() => {
|
|
2643
3088
|
if (listId && !entityQuery.data) return;
|
|
2644
3089
|
form.reset(builderListEditorValuesFromEntity(entityQuery.data ?? null, deps.emptyValues));
|
|
2645
3090
|
}, [entityQuery.data, form, listId]);
|
|
@@ -2658,12 +3103,12 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
2658
3103
|
}
|
|
2659
3104
|
});
|
|
2660
3105
|
if (listId && entityQuery.isPending) {
|
|
2661
|
-
return /* @__PURE__ */
|
|
3106
|
+
return /* @__PURE__ */ jsx13("div", { className: "text-muted-foreground text-sm", children: deps.states.loading });
|
|
2662
3107
|
}
|
|
2663
3108
|
if (listId && entityQuery.isError) {
|
|
2664
|
-
return /* @__PURE__ */
|
|
3109
|
+
return /* @__PURE__ */ jsx13("div", { className: "text-destructive text-sm", children: deps.states.error });
|
|
2665
3110
|
}
|
|
2666
|
-
return /* @__PURE__ */
|
|
3111
|
+
return /* @__PURE__ */ jsx13(FormProvider3, { ...form, children: /* @__PURE__ */ jsx13("form", { onSubmit, noValidate: true, className: "space-y-6", children: /* @__PURE__ */ jsx13(
|
|
2667
3112
|
Body,
|
|
2668
3113
|
{
|
|
2669
3114
|
listId,
|
|
@@ -2684,10 +3129,11 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
2684
3129
|
}
|
|
2685
3130
|
|
|
2686
3131
|
// src/admin/BuilderAdminPages.tsx
|
|
2687
|
-
import { jsx as
|
|
3132
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2688
3133
|
var defaultFieldTypeOptions = [
|
|
2689
3134
|
{ value: "text", label: "Text" },
|
|
2690
3135
|
{ value: "textarea", label: "Textarea" },
|
|
3136
|
+
{ value: "richtext", label: "Rich text" },
|
|
2691
3137
|
{ value: "number", label: "Number" },
|
|
2692
3138
|
{ value: "money", label: "Money" },
|
|
2693
3139
|
{ value: "select", label: "Select" },
|
|
@@ -2798,6 +3244,10 @@ function createBuilderAdminPages({
|
|
|
2798
3244
|
required: true,
|
|
2799
3245
|
hidden: false,
|
|
2800
3246
|
disabled: false,
|
|
3247
|
+
storage: "s3",
|
|
3248
|
+
contentKind: "image",
|
|
3249
|
+
multiple: false,
|
|
3250
|
+
maxMegabytes: 10,
|
|
2801
3251
|
placeholder: "",
|
|
2802
3252
|
optionsText: "",
|
|
2803
3253
|
optionsMode: "static",
|
|
@@ -2944,14 +3394,14 @@ function createBuilderAdminPages({
|
|
|
2944
3394
|
href: viewsPath
|
|
2945
3395
|
}
|
|
2946
3396
|
];
|
|
2947
|
-
return /* @__PURE__ */
|
|
2948
|
-
/* @__PURE__ */
|
|
2949
|
-
/* @__PURE__ */
|
|
2950
|
-
/* @__PURE__ */
|
|
3397
|
+
return /* @__PURE__ */ jsxs12("section", { style: homeStyles.page, children: [
|
|
3398
|
+
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3399
|
+
/* @__PURE__ */ jsx14("h1", { style: homeStyles.headerTitle, children: "Builder" }),
|
|
3400
|
+
/* @__PURE__ */ jsx14("p", { style: homeStyles.description, children: "Manage dynamic forms, lists, and views." })
|
|
2951
3401
|
] }),
|
|
2952
|
-
/* @__PURE__ */
|
|
2953
|
-
/* @__PURE__ */
|
|
2954
|
-
/* @__PURE__ */
|
|
3402
|
+
/* @__PURE__ */ jsx14("div", { style: homeStyles.grid, children: items.map((item) => /* @__PURE__ */ jsxs12("a", { href: item.href, style: homeStyles.card, children: [
|
|
3403
|
+
/* @__PURE__ */ jsx14("h2", { style: homeStyles.cardTitle, children: item.title }),
|
|
3404
|
+
/* @__PURE__ */ jsx14("p", { style: homeStyles.description, children: item.description })
|
|
2955
3405
|
] }, item.href)) })
|
|
2956
3406
|
] });
|
|
2957
3407
|
};
|
|
@@ -3040,24 +3490,24 @@ function createBuilderAdminPages({
|
|
|
3040
3490
|
AdminHomePage,
|
|
3041
3491
|
AdminFormsPage,
|
|
3042
3492
|
AdminNewFormPage: function BuilderAdminNewFormPage() {
|
|
3043
|
-
return /* @__PURE__ */
|
|
3493
|
+
return /* @__PURE__ */ jsx14(FormEditorPage, {});
|
|
3044
3494
|
},
|
|
3045
3495
|
AdminEditFormPage: function BuilderAdminEditFormPage({ formId }) {
|
|
3046
|
-
return /* @__PURE__ */
|
|
3496
|
+
return /* @__PURE__ */ jsx14(FormEditorPage, { formId });
|
|
3047
3497
|
},
|
|
3048
3498
|
AdminListsPage,
|
|
3049
3499
|
AdminNewListPage: function BuilderAdminNewListPage() {
|
|
3050
|
-
return /* @__PURE__ */
|
|
3500
|
+
return /* @__PURE__ */ jsx14(ListEditorPage, {});
|
|
3051
3501
|
},
|
|
3052
3502
|
AdminEditListPage: function BuilderAdminEditListPage({ listId }) {
|
|
3053
|
-
return /* @__PURE__ */
|
|
3503
|
+
return /* @__PURE__ */ jsx14(ListEditorPage, { listId });
|
|
3054
3504
|
},
|
|
3055
3505
|
AdminViewsPage,
|
|
3056
3506
|
AdminNewViewPage: function BuilderAdminNewViewPage() {
|
|
3057
|
-
return /* @__PURE__ */
|
|
3507
|
+
return /* @__PURE__ */ jsx14(ViewEditorPage, {});
|
|
3058
3508
|
},
|
|
3059
3509
|
AdminEditViewPage: function BuilderAdminEditViewPage({ viewId }) {
|
|
3060
|
-
return /* @__PURE__ */
|
|
3510
|
+
return /* @__PURE__ */ jsx14(ViewEditorPage, { viewId });
|
|
3061
3511
|
},
|
|
3062
3512
|
routes: {
|
|
3063
3513
|
adminBasePath,
|
|
@@ -3075,11 +3525,11 @@ function createBuilderAdminPages({
|
|
|
3075
3525
|
}
|
|
3076
3526
|
|
|
3077
3527
|
// src/admin/BuilderEntityManager.tsx
|
|
3078
|
-
import { useCallback as useCallback2, useMemo as useMemo6, useState as
|
|
3079
|
-
import { jsx as
|
|
3528
|
+
import { useCallback as useCallback2, useMemo as useMemo6, useState as useState8 } from "react";
|
|
3529
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3080
3530
|
function createBuilderEntityManagerComponent(deps) {
|
|
3081
3531
|
return function BuilderEntityManager() {
|
|
3082
|
-
const [pendingDelete, setPendingDelete] =
|
|
3532
|
+
const [pendingDelete, setPendingDelete] = useState8(null);
|
|
3083
3533
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
3084
3534
|
const query = deps.hooks.useEntities(state.query);
|
|
3085
3535
|
const remove = deps.hooks.useDelete();
|
|
@@ -3104,8 +3554,8 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
3104
3554
|
state,
|
|
3105
3555
|
getRowId: (row) => row.id
|
|
3106
3556
|
});
|
|
3107
|
-
return /* @__PURE__ */
|
|
3108
|
-
/* @__PURE__ */
|
|
3557
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
3558
|
+
/* @__PURE__ */ jsx15(
|
|
3109
3559
|
deps.DataGrid,
|
|
3110
3560
|
{
|
|
3111
3561
|
title: deps.labels.title,
|
|
@@ -3116,10 +3566,10 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
3116
3566
|
emptyTitle: deps.labels.emptyTitle,
|
|
3117
3567
|
emptyDescription: deps.labels.emptyDescription,
|
|
3118
3568
|
onRowClick: deps.navigateToEdit,
|
|
3119
|
-
toolbarExtra: /* @__PURE__ */
|
|
3569
|
+
toolbarExtra: /* @__PURE__ */ jsx15(deps.AddButton, { href: deps.createHref, label: deps.labels.addLabel })
|
|
3120
3570
|
}
|
|
3121
3571
|
),
|
|
3122
|
-
/* @__PURE__ */
|
|
3572
|
+
/* @__PURE__ */ jsx15(
|
|
3123
3573
|
deps.DeleteDialog,
|
|
3124
3574
|
{
|
|
3125
3575
|
entity: pendingDelete,
|
|
@@ -3139,9 +3589,9 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
3139
3589
|
}
|
|
3140
3590
|
function createBuilderEntityDialogManagerComponent(deps) {
|
|
3141
3591
|
return function BuilderEntityDialogManager() {
|
|
3142
|
-
const [editing, setEditing] =
|
|
3143
|
-
const [isEditorOpen, setEditorOpen] =
|
|
3144
|
-
const [pendingDelete, setPendingDelete] =
|
|
3592
|
+
const [editing, setEditing] = useState8(null);
|
|
3593
|
+
const [isEditorOpen, setEditorOpen] = useState8(false);
|
|
3594
|
+
const [pendingDelete, setPendingDelete] = useState8(null);
|
|
3145
3595
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
3146
3596
|
const query = deps.hooks.useEntities(state.query);
|
|
3147
3597
|
const remove = deps.hooks.useDelete();
|
|
@@ -3170,8 +3620,8 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
3170
3620
|
state,
|
|
3171
3621
|
getRowId: (row) => row.id
|
|
3172
3622
|
});
|
|
3173
|
-
return /* @__PURE__ */
|
|
3174
|
-
/* @__PURE__ */
|
|
3623
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
3624
|
+
/* @__PURE__ */ jsx15(
|
|
3175
3625
|
deps.DataGrid,
|
|
3176
3626
|
{
|
|
3177
3627
|
title: deps.labels.title,
|
|
@@ -3182,10 +3632,10 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
3182
3632
|
emptyTitle: deps.labels.emptyTitle,
|
|
3183
3633
|
emptyDescription: deps.labels.emptyDescription,
|
|
3184
3634
|
onRowClick: openEditor,
|
|
3185
|
-
toolbarExtra: /* @__PURE__ */
|
|
3635
|
+
toolbarExtra: /* @__PURE__ */ jsx15(deps.AddButton, { label: deps.labels.addLabel, onAdd: () => openEditor(null) })
|
|
3186
3636
|
}
|
|
3187
3637
|
),
|
|
3188
|
-
/* @__PURE__ */
|
|
3638
|
+
/* @__PURE__ */ jsx15(
|
|
3189
3639
|
deps.EditorDialog,
|
|
3190
3640
|
{
|
|
3191
3641
|
open: isEditorOpen,
|
|
@@ -3193,7 +3643,7 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
3193
3643
|
onClose: () => setEditorOpen(false)
|
|
3194
3644
|
}
|
|
3195
3645
|
),
|
|
3196
|
-
/* @__PURE__ */
|
|
3646
|
+
/* @__PURE__ */ jsx15(
|
|
3197
3647
|
deps.DeleteDialog,
|
|
3198
3648
|
{
|
|
3199
3649
|
entity: pendingDelete,
|
|
@@ -3213,9 +3663,9 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
3213
3663
|
}
|
|
3214
3664
|
|
|
3215
3665
|
// src/admin/BuilderViewDialog.tsx
|
|
3216
|
-
import { useEffect as
|
|
3666
|
+
import { useEffect as useEffect6 } from "react";
|
|
3217
3667
|
import { FormProvider as FormProvider4, useForm as useForm5 } from "react-hook-form";
|
|
3218
|
-
import { jsx as
|
|
3668
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3219
3669
|
function createBuilderViewDialogComponent(deps) {
|
|
3220
3670
|
return function BuilderViewDialog({
|
|
3221
3671
|
open,
|
|
@@ -3230,7 +3680,7 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
3230
3680
|
resolver: deps.resolver,
|
|
3231
3681
|
defaultValues: deps.emptyValues
|
|
3232
3682
|
});
|
|
3233
|
-
|
|
3683
|
+
useEffect6(() => {
|
|
3234
3684
|
if (!open) return;
|
|
3235
3685
|
form.reset(
|
|
3236
3686
|
builderViewEditorValuesFromEntity(editing, deps.emptyValues, deps.defaultPermission)
|
|
@@ -3245,7 +3695,7 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
3245
3695
|
deps.notifications.error(error);
|
|
3246
3696
|
}
|
|
3247
3697
|
});
|
|
3248
|
-
return /* @__PURE__ */
|
|
3698
|
+
return /* @__PURE__ */ jsx16(deps.Shell, { open, editing, onClose, children: /* @__PURE__ */ jsx16(FormProvider4, { ...form, children: /* @__PURE__ */ jsx16("form", { onSubmit, noValidate: true, children: deps.Body({
|
|
3249
3699
|
form,
|
|
3250
3700
|
editing,
|
|
3251
3701
|
forms,
|
|
@@ -3260,7 +3710,7 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
3260
3710
|
|
|
3261
3711
|
// src/admin/formLayoutEditorState.ts
|
|
3262
3712
|
import { useMemo as useMemo7 } from "react";
|
|
3263
|
-
import { useWatch as
|
|
3713
|
+
import { useWatch as useWatch6 } from "react-hook-form";
|
|
3264
3714
|
var builderFormLayoutDragDataType = "application/x-winu-builder-layout-field";
|
|
3265
3715
|
function clampBuilderFormLayoutSpan(span, columns) {
|
|
3266
3716
|
return Math.max(1, Math.min(columns, span));
|
|
@@ -3307,7 +3757,7 @@ function parseBuilderFormLayoutDragPayload(raw) {
|
|
|
3307
3757
|
}
|
|
3308
3758
|
}
|
|
3309
3759
|
function useBuilderFormLayoutEditor({ form, fields, subforms = [] }) {
|
|
3310
|
-
const layoutGroups =
|
|
3760
|
+
const layoutGroups = useWatch6({ control: form.control, name: "layoutGroups" }) ?? [];
|
|
3311
3761
|
const layoutItems = useMemo7(
|
|
3312
3762
|
() => [
|
|
3313
3763
|
...fields.map((field) => ({
|
|
@@ -3430,7 +3880,7 @@ function useBuilderFormLayoutEditor({ form, fields, subforms = [] }) {
|
|
|
3430
3880
|
// src/components/DynamicForm.tsx
|
|
3431
3881
|
import { useMemo as useMemo8 } from "react";
|
|
3432
3882
|
import { FormProvider as FormProvider5, useForm as useForm6 } from "react-hook-form";
|
|
3433
|
-
import { jsx as
|
|
3883
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3434
3884
|
function createDynamicFormComponent(deps) {
|
|
3435
3885
|
return function DynamicForm({ formId }) {
|
|
3436
3886
|
const query = deps.hooks.useRuntimeBuilderForm(formId);
|
|
@@ -3453,7 +3903,7 @@ function createDynamicFormComponent(deps) {
|
|
|
3453
3903
|
}
|
|
3454
3904
|
});
|
|
3455
3905
|
if (query.isError) {
|
|
3456
|
-
return /* @__PURE__ */
|
|
3906
|
+
return /* @__PURE__ */ jsx17(
|
|
3457
3907
|
deps.ErrorState,
|
|
3458
3908
|
{
|
|
3459
3909
|
title: "Form \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
@@ -3462,16 +3912,16 @@ function createDynamicFormComponent(deps) {
|
|
|
3462
3912
|
);
|
|
3463
3913
|
}
|
|
3464
3914
|
if (!query.data) return null;
|
|
3465
|
-
return /* @__PURE__ */
|
|
3466
|
-
/* @__PURE__ */
|
|
3467
|
-
/* @__PURE__ */
|
|
3915
|
+
return /* @__PURE__ */ jsx17(deps.FormShell, { title: query.data.title, children: /* @__PURE__ */ jsx17(FormProvider5, { ...form, children: /* @__PURE__ */ jsxs14("form", { onSubmit, noValidate: true, className: "space-y-6", children: [
|
|
3916
|
+
/* @__PURE__ */ jsx17(deps.FormFields, { formId, schema: query.data.schema, namePrefix: "values" }),
|
|
3917
|
+
/* @__PURE__ */ jsx17(deps.SubmitButton, { isSaving: save.isPending })
|
|
3468
3918
|
] }) }) });
|
|
3469
3919
|
};
|
|
3470
3920
|
}
|
|
3471
3921
|
|
|
3472
3922
|
// src/components/DynamicList.tsx
|
|
3473
3923
|
import { useMemo as useMemo9 } from "react";
|
|
3474
|
-
import { jsx as
|
|
3924
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
3475
3925
|
function createDynamicListComponent(deps) {
|
|
3476
3926
|
return function DynamicList({ listId }) {
|
|
3477
3927
|
const query = deps.hooks.useRuntimeBuilderList(listId);
|
|
@@ -3487,7 +3937,7 @@ function createDynamicListComponent(deps) {
|
|
|
3487
3937
|
getRowId: (row) => row.id
|
|
3488
3938
|
});
|
|
3489
3939
|
if (query.isError) {
|
|
3490
|
-
return /* @__PURE__ */
|
|
3940
|
+
return /* @__PURE__ */ jsx18(
|
|
3491
3941
|
deps.ErrorState,
|
|
3492
3942
|
{
|
|
3493
3943
|
title: "List \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
@@ -3495,7 +3945,7 @@ function createDynamicListComponent(deps) {
|
|
|
3495
3945
|
}
|
|
3496
3946
|
);
|
|
3497
3947
|
}
|
|
3498
|
-
return /* @__PURE__ */
|
|
3948
|
+
return /* @__PURE__ */ jsx18(
|
|
3499
3949
|
deps.DataGrid,
|
|
3500
3950
|
{
|
|
3501
3951
|
title: query.data?.title ?? "Dynamic List",
|
|
@@ -3511,8 +3961,8 @@ function createDynamicListComponent(deps) {
|
|
|
3511
3961
|
}
|
|
3512
3962
|
|
|
3513
3963
|
// src/components/DynamicView.tsx
|
|
3514
|
-
import { useMemo as useMemo10, useState as
|
|
3515
|
-
import { jsx as
|
|
3964
|
+
import { useMemo as useMemo10, useState as useState9 } from "react";
|
|
3965
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3516
3966
|
var interactiveRowTargetSelector = "button,a,input,select,textarea,[role='button'],[role='menuitem'],[data-builder-row-action]";
|
|
3517
3967
|
function hasClosest(target) {
|
|
3518
3968
|
return typeof target === "object" && target !== null && "closest" in target && typeof target.closest === "function";
|
|
@@ -3524,9 +3974,9 @@ function shouldHandleDynamicViewRowClick(event) {
|
|
|
3524
3974
|
}
|
|
3525
3975
|
function createDynamicViewComponent(deps) {
|
|
3526
3976
|
return function DynamicView({ viewId }) {
|
|
3527
|
-
const [editing, setEditing] =
|
|
3528
|
-
const [isDialogOpen, setDialogOpen] =
|
|
3529
|
-
const [pendingDelete, setPendingDelete] =
|
|
3977
|
+
const [editing, setEditing] = useState9(null);
|
|
3978
|
+
const [isDialogOpen, setDialogOpen] = useState9(false);
|
|
3979
|
+
const [pendingDelete, setPendingDelete] = useState9(null);
|
|
3530
3980
|
const viewQuery = deps.hooks.useRuntimeBuilderView(viewId);
|
|
3531
3981
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
3532
3982
|
const entriesQuery = deps.hooks.useBuilderViewEntries(viewId, state.query);
|
|
@@ -3555,7 +4005,7 @@ function createDynamicViewComponent(deps) {
|
|
|
3555
4005
|
getRowId: (row) => row.id
|
|
3556
4006
|
});
|
|
3557
4007
|
if (viewQuery.isError) {
|
|
3558
|
-
return /* @__PURE__ */
|
|
4008
|
+
return /* @__PURE__ */ jsx19(
|
|
3559
4009
|
deps.ErrorState,
|
|
3560
4010
|
{
|
|
3561
4011
|
title: "View \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
@@ -3563,8 +4013,8 @@ function createDynamicViewComponent(deps) {
|
|
|
3563
4013
|
}
|
|
3564
4014
|
);
|
|
3565
4015
|
}
|
|
3566
|
-
return /* @__PURE__ */
|
|
3567
|
-
/* @__PURE__ */
|
|
4016
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-6", children: [
|
|
4017
|
+
/* @__PURE__ */ jsx19(
|
|
3568
4018
|
deps.DataGrid,
|
|
3569
4019
|
{
|
|
3570
4020
|
title: view?.title ?? "Dynamic View",
|
|
@@ -3579,7 +4029,7 @@ function createDynamicViewComponent(deps) {
|
|
|
3579
4029
|
setEditing(entry);
|
|
3580
4030
|
setDialogOpen(true);
|
|
3581
4031
|
},
|
|
3582
|
-
toolbarExtra: /* @__PURE__ */
|
|
4032
|
+
toolbarExtra: /* @__PURE__ */ jsx19(
|
|
3583
4033
|
deps.AddButton,
|
|
3584
4034
|
{
|
|
3585
4035
|
disabled: !view?.form,
|
|
@@ -3591,7 +4041,7 @@ function createDynamicViewComponent(deps) {
|
|
|
3591
4041
|
)
|
|
3592
4042
|
}
|
|
3593
4043
|
),
|
|
3594
|
-
view ? /* @__PURE__ */
|
|
4044
|
+
view ? /* @__PURE__ */ jsx19(
|
|
3595
4045
|
deps.EntryDialog,
|
|
3596
4046
|
{
|
|
3597
4047
|
open: isDialogOpen,
|
|
@@ -3602,7 +4052,7 @@ function createDynamicViewComponent(deps) {
|
|
|
3602
4052
|
isSaving: save.isPending
|
|
3603
4053
|
}
|
|
3604
4054
|
) : null,
|
|
3605
|
-
/* @__PURE__ */
|
|
4055
|
+
/* @__PURE__ */ jsx19(
|
|
3606
4056
|
deps.DeleteDialog,
|
|
3607
4057
|
{
|
|
3608
4058
|
entry: pendingDelete,
|
|
@@ -3620,9 +4070,9 @@ function createDynamicViewComponent(deps) {
|
|
|
3620
4070
|
}
|
|
3621
4071
|
|
|
3622
4072
|
// src/components/RuntimeEntryDialog.tsx
|
|
3623
|
-
import { useEffect as
|
|
4073
|
+
import { useEffect as useEffect7, useMemo as useMemo11, useRef as useRef8, useState as useState10 } from "react";
|
|
3624
4074
|
import { FormProvider as FormProvider6, useForm as useForm7 } from "react-hook-form";
|
|
3625
|
-
import { jsx as
|
|
4075
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3626
4076
|
function isDbTableSource(source) {
|
|
3627
4077
|
return source?.type === "dbTable" && "tableName" in source;
|
|
3628
4078
|
}
|
|
@@ -3646,6 +4096,12 @@ function childRowPayload(row, includeIdentity) {
|
|
|
3646
4096
|
...values
|
|
3647
4097
|
};
|
|
3648
4098
|
}
|
|
4099
|
+
function hasDraftChange(row) {
|
|
4100
|
+
return row.values._delete === true || row.values._draftNew === true || row.values._draftDirty === true;
|
|
4101
|
+
}
|
|
4102
|
+
function changedChildPayloads(rows, includeIdentity) {
|
|
4103
|
+
return rows.filter(hasDraftChange).filter((row) => includeIdentity || row.values._delete !== true).map((row) => childRowPayload(row, includeIdentity));
|
|
4104
|
+
}
|
|
3649
4105
|
function createRuntimeEntryDialogComponent(deps) {
|
|
3650
4106
|
return function RuntimeEntryDialog({
|
|
3651
4107
|
open,
|
|
@@ -3655,7 +4111,8 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3655
4111
|
onSave,
|
|
3656
4112
|
isSaving
|
|
3657
4113
|
}) {
|
|
3658
|
-
const [draftSubforms, setDraftSubforms] =
|
|
4114
|
+
const [draftSubforms, setDraftSubforms] = useState10({});
|
|
4115
|
+
const isSubmittingRef = useRef8(false);
|
|
3659
4116
|
const compositeCreate = deps.useCreateCompositeEntry?.(view.id);
|
|
3660
4117
|
const compositeUpdate = deps.useUpdateCompositeEntry?.(view.id);
|
|
3661
4118
|
const form = useForm7({
|
|
@@ -3663,16 +4120,18 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3663
4120
|
values: open ? createBuilderEntryDefaultValues(view, editing) : void 0
|
|
3664
4121
|
});
|
|
3665
4122
|
const mainTableName = runtimeViewTableName(view);
|
|
3666
|
-
const
|
|
3667
|
-
() => Object.values(draftSubforms).some((draft) => draft.rows.
|
|
4123
|
+
const hasDraftChanges = useMemo11(
|
|
4124
|
+
() => Object.values(draftSubforms).some((draft) => draft.rows.some(hasDraftChange)),
|
|
3668
4125
|
[draftSubforms]
|
|
3669
4126
|
);
|
|
3670
|
-
|
|
4127
|
+
useEffect7(() => {
|
|
3671
4128
|
if (open) setDraftSubforms({});
|
|
3672
4129
|
}, [open]);
|
|
3673
4130
|
const onSubmit = form.handleSubmit(async (values) => {
|
|
4131
|
+
if (isSubmittingRef.current) return;
|
|
4132
|
+
isSubmittingRef.current = true;
|
|
3674
4133
|
try {
|
|
3675
|
-
if (!editing &&
|
|
4134
|
+
if (!editing && hasDraftChanges) {
|
|
3676
4135
|
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
3677
4136
|
if (!compositeCreate) throw new Error("Composite create handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
3678
4137
|
await compositeCreate.mutateAsync({
|
|
@@ -3681,12 +4140,12 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3681
4140
|
...Object.fromEntries(
|
|
3682
4141
|
Object.values(draftSubforms).map((draft) => [
|
|
3683
4142
|
draft.dataKey,
|
|
3684
|
-
draft.rows
|
|
4143
|
+
changedChildPayloads(draft.rows, false)
|
|
3685
4144
|
])
|
|
3686
4145
|
)
|
|
3687
4146
|
}
|
|
3688
4147
|
});
|
|
3689
|
-
} else if (editing &&
|
|
4148
|
+
} else if (editing && hasDraftChanges) {
|
|
3690
4149
|
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
3691
4150
|
if (!compositeUpdate) throw new Error("Composite update handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
3692
4151
|
await compositeUpdate.mutateAsync({
|
|
@@ -3701,7 +4160,7 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3701
4160
|
...Object.fromEntries(
|
|
3702
4161
|
Object.values(draftSubforms).map((draft) => [
|
|
3703
4162
|
draft.dataKey,
|
|
3704
|
-
draft.rows
|
|
4163
|
+
changedChildPayloads(draft.rows, true)
|
|
3705
4164
|
])
|
|
3706
4165
|
)
|
|
3707
4166
|
}
|
|
@@ -3714,12 +4173,14 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3714
4173
|
deps.notifications.success(editing ? "\u041C\u04E9\u0440 \u0445\u0430\u0434\u0433\u0430\u043B\u0430\u0433\u0434\u043B\u0430\u0430" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0433\u0434\u043B\u044D\u044D");
|
|
3715
4174
|
} catch (error) {
|
|
3716
4175
|
deps.notifications.error(deps.notifications.errorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430"));
|
|
4176
|
+
} finally {
|
|
4177
|
+
isSubmittingRef.current = false;
|
|
3717
4178
|
}
|
|
3718
4179
|
});
|
|
3719
4180
|
const saving = isSaving || Boolean(compositeCreate?.isPending || compositeUpdate?.isPending);
|
|
3720
4181
|
const extraItems = deps.SubformField && view.form?.schema.subforms?.length ? view.form.schema.subforms.map((subform) => ({
|
|
3721
4182
|
key: subform.key,
|
|
3722
|
-
render: () => deps.SubformField ? /* @__PURE__ */
|
|
4183
|
+
render: () => deps.SubformField ? /* @__PURE__ */ jsx20(
|
|
3723
4184
|
deps.SubformField,
|
|
3724
4185
|
{
|
|
3725
4186
|
subform,
|
|
@@ -3734,7 +4195,7 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3734
4195
|
}
|
|
3735
4196
|
) : null
|
|
3736
4197
|
})) : void 0;
|
|
3737
|
-
return /* @__PURE__ */
|
|
4198
|
+
return /* @__PURE__ */ jsx20(
|
|
3738
4199
|
deps.DialogShell,
|
|
3739
4200
|
{
|
|
3740
4201
|
open,
|
|
@@ -3742,8 +4203,8 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3742
4203
|
title: editing ? "\u041C\u04E9\u0440 \u0437\u0430\u0441\u0430\u0445" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0445",
|
|
3743
4204
|
description: view.title,
|
|
3744
4205
|
onClose,
|
|
3745
|
-
children: /* @__PURE__ */
|
|
3746
|
-
view.form ? /* @__PURE__ */
|
|
4206
|
+
children: /* @__PURE__ */ jsx20(FormProvider6, { ...form, children: /* @__PURE__ */ jsxs16("form", { onSubmit, noValidate: true, className: deps.formClassName, children: [
|
|
4207
|
+
view.form ? /* @__PURE__ */ jsx20(
|
|
3747
4208
|
deps.FormFields,
|
|
3748
4209
|
{
|
|
3749
4210
|
formId: view.form.id,
|
|
@@ -3754,7 +4215,7 @@ function createRuntimeEntryDialogComponent(deps) {
|
|
|
3754
4215
|
extraItems
|
|
3755
4216
|
}
|
|
3756
4217
|
) : null,
|
|
3757
|
-
/* @__PURE__ */
|
|
4218
|
+
/* @__PURE__ */ jsx20(deps.Actions, { isSaving: saving, onClose })
|
|
3758
4219
|
] }) })
|
|
3759
4220
|
}
|
|
3760
4221
|
);
|
|
@@ -3841,7 +4302,7 @@ function validateBuilderFrontendSetup(config) {
|
|
|
3841
4302
|
// src/index.ts
|
|
3842
4303
|
var builderUiPackage = {
|
|
3843
4304
|
name: "@duke333/builder-ui",
|
|
3844
|
-
version: "0.2.
|
|
4305
|
+
version: "0.2.4"
|
|
3845
4306
|
};
|
|
3846
4307
|
export {
|
|
3847
4308
|
BUILDER_EDITOR_NONE_VALUE,
|
|
@@ -3849,6 +4310,9 @@ export {
|
|
|
3849
4310
|
BuilderGrid,
|
|
3850
4311
|
BuilderProvider,
|
|
3851
4312
|
BuilderView,
|
|
4313
|
+
ReadyFileField,
|
|
4314
|
+
ReadyRichTextField,
|
|
4315
|
+
RichTextContent,
|
|
3852
4316
|
builderEditorOptionsToText,
|
|
3853
4317
|
builderEditorSearchFieldsToText,
|
|
3854
4318
|
builderEditorTextToOptions,
|
|
@@ -3891,9 +4355,11 @@ export {
|
|
|
3891
4355
|
getBuilderEditorTriggerRoute,
|
|
3892
4356
|
nextBuilderFormLayoutGroupId,
|
|
3893
4357
|
parseBuilderFormLayoutDragPayload,
|
|
4358
|
+
richTextToPlainText,
|
|
3894
4359
|
serializeBuilderFormLayoutDragPayload,
|
|
3895
4360
|
shouldHandleDynamicViewRowClick,
|
|
3896
4361
|
swapBuilderFormLayoutItems,
|
|
4362
|
+
toRichTextDocument,
|
|
3897
4363
|
useBuilderFormLayoutEditor,
|
|
3898
4364
|
useBuilderRuntime,
|
|
3899
4365
|
validateBuilderFrontendSetup
|