strapi-plugin-hubspot 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/_chunks/{Forms-B2y_0-x4.mjs → Forms-77Mornxt.mjs} +115 -18
- package/dist/_chunks/{Forms-CaT0YEJo.js → Forms-B8kkPY0c.js} +133 -36
- package/dist/_chunks/HubspotFormInput-BVknnlmR.mjs +61 -0
- package/dist/_chunks/HubspotFormInput-kx3LlQYF.js +79 -0
- package/dist/_chunks/{HubspotObjectInput-DdLAUh0N.mjs → HubspotObjectInput-B-Y1PZ6c.mjs} +4 -3
- package/dist/_chunks/{HubspotObjectInput-Crpcpa8T.js → HubspotObjectInput-BOO1PvOj.js} +8 -7
- package/dist/_chunks/{HubspotPropertyInput-k7wMSmeF.mjs → HubspotPropertyInput-Drxn_Ddt.mjs} +4 -3
- package/dist/_chunks/{HubspotPropertyInput-SnJMFsII.js → HubspotPropertyInput-awfD1opH.js} +18 -17
- package/dist/_chunks/{Settings-BPAAD-QW.js → Settings-BT1NhvxO.js} +16 -15
- package/dist/_chunks/{Settings-BMOmj4NJ.mjs → Settings-DrujhMxS.mjs} +3 -2
- package/dist/_chunks/{en-C_-N8cjv.js → en-B8adhJhO.js} +17 -3
- package/dist/_chunks/{en-CJ9wYHgN.mjs → en-BYKKi1LK.mjs} +17 -3
- package/dist/_chunks/{fr-BHObPoUp.js → fr-DnKtGXaB.js} +17 -3
- package/dist/_chunks/{fr-DttDn-2Y.mjs → fr-DzgArgi3.mjs} +17 -3
- package/dist/_chunks/{objectLabels-C9ocOgVY.mjs → index-CEh8vkxY.mjs} +0 -14
- package/dist/_chunks/{objectLabels-VTt_-qTZ.js → index-DkTxsEqL.js} +0 -14
- package/dist/_chunks/{index-foVSGFWb.mjs → index-LrCSAHoH.mjs} +21 -5
- package/dist/_chunks/{index-D_CPrIHe.js → index-P7p8ASb6.js} +21 -5
- package/dist/_chunks/objectLabels-Dn-zriuZ.js +15 -0
- package/dist/_chunks/objectLabels-yNrnTOBo.mjs +16 -0
- package/dist/_chunks/{useHubspotSchema-B8SctALV.js → useHubspotSchema-BottzdRR.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-Du3rLY_O.mjs → useHubspotSchema-DccG2KbZ.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/builder/types.d.ts +1 -0
- package/dist/admin/src/components/HubspotFormInput.d.ts +29 -0
- package/dist/server/index.js +100 -8
- package/dist/server/index.mjs +100 -8
- package/dist/server/src/content-types.d.ts +3 -0
- package/dist/server/src/forms.d.ts +2 -0
- package/dist/server/src/formsAdmin.d.ts +13 -0
- package/dist/server/src/importLegacy.d.ts +1 -0
- package/dist/server/src/index.d.ts +5 -0
- package/dist/shared/types.d.ts +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0 — 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Improved (builder UX pass, from a live session)
|
|
6
|
+
- **The whole step card now selects the step** — the click target was the tiny
|
|
7
|
+
"Step N" text, which read as "step titles can't be edited". Inner controls
|
|
8
|
+
stop propagation, so field selection and the action buttons are unaffected.
|
|
9
|
+
- Field panel gains the imported-but-invisible settings: **icon**, **answer
|
|
10
|
+
memory (persist)** and **CSS classes**; the step and form panels gain **CSS
|
|
11
|
+
classes** too.
|
|
12
|
+
- **Form-level `class`** now exists end to end: content-type attribute, save,
|
|
13
|
+
public API, legacy import (it used to be silently dropped on migration).
|
|
14
|
+
- **Duplicate** action on the forms list — every locale of the draft is
|
|
15
|
+
copied under a fresh slug.
|
|
16
|
+
- Leaving the editor with unsaved changes now warns before the tab closes.
|
|
17
|
+
- Cosmetics: the actions column no longer shows a raw translation key, and the
|
|
18
|
+
structure column pluralizes properly.
|
|
19
|
+
|
|
20
|
+
## 0.7.0 — 2026-08-29
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- `hubspot.form-picker` custom field: a searchable select over the forms
|
|
24
|
+
built in the builder, storing the chosen form's **slug** as a plain string —
|
|
25
|
+
for host content that references a form (a hero block, a landing…).
|
|
26
|
+
Unpublished forms stay selectable but are flagged; a slug whose form was
|
|
27
|
+
deleted is kept and flagged instead of silently dropped; a fetch failure
|
|
28
|
+
degrades to free text. Fed by `GET /hubspot/forms-options`, open to any
|
|
29
|
+
authenticated admin (the builder itself stays RBAC-gated).
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- Removed an accidental self-dependency (`strapi-plugin-hubspot` listed in its
|
|
33
|
+
own `dependencies`) introduced by a stray `npm install`.
|
|
34
|
+
|
|
3
35
|
## 0.6.1 — 2026-08-28
|
|
4
36
|
|
|
5
37
|
### Fixed
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useParams, useSearchParams, Link, useNavigate, Routes, Route } from "react-router-dom";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { u as useIntl
|
|
4
|
+
import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
5
5
|
import { Typography, Flex, Box, SingleSelect, SingleSelectOption, TextInput, IconButton, Button, Field, Checkbox, Divider, Combobox, ComboboxOption, Loader, Badge, Textarea, Table, Thead, Tr, Th, Tbody, Td } from "@strapi/design-system";
|
|
6
|
-
import { Trash, Plus, ArrowClockwise, ArrowLeft, ArrowUp, ArrowDown } from "@strapi/icons";
|
|
6
|
+
import { Trash, Plus, ArrowClockwise, ArrowLeft, ArrowUp, ArrowDown, Duplicate } from "@strapi/icons";
|
|
7
7
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
8
|
-
import { g as getTranslation, P as PLUGIN_ID } from "./index-
|
|
9
|
-
import {
|
|
8
|
+
import { g as getTranslation, P as PLUGIN_ID } from "./index-LrCSAHoH.mjs";
|
|
9
|
+
import { o as objectLabel } from "./objectLabels-yNrnTOBo.mjs";
|
|
10
|
+
import { u as useHubspotSchema } from "./useHubspotSchema-DccG2KbZ.mjs";
|
|
10
11
|
const OPERATORS = ["eq", "neq", "contains", "empty", "notEmpty", "gt", "lt"];
|
|
11
12
|
const NEEDS_VALUE = /* @__PURE__ */ new Set(["eq", "neq", "contains", "gt", "lt"]);
|
|
12
13
|
const ConditionEditor = ({ condition, candidates, onChange }) => {
|
|
@@ -223,6 +224,43 @@ const FieldPanel = ({ field, candidates, problem, onChange }) => {
|
|
|
223
224
|
children: t("panel.required", "Required")
|
|
224
225
|
}
|
|
225
226
|
),
|
|
227
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 4, children: [
|
|
228
|
+
/* @__PURE__ */ jsx(Box, { flex: "1", children: /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
229
|
+
/* @__PURE__ */ jsx(Field.Label, { children: t("panel.icon", "Icon") }),
|
|
230
|
+
/* @__PURE__ */ jsx(
|
|
231
|
+
TextInput,
|
|
232
|
+
{
|
|
233
|
+
value: field.icon ?? "",
|
|
234
|
+
placeholder: "i-lucide-building-2",
|
|
235
|
+
onChange: (e) => onChange({ icon: e.target.value })
|
|
236
|
+
}
|
|
237
|
+
)
|
|
238
|
+
] }) }),
|
|
239
|
+
/* @__PURE__ */ jsx(Box, { flex: "1", children: /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
240
|
+
/* @__PURE__ */ jsx(Field.Label, { children: t("panel.persist", "Answer memory") }),
|
|
241
|
+
/* @__PURE__ */ jsxs(
|
|
242
|
+
SingleSelect,
|
|
243
|
+
{
|
|
244
|
+
value: field.persist ?? "session",
|
|
245
|
+
onChange: (v) => onChange({ persist: v }),
|
|
246
|
+
children: [
|
|
247
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "session", children: t("panel.persist-session", "This visit only") }),
|
|
248
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "days30", children: t("panel.persist-days30", "30 days (non-identifying fields only)") })
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
] }) })
|
|
253
|
+
] }),
|
|
254
|
+
/* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
255
|
+
/* @__PURE__ */ jsx(Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
256
|
+
/* @__PURE__ */ jsx(
|
|
257
|
+
TextInput,
|
|
258
|
+
{
|
|
259
|
+
value: field.class ?? "",
|
|
260
|
+
onChange: (e) => onChange({ class: e.target.value })
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
] }),
|
|
226
264
|
isChoice && /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
227
265
|
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: t("panel.options", "Choices") }),
|
|
228
266
|
(field.options ?? []).map((option, index) => /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
@@ -369,6 +407,14 @@ const FormEditor = () => {
|
|
|
369
407
|
const [feedback, setFeedback] = React.useState(null);
|
|
370
408
|
const t = (id, defaultMessage, values) => formatMessage({ id: getTranslation(id), defaultMessage }, values);
|
|
371
409
|
const query = locale ? `?locale=${locale}` : "";
|
|
410
|
+
React.useEffect(() => {
|
|
411
|
+
if (!dirty) return void 0;
|
|
412
|
+
const warn = (event) => {
|
|
413
|
+
event.preventDefault();
|
|
414
|
+
};
|
|
415
|
+
window.addEventListener("beforeunload", warn);
|
|
416
|
+
return () => window.removeEventListener("beforeunload", warn);
|
|
417
|
+
}, [dirty]);
|
|
372
418
|
React.useEffect(() => {
|
|
373
419
|
get("/i18n/locales").then(({ data }) => Array.isArray(data) && setLocales(data)).catch(() => setLocales([]));
|
|
374
420
|
}, [get]);
|
|
@@ -461,6 +507,7 @@ const FormEditor = () => {
|
|
|
461
507
|
nextLabel: entry.nextLabel,
|
|
462
508
|
submitLabel: entry.submitLabel,
|
|
463
509
|
successMessage: entry.successMessage,
|
|
510
|
+
class: entry.class,
|
|
464
511
|
definition
|
|
465
512
|
}
|
|
466
513
|
);
|
|
@@ -566,6 +613,8 @@ const FormEditor = () => {
|
|
|
566
613
|
hasRadius: true,
|
|
567
614
|
shadow: "tableShadow",
|
|
568
615
|
padding: 4,
|
|
616
|
+
onClick: () => setSelection({ kind: "step", stepId: step.id }),
|
|
617
|
+
style: { cursor: "pointer" },
|
|
569
618
|
borderColor: selection.kind === "step" && selection.stepId === step.id ? "primary600" : void 0,
|
|
570
619
|
borderStyle: selection.kind === "step" && selection.stepId === step.id ? "solid" : void 0,
|
|
571
620
|
borderWidth: selection.kind === "step" && selection.stepId === step.id ? "1px" : void 0,
|
|
@@ -588,7 +637,7 @@ const FormEditor = () => {
|
|
|
588
637
|
]
|
|
589
638
|
}
|
|
590
639
|
),
|
|
591
|
-
/* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
|
|
640
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 1, onClick: (e) => e.stopPropagation(), children: [
|
|
592
641
|
/* @__PURE__ */ jsx(
|
|
593
642
|
IconButton,
|
|
594
643
|
{
|
|
@@ -630,7 +679,10 @@ const FormEditor = () => {
|
|
|
630
679
|
background: isSelected ? "primary100" : "neutral100",
|
|
631
680
|
hasRadius: true,
|
|
632
681
|
padding: 3,
|
|
633
|
-
onClick: () =>
|
|
682
|
+
onClick: (e) => {
|
|
683
|
+
e.stopPropagation();
|
|
684
|
+
setSelection({ kind: "field", fieldId: field.id });
|
|
685
|
+
},
|
|
634
686
|
style: { cursor: "pointer" },
|
|
635
687
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
636
688
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
@@ -688,7 +740,8 @@ const FormEditor = () => {
|
|
|
688
740
|
{
|
|
689
741
|
variant: "tertiary",
|
|
690
742
|
startIcon: /* @__PURE__ */ jsx(Plus, {}),
|
|
691
|
-
onClick: () => {
|
|
743
|
+
onClick: (e) => {
|
|
744
|
+
e.stopPropagation();
|
|
692
745
|
const field = newField(t("editor.new-field", "New field"));
|
|
693
746
|
patchStep(step.id, { fields: [...step.fields, field] });
|
|
694
747
|
setSelection({ kind: "field", fieldId: field.id });
|
|
@@ -745,6 +798,16 @@ const FormEditor = () => {
|
|
|
745
798
|
}
|
|
746
799
|
)
|
|
747
800
|
] }),
|
|
801
|
+
/* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
802
|
+
/* @__PURE__ */ jsx(Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
803
|
+
/* @__PURE__ */ jsx(
|
|
804
|
+
TextInput,
|
|
805
|
+
{
|
|
806
|
+
value: selectedStep.class ?? "",
|
|
807
|
+
onChange: (e) => patchStep(selectedStep.id, { class: e.target.value })
|
|
808
|
+
}
|
|
809
|
+
)
|
|
810
|
+
] }),
|
|
748
811
|
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: t("editor.step-condition", "Show this step only when…") }),
|
|
749
812
|
/* @__PURE__ */ jsx(
|
|
750
813
|
ConditionEditor,
|
|
@@ -818,6 +881,16 @@ const FormEditor = () => {
|
|
|
818
881
|
}
|
|
819
882
|
)
|
|
820
883
|
] }),
|
|
884
|
+
/* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
885
|
+
/* @__PURE__ */ jsx(Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
886
|
+
/* @__PURE__ */ jsx(
|
|
887
|
+
TextInput,
|
|
888
|
+
{
|
|
889
|
+
value: entry.class ?? "",
|
|
890
|
+
onChange: (e) => patchEntry({ class: e.target.value })
|
|
891
|
+
}
|
|
892
|
+
)
|
|
893
|
+
] }),
|
|
821
894
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
822
895
|
"editor.form-hint",
|
|
823
896
|
"Select a step or a field to edit it. The public endpoint serves this form at /api/hubspot/forms/{slug}.",
|
|
@@ -877,6 +950,19 @@ const FormsList = () => {
|
|
|
877
950
|
setBusy(false);
|
|
878
951
|
}
|
|
879
952
|
};
|
|
953
|
+
const duplicate = async (row) => {
|
|
954
|
+
setBusy(true);
|
|
955
|
+
setError(null);
|
|
956
|
+
try {
|
|
957
|
+
const { data } = await post(
|
|
958
|
+
`/${PLUGIN_ID}/builder/forms/${row.documentId}/duplicate`
|
|
959
|
+
);
|
|
960
|
+
navigate(data.documentId);
|
|
961
|
+
} catch {
|
|
962
|
+
setError(t("forms.duplicate-error", "Could not duplicate the form."));
|
|
963
|
+
setBusy(false);
|
|
964
|
+
}
|
|
965
|
+
};
|
|
880
966
|
const remove = async (row) => {
|
|
881
967
|
if (!window.confirm(t("forms.delete-confirm", 'Delete "{name}" and all its locales?', { name: row.name }))) {
|
|
882
968
|
return;
|
|
@@ -948,7 +1034,7 @@ const FormsList = () => {
|
|
|
948
1034
|
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: t("forms.col-structure", "Structure") }) }),
|
|
949
1035
|
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: t("forms.col-status", "Status") }) }),
|
|
950
1036
|
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: t("forms.col-updated", "Updated") }) }),
|
|
951
|
-
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: t("forms.col-actions", "") }) })
|
|
1037
|
+
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: t("forms.col-actions", "Actions") }) })
|
|
952
1038
|
] }) }),
|
|
953
1039
|
/* @__PURE__ */ jsx(Tbody, { children: rows.map((row) => /* @__PURE__ */ jsxs(
|
|
954
1040
|
Tr,
|
|
@@ -958,21 +1044,32 @@ const FormsList = () => {
|
|
|
958
1044
|
children: [
|
|
959
1045
|
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: row.name }) }),
|
|
960
1046
|
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: row.slug }) }),
|
|
961
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: t("forms.structure", "{steps} steps · {fields} fields", {
|
|
1047
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: t("forms.structure", "{steps, plural, one {# step} other {# steps}} · {fields, plural, one {# field} other {# fields}}", {
|
|
962
1048
|
steps: row.steps,
|
|
963
1049
|
fields: row.fields
|
|
964
1050
|
}) }) }),
|
|
965
1051
|
/* @__PURE__ */ jsx(Td, { children: row.published ? /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", children: t("forms.published", "Published") }) : /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: t("forms.draft", "Draft") }) }),
|
|
966
1052
|
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: row.updatedAt ? new Date(row.updatedAt).toLocaleString() : "—" }) }),
|
|
967
|
-
/* @__PURE__ */ jsx(Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1053
|
+
/* @__PURE__ */ jsx(Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
|
|
1054
|
+
/* @__PURE__ */ jsx(
|
|
1055
|
+
IconButton,
|
|
1056
|
+
{
|
|
1057
|
+
label: t("forms.duplicate", "Duplicate"),
|
|
1058
|
+
onClick: () => duplicate(row),
|
|
1059
|
+
disabled: busy,
|
|
1060
|
+
children: /* @__PURE__ */ jsx(Duplicate, {})
|
|
1061
|
+
}
|
|
1062
|
+
),
|
|
1063
|
+
/* @__PURE__ */ jsx(
|
|
1064
|
+
IconButton,
|
|
1065
|
+
{
|
|
1066
|
+
label: t("forms.delete", "Delete"),
|
|
1067
|
+
onClick: () => remove(row),
|
|
1068
|
+
disabled: busy,
|
|
1069
|
+
children: /* @__PURE__ */ jsx(Trash, {})
|
|
1070
|
+
}
|
|
1071
|
+
)
|
|
1072
|
+
] }) })
|
|
976
1073
|
]
|
|
977
1074
|
},
|
|
978
1075
|
row.documentId
|
|
@@ -3,12 +3,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const reactRouterDom = require("react-router-dom");
|
|
5
5
|
const React = require("react");
|
|
6
|
-
const
|
|
6
|
+
const index = require("./index-DkTxsEqL.js");
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const admin = require("@strapi/strapi/admin");
|
|
10
|
-
const index = require("./index-
|
|
11
|
-
const
|
|
10
|
+
const index$1 = require("./index-P7p8ASb6.js");
|
|
11
|
+
const objectLabels = require("./objectLabels-Dn-zriuZ.js");
|
|
12
|
+
const useHubspotSchema = require("./useHubspotSchema-BottzdRR.js");
|
|
12
13
|
function _interopNamespace(e) {
|
|
13
14
|
if (e && e.__esModule) return e;
|
|
14
15
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -30,8 +31,8 @@ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
|
|
30
31
|
const OPERATORS = ["eq", "neq", "contains", "empty", "notEmpty", "gt", "lt"];
|
|
31
32
|
const NEEDS_VALUE = /* @__PURE__ */ new Set(["eq", "neq", "contains", "gt", "lt"]);
|
|
32
33
|
const ConditionEditor = ({ condition, candidates, onChange }) => {
|
|
33
|
-
const { formatMessage } =
|
|
34
|
-
const t = (id, defaultMessage) => formatMessage({ id: index.getTranslation(id), defaultMessage });
|
|
34
|
+
const { formatMessage } = index.useIntl();
|
|
35
|
+
const t = (id, defaultMessage) => formatMessage({ id: index$1.getTranslation(id), defaultMessage });
|
|
35
36
|
const opLabel = {
|
|
36
37
|
eq: t("condition.op.eq", "is"),
|
|
37
38
|
neq: t("condition.op.neq", "is not"),
|
|
@@ -146,10 +147,10 @@ function fieldsBefore(definition, beforeId) {
|
|
|
146
147
|
}
|
|
147
148
|
const slugifyName = (label) => label.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
148
149
|
const FieldPanel = ({ field, candidates, problem, onChange }) => {
|
|
149
|
-
const intl =
|
|
150
|
+
const intl = index.useIntl();
|
|
150
151
|
const { formatMessage } = intl;
|
|
151
152
|
const { schema, refresh, refreshing } = useHubspotSchema.useHubspotSchema();
|
|
152
|
-
const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
|
|
153
|
+
const t = (id, defaultMessage, values) => formatMessage({ id: index$1.getTranslation(id), defaultMessage }, values);
|
|
153
154
|
const object = field.hubspot?.object || "contact";
|
|
154
155
|
const properties = (schema?.properties ?? []).filter((p) => p.object === object);
|
|
155
156
|
const selected = properties.find((p) => p.name === field.hubspot?.property);
|
|
@@ -243,6 +244,43 @@ const FieldPanel = ({ field, candidates, problem, onChange }) => {
|
|
|
243
244
|
children: t("panel.required", "Required")
|
|
244
245
|
}
|
|
245
246
|
),
|
|
247
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, children: [
|
|
248
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
249
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("panel.icon", "Icon") }),
|
|
250
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
251
|
+
designSystem.TextInput,
|
|
252
|
+
{
|
|
253
|
+
value: field.icon ?? "",
|
|
254
|
+
placeholder: "i-lucide-building-2",
|
|
255
|
+
onChange: (e) => onChange({ icon: e.target.value })
|
|
256
|
+
}
|
|
257
|
+
)
|
|
258
|
+
] }) }),
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
260
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("panel.persist", "Answer memory") }),
|
|
261
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
262
|
+
designSystem.SingleSelect,
|
|
263
|
+
{
|
|
264
|
+
value: field.persist ?? "session",
|
|
265
|
+
onChange: (v) => onChange({ persist: v }),
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "session", children: t("panel.persist-session", "This visit only") }),
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "days30", children: t("panel.persist-days30", "30 days (non-identifying fields only)") })
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
] }) })
|
|
273
|
+
] }),
|
|
274
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
275
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
276
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
277
|
+
designSystem.TextInput,
|
|
278
|
+
{
|
|
279
|
+
value: field.class ?? "",
|
|
280
|
+
onChange: (e) => onChange({ class: e.target.value })
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
] }),
|
|
246
284
|
isChoice && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
247
285
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", children: t("panel.options", "Choices") }),
|
|
248
286
|
(field.options ?? []).map((option, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
@@ -373,7 +411,7 @@ const newField = (label) => ({
|
|
|
373
411
|
});
|
|
374
412
|
const newStep = () => ({ id: makeId("stp"), title: "", fields: [] });
|
|
375
413
|
const FormEditor = () => {
|
|
376
|
-
const { formatMessage } =
|
|
414
|
+
const { formatMessage } = index.useIntl();
|
|
377
415
|
const { get, post, put } = admin.useFetchClient();
|
|
378
416
|
const { documentId } = reactRouterDom.useParams();
|
|
379
417
|
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
@@ -387,8 +425,16 @@ const FormEditor = () => {
|
|
|
387
425
|
const [errors, setErrors] = React__namespace.useState([]);
|
|
388
426
|
const [problems, setProblems] = React__namespace.useState([]);
|
|
389
427
|
const [feedback, setFeedback] = React__namespace.useState(null);
|
|
390
|
-
const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
|
|
428
|
+
const t = (id, defaultMessage, values) => formatMessage({ id: index$1.getTranslation(id), defaultMessage }, values);
|
|
391
429
|
const query = locale ? `?locale=${locale}` : "";
|
|
430
|
+
React__namespace.useEffect(() => {
|
|
431
|
+
if (!dirty) return void 0;
|
|
432
|
+
const warn = (event) => {
|
|
433
|
+
event.preventDefault();
|
|
434
|
+
};
|
|
435
|
+
window.addEventListener("beforeunload", warn);
|
|
436
|
+
return () => window.removeEventListener("beforeunload", warn);
|
|
437
|
+
}, [dirty]);
|
|
392
438
|
React__namespace.useEffect(() => {
|
|
393
439
|
get("/i18n/locales").then(({ data }) => Array.isArray(data) && setLocales(data)).catch(() => setLocales([]));
|
|
394
440
|
}, [get]);
|
|
@@ -399,7 +445,7 @@ const FormEditor = () => {
|
|
|
399
445
|
setErrors([]);
|
|
400
446
|
setProblems([]);
|
|
401
447
|
get(
|
|
402
|
-
`/${index.PLUGIN_ID}/builder/forms/${documentId}${query}`
|
|
448
|
+
`/${index$1.PLUGIN_ID}/builder/forms/${documentId}${query}`
|
|
403
449
|
).then(({ data }) => {
|
|
404
450
|
if (cancelled) return;
|
|
405
451
|
setEntry(data.form);
|
|
@@ -409,7 +455,7 @@ const FormEditor = () => {
|
|
|
409
455
|
if (cancelled || !locale) return;
|
|
410
456
|
try {
|
|
411
457
|
const { data } = await get(
|
|
412
|
-
`/${index.PLUGIN_ID}/builder/forms/${documentId}`
|
|
458
|
+
`/${index$1.PLUGIN_ID}/builder/forms/${documentId}`
|
|
413
459
|
);
|
|
414
460
|
if (cancelled) return;
|
|
415
461
|
setEntry({ ...data.form, locale });
|
|
@@ -473,7 +519,7 @@ const FormEditor = () => {
|
|
|
473
519
|
setErrors([]);
|
|
474
520
|
try {
|
|
475
521
|
const { data } = await put(
|
|
476
|
-
`/${index.PLUGIN_ID}/builder/forms/${documentId}${query}`,
|
|
522
|
+
`/${index$1.PLUGIN_ID}/builder/forms/${documentId}${query}`,
|
|
477
523
|
{
|
|
478
524
|
name: entry.name,
|
|
479
525
|
title: entry.title,
|
|
@@ -481,6 +527,7 @@ const FormEditor = () => {
|
|
|
481
527
|
nextLabel: entry.nextLabel,
|
|
482
528
|
submitLabel: entry.submitLabel,
|
|
483
529
|
successMessage: entry.successMessage,
|
|
530
|
+
class: entry.class,
|
|
484
531
|
definition
|
|
485
532
|
}
|
|
486
533
|
);
|
|
@@ -506,7 +553,7 @@ const FormEditor = () => {
|
|
|
506
553
|
setBusy(true);
|
|
507
554
|
setFeedback(null);
|
|
508
555
|
try {
|
|
509
|
-
await post(`/${index.PLUGIN_ID}/builder/forms/${documentId}/publish${query}`);
|
|
556
|
+
await post(`/${index$1.PLUGIN_ID}/builder/forms/${documentId}/publish${query}`);
|
|
510
557
|
setPublished(true);
|
|
511
558
|
setErrors([]);
|
|
512
559
|
setProblems([]);
|
|
@@ -526,7 +573,7 @@ const FormEditor = () => {
|
|
|
526
573
|
const unpublish = async () => {
|
|
527
574
|
setBusy(true);
|
|
528
575
|
try {
|
|
529
|
-
await post(`/${index.PLUGIN_ID}/builder/forms/${documentId}/unpublish${query}`);
|
|
576
|
+
await post(`/${index$1.PLUGIN_ID}/builder/forms/${documentId}/unpublish${query}`);
|
|
530
577
|
setPublished(false);
|
|
531
578
|
setFeedback({ tone: "success", text: t("editor.unpublished", "Form unpublished.") });
|
|
532
579
|
} catch {
|
|
@@ -544,7 +591,7 @@ const FormEditor = () => {
|
|
|
544
591
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
|
|
545
592
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", paddingBottom: 4, children: [
|
|
546
593
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
|
|
547
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: `/plugins/${index.PLUGIN_ID}`, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.IconButton, { label: t("editor.back", "Back to the list"), tag: "span", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}) }) }),
|
|
594
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: `/plugins/${index$1.PLUGIN_ID}`, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.IconButton, { label: t("editor.back", "Back to the list"), tag: "span", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}) }) }),
|
|
548
595
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
|
|
549
596
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
|
|
550
597
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h1", children: entry.name }),
|
|
@@ -586,6 +633,8 @@ const FormEditor = () => {
|
|
|
586
633
|
hasRadius: true,
|
|
587
634
|
shadow: "tableShadow",
|
|
588
635
|
padding: 4,
|
|
636
|
+
onClick: () => setSelection({ kind: "step", stepId: step.id }),
|
|
637
|
+
style: { cursor: "pointer" },
|
|
589
638
|
borderColor: selection.kind === "step" && selection.stepId === step.id ? "primary600" : void 0,
|
|
590
639
|
borderStyle: selection.kind === "step" && selection.stepId === step.id ? "solid" : void 0,
|
|
591
640
|
borderWidth: selection.kind === "step" && selection.stepId === step.id ? "1px" : void 0,
|
|
@@ -608,7 +657,7 @@ const FormEditor = () => {
|
|
|
608
657
|
]
|
|
609
658
|
}
|
|
610
659
|
),
|
|
611
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, children: [
|
|
660
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, onClick: (e) => e.stopPropagation(), children: [
|
|
612
661
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
613
662
|
designSystem.IconButton,
|
|
614
663
|
{
|
|
@@ -650,7 +699,10 @@ const FormEditor = () => {
|
|
|
650
699
|
background: isSelected ? "primary100" : "neutral100",
|
|
651
700
|
hasRadius: true,
|
|
652
701
|
padding: 3,
|
|
653
|
-
onClick: () =>
|
|
702
|
+
onClick: (e) => {
|
|
703
|
+
e.stopPropagation();
|
|
704
|
+
setSelection({ kind: "field", fieldId: field.id });
|
|
705
|
+
},
|
|
654
706
|
style: { cursor: "pointer" },
|
|
655
707
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
656
708
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
@@ -708,7 +760,8 @@ const FormEditor = () => {
|
|
|
708
760
|
{
|
|
709
761
|
variant: "tertiary",
|
|
710
762
|
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
|
|
711
|
-
onClick: () => {
|
|
763
|
+
onClick: (e) => {
|
|
764
|
+
e.stopPropagation();
|
|
712
765
|
const field = newField(t("editor.new-field", "New field"));
|
|
713
766
|
patchStep(step.id, { fields: [...step.fields, field] });
|
|
714
767
|
setSelection({ kind: "field", fieldId: field.id });
|
|
@@ -765,6 +818,16 @@ const FormEditor = () => {
|
|
|
765
818
|
}
|
|
766
819
|
)
|
|
767
820
|
] }),
|
|
821
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
823
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
824
|
+
designSystem.TextInput,
|
|
825
|
+
{
|
|
826
|
+
value: selectedStep.class ?? "",
|
|
827
|
+
onChange: (e) => patchStep(selectedStep.id, { class: e.target.value })
|
|
828
|
+
}
|
|
829
|
+
)
|
|
830
|
+
] }),
|
|
768
831
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", children: t("editor.step-condition", "Show this step only when…") }),
|
|
769
832
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
770
833
|
ConditionEditor,
|
|
@@ -838,6 +901,16 @@ const FormEditor = () => {
|
|
|
838
901
|
}
|
|
839
902
|
)
|
|
840
903
|
] }),
|
|
904
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
905
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("panel.class", "CSS classes") }),
|
|
906
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
907
|
+
designSystem.TextInput,
|
|
908
|
+
{
|
|
909
|
+
value: entry.class ?? "",
|
|
910
|
+
onChange: (e) => patchEntry({ class: e.target.value })
|
|
911
|
+
}
|
|
912
|
+
)
|
|
913
|
+
] }),
|
|
841
914
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
842
915
|
"editor.form-hint",
|
|
843
916
|
"Select a step or a field to edit it. The public endpoint serves this form at /api/hubspot/forms/{slug}.",
|
|
@@ -848,7 +921,7 @@ const FormEditor = () => {
|
|
|
848
921
|
] });
|
|
849
922
|
};
|
|
850
923
|
const FormsList = () => {
|
|
851
|
-
const { formatMessage } =
|
|
924
|
+
const { formatMessage } = index.useIntl();
|
|
852
925
|
const { get, post, del } = admin.useFetchClient();
|
|
853
926
|
const navigate = reactRouterDom.useNavigate();
|
|
854
927
|
const [rows, setRows] = React__namespace.useState(null);
|
|
@@ -857,15 +930,15 @@ const FormsList = () => {
|
|
|
857
930
|
const [error, setError] = React__namespace.useState(null);
|
|
858
931
|
const [sources, setSources] = React__namespace.useState([]);
|
|
859
932
|
const [sourceId, setSourceId] = React__namespace.useState("");
|
|
860
|
-
const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
|
|
933
|
+
const t = (id, defaultMessage, values) => formatMessage({ id: index$1.getTranslation(id), defaultMessage }, values);
|
|
861
934
|
const load = React__namespace.useCallback(async () => {
|
|
862
|
-
const { data } = await get(`/${index.PLUGIN_ID}/builder/forms`);
|
|
935
|
+
const { data } = await get(`/${index$1.PLUGIN_ID}/builder/forms`);
|
|
863
936
|
setRows(data.forms);
|
|
864
937
|
}, [get]);
|
|
865
938
|
React__namespace.useEffect(() => {
|
|
866
939
|
load().catch(() => setError(t("forms.load-error", "Could not load the forms.")));
|
|
867
940
|
get(
|
|
868
|
-
`/${index.PLUGIN_ID}/builder/import/sources`
|
|
941
|
+
`/${index$1.PLUGIN_ID}/builder/import/sources`
|
|
869
942
|
).then(({ data }) => setSources(data.sources ?? [])).catch(() => setSources([]));
|
|
870
943
|
}, [load]);
|
|
871
944
|
const runImport = async () => {
|
|
@@ -873,7 +946,7 @@ const FormsList = () => {
|
|
|
873
946
|
setBusy(true);
|
|
874
947
|
setError(null);
|
|
875
948
|
try {
|
|
876
|
-
const { data } = await post(`/${index.PLUGIN_ID}/builder/import`, {
|
|
949
|
+
const { data } = await post(`/${index$1.PLUGIN_ID}/builder/import`, {
|
|
877
950
|
documentId: sourceId
|
|
878
951
|
});
|
|
879
952
|
navigate(data.documentId);
|
|
@@ -888,7 +961,7 @@ const FormsList = () => {
|
|
|
888
961
|
setError(null);
|
|
889
962
|
try {
|
|
890
963
|
const { data } = await post(
|
|
891
|
-
`/${index.PLUGIN_ID}/builder/forms`,
|
|
964
|
+
`/${index$1.PLUGIN_ID}/builder/forms`,
|
|
892
965
|
{ name: name.trim() }
|
|
893
966
|
);
|
|
894
967
|
navigate(data.form.documentId);
|
|
@@ -897,13 +970,26 @@ const FormsList = () => {
|
|
|
897
970
|
setBusy(false);
|
|
898
971
|
}
|
|
899
972
|
};
|
|
973
|
+
const duplicate = async (row) => {
|
|
974
|
+
setBusy(true);
|
|
975
|
+
setError(null);
|
|
976
|
+
try {
|
|
977
|
+
const { data } = await post(
|
|
978
|
+
`/${index$1.PLUGIN_ID}/builder/forms/${row.documentId}/duplicate`
|
|
979
|
+
);
|
|
980
|
+
navigate(data.documentId);
|
|
981
|
+
} catch {
|
|
982
|
+
setError(t("forms.duplicate-error", "Could not duplicate the form."));
|
|
983
|
+
setBusy(false);
|
|
984
|
+
}
|
|
985
|
+
};
|
|
900
986
|
const remove = async (row) => {
|
|
901
987
|
if (!window.confirm(t("forms.delete-confirm", 'Delete "{name}" and all its locales?', { name: row.name }))) {
|
|
902
988
|
return;
|
|
903
989
|
}
|
|
904
990
|
setBusy(true);
|
|
905
991
|
try {
|
|
906
|
-
await del(`/${index.PLUGIN_ID}/builder/forms/${row.documentId}`);
|
|
992
|
+
await del(`/${index$1.PLUGIN_ID}/builder/forms/${row.documentId}`);
|
|
907
993
|
await load();
|
|
908
994
|
} catch {
|
|
909
995
|
setError(t("forms.delete-error", "Could not delete the form."));
|
|
@@ -968,7 +1054,7 @@ const FormsList = () => {
|
|
|
968
1054
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: t("forms.col-structure", "Structure") }) }),
|
|
969
1055
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: t("forms.col-status", "Status") }) }),
|
|
970
1056
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: t("forms.col-updated", "Updated") }) }),
|
|
971
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: t("forms.col-actions", "") }) })
|
|
1057
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: t("forms.col-actions", "Actions") }) })
|
|
972
1058
|
] }) }),
|
|
973
1059
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: rows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
974
1060
|
designSystem.Tr,
|
|
@@ -978,21 +1064,32 @@ const FormsList = () => {
|
|
|
978
1064
|
children: [
|
|
979
1065
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: row.name }) }),
|
|
980
1066
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: row.slug }) }),
|
|
981
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: t("forms.structure", "{steps} steps · {fields} fields", {
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: t("forms.structure", "{steps, plural, one {# step} other {# steps}} · {fields, plural, one {# field} other {# fields}}", {
|
|
982
1068
|
steps: row.steps,
|
|
983
1069
|
fields: row.fields
|
|
984
1070
|
}) }) }),
|
|
985
1071
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: row.published ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: t("forms.published", "Published") }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: t("forms.draft", "Draft") }) }),
|
|
986
1072
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: row.updatedAt ? new Date(row.updatedAt).toLocaleString() : "—" }) }),
|
|
987
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1073
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, children: [
|
|
1074
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1075
|
+
designSystem.IconButton,
|
|
1076
|
+
{
|
|
1077
|
+
label: t("forms.duplicate", "Duplicate"),
|
|
1078
|
+
onClick: () => duplicate(row),
|
|
1079
|
+
disabled: busy,
|
|
1080
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Duplicate, {})
|
|
1081
|
+
}
|
|
1082
|
+
),
|
|
1083
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1084
|
+
designSystem.IconButton,
|
|
1085
|
+
{
|
|
1086
|
+
label: t("forms.delete", "Delete"),
|
|
1087
|
+
onClick: () => remove(row),
|
|
1088
|
+
disabled: busy,
|
|
1089
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1092
|
+
] }) })
|
|
996
1093
|
]
|
|
997
1094
|
},
|
|
998
1095
|
row.documentId
|