@nextlyhq/plugin-form-builder 0.0.2-alpha.72 → 0.0.2-alpha.74
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/admin/index.d.ts +12 -1
- package/dist/admin/index.js +193 -12
- package/dist/admin/index.js.map +1 -1
- package/dist/{field-references-BshlgMcn.js → field-references-CtzGg51W.js} +272 -2
- package/dist/field-references-CtzGg51W.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +157 -17
- package/dist/index.js.map +1 -1
- package/dist/{types-BHReIA0j.d.ts → new-submissions-CzlhVGhH.d.ts} +34 -2
- package/package.json +12 -12
- package/dist/field-references-BshlgMcn.js.map +0 -1
package/dist/admin/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as
|
|
1
|
+
import { O as FormSettings, S as FormFieldTypeId, T as FormNotification, b as FormField, i as AnyFormField, r as NewSubmissionsData } from "../new-submissions-CzlhVGhH.js";
|
|
2
2
|
import { ComponentPath, DocumentLockGates } from "@nextlyhq/plugin-sdk/admin";
|
|
3
3
|
import React, { JSX, ReactNode } from "react";
|
|
4
4
|
import { FieldTypeCatalogEntry, FormFieldCatalogType } from "nextly/field-catalog";
|
|
@@ -18,6 +18,11 @@ interface FormBuilderViewProps {
|
|
|
18
18
|
fields?: unknown[];
|
|
19
19
|
settings?: Record<string, unknown>;
|
|
20
20
|
notifications?: unknown[];
|
|
21
|
+
/**
|
|
22
|
+
* The form's version as read, which a save sends back so one made from an
|
|
23
|
+
* older version is refused rather than replacing what someone saved since.
|
|
24
|
+
*/
|
|
25
|
+
_rev?: string;
|
|
21
26
|
};
|
|
22
27
|
onSave?: (data: unknown) => void;
|
|
23
28
|
onSuccess?: (entry?: Record<string, unknown>) => void;
|
|
@@ -49,6 +54,8 @@ interface SubmissionRow {
|
|
|
49
54
|
submittedAt?: string | null;
|
|
50
55
|
editedAt?: string | null;
|
|
51
56
|
editedBy?: string | null;
|
|
57
|
+
/** The submission's version as the list read it; see `submissionPatch`. */
|
|
58
|
+
_rev?: string;
|
|
52
59
|
}
|
|
53
60
|
interface FormOption {
|
|
54
61
|
id: string;
|
|
@@ -69,6 +76,10 @@ interface SubmissionSheetProps {
|
|
|
69
76
|
onSave: (changes: Record<string, unknown>) => Promise<void>;
|
|
70
77
|
}
|
|
71
78
|
export declare function SubmissionSheet({ submission, form, canUpdate, onClose, onPrev, onNext, onSave }: SubmissionSheetProps): JSX.Element;
|
|
79
|
+
/** The card's rows, as many as its size holds. */
|
|
80
|
+
export declare function NewSubmissionsCard({ data }: {
|
|
81
|
+
data: NewSubmissionsData;
|
|
82
|
+
}): JSX.Element;
|
|
72
83
|
interface FieldCardsProps {
|
|
73
84
|
/**
|
|
74
85
|
* Form-surface types the host has NOT excluded (the plugin's field
|
package/dist/admin/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as isKnownFormField, C as enforcedValidationRules,
|
|
2
|
-
import { ConditionRow, DataTableView, FieldOptionsEditor, FieldTypePicker, ValidationRulesEditor, drawsAnyValidationRule, registerComponents, registerKnownPlugin, usePluginFieldTypeEntries, withOptionIds } from "@nextlyhq/plugin-sdk/admin";
|
|
1
|
+
import { A as isKnownFormField, C as enforcedValidationRules, L as documentReachability, R as parseRedirectReference, l as evaluateConditions, m as DEFAULT_FORM_SETTINGS, n as parseFieldRef, p as normalizeFormSettings, s as formatExportValue, t as buildFieldReferenceMap } from "../field-references-CtzGg51W.js";
|
|
2
|
+
import { ConditionRow, DataTableView, FieldOptionsEditor, FieldTypePicker, FrameState, ValidationRulesEditor, Widget, drawsAnyValidationRule, formatWidgetTime, registerComponents, registerKnownPlugin, usePluginFieldTypeEntries, useRefreshDashboard, useWidgetClock, withOptionIds } from "@nextlyhq/plugin-sdk/admin";
|
|
3
3
|
import { Badge, Button, Card, Checkbox, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, FieldShell, FormActions, FormLabelWithTooltip, FormSection, Grid, Input, Label, RadioGroup, RadioGroupItem, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Tooltip, TooltipContent, TooltipTrigger, toast } from "@nextlyhq/ui";
|
|
4
4
|
import * as Lucide from "lucide-react";
|
|
5
5
|
import { ChevronLeft, ChevronRight, Columns3, Copy, Download, ExternalLink, Eye, Filter, Mail, Monitor, MoreHorizontal, Paperclip, Pencil, Plus, RotateCcw, Smartphone, Trash2, TriangleAlert, X } from "lucide-react";
|
|
@@ -388,6 +388,19 @@ function SubmissionSheet({ submission, form, canUpdate, onClose, onPrev, onNext,
|
|
|
388
388
|
*
|
|
389
389
|
* @module admin/components/submissions/SubmissionsView
|
|
390
390
|
*/
|
|
391
|
+
/**
|
|
392
|
+
* What a change to a submission sends: the change, with the version its row
|
|
393
|
+
* had when the list read it, so a change made from an older copy is refused
|
|
394
|
+
* rather than replacing what someone saved since.
|
|
395
|
+
*/
|
|
396
|
+
function submissionPatch(row, changes) {
|
|
397
|
+
return typeof row?._rev === "string" ? {
|
|
398
|
+
...changes,
|
|
399
|
+
_rev: row._rev
|
|
400
|
+
} : changes;
|
|
401
|
+
}
|
|
402
|
+
/** What a refused change says when someone saved the submission since. */
|
|
403
|
+
const SUBMISSION_CHANGED_SINCE = "Someone changed this submission since the list loaded. The list now shows their change; make yours again.";
|
|
391
404
|
const STATUS_TABS = [
|
|
392
405
|
{
|
|
393
406
|
value: "all",
|
|
@@ -469,7 +482,7 @@ function SubmissionsView({ collectionSlug }) {
|
|
|
469
482
|
const allForms = [];
|
|
470
483
|
const formsPageSize = 200;
|
|
471
484
|
for (let formsPage = 1;; formsPage += 1) {
|
|
472
|
-
const formsRes = await fetch(`/admin/api/collections/${resolved.forms}/entries?
|
|
485
|
+
const formsRes = await fetch(`/admin/api/collections/${resolved.forms}/entries?limit=${formsPageSize}&page=${formsPage}`, { credentials: "include" });
|
|
473
486
|
if (!formsRes.ok) break;
|
|
474
487
|
const items = (await formsRes.json()).items ?? [];
|
|
475
488
|
allForms.push(...items.map((item) => ({
|
|
@@ -513,7 +526,7 @@ function SubmissionsView({ collectionSlug }) {
|
|
|
513
526
|
else where.status = { equals: statusTab };
|
|
514
527
|
const params = new URLSearchParams({
|
|
515
528
|
page: String(page),
|
|
516
|
-
|
|
529
|
+
limit: String(PAGE_SIZE$1),
|
|
517
530
|
sortBy: "submittedAt",
|
|
518
531
|
sortOrder: "desc",
|
|
519
532
|
where: JSON.stringify(where)
|
|
@@ -592,14 +605,22 @@ function SubmissionsView({ collectionSlug }) {
|
|
|
592
605
|
formNameById,
|
|
593
606
|
hiddenFieldColumns
|
|
594
607
|
]);
|
|
608
|
+
const rowsNow = useRef(rows);
|
|
609
|
+
rowsNow.current = rows;
|
|
595
610
|
const patchSubmission = useCallback(async (id, body) => {
|
|
596
611
|
const res = await fetch(`/admin/api/collections/${submissionsSlug}/entries/${id}`, {
|
|
597
612
|
method: "PATCH",
|
|
598
613
|
headers: { "Content-Type": "application/json" },
|
|
599
614
|
credentials: "include",
|
|
600
|
-
body: JSON.stringify(body)
|
|
615
|
+
body: JSON.stringify(submissionPatch(rowsNow.current.find((row) => row.id === id), body))
|
|
601
616
|
});
|
|
602
|
-
if (!res.ok)
|
|
617
|
+
if (!res.ok) {
|
|
618
|
+
if ((await res.json().catch(() => null))?.error?.code === "STALE_VERSION") {
|
|
619
|
+
await fetchRows();
|
|
620
|
+
throw new Error(SUBMISSION_CHANGED_SINCE);
|
|
621
|
+
}
|
|
622
|
+
throw new Error(`Update failed (${res.status})`);
|
|
623
|
+
}
|
|
603
624
|
await fetchRows();
|
|
604
625
|
}, [submissionsSlug, fetchRows]);
|
|
605
626
|
const deleteSubmission = useCallback(async (id) => {
|
|
@@ -619,7 +640,7 @@ function SubmissionsView({ collectionSlug }) {
|
|
|
619
640
|
onSelect: (target) => void patchSubmission(target.id, {
|
|
620
641
|
status: "new",
|
|
621
642
|
spamReason: null
|
|
622
|
-
})
|
|
643
|
+
}).catch((reason) => setError(reason instanceof Error ? reason.message : "Update failed."))
|
|
623
644
|
});
|
|
624
645
|
if (canDelete) actions.push({
|
|
625
646
|
id: "delete",
|
|
@@ -2427,7 +2448,7 @@ async function fetchCanEditTemplates() {
|
|
|
2427
2448
|
if (!res.ok) return false;
|
|
2428
2449
|
const json = await res.json();
|
|
2429
2450
|
const held = json.permissions ?? [];
|
|
2430
|
-
return Boolean(json.isSuperAdmin) || held.includes("update-email-templates")
|
|
2451
|
+
return Boolean(json.isSuperAdmin) || held.includes("update-email-templates");
|
|
2431
2452
|
} catch {
|
|
2432
2453
|
return false;
|
|
2433
2454
|
}
|
|
@@ -4407,10 +4428,32 @@ function FormPreview({ fields, formData }) {
|
|
|
4407
4428
|
* @module admin/FormBuilderView
|
|
4408
4429
|
* @since 0.1.0
|
|
4409
4430
|
*/
|
|
4431
|
+
/**
|
|
4432
|
+
* The key a form's version travels under, as the admin reads and sends it.
|
|
4433
|
+
* Spelled here because the plugin reaches the admin only through the SDK,
|
|
4434
|
+
* which does not publish it.
|
|
4435
|
+
*/
|
|
4436
|
+
const DOCUMENT_VERSION_KEY = "_rev";
|
|
4437
|
+
/**
|
|
4438
|
+
* What a save sends: an existing form's save names the version the editor's
|
|
4439
|
+
* copy started from, where it has one, so a save from an older copy is refused.
|
|
4440
|
+
*/
|
|
4441
|
+
function saveBody(saveData, isCreating, startedFrom) {
|
|
4442
|
+
return isCreating || startedFrom === void 0 ? saveData : {
|
|
4443
|
+
...saveData,
|
|
4444
|
+
[DOCUMENT_VERSION_KEY]: startedFrom
|
|
4445
|
+
};
|
|
4446
|
+
}
|
|
4447
|
+
/** The version a save answered, or the copy's own where it names none. */
|
|
4448
|
+
function versionAfterSave(saved, previous) {
|
|
4449
|
+
const answered = saved[DOCUMENT_VERSION_KEY];
|
|
4450
|
+
return typeof answered === "string" ? answered : previous;
|
|
4451
|
+
}
|
|
4410
4452
|
function slugify(text) {
|
|
4411
4453
|
return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4412
4454
|
}
|
|
4413
|
-
function FormBuilderViewInner({ isCreating = false, collectionSlug = "forms", entryId, onSave, onSuccess, onCancel, documentLock }) {
|
|
4455
|
+
function FormBuilderViewInner({ isCreating = false, collectionSlug = "forms", entryId, onSave, onSuccess, onCancel, documentLock, version }) {
|
|
4456
|
+
const startedFrom = useRef(version);
|
|
4414
4457
|
const { fields, activeTab, isDirty, formData, settings, notifications, setActiveTab, addField, selectField, seedNotifications, updateFormData, markAsSaved } = useFormBuilder();
|
|
4415
4458
|
const queryClient = useQueryClient();
|
|
4416
4459
|
const [isSaving, setIsSaving] = useState(false);
|
|
@@ -4497,11 +4540,12 @@ function FormBuilderViewInner({ isCreating = false, collectionSlug = "forms", en
|
|
|
4497
4540
|
method: isCreating ? "POST" : "PATCH",
|
|
4498
4541
|
headers: { "Content-Type": "application/json" },
|
|
4499
4542
|
credentials: "include",
|
|
4500
|
-
body: JSON.stringify(saveData)
|
|
4543
|
+
body: JSON.stringify(saveBody(saveData, isCreating, startedFrom.current))
|
|
4501
4544
|
});
|
|
4502
4545
|
if (!response.ok) throw new Error(saveErrorMessage(await response.json().catch(() => ({})), response.statusText));
|
|
4503
4546
|
const result = await response.json();
|
|
4504
4547
|
const savedEntry = result.item ?? result;
|
|
4548
|
+
startedFrom.current = versionAfterSave(savedEntry, startedFrom.current);
|
|
4505
4549
|
queryClient.invalidateQueries({ queryKey: [
|
|
4506
4550
|
"entries",
|
|
4507
4551
|
"list",
|
|
@@ -4744,6 +4788,10 @@ function FormBuilderViewInner({ isCreating = false, collectionSlug = "forms", en
|
|
|
4744
4788
|
*/
|
|
4745
4789
|
function saveErrorMessage(body, statusText) {
|
|
4746
4790
|
const error = body?.error;
|
|
4791
|
+
if (error?.code === "STALE_VERSION") {
|
|
4792
|
+
const name = error.data?.changedBy?.name;
|
|
4793
|
+
return `${typeof name === "string" && name.trim() !== "" ? name.trim() : "Someone"} changed this form since you opened it. Reload to see their change; your edits are still here, not saved.`;
|
|
4794
|
+
}
|
|
4747
4795
|
return (error?.data?.errors ?? []).map((issue) => issue.message).filter((message) => Boolean(message)).join(" ") || error?.message || `Failed to save form: ${statusText}`;
|
|
4748
4796
|
}
|
|
4749
4797
|
function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess, onCancel, documentLock }) {
|
|
@@ -4771,11 +4819,144 @@ function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating,
|
|
|
4771
4819
|
onSave,
|
|
4772
4820
|
onSuccess,
|
|
4773
4821
|
onCancel,
|
|
4774
|
-
documentLock
|
|
4822
|
+
documentLock,
|
|
4823
|
+
version: initialData?._rev
|
|
4775
4824
|
})
|
|
4776
4825
|
}, providerKey);
|
|
4777
4826
|
}
|
|
4778
4827
|
|
|
4828
|
+
// src/dashboard/mark-read.ts
|
|
4829
|
+
/**
|
|
4830
|
+
* Marking a submission read when it is opened from the New form submissions
|
|
4831
|
+
* card: the status the submissions list sets, through the same collection
|
|
4832
|
+
* update the list's own status changes are sent through, as the reader.
|
|
4833
|
+
*
|
|
4834
|
+
* Sent as an update of the submissions that match the id AND are still new,
|
|
4835
|
+
* so a submission someone archived, flagged or read since the card loaded is
|
|
4836
|
+
* matched by nothing and keeps its status. The update is judged as every
|
|
4837
|
+
* update of the collection is (`update-<slug>` and its rule): a reader who
|
|
4838
|
+
* may not update submissions is refused, and the submission stays new.
|
|
4839
|
+
*
|
|
4840
|
+
* @module dashboard/mark-read
|
|
4841
|
+
*/
|
|
4842
|
+
/** The status an opened submission moves to, as the submissions list names it. */
|
|
4843
|
+
const READ_STATUS = "read";
|
|
4844
|
+
/** The admin's API root, which the submissions list sends its updates to. */
|
|
4845
|
+
const ADMIN_API = "/admin/api";
|
|
4846
|
+
/** The request that marks submission `id` of `collection` read while it is still new. */
|
|
4847
|
+
function markReadRequest(collection, id) {
|
|
4848
|
+
return {
|
|
4849
|
+
url: `${ADMIN_API}/collections/${encodeURIComponent(collection)}/entries`,
|
|
4850
|
+
init: {
|
|
4851
|
+
method: "PATCH",
|
|
4852
|
+
headers: { "Content-Type": "application/json" },
|
|
4853
|
+
credentials: "include",
|
|
4854
|
+
keepalive: true,
|
|
4855
|
+
body: JSON.stringify({
|
|
4856
|
+
where: {
|
|
4857
|
+
id: { equals: id },
|
|
4858
|
+
status: { equals: "new" }
|
|
4859
|
+
},
|
|
4860
|
+
data: {
|
|
4861
|
+
status: READ_STATUS,
|
|
4862
|
+
_overwrite: true
|
|
4863
|
+
}
|
|
4864
|
+
})
|
|
4865
|
+
}
|
|
4866
|
+
};
|
|
4867
|
+
}
|
|
4868
|
+
/**
|
|
4869
|
+
* Marks submission `id` read, answering whether the update was taken. A
|
|
4870
|
+
* refusal or a failed request answers `false` and leaves it new, which the
|
|
4871
|
+
* card and the list then still say; it never rejects.
|
|
4872
|
+
*/
|
|
4873
|
+
async function markRead(collection, id) {
|
|
4874
|
+
const { url, init } = markReadRequest(collection, id);
|
|
4875
|
+
try {
|
|
4876
|
+
return (await fetch(url, init)).ok;
|
|
4877
|
+
} catch {
|
|
4878
|
+
return false;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
// src/dashboard/NewSubmissionsCard.tsx
|
|
4883
|
+
/**
|
|
4884
|
+
* The New form submissions card's body: the newest new submissions as core's
|
|
4885
|
+
* list rows, each opening its submission and marking it read, with the
|
|
4886
|
+
* card's footer leading to every submission, and how many are new beside its
|
|
4887
|
+
* title. While nothing is new it says so, with a link to every submission,
|
|
4888
|
+
* and its title carries no count.
|
|
4889
|
+
*
|
|
4890
|
+
* Drawn only with data: the frame draws loading and every failure itself.
|
|
4891
|
+
* The empty state is drawn here rather than by the frame, because its link
|
|
4892
|
+
* is the submissions collection the site installed, which only the card's
|
|
4893
|
+
* data knows; the frame's would name the slug the plugin declared. Built from
|
|
4894
|
+
* the widget kit alone, so it reads like core's list cards beside it.
|
|
4895
|
+
*
|
|
4896
|
+
* @module dashboard/NewSubmissionsCard
|
|
4897
|
+
*/
|
|
4898
|
+
/** The mouse button that opens a link in a new tab. */
|
|
4899
|
+
const MIDDLE_BUTTON = 1;
|
|
4900
|
+
/** What a row says under its title: its form, and the first line of its first text answer. */
|
|
4901
|
+
function metaOf(row) {
|
|
4902
|
+
return [row.form, row.excerpt].filter((part) => part !== void 0);
|
|
4903
|
+
}
|
|
4904
|
+
/** The row whose link a click landed on, if it landed on one. */
|
|
4905
|
+
function openedRow(event, rows) {
|
|
4906
|
+
if (!(event.target instanceof Element)) return void 0;
|
|
4907
|
+
const href = event.target.closest("a[href]")?.getAttribute("href");
|
|
4908
|
+
return href === null || href === void 0 ? void 0 : rows.find((row) => row.href === href);
|
|
4909
|
+
}
|
|
4910
|
+
/**
|
|
4911
|
+
* Nothing new, with a way to every submission. Offered to whoever sees the
|
|
4912
|
+
* card: the card is shown only to a reader who may read the submissions
|
|
4913
|
+
* collection the site installed, which is where the link leads.
|
|
4914
|
+
*/
|
|
4915
|
+
function NothingNew({ allHref }) {
|
|
4916
|
+
return /* @__PURE__ */ jsx(FrameState, { state: {
|
|
4917
|
+
kind: "empty",
|
|
4918
|
+
empty: {
|
|
4919
|
+
title: "No new submissions",
|
|
4920
|
+
action: {
|
|
4921
|
+
label: "All submissions",
|
|
4922
|
+
href: allHref
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
} });
|
|
4926
|
+
}
|
|
4927
|
+
/** The card's rows, as many as its size holds. */
|
|
4928
|
+
function NewSubmissionsCard({ data }) {
|
|
4929
|
+
const now = useWidgetClock();
|
|
4930
|
+
const refresh = useRefreshDashboard();
|
|
4931
|
+
Widget.useTitleCount(data.total > 0 ? data.total : void 0, data.atLeast === true);
|
|
4932
|
+
if (data.total === 0) return /* @__PURE__ */ jsx(NothingNew, { allHref: data.allHref });
|
|
4933
|
+
const opened = (event) => {
|
|
4934
|
+
const row = openedRow(event, data.items);
|
|
4935
|
+
if (row === void 0) return;
|
|
4936
|
+
markRead(data.collection, row.id).then((taken) => {
|
|
4937
|
+
if (taken) refresh();
|
|
4938
|
+
});
|
|
4939
|
+
};
|
|
4940
|
+
return /* @__PURE__ */ jsx("div", {
|
|
4941
|
+
className: "contents",
|
|
4942
|
+
onClickCapture: opened,
|
|
4943
|
+
onAuxClickCapture: (event) => {
|
|
4944
|
+
if (event.button === MIDDLE_BUTTON) opened(event);
|
|
4945
|
+
},
|
|
4946
|
+
children: /* @__PURE__ */ jsx(Widget.List, {
|
|
4947
|
+
rows: data.items,
|
|
4948
|
+
title: (row) => row.title,
|
|
4949
|
+
href: (row) => row.href,
|
|
4950
|
+
meta: metaOf,
|
|
4951
|
+
trailing: (row) => row.at === void 0 ? void 0 : /* @__PURE__ */ jsx("time", {
|
|
4952
|
+
dateTime: row.at,
|
|
4953
|
+
children: formatWidgetTime(row.at, now)
|
|
4954
|
+
}),
|
|
4955
|
+
viewAllHref: data.allHref
|
|
4956
|
+
})
|
|
4957
|
+
});
|
|
4958
|
+
}
|
|
4959
|
+
|
|
4779
4960
|
// src/admin/index.ts
|
|
4780
4961
|
/**
|
|
4781
4962
|
* Form Builder Admin Components
|
|
@@ -4823,5 +5004,5 @@ registerKnownPlugin("@nextlyhq/plugin-form-builder", async () => {
|
|
|
4823
5004
|
});
|
|
4824
5005
|
});
|
|
4825
5006
|
|
|
4826
|
-
export { AddFieldDialog, DEFAULT_SETTINGS, FORM_BUILDER_VIEW_PATH, FieldCards, FieldEditor, FormBuilderProvider, FormBuilderView, FormNotificationsTab, FormPreview, FormSettingsTab, SUBMISSIONS_VIEW_PATH, SubmissionSheet, SubmissionsView, createFieldFromType, createNotification, generateFieldLabel, generateFieldName, useFormBuilder, useOptionalFormBuilder };
|
|
5007
|
+
export { AddFieldDialog, DEFAULT_SETTINGS, FORM_BUILDER_VIEW_PATH, FieldCards, FieldEditor, FormBuilderProvider, FormBuilderView, FormNotificationsTab, FormPreview, FormSettingsTab, NewSubmissionsCard, SUBMISSIONS_VIEW_PATH, SubmissionSheet, SubmissionsView, createFieldFromType, createNotification, generateFieldLabel, generateFieldName, useFormBuilder, useOptionalFormBuilder };
|
|
4827
5008
|
//# sourceMappingURL=index.js.map
|