@servicetitan/dte-unlayer 0.129.0 → 0.130.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/dist/display-conditions/DisplayConditionModal.d.ts +6 -1
- package/dist/display-conditions/DisplayConditionModal.d.ts.map +1 -1
- package/dist/display-conditions/DisplayConditionModal.js +139 -110
- package/dist/display-conditions/DisplayConditionModal.js.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +1 -0
- package/dist/editor.js.map +1 -1
- package/dist/unlayer-interface.d.ts +2 -0
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js.map +1 -1
- package/package.json +1 -1
- package/src/display-conditions/DisplayConditionModal.tsx +164 -98
- package/src/editor.tsx +1 -0
- package/src/unlayer-interface.tsx +2 -0
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { FormFieldInfo, FormInfo } from '../shared/forms';
|
|
2
2
|
export interface DisplayConditionModalProps {
|
|
3
|
+
/**
|
|
4
|
+
* When set, the conditions dialog is portaled here instead of resolving from the DOM anchor.
|
|
5
|
+
* Use when the host controls stacking context or shadow boundaries explicitly.
|
|
6
|
+
*/
|
|
7
|
+
portalContainer?: Element | DocumentFragment | null;
|
|
3
8
|
onConditionFormSelect?: (formId: number, sendFormFields: (formId: number, fields: FormFieldInfo[]) => void) => void;
|
|
4
9
|
onConditionalsOpen?: (usedFormIds: number[], sendFormList: (forms: FormInfo[]) => void, sendFormFields: (formId: number, fields: FormFieldInfo[]) => void) => void;
|
|
5
10
|
schema?: import('../shared/schema').SchemaObject;
|
|
6
11
|
}
|
|
7
|
-
export declare const DisplayConditionModal: (props: DisplayConditionModalProps) => import("react").
|
|
12
|
+
export declare const DisplayConditionModal: (props: DisplayConditionModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
13
|
//# sourceMappingURL=DisplayConditionModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEH,aAAa,EACb,QAAQ,EAGX,MAAM,iBAAiB,CAAC;AA4DzB,MAAM,WAAW,0BAA0B;IACvC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAAC;IACpD,qBAAqB,CAAC,EAAE,CACpB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,KAChE,IAAI,CAAC;IACV,kBAAkB,CAAC,EAAE,CACjB,WAAW,EAAE,MAAM,EAAE,EACrB,YAAY,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,EACzC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,KAChE,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,kBAAkB,EAAE,YAAY,CAAC;CACpD;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,4CAsVtE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import { buildFormFieldKey, getConditionalFieldTypeFromFormItemType, parseFormFieldKey } from '../shared/forms';
|
|
6
6
|
import { ConditionGroupsSection } from './ConditionGroupsSection';
|
|
@@ -19,6 +19,13 @@ const BEHAVIOR_OPTIONS = [
|
|
|
19
19
|
}
|
|
20
20
|
];
|
|
21
21
|
const NUMERIC_VALUE_RE = /^-?(?:\d+\.?\d*|\.\d+)$/;
|
|
22
|
+
/** When the editor runs inside a shadow root (e.g. monolith MFE), portaling to `document.body` escapes the shadow tree and loses bundled styles. */ function resolveDisplayConditionPortalContainer(anchor) {
|
|
23
|
+
const rootNode = anchor.getRootNode();
|
|
24
|
+
if (rootNode instanceof ShadowRoot) {
|
|
25
|
+
return rootNode;
|
|
26
|
+
}
|
|
27
|
+
return document.body;
|
|
28
|
+
}
|
|
22
29
|
function deriveMatchType(conditionState) {
|
|
23
30
|
const firstGroup = conditionState.groups[0];
|
|
24
31
|
if (!firstGroup || firstGroup.conditions.length <= 1) {
|
|
@@ -46,7 +53,7 @@ function applyMatchTypeToState(conditionState, matchType) {
|
|
|
46
53
|
};
|
|
47
54
|
}
|
|
48
55
|
export const DisplayConditionModal = (props)=>{
|
|
49
|
-
const { onConditionFormSelect, onConditionalsOpen, schema } = props;
|
|
56
|
+
const { onConditionFormSelect, onConditionalsOpen, portalContainer: portalContainerProp, schema } = props;
|
|
50
57
|
const [request, setRequest] = useState(null);
|
|
51
58
|
const [isOpen, setIsOpen] = useState(false);
|
|
52
59
|
const [state, setState] = useState(defaultState);
|
|
@@ -124,12 +131,20 @@ export const DisplayConditionModal = (props)=>{
|
|
|
124
131
|
}, [
|
|
125
132
|
onConditionFormSelect
|
|
126
133
|
]);
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
const portalAnchorRef = useRef(null);
|
|
135
|
+
const [resolvedPortalContainer, setResolvedPortalContainer] = useState(null);
|
|
136
|
+
useLayoutEffect(()=>{
|
|
137
|
+
if (typeof document === 'undefined' || portalContainerProp !== undefined) {
|
|
138
|
+
return;
|
|
130
139
|
}
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
const anchor = portalAnchorRef.current;
|
|
141
|
+
if (!anchor) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
setResolvedPortalContainer(resolveDisplayConditionPortalContainer(anchor));
|
|
145
|
+
}, [
|
|
146
|
+
portalContainerProp
|
|
147
|
+
]);
|
|
133
148
|
useEffect(()=>{
|
|
134
149
|
return onDisplayCondition((nextRequest)=>{
|
|
135
150
|
setRequest(nextRequest);
|
|
@@ -255,120 +270,134 @@ export const DisplayConditionModal = (props)=>{
|
|
|
255
270
|
isFieldDataLoading,
|
|
256
271
|
state.groups
|
|
257
272
|
]);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
return /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsxs(Dialog, {
|
|
262
|
-
open: isOpen,
|
|
263
|
-
onClose: handleClose,
|
|
264
|
-
size: "xlarge",
|
|
273
|
+
const portalTarget = portalContainerProp === undefined ? resolvedPortalContainer : portalContainerProp;
|
|
274
|
+
return /*#__PURE__*/ _jsxs(Fragment, {
|
|
265
275
|
children: [
|
|
266
|
-
/*#__PURE__*/ _jsx(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
276
|
+
portalContainerProp === undefined ? /*#__PURE__*/ _jsx("span", {
|
|
277
|
+
ref: portalAnchorRef,
|
|
278
|
+
"aria-hidden": "true",
|
|
279
|
+
style: {
|
|
280
|
+
position: 'absolute',
|
|
281
|
+
width: 0,
|
|
282
|
+
height: 0,
|
|
283
|
+
clipPath: 'inset(50%)',
|
|
284
|
+
overflow: 'hidden',
|
|
285
|
+
whiteSpace: 'nowrap'
|
|
286
|
+
}
|
|
287
|
+
}) : null,
|
|
288
|
+
portalTarget && isOpen ? /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsxs(Dialog, {
|
|
289
|
+
open: isOpen,
|
|
290
|
+
onClose: handleClose,
|
|
291
|
+
size: "xlarge",
|
|
292
|
+
children: [
|
|
293
|
+
/*#__PURE__*/ _jsx(Dialog.Header, {
|
|
294
|
+
children: "Conditions"
|
|
295
|
+
}),
|
|
296
|
+
/*#__PURE__*/ _jsx(Dialog.Content, {
|
|
297
|
+
children: /*#__PURE__*/ _jsx(Flex, {
|
|
298
|
+
direction: "column",
|
|
299
|
+
gap: "4",
|
|
284
300
|
style: {
|
|
285
|
-
|
|
301
|
+
maxHeight: MODAL_CONTENT_MAX_HEIGHT,
|
|
302
|
+
overflowY: 'auto',
|
|
303
|
+
paddingRight: 8,
|
|
304
|
+
width: '100%'
|
|
286
305
|
},
|
|
287
|
-
children:
|
|
288
|
-
/*#__PURE__*/
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
children: "Select to include or exclude selected template/file."
|
|
293
|
-
}),
|
|
294
|
-
/*#__PURE__*/ _jsx("div", {
|
|
306
|
+
children: /*#__PURE__*/ _jsx(ConditionGroupsSection, {
|
|
307
|
+
behaviorSection: /*#__PURE__*/ _jsxs(Flex, {
|
|
308
|
+
direction: "row",
|
|
309
|
+
alignItems: "center",
|
|
310
|
+
gap: "2",
|
|
295
311
|
style: {
|
|
296
|
-
|
|
312
|
+
flexWrap: 'wrap'
|
|
297
313
|
},
|
|
298
|
-
children:
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
314
|
+
children: [
|
|
315
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
316
|
+
size: "small",
|
|
317
|
+
subdued: true,
|
|
318
|
+
variant: "body",
|
|
319
|
+
children: "Select to include or exclude selected template/file."
|
|
320
|
+
}),
|
|
321
|
+
/*#__PURE__*/ _jsx("div", {
|
|
322
|
+
style: {
|
|
323
|
+
width: 90
|
|
324
|
+
},
|
|
325
|
+
children: /*#__PURE__*/ _jsxs(Combobox.Select, {
|
|
326
|
+
...{
|
|
327
|
+
disableClearSelection: true
|
|
328
|
+
},
|
|
329
|
+
itemToKey: (item)=>{
|
|
330
|
+
var _item_value;
|
|
331
|
+
return (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : '';
|
|
332
|
+
},
|
|
333
|
+
itemToString: (item)=>{
|
|
334
|
+
var _item_label;
|
|
335
|
+
return (_item_label = item === null || item === void 0 ? void 0 : item.label) !== null && _item_label !== void 0 ? _item_label : '';
|
|
336
|
+
},
|
|
337
|
+
items: [
|
|
338
|
+
...BEHAVIOR_OPTIONS
|
|
339
|
+
],
|
|
340
|
+
selectedItem: selectedBehavior,
|
|
341
|
+
onChange: handleBehaviorChange,
|
|
342
|
+
children: [
|
|
343
|
+
/*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
|
|
344
|
+
label: "",
|
|
345
|
+
placeholder: "Select...",
|
|
346
|
+
size: "small"
|
|
347
|
+
}),
|
|
348
|
+
/*#__PURE__*/ _jsx(Combobox.Content, {
|
|
349
|
+
children: ({ items })=>/*#__PURE__*/ _jsx(Combobox.List, {
|
|
350
|
+
children: items.map((item, i)=>/*#__PURE__*/ _jsx(Combobox.Item, {
|
|
351
|
+
index: i,
|
|
352
|
+
item: item,
|
|
353
|
+
children: item.label
|
|
354
|
+
}, item.value))
|
|
355
|
+
})
|
|
328
356
|
})
|
|
357
|
+
]
|
|
329
358
|
})
|
|
330
|
-
|
|
331
|
-
|
|
359
|
+
})
|
|
360
|
+
]
|
|
361
|
+
}),
|
|
362
|
+
dataPointOptions: dataPointOptions,
|
|
363
|
+
formFieldOptions: formFieldOptions,
|
|
364
|
+
forms: forms,
|
|
365
|
+
groups: state.groups,
|
|
366
|
+
matchType: matchType,
|
|
367
|
+
onFormSelect: handleFormSelect,
|
|
368
|
+
onMatchTypeChange: setMatchType,
|
|
369
|
+
onUpdateGroup: updateGroup
|
|
370
|
+
})
|
|
371
|
+
})
|
|
372
|
+
}),
|
|
373
|
+
/*#__PURE__*/ _jsx(Dialog.Footer, {
|
|
374
|
+
sticky: true,
|
|
375
|
+
children: /*#__PURE__*/ _jsxs(Flex, {
|
|
376
|
+
justifyContent: "flex-end",
|
|
377
|
+
alignItems: "center",
|
|
378
|
+
gap: "3",
|
|
379
|
+
style: {
|
|
380
|
+
width: '100%'
|
|
381
|
+
},
|
|
382
|
+
children: [
|
|
383
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
384
|
+
appearance: "secondary",
|
|
385
|
+
onClick: handleClose,
|
|
386
|
+
children: "Cancel"
|
|
387
|
+
}),
|
|
388
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
389
|
+
appearance: "primary",
|
|
390
|
+
disabled: !canSave,
|
|
391
|
+
onClick: handleSave,
|
|
392
|
+
children: "Save Changes"
|
|
332
393
|
})
|
|
333
394
|
]
|
|
334
|
-
}),
|
|
335
|
-
dataPointOptions: dataPointOptions,
|
|
336
|
-
formFieldOptions: formFieldOptions,
|
|
337
|
-
forms: forms,
|
|
338
|
-
groups: state.groups,
|
|
339
|
-
matchType: matchType,
|
|
340
|
-
onFormSelect: handleFormSelect,
|
|
341
|
-
onMatchTypeChange: setMatchType,
|
|
342
|
-
onUpdateGroup: updateGroup
|
|
343
|
-
})
|
|
344
|
-
})
|
|
345
|
-
}),
|
|
346
|
-
/*#__PURE__*/ _jsx(Dialog.Footer, {
|
|
347
|
-
sticky: true,
|
|
348
|
-
children: /*#__PURE__*/ _jsxs(Flex, {
|
|
349
|
-
justifyContent: "flex-end",
|
|
350
|
-
alignItems: "center",
|
|
351
|
-
gap: "3",
|
|
352
|
-
style: {
|
|
353
|
-
width: '100%'
|
|
354
|
-
},
|
|
355
|
-
children: [
|
|
356
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
357
|
-
appearance: "secondary",
|
|
358
|
-
onClick: handleClose,
|
|
359
|
-
children: "Cancel"
|
|
360
|
-
}),
|
|
361
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
362
|
-
appearance: "primary",
|
|
363
|
-
disabled: !canSave,
|
|
364
|
-
onClick: handleSave,
|
|
365
|
-
children: "Save Changes"
|
|
366
395
|
})
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
})
|
|
396
|
+
})
|
|
397
|
+
]
|
|
398
|
+
}), portalTarget) : null
|
|
370
399
|
]
|
|
371
|
-
})
|
|
400
|
+
});
|
|
372
401
|
};
|
|
373
402
|
|
|
374
403
|
//# sourceMappingURL=DisplayConditionModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n buildFormFieldKey,\n FormFieldInfo,\n FormInfo,\n getConditionalFieldTypeFromFormItemType,\n parseFormFieldKey,\n} from '../shared/forms';\nimport { ConditionGroupsSection, MatchType } from './ConditionGroupsSection';\nimport { defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport {\n ConditionGroup as ConditionGroupType,\n DisplayBehavior,\n DisplayConditionState,\n FormFieldOption,\n LogicalOperator,\n} from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\nfunction deriveMatchType(conditionState: DisplayConditionState): MatchType {\n const firstGroup = conditionState.groups[0];\n if (!firstGroup || firstGroup.conditions.length <= 1) {\n return 'all';\n }\n const hasOr = firstGroup.conditions.some(c => c.logicalOperator === 'or');\n return hasOr ? 'any' : 'all';\n}\n\nfunction applyMatchTypeToState(\n conditionState: DisplayConditionState,\n matchType: MatchType,\n): DisplayConditionState {\n const logicalOp: LogicalOperator = matchType === 'all' ? 'and' : 'or';\n return {\n ...conditionState,\n groups: conditionState.groups.map((group, groupIndex) => {\n if (groupIndex !== 0) {\n return group;\n }\n return {\n ...group,\n conditions: group.conditions.map((c, i) =>\n i === 0 ? c : { ...c, logicalOperator: logicalOp },\n ),\n };\n }),\n };\n}\n\nexport interface DisplayConditionModalProps {\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const { onConditionFormSelect, onConditionalsOpen, schema } = props;\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n const [matchType, setMatchType] = useState<MatchType>('all');\n const [forms, setForms] = useState<FormInfo[]>([]);\n const [formFieldsByFormId, setFormFieldsByFormId] = useState<Record<number, FormFieldInfo[]>>(\n {},\n );\n const [loadingFormIds, setLoadingFormIds] = useState<number[]>([]);\n const [isFormsListLoading, setIsFormsListLoading] = useState(false);\n const formFieldsByFormIdRef = useRef<Record<number, FormFieldInfo[]>>({});\n const loadingFormIdsRef = useRef<number[]>([]);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);\n const formFieldOptions = useMemo<FormFieldOption[]>(() => {\n const nextOptions: FormFieldOption[] = [];\n for (const form of forms) {\n const fields = formFieldsByFormId[form.id];\n if (!fields) {\n continue;\n }\n for (const field of fields) {\n const fieldType = getConditionalFieldTypeFromFormItemType(field.itemType);\n if (!fieldType) {\n continue;\n }\n nextOptions.push({\n fieldType,\n formId: form.id,\n fullKey: buildFormFieldKey(form.id, field.id),\n title: field.header,\n });\n }\n }\n return nextOptions.sort((left, right) => left.title.localeCompare(right.title));\n }, [forms, formFieldsByFormId]);\n const allFieldOptions = useMemo(\n () => [...dataPointOptions, ...formFieldOptions],\n [dataPointOptions, formFieldOptions],\n );\n const isFieldDataLoading = isFormsListLoading || loadingFormIds.length > 0;\n\n useEffect(() => {\n formFieldsByFormIdRef.current = formFieldsByFormId;\n }, [formFieldsByFormId]);\n\n useEffect(() => {\n loadingFormIdsRef.current = loadingFormIds;\n }, [loadingFormIds]);\n\n const requestFormFields = useCallback(\n (formId: number) => {\n if (!onConditionFormSelect) {\n return;\n }\n if (\n formFieldsByFormIdRef.current[formId] ||\n loadingFormIdsRef.current.includes(formId)\n ) {\n return;\n }\n\n setLoadingFormIds(prev => (prev.includes(formId) ? prev : [...prev, formId]));\n onConditionFormSelect(formId, (selectedFormId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [selectedFormId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== selectedFormId));\n });\n },\n [onConditionFormSelect],\n );\n\n const portalTarget = useMemo(() => {\n if (typeof document === 'undefined') {\n return null;\n }\n return document.body;\n }, []);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n const initialState = parsed ?? defaultState();\n const usedFormIds = Array.from(\n new Set(\n initialState.groups\n .flatMap(group => group.conditions)\n .map(condition => parseFormFieldKey(condition.dataPointKey)?.formId)\n .filter((formId): formId is number => formId != null),\n ),\n );\n\n setForms([]);\n setFormFieldsByFormId({});\n setIsFormsListLoading(!!onConditionalsOpen);\n setLoadingFormIds([]);\n\n if (onConditionalsOpen) {\n onConditionalsOpen(\n usedFormIds,\n nextForms => {\n setForms(nextForms);\n setIsFormsListLoading(false);\n },\n (formId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [formId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== formId));\n },\n );\n\n /*\n * Keep display-condition flow aligned with calculated-field flow:\n * when modal opens, request fields for already-used forms so labels\n * are available in edit mode.\n */\n usedFormIds.forEach(formId => requestFormFields(formId));\n } else {\n setIsFormsListLoading(false);\n setLoadingFormIds([]);\n }\n\n setState(initialState);\n setMatchType(deriveMatchType(initialState));\n setIsOpen(true);\n });\n }, [onConditionalsOpen, requestFormFields]);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const finalState = applyMatchTypeToState(state, matchType);\n const condition = buildUnlayerDisplayCondition(finalState);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [matchType, request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const handleFormSelect = useCallback(\n (formId: number) => {\n requestFormFields(formId);\n },\n [requestFormFields],\n );\n\n const canSave = useMemo(() => {\n if (isFieldDataLoading) {\n return false;\n }\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n allFieldOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [allFieldOptions, isFieldDataLoading, state.groups]);\n\n if (!portalTarget || !isOpen) {\n return null;\n }\n\n return createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"4\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <ConditionGroupsSection\n behaviorSection={\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"2\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to include or exclude selected template/file.\n </Text>\n <div style={{ width: 90 }}>\n <Combobox.Select\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: BehaviorOption | null) =>\n item?.value ?? ''\n }\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger\n label=\"\"\n placeholder=\"Select...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: BehaviorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n </Flex>\n }\n dataPointOptions={dataPointOptions}\n formFieldOptions={formFieldOptions}\n forms={forms}\n groups={state.groups}\n matchType={matchType}\n onFormSelect={handleFormSelect}\n onMatchTypeChange={setMatchType}\n onUpdateGroup={updateGroup}\n />\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Flex\n justifyContent=\"flex-end\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ width: '100%' }}\n >\n <Button appearance=\"secondary\" onClick={handleClose}>\n Cancel\n </Button>\n <Button appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","useCallback","useEffect","useMemo","useRef","useState","createPortal","buildFormFieldKey","getConditionalFieldTypeFromFormItemType","parseFormFieldKey","ConditionGroupsSection","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","deriveMatchType","conditionState","firstGroup","groups","conditions","length","hasOr","some","c","logicalOperator","applyMatchTypeToState","matchType","logicalOp","map","group","groupIndex","i","DisplayConditionModal","props","onConditionFormSelect","onConditionalsOpen","schema","request","setRequest","isOpen","setIsOpen","state","setState","setMatchType","forms","setForms","formFieldsByFormId","setFormFieldsByFormId","loadingFormIds","setLoadingFormIds","isFormsListLoading","setIsFormsListLoading","formFieldsByFormIdRef","loadingFormIdsRef","dataPointOptions","formFieldOptions","nextOptions","form","fields","id","field","fieldType","itemType","push","formId","fullKey","title","header","sort","left","right","localeCompare","allFieldOptions","isFieldDataLoading","current","requestFormFields","includes","prev","selectedFormId","filter","portalTarget","document","body","nextRequest","existing","data","parsed","initialState","usedFormIds","Array","from","Set","flatMap","condition","dataPointKey","nextForms","forEach","handleClose","handleSave","finalState","done","updateGroup","index","next","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","handleFormSelect","canSave","operator","trimmedValue","trim","test","open","onClose","size","Header","Content","direction","gap","style","maxHeight","overflowY","paddingRight","width","behaviorSection","alignItems","flexWrap","subdued","variant","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","Item","onFormSelect","onMatchTypeChange","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":";AAAA,SAASA,MAAM,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,IAAI,EAAEC,IAAI,QAAQ,uBAAuB;AAC5E,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAC1E,SAASC,YAAY,QAAQ,YAAY;AACzC,SACIC,iBAAiB,EAGjBC,uCAAuC,EACvCC,iBAAiB,QACd,kBAAkB;AACzB,SAASC,sBAAsB,QAAmB,2BAA2B;AAC7E,SAASC,YAAY,EAAEC,wBAAwB,QAAQ,cAAc;AACrE,SAAkCC,kBAAkB,QAAQ,+BAA+B;AAC3F,SAASC,4BAA4B,EAAEC,4BAA4B,QAAQ,aAAa;AACxF,SAASC,yBAAyB,QAAQ,qBAAqB;AAS/D,MAAMC,mBAAmB;IACrB;QAAEC,OAAO;QAAQC,OAAO;IAAO;IAC/B;QAAED,OAAO;QAAQC,OAAO;IAAO;CAClC;AACD,MAAMC,mBAAmB;AAGzB,SAASC,gBAAgBC,cAAqC;IAC1D,MAAMC,aAAaD,eAAeE,MAAM,CAAC,EAAE;IAC3C,IAAI,CAACD,cAAcA,WAAWE,UAAU,CAACC,MAAM,IAAI,GAAG;QAClD,OAAO;IACX;IACA,MAAMC,QAAQJ,WAAWE,UAAU,CAACG,IAAI,CAACC,CAAAA,IAAKA,EAAEC,eAAe,KAAK;IACpE,OAAOH,QAAQ,QAAQ;AAC3B;AAEA,SAASI,sBACLT,cAAqC,EACrCU,SAAoB;IAEpB,MAAMC,YAA6BD,cAAc,QAAQ,QAAQ;IACjE,OAAO;QACH,GAAGV,cAAc;QACjBE,QAAQF,eAAeE,MAAM,CAACU,GAAG,CAAC,CAACC,OAAOC;YACtC,IAAIA,eAAe,GAAG;gBAClB,OAAOD;YACX;YACA,OAAO;gBACH,GAAGA,KAAK;gBACRV,YAAYU,MAAMV,UAAU,CAACS,GAAG,CAAC,CAACL,GAAGQ,IACjCA,MAAM,IAAIR,IAAI;wBAAE,GAAGA,CAAC;wBAAEC,iBAAiBG;oBAAU;YAEzD;QACJ;IACJ;AACJ;AAeA,OAAO,MAAMK,wBAAwB,CAACC;IAClC,MAAM,EAAEC,qBAAqB,EAAEC,kBAAkB,EAAEC,MAAM,EAAE,GAAGH;IAC9D,MAAM,CAACI,SAASC,WAAW,GAAGvC,SAAyC;IACvE,MAAM,CAACwC,QAAQC,UAAU,GAAGzC,SAAS;IACrC,MAAM,CAAC0C,OAAOC,SAAS,GAAG3C,SAASM;IACnC,MAAM,CAACqB,WAAWiB,aAAa,GAAG5C,SAAoB;IACtD,MAAM,CAAC6C,OAAOC,SAAS,GAAG9C,SAAqB,EAAE;IACjD,MAAM,CAAC+C,oBAAoBC,sBAAsB,GAAGhD,SAChD,CAAC;IAEL,MAAM,CAACiD,gBAAgBC,kBAAkB,GAAGlD,SAAmB,EAAE;IACjE,MAAM,CAACmD,oBAAoBC,sBAAsB,GAAGpD,SAAS;IAC7D,MAAMqD,wBAAwBtD,OAAwC,CAAC;IACvE,MAAMuD,oBAAoBvD,OAAiB,EAAE;IAE7C,MAAMwD,mBAAmBzD,QAAQ,IAAMa,0BAA0B0B,SAAS;QAACA;KAAO;IAClF,MAAMmB,mBAAmB1D,QAA2B;QAChD,MAAM2D,cAAiC,EAAE;QACzC,KAAK,MAAMC,QAAQb,MAAO;YACtB,MAAMc,SAASZ,kBAAkB,CAACW,KAAKE,EAAE,CAAC;YAC1C,IAAI,CAACD,QAAQ;gBACT;YACJ;YACA,KAAK,MAAME,SAASF,OAAQ;gBACxB,MAAMG,YAAY3D,wCAAwC0D,MAAME,QAAQ;gBACxE,IAAI,CAACD,WAAW;oBACZ;gBACJ;gBACAL,YAAYO,IAAI,CAAC;oBACbF;oBACAG,QAAQP,KAAKE,EAAE;oBACfM,SAAShE,kBAAkBwD,KAAKE,EAAE,EAAEC,MAAMD,EAAE;oBAC5CO,OAAON,MAAMO,MAAM;gBACvB;YACJ;QACJ;QACA,OAAOX,YAAYY,IAAI,CAAC,CAACC,MAAMC,QAAUD,KAAKH,KAAK,CAACK,aAAa,CAACD,MAAMJ,KAAK;IACjF,GAAG;QAACtB;QAAOE;KAAmB;IAC9B,MAAM0B,kBAAkB3E,QACpB,IAAM;eAAIyD;eAAqBC;SAAiB,EAChD;QAACD;QAAkBC;KAAiB;IAExC,MAAMkB,qBAAqBvB,sBAAsBF,eAAe5B,MAAM,GAAG;IAEzExB,UAAU;QACNwD,sBAAsBsB,OAAO,GAAG5B;IACpC,GAAG;QAACA;KAAmB;IAEvBlD,UAAU;QACNyD,kBAAkBqB,OAAO,GAAG1B;IAChC,GAAG;QAACA;KAAe;IAEnB,MAAM2B,oBAAoBhF,YACtB,CAACqE;QACG,IAAI,CAAC9B,uBAAuB;YACxB;QACJ;QACA,IACIkB,sBAAsBsB,OAAO,CAACV,OAAO,IACrCX,kBAAkBqB,OAAO,CAACE,QAAQ,CAACZ,SACrC;YACE;QACJ;QAEAf,kBAAkB4B,CAAAA,OAASA,KAAKD,QAAQ,CAACZ,UAAUa,OAAO;mBAAIA;gBAAMb;aAAO;QAC3E9B,sBAAsB8B,QAAQ,CAACc,gBAAgBpB;YAC3CX,sBAAsB8B,CAAAA,OAAS,CAAA;oBAAE,GAAGA,IAAI;oBAAE,CAACC,eAAe,EAAEpB;gBAAO,CAAA;YACnET,kBAAkB4B,CAAAA,OAAQA,KAAKE,MAAM,CAACpB,CAAAA,KAAMA,OAAOmB;QACvD;IACJ,GACA;QAAC5C;KAAsB;IAG3B,MAAM8C,eAAenF,QAAQ;QACzB,IAAI,OAAOoF,aAAa,aAAa;YACjC,OAAO;QACX;QACA,OAAOA,SAASC,IAAI;IACxB,GAAG,EAAE;IAELtF,UAAU;QACN,OAAOW,mBAAmB4E,CAAAA;YACtB7C,WAAW6C;YACX,MAAMC,WAAWD,YAAYE,IAAI;YACjC,MAAMC,SAAS7E,6BAA6B2E;YAC5C,MAAMG,eAAeD,mBAAAA,oBAAAA,SAAUjF;YAC/B,MAAMmF,cAAcC,MAAMC,IAAI,CAC1B,IAAIC,IACAJ,aAAarE,MAAM,CACd0E,OAAO,CAAC/D,CAAAA,QAASA,MAAMV,UAAU,EACjCS,GAAG,CAACiE,CAAAA;oBAAa1F;wBAAAA,qBAAAA,kBAAkB0F,UAAUC,YAAY,eAAxC3F,yCAAAA,mBAA2C6D,MAAM;eAClEe,MAAM,CAAC,CAACf,SAA6BA,UAAU;YAI5DnB,SAAS,EAAE;YACXE,sBAAsB,CAAC;YACvBI,sBAAsB,CAAC,CAAChB;YACxBc,kBAAkB,EAAE;YAEpB,IAAId,oBAAoB;gBACpBA,mBACIqD,aACAO,CAAAA;oBACIlD,SAASkD;oBACT5C,sBAAsB;gBAC1B,GACA,CAACa,QAAQN;oBACLX,sBAAsB8B,CAAAA,OAAS,CAAA;4BAAE,GAAGA,IAAI;4BAAE,CAACb,OAAO,EAAEN;wBAAO,CAAA;oBAC3DT,kBAAkB4B,CAAAA,OAAQA,KAAKE,MAAM,CAACpB,CAAAA,KAAMA,OAAOK;gBACvD;gBAGJ;;;;iBAIC,GACDwB,YAAYQ,OAAO,CAAChC,CAAAA,SAAUW,kBAAkBX;YACpD,OAAO;gBACHb,sBAAsB;gBACtBF,kBAAkB,EAAE;YACxB;YAEAP,SAAS6C;YACT5C,aAAa5B,gBAAgBwE;YAC7B/C,UAAU;QACd;IACJ,GAAG;QAACL;QAAoBwC;KAAkB;IAE1C,MAAMsB,cAActG,YAAY;QAC5B2C,WAAW;QACXE,UAAU;IACd,GAAG,EAAE;IAEL,MAAM0D,aAAavG,YAAY;QAC3B,IAAI,CAAC0C,SAAS;YACV;QACJ;QACA,MAAM8D,aAAa1E,sBAAsBgB,OAAOf;QAChD,MAAMmE,YAAYrF,6BAA6B2F;QAC/C,IAAIN,WAAW;YACXxD,QAAQ+D,IAAI,CAACP;QACjB,OAAO;YACHxD,QAAQ+D,IAAI,CAAC;QACjB;QACA9D,WAAW;QACXE,UAAU;IACd,GAAG;QAACd;QAAWW;QAASI;KAAM;IAE9B,MAAM4D,cAAc1G,YAAY,CAAC2G,OAAezE;QAC5Ca,SAASmC,CAAAA;YACL,MAAM0B,OAAO;mBAAI1B,KAAK3D,MAAM;aAAC;YAC7BqF,IAAI,CAACD,MAAM,GAAGzE;YACd,OAAO;gBAAE,GAAGgD,IAAI;gBAAE3D,QAAQqF;YAAK;QACnC;IACJ,GAAG,EAAE;IAEL,MAAMC,mBAAmB3G,QACrB;YAAMc;eAAAA,CAAAA,yBAAAA,iBAAiB8F,IAAI,CAACC,CAAAA,MAAOA,IAAI7F,KAAK,KAAK4B,MAAMkE,QAAQ,eAAzDhG,oCAAAA,yBAA8DA,gBAAgB,CAAC,EAAE;OACvF;QAAC8B,MAAMkE,QAAQ;KAAC;IAGpB,MAAMC,uBAAuBjH,YAAY,CAACkH;QACtC,IAAIA,MAAM;YACNnE,SAASmC,CAAAA,OAAS,CAAA;oBAAE,GAAGA,IAAI;oBAAE8B,UAAUE,KAAKhG,KAAK;gBAAoB,CAAA;QACzE;IACJ,GAAG,EAAE;IAEL,MAAMiG,mBAAmBnH,YACrB,CAACqE;QACGW,kBAAkBX;IACtB,GACA;QAACW;KAAkB;IAGvB,MAAMoC,UAAUlH,QAAQ;QACpB,IAAI4E,oBAAoB;YACpB,OAAO;QACX;QACA,KAAK,MAAM5C,SAASY,MAAMvB,MAAM,CAAE;YAC9B,KAAK,MAAM2E,aAAahE,MAAMV,UAAU,CAAE;oBAYlCqD;gBAXJ,IAAI,CAACqB,UAAUC,YAAY,EAAE;oBACzB,OAAO;gBACX;gBACA,IAAID,UAAUmB,QAAQ,KAAK,cAAcnB,UAAUmB,QAAQ,KAAK,gBAAgB;oBAC5E;gBACJ;gBACA,MAAMC,eAAepB,UAAUhF,KAAK,CAACqG,IAAI;gBACzC,IAAI,CAACD,cAAc;oBACf,OAAO;gBACX;oBAEIzC;gBADJ,MAAMX,YACFW,CAAAA,mCAAAA,wBAAAA,gBAAgBiC,IAAI,CAACC,CAAAA,MAAOA,IAAIzC,OAAO,KAAK4B,UAAUC,YAAY,eAAlEtB,4CAAAA,sBACMX,SAAS,cADfW,6CAAAA,kCACmB;gBACvB,IAAIX,cAAc,YAAY,CAAC/C,iBAAiBqG,IAAI,CAACF,eAAe;oBAChE,OAAO;gBACX;YACJ;QACJ;QACA,OAAOxE,MAAMvB,MAAM,CAACE,MAAM,GAAG;IACjC,GAAG;QAACoD;QAAiBC;QAAoBhC,MAAMvB,MAAM;KAAC;IAEtD,IAAI,CAAC8D,gBAAgB,CAACzC,QAAQ;QAC1B,OAAO;IACX;IAEA,qBAAOvC,2BACH,MAACR;QAAO4H,MAAM7E;QAAQ8E,SAASpB;QAAaqB,MAAK;;0BAC7C,KAAC9H,OAAO+H,MAAM;0BAAC;;0BACf,KAAC/H,OAAOgI,OAAO;0BACX,cAAA,KAAC/H;oBACGgI,WAAU;oBACVC,KAAI;oBACJC,OAAO;wBACHC,WAAWtH;wBACXuH,WAAW;wBACXC,cAAc;wBACdC,OAAO;oBACX;8BAEA,cAAA,KAAC3H;wBACG4H,+BACI,MAACvI;4BACGgI,WAAU;4BACVQ,YAAW;4BACXP,KAAI;4BACJC,OAAO;gCAAEO,UAAU;4BAAO;;8CAE1B,KAACxI;oCAAK4H,MAAK;oCAAQa,OAAO;oCAACC,SAAQ;8CAAO;;8CAG1C,KAACC;oCAAIV,OAAO;wCAAEI,OAAO;oCAAG;8CACpB,cAAA,MAACxI,SAAS+I,MAAM;wCACX,GAAI;4CAAEC,uBAAuB;wCAAK,CAAC;wCACpCC,WAAW,CAAC3B;gDACRA;mDAAAA,CAAAA,cAAAA,iBAAAA,2BAAAA,KAAMhG,KAAK,cAAXgG,yBAAAA,cAAe;;wCAEnB4B,cAAc,CAAC5B;gDACXA;mDAAAA,CAAAA,cAAAA,iBAAAA,2BAAAA,KAAMjG,KAAK,cAAXiG,yBAAAA,cAAe;;wCAEnB6B,OAAO;+CAAI/H;yCAAiB;wCAC5BgI,cAAcnC;wCACdoC,UAAUhC;;0DAEV,KAACrH,SAASsJ,aAAa;gDACnBjI,OAAM;gDACNkI,aAAY;gDACZxB,MAAK;;0DAET,KAAC/H,SAASiI,OAAO;0DACZ,CAAC,EAAEkB,KAAK,EAA+B,iBACpC,KAACnJ,SAASwJ,IAAI;kEACTL,MAAM9G,GAAG,CAAC,CAACiF,MAAM9E,kBACd,KAACxC,SAASyJ,IAAI;gEACV1C,OAAOvE;gEACP8E,MAAMA;0EAGLA,KAAKjG,KAAK;+DAFNiG,KAAKhG,KAAK;;;;;;;;wBAYnDyC,kBAAkBA;wBAClBC,kBAAkBA;wBAClBX,OAAOA;wBACP1B,QAAQuB,MAAMvB,MAAM;wBACpBQ,WAAWA;wBACXuH,cAAcnC;wBACdoC,mBAAmBvG;wBACnBwG,eAAe9C;;;;0BAI3B,KAAC7G,OAAO4J,MAAM;gBAACC,MAAM;0BACjB,cAAA,MAAC5J;oBACG6J,gBAAe;oBACfrB,YAAW;oBACXP,KAAI;oBACJC,OAAO;wBAAEI,OAAO;oBAAO;;sCAEvB,KAACzI;4BAAOiK,YAAW;4BAAYC,SAASvD;sCAAa;;sCAGrD,KAAC3G;4BAAOiK,YAAW;4BAAUE,UAAU,CAAC1C;4BAASyC,SAAStD;sCAAY;;;;;;QAMlFlB;AAER,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport {\n Fragment,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n buildFormFieldKey,\n FormFieldInfo,\n FormInfo,\n getConditionalFieldTypeFromFormItemType,\n parseFormFieldKey,\n} from '../shared/forms';\nimport { ConditionGroupsSection, MatchType } from './ConditionGroupsSection';\nimport { defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport {\n ConditionGroup as ConditionGroupType,\n DisplayBehavior,\n DisplayConditionState,\n FormFieldOption,\n LogicalOperator,\n} from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\n/** When the editor runs inside a shadow root (e.g. monolith MFE), portaling to `document.body` escapes the shadow tree and loses bundled styles. */\nfunction resolveDisplayConditionPortalContainer(anchor: HTMLElement): Element | DocumentFragment {\n const rootNode = anchor.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n return rootNode;\n }\n return document.body;\n}\n\nfunction deriveMatchType(conditionState: DisplayConditionState): MatchType {\n const firstGroup = conditionState.groups[0];\n if (!firstGroup || firstGroup.conditions.length <= 1) {\n return 'all';\n }\n const hasOr = firstGroup.conditions.some(c => c.logicalOperator === 'or');\n return hasOr ? 'any' : 'all';\n}\n\nfunction applyMatchTypeToState(\n conditionState: DisplayConditionState,\n matchType: MatchType,\n): DisplayConditionState {\n const logicalOp: LogicalOperator = matchType === 'all' ? 'and' : 'or';\n return {\n ...conditionState,\n groups: conditionState.groups.map((group, groupIndex) => {\n if (groupIndex !== 0) {\n return group;\n }\n return {\n ...group,\n conditions: group.conditions.map((c, i) =>\n i === 0 ? c : { ...c, logicalOperator: logicalOp },\n ),\n };\n }),\n };\n}\n\nexport interface DisplayConditionModalProps {\n /**\n * When set, the conditions dialog is portaled here instead of resolving from the DOM anchor.\n * Use when the host controls stacking context or shadow boundaries explicitly.\n */\n portalContainer?: Element | DocumentFragment | null;\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const {\n onConditionFormSelect,\n onConditionalsOpen,\n portalContainer: portalContainerProp,\n schema,\n } = props;\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n const [matchType, setMatchType] = useState<MatchType>('all');\n const [forms, setForms] = useState<FormInfo[]>([]);\n const [formFieldsByFormId, setFormFieldsByFormId] = useState<Record<number, FormFieldInfo[]>>(\n {},\n );\n const [loadingFormIds, setLoadingFormIds] = useState<number[]>([]);\n const [isFormsListLoading, setIsFormsListLoading] = useState(false);\n const formFieldsByFormIdRef = useRef<Record<number, FormFieldInfo[]>>({});\n const loadingFormIdsRef = useRef<number[]>([]);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);\n const formFieldOptions = useMemo<FormFieldOption[]>(() => {\n const nextOptions: FormFieldOption[] = [];\n for (const form of forms) {\n const fields = formFieldsByFormId[form.id];\n if (!fields) {\n continue;\n }\n for (const field of fields) {\n const fieldType = getConditionalFieldTypeFromFormItemType(field.itemType);\n if (!fieldType) {\n continue;\n }\n nextOptions.push({\n fieldType,\n formId: form.id,\n fullKey: buildFormFieldKey(form.id, field.id),\n title: field.header,\n });\n }\n }\n return nextOptions.sort((left, right) => left.title.localeCompare(right.title));\n }, [forms, formFieldsByFormId]);\n const allFieldOptions = useMemo(\n () => [...dataPointOptions, ...formFieldOptions],\n [dataPointOptions, formFieldOptions],\n );\n const isFieldDataLoading = isFormsListLoading || loadingFormIds.length > 0;\n\n useEffect(() => {\n formFieldsByFormIdRef.current = formFieldsByFormId;\n }, [formFieldsByFormId]);\n\n useEffect(() => {\n loadingFormIdsRef.current = loadingFormIds;\n }, [loadingFormIds]);\n\n const requestFormFields = useCallback(\n (formId: number) => {\n if (!onConditionFormSelect) {\n return;\n }\n if (\n formFieldsByFormIdRef.current[formId] ||\n loadingFormIdsRef.current.includes(formId)\n ) {\n return;\n }\n\n setLoadingFormIds(prev => (prev.includes(formId) ? prev : [...prev, formId]));\n onConditionFormSelect(formId, (selectedFormId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [selectedFormId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== selectedFormId));\n });\n },\n [onConditionFormSelect],\n );\n\n const portalAnchorRef = useRef<HTMLSpanElement>(null);\n const [resolvedPortalContainer, setResolvedPortalContainer] = useState<\n Element | DocumentFragment | null\n >(null);\n\n useLayoutEffect(() => {\n if (typeof document === 'undefined' || portalContainerProp !== undefined) {\n return;\n }\n const anchor = portalAnchorRef.current;\n if (!anchor) {\n return;\n }\n setResolvedPortalContainer(resolveDisplayConditionPortalContainer(anchor));\n }, [portalContainerProp]);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n const initialState = parsed ?? defaultState();\n const usedFormIds = Array.from(\n new Set(\n initialState.groups\n .flatMap(group => group.conditions)\n .map(condition => parseFormFieldKey(condition.dataPointKey)?.formId)\n .filter((formId): formId is number => formId != null),\n ),\n );\n\n setForms([]);\n setFormFieldsByFormId({});\n setIsFormsListLoading(!!onConditionalsOpen);\n setLoadingFormIds([]);\n\n if (onConditionalsOpen) {\n onConditionalsOpen(\n usedFormIds,\n nextForms => {\n setForms(nextForms);\n setIsFormsListLoading(false);\n },\n (formId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [formId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== formId));\n },\n );\n\n /*\n * Keep display-condition flow aligned with calculated-field flow:\n * when modal opens, request fields for already-used forms so labels\n * are available in edit mode.\n */\n usedFormIds.forEach(formId => requestFormFields(formId));\n } else {\n setIsFormsListLoading(false);\n setLoadingFormIds([]);\n }\n\n setState(initialState);\n setMatchType(deriveMatchType(initialState));\n setIsOpen(true);\n });\n }, [onConditionalsOpen, requestFormFields]);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const finalState = applyMatchTypeToState(state, matchType);\n const condition = buildUnlayerDisplayCondition(finalState);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [matchType, request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const handleFormSelect = useCallback(\n (formId: number) => {\n requestFormFields(formId);\n },\n [requestFormFields],\n );\n\n const canSave = useMemo(() => {\n if (isFieldDataLoading) {\n return false;\n }\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n allFieldOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [allFieldOptions, isFieldDataLoading, state.groups]);\n\n const portalTarget =\n portalContainerProp === undefined ? resolvedPortalContainer : portalContainerProp;\n\n return (\n <Fragment>\n {portalContainerProp === undefined ? (\n <span\n ref={portalAnchorRef}\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n width: 0,\n height: 0,\n clipPath: 'inset(50%)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }}\n />\n ) : null}\n {portalTarget && isOpen\n ? createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"4\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <ConditionGroupsSection\n behaviorSection={\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"2\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to include or exclude selected\n template/file.\n </Text>\n <div style={{ width: 90 }}>\n <Combobox.Select\n {...({\n disableClearSelection: true,\n } as object)}\n itemToKey={(item: BehaviorOption | null) =>\n item?.value ?? ''\n }\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger\n label=\"\"\n placeholder=\"Select...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({\n items,\n }: {\n items: BehaviorOption[];\n }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n </Flex>\n }\n dataPointOptions={dataPointOptions}\n formFieldOptions={formFieldOptions}\n forms={forms}\n groups={state.groups}\n matchType={matchType}\n onFormSelect={handleFormSelect}\n onMatchTypeChange={setMatchType}\n onUpdateGroup={updateGroup}\n />\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Flex\n justifyContent=\"flex-end\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ width: '100%' }}\n >\n <Button appearance=\"secondary\" onClick={handleClose}>\n Cancel\n </Button>\n <Button\n appearance=\"primary\"\n disabled={!canSave}\n onClick={handleSave}\n >\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n )\n : null}\n </Fragment>\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","Fragment","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","createPortal","buildFormFieldKey","getConditionalFieldTypeFromFormItemType","parseFormFieldKey","ConditionGroupsSection","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","resolveDisplayConditionPortalContainer","anchor","rootNode","getRootNode","ShadowRoot","document","body","deriveMatchType","conditionState","firstGroup","groups","conditions","length","hasOr","some","c","logicalOperator","applyMatchTypeToState","matchType","logicalOp","map","group","groupIndex","i","DisplayConditionModal","props","onConditionFormSelect","onConditionalsOpen","portalContainer","portalContainerProp","schema","request","setRequest","isOpen","setIsOpen","state","setState","setMatchType","forms","setForms","formFieldsByFormId","setFormFieldsByFormId","loadingFormIds","setLoadingFormIds","isFormsListLoading","setIsFormsListLoading","formFieldsByFormIdRef","loadingFormIdsRef","dataPointOptions","formFieldOptions","nextOptions","form","fields","id","field","fieldType","itemType","push","formId","fullKey","title","header","sort","left","right","localeCompare","allFieldOptions","isFieldDataLoading","current","requestFormFields","includes","prev","selectedFormId","filter","portalAnchorRef","resolvedPortalContainer","setResolvedPortalContainer","undefined","nextRequest","existing","data","parsed","initialState","usedFormIds","Array","from","Set","flatMap","condition","dataPointKey","nextForms","forEach","handleClose","handleSave","finalState","done","updateGroup","index","next","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","handleFormSelect","canSave","operator","trimmedValue","trim","test","portalTarget","span","ref","aria-hidden","style","position","width","height","clipPath","overflow","whiteSpace","open","onClose","size","Header","Content","direction","gap","maxHeight","overflowY","paddingRight","behaviorSection","alignItems","flexWrap","subdued","variant","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","Item","onFormSelect","onMatchTypeChange","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":"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"}
|
package/dist/editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,EACH,aAAa,EAOhB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAgB,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,EAAE,wBAAwB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,OAAO,CAAC,IAAI,IAAI,CAAC;IAEjB,QAAQ,CAAC,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE/C,cAAc,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAE/C,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpD,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,aAAa,2DAAwC,CAAC;AAEnE,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,EACH,aAAa,EAOhB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAgB,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,EAAE,wBAAwB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,OAAO,CAAC,IAAI,IAAI,CAAC;IAEjB,QAAQ,CAAC,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE/C,cAAc,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAE/C,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpD,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;CAC7C;AAED,eAAO,MAAM,aAAa,2DAAwC,CAAC;AAEnE,eAAO,MAAM,aAAa,2GAuGxB,CAAC"}
|
package/dist/editor.js
CHANGED
|
@@ -117,6 +117,7 @@ export const UnlayerEditor = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
117
117
|
ref: containerRef
|
|
118
118
|
}),
|
|
119
119
|
props.opts.displayConditions && /*#__PURE__*/ _jsx(DisplayConditionModal, {
|
|
120
|
+
portalContainer: props.opts.displayConditionModalPortalContainer,
|
|
120
121
|
schema: props.opts.schema,
|
|
121
122
|
onConditionalsOpen: props.opts.onConditionalsOpen,
|
|
122
123
|
onConditionFormSelect: props.opts.onConditionFormSelect
|
package/dist/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import {\n CSSProperties,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { DisplayConditionModal } from './display-conditions/DisplayConditionModal';\nimport { UnlayerEditorTwin } from './shared/const';\nimport { UnlayerStore, UnlayerDesignChangeInfo } from './store';\nimport { UnlayerRef, CreateUnlayerEditorProps } from './unlayer-interface';\n\nexport interface UnlayerEditorProps {\n id?: string;\n design?: any;\n opts: CreateUnlayerEditorProps;\n minHeight?: number;\n style?: CSSProperties;\n\n onReady?(): void;\n\n onChange?(info: UnlayerDesignChangeInfo): void;\n\n onSnapshotSave?(tool: UnlayerEditorTwin): void;\n\n onImage?(file: File): Promise<{ url: string }>;\n\n onError?(title: string, description?: string): void;\n\n onMessage?(type: string, data: any): void;\n}\n\nexport const useUnlayerRef = () => useRef<UnlayerRef | null>(null);\n\nexport const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props, ref) => {\n const [isReady, setIsReady] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const store = useMemo(\n () => new UnlayerStore(props.opts),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n useEffect(() => {\n if (containerRef.current) {\n store\n .init(containerRef.current)\n .then(() => setIsReady(true))\n .catch(() => setIsReady(false));\n }\n\n return () => store.destroy();\n }, [store]);\n useImperativeHandle(ref, () => store.unlayerRef, [store]);\n\n useEffect(() => {\n if (isReady) {\n store.setDesign(props.design);\n }\n }, [isReady, props.design, store]);\n\n useEffect(() => {\n store.setOnChange(props.onChange);\n\n return () => store.setOnChange();\n }, [props.onChange, store]);\n\n useEffect(() => {\n store.setOnSnapshotSave(props.onSnapshotSave);\n\n return () => store.setOnSnapshotSave();\n }, [props.onSnapshotSave, store]);\n\n useEffect(() => {\n if (props.opts.newSnapshot) {\n store.addTwin(props.opts.newSnapshot);\n }\n }, [props.opts.newSnapshot, store]);\n\n useEffect(() => {\n store.setOnReady(props.onReady);\n\n return () => store.setOnReady();\n }, [props.onReady, store]);\n\n useEffect(() => {\n store.setOnImage(props.onImage);\n\n return () => store.setOnImage();\n }, [props.onImage, store]);\n\n useEffect(() => {\n store.setOnError(props.onError);\n\n return () => store.setOnError();\n }, [props.onError, store]);\n\n useEffect(() => {\n store.setOnMessage(props.onMessage);\n\n return () => store.setOnMessage();\n }, [props.onMessage, store]);\n\n useEffect(() => {\n store.setOnFormSelect(props.opts.onFormSelect);\n\n return () => store.setOnFormSelect();\n }, [props.opts.onFormSelect, store]);\n\n useEffect(() => {\n store.setOnCalcFieldOpen(props.opts.onCalcFieldOpen);\n\n return () => store.setOnCalcFieldOpen();\n }, [props.opts.onCalcFieldOpen, store]);\n\n useEffect(() => {\n store.setOnCalcFieldSelect(props.opts.onCalcFieldSelect);\n\n return () => store.setOnCalcFieldSelect();\n }, [props.opts.onCalcFieldSelect, store]);\n\n const { minHeight = 800, style = {} } = props;\n\n return (\n <div style={{ minHeight, display: 'flex' }}>\n {!isReady && <p className=\"c-red-500\">error loading editor</p>}\n <div id={props.id ?? 'editor'} style={style} ref={containerRef} />\n {props.opts.displayConditions && (\n <DisplayConditionModal\n schema={props.opts.schema}\n onConditionalsOpen={props.opts.onConditionalsOpen}\n onConditionFormSelect={props.opts.onConditionFormSelect}\n />\n )}\n </div>\n );\n});\n"],"names":["forwardRef","useEffect","useImperativeHandle","useMemo","useRef","useState","DisplayConditionModal","UnlayerStore","useUnlayerRef","UnlayerEditor","props","ref","isReady","setIsReady","containerRef","store","opts","current","init","then","catch","destroy","unlayerRef","setDesign","design","setOnChange","onChange","setOnSnapshotSave","onSnapshotSave","newSnapshot","addTwin","setOnReady","onReady","setOnImage","onImage","setOnError","onError","setOnMessage","onMessage","setOnFormSelect","onFormSelect","setOnCalcFieldOpen","onCalcFieldOpen","setOnCalcFieldSelect","onCalcFieldSelect","minHeight","style","div","display","p","className","id","displayConditions","schema","onConditionalsOpen","onConditionFormSelect"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import {\n CSSProperties,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { DisplayConditionModal } from './display-conditions/DisplayConditionModal';\nimport { UnlayerEditorTwin } from './shared/const';\nimport { UnlayerStore, UnlayerDesignChangeInfo } from './store';\nimport { UnlayerRef, CreateUnlayerEditorProps } from './unlayer-interface';\n\nexport interface UnlayerEditorProps {\n id?: string;\n design?: any;\n opts: CreateUnlayerEditorProps;\n minHeight?: number;\n style?: CSSProperties;\n\n onReady?(): void;\n\n onChange?(info: UnlayerDesignChangeInfo): void;\n\n onSnapshotSave?(tool: UnlayerEditorTwin): void;\n\n onImage?(file: File): Promise<{ url: string }>;\n\n onError?(title: string, description?: string): void;\n\n onMessage?(type: string, data: any): void;\n}\n\nexport const useUnlayerRef = () => useRef<UnlayerRef | null>(null);\n\nexport const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props, ref) => {\n const [isReady, setIsReady] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const store = useMemo(\n () => new UnlayerStore(props.opts),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n useEffect(() => {\n if (containerRef.current) {\n store\n .init(containerRef.current)\n .then(() => setIsReady(true))\n .catch(() => setIsReady(false));\n }\n\n return () => store.destroy();\n }, [store]);\n useImperativeHandle(ref, () => store.unlayerRef, [store]);\n\n useEffect(() => {\n if (isReady) {\n store.setDesign(props.design);\n }\n }, [isReady, props.design, store]);\n\n useEffect(() => {\n store.setOnChange(props.onChange);\n\n return () => store.setOnChange();\n }, [props.onChange, store]);\n\n useEffect(() => {\n store.setOnSnapshotSave(props.onSnapshotSave);\n\n return () => store.setOnSnapshotSave();\n }, [props.onSnapshotSave, store]);\n\n useEffect(() => {\n if (props.opts.newSnapshot) {\n store.addTwin(props.opts.newSnapshot);\n }\n }, [props.opts.newSnapshot, store]);\n\n useEffect(() => {\n store.setOnReady(props.onReady);\n\n return () => store.setOnReady();\n }, [props.onReady, store]);\n\n useEffect(() => {\n store.setOnImage(props.onImage);\n\n return () => store.setOnImage();\n }, [props.onImage, store]);\n\n useEffect(() => {\n store.setOnError(props.onError);\n\n return () => store.setOnError();\n }, [props.onError, store]);\n\n useEffect(() => {\n store.setOnMessage(props.onMessage);\n\n return () => store.setOnMessage();\n }, [props.onMessage, store]);\n\n useEffect(() => {\n store.setOnFormSelect(props.opts.onFormSelect);\n\n return () => store.setOnFormSelect();\n }, [props.opts.onFormSelect, store]);\n\n useEffect(() => {\n store.setOnCalcFieldOpen(props.opts.onCalcFieldOpen);\n\n return () => store.setOnCalcFieldOpen();\n }, [props.opts.onCalcFieldOpen, store]);\n\n useEffect(() => {\n store.setOnCalcFieldSelect(props.opts.onCalcFieldSelect);\n\n return () => store.setOnCalcFieldSelect();\n }, [props.opts.onCalcFieldSelect, store]);\n\n const { minHeight = 800, style = {} } = props;\n\n return (\n <div style={{ minHeight, display: 'flex' }}>\n {!isReady && <p className=\"c-red-500\">error loading editor</p>}\n <div id={props.id ?? 'editor'} style={style} ref={containerRef} />\n {props.opts.displayConditions && (\n <DisplayConditionModal\n portalContainer={props.opts.displayConditionModalPortalContainer}\n schema={props.opts.schema}\n onConditionalsOpen={props.opts.onConditionalsOpen}\n onConditionFormSelect={props.opts.onConditionFormSelect}\n />\n )}\n </div>\n );\n});\n"],"names":["forwardRef","useEffect","useImperativeHandle","useMemo","useRef","useState","DisplayConditionModal","UnlayerStore","useUnlayerRef","UnlayerEditor","props","ref","isReady","setIsReady","containerRef","store","opts","current","init","then","catch","destroy","unlayerRef","setDesign","design","setOnChange","onChange","setOnSnapshotSave","onSnapshotSave","newSnapshot","addTwin","setOnReady","onReady","setOnImage","onImage","setOnError","onError","setOnMessage","onMessage","setOnFormSelect","onFormSelect","setOnCalcFieldOpen","onCalcFieldOpen","setOnCalcFieldSelect","onCalcFieldSelect","minHeight","style","div","display","p","className","id","displayConditions","portalContainer","displayConditionModalPortalContainer","schema","onConditionalsOpen","onConditionFormSelect"],"mappings":"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"}
|
|
@@ -71,6 +71,8 @@ export interface CreateUnlayerEditorProps {
|
|
|
71
71
|
hideContentControls?: boolean;
|
|
72
72
|
hideBodyMenuItem?: boolean;
|
|
73
73
|
displayConditions?: boolean;
|
|
74
|
+
/** Override portal target for the display-conditions dialog (defaults: shadow root when embedded, else `document.body`). */
|
|
75
|
+
displayConditionModalPortalContainer?: Element | DocumentFragment | null;
|
|
74
76
|
enableHTMLEditing?: boolean;
|
|
75
77
|
enableHTMLEditingReadonly?: boolean;
|
|
76
78
|
imageValidation?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlayer-interface.d.ts","sourceRoot":"","sources":["../src/unlayer-interface.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unlayer-interface.d.ts","sourceRoot":"","sources":["../src/unlayer-interface.tsx"],"names":[],"mappings":"AAAA,OAAO,EACH,+BAA+B,EAC/B,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,GAAG,CAAC;CACf;AACD,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAC9D,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE;QACF,IAAI,EAAE;YACF,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,OAAO,EAAE;gBACL,QAAQ,EAAE,iBAAiB,EAAE,CAAC;gBAC9B,MAAM,CAAC,EAAE,GAAG,CAAC;aAChB,EAAE,CAAC;YACJ,MAAM,CAAC,EAAE,GAAG,CAAC;SAChB,EAAE,CAAC;QACJ,MAAM,CAAC,EAAE,GAAG,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAC9B,UAAU,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI,CAAC;IACpD,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACtC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAC9D,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,yBAAyB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,yBAAyB,EAAE,GAAG,SAAS,CAAC;IACpD,eAAe,CAAC,EAAE,+BAA+B,EAAE,GAAG,SAAS,CAAC;IAChE,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACvC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4HAA4H;IAC5H,oCAAoC,CAAC,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAAC;IACzE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,eAAe,CAAC,EAAE;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClD,kBAAkB,CAAC,EAAE,CACjB,WAAW,EAAE,MAAM,EAAE,EACrB,YAAY,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,EACzC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,KAChE,IAAI,CAAC;IACV,qBAAqB,CAAC,EAAE,CACpB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,KAChE,IAAI,CAAC;CACb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/unlayer-interface.tsx"],"sourcesContent":["import {\n UnlayerEditorESignRecipientInfo,\n UnlayerEditorTwin,\n UnlayerEditorUnit,\n} from './shared/const';\nimport { FormFieldInfo, FormInfo } from './shared/forms';\nimport { SchemaObject } from './shared/schema';\n\nexport interface UnlayerDesignTool {\n type: string;\n slug?: string;\n values: any;\n}\nexport interface UnlayerDesignCustomTool extends UnlayerDesignTool {\n slug: string;\n}\n\nexport interface UnlayerDesignFormat {\n body: {\n rows: {\n cells: number[];\n columns: {\n contents: UnlayerDesignTool[];\n values?: any;\n }[];\n values?: any;\n }[];\n values?: any;\n };\n counters: Record<string, number>;\n schemaVersion: number;\n}\n\nexport interface UnlayerExport {\n html: string;\n chunks: any;\n design: UnlayerDesignFormat;\n}\n\nexport interface UnlayerRef {\n loadDesign(design: any): void;\n saveDesign(cb: (design: any) => void): void;\n exportHtml(cb: (data: UnlayerExport) => void): void;\n sendFormList(forms: FormInfo[]): void;\n sendFormFields(formId: number, fields: FormFieldInfo[]): void;\n sendCalcFieldLabels(labels: Record<string, string>): void;\n}\n\nexport interface UnlayerEditorMergeTagInfo {\n id: string;\n name: string;\n propertyPath: string;\n}\n\nexport interface UnlayerEditorCustomTool {\n key: string;\n title: string;\n description?: string;\n url: string;\n groupUrl?: string;\n}\n\nexport interface CreateUnlayerEditorProps {\n tools: UnlayerEditorCustomTool[];\n newSnapshot?: UnlayerEditorTwin;\n toolTwins?: UnlayerEditorTwin[];\n isSnapshotMode?: boolean;\n dummyData?: any;\n schema?: SchemaObject;\n customCSS?: string | string[] | undefined;\n customJS?: string | string[] | undefined;\n mergeTags?: UnlayerEditorMergeTagInfo[] | undefined;\n eSignRecipients?: UnlayerEditorESignRecipientInfo[] | undefined;\n eSignFieldTypes?: string[] | undefined;\n genericConfigMode?: boolean;\n generics?: true | string[];\n units?: UnlayerEditorUnit[];\n noCoreTools?: boolean;\n latest?: boolean;\n blocks?: boolean;\n hideAllTools?: boolean;\n hideContentControls?: boolean;\n hideBodyMenuItem?: boolean;\n displayConditions?: boolean;\n enableHTMLEditing?: boolean;\n enableHTMLEditingReadonly?: boolean;\n imageValidation?: {\n maxWidth?: number;\n maxHeight?: number;\n maxFileSize?: number;\n };\n holidays?: string[];\n onFormSelect?: (formId: number) => void;\n onCalcFieldOpen?: (usedFormIds: number[]) => void;\n onCalcFieldSelect?: (fieldKeys: string[]) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n}\n"],"names":[],"mappings":"AA8DA,
|
|
1
|
+
{"version":3,"sources":["../src/unlayer-interface.tsx"],"sourcesContent":["import {\n UnlayerEditorESignRecipientInfo,\n UnlayerEditorTwin,\n UnlayerEditorUnit,\n} from './shared/const';\nimport { FormFieldInfo, FormInfo } from './shared/forms';\nimport { SchemaObject } from './shared/schema';\n\nexport interface UnlayerDesignTool {\n type: string;\n slug?: string;\n values: any;\n}\nexport interface UnlayerDesignCustomTool extends UnlayerDesignTool {\n slug: string;\n}\n\nexport interface UnlayerDesignFormat {\n body: {\n rows: {\n cells: number[];\n columns: {\n contents: UnlayerDesignTool[];\n values?: any;\n }[];\n values?: any;\n }[];\n values?: any;\n };\n counters: Record<string, number>;\n schemaVersion: number;\n}\n\nexport interface UnlayerExport {\n html: string;\n chunks: any;\n design: UnlayerDesignFormat;\n}\n\nexport interface UnlayerRef {\n loadDesign(design: any): void;\n saveDesign(cb: (design: any) => void): void;\n exportHtml(cb: (data: UnlayerExport) => void): void;\n sendFormList(forms: FormInfo[]): void;\n sendFormFields(formId: number, fields: FormFieldInfo[]): void;\n sendCalcFieldLabels(labels: Record<string, string>): void;\n}\n\nexport interface UnlayerEditorMergeTagInfo {\n id: string;\n name: string;\n propertyPath: string;\n}\n\nexport interface UnlayerEditorCustomTool {\n key: string;\n title: string;\n description?: string;\n url: string;\n groupUrl?: string;\n}\n\nexport interface CreateUnlayerEditorProps {\n tools: UnlayerEditorCustomTool[];\n newSnapshot?: UnlayerEditorTwin;\n toolTwins?: UnlayerEditorTwin[];\n isSnapshotMode?: boolean;\n dummyData?: any;\n schema?: SchemaObject;\n customCSS?: string | string[] | undefined;\n customJS?: string | string[] | undefined;\n mergeTags?: UnlayerEditorMergeTagInfo[] | undefined;\n eSignRecipients?: UnlayerEditorESignRecipientInfo[] | undefined;\n eSignFieldTypes?: string[] | undefined;\n genericConfigMode?: boolean;\n generics?: true | string[];\n units?: UnlayerEditorUnit[];\n noCoreTools?: boolean;\n latest?: boolean;\n blocks?: boolean;\n hideAllTools?: boolean;\n hideContentControls?: boolean;\n hideBodyMenuItem?: boolean;\n displayConditions?: boolean;\n /** Override portal target for the display-conditions dialog (defaults: shadow root when embedded, else `document.body`). */\n displayConditionModalPortalContainer?: Element | DocumentFragment | null;\n enableHTMLEditing?: boolean;\n enableHTMLEditingReadonly?: boolean;\n imageValidation?: {\n maxWidth?: number;\n maxHeight?: number;\n maxFileSize?: number;\n };\n holidays?: string[];\n onFormSelect?: (formId: number) => void;\n onCalcFieldOpen?: (usedFormIds: number[]) => void;\n onCalcFieldSelect?: (fieldKeys: string[]) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n}\n"],"names":[],"mappings":"AA8DA,WA4CC"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Fragment,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'react';
|
|
3
11
|
import { createPortal } from 'react-dom';
|
|
4
12
|
import {
|
|
5
13
|
buildFormFieldKey,
|
|
@@ -28,6 +36,15 @@ const BEHAVIOR_OPTIONS = [
|
|
|
28
36
|
const NUMERIC_VALUE_RE = /^-?(?:\d+\.?\d*|\.\d+)$/;
|
|
29
37
|
type BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];
|
|
30
38
|
|
|
39
|
+
/** When the editor runs inside a shadow root (e.g. monolith MFE), portaling to `document.body` escapes the shadow tree and loses bundled styles. */
|
|
40
|
+
function resolveDisplayConditionPortalContainer(anchor: HTMLElement): Element | DocumentFragment {
|
|
41
|
+
const rootNode = anchor.getRootNode();
|
|
42
|
+
if (rootNode instanceof ShadowRoot) {
|
|
43
|
+
return rootNode;
|
|
44
|
+
}
|
|
45
|
+
return document.body;
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
function deriveMatchType(conditionState: DisplayConditionState): MatchType {
|
|
32
49
|
const firstGroup = conditionState.groups[0];
|
|
33
50
|
if (!firstGroup || firstGroup.conditions.length <= 1) {
|
|
@@ -59,6 +76,11 @@ function applyMatchTypeToState(
|
|
|
59
76
|
}
|
|
60
77
|
|
|
61
78
|
export interface DisplayConditionModalProps {
|
|
79
|
+
/**
|
|
80
|
+
* When set, the conditions dialog is portaled here instead of resolving from the DOM anchor.
|
|
81
|
+
* Use when the host controls stacking context or shadow boundaries explicitly.
|
|
82
|
+
*/
|
|
83
|
+
portalContainer?: Element | DocumentFragment | null;
|
|
62
84
|
onConditionFormSelect?: (
|
|
63
85
|
formId: number,
|
|
64
86
|
sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,
|
|
@@ -72,7 +94,12 @@ export interface DisplayConditionModalProps {
|
|
|
72
94
|
}
|
|
73
95
|
|
|
74
96
|
export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
75
|
-
const {
|
|
97
|
+
const {
|
|
98
|
+
onConditionFormSelect,
|
|
99
|
+
onConditionalsOpen,
|
|
100
|
+
portalContainer: portalContainerProp,
|
|
101
|
+
schema,
|
|
102
|
+
} = props;
|
|
76
103
|
const [request, setRequest] = useState<DisplayConditionRequest | null>(null);
|
|
77
104
|
const [isOpen, setIsOpen] = useState(false);
|
|
78
105
|
const [state, setState] = useState(defaultState);
|
|
@@ -144,12 +171,21 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
144
171
|
[onConditionFormSelect],
|
|
145
172
|
);
|
|
146
173
|
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
174
|
+
const portalAnchorRef = useRef<HTMLSpanElement>(null);
|
|
175
|
+
const [resolvedPortalContainer, setResolvedPortalContainer] = useState<
|
|
176
|
+
Element | DocumentFragment | null
|
|
177
|
+
>(null);
|
|
178
|
+
|
|
179
|
+
useLayoutEffect(() => {
|
|
180
|
+
if (typeof document === 'undefined' || portalContainerProp !== undefined) {
|
|
181
|
+
return;
|
|
150
182
|
}
|
|
151
|
-
|
|
152
|
-
|
|
183
|
+
const anchor = portalAnchorRef.current;
|
|
184
|
+
if (!anchor) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
setResolvedPortalContainer(resolveDisplayConditionPortalContainer(anchor));
|
|
188
|
+
}, [portalContainerProp]);
|
|
153
189
|
|
|
154
190
|
useEffect(() => {
|
|
155
191
|
return onDisplayCondition(nextRequest => {
|
|
@@ -274,99 +310,129 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
274
310
|
return state.groups.length > 0;
|
|
275
311
|
}, [allFieldOptions, isFieldDataLoading, state.groups]);
|
|
276
312
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
313
|
+
const portalTarget =
|
|
314
|
+
portalContainerProp === undefined ? resolvedPortalContainer : portalContainerProp;
|
|
280
315
|
|
|
281
|
-
return
|
|
282
|
-
<
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
gap="4"
|
|
316
|
+
return (
|
|
317
|
+
<Fragment>
|
|
318
|
+
{portalContainerProp === undefined ? (
|
|
319
|
+
<span
|
|
320
|
+
ref={portalAnchorRef}
|
|
321
|
+
aria-hidden="true"
|
|
288
322
|
style={{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
323
|
+
position: 'absolute',
|
|
324
|
+
width: 0,
|
|
325
|
+
height: 0,
|
|
326
|
+
clipPath: 'inset(50%)',
|
|
327
|
+
overflow: 'hidden',
|
|
328
|
+
whiteSpace: 'nowrap',
|
|
293
329
|
}}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
330
|
+
/>
|
|
331
|
+
) : null}
|
|
332
|
+
{portalTarget && isOpen
|
|
333
|
+
? createPortal(
|
|
334
|
+
<Dialog open={isOpen} onClose={handleClose} size="xlarge">
|
|
335
|
+
<Dialog.Header>Conditions</Dialog.Header>
|
|
336
|
+
<Dialog.Content>
|
|
337
|
+
<Flex
|
|
338
|
+
direction="column"
|
|
339
|
+
gap="4"
|
|
340
|
+
style={{
|
|
341
|
+
maxHeight: MODAL_CONTENT_MAX_HEIGHT,
|
|
342
|
+
overflowY: 'auto',
|
|
343
|
+
paddingRight: 8,
|
|
344
|
+
width: '100%',
|
|
345
|
+
}}
|
|
346
|
+
>
|
|
347
|
+
<ConditionGroupsSection
|
|
348
|
+
behaviorSection={
|
|
349
|
+
<Flex
|
|
350
|
+
direction="row"
|
|
351
|
+
alignItems="center"
|
|
352
|
+
gap="2"
|
|
353
|
+
style={{ flexWrap: 'wrap' }}
|
|
354
|
+
>
|
|
355
|
+
<Text size="small" subdued variant="body">
|
|
356
|
+
Select to include or exclude selected
|
|
357
|
+
template/file.
|
|
358
|
+
</Text>
|
|
359
|
+
<div style={{ width: 90 }}>
|
|
360
|
+
<Combobox.Select
|
|
361
|
+
{...({
|
|
362
|
+
disableClearSelection: true,
|
|
363
|
+
} as object)}
|
|
364
|
+
itemToKey={(item: BehaviorOption | null) =>
|
|
365
|
+
item?.value ?? ''
|
|
366
|
+
}
|
|
367
|
+
itemToString={(item: BehaviorOption | null) =>
|
|
368
|
+
item?.label ?? ''
|
|
369
|
+
}
|
|
370
|
+
items={[...BEHAVIOR_OPTIONS]}
|
|
371
|
+
selectedItem={selectedBehavior}
|
|
372
|
+
onChange={handleBehaviorChange}
|
|
373
|
+
>
|
|
374
|
+
<Combobox.SelectTrigger
|
|
375
|
+
label=""
|
|
376
|
+
placeholder="Select..."
|
|
377
|
+
size="small"
|
|
378
|
+
/>
|
|
379
|
+
<Combobox.Content>
|
|
380
|
+
{({
|
|
381
|
+
items,
|
|
382
|
+
}: {
|
|
383
|
+
items: BehaviorOption[];
|
|
384
|
+
}) => (
|
|
385
|
+
<Combobox.List>
|
|
386
|
+
{items.map((item, i) => (
|
|
387
|
+
<Combobox.Item
|
|
388
|
+
index={i}
|
|
389
|
+
item={item}
|
|
390
|
+
key={item.value}
|
|
391
|
+
>
|
|
392
|
+
{item.label}
|
|
393
|
+
</Combobox.Item>
|
|
394
|
+
))}
|
|
395
|
+
</Combobox.List>
|
|
396
|
+
)}
|
|
397
|
+
</Combobox.Content>
|
|
398
|
+
</Combobox.Select>
|
|
399
|
+
</div>
|
|
400
|
+
</Flex>
|
|
401
|
+
}
|
|
402
|
+
dataPointOptions={dataPointOptions}
|
|
403
|
+
formFieldOptions={formFieldOptions}
|
|
404
|
+
forms={forms}
|
|
405
|
+
groups={state.groups}
|
|
406
|
+
matchType={matchType}
|
|
407
|
+
onFormSelect={handleFormSelect}
|
|
408
|
+
onMatchTypeChange={setMatchType}
|
|
409
|
+
onUpdateGroup={updateGroup}
|
|
410
|
+
/>
|
|
411
|
+
</Flex>
|
|
412
|
+
</Dialog.Content>
|
|
413
|
+
<Dialog.Footer sticky>
|
|
414
|
+
<Flex
|
|
415
|
+
justifyContent="flex-end"
|
|
416
|
+
alignItems="center"
|
|
417
|
+
gap="3"
|
|
418
|
+
style={{ width: '100%' }}
|
|
419
|
+
>
|
|
420
|
+
<Button appearance="secondary" onClick={handleClose}>
|
|
421
|
+
Cancel
|
|
422
|
+
</Button>
|
|
423
|
+
<Button
|
|
424
|
+
appearance="primary"
|
|
425
|
+
disabled={!canSave}
|
|
426
|
+
onClick={handleSave}
|
|
427
|
+
>
|
|
428
|
+
Save Changes
|
|
429
|
+
</Button>
|
|
430
|
+
</Flex>
|
|
431
|
+
</Dialog.Footer>
|
|
432
|
+
</Dialog>,
|
|
433
|
+
portalTarget,
|
|
434
|
+
)
|
|
435
|
+
: null}
|
|
436
|
+
</Fragment>
|
|
371
437
|
);
|
|
372
438
|
};
|
package/src/editor.tsx
CHANGED
|
@@ -129,6 +129,7 @@ export const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props,
|
|
|
129
129
|
<div id={props.id ?? 'editor'} style={style} ref={containerRef} />
|
|
130
130
|
{props.opts.displayConditions && (
|
|
131
131
|
<DisplayConditionModal
|
|
132
|
+
portalContainer={props.opts.displayConditionModalPortalContainer}
|
|
132
133
|
schema={props.opts.schema}
|
|
133
134
|
onConditionalsOpen={props.opts.onConditionalsOpen}
|
|
134
135
|
onConditionFormSelect={props.opts.onConditionFormSelect}
|
|
@@ -82,6 +82,8 @@ export interface CreateUnlayerEditorProps {
|
|
|
82
82
|
hideContentControls?: boolean;
|
|
83
83
|
hideBodyMenuItem?: boolean;
|
|
84
84
|
displayConditions?: boolean;
|
|
85
|
+
/** Override portal target for the display-conditions dialog (defaults: shadow root when embedded, else `document.body`). */
|
|
86
|
+
displayConditionModalPortalContainer?: Element | DocumentFragment | null;
|
|
85
87
|
enableHTMLEditing?: boolean;
|
|
86
88
|
enableHTMLEditingReadonly?: boolean;
|
|
87
89
|
imageValidation?: {
|