hs-uix 2.1.0 → 2.2.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/README.md +3 -1
- package/common-components.d.ts +319 -68
- package/dist/calendar.js +397 -119
- package/dist/calendar.mjs +399 -119
- package/dist/common-components.js +3546 -88
- package/dist/common-components.mjs +3530 -84
- package/dist/datatable.js +108 -18
- package/dist/datatable.mjs +108 -18
- package/dist/experimental.js +2876 -0
- package/dist/experimental.mjs +2883 -0
- package/dist/feed.js +267 -38
- package/dist/feed.mjs +260 -37
- package/dist/filter.js +1379 -0
- package/dist/filter.mjs +1334 -0
- package/dist/form.js +222 -26
- package/dist/form.mjs +227 -27
- package/dist/index.js +3255 -353
- package/dist/index.mjs +3199 -344
- package/dist/kanban.js +282 -62
- package/dist/kanban.mjs +273 -61
- package/dist/safe.js +9207 -0
- package/dist/safe.mjs +9298 -0
- package/dist/utils.js +491 -75
- package/dist/utils.mjs +491 -75
- package/experimental.d.ts +1 -0
- package/filter.d.ts +1 -0
- package/index.d.ts +45 -3
- package/package.json +19 -1
- package/safe.d.ts +1 -0
- package/src/calendar/README.md +76 -5
- package/src/calendar/index.d.ts +108 -1
- package/src/common-components/README.md +140 -1
- package/src/datatable/README.md +0 -2
- package/src/experimental/README.md +126 -0
- package/src/experimental/index.d.ts +346 -0
- package/src/feed/README.md +69 -0
- package/src/feed/index.d.ts +103 -0
- package/src/filter/README.md +148 -0
- package/src/filter/index.d.ts +221 -0
- package/src/form/README.md +132 -4
- package/src/form/index.d.ts +82 -1
- package/src/kanban/README.md +119 -6
- package/src/kanban/index.d.ts +153 -2
- package/src/safe/README.md +108 -0
- package/src/safe/index.d.ts +158 -0
- package/src/utils/README.md +39 -0
- package/src/wizard/README.md +158 -0
- package/src/wizard/index.d.ts +138 -0
- package/utils.d.ts +17 -0
package/dist/form.mjs
CHANGED
|
@@ -35,7 +35,12 @@ import {
|
|
|
35
35
|
TimeInput,
|
|
36
36
|
Toggle,
|
|
37
37
|
Checkbox,
|
|
38
|
-
ToggleGroup
|
|
38
|
+
ToggleGroup,
|
|
39
|
+
Modal,
|
|
40
|
+
ModalBody,
|
|
41
|
+
ModalFooter,
|
|
42
|
+
LoadingSpinner,
|
|
43
|
+
useExtensionActions
|
|
39
44
|
} from "@hubspot/ui-extensions";
|
|
40
45
|
|
|
41
46
|
// src/common-components/Icon.js
|
|
@@ -297,7 +302,7 @@ var GENERATED_ICONS = {
|
|
|
297
302
|
"ZoomOut": { "viewBox": "0 0 32 32", "paths": ["M14.42 26.75c2.85 0 5.47-.97 7.56-2.6l-.03.02 5.28 5.34a1.619 1.619 0 0 0 2.76-1.15c0-.45-.18-.85-.47-1.14l-5.33-5.33c1.59-2.06 2.55-4.68 2.55-7.52C26.74 7.54 21.2 2 14.37 2S2 7.55 2 14.38s5.54 12.37 12.37 12.37h.05m0-21.55c5.06 0 9.16 4.1 9.16 9.16s-4.1 9.16-9.16 9.16-9.16-4.1-9.16-9.16c.01-5.05 4.11-9.14 9.16-9.15Zm-4.31 10.78h8.62c.89 0 1.62-.72 1.62-1.62s-.72-1.62-1.62-1.62h-8.62c-.89 0-1.62.72-1.62 1.62s.72 1.62 1.62 1.62"] }
|
|
298
303
|
};
|
|
299
304
|
|
|
300
|
-
// src/common-components/
|
|
305
|
+
// src/common-components/nativeIconNames.js
|
|
301
306
|
var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
|
|
302
307
|
"add",
|
|
303
308
|
"appointment",
|
|
@@ -309,12 +314,12 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
|
|
|
309
314
|
"block",
|
|
310
315
|
"book",
|
|
311
316
|
"bulb",
|
|
317
|
+
"callTranscript",
|
|
312
318
|
"calling",
|
|
313
319
|
"callingHangup",
|
|
314
320
|
"callingMade",
|
|
315
321
|
"callingMissed",
|
|
316
322
|
"callingVoicemail",
|
|
317
|
-
"callTranscript",
|
|
318
323
|
"campaigns",
|
|
319
324
|
"cap",
|
|
320
325
|
"checkCircle",
|
|
@@ -343,13 +348,13 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
|
|
|
343
348
|
"enroll",
|
|
344
349
|
"exclamation",
|
|
345
350
|
"exclamationCircle",
|
|
346
|
-
"facebook",
|
|
347
351
|
"faceHappy",
|
|
348
352
|
"faceHappyFilled",
|
|
349
353
|
"faceNeutral",
|
|
350
354
|
"faceNeutralFilled",
|
|
351
355
|
"faceSad",
|
|
352
356
|
"faceSadFilled",
|
|
357
|
+
"facebook",
|
|
353
358
|
"favoriteHollow",
|
|
354
359
|
"file",
|
|
355
360
|
"filledXCircleIcon",
|
|
@@ -490,6 +495,8 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
|
|
|
490
495
|
"zoomIn",
|
|
491
496
|
"zoomOut"
|
|
492
497
|
]);
|
|
498
|
+
|
|
499
|
+
// src/common-components/Icon.js
|
|
493
500
|
var NATIVE_COLORS = /* @__PURE__ */ new Set(["inherit", "alert", "warning", "success"]);
|
|
494
501
|
var NATIVE_SIZE_TOKENS = {
|
|
495
502
|
sm: "sm",
|
|
@@ -988,8 +995,25 @@ var resolveDependentCascade = ({ name, value, fields, values, getEmptyValueForFi
|
|
|
988
995
|
return { newValues, changedDependents };
|
|
989
996
|
};
|
|
990
997
|
|
|
998
|
+
// src/form/formDirty.js
|
|
999
|
+
var isFormDirty = (values, initialValues) => !deepEqual(values || {}, initialValues || {});
|
|
1000
|
+
var getDirtyFields = (values, initialValues) => {
|
|
1001
|
+
const current = values || {};
|
|
1002
|
+
const baseline = initialValues || {};
|
|
1003
|
+
const names = [...Object.keys(current)];
|
|
1004
|
+
for (const name of Object.keys(baseline)) {
|
|
1005
|
+
if (!Object.prototype.hasOwnProperty.call(current, name)) names.push(name);
|
|
1006
|
+
}
|
|
1007
|
+
return names.filter((name) => !deepEqual(current[name], baseline[name]));
|
|
1008
|
+
};
|
|
1009
|
+
|
|
991
1010
|
// src/form/FormBuilder.jsx
|
|
992
1011
|
var getRepeaterErrorKey = (fieldName, rowIdx, subFieldName) => `${fieldName}[${rowIdx}].${subFieldName}`;
|
|
1012
|
+
var withFieldLoadingSpinner = (element, loading) => {
|
|
1013
|
+
if (!loading) return element;
|
|
1014
|
+
return /* @__PURE__ */ React2.createElement(Flex, { direction: "row", gap: "xs", align: "end" }, /* @__PURE__ */ React2.createElement(Box, { flex: 1 }, element), /* @__PURE__ */ React2.createElement(LoadingSpinner, { size: "xs", layout: "inline" }));
|
|
1015
|
+
};
|
|
1016
|
+
var formBuilderInstanceCounter = 0;
|
|
993
1017
|
var fieldSetHasErrors = (errors, fields) => {
|
|
994
1018
|
if (!errors || !fields || fields.length === 0) return false;
|
|
995
1019
|
const names = new Set(fields.map((field) => field.name));
|
|
@@ -1089,8 +1113,10 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
1089
1113
|
// controlled loading state
|
|
1090
1114
|
disabled = false,
|
|
1091
1115
|
// disable entire form
|
|
1092
|
-
renderButtons: renderButtonsProp
|
|
1116
|
+
renderButtons: renderButtonsProp,
|
|
1093
1117
|
// custom action row renderer
|
|
1118
|
+
confirmDiscard
|
|
1119
|
+
// true | { title, message, confirmLabel, cancelLabel } — confirm before the built-in Cancel discards dirty changes
|
|
1094
1120
|
} = props;
|
|
1095
1121
|
const {
|
|
1096
1122
|
columns = 1,
|
|
@@ -1209,6 +1235,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
1209
1235
|
"readOnly",
|
|
1210
1236
|
"alwaysEditable",
|
|
1211
1237
|
"disabled",
|
|
1238
|
+
"loading",
|
|
1212
1239
|
"defaultValue",
|
|
1213
1240
|
"fieldProps",
|
|
1214
1241
|
"colSpan",
|
|
@@ -1465,7 +1492,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
1465
1492
|
syncDirtyBaseline(values);
|
|
1466
1493
|
}, [values, syncDirtyBaseline]);
|
|
1467
1494
|
const isDirty = useMemo(() => {
|
|
1468
|
-
return
|
|
1495
|
+
return isFormDirty(formValues, initialSnapshot.current);
|
|
1469
1496
|
}, [formValues]);
|
|
1470
1497
|
const prevDirtyRef = useRef(false);
|
|
1471
1498
|
useEffect(() => {
|
|
@@ -1474,6 +1501,27 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
1474
1501
|
if (onDirtyChange) onDirtyChange(isDirty);
|
|
1475
1502
|
}
|
|
1476
1503
|
}, [isDirty, onDirtyChange]);
|
|
1504
|
+
let hostActions = null;
|
|
1505
|
+
try {
|
|
1506
|
+
hostActions = useExtensionActions();
|
|
1507
|
+
} catch (err) {
|
|
1508
|
+
hostActions = null;
|
|
1509
|
+
}
|
|
1510
|
+
const discardModalIdRef = useRef(null);
|
|
1511
|
+
if (discardModalIdRef.current === null) {
|
|
1512
|
+
formBuilderInstanceCounter += 1;
|
|
1513
|
+
discardModalIdRef.current = `hs-uix-form-discard-${formBuilderInstanceCounter}`;
|
|
1514
|
+
}
|
|
1515
|
+
const discardConfig = confirmDiscard ? confirmDiscard === true ? {} : confirmDiscard : null;
|
|
1516
|
+
const discardTitle = discardConfig && discardConfig.title || "Discard changes?";
|
|
1517
|
+
const discardMessage = discardConfig && discardConfig.message || "You have unsaved changes. If you discard now, they will be lost.";
|
|
1518
|
+
const discardConfirmLabel = discardConfig && discardConfig.confirmLabel || "Discard changes";
|
|
1519
|
+
const discardCancelLabel = discardConfig && discardConfig.cancelLabel || "Keep editing";
|
|
1520
|
+
const closeDiscardModal = useCallback(() => {
|
|
1521
|
+
if (hostActions && typeof hostActions.closeOverlay === "function") {
|
|
1522
|
+
hostActions.closeOverlay(discardModalIdRef.current);
|
|
1523
|
+
}
|
|
1524
|
+
}, [hostActions]);
|
|
1477
1525
|
const autoSaveTimerRef = useRef(null);
|
|
1478
1526
|
const autoSaveRef = useRef(autoSave);
|
|
1479
1527
|
autoSaveRef.current = autoSave;
|
|
@@ -2112,6 +2160,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2112
2160
|
},
|
|
2113
2161
|
getValues: () => formValues,
|
|
2114
2162
|
isDirty: () => isDirty,
|
|
2163
|
+
getDirtyFields: () => getDirtyFields(formValuesRef.current, initialSnapshot.current),
|
|
2115
2164
|
setFieldValue: (name, value) => handleFieldChange(name, value),
|
|
2116
2165
|
setFieldError: (name, message) => updateErrors({ [name]: message }),
|
|
2117
2166
|
setErrors: (errors) => {
|
|
@@ -2131,7 +2180,8 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2131
2180
|
const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
|
|
2132
2181
|
const fieldFormReadOnly = field.alwaysEditable ? false : formReadOnly;
|
|
2133
2182
|
const isReadOnly = field.readOnly || fieldFormReadOnly;
|
|
2134
|
-
const
|
|
2183
|
+
const isFieldLoading = !!field.loading;
|
|
2184
|
+
const isDisabled = disabled || resolveDisabled(field, formValues) || fieldFormReadOnly || isFieldLoading;
|
|
2135
2185
|
const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
|
|
2136
2186
|
if (field.type === "display" || field.type === "slot") {
|
|
2137
2187
|
if (field.render) {
|
|
@@ -2315,7 +2365,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2315
2365
|
disabled: isDisabled,
|
|
2316
2366
|
error: hasError,
|
|
2317
2367
|
validationMessage: renderFieldError ? void 0 : fieldError || void 0,
|
|
2318
|
-
...
|
|
2368
|
+
...validatingFields[field.name] ? { loading: true } : {},
|
|
2319
2369
|
...field.fieldProps || {}
|
|
2320
2370
|
};
|
|
2321
2371
|
const options = resolveOptions(field, formValues);
|
|
@@ -2473,25 +2523,31 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2473
2523
|
)));
|
|
2474
2524
|
}
|
|
2475
2525
|
case "select":
|
|
2476
|
-
return
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2526
|
+
return withFieldLoadingSpinner(
|
|
2527
|
+
/* @__PURE__ */ React2.createElement(
|
|
2528
|
+
Select,
|
|
2529
|
+
{
|
|
2530
|
+
...commonProps,
|
|
2531
|
+
value: fieldValue,
|
|
2532
|
+
options,
|
|
2533
|
+
variant: field.variant,
|
|
2534
|
+
onChange: fieldOnChange
|
|
2535
|
+
}
|
|
2536
|
+
),
|
|
2537
|
+
isFieldLoading
|
|
2485
2538
|
);
|
|
2486
2539
|
case "multiselect":
|
|
2487
|
-
return
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2540
|
+
return withFieldLoadingSpinner(
|
|
2541
|
+
/* @__PURE__ */ React2.createElement(
|
|
2542
|
+
MultiSelect,
|
|
2543
|
+
{
|
|
2544
|
+
...commonProps,
|
|
2545
|
+
value: fieldValue || [],
|
|
2546
|
+
options,
|
|
2547
|
+
onChange: fieldOnChange
|
|
2548
|
+
}
|
|
2549
|
+
),
|
|
2550
|
+
isFieldLoading
|
|
2495
2551
|
);
|
|
2496
2552
|
case "toggle":
|
|
2497
2553
|
return /* @__PURE__ */ React2.createElement(
|
|
@@ -3012,6 +3068,30 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
3012
3068
|
if (layout) return renderExplicitLayout();
|
|
3013
3069
|
return renderFieldSubset(visibleFields);
|
|
3014
3070
|
};
|
|
3071
|
+
const renderCancelButton = () => {
|
|
3072
|
+
if (discardConfig && isDirty) {
|
|
3073
|
+
return /* @__PURE__ */ React2.createElement(
|
|
3074
|
+
Button,
|
|
3075
|
+
{
|
|
3076
|
+
variant: "secondary",
|
|
3077
|
+
disabled,
|
|
3078
|
+
overlay: /* @__PURE__ */ React2.createElement(Modal, { id: discardModalIdRef.current, title: discardTitle, width: "small" }, /* @__PURE__ */ React2.createElement(ModalBody, null, /* @__PURE__ */ React2.createElement(Text, null, discardMessage)), /* @__PURE__ */ React2.createElement(ModalFooter, null, /* @__PURE__ */ React2.createElement(Button, { variant: "secondary", onClick: closeDiscardModal }, discardCancelLabel), /* @__PURE__ */ React2.createElement(
|
|
3079
|
+
Button,
|
|
3080
|
+
{
|
|
3081
|
+
variant: "destructive",
|
|
3082
|
+
onClick: () => {
|
|
3083
|
+
closeDiscardModal();
|
|
3084
|
+
if (onCancel) onCancel();
|
|
3085
|
+
}
|
|
3086
|
+
},
|
|
3087
|
+
discardConfirmLabel
|
|
3088
|
+
)))
|
|
3089
|
+
},
|
|
3090
|
+
cancelButtonLabel
|
|
3091
|
+
);
|
|
3092
|
+
}
|
|
3093
|
+
return /* @__PURE__ */ React2.createElement(Button, { variant: "secondary", onClick: onCancel, disabled }, cancelButtonLabel);
|
|
3094
|
+
};
|
|
3015
3095
|
const renderButtons = () => {
|
|
3016
3096
|
if (submitPosition === "none" || formReadOnly) return null;
|
|
3017
3097
|
const isLastStep = !isMultiStep || currentStep === steps.length - 1;
|
|
@@ -3025,6 +3105,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
3025
3105
|
totalSteps: isMultiStep ? steps.length : 1,
|
|
3026
3106
|
disabled,
|
|
3027
3107
|
loading: isLoading,
|
|
3108
|
+
isDirty,
|
|
3028
3109
|
labels: {
|
|
3029
3110
|
submit: submitButtonLabel,
|
|
3030
3111
|
cancel: cancelButtonLabel,
|
|
@@ -3040,7 +3121,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
3040
3121
|
return renderButtonsProp(buttonContext);
|
|
3041
3122
|
}
|
|
3042
3123
|
if (isMultiStep) {
|
|
3043
|
-
return /* @__PURE__ */ React2.createElement(Flex, { direction: "row", justify: "between", align: "center" }, !isFirstStep ? /* @__PURE__ */ React2.createElement(Button, { variant: "secondary", onClick: handleBack, disabled }, backButtonLabel) : showCancel ?
|
|
3124
|
+
return /* @__PURE__ */ React2.createElement(Flex, { direction: "row", justify: "between", align: "center" }, !isFirstStep ? /* @__PURE__ */ React2.createElement(Button, { variant: "secondary", onClick: handleBack, disabled }, backButtonLabel) : showCancel ? renderCancelButton() : /* @__PURE__ */ React2.createElement(Text, null, " "), /* @__PURE__ */ React2.createElement(Inline, { gap: "small" }, /* @__PURE__ */ React2.createElement(Text, { variant: "microcopy" }, "Step ", currentStep + 1, " of ", steps.length), isLastStep ? /* @__PURE__ */ React2.createElement(
|
|
3044
3125
|
LoadingButton,
|
|
3045
3126
|
{
|
|
3046
3127
|
variant: submitVariant,
|
|
@@ -3051,7 +3132,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
3051
3132
|
submitButtonLabel
|
|
3052
3133
|
) : /* @__PURE__ */ React2.createElement(Button, { variant: "primary", onClick: handleNext, disabled }, nextButtonLabel)));
|
|
3053
3134
|
}
|
|
3054
|
-
return /* @__PURE__ */ React2.createElement(Flex, { direction: "row", justify: singleStepJustify, gap: "sm" }, showCancel &&
|
|
3135
|
+
return /* @__PURE__ */ React2.createElement(Flex, { direction: "row", justify: singleStepJustify, gap: "sm" }, showCancel && renderCancelButton(), /* @__PURE__ */ React2.createElement(
|
|
3055
3136
|
LoadingButton,
|
|
3056
3137
|
{
|
|
3057
3138
|
variant: submitVariant,
|
|
@@ -3091,7 +3172,126 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
3091
3172
|
formContent
|
|
3092
3173
|
);
|
|
3093
3174
|
});
|
|
3175
|
+
FormBuilder.displayName = "FormBuilder";
|
|
3176
|
+
|
|
3177
|
+
// src/form/hubspotSchema.js
|
|
3178
|
+
var coerceBool = (value) => value === true || value === "true" || value === "Yes" || value === "yes" || value === "1";
|
|
3179
|
+
var coerceNumber = (value) => {
|
|
3180
|
+
if (value === null || value === void 0 || value === "") return void 0;
|
|
3181
|
+
if (typeof value === "number") return value;
|
|
3182
|
+
const parsed = Number(value);
|
|
3183
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
3184
|
+
};
|
|
3185
|
+
var mapPropertyOptions = (options) => {
|
|
3186
|
+
if (!Array.isArray(options)) return void 0;
|
|
3187
|
+
const mapped = options.filter((opt) => opt && opt.hidden !== true).map((opt) => {
|
|
3188
|
+
const result = { label: opt.label != null ? opt.label : String(opt.value), value: opt.value };
|
|
3189
|
+
if (opt.description != null && opt.description !== "") result.description = opt.description;
|
|
3190
|
+
return result;
|
|
3191
|
+
});
|
|
3192
|
+
return mapped;
|
|
3193
|
+
};
|
|
3194
|
+
var resolveFieldType = (property) => {
|
|
3195
|
+
const { type, fieldType } = property;
|
|
3196
|
+
if (type === "datetime") return "datetime";
|
|
3197
|
+
if (type === "date" || fieldType === "date") return "date";
|
|
3198
|
+
switch (fieldType) {
|
|
3199
|
+
case "select":
|
|
3200
|
+
return "select";
|
|
3201
|
+
// FormBuilder's radio rendering is the "radioGroup" type (native
|
|
3202
|
+
// ToggleGroup with toggleType="radioButtonList").
|
|
3203
|
+
case "radio":
|
|
3204
|
+
return "radioGroup";
|
|
3205
|
+
// HubSpot "checkbox" = multiple checkboxes over an enumeration → multiselect.
|
|
3206
|
+
case "checkbox":
|
|
3207
|
+
return "multiselect";
|
|
3208
|
+
case "booleancheckbox":
|
|
3209
|
+
return "toggle";
|
|
3210
|
+
case "number":
|
|
3211
|
+
return "number";
|
|
3212
|
+
case "textarea":
|
|
3213
|
+
return "textarea";
|
|
3214
|
+
case "text":
|
|
3215
|
+
case "phonenumber":
|
|
3216
|
+
return "text";
|
|
3217
|
+
default:
|
|
3218
|
+
break;
|
|
3219
|
+
}
|
|
3220
|
+
switch (type) {
|
|
3221
|
+
case "enumeration":
|
|
3222
|
+
return "select";
|
|
3223
|
+
case "number":
|
|
3224
|
+
return "number";
|
|
3225
|
+
case "bool":
|
|
3226
|
+
return "toggle";
|
|
3227
|
+
default:
|
|
3228
|
+
return "text";
|
|
3229
|
+
}
|
|
3230
|
+
};
|
|
3231
|
+
var isPropertyReadOnly = (property) => property.calculated === true || property.modificationMetadata && property.modificationMetadata.readOnlyValue === true;
|
|
3232
|
+
var resolveRequiredOverride = (requiredOverrides, name) => {
|
|
3233
|
+
if (!requiredOverrides) return void 0;
|
|
3234
|
+
if (Array.isArray(requiredOverrides)) {
|
|
3235
|
+
return requiredOverrides.includes(name) ? true : void 0;
|
|
3236
|
+
}
|
|
3237
|
+
if (Object.prototype.hasOwnProperty.call(requiredOverrides, name)) {
|
|
3238
|
+
return !!requiredOverrides[name];
|
|
3239
|
+
}
|
|
3240
|
+
return void 0;
|
|
3241
|
+
};
|
|
3242
|
+
var fieldsFromHubSpotProperties = (properties, options = {}) => {
|
|
3243
|
+
if (!Array.isArray(properties)) return [];
|
|
3244
|
+
const {
|
|
3245
|
+
include,
|
|
3246
|
+
exclude,
|
|
3247
|
+
overrides,
|
|
3248
|
+
requiredOverrides,
|
|
3249
|
+
includeDescriptions = false
|
|
3250
|
+
} = options;
|
|
3251
|
+
const includeSet = Array.isArray(include) ? new Set(include) : null;
|
|
3252
|
+
const excludeSet = Array.isArray(exclude) ? new Set(exclude) : null;
|
|
3253
|
+
let selected = properties.filter((property) => {
|
|
3254
|
+
if (!property || !property.name) return false;
|
|
3255
|
+
if (includeSet && !includeSet.has(property.name)) return false;
|
|
3256
|
+
if (excludeSet && excludeSet.has(property.name)) return false;
|
|
3257
|
+
if (property.hidden === true && !includeSet) return false;
|
|
3258
|
+
return true;
|
|
3259
|
+
});
|
|
3260
|
+
if (includeSet) {
|
|
3261
|
+
const order = new Map(include.map((name, idx) => [name, idx]));
|
|
3262
|
+
selected = [...selected].sort((a, b) => order.get(a.name) - order.get(b.name));
|
|
3263
|
+
}
|
|
3264
|
+
return selected.map((property) => {
|
|
3265
|
+
const type = resolveFieldType(property);
|
|
3266
|
+
const field = {
|
|
3267
|
+
name: property.name,
|
|
3268
|
+
type,
|
|
3269
|
+
label: property.label || property.name
|
|
3270
|
+
};
|
|
3271
|
+
if (includeDescriptions && property.description) {
|
|
3272
|
+
field.description = property.description;
|
|
3273
|
+
}
|
|
3274
|
+
if (type === "select" || type === "multiselect" || type === "radioGroup") {
|
|
3275
|
+
field.options = mapPropertyOptions(property.options) || [];
|
|
3276
|
+
}
|
|
3277
|
+
if (type === "toggle") {
|
|
3278
|
+
field.transformIn = coerceBool;
|
|
3279
|
+
field.transformOut = (value) => !!value;
|
|
3280
|
+
}
|
|
3281
|
+
if (type === "number") {
|
|
3282
|
+
field.transformIn = coerceNumber;
|
|
3283
|
+
}
|
|
3284
|
+
if (isPropertyReadOnly(property)) {
|
|
3285
|
+
field.readOnly = true;
|
|
3286
|
+
}
|
|
3287
|
+
const required = resolveRequiredOverride(requiredOverrides, property.name);
|
|
3288
|
+
if (required !== void 0) field.required = required;
|
|
3289
|
+
const override = overrides && overrides[property.name];
|
|
3290
|
+
return override ? { ...field, ...override } : field;
|
|
3291
|
+
});
|
|
3292
|
+
};
|
|
3094
3293
|
export {
|
|
3095
3294
|
FormBuilder,
|
|
3295
|
+
fieldsFromHubSpotProperties,
|
|
3096
3296
|
useFormPrefill
|
|
3097
3297
|
};
|