strapi-plugin-hubspot 0.16.0 → 0.16.2
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 +15 -0
- package/README.md +4 -4
- package/dist/_chunks/{Forms-6EoEYzAc.mjs → Forms-BOQWely0.mjs} +240 -114
- package/dist/_chunks/{Forms-BW_zGc1P.js → Forms-mMNP7hc9.js} +238 -112
- package/dist/_chunks/{HubspotFormInput-V5w4y1fb.mjs → HubspotFormInput-DCkoavrN.mjs} +1 -1
- package/dist/_chunks/{HubspotFormInput-oMhm1UJm.js → HubspotFormInput-DI35Aqiu.js} +1 -1
- package/dist/_chunks/{HubspotObjectInput-DhsnSguG.mjs → HubspotObjectInput-BbnvhdbD.mjs} +3 -3
- package/dist/_chunks/{HubspotObjectInput-Bmo6YQgs.js → HubspotObjectInput-Cq1TuL_l.js} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-CrYP4pc0.mjs → HubspotPropertyInput-BHfpBD36.mjs} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-luFfnxqy.js → HubspotPropertyInput-BLZzsW08.js} +3 -3
- package/dist/_chunks/{Settings-B3A22i7Z.js → Settings-BAsx0LGv.js} +2 -2
- package/dist/_chunks/{Settings-CjcWj9I6.mjs → Settings-DqRpHtnT.mjs} +2 -2
- package/dist/_chunks/{en-D6GHgMOt.mjs → en-Djd3TID0.mjs} +7 -3
- package/dist/_chunks/{en-C7ls2EUl.js → en-sfzopB5K.js} +7 -3
- package/dist/_chunks/{fr-CfohMY8n.mjs → fr-C7t1elmR.mjs} +7 -3
- package/dist/_chunks/{fr-pOP8ZXqM.js → fr-sF5Josfh.js} +7 -3
- package/dist/_chunks/{index-7cL9PRh1.mjs → index-CLAy5dVN.mjs} +6 -6
- package/dist/_chunks/{index-CodpLKZx.js → index-R3ReZXF1.js} +6 -6
- package/dist/_chunks/{objectLabels-Dnj14fsp.mjs → objectLabels--zOmqsfm.mjs} +1 -1
- package/dist/_chunks/{objectLabels-CSWGIgNb.js → objectLabels-CW2iBOkD.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-DiRN3HrN.js → useHubspotSchema-BRzzvs9t.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-BsmQgJgx.mjs → useHubspotSchema-Bz2o1BU-.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/builder/Sortable.d.ts +25 -12
- package/dist/admin/src/builder/__tests__/relocateField.test.d.ts +1 -0
- package/dist/admin/src/builder/relocateField.d.ts +14 -0
- package/dist/server/index.js +129 -12
- package/dist/server/index.mjs +129 -12
- package/dist/server/src/formsAdmin.d.ts +8 -3
- package/dist/server/src/importHubspot.d.ts +12 -0
- package/dist/server/src/index.d.ts +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.16.2 — 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Resync from HubSpot** in the form editor (and a safer list re-import):
|
|
9
|
+
mapped fields update in place (label, type, required, options), new HubSpot
|
|
10
|
+
fields append to the last step, Strapi steps / conditions / extra fields
|
|
11
|
+
stay. Matching uses the linked form GUID rather than the slug.
|
|
12
|
+
|
|
13
|
+
## 0.16.1 — 2026-09-22
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Fields in the builder can be dragged from one step to another (the grip
|
|
17
|
+
handle is no longer limited to reordering inside the current step). Arrow
|
|
18
|
+
buttons still move a field into the neighbouring step.
|
|
19
|
+
|
|
5
20
|
## 0.16.0 — 2026-09-22
|
|
6
21
|
|
|
7
22
|
### Added — submission policies
|
package/README.md
CHANGED
|
@@ -174,10 +174,10 @@ the portal. The translation carries over what the builder can express:
|
|
|
174
174
|
- dependent fields become `visibleIf` conditions (value lists are expanded
|
|
175
175
|
into OR'd/AND'd rules).
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
177
|
+
The HubSpot original is never modified. Re-importing (or **Resync from HubSpot**
|
|
178
|
+
in the editor) updates mapped fields in place and appends new ones — Strapi
|
|
179
|
+
steps, conditions and extra fields stay. Matching is by HubSpot form GUID,
|
|
180
|
+
then slug. The published version is never touched.
|
|
181
181
|
|
|
182
182
|
### i18n and publishing
|
|
183
183
|
|
|
@@ -5,12 +5,12 @@ import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
|
5
5
|
import { Typography, Flex, Box, SingleSelect, SingleSelectOption, MultiSelect, MultiSelectOption, TextInput, IconButton, Button, Combobox, ComboboxOption, Field, Textarea, Checkbox, Divider, Loader, Badge, Table, Thead, Tr, Th, Tbody, Td, Modal } from "@strapi/design-system";
|
|
6
6
|
import { Trash, Plus, ArrowClockwise, ArrowLeft, Drag, ArrowUp, ArrowDown, List, Duplicate, Download } from "@strapi/icons";
|
|
7
7
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
8
|
-
import { g as getTranslation, P as PLUGIN_ID } from "./index-
|
|
9
|
-
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext,
|
|
10
|
-
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable
|
|
8
|
+
import { g as getTranslation, P as PLUGIN_ID } from "./index-CLAy5dVN.mjs";
|
|
9
|
+
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, useDroppable, closestCorners } from "@dnd-kit/core";
|
|
10
|
+
import { arrayMove, sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
|
|
11
11
|
import { CSS } from "@dnd-kit/utilities";
|
|
12
|
-
import { o as objectLabel } from "./objectLabels
|
|
13
|
-
import { u as useHubspotSchema } from "./useHubspotSchema-
|
|
12
|
+
import { o as objectLabel } from "./objectLabels--zOmqsfm.mjs";
|
|
13
|
+
import { u as useHubspotSchema } from "./useHubspotSchema-Bz2o1BU-.mjs";
|
|
14
14
|
const OPERATORS = [
|
|
15
15
|
"eq",
|
|
16
16
|
"neq",
|
|
@@ -153,32 +153,107 @@ const ConditionEditor = ({ condition, candidates, onChange }) => {
|
|
|
153
153
|
] })
|
|
154
154
|
] });
|
|
155
155
|
};
|
|
156
|
-
function
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
function relocateField(steps, fieldId, overId) {
|
|
157
|
+
const next = steps.map((step) => ({ ...step, fields: [...step.fields] }));
|
|
158
|
+
let fromStep = -1;
|
|
159
|
+
let fromIndex = -1;
|
|
160
|
+
for (let i = 0; i < next.length; i += 1) {
|
|
161
|
+
const index = next[i].fields.findIndex((field2) => field2.id === fieldId);
|
|
162
|
+
if (index !== -1) {
|
|
163
|
+
fromStep = i;
|
|
164
|
+
fromIndex = index;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (fromStep === -1) return steps;
|
|
169
|
+
let toStep = -1;
|
|
170
|
+
let toIndex = -1;
|
|
171
|
+
const containerId = overId.startsWith("container:") ? overId.slice("container:".length) : "";
|
|
172
|
+
if (containerId) {
|
|
173
|
+
toStep = next.findIndex((step) => step.id === containerId);
|
|
174
|
+
toIndex = toStep === -1 ? -1 : next[toStep].fields.length;
|
|
175
|
+
} else {
|
|
176
|
+
for (let i = 0; i < next.length; i += 1) {
|
|
177
|
+
const index = next[i].fields.findIndex((field2) => field2.id === overId);
|
|
178
|
+
if (index !== -1) {
|
|
179
|
+
toStep = i;
|
|
180
|
+
toIndex = index;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (toStep === -1) {
|
|
185
|
+
toStep = next.findIndex((step) => step.id === overId);
|
|
186
|
+
toIndex = toStep === -1 ? -1 : next[toStep].fields.length;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (toStep === -1 || toIndex === -1) return steps;
|
|
190
|
+
if (fromStep === toStep) {
|
|
191
|
+
if (fromIndex === toIndex) return steps;
|
|
192
|
+
next[fromStep].fields = arrayMove(next[fromStep].fields, fromIndex, toIndex);
|
|
193
|
+
return next;
|
|
194
|
+
}
|
|
195
|
+
const [field] = next[fromStep].fields.splice(fromIndex, 1);
|
|
196
|
+
if (!field) return steps;
|
|
197
|
+
next[toStep].fields.splice(toIndex, 0, field);
|
|
198
|
+
return next;
|
|
199
|
+
}
|
|
200
|
+
const collisionDetection = (args) => {
|
|
201
|
+
const type = args.active.data.current?.type;
|
|
202
|
+
const droppableContainers = args.droppableContainers.filter((container) => {
|
|
203
|
+
const other = container.data.current?.type;
|
|
204
|
+
if (type === "step") return other === "step";
|
|
205
|
+
if (type === "field") return other === "field" || other === "container";
|
|
206
|
+
return true;
|
|
207
|
+
});
|
|
208
|
+
return closestCorners({ ...args, droppableContainers });
|
|
209
|
+
};
|
|
210
|
+
function SortableBoard({
|
|
211
|
+
children,
|
|
212
|
+
onDragEnd
|
|
160
213
|
}) {
|
|
161
214
|
const sensors = useSensors(
|
|
162
215
|
// An 8px activation distance keeps clicks (selection!) from starting drags.
|
|
163
216
|
useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
|
|
164
217
|
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
|
|
165
218
|
);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
219
|
+
return /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd, children });
|
|
220
|
+
}
|
|
221
|
+
function SortableGroup({
|
|
222
|
+
ids,
|
|
223
|
+
children
|
|
224
|
+
}) {
|
|
225
|
+
return /* @__PURE__ */ jsx(SortableContext, { items: ids, strategy: verticalListSortingStrategy, children });
|
|
226
|
+
}
|
|
227
|
+
function SortableContainer({
|
|
228
|
+
stepId,
|
|
229
|
+
children
|
|
230
|
+
}) {
|
|
231
|
+
const { setNodeRef, isOver } = useDroppable({
|
|
232
|
+
id: `container:${stepId}`,
|
|
233
|
+
data: { type: "container", stepId }
|
|
234
|
+
});
|
|
235
|
+
return /* @__PURE__ */ jsx(
|
|
236
|
+
"div",
|
|
237
|
+
{
|
|
238
|
+
ref: setNodeRef,
|
|
239
|
+
style: {
|
|
240
|
+
minHeight: 8,
|
|
241
|
+
borderRadius: 4,
|
|
242
|
+
outline: isOver ? "2px dashed currentColor" : void 0,
|
|
243
|
+
outlineOffset: 4
|
|
244
|
+
},
|
|
245
|
+
children
|
|
246
|
+
}
|
|
247
|
+
);
|
|
175
248
|
}
|
|
176
249
|
function SortableItem({
|
|
177
250
|
id,
|
|
251
|
+
data,
|
|
178
252
|
children
|
|
179
253
|
}) {
|
|
180
254
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
181
|
-
id
|
|
255
|
+
id,
|
|
256
|
+
data
|
|
182
257
|
});
|
|
183
258
|
return /* @__PURE__ */ jsx(
|
|
184
259
|
"div",
|
|
@@ -824,6 +899,40 @@ const FormEditor = () => {
|
|
|
824
899
|
setBusy(false);
|
|
825
900
|
}
|
|
826
901
|
};
|
|
902
|
+
const resync = async () => {
|
|
903
|
+
if (dirty && !await save()) return;
|
|
904
|
+
setBusy(true);
|
|
905
|
+
setFeedback(null);
|
|
906
|
+
try {
|
|
907
|
+
const { data } = await post(`/${PLUGIN_ID}/builder/forms/${documentId}/resync${query}`);
|
|
908
|
+
if (data.form) {
|
|
909
|
+
setEntry(data.form);
|
|
910
|
+
setDirty(false);
|
|
911
|
+
}
|
|
912
|
+
const added = data.added?.length ?? 0;
|
|
913
|
+
const updated = data.updated?.length ?? 0;
|
|
914
|
+
const skipped = data.skipped?.length ?? 0;
|
|
915
|
+
setFeedback({
|
|
916
|
+
tone: "success",
|
|
917
|
+
text: skipped > 0 ? t(
|
|
918
|
+
"editor.resynced-gaps",
|
|
919
|
+
"Resynced from HubSpot — {updated, plural, one {# updated} other {# updated}}, {added, plural, one {# added} other {# added}}, {skipped, plural, one {# skipped} other {# skipped}}.",
|
|
920
|
+
{ updated, added, skipped }
|
|
921
|
+
) : t(
|
|
922
|
+
"editor.resynced",
|
|
923
|
+
"Resynced from HubSpot — {updated, plural, one {# field updated} other {# fields updated}}, {added, plural, one {# added} other {# added}}.",
|
|
924
|
+
{ updated, added }
|
|
925
|
+
)
|
|
926
|
+
});
|
|
927
|
+
} catch {
|
|
928
|
+
setFeedback({
|
|
929
|
+
tone: "danger",
|
|
930
|
+
text: t("editor.resync-error", "Could not resync from HubSpot — is the form still linked?")
|
|
931
|
+
});
|
|
932
|
+
} finally {
|
|
933
|
+
setBusy(false);
|
|
934
|
+
}
|
|
935
|
+
};
|
|
827
936
|
const fieldFlags = (fieldId) => ({
|
|
828
937
|
error: errors.find((e) => e.fieldId === fieldId),
|
|
829
938
|
problem: problems.find((p) => p.fieldId === fieldId)
|
|
@@ -861,6 +970,15 @@ const FormEditor = () => {
|
|
|
861
970
|
}
|
|
862
971
|
),
|
|
863
972
|
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: save, disabled: busy || !dirty, children: t("editor.save", "Save") }),
|
|
973
|
+
/* @__PURE__ */ jsx(
|
|
974
|
+
Button,
|
|
975
|
+
{
|
|
976
|
+
variant: "tertiary",
|
|
977
|
+
onClick: resync,
|
|
978
|
+
disabled: busy || !entry.hubspotFormId,
|
|
979
|
+
children: t("editor.resync", "Resync from HubSpot")
|
|
980
|
+
}
|
|
981
|
+
),
|
|
864
982
|
/* @__PURE__ */ jsx(Button, { onClick: publish, disabled: busy, children: t("editor.publish", "Publish") }),
|
|
865
983
|
published && /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: unpublish, disabled: busy, children: t("editor.unpublish", "Unpublish") })
|
|
866
984
|
] })
|
|
@@ -869,14 +987,28 @@ const FormEditor = () => {
|
|
|
869
987
|
/* @__PURE__ */ jsxs(Flex, { gap: 6, alignItems: "flex-start", children: [
|
|
870
988
|
/* @__PURE__ */ jsx(Box, { flex: "1", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
871
989
|
/* @__PURE__ */ jsx(
|
|
872
|
-
|
|
990
|
+
SortableBoard,
|
|
873
991
|
{
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
992
|
+
onDragEnd: ({ active, over }) => {
|
|
993
|
+
if (!over || active.id === over.id) return;
|
|
994
|
+
const kind = active.data.current?.type;
|
|
995
|
+
if (kind === "step") {
|
|
996
|
+
const ids = definition.steps.map((s) => s.id);
|
|
997
|
+
const from = ids.indexOf(String(active.id));
|
|
998
|
+
const to = ids.indexOf(String(over.id));
|
|
999
|
+
if (from === -1 || to === -1) return;
|
|
1000
|
+
patchDefinition((steps) => reorderByIds(steps, arrayMove(ids, from, to)));
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
if (kind === "field") {
|
|
1004
|
+
patchDefinition((steps) => relocateField(steps, String(active.id), String(over.id)));
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
children: /* @__PURE__ */ jsx(SortableGroup, { ids: definition.steps.map((s) => s.id), children: definition.steps.map((step, stepIndex) => /* @__PURE__ */ jsx(
|
|
877
1008
|
SortableItem,
|
|
878
1009
|
{
|
|
879
1010
|
id: step.id,
|
|
1011
|
+
data: { type: "step" },
|
|
880
1012
|
children: (stepHandle) => /* @__PURE__ */ jsxs(
|
|
881
1013
|
Box,
|
|
882
1014
|
{
|
|
@@ -952,95 +1084,89 @@ const FormEditor = () => {
|
|
|
952
1084
|
] })
|
|
953
1085
|
] }),
|
|
954
1086
|
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
955
|
-
/* @__PURE__ */ jsx(
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1087
|
+
/* @__PURE__ */ jsx(SortableContainer, { stepId: step.id, children: /* @__PURE__ */ jsx(SortableGroup, { ids: step.fields.map((f) => f.id), children: step.fields.map((field, fieldIndex) => {
|
|
1088
|
+
const flags = fieldFlags(field.id);
|
|
1089
|
+
const isSelected = selection.kind === "field" && selection.fieldId === field.id;
|
|
1090
|
+
return /* @__PURE__ */ jsx(
|
|
1091
|
+
SortableItem,
|
|
1092
|
+
{
|
|
1093
|
+
id: field.id,
|
|
1094
|
+
data: { type: "field", stepId: step.id },
|
|
1095
|
+
children: (fieldHandle) => /* @__PURE__ */ jsx(
|
|
1096
|
+
Box,
|
|
965
1097
|
{
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
),
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
),
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
{
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
},
|
|
1039
|
-
field.id
|
|
1040
|
-
);
|
|
1041
|
-
})
|
|
1042
|
-
}
|
|
1043
|
-
),
|
|
1098
|
+
background: isSelected ? "primary100" : "neutral100",
|
|
1099
|
+
hasRadius: true,
|
|
1100
|
+
padding: 3,
|
|
1101
|
+
onClick: (e) => {
|
|
1102
|
+
e.stopPropagation();
|
|
1103
|
+
setSelection({ kind: "field", fieldId: field.id });
|
|
1104
|
+
},
|
|
1105
|
+
style: { cursor: "pointer" },
|
|
1106
|
+
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1107
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
1108
|
+
/* @__PURE__ */ jsx(
|
|
1109
|
+
"span",
|
|
1110
|
+
{
|
|
1111
|
+
...fieldHandle.attributes,
|
|
1112
|
+
...fieldHandle.listeners,
|
|
1113
|
+
onClick: (e) => e.stopPropagation(),
|
|
1114
|
+
style: { cursor: "grab", display: "inline-flex" },
|
|
1115
|
+
"aria-label": t("editor.drag-field", "Drag to move the field, including to another step"),
|
|
1116
|
+
children: /* @__PURE__ */ jsx(Drag, {})
|
|
1117
|
+
}
|
|
1118
|
+
),
|
|
1119
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: field.label || field.name || "—" }),
|
|
1120
|
+
/* @__PURE__ */ jsx(Badge, { children: field.type }),
|
|
1121
|
+
field.required && /* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral150", textColor: "neutral600", children: t("editor.required", "required") }),
|
|
1122
|
+
field.hubspot?.property && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
1123
|
+
field.hubspot.object ?? "contact",
|
|
1124
|
+
".",
|
|
1125
|
+
field.hubspot.property
|
|
1126
|
+
] }),
|
|
1127
|
+
field.visibleIf?.rules?.length ? /* @__PURE__ */ jsx(Badge, { backgroundColor: "alternative100", textColor: "alternative700", children: t("editor.conditional", "Conditional") }) : null,
|
|
1128
|
+
(flags.error || flags.problem) && /* @__PURE__ */ jsx(Badge, { backgroundColor: "danger100", textColor: "danger700", children: flags.error?.code ?? flags.problem?.code })
|
|
1129
|
+
] }),
|
|
1130
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 1, onClick: (e) => e.stopPropagation(), children: [
|
|
1131
|
+
/* @__PURE__ */ jsx(
|
|
1132
|
+
IconButton,
|
|
1133
|
+
{
|
|
1134
|
+
label: t("editor.field-up", "Move up"),
|
|
1135
|
+
onClick: () => moveField(stepIndex, fieldIndex, -1),
|
|
1136
|
+
disabled: stepIndex === 0 && fieldIndex === 0,
|
|
1137
|
+
children: /* @__PURE__ */ jsx(ArrowUp, {})
|
|
1138
|
+
}
|
|
1139
|
+
),
|
|
1140
|
+
/* @__PURE__ */ jsx(
|
|
1141
|
+
IconButton,
|
|
1142
|
+
{
|
|
1143
|
+
label: t("editor.field-down", "Move down"),
|
|
1144
|
+
onClick: () => moveField(stepIndex, fieldIndex, 1),
|
|
1145
|
+
disabled: stepIndex === definition.steps.length - 1 && fieldIndex === step.fields.length - 1,
|
|
1146
|
+
children: /* @__PURE__ */ jsx(ArrowDown, {})
|
|
1147
|
+
}
|
|
1148
|
+
),
|
|
1149
|
+
/* @__PURE__ */ jsx(
|
|
1150
|
+
IconButton,
|
|
1151
|
+
{
|
|
1152
|
+
label: t("editor.field-delete", "Delete the field"),
|
|
1153
|
+
onClick: () => {
|
|
1154
|
+
setSelection({ kind: "form" });
|
|
1155
|
+
patchStep(step.id, {
|
|
1156
|
+
fields: step.fields.filter((f) => f.id !== field.id)
|
|
1157
|
+
});
|
|
1158
|
+
},
|
|
1159
|
+
children: /* @__PURE__ */ jsx(Trash, {})
|
|
1160
|
+
}
|
|
1161
|
+
)
|
|
1162
|
+
] })
|
|
1163
|
+
] })
|
|
1164
|
+
}
|
|
1165
|
+
)
|
|
1166
|
+
},
|
|
1167
|
+
field.id
|
|
1168
|
+
);
|
|
1169
|
+
}) }) }),
|
|
1044
1170
|
/* @__PURE__ */ jsx(
|
|
1045
1171
|
Button,
|
|
1046
1172
|
{
|
|
@@ -1061,7 +1187,7 @@ const FormEditor = () => {
|
|
|
1061
1187
|
)
|
|
1062
1188
|
},
|
|
1063
1189
|
step.id
|
|
1064
|
-
))
|
|
1190
|
+
)) })
|
|
1065
1191
|
}
|
|
1066
1192
|
),
|
|
1067
1193
|
/* @__PURE__ */ jsx(
|
|
@@ -1228,7 +1354,7 @@ const FormEditor = () => {
|
|
|
1228
1354
|
),
|
|
1229
1355
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
1230
1356
|
"editor.hubspot-form-hint",
|
|
1231
|
-
"Submissions go through HubSpot’s Forms API so they count as conversions.
|
|
1357
|
+
"Submissions go through HubSpot’s Forms API so they count as conversions. After you change the form in HubSpot, use Resync from HubSpot — mapped fields update in place, new ones are appended, your steps stay."
|
|
1232
1358
|
) })
|
|
1233
1359
|
] }),
|
|
1234
1360
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
@@ -1407,7 +1533,7 @@ const FormsList = () => {
|
|
|
1407
1533
|
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: t("forms.import-hubspot-title", "Import from your HubSpot portal") }),
|
|
1408
1534
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", tag: "p", children: t(
|
|
1409
1535
|
"forms.import-hubspot-hint",
|
|
1410
|
-
"Translates a form built in HubSpot into a draft here, CRM mapping included. What the builder can't express is skipped and reported. Re-importing
|
|
1536
|
+
"Translates a form built in HubSpot into a draft here, CRM mapping included. What the builder can't express is skipped and reported. Re-importing updates mapped fields in place and appends new ones."
|
|
1411
1537
|
) })
|
|
1412
1538
|
] }),
|
|
1413
1539
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|