strapi-plugin-hubspot 0.15.0 → 0.16.1
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 +21 -0
- package/README.md +28 -13
- package/dist/_chunks/{Forms-ClyI4MJ1.js → Forms-D0QXkYAN.js} +216 -112
- package/dist/_chunks/{Forms-B7eIm0Fi.mjs → Forms-DEoZGrEt.mjs} +218 -114
- package/dist/_chunks/{HubspotFormInput-Do7F83V6.js → HubspotFormInput-4ZMYXWM_.js} +1 -1
- package/dist/_chunks/{HubspotFormInput-cZAiaAaq.mjs → HubspotFormInput-CPep55GL.mjs} +1 -1
- package/dist/_chunks/{HubspotObjectInput-DWqk2C26.js → HubspotObjectInput-BTqYXJIa.js} +3 -3
- package/dist/_chunks/{HubspotObjectInput-ZZk_7hWq.mjs → HubspotObjectInput-CQszIx1W.mjs} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-v9B3wb1a.js → HubspotPropertyInput-2MgIKlR_.js} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-5bkDGmGo.mjs → HubspotPropertyInput-ClNph0f1.mjs} +3 -3
- package/dist/_chunks/{Settings-QcFbm3s5.mjs → Settings-CZ-qQSKT.mjs} +78 -5
- package/dist/_chunks/{Settings-X3EHnTaO.js → Settings-DhiHQC6U.js} +77 -4
- package/dist/_chunks/{en-ZHvaZLi7.js → en-CSgFmKmM.js} +16 -3
- package/dist/_chunks/{en-DMJeF7EN.mjs → en-Dh3bMS6N.mjs} +16 -3
- package/dist/_chunks/{fr-Ds_2EAzZ.js → fr-D_EhZS0P.js} +16 -3
- package/dist/_chunks/{fr-CVAntLmc.mjs → fr-aWOIOlS9.mjs} +16 -3
- package/dist/_chunks/{index-BpcilDy1.js → index-ciliGv0E.js} +6 -6
- package/dist/_chunks/{index-BSJAhj8r.mjs → index-gKM4jVf8.mjs} +6 -6
- package/dist/_chunks/{objectLabels-CYXXFpNB.js → objectLabels-BjYfdhRB.js} +1 -1
- package/dist/_chunks/{objectLabels-CrYRzsqe.mjs → objectLabels-DQpSLUaJ.mjs} +1 -1
- package/dist/_chunks/{useHubspotSchema-CBF4GkmK.mjs → useHubspotSchema-CE7tJgOM.mjs} +1 -1
- package/dist/_chunks/{useHubspotSchema-Ba6xZUCL.js → useHubspotSchema-KKVppjC2.js} +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 +216 -7
- package/dist/server/index.mjs +216 -7
- package/dist/server/src/__tests__/formSync.test.d.ts +1 -0
- package/dist/server/src/formSync.d.ts +37 -0
- package/dist/server/src/forms.d.ts +6 -8
- package/dist/server/src/hsforms.d.ts +8 -0
- package/dist/server/src/importHubspot.d.ts +4 -0
- package/dist/server/src/index.d.ts +6 -0
- package/dist/server/src/settings.d.ts +32 -3
- package/package.json +1 -1
|
@@ -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-
|
|
8
|
+
const index$1 = require("./index-ciliGv0E.js");
|
|
9
9
|
const reactRouterDom = require("react-router-dom");
|
|
10
|
-
const objectLabels = require("./objectLabels-
|
|
10
|
+
const objectLabels = require("./objectLabels-BjYfdhRB.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" } });
|
|
@@ -201,6 +201,9 @@ const HubspotSettings = () => {
|
|
|
201
201
|
const [portalId, setPortalId] = React__namespace.useState("");
|
|
202
202
|
const [region, setRegion] = React__namespace.useState("eu1");
|
|
203
203
|
const [defaultFormId, setDefaultFormId] = React__namespace.useState("");
|
|
204
|
+
const [submissionMode, setSubmissionMode] = React__namespace.useState("auto");
|
|
205
|
+
const [writeExtraProperties, setWriteExtraProperties] = React__namespace.useState(true);
|
|
206
|
+
const [syncFieldsOnPublish, setSyncFieldsOnPublish] = React__namespace.useState(false);
|
|
204
207
|
const [forms, setForms] = React__namespace.useState([]);
|
|
205
208
|
const [busy, setBusy] = React__namespace.useState(false);
|
|
206
209
|
const [feedback, setFeedback] = React__namespace.useState(
|
|
@@ -212,6 +215,9 @@ const HubspotSettings = () => {
|
|
|
212
215
|
setPortalId(data.portalId ?? "");
|
|
213
216
|
setRegion(data.region || "eu1");
|
|
214
217
|
setDefaultFormId(data.defaultFormId ?? "");
|
|
218
|
+
setSubmissionMode(data.submissionMode === "crm" || data.submissionMode === "forms" ? data.submissionMode : "auto");
|
|
219
|
+
setWriteExtraProperties(data.writeExtraProperties !== false);
|
|
220
|
+
setSyncFieldsOnPublish(data.syncFieldsOnPublish === true);
|
|
215
221
|
setForms(Array.isArray(data.forms) ? data.forms : []);
|
|
216
222
|
};
|
|
217
223
|
const load = React__namespace.useCallback(async () => {
|
|
@@ -231,7 +237,10 @@ const HubspotSettings = () => {
|
|
|
231
237
|
...apiKey.trim() ? { apiKey: apiKey.trim() } : {},
|
|
232
238
|
portalId,
|
|
233
239
|
region,
|
|
234
|
-
defaultFormId
|
|
240
|
+
defaultFormId,
|
|
241
|
+
submissionMode,
|
|
242
|
+
writeExtraProperties,
|
|
243
|
+
syncFieldsOnPublish
|
|
235
244
|
});
|
|
236
245
|
setApiKey("");
|
|
237
246
|
await load();
|
|
@@ -401,7 +410,71 @@ const HubspotSettings = () => {
|
|
|
401
410
|
sourceHint(settings.formSource)
|
|
402
411
|
]
|
|
403
412
|
}
|
|
404
|
-
)
|
|
413
|
+
),
|
|
414
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: t("settings.policy.title", "How submissions reach HubSpot") }),
|
|
415
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
416
|
+
"settings.policy.hint",
|
|
417
|
+
"Pick the policy that matches this portal. Defaults stay safe for every install: conversions when a form is linked, leftover answers still written on the contact, HubSpot forms never mutated unless you ask."
|
|
418
|
+
) }),
|
|
419
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
420
|
+
designSystem.Field.Root,
|
|
421
|
+
{
|
|
422
|
+
name: "submissionMode",
|
|
423
|
+
hint: t(
|
|
424
|
+
"settings.mode.hint",
|
|
425
|
+
"Automatic uses the marketing form when one is linked, otherwise a CRM upsert. CRM-only never counts as a conversion. Forms-only prefers the Forms API and falls back to the CRM if HubSpot refuses the submit."
|
|
426
|
+
),
|
|
427
|
+
children: [
|
|
428
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("settings.mode.label", "Submission path") }),
|
|
429
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
430
|
+
designSystem.SingleSelect,
|
|
431
|
+
{
|
|
432
|
+
value: submissionMode,
|
|
433
|
+
onChange: (value) => {
|
|
434
|
+
const next = String(value);
|
|
435
|
+
if (next === "crm" || next === "forms" || next === "auto") setSubmissionMode(next);
|
|
436
|
+
},
|
|
437
|
+
children: [
|
|
438
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "auto", children: t("settings.mode.auto", "Automatic — form conversion if linked, else CRM") }),
|
|
439
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "forms", children: t("settings.mode.forms", "Marketing form — native HubSpot conversions") }),
|
|
440
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "crm", children: t("settings.mode.crm", "CRM only — upsert the contact, no form conversion") })
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
),
|
|
444
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
|
|
445
|
+
]
|
|
446
|
+
}
|
|
447
|
+
),
|
|
448
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
449
|
+
designSystem.Checkbox,
|
|
450
|
+
{
|
|
451
|
+
checked: writeExtraProperties,
|
|
452
|
+
onCheckedChange: (checked) => setWriteExtraProperties(checked === true),
|
|
453
|
+
children: t(
|
|
454
|
+
"settings.extra.label",
|
|
455
|
+
"After a conversion, also write mapped contact fields that the HubSpot form doesn't have"
|
|
456
|
+
)
|
|
457
|
+
}
|
|
458
|
+
),
|
|
459
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
460
|
+
"settings.extra.hint",
|
|
461
|
+
"The Forms API drops unknown fields (they 400 the submit). With this on, leftovers still land on the contact. Turn it off if HubSpot must only receive what the marketing form declares."
|
|
462
|
+
) }),
|
|
463
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
464
|
+
designSystem.Checkbox,
|
|
465
|
+
{
|
|
466
|
+
checked: syncFieldsOnPublish,
|
|
467
|
+
onCheckedChange: (checked) => setSyncFieldsOnPublish(checked === true),
|
|
468
|
+
children: t(
|
|
469
|
+
"settings.sync.label",
|
|
470
|
+
"On publish, add mapped contact fields that are missing on the HubSpot form"
|
|
471
|
+
)
|
|
472
|
+
}
|
|
473
|
+
),
|
|
474
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
475
|
+
"settings.sync.hint",
|
|
476
|
+
"Strapi-first installs: a field added here appears on the HubSpot form next publish. HubSpot-first installs should leave this off — importing a form already carries its fields. Properties themselves are never created; map to ones that exist in the portal."
|
|
477
|
+
) })
|
|
405
478
|
] }) }),
|
|
406
479
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
407
480
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: save, loading: busy, children: t("settings.save", "Save") }),
|
|
@@ -30,7 +30,18 @@ const en = {
|
|
|
30
30
|
"picker.refresh": "Refresh the properties from HubSpot",
|
|
31
31
|
"picker.import": "Import the {count} options from HubSpot",
|
|
32
32
|
"picker.imported": "Options imported — save to keep them.",
|
|
33
|
-
"settings.subtitle": "Private app token
|
|
33
|
+
"settings.subtitle": "Private app token, HubSpot account, and how submissions reach the CRM. Switch test → production here — nothing is hardcoded.",
|
|
34
|
+
"settings.policy.title": "How submissions reach HubSpot",
|
|
35
|
+
"settings.policy.hint": "Pick the policy that matches this portal. Defaults stay safe for every install: conversions when a form is linked, leftover answers still written on the contact, HubSpot forms never mutated unless you ask.",
|
|
36
|
+
"settings.mode.label": "Submission path",
|
|
37
|
+
"settings.mode.hint": "Automatic uses the marketing form when one is linked, otherwise a CRM upsert. CRM-only never counts as a conversion. Forms-only prefers the Forms API and falls back to the CRM if HubSpot refuses the submit.",
|
|
38
|
+
"settings.mode.auto": "Automatic — form conversion if linked, else CRM",
|
|
39
|
+
"settings.mode.forms": "Marketing form — native HubSpot conversions",
|
|
40
|
+
"settings.mode.crm": "CRM only — upsert the contact, no form conversion",
|
|
41
|
+
"settings.extra.label": "After a conversion, also write mapped contact fields that the HubSpot form doesn't have",
|
|
42
|
+
"settings.extra.hint": "The Forms API drops unknown fields (they 400 the submit). With this on, leftovers still land on the contact. Turn it off if HubSpot must only receive what the marketing form declares.",
|
|
43
|
+
"settings.sync.label": "On publish, add mapped contact fields that are missing on the HubSpot form",
|
|
44
|
+
"settings.sync.hint": "Strapi-first installs: a field added here appears on the HubSpot form next publish. HubSpot-first installs should leave this off — importing a form already carries its fields. Properties themselves are never created; map to ones that exist in the portal.",
|
|
34
45
|
"settings.configured": "Configured {hint}",
|
|
35
46
|
"settings.not-configured": "Not configured",
|
|
36
47
|
"settings.source": "source: {source}",
|
|
@@ -62,7 +73,7 @@ const en = {
|
|
|
62
73
|
"settings.test-ok": "Connection established — {count} readable properties.",
|
|
63
74
|
"settings.test-no-key": "No key configured.",
|
|
64
75
|
"settings.test-error": "HubSpot unreachable — invalid or revoked key?",
|
|
65
|
-
"settings.scopes": "The token needs crm.schemas.contacts.read, crm.schemas.companies.read and forms (to list and
|
|
76
|
+
"settings.scopes": "The token needs crm.schemas.contacts.read, crm.schemas.companies.read and forms (to list, submit, and optionally update marketing forms). The token is never returned to the browser.",
|
|
66
77
|
"audit.title": "Mapping audit",
|
|
67
78
|
"audit.subtitle": "Scans every entry of the validated content types and lists the mappings the portal would reject today — including properties deleted in HubSpot since they were saved.",
|
|
68
79
|
"audit.run": "Run the audit",
|
|
@@ -122,6 +133,8 @@ const en = {
|
|
|
122
133
|
"editor.invalid": "The structure has problems — see the flagged cards.",
|
|
123
134
|
"editor.publish": "Publish",
|
|
124
135
|
"editor.published": "Form published.",
|
|
136
|
+
"editor.published-synced": "Form published. {count, plural, one {# field added} other {# fields added}} to the HubSpot form.",
|
|
137
|
+
"editor.published-sync-warn": "Form published. HubSpot field sync failed: {error}",
|
|
125
138
|
"editor.publish-blocked": "Publishing is blocked — fix the flagged mappings first.",
|
|
126
139
|
"editor.unpublish": "Unpublish",
|
|
127
140
|
"editor.unpublished": "Form unpublished.",
|
|
@@ -284,6 +297,6 @@ const en = {
|
|
|
284
297
|
"company.datum.nafLabel": "NAF label",
|
|
285
298
|
"company.datum.headcount": "Headcount range",
|
|
286
299
|
"editor.drag-step": "Drag to reorder the step",
|
|
287
|
-
"editor.drag-field": "Drag to
|
|
300
|
+
"editor.drag-field": "Drag to move the field, including to another step"
|
|
288
301
|
};
|
|
289
302
|
exports.default = en;
|
|
@@ -28,7 +28,18 @@ const en = {
|
|
|
28
28
|
"picker.refresh": "Refresh the properties from HubSpot",
|
|
29
29
|
"picker.import": "Import the {count} options from HubSpot",
|
|
30
30
|
"picker.imported": "Options imported — save to keep them.",
|
|
31
|
-
"settings.subtitle": "Private app token
|
|
31
|
+
"settings.subtitle": "Private app token, HubSpot account, and how submissions reach the CRM. Switch test → production here — nothing is hardcoded.",
|
|
32
|
+
"settings.policy.title": "How submissions reach HubSpot",
|
|
33
|
+
"settings.policy.hint": "Pick the policy that matches this portal. Defaults stay safe for every install: conversions when a form is linked, leftover answers still written on the contact, HubSpot forms never mutated unless you ask.",
|
|
34
|
+
"settings.mode.label": "Submission path",
|
|
35
|
+
"settings.mode.hint": "Automatic uses the marketing form when one is linked, otherwise a CRM upsert. CRM-only never counts as a conversion. Forms-only prefers the Forms API and falls back to the CRM if HubSpot refuses the submit.",
|
|
36
|
+
"settings.mode.auto": "Automatic — form conversion if linked, else CRM",
|
|
37
|
+
"settings.mode.forms": "Marketing form — native HubSpot conversions",
|
|
38
|
+
"settings.mode.crm": "CRM only — upsert the contact, no form conversion",
|
|
39
|
+
"settings.extra.label": "After a conversion, also write mapped contact fields that the HubSpot form doesn't have",
|
|
40
|
+
"settings.extra.hint": "The Forms API drops unknown fields (they 400 the submit). With this on, leftovers still land on the contact. Turn it off if HubSpot must only receive what the marketing form declares.",
|
|
41
|
+
"settings.sync.label": "On publish, add mapped contact fields that are missing on the HubSpot form",
|
|
42
|
+
"settings.sync.hint": "Strapi-first installs: a field added here appears on the HubSpot form next publish. HubSpot-first installs should leave this off — importing a form already carries its fields. Properties themselves are never created; map to ones that exist in the portal.",
|
|
32
43
|
"settings.configured": "Configured {hint}",
|
|
33
44
|
"settings.not-configured": "Not configured",
|
|
34
45
|
"settings.source": "source: {source}",
|
|
@@ -60,7 +71,7 @@ const en = {
|
|
|
60
71
|
"settings.test-ok": "Connection established — {count} readable properties.",
|
|
61
72
|
"settings.test-no-key": "No key configured.",
|
|
62
73
|
"settings.test-error": "HubSpot unreachable — invalid or revoked key?",
|
|
63
|
-
"settings.scopes": "The token needs crm.schemas.contacts.read, crm.schemas.companies.read and forms (to list and
|
|
74
|
+
"settings.scopes": "The token needs crm.schemas.contacts.read, crm.schemas.companies.read and forms (to list, submit, and optionally update marketing forms). The token is never returned to the browser.",
|
|
64
75
|
"audit.title": "Mapping audit",
|
|
65
76
|
"audit.subtitle": "Scans every entry of the validated content types and lists the mappings the portal would reject today — including properties deleted in HubSpot since they were saved.",
|
|
66
77
|
"audit.run": "Run the audit",
|
|
@@ -120,6 +131,8 @@ const en = {
|
|
|
120
131
|
"editor.invalid": "The structure has problems — see the flagged cards.",
|
|
121
132
|
"editor.publish": "Publish",
|
|
122
133
|
"editor.published": "Form published.",
|
|
134
|
+
"editor.published-synced": "Form published. {count, plural, one {# field added} other {# fields added}} to the HubSpot form.",
|
|
135
|
+
"editor.published-sync-warn": "Form published. HubSpot field sync failed: {error}",
|
|
123
136
|
"editor.publish-blocked": "Publishing is blocked — fix the flagged mappings first.",
|
|
124
137
|
"editor.unpublish": "Unpublish",
|
|
125
138
|
"editor.unpublished": "Form unpublished.",
|
|
@@ -282,7 +295,7 @@ const en = {
|
|
|
282
295
|
"company.datum.nafLabel": "NAF label",
|
|
283
296
|
"company.datum.headcount": "Headcount range",
|
|
284
297
|
"editor.drag-step": "Drag to reorder the step",
|
|
285
|
-
"editor.drag-field": "Drag to
|
|
298
|
+
"editor.drag-field": "Drag to move the field, including to another step"
|
|
286
299
|
};
|
|
287
300
|
export {
|
|
288
301
|
en as default
|
|
@@ -30,7 +30,18 @@ const fr = {
|
|
|
30
30
|
"picker.refresh": "Rafraîchir les propriétés depuis HubSpot",
|
|
31
31
|
"picker.import": "Importer les {count} options depuis HubSpot",
|
|
32
32
|
"picker.imported": "Options importées — enregistrez pour les conserver.",
|
|
33
|
-
"settings.subtitle": "Jeton d'application privée
|
|
33
|
+
"settings.subtitle": "Jeton d'application privée, compte HubSpot, et la façon dont les envois atteignent le CRM. Passez du test à la prod ici — rien n'est figé dans le code.",
|
|
34
|
+
"settings.policy.title": "Comment les envois atteignent HubSpot",
|
|
35
|
+
"settings.policy.hint": "Choisissez la politique de ce portail. Les défauts restent sûrs pour toute install : conversion si un formulaire est lié, réponses en trop écrites sur le contact, formulaires HubSpot jamais mutés sauf si vous le demandez.",
|
|
36
|
+
"settings.mode.label": "Chemin d'envoi",
|
|
37
|
+
"settings.mode.hint": "Automatique utilise le formulaire marketing s'il est lié, sinon un upsert CRM. CRM seul ne compte jamais comme conversion. Formulaire marketing privilégie l'API Forms et retombe sur le CRM si HubSpot refuse l'envoi.",
|
|
38
|
+
"settings.mode.auto": "Automatique — conversion si un formulaire est lié, sinon CRM",
|
|
39
|
+
"settings.mode.forms": "Formulaire marketing — conversions HubSpot natives",
|
|
40
|
+
"settings.mode.crm": "CRM uniquement — upsert du contact, pas de conversion",
|
|
41
|
+
"settings.extra.label": "Après une conversion, écrire aussi sur le contact les champs mappés absents du formulaire HubSpot",
|
|
42
|
+
"settings.extra.hint": "L'API Forms écarte les champs inconnus (ils font échouer tout l'envoi). Activé, les champs restants atterrissent quand même sur le contact. Désactivez si HubSpot ne doit recevoir que ce que le formulaire marketing déclare.",
|
|
43
|
+
"settings.sync.label": "À la publication, ajouter au formulaire HubSpot les champs mappés manquants",
|
|
44
|
+
"settings.sync.hint": "Install Strapi-first : un champ ajouté ici apparaît sur le formulaire HubSpot à la publication suivante. Install HubSpot-first : laissez désactivé — l'import porte déjà les champs. Les propriétés CRM ne sont jamais créées ; mappez vers des propriétés déjà présentes dans le portail.",
|
|
34
45
|
"settings.configured": "Configurée {hint}",
|
|
35
46
|
"settings.not-configured": "Non configurée",
|
|
36
47
|
"settings.source": "source : {source}",
|
|
@@ -62,7 +73,7 @@ const fr = {
|
|
|
62
73
|
"settings.test-ok": "Connexion établie — {count} propriétés lisibles.",
|
|
63
74
|
"settings.test-no-key": "Aucune clé configurée.",
|
|
64
75
|
"settings.test-error": "HubSpot injoignable — clé invalide ou révoquée ?",
|
|
65
|
-
"settings.scopes": "Le jeton a besoin de crm.schemas.contacts.read, crm.schemas.companies.read et forms (lister et
|
|
76
|
+
"settings.scopes": "Le jeton a besoin de crm.schemas.contacts.read, crm.schemas.companies.read et forms (lister, soumettre et éventuellement mettre à jour les formulaires marketing). Il n'est jamais renvoyé au navigateur.",
|
|
66
77
|
"audit.title": "Audit des mappings",
|
|
67
78
|
"audit.subtitle": "Parcourt toutes les entrées des content-types validés et liste les mappings que le portail refuserait aujourd'hui — y compris les propriétés supprimées dans HubSpot depuis leur enregistrement.",
|
|
68
79
|
"audit.run": "Lancer l'audit",
|
|
@@ -122,6 +133,8 @@ const fr = {
|
|
|
122
133
|
"editor.invalid": "La structure a des problèmes — voir les cartes signalées.",
|
|
123
134
|
"editor.publish": "Publier",
|
|
124
135
|
"editor.published": "Formulaire publié.",
|
|
136
|
+
"editor.published-synced": "Formulaire publié. {count, plural, one {# champ ajouté} other {# champs ajoutés}} au formulaire HubSpot.",
|
|
137
|
+
"editor.published-sync-warn": "Formulaire publié. La sync des champs HubSpot a échoué : {error}",
|
|
125
138
|
"editor.publish-blocked": "Publication bloquée — corrigez d'abord les mappings signalés.",
|
|
126
139
|
"editor.unpublish": "Dépublier",
|
|
127
140
|
"editor.unpublished": "Formulaire dépublié.",
|
|
@@ -284,6 +297,6 @@ const fr = {
|
|
|
284
297
|
"company.datum.nafLabel": "Libellé NAF",
|
|
285
298
|
"company.datum.headcount": "Tranche d'effectif",
|
|
286
299
|
"editor.drag-step": "Glisser pour réordonner l'étape",
|
|
287
|
-
"editor.drag-field": "Glisser pour
|
|
300
|
+
"editor.drag-field": "Glisser pour déplacer le champ, y compris vers une autre étape"
|
|
288
301
|
};
|
|
289
302
|
exports.default = fr;
|
|
@@ -28,7 +28,18 @@ const fr = {
|
|
|
28
28
|
"picker.refresh": "Rafraîchir les propriétés depuis HubSpot",
|
|
29
29
|
"picker.import": "Importer les {count} options depuis HubSpot",
|
|
30
30
|
"picker.imported": "Options importées — enregistrez pour les conserver.",
|
|
31
|
-
"settings.subtitle": "Jeton d'application privée
|
|
31
|
+
"settings.subtitle": "Jeton d'application privée, compte HubSpot, et la façon dont les envois atteignent le CRM. Passez du test à la prod ici — rien n'est figé dans le code.",
|
|
32
|
+
"settings.policy.title": "Comment les envois atteignent HubSpot",
|
|
33
|
+
"settings.policy.hint": "Choisissez la politique de ce portail. Les défauts restent sûrs pour toute install : conversion si un formulaire est lié, réponses en trop écrites sur le contact, formulaires HubSpot jamais mutés sauf si vous le demandez.",
|
|
34
|
+
"settings.mode.label": "Chemin d'envoi",
|
|
35
|
+
"settings.mode.hint": "Automatique utilise le formulaire marketing s'il est lié, sinon un upsert CRM. CRM seul ne compte jamais comme conversion. Formulaire marketing privilégie l'API Forms et retombe sur le CRM si HubSpot refuse l'envoi.",
|
|
36
|
+
"settings.mode.auto": "Automatique — conversion si un formulaire est lié, sinon CRM",
|
|
37
|
+
"settings.mode.forms": "Formulaire marketing — conversions HubSpot natives",
|
|
38
|
+
"settings.mode.crm": "CRM uniquement — upsert du contact, pas de conversion",
|
|
39
|
+
"settings.extra.label": "Après une conversion, écrire aussi sur le contact les champs mappés absents du formulaire HubSpot",
|
|
40
|
+
"settings.extra.hint": "L'API Forms écarte les champs inconnus (ils font échouer tout l'envoi). Activé, les champs restants atterrissent quand même sur le contact. Désactivez si HubSpot ne doit recevoir que ce que le formulaire marketing déclare.",
|
|
41
|
+
"settings.sync.label": "À la publication, ajouter au formulaire HubSpot les champs mappés manquants",
|
|
42
|
+
"settings.sync.hint": "Install Strapi-first : un champ ajouté ici apparaît sur le formulaire HubSpot à la publication suivante. Install HubSpot-first : laissez désactivé — l'import porte déjà les champs. Les propriétés CRM ne sont jamais créées ; mappez vers des propriétés déjà présentes dans le portail.",
|
|
32
43
|
"settings.configured": "Configurée {hint}",
|
|
33
44
|
"settings.not-configured": "Non configurée",
|
|
34
45
|
"settings.source": "source : {source}",
|
|
@@ -60,7 +71,7 @@ const fr = {
|
|
|
60
71
|
"settings.test-ok": "Connexion établie — {count} propriétés lisibles.",
|
|
61
72
|
"settings.test-no-key": "Aucune clé configurée.",
|
|
62
73
|
"settings.test-error": "HubSpot injoignable — clé invalide ou révoquée ?",
|
|
63
|
-
"settings.scopes": "Le jeton a besoin de crm.schemas.contacts.read, crm.schemas.companies.read et forms (lister et
|
|
74
|
+
"settings.scopes": "Le jeton a besoin de crm.schemas.contacts.read, crm.schemas.companies.read et forms (lister, soumettre et éventuellement mettre à jour les formulaires marketing). Il n'est jamais renvoyé au navigateur.",
|
|
64
75
|
"audit.title": "Audit des mappings",
|
|
65
76
|
"audit.subtitle": "Parcourt toutes les entrées des content-types validés et liste les mappings que le portail refuserait aujourd'hui — y compris les propriétés supprimées dans HubSpot depuis leur enregistrement.",
|
|
66
77
|
"audit.run": "Lancer l'audit",
|
|
@@ -120,6 +131,8 @@ const fr = {
|
|
|
120
131
|
"editor.invalid": "La structure a des problèmes — voir les cartes signalées.",
|
|
121
132
|
"editor.publish": "Publier",
|
|
122
133
|
"editor.published": "Formulaire publié.",
|
|
134
|
+
"editor.published-synced": "Formulaire publié. {count, plural, one {# champ ajouté} other {# champs ajoutés}} au formulaire HubSpot.",
|
|
135
|
+
"editor.published-sync-warn": "Formulaire publié. La sync des champs HubSpot a échoué : {error}",
|
|
123
136
|
"editor.publish-blocked": "Publication bloquée — corrigez d'abord les mappings signalés.",
|
|
124
137
|
"editor.unpublish": "Dépublier",
|
|
125
138
|
"editor.unpublished": "Formulaire dépublié.",
|
|
@@ -282,7 +295,7 @@ const fr = {
|
|
|
282
295
|
"company.datum.nafLabel": "Libellé NAF",
|
|
283
296
|
"company.datum.headcount": "Tranche d'effectif",
|
|
284
297
|
"editor.drag-step": "Glisser pour réordonner l'étape",
|
|
285
|
-
"editor.drag-field": "Glisser pour
|
|
298
|
+
"editor.drag-field": "Glisser pour déplacer le champ, y compris vers une autre étape"
|
|
286
299
|
};
|
|
287
300
|
export {
|
|
288
301
|
fr as default
|
|
@@ -26,7 +26,7 @@ const index = {
|
|
|
26
26
|
icon: icons.PaperPlane,
|
|
27
27
|
intlLabel: { id: `${PLUGIN_ID}.menu.label`, defaultMessage: "HubSpot Forms" },
|
|
28
28
|
permissions: [{ action: `plugin::${PLUGIN_ID}.forms`, subject: null }],
|
|
29
|
-
Component: async () => (await Promise.resolve().then(() => require("./Forms-
|
|
29
|
+
Component: async () => (await Promise.resolve().then(() => require("./Forms-D0QXkYAN.js"))).default
|
|
30
30
|
});
|
|
31
31
|
app.customFields.register({
|
|
32
32
|
name: "property",
|
|
@@ -41,7 +41,7 @@ const index = {
|
|
|
41
41
|
defaultMessage: "Picked from the portal's real properties"
|
|
42
42
|
},
|
|
43
43
|
components: {
|
|
44
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotPropertyInput-
|
|
44
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotPropertyInput-2MgIKlR_.js"))
|
|
45
45
|
},
|
|
46
46
|
// Exposed in the Content-Type Builder. Without this, `objectField` could
|
|
47
47
|
// only be set by hand-editing schema.json — which is not how anyone
|
|
@@ -104,7 +104,7 @@ const index = {
|
|
|
104
104
|
defaultMessage: "Picked from the portal's configured objects"
|
|
105
105
|
},
|
|
106
106
|
components: {
|
|
107
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotObjectInput-
|
|
107
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotObjectInput-BTqYXJIa.js"))
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
app.customFields.register({
|
|
@@ -120,7 +120,7 @@ const index = {
|
|
|
120
120
|
defaultMessage: "A form built in the HubSpot form builder, stored by slug"
|
|
121
121
|
},
|
|
122
122
|
components: {
|
|
123
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotFormInput-
|
|
123
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotFormInput-4ZMYXWM_.js"))
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
app.createSettingSection(
|
|
@@ -136,7 +136,7 @@ const index = {
|
|
|
136
136
|
// Mirrors the RBAC action registered server-side: a role without it
|
|
137
137
|
// doesn't see the link at all — the routes refuse it anyway.
|
|
138
138
|
permissions: [{ action: `plugin::${PLUGIN_ID}.settings`, subject: null }],
|
|
139
|
-
Component: async () => (await Promise.resolve().then(() => require("./Settings-
|
|
139
|
+
Component: async () => (await Promise.resolve().then(() => require("./Settings-DhiHQC6U.js"))).default
|
|
140
140
|
}
|
|
141
141
|
]
|
|
142
142
|
);
|
|
@@ -146,7 +146,7 @@ const index = {
|
|
|
146
146
|
return Promise.all(
|
|
147
147
|
locales.map(async (locale) => {
|
|
148
148
|
try {
|
|
149
|
-
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-
|
|
149
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-CSgFmKmM.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-D_EhZS0P.js")) }), `./translations/${locale}.json`, 3);
|
|
150
150
|
return { data: prefixPluginTranslations(data), locale };
|
|
151
151
|
} catch {
|
|
152
152
|
return { data: {}, locale };
|
|
@@ -25,7 +25,7 @@ const index = {
|
|
|
25
25
|
icon: PaperPlane,
|
|
26
26
|
intlLabel: { id: `${PLUGIN_ID}.menu.label`, defaultMessage: "HubSpot Forms" },
|
|
27
27
|
permissions: [{ action: `plugin::${PLUGIN_ID}.forms`, subject: null }],
|
|
28
|
-
Component: async () => (await import("./Forms-
|
|
28
|
+
Component: async () => (await import("./Forms-DEoZGrEt.mjs")).default
|
|
29
29
|
});
|
|
30
30
|
app.customFields.register({
|
|
31
31
|
name: "property",
|
|
@@ -40,7 +40,7 @@ const index = {
|
|
|
40
40
|
defaultMessage: "Picked from the portal's real properties"
|
|
41
41
|
},
|
|
42
42
|
components: {
|
|
43
|
-
Input: async () => import("./HubspotPropertyInput-
|
|
43
|
+
Input: async () => import("./HubspotPropertyInput-ClNph0f1.mjs")
|
|
44
44
|
},
|
|
45
45
|
// Exposed in the Content-Type Builder. Without this, `objectField` could
|
|
46
46
|
// only be set by hand-editing schema.json — which is not how anyone
|
|
@@ -103,7 +103,7 @@ const index = {
|
|
|
103
103
|
defaultMessage: "Picked from the portal's configured objects"
|
|
104
104
|
},
|
|
105
105
|
components: {
|
|
106
|
-
Input: async () => import("./HubspotObjectInput-
|
|
106
|
+
Input: async () => import("./HubspotObjectInput-CQszIx1W.mjs")
|
|
107
107
|
}
|
|
108
108
|
});
|
|
109
109
|
app.customFields.register({
|
|
@@ -119,7 +119,7 @@ const index = {
|
|
|
119
119
|
defaultMessage: "A form built in the HubSpot form builder, stored by slug"
|
|
120
120
|
},
|
|
121
121
|
components: {
|
|
122
|
-
Input: async () => import("./HubspotFormInput-
|
|
122
|
+
Input: async () => import("./HubspotFormInput-CPep55GL.mjs")
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
app.createSettingSection(
|
|
@@ -135,7 +135,7 @@ const index = {
|
|
|
135
135
|
// Mirrors the RBAC action registered server-side: a role without it
|
|
136
136
|
// doesn't see the link at all — the routes refuse it anyway.
|
|
137
137
|
permissions: [{ action: `plugin::${PLUGIN_ID}.settings`, subject: null }],
|
|
138
|
-
Component: async () => (await import("./Settings-
|
|
138
|
+
Component: async () => (await import("./Settings-CZ-qQSKT.mjs")).default
|
|
139
139
|
}
|
|
140
140
|
]
|
|
141
141
|
);
|
|
@@ -145,7 +145,7 @@ const index = {
|
|
|
145
145
|
return Promise.all(
|
|
146
146
|
locales.map(async (locale) => {
|
|
147
147
|
try {
|
|
148
|
-
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-
|
|
148
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-Dh3bMS6N.mjs"), "./translations/fr.json": () => import("./fr-aWOIOlS9.mjs") }), `./translations/${locale}.json`, 3);
|
|
149
149
|
return { data: prefixPluginTranslations(data), locale };
|
|
150
150
|
} catch {
|
|
151
151
|
return { data: {}, locale };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
3
|
-
import { P as PLUGIN_ID } from "./index-
|
|
3
|
+
import { P as PLUGIN_ID } from "./index-gKM4jVf8.mjs";
|
|
4
4
|
let cached = null;
|
|
5
5
|
let inFlight = null;
|
|
6
6
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const React = require("react");
|
|
3
3
|
const admin = require("@strapi/strapi/admin");
|
|
4
|
-
const index = require("./index-
|
|
4
|
+
const index = require("./index-ciliGv0E.js");
|
|
5
5
|
function _interopNamespace(e) {
|
|
6
6
|
if (e && e.__esModule) return e;
|
|
7
7
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { type DragEndEvent } from "@dnd-kit/core";
|
|
3
|
+
import { arrayMove, relocateField } from "./relocateField";
|
|
4
|
+
export { arrayMove, relocateField };
|
|
5
|
+
export type { DragEndEvent };
|
|
4
6
|
/** The drag-handle props to spread on the grip element. */
|
|
5
7
|
export interface HandleProps {
|
|
6
8
|
attributes: React.HTMLAttributes<HTMLElement>;
|
|
7
9
|
listeners: Record<string, unknown> | undefined;
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export type SortableData = {
|
|
12
|
+
type: "step";
|
|
13
|
+
} | {
|
|
14
|
+
type: "field";
|
|
15
|
+
stepId: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: "container";
|
|
18
|
+
stepId: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function SortableBoard({ children, onDragEnd, }: {
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
onDragEnd: (event: DragEndEvent) => void;
|
|
23
|
+
}): React.JSX.Element;
|
|
24
|
+
export declare function SortableGroup({ ids, children, }: {
|
|
16
25
|
ids: string[];
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
}): React.JSX.Element;
|
|
28
|
+
/** Drop target for a step's field list — including when the list is empty. */
|
|
29
|
+
export declare function SortableContainer({ stepId, children, }: {
|
|
30
|
+
stepId: string;
|
|
19
31
|
children: React.ReactNode;
|
|
20
32
|
}): React.JSX.Element;
|
|
21
33
|
/** A sortable row: wraps the card, hands the grip props to its children. */
|
|
22
|
-
export declare function SortableItem({ id, children, }: {
|
|
34
|
+
export declare function SortableItem({ id, data, children, }: {
|
|
23
35
|
id: string;
|
|
36
|
+
data?: SortableData;
|
|
24
37
|
children: (handle: HandleProps) => React.ReactNode;
|
|
25
38
|
}): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { arrayMove } from "@dnd-kit/sortable";
|
|
2
|
+
export { arrayMove };
|
|
3
|
+
/**
|
|
4
|
+
* Move `fieldId` onto `overId` across steps.
|
|
5
|
+
*
|
|
6
|
+
* `overId` is another field (insert at that index), a step id (append),
|
|
7
|
+
* or `container:${stepId}` (the empty-area droppable of that step).
|
|
8
|
+
*/
|
|
9
|
+
export declare function relocateField<S extends {
|
|
10
|
+
id: string;
|
|
11
|
+
fields: F[];
|
|
12
|
+
}, F extends {
|
|
13
|
+
id: string;
|
|
14
|
+
}>(steps: S[], fieldId: string, overId: string): S[];
|