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.
Files changed (33) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +4 -4
  3. package/dist/_chunks/{Forms-6EoEYzAc.mjs → Forms-BOQWely0.mjs} +240 -114
  4. package/dist/_chunks/{Forms-BW_zGc1P.js → Forms-mMNP7hc9.js} +238 -112
  5. package/dist/_chunks/{HubspotFormInput-V5w4y1fb.mjs → HubspotFormInput-DCkoavrN.mjs} +1 -1
  6. package/dist/_chunks/{HubspotFormInput-oMhm1UJm.js → HubspotFormInput-DI35Aqiu.js} +1 -1
  7. package/dist/_chunks/{HubspotObjectInput-DhsnSguG.mjs → HubspotObjectInput-BbnvhdbD.mjs} +3 -3
  8. package/dist/_chunks/{HubspotObjectInput-Bmo6YQgs.js → HubspotObjectInput-Cq1TuL_l.js} +3 -3
  9. package/dist/_chunks/{HubspotPropertyInput-CrYP4pc0.mjs → HubspotPropertyInput-BHfpBD36.mjs} +3 -3
  10. package/dist/_chunks/{HubspotPropertyInput-luFfnxqy.js → HubspotPropertyInput-BLZzsW08.js} +3 -3
  11. package/dist/_chunks/{Settings-B3A22i7Z.js → Settings-BAsx0LGv.js} +2 -2
  12. package/dist/_chunks/{Settings-CjcWj9I6.mjs → Settings-DqRpHtnT.mjs} +2 -2
  13. package/dist/_chunks/{en-D6GHgMOt.mjs → en-Djd3TID0.mjs} +7 -3
  14. package/dist/_chunks/{en-C7ls2EUl.js → en-sfzopB5K.js} +7 -3
  15. package/dist/_chunks/{fr-CfohMY8n.mjs → fr-C7t1elmR.mjs} +7 -3
  16. package/dist/_chunks/{fr-pOP8ZXqM.js → fr-sF5Josfh.js} +7 -3
  17. package/dist/_chunks/{index-7cL9PRh1.mjs → index-CLAy5dVN.mjs} +6 -6
  18. package/dist/_chunks/{index-CodpLKZx.js → index-R3ReZXF1.js} +6 -6
  19. package/dist/_chunks/{objectLabels-Dnj14fsp.mjs → objectLabels--zOmqsfm.mjs} +1 -1
  20. package/dist/_chunks/{objectLabels-CSWGIgNb.js → objectLabels-CW2iBOkD.js} +1 -1
  21. package/dist/_chunks/{useHubspotSchema-DiRN3HrN.js → useHubspotSchema-BRzzvs9t.js} +1 -1
  22. package/dist/_chunks/{useHubspotSchema-BsmQgJgx.mjs → useHubspotSchema-Bz2o1BU-.mjs} +1 -1
  23. package/dist/admin/index.js +1 -1
  24. package/dist/admin/index.mjs +1 -1
  25. package/dist/admin/src/builder/Sortable.d.ts +25 -12
  26. package/dist/admin/src/builder/__tests__/relocateField.test.d.ts +1 -0
  27. package/dist/admin/src/builder/relocateField.d.ts +14 -0
  28. package/dist/server/index.js +129 -12
  29. package/dist/server/index.mjs +129 -12
  30. package/dist/server/src/formsAdmin.d.ts +8 -3
  31. package/dist/server/src/importHubspot.d.ts +12 -0
  32. package/dist/server/src/index.d.ts +1 -0
  33. package/package.json +1 -1
@@ -7,12 +7,12 @@ 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$1 = require("./index-CodpLKZx.js");
10
+ const index$1 = require("./index-R3ReZXF1.js");
11
11
  const core = require("@dnd-kit/core");
12
12
  const sortable = require("@dnd-kit/sortable");
13
13
  const utilities = require("@dnd-kit/utilities");
14
- const objectLabels = require("./objectLabels-CSWGIgNb.js");
15
- const useHubspotSchema = require("./useHubspotSchema-DiRN3HrN.js");
14
+ const objectLabels = require("./objectLabels-CW2iBOkD.js");
15
+ const useHubspotSchema = require("./useHubspotSchema-BRzzvs9t.js");
16
16
  function _interopNamespace(e) {
17
17
  if (e && e.__esModule) return e;
18
18
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -173,32 +173,107 @@ const ConditionEditor = ({ condition, candidates, onChange }) => {
173
173
  ] })
174
174
  ] });
175
175
  };
176
- function SortableList({
177
- ids,
178
- onReorder,
179
- children
176
+ function relocateField(steps, fieldId, overId) {
177
+ const next = steps.map((step) => ({ ...step, fields: [...step.fields] }));
178
+ let fromStep = -1;
179
+ let fromIndex = -1;
180
+ for (let i = 0; i < next.length; i += 1) {
181
+ const index2 = next[i].fields.findIndex((field2) => field2.id === fieldId);
182
+ if (index2 !== -1) {
183
+ fromStep = i;
184
+ fromIndex = index2;
185
+ break;
186
+ }
187
+ }
188
+ if (fromStep === -1) return steps;
189
+ let toStep = -1;
190
+ let toIndex = -1;
191
+ const containerId = overId.startsWith("container:") ? overId.slice("container:".length) : "";
192
+ if (containerId) {
193
+ toStep = next.findIndex((step) => step.id === containerId);
194
+ toIndex = toStep === -1 ? -1 : next[toStep].fields.length;
195
+ } else {
196
+ for (let i = 0; i < next.length; i += 1) {
197
+ const index2 = next[i].fields.findIndex((field2) => field2.id === overId);
198
+ if (index2 !== -1) {
199
+ toStep = i;
200
+ toIndex = index2;
201
+ break;
202
+ }
203
+ }
204
+ if (toStep === -1) {
205
+ toStep = next.findIndex((step) => step.id === overId);
206
+ toIndex = toStep === -1 ? -1 : next[toStep].fields.length;
207
+ }
208
+ }
209
+ if (toStep === -1 || toIndex === -1) return steps;
210
+ if (fromStep === toStep) {
211
+ if (fromIndex === toIndex) return steps;
212
+ next[fromStep].fields = sortable.arrayMove(next[fromStep].fields, fromIndex, toIndex);
213
+ return next;
214
+ }
215
+ const [field] = next[fromStep].fields.splice(fromIndex, 1);
216
+ if (!field) return steps;
217
+ next[toStep].fields.splice(toIndex, 0, field);
218
+ return next;
219
+ }
220
+ const collisionDetection = (args) => {
221
+ const type = args.active.data.current?.type;
222
+ const droppableContainers = args.droppableContainers.filter((container) => {
223
+ const other = container.data.current?.type;
224
+ if (type === "step") return other === "step";
225
+ if (type === "field") return other === "field" || other === "container";
226
+ return true;
227
+ });
228
+ return core.closestCorners({ ...args, droppableContainers });
229
+ };
230
+ function SortableBoard({
231
+ children,
232
+ onDragEnd
180
233
  }) {
181
234
  const sensors = core.useSensors(
182
235
  // An 8px activation distance keeps clicks (selection!) from starting drags.
183
236
  core.useSensor(core.PointerSensor, { activationConstraint: { distance: 8 } }),
184
237
  core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
185
238
  );
186
- const handleDragEnd = (event) => {
187
- const { active, over } = event;
188
- if (!over || active.id === over.id) return;
189
- const from = ids.indexOf(String(active.id));
190
- const to = ids.indexOf(String(over.id));
191
- if (from === -1 || to === -1) return;
192
- onReorder(sortable.arrayMove(ids, from, to));
193
- };
194
- return /* @__PURE__ */ jsxRuntime.jsx(core.DndContext, { sensors, collisionDetection: core.closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: ids, strategy: sortable.verticalListSortingStrategy, children }) });
239
+ return /* @__PURE__ */ jsxRuntime.jsx(core.DndContext, { sensors, collisionDetection, onDragEnd, children });
240
+ }
241
+ function SortableGroup({
242
+ ids,
243
+ children
244
+ }) {
245
+ return /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: ids, strategy: sortable.verticalListSortingStrategy, children });
246
+ }
247
+ function SortableContainer({
248
+ stepId,
249
+ children
250
+ }) {
251
+ const { setNodeRef, isOver } = core.useDroppable({
252
+ id: `container:${stepId}`,
253
+ data: { type: "container", stepId }
254
+ });
255
+ return /* @__PURE__ */ jsxRuntime.jsx(
256
+ "div",
257
+ {
258
+ ref: setNodeRef,
259
+ style: {
260
+ minHeight: 8,
261
+ borderRadius: 4,
262
+ outline: isOver ? "2px dashed currentColor" : void 0,
263
+ outlineOffset: 4
264
+ },
265
+ children
266
+ }
267
+ );
195
268
  }
196
269
  function SortableItem({
197
270
  id,
271
+ data,
198
272
  children
199
273
  }) {
200
274
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable.useSortable({
201
- id
275
+ id,
276
+ data
202
277
  });
203
278
  return /* @__PURE__ */ jsxRuntime.jsx(
204
279
  "div",
@@ -844,6 +919,40 @@ const FormEditor = () => {
844
919
  setBusy(false);
845
920
  }
846
921
  };
922
+ const resync = async () => {
923
+ if (dirty && !await save()) return;
924
+ setBusy(true);
925
+ setFeedback(null);
926
+ try {
927
+ const { data } = await post(`/${index$1.PLUGIN_ID}/builder/forms/${documentId}/resync${query}`);
928
+ if (data.form) {
929
+ setEntry(data.form);
930
+ setDirty(false);
931
+ }
932
+ const added = data.added?.length ?? 0;
933
+ const updated = data.updated?.length ?? 0;
934
+ const skipped = data.skipped?.length ?? 0;
935
+ setFeedback({
936
+ tone: "success",
937
+ text: skipped > 0 ? t(
938
+ "editor.resynced-gaps",
939
+ "Resynced from HubSpot — {updated, plural, one {# updated} other {# updated}}, {added, plural, one {# added} other {# added}}, {skipped, plural, one {# skipped} other {# skipped}}.",
940
+ { updated, added, skipped }
941
+ ) : t(
942
+ "editor.resynced",
943
+ "Resynced from HubSpot — {updated, plural, one {# field updated} other {# fields updated}}, {added, plural, one {# added} other {# added}}.",
944
+ { updated, added }
945
+ )
946
+ });
947
+ } catch {
948
+ setFeedback({
949
+ tone: "danger",
950
+ text: t("editor.resync-error", "Could not resync from HubSpot — is the form still linked?")
951
+ });
952
+ } finally {
953
+ setBusy(false);
954
+ }
955
+ };
847
956
  const fieldFlags = (fieldId) => ({
848
957
  error: errors.find((e) => e.fieldId === fieldId),
849
958
  problem: problems.find((p) => p.fieldId === fieldId)
@@ -881,6 +990,15 @@ const FormEditor = () => {
881
990
  }
882
991
  ),
883
992
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: save, disabled: busy || !dirty, children: t("editor.save", "Save") }),
993
+ /* @__PURE__ */ jsxRuntime.jsx(
994
+ designSystem.Button,
995
+ {
996
+ variant: "tertiary",
997
+ onClick: resync,
998
+ disabled: busy || !entry.hubspotFormId,
999
+ children: t("editor.resync", "Resync from HubSpot")
1000
+ }
1001
+ ),
884
1002
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: publish, disabled: busy, children: t("editor.publish", "Publish") }),
885
1003
  published && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: unpublish, disabled: busy, children: t("editor.unpublish", "Unpublish") })
886
1004
  ] })
@@ -889,14 +1007,28 @@ const FormEditor = () => {
889
1007
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 6, alignItems: "flex-start", children: [
890
1008
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
891
1009
  /* @__PURE__ */ jsxRuntime.jsx(
892
- SortableList,
1010
+ SortableBoard,
893
1011
  {
894
- ids: definition.steps.map((s) => s.id),
895
- onReorder: (ids) => patchDefinition((steps) => reorderByIds(steps, ids)),
896
- children: definition.steps.map((step, stepIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1012
+ onDragEnd: ({ active, over }) => {
1013
+ if (!over || active.id === over.id) return;
1014
+ const kind = active.data.current?.type;
1015
+ if (kind === "step") {
1016
+ const ids = definition.steps.map((s) => s.id);
1017
+ const from = ids.indexOf(String(active.id));
1018
+ const to = ids.indexOf(String(over.id));
1019
+ if (from === -1 || to === -1) return;
1020
+ patchDefinition((steps) => reorderByIds(steps, sortable.arrayMove(ids, from, to)));
1021
+ return;
1022
+ }
1023
+ if (kind === "field") {
1024
+ patchDefinition((steps) => relocateField(steps, String(active.id), String(over.id)));
1025
+ }
1026
+ },
1027
+ children: /* @__PURE__ */ jsxRuntime.jsx(SortableGroup, { ids: definition.steps.map((s) => s.id), children: definition.steps.map((step, stepIndex) => /* @__PURE__ */ jsxRuntime.jsx(
897
1028
  SortableItem,
898
1029
  {
899
1030
  id: step.id,
1031
+ data: { type: "step" },
900
1032
  children: (stepHandle) => /* @__PURE__ */ jsxRuntime.jsxs(
901
1033
  designSystem.Box,
902
1034
  {
@@ -972,95 +1104,89 @@ const FormEditor = () => {
972
1104
  ] })
973
1105
  ] }),
974
1106
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
975
- /* @__PURE__ */ jsxRuntime.jsx(
976
- SortableList,
977
- {
978
- ids: step.fields.map((f) => f.id),
979
- onReorder: (ids) => patchStep(step.id, { fields: reorderByIds(step.fields, ids) }),
980
- children: step.fields.map((field, fieldIndex) => {
981
- const flags = fieldFlags(field.id);
982
- const isSelected = selection.kind === "field" && selection.fieldId === field.id;
983
- return /* @__PURE__ */ jsxRuntime.jsx(
984
- SortableItem,
1107
+ /* @__PURE__ */ jsxRuntime.jsx(SortableContainer, { stepId: step.id, children: /* @__PURE__ */ jsxRuntime.jsx(SortableGroup, { ids: step.fields.map((f) => f.id), children: step.fields.map((field, fieldIndex) => {
1108
+ const flags = fieldFlags(field.id);
1109
+ const isSelected = selection.kind === "field" && selection.fieldId === field.id;
1110
+ return /* @__PURE__ */ jsxRuntime.jsx(
1111
+ SortableItem,
1112
+ {
1113
+ id: field.id,
1114
+ data: { type: "field", stepId: step.id },
1115
+ children: (fieldHandle) => /* @__PURE__ */ jsxRuntime.jsx(
1116
+ designSystem.Box,
985
1117
  {
986
- id: field.id,
987
- children: (fieldHandle) => /* @__PURE__ */ jsxRuntime.jsx(
988
- designSystem.Box,
989
- {
990
- background: isSelected ? "primary100" : "neutral100",
991
- hasRadius: true,
992
- padding: 3,
993
- onClick: (e) => {
994
- e.stopPropagation();
995
- setSelection({ kind: "field", fieldId: field.id });
996
- },
997
- style: { cursor: "pointer" },
998
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
999
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
1000
- /* @__PURE__ */ jsxRuntime.jsx(
1001
- "span",
1002
- {
1003
- ...fieldHandle.attributes,
1004
- ...fieldHandle.listeners,
1005
- onClick: (e) => e.stopPropagation(),
1006
- style: { cursor: "grab", display: "inline-flex" },
1007
- "aria-label": t("editor.drag-field", "Drag to reorder the field"),
1008
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Drag, {})
1009
- }
1010
- ),
1011
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: field.label || field.name || "—" }),
1012
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: field.type }),
1013
- field.required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral600", children: t("editor.required", "required") }),
1014
- field.hubspot?.property && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
1015
- field.hubspot.object ?? "contact",
1016
- ".",
1017
- field.hubspot.property
1018
- ] }),
1019
- field.visibleIf?.rules?.length ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "alternative100", textColor: "alternative700", children: t("editor.conditional", "Conditional") }) : null,
1020
- (flags.error || flags.problem) && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "danger100", textColor: "danger700", children: flags.error?.code ?? flags.problem?.code })
1021
- ] }),
1022
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, onClick: (e) => e.stopPropagation(), children: [
1023
- /* @__PURE__ */ jsxRuntime.jsx(
1024
- designSystem.IconButton,
1025
- {
1026
- label: t("editor.field-up", "Move up"),
1027
- onClick: () => moveField(stepIndex, fieldIndex, -1),
1028
- disabled: stepIndex === 0 && fieldIndex === 0,
1029
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUp, {})
1030
- }
1031
- ),
1032
- /* @__PURE__ */ jsxRuntime.jsx(
1033
- designSystem.IconButton,
1034
- {
1035
- label: t("editor.field-down", "Move down"),
1036
- onClick: () => moveField(stepIndex, fieldIndex, 1),
1037
- disabled: stepIndex === definition.steps.length - 1 && fieldIndex === step.fields.length - 1,
1038
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDown, {})
1039
- }
1040
- ),
1041
- /* @__PURE__ */ jsxRuntime.jsx(
1042
- designSystem.IconButton,
1043
- {
1044
- label: t("editor.field-delete", "Delete the field"),
1045
- onClick: () => {
1046
- setSelection({ kind: "form" });
1047
- patchStep(step.id, {
1048
- fields: step.fields.filter((f) => f.id !== field.id)
1049
- });
1050
- },
1051
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
1052
- }
1053
- )
1054
- ] })
1055
- ] })
1056
- }
1057
- )
1058
- },
1059
- field.id
1060
- );
1061
- })
1062
- }
1063
- ),
1118
+ background: isSelected ? "primary100" : "neutral100",
1119
+ hasRadius: true,
1120
+ padding: 3,
1121
+ onClick: (e) => {
1122
+ e.stopPropagation();
1123
+ setSelection({ kind: "field", fieldId: field.id });
1124
+ },
1125
+ style: { cursor: "pointer" },
1126
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
1127
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
1128
+ /* @__PURE__ */ jsxRuntime.jsx(
1129
+ "span",
1130
+ {
1131
+ ...fieldHandle.attributes,
1132
+ ...fieldHandle.listeners,
1133
+ onClick: (e) => e.stopPropagation(),
1134
+ style: { cursor: "grab", display: "inline-flex" },
1135
+ "aria-label": t("editor.drag-field", "Drag to move the field, including to another step"),
1136
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Drag, {})
1137
+ }
1138
+ ),
1139
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: field.label || field.name || "—" }),
1140
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: field.type }),
1141
+ field.required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral600", children: t("editor.required", "required") }),
1142
+ field.hubspot?.property && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
1143
+ field.hubspot.object ?? "contact",
1144
+ ".",
1145
+ field.hubspot.property
1146
+ ] }),
1147
+ field.visibleIf?.rules?.length ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "alternative100", textColor: "alternative700", children: t("editor.conditional", "Conditional") }) : null,
1148
+ (flags.error || flags.problem) && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "danger100", textColor: "danger700", children: flags.error?.code ?? flags.problem?.code })
1149
+ ] }),
1150
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, onClick: (e) => e.stopPropagation(), children: [
1151
+ /* @__PURE__ */ jsxRuntime.jsx(
1152
+ designSystem.IconButton,
1153
+ {
1154
+ label: t("editor.field-up", "Move up"),
1155
+ onClick: () => moveField(stepIndex, fieldIndex, -1),
1156
+ disabled: stepIndex === 0 && fieldIndex === 0,
1157
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUp, {})
1158
+ }
1159
+ ),
1160
+ /* @__PURE__ */ jsxRuntime.jsx(
1161
+ designSystem.IconButton,
1162
+ {
1163
+ label: t("editor.field-down", "Move down"),
1164
+ onClick: () => moveField(stepIndex, fieldIndex, 1),
1165
+ disabled: stepIndex === definition.steps.length - 1 && fieldIndex === step.fields.length - 1,
1166
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDown, {})
1167
+ }
1168
+ ),
1169
+ /* @__PURE__ */ jsxRuntime.jsx(
1170
+ designSystem.IconButton,
1171
+ {
1172
+ label: t("editor.field-delete", "Delete the field"),
1173
+ onClick: () => {
1174
+ setSelection({ kind: "form" });
1175
+ patchStep(step.id, {
1176
+ fields: step.fields.filter((f) => f.id !== field.id)
1177
+ });
1178
+ },
1179
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
1180
+ }
1181
+ )
1182
+ ] })
1183
+ ] })
1184
+ }
1185
+ )
1186
+ },
1187
+ field.id
1188
+ );
1189
+ }) }) }),
1064
1190
  /* @__PURE__ */ jsxRuntime.jsx(
1065
1191
  designSystem.Button,
1066
1192
  {
@@ -1081,7 +1207,7 @@ const FormEditor = () => {
1081
1207
  )
1082
1208
  },
1083
1209
  step.id
1084
- ))
1210
+ )) })
1085
1211
  }
1086
1212
  ),
1087
1213
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1248,7 +1374,7 @@ const FormEditor = () => {
1248
1374
  ),
1249
1375
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
1250
1376
  "editor.hubspot-form-hint",
1251
- "Submissions go through HubSpot’s Forms API so they count as conversions. Switch the connected portal (test → production) and pick the matching form — nothing is hardcoded."
1377
+ "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."
1252
1378
  ) })
1253
1379
  ] }),
1254
1380
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
@@ -1427,7 +1553,7 @@ const FormsList = () => {
1427
1553
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", children: t("forms.import-hubspot-title", "Import from your HubSpot portal") }),
1428
1554
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", tag: "p", children: t(
1429
1555
  "forms.import-hubspot-hint",
1430
- "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 overwrites the draft."
1556
+ "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."
1431
1557
  ) })
1432
1558
  ] }),
1433
1559
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
@@ -3,7 +3,7 @@ import * as React from "react";
3
3
  import { u as useIntl } from "./index-CEh8vkxY.mjs";
4
4
  import { Field, Flex, Loader, Combobox, ComboboxOption } from "@strapi/design-system";
5
5
  import { useFetchClient } from "@strapi/strapi/admin";
6
- import { P as PLUGIN_ID, g as getTranslation } from "./index-7cL9PRh1.mjs";
6
+ import { P as PLUGIN_ID, g as getTranslation } from "./index-CLAy5dVN.mjs";
7
7
  const HubspotFormInput = React.forwardRef(
8
8
  ({ name, value, onChange, disabled, error, required, label, hint, labelAction }, ref) => {
9
9
  const { formatMessage } = useIntl();
@@ -5,7 +5,7 @@ const React = require("react");
5
5
  const index = require("./index-DkTxsEqL.js");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const admin = require("@strapi/strapi/admin");
8
- const index$1 = require("./index-CodpLKZx.js");
8
+ const index$1 = require("./index-R3ReZXF1.js");
9
9
  function _interopNamespace(e) {
10
10
  if (e && e.__esModule) return e;
11
11
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -2,9 +2,9 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { u as useIntl } from "./index-CEh8vkxY.mjs";
4
4
  import { Field, Flex, Loader, SingleSelect, SingleSelectOption } from "@strapi/design-system";
5
- import { g as getTranslation } from "./index-7cL9PRh1.mjs";
6
- import { o as objectLabel } from "./objectLabels-Dnj14fsp.mjs";
7
- import { u as useHubspotSchema } from "./useHubspotSchema-BsmQgJgx.mjs";
5
+ import { g as getTranslation } from "./index-CLAy5dVN.mjs";
6
+ import { o as objectLabel } from "./objectLabels--zOmqsfm.mjs";
7
+ import { u as useHubspotSchema } from "./useHubspotSchema-Bz2o1BU-.mjs";
8
8
  const HubspotObjectInput = React.forwardRef(
9
9
  ({ name, value, onChange, disabled, error, required, label, hint, labelAction }, ref) => {
10
10
  const intl = useIntl();
@@ -4,9 +4,9 @@ const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const index = require("./index-DkTxsEqL.js");
6
6
  const designSystem = require("@strapi/design-system");
7
- const index$1 = require("./index-CodpLKZx.js");
8
- const objectLabels = require("./objectLabels-CSWGIgNb.js");
9
- const useHubspotSchema = require("./useHubspotSchema-DiRN3HrN.js");
7
+ const index$1 = require("./index-R3ReZXF1.js");
8
+ const objectLabels = require("./objectLabels-CW2iBOkD.js");
9
+ const useHubspotSchema = require("./useHubspotSchema-BRzzvs9t.js");
10
10
  function _interopNamespace(e) {
11
11
  if (e && e.__esModule) return e;
12
12
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -4,9 +4,9 @@ import { u as useIntl } from "./index-CEh8vkxY.mjs";
4
4
  import { Field, Flex, Loader, Combobox, ComboboxOption, IconButton, Button, Typography, Link } from "@strapi/design-system";
5
5
  import { ArrowClockwise } from "@strapi/icons";
6
6
  import { useField } from "@strapi/strapi/admin";
7
- import { g as getTranslation } from "./index-7cL9PRh1.mjs";
8
- import { o as objectLabel } from "./objectLabels-Dnj14fsp.mjs";
9
- import { u as useHubspotSchema } from "./useHubspotSchema-BsmQgJgx.mjs";
7
+ import { g as getTranslation } from "./index-CLAy5dVN.mjs";
8
+ import { o as objectLabel } from "./objectLabels--zOmqsfm.mjs";
9
+ import { u as useHubspotSchema } from "./useHubspotSchema-Bz2o1BU-.mjs";
10
10
  const oneLine = {
11
11
  display: "block",
12
12
  whiteSpace: "nowrap",
@@ -6,9 +6,9 @@ const index = require("./index-DkTxsEqL.js");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const icons = require("@strapi/icons");
8
8
  const admin = require("@strapi/strapi/admin");
9
- const index$1 = require("./index-CodpLKZx.js");
10
- const objectLabels = require("./objectLabels-CSWGIgNb.js");
11
- const useHubspotSchema = require("./useHubspotSchema-DiRN3HrN.js");
9
+ const index$1 = require("./index-R3ReZXF1.js");
10
+ const objectLabels = require("./objectLabels-CW2iBOkD.js");
11
+ const useHubspotSchema = require("./useHubspotSchema-BRzzvs9t.js");
12
12
  function _interopNamespace(e) {
13
13
  if (e && e.__esModule) return e;
14
14
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -5,9 +5,9 @@ const React = require("react");
5
5
  const index = require("./index-DkTxsEqL.js");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const admin = require("@strapi/strapi/admin");
8
- const index$1 = require("./index-CodpLKZx.js");
8
+ const index$1 = require("./index-R3ReZXF1.js");
9
9
  const reactRouterDom = require("react-router-dom");
10
- const objectLabels = require("./objectLabels-CSWGIgNb.js");
10
+ const objectLabels = require("./objectLabels-CW2iBOkD.js");
11
11
  function _interopNamespace(e) {
12
12
  if (e && e.__esModule) return e;
13
13
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -3,9 +3,9 @@ import * as React from "react";
3
3
  import { u as useIntl } from "./index-CEh8vkxY.mjs";
4
4
  import { Flex, Divider, Typography, Button, Box, Link, Badge, Loader, Field, SingleSelect, SingleSelectOption, Checkbox } from "@strapi/design-system";
5
5
  import { useFetchClient } from "@strapi/strapi/admin";
6
- import { g as getTranslation, P as PLUGIN_ID } from "./index-7cL9PRh1.mjs";
6
+ import { g as getTranslation, P as PLUGIN_ID } from "./index-CLAy5dVN.mjs";
7
7
  import { Link as Link$1 } from "react-router-dom";
8
- import { o as objectLabel } from "./objectLabels-Dnj14fsp.mjs";
8
+ import { o as objectLabel } from "./objectLabels--zOmqsfm.mjs";
9
9
  const AuditSection = ({ configured }) => {
10
10
  const intl = useIntl();
11
11
  const { formatMessage } = intl;
@@ -164,7 +164,11 @@ const en = {
164
164
  "editor.hubspot-form": "HubSpot marketing form",
165
165
  "editor.hubspot-form-placeholder": "Pick a form of the connected portal",
166
166
  "editor.hubspot-form-none": "None — CRM upsert only",
167
- "editor.hubspot-form-hint": "Submissions go through HubSpot’s Forms API so they count as conversions. Switch the connected portal (test → production) and pick the matching form — nothing is hardcoded.",
167
+ "editor.hubspot-form-hint": "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.",
168
+ "editor.resync": "Resync from HubSpot",
169
+ "editor.resynced": "Resynced from HubSpot — {updated, plural, one {# field updated} other {# fields updated}}, {added, plural, one {# added} other {# added}}.",
170
+ "editor.resynced-gaps": "Resynced from HubSpot — {updated, plural, one {# updated} other {# updated}}, {added, plural, one {# added} other {# added}}, {skipped, plural, one {# skipped} other {# skipped}}.",
171
+ "editor.resync-error": "Could not resync from HubSpot — is the form still linked?",
168
172
  "editor.form-hint": "Select a step or a field to edit it. The public endpoint serves this form at /api/hubspot/forms/{slug}.",
169
173
  "panel.label": "Label",
170
174
  "panel.name": "Payload key",
@@ -234,7 +238,7 @@ const en = {
234
238
  "forms.col-submissions": "Submissions",
235
239
  "forms.submissions": "Submissions",
236
240
  "forms.import-hubspot-title": "Import from your HubSpot portal",
237
- "forms.import-hubspot-hint": "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 overwrites the draft.",
241
+ "forms.import-hubspot-hint": "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.",
238
242
  "forms.import-hubspot-source": "HubSpot form to import",
239
243
  "forms.hubspot-list-error": "Could not list the portal's forms — the token needs the `forms` read scope.",
240
244
  "forms.report-title": "Imported with gaps",
@@ -295,7 +299,7 @@ const en = {
295
299
  "company.datum.nafLabel": "NAF label",
296
300
  "company.datum.headcount": "Headcount range",
297
301
  "editor.drag-step": "Drag to reorder the step",
298
- "editor.drag-field": "Drag to reorder the field"
302
+ "editor.drag-field": "Drag to move the field, including to another step"
299
303
  };
300
304
  export {
301
305
  en as default
@@ -166,7 +166,11 @@ const en = {
166
166
  "editor.hubspot-form": "HubSpot marketing form",
167
167
  "editor.hubspot-form-placeholder": "Pick a form of the connected portal",
168
168
  "editor.hubspot-form-none": "None — CRM upsert only",
169
- "editor.hubspot-form-hint": "Submissions go through HubSpot’s Forms API so they count as conversions. Switch the connected portal (test → production) and pick the matching form — nothing is hardcoded.",
169
+ "editor.hubspot-form-hint": "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.",
170
+ "editor.resync": "Resync from HubSpot",
171
+ "editor.resynced": "Resynced from HubSpot — {updated, plural, one {# field updated} other {# fields updated}}, {added, plural, one {# added} other {# added}}.",
172
+ "editor.resynced-gaps": "Resynced from HubSpot — {updated, plural, one {# updated} other {# updated}}, {added, plural, one {# added} other {# added}}, {skipped, plural, one {# skipped} other {# skipped}}.",
173
+ "editor.resync-error": "Could not resync from HubSpot — is the form still linked?",
170
174
  "editor.form-hint": "Select a step or a field to edit it. The public endpoint serves this form at /api/hubspot/forms/{slug}.",
171
175
  "panel.label": "Label",
172
176
  "panel.name": "Payload key",
@@ -236,7 +240,7 @@ const en = {
236
240
  "forms.col-submissions": "Submissions",
237
241
  "forms.submissions": "Submissions",
238
242
  "forms.import-hubspot-title": "Import from your HubSpot portal",
239
- "forms.import-hubspot-hint": "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 overwrites the draft.",
243
+ "forms.import-hubspot-hint": "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.",
240
244
  "forms.import-hubspot-source": "HubSpot form to import",
241
245
  "forms.hubspot-list-error": "Could not list the portal's forms — the token needs the `forms` read scope.",
242
246
  "forms.report-title": "Imported with gaps",
@@ -297,6 +301,6 @@ const en = {
297
301
  "company.datum.nafLabel": "NAF label",
298
302
  "company.datum.headcount": "Headcount range",
299
303
  "editor.drag-step": "Drag to reorder the step",
300
- "editor.drag-field": "Drag to reorder the field"
304
+ "editor.drag-field": "Drag to move the field, including to another step"
301
305
  };
302
306
  exports.default = en;