@servicetitan/dte-unlayer 0.158.0 → 0.159.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/api-core.js +22 -29
- package/dist/api-core.js.map +1 -1
- package/dist/api-custom-tools.js +23 -29
- package/dist/api-custom-tools.js.map +1 -1
- package/dist/business-calendar/BusinessCalendarDrawer.d.ts +19 -0
- package/dist/business-calendar/BusinessCalendarDrawer.d.ts.map +1 -0
- package/dist/business-calendar/BusinessCalendarDrawer.js +41 -0
- package/dist/business-calendar/BusinessCalendarDrawer.js.map +1 -0
- package/dist/business-calendar/business-calendar-requests.d.ts +25 -0
- package/dist/business-calendar/business-calendar-requests.d.ts.map +1 -0
- package/dist/business-calendar/business-calendar-requests.js +46 -0
- package/dist/business-calendar/business-calendar-requests.js.map +1 -0
- package/dist/business-calendar/business-calendar-state.d.ts +22 -0
- package/dist/business-calendar/business-calendar-state.d.ts.map +1 -0
- package/dist/business-calendar/business-calendar-state.js +74 -0
- package/dist/business-calendar/business-calendar-state.js.map +1 -0
- package/dist/business-calendar/useBusinessCalendarRequests.d.ts +15 -0
- package/dist/business-calendar/useBusinessCalendarRequests.d.ts.map +1 -0
- package/dist/business-calendar/useBusinessCalendarRequests.js +30 -0
- package/dist/business-calendar/useBusinessCalendarRequests.js.map +1 -0
- package/dist/display-conditions/ConditionGroup.js +15 -89
- package/dist/display-conditions/ConditionGroup.js.map +1 -1
- package/dist/display-conditions/ConditionGroupsSection.js +2 -70
- package/dist/display-conditions/ConditionGroupsSection.js.map +1 -1
- package/dist/display-conditions/ConditionRow.js +63 -205
- package/dist/display-conditions/ConditionRow.js.map +1 -1
- package/dist/display-conditions/DisplayConditionModal.js +40 -190
- package/dist/display-conditions/DisplayConditionModal.js.map +1 -1
- package/dist/display-conditions/LookupValueControl.js +42 -105
- package/dist/display-conditions/LookupValueControl.js.map +1 -1
- package/dist/display-conditions/SeparatorWithChip.js +1 -10
- package/dist/display-conditions/SeparatorWithChip.js.map +1 -1
- package/dist/display-conditions/constants.js +15 -20
- package/dist/display-conditions/constants.js.map +1 -1
- package/dist/display-conditions/displayConditionController.js +5 -8
- package/dist/display-conditions/displayConditionController.js.map +1 -1
- package/dist/display-conditions/lookupOptionsController.js +16 -16
- package/dist/display-conditions/lookupOptionsController.js.map +1 -1
- package/dist/display-conditions/nunjucks.js +98 -116
- package/dist/display-conditions/nunjucks.js.map +1 -1
- package/dist/display-conditions/schemaDataPoints.js +13 -11
- package/dist/display-conditions/schemaDataPoints.js.map +1 -1
- package/dist/display-conditions/types.js +23 -67
- package/dist/display-conditions/types.js.map +1 -1
- package/dist/display-conditions/useConditionForms.js +38 -56
- package/dist/display-conditions/useConditionForms.js.map +1 -1
- package/dist/display-conditions/useLookupOptions.js +24 -44
- package/dist/display-conditions/useLookupOptions.js.map +1 -1
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js +37 -150
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js.map +1 -1
- package/dist/e-sign-offset/ESignOffsetRuleRow.js +12 -73
- package/dist/e-sign-offset/ESignOffsetRuleRow.js.map +1 -1
- package/dist/e-sign-offset/eSignOffsetController.js +5 -8
- package/dist/e-sign-offset/eSignOffsetController.js.map +1 -1
- package/dist/editor-core-source.d.ts +2 -2
- package/dist/editor-core-source.d.ts.map +1 -1
- package/dist/editor-core-source.js +3 -3
- package/dist/editor-core-source.js.map +1 -1
- package/dist/editor-core.js +2 -2
- package/dist/editor-core.js.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +56 -118
- package/dist/editor.js.map +1 -1
- package/dist/image-upload-error.js +3 -3
- package/dist/image-upload-error.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/loadScript.js +7 -8
- package/dist/loadScript.js.map +1 -1
- package/dist/log.js +2 -3
- package/dist/log.js.map +1 -1
- package/dist/merge-tags.js +18 -17
- package/dist/merge-tags.js.map +1 -1
- package/dist/shared/configs.js +1 -2
- package/dist/shared/configs.js.map +1 -1
- package/dist/shared/const.d.ts +70 -0
- package/dist/shared/const.d.ts.map +1 -1
- package/dist/shared/const.js +13 -4
- package/dist/shared/const.js.map +1 -1
- package/dist/shared/date-calc.js +47 -38
- package/dist/shared/date-calc.js.map +1 -1
- package/dist/shared/e-sign-offset.js +46 -63
- package/dist/shared/e-sign-offset.js.map +1 -1
- package/dist/shared/edit-icon.js +0 -1
- package/dist/shared/edit-icon.js.map +1 -1
- package/dist/shared/fonts.js +16 -17
- package/dist/shared/fonts.js.map +1 -1
- package/dist/shared/forms.js +16 -38
- package/dist/shared/forms.js.map +1 -1
- package/dist/shared/instance-id.js +6 -9
- package/dist/shared/instance-id.js.map +1 -1
- package/dist/shared/nunjucks-helpers.js +2 -5
- package/dist/shared/nunjucks-helpers.js.map +1 -1
- package/dist/shared/schema.js +52 -96
- package/dist/shared/schema.js.map +1 -1
- package/dist/shared/tools.js +6 -13
- package/dist/shared/tools.js.map +1 -1
- package/dist/store.d.ts +15 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +851 -548
- package/dist/store.js.map +1 -1
- package/dist/tools.js +133 -143
- package/dist/tools.js.map +1 -1
- package/dist/unlayer-interface.d.ts +15 -4
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js +1 -2
- package/dist/unlayer-interface.js.map +1 -1
- package/dist/unlayer.js +86 -113
- package/dist/unlayer.js.map +1 -1
- package/dist/vendor/dte-shared/business-calendar-validation.utils.d.ts +25 -0
- package/dist/vendor/dte-shared/business-calendar-validation.utils.js +80 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.d.ts +15 -0
- package/dist/vendor/dte-shared/components/business-calendar-section.js +14 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.d.ts +18 -0
- package/dist/vendor/dte-shared/components/schedule-drawer.js +119 -0
- package/dist/vendor/dte-shared/components/schedule-picker.d.ts +8 -0
- package/dist/vendor/dte-shared/components/schedule-picker.js +88 -0
- package/dist/vendor/dte-shared/constants.d.ts +31 -0
- package/dist/vendor/dte-shared/constants.js +34 -0
- package/dist/vendor/dte-shared/field-schedule-editor-context.d.ts +31 -0
- package/dist/vendor/dte-shared/field-schedule-editor-context.js +110 -0
- package/dist/vendor/dte-shared/index.d.ts +8 -0
- package/dist/vendor/dte-shared/index.js +7 -0
- package/dist/vendor/dte-shared/schedule-bindings.utils.d.ts +22 -0
- package/dist/vendor/dte-shared/schedule-bindings.utils.js +31 -0
- package/dist/vendor/dte-shared/styles/schedule.css +19 -0
- package/dist/vendor/dte-shared/types.d.ts +129 -0
- package/dist/vendor/dte-shared/types.js +1 -0
- package/package.json +7 -1
- package/src/__tests__/business-calendar-drawer.test.tsx +183 -0
- package/src/__tests__/business-calendar-requests.test.ts +166 -0
- package/src/__tests__/business-calendar-state.test.tsx +142 -0
- package/src/__tests__/store.business-calendar.test.ts +185 -0
- package/src/__tests__/unlayer.e-sign-types.test.ts +30 -0
- package/src/business-calendar/BusinessCalendarDrawer.tsx +76 -0
- package/src/business-calendar/business-calendar-requests.ts +80 -0
- package/src/business-calendar/business-calendar-state.ts +113 -0
- package/src/business-calendar/useBusinessCalendarRequests.ts +49 -0
- package/src/editor-core-source.ts +2 -2
- package/src/editor.tsx +15 -0
- package/src/index.ts +10 -0
- package/src/shared/const.ts +59 -0
- package/src/store.ts +67 -5
- package/src/unlayer-interface.tsx +15 -4
- package/src/unlayer.tsx +5 -5
|
@@ -7,16 +7,10 @@ import { defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';
|
|
|
7
7
|
import { onDisplayCondition } from './displayConditionController';
|
|
8
8
|
import { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';
|
|
9
9
|
import { getSchemaDataPointOptions } from './schemaDataPoints';
|
|
10
|
-
import { useConditionForms } from './useConditionForms';
|
|
10
|
+
import { useConditionForms, } from './useConditionForms';
|
|
11
11
|
const BEHAVIOR_OPTIONS = [
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
value: 'show'
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
label: 'Hide',
|
|
18
|
-
value: 'hide'
|
|
19
|
-
}
|
|
12
|
+
{ label: 'Show', value: 'show' },
|
|
13
|
+
{ label: 'Hide', value: 'hide' },
|
|
20
14
|
];
|
|
21
15
|
const NUMERIC_VALUE_RE = /^-?(?:\d+\.?\d*|\.\d+)$/;
|
|
22
16
|
function deriveMatchType(conditionState) {
|
|
@@ -24,49 +18,35 @@ function deriveMatchType(conditionState) {
|
|
|
24
18
|
if (!firstGroup || firstGroup.conditions.length <= 1) {
|
|
25
19
|
return 'all';
|
|
26
20
|
}
|
|
27
|
-
const hasOr = firstGroup.conditions.some(
|
|
21
|
+
const hasOr = firstGroup.conditions.some(c => c.logicalOperator === 'or');
|
|
28
22
|
return hasOr ? 'any' : 'all';
|
|
29
23
|
}
|
|
30
24
|
function applyMatchTypeToState(conditionState, matchType) {
|
|
31
25
|
const logicalOp = matchType === 'all' ? 'and' : 'or';
|
|
32
26
|
return {
|
|
33
27
|
...conditionState,
|
|
34
|
-
groups: conditionState.groups.map((group, groupIndex)=>{
|
|
28
|
+
groups: conditionState.groups.map((group, groupIndex) => {
|
|
35
29
|
if (groupIndex !== 0) {
|
|
36
30
|
return group;
|
|
37
31
|
}
|
|
38
32
|
return {
|
|
39
33
|
...group,
|
|
40
|
-
conditions: group.conditions.map((c, i)=>i === 0 ? c : {
|
|
41
|
-
...c,
|
|
42
|
-
logicalOperator: logicalOp
|
|
43
|
-
})
|
|
34
|
+
conditions: group.conditions.map((c, i) => i === 0 ? c : { ...c, logicalOperator: logicalOp }),
|
|
44
35
|
};
|
|
45
|
-
})
|
|
36
|
+
}),
|
|
46
37
|
};
|
|
47
38
|
}
|
|
48
|
-
export const DisplayConditionModal = (props)=>{
|
|
49
|
-
const { onConditionFormSelect, onConditionalsOpen, portalContainer: portalContainerProp, schema } = props;
|
|
39
|
+
export const DisplayConditionModal = (props) => {
|
|
40
|
+
const { onConditionFormSelect, onConditionalsOpen, portalContainer: portalContainerProp, schema, } = props;
|
|
50
41
|
const [request, setRequest] = useState(null);
|
|
51
42
|
const [isOpen, setIsOpen] = useState(false);
|
|
52
43
|
const [state, setState] = useState(defaultState);
|
|
53
44
|
const [matchType, setMatchType] = useState('all');
|
|
54
|
-
const { formFieldOptions, forms, isFieldDataLoading, loadForms, requestFormFields } = useConditionForms({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
schema
|
|
60
|
-
]);
|
|
61
|
-
const allFieldOptions = useMemo(()=>[
|
|
62
|
-
...dataPointOptions,
|
|
63
|
-
...formFieldOptions
|
|
64
|
-
], [
|
|
65
|
-
dataPointOptions,
|
|
66
|
-
formFieldOptions
|
|
67
|
-
]);
|
|
68
|
-
useEffect(()=>{
|
|
69
|
-
return onDisplayCondition((nextRequest)=>{
|
|
45
|
+
const { formFieldOptions, forms, isFieldDataLoading, loadForms, requestFormFields } = useConditionForms({ onConditionFormSelect, onConditionalsOpen });
|
|
46
|
+
const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);
|
|
47
|
+
const allFieldOptions = useMemo(() => [...dataPointOptions, ...formFieldOptions], [dataPointOptions, formFieldOptions]);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
return onDisplayCondition(nextRequest => {
|
|
70
50
|
setRequest(nextRequest);
|
|
71
51
|
const existing = nextRequest.data;
|
|
72
52
|
const parsed = parseUnlayerDisplayCondition(existing);
|
|
@@ -76,14 +56,12 @@ export const DisplayConditionModal = (props)=>{
|
|
|
76
56
|
setMatchType(deriveMatchType(initialState));
|
|
77
57
|
setIsOpen(true);
|
|
78
58
|
});
|
|
79
|
-
}, [
|
|
80
|
-
|
|
81
|
-
]);
|
|
82
|
-
const handleClose = useCallback(()=>{
|
|
59
|
+
}, [loadForms]);
|
|
60
|
+
const handleClose = useCallback(() => {
|
|
83
61
|
setRequest(null);
|
|
84
62
|
setIsOpen(false);
|
|
85
63
|
}, []);
|
|
86
|
-
const handleSave = useCallback(()=>{
|
|
64
|
+
const handleSave = useCallback(() => {
|
|
87
65
|
if (!request) {
|
|
88
66
|
return;
|
|
89
67
|
}
|
|
@@ -91,55 +69,36 @@ export const DisplayConditionModal = (props)=>{
|
|
|
91
69
|
const condition = buildUnlayerDisplayCondition(finalState);
|
|
92
70
|
if (condition) {
|
|
93
71
|
request.done(condition);
|
|
94
|
-
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
95
74
|
request.done(null);
|
|
96
75
|
}
|
|
97
76
|
setRequest(null);
|
|
98
77
|
setIsOpen(false);
|
|
99
|
-
}, [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
]);
|
|
104
|
-
const updateGroup = useCallback((index, group)=>{
|
|
105
|
-
setState((prev)=>{
|
|
106
|
-
const next = [
|
|
107
|
-
...prev.groups
|
|
108
|
-
];
|
|
78
|
+
}, [matchType, request, state]);
|
|
79
|
+
const updateGroup = useCallback((index, group) => {
|
|
80
|
+
setState(prev => {
|
|
81
|
+
const next = [...prev.groups];
|
|
109
82
|
next[index] = group;
|
|
110
|
-
return {
|
|
111
|
-
...prev,
|
|
112
|
-
groups: next
|
|
113
|
-
};
|
|
83
|
+
return { ...prev, groups: next };
|
|
114
84
|
});
|
|
115
85
|
}, []);
|
|
116
|
-
const selectedBehavior = useMemo(()=>{
|
|
117
|
-
|
|
118
|
-
return (_BEHAVIOR_OPTIONS_find = BEHAVIOR_OPTIONS.find((opt)=>opt.value === state.behavior)) !== null && _BEHAVIOR_OPTIONS_find !== void 0 ? _BEHAVIOR_OPTIONS_find : BEHAVIOR_OPTIONS[0];
|
|
119
|
-
}, [
|
|
120
|
-
state.behavior
|
|
121
|
-
]);
|
|
122
|
-
const handleBehaviorChange = useCallback((item)=>{
|
|
86
|
+
const selectedBehavior = useMemo(() => { var _a; return (_a = BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior)) !== null && _a !== void 0 ? _a : BEHAVIOR_OPTIONS[0]; }, [state.behavior]);
|
|
87
|
+
const handleBehaviorChange = useCallback((item) => {
|
|
123
88
|
if (item) {
|
|
124
|
-
setState(
|
|
125
|
-
...prev,
|
|
126
|
-
behavior: item.value
|
|
127
|
-
}));
|
|
89
|
+
setState(prev => ({ ...prev, behavior: item.value }));
|
|
128
90
|
}
|
|
129
91
|
}, []);
|
|
130
|
-
const handleFormSelect = useCallback((formId)=>{
|
|
92
|
+
const handleFormSelect = useCallback((formId) => {
|
|
131
93
|
requestFormFields(formId);
|
|
132
|
-
}, [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const canSave = useMemo(()=>{
|
|
94
|
+
}, [requestFormFields]);
|
|
95
|
+
const canSave = useMemo(() => {
|
|
96
|
+
var _a, _b;
|
|
136
97
|
if (isFieldDataLoading) {
|
|
137
98
|
return false;
|
|
138
99
|
}
|
|
139
|
-
for (const group of state.groups){
|
|
140
|
-
for (const condition of group.conditions){
|
|
141
|
-
var _ref;
|
|
142
|
-
var _allFieldOptions_find;
|
|
100
|
+
for (const group of state.groups) {
|
|
101
|
+
for (const condition of group.conditions) {
|
|
143
102
|
if (!condition.dataPointKey) {
|
|
144
103
|
return false;
|
|
145
104
|
}
|
|
@@ -150,18 +109,14 @@ export const DisplayConditionModal = (props)=>{
|
|
|
150
109
|
if (!trimmedValue) {
|
|
151
110
|
return false;
|
|
152
111
|
}
|
|
153
|
-
const fieldType = (
|
|
112
|
+
const fieldType = (_b = (_a = allFieldOptions.find(opt => opt.fullKey === condition.dataPointKey)) === null || _a === void 0 ? void 0 : _a.fieldType) !== null && _b !== void 0 ? _b : 'string';
|
|
154
113
|
if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {
|
|
155
114
|
return false;
|
|
156
115
|
}
|
|
157
116
|
}
|
|
158
117
|
}
|
|
159
118
|
return state.groups.length > 0;
|
|
160
|
-
}, [
|
|
161
|
-
allFieldOptions,
|
|
162
|
-
isFieldDataLoading,
|
|
163
|
-
state.groups
|
|
164
|
-
]);
|
|
119
|
+
}, [allFieldOptions, isFieldDataLoading, state.groups]);
|
|
165
120
|
if (!isOpen) {
|
|
166
121
|
return null;
|
|
167
122
|
}
|
|
@@ -169,121 +124,16 @@ export const DisplayConditionModal = (props)=>{
|
|
|
169
124
|
* Render in-place by default (same as pdf-editor). Anvil2 3.x CSS is nested under
|
|
170
125
|
* `.anvil2`; portaling to `document.body` / bare shadow root drops that ancestor and
|
|
171
126
|
* styles disappear in MFE prod. Native `<dialog>` top-layer still stacks correctly.
|
|
172
|
-
*/
|
|
173
|
-
|
|
174
|
-
onClose: handleClose,
|
|
175
|
-
size: "xlarge",
|
|
176
|
-
children: [
|
|
177
|
-
/*#__PURE__*/ _jsx(Dialog.Header, {
|
|
178
|
-
children: "Conditions"
|
|
179
|
-
}),
|
|
180
|
-
/*#__PURE__*/ _jsx(Dialog.Content, {
|
|
181
|
-
children: /*#__PURE__*/ _jsx(Flex, {
|
|
182
|
-
direction: "column",
|
|
183
|
-
gap: "4",
|
|
184
|
-
style: {
|
|
127
|
+
*/
|
|
128
|
+
const dialog = (_jsxs(Dialog, { open: isOpen, onClose: handleClose, size: "xlarge", children: [_jsx(Dialog.Header, { children: "Conditions" }), _jsx(Dialog.Content, { children: _jsx(Flex, { direction: "column", gap: "4", style: {
|
|
185
129
|
maxHeight: MODAL_CONTENT_MAX_HEIGHT,
|
|
186
130
|
overflowY: 'auto',
|
|
187
131
|
paddingRight: 8,
|
|
188
|
-
width: '100%'
|
|
189
|
-
},
|
|
190
|
-
children: /*#__PURE__*/ _jsx(ConditionGroupsSection, {
|
|
191
|
-
behaviorSection: /*#__PURE__*/ _jsxs(Flex, {
|
|
192
|
-
direction: "row",
|
|
193
|
-
alignItems: "center",
|
|
194
|
-
gap: "2",
|
|
195
|
-
style: {
|
|
196
|
-
flexWrap: 'wrap'
|
|
197
|
-
},
|
|
198
|
-
children: [
|
|
199
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
200
|
-
size: "small",
|
|
201
|
-
subdued: true,
|
|
202
|
-
variant: "body",
|
|
203
|
-
children: "Select to include or exclude selected template/file."
|
|
204
|
-
}),
|
|
205
|
-
/*#__PURE__*/ _jsx("div", {
|
|
206
|
-
style: {
|
|
207
|
-
width: 90
|
|
208
|
-
},
|
|
209
|
-
children: /*#__PURE__*/ _jsxs(Combobox.Select, {
|
|
210
|
-
disableClearSelection: true,
|
|
211
|
-
itemToKey: (item)=>{
|
|
212
|
-
var _ref;
|
|
213
|
-
return (_ref = item === null || item === void 0 ? void 0 : item.value) !== null && _ref !== void 0 ? _ref : '';
|
|
214
|
-
},
|
|
215
|
-
itemToString: (item)=>{
|
|
216
|
-
var _ref;
|
|
217
|
-
return (_ref = item === null || item === void 0 ? void 0 : item.label) !== null && _ref !== void 0 ? _ref : '';
|
|
218
|
-
},
|
|
219
|
-
items: [
|
|
220
|
-
...BEHAVIOR_OPTIONS
|
|
221
|
-
],
|
|
222
|
-
selectedItem: selectedBehavior,
|
|
223
|
-
onChange: handleBehaviorChange,
|
|
224
|
-
children: [
|
|
225
|
-
/*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
|
|
226
|
-
label: "",
|
|
227
|
-
placeholder: "Select...",
|
|
228
|
-
size: "small"
|
|
229
|
-
}),
|
|
230
|
-
/*#__PURE__*/ _jsx(Combobox.Content, {
|
|
231
|
-
children: ({ items })=>/*#__PURE__*/ _jsx(Combobox.List, {
|
|
232
|
-
children: items.map((item, i)=>/*#__PURE__*/ _jsx(Combobox.Item, {
|
|
233
|
-
index: i,
|
|
234
|
-
item: item,
|
|
235
|
-
children: item.label
|
|
236
|
-
}, item.value))
|
|
237
|
-
})
|
|
238
|
-
})
|
|
239
|
-
]
|
|
240
|
-
})
|
|
241
|
-
})
|
|
242
|
-
]
|
|
243
|
-
}),
|
|
244
|
-
dataPointOptions: dataPointOptions,
|
|
245
|
-
formFieldOptions: formFieldOptions,
|
|
246
|
-
forms: forms,
|
|
247
|
-
groups: state.groups,
|
|
248
|
-
matchType: matchType,
|
|
249
|
-
onFormSelect: handleFormSelect,
|
|
250
|
-
onMatchTypeChange: setMatchType,
|
|
251
|
-
onUpdateGroup: updateGroup
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
}),
|
|
255
|
-
/*#__PURE__*/ _jsx(Dialog.Footer, {
|
|
256
|
-
sticky: true,
|
|
257
|
-
children: /*#__PURE__*/ _jsxs(Flex, {
|
|
258
|
-
justifyContent: "flex-end",
|
|
259
|
-
alignItems: "center",
|
|
260
|
-
gap: "3",
|
|
261
|
-
style: {
|
|
262
|
-
width: '100%'
|
|
263
|
-
},
|
|
264
|
-
children: [
|
|
265
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
266
|
-
appearance: "secondary",
|
|
267
|
-
onClick: handleClose,
|
|
268
|
-
children: "Cancel"
|
|
269
|
-
}),
|
|
270
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
271
|
-
appearance: "primary",
|
|
272
|
-
disabled: !canSave,
|
|
273
|
-
onClick: handleSave,
|
|
274
|
-
children: "Save Changes"
|
|
275
|
-
})
|
|
276
|
-
]
|
|
277
|
-
})
|
|
278
|
-
})
|
|
279
|
-
]
|
|
280
|
-
});
|
|
132
|
+
width: '100%',
|
|
133
|
+
}, children: _jsx(ConditionGroupsSection, { behaviorSection: _jsxs(Flex, { direction: "row", alignItems: "center", gap: "2", style: { flexWrap: 'wrap' }, children: [_jsx(Text, { size: "small", subdued: true, variant: "body", children: "Select to include or exclude selected template/file." }), _jsx("div", { style: { width: 90 }, children: _jsxs(Combobox.Select, { disableClearSelection: true, itemToKey: (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.value) !== null && _a !== void 0 ? _a : ''; }, itemToString: (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ''; }, items: [...BEHAVIOR_OPTIONS], selectedItem: selectedBehavior, onChange: handleBehaviorChange, children: [_jsx(Combobox.SelectTrigger, { label: "", placeholder: "Select...", size: "small" }), _jsx(Combobox.Content, { children: ({ items, }) => (_jsx(Combobox.List, { children: items.map((item, i) => (_jsx(Combobox.Item, { index: i, item: item, children: item.label }, item.value))) })) })] }) })] }), dataPointOptions: dataPointOptions, formFieldOptions: formFieldOptions, forms: forms, groups: state.groups, matchType: matchType, onFormSelect: handleFormSelect, onMatchTypeChange: setMatchType, onUpdateGroup: updateGroup }) }) }), _jsx(Dialog.Footer, { sticky: true, children: _jsxs(Flex, { justifyContent: "flex-end", alignItems: "center", gap: "3", style: { width: '100%' }, children: [_jsx(Button, { appearance: "secondary", onClick: handleClose, children: "Cancel" }), _jsx(Button, { appearance: "primary", disabled: !canSave, onClick: handleSave, children: "Save Changes" })] }) })] }));
|
|
281
134
|
if (portalContainerProp) {
|
|
282
|
-
return
|
|
283
|
-
children: dialog
|
|
284
|
-
}), portalContainerProp);
|
|
135
|
+
return createPortal(_jsx(ThemeProvider, { children: dialog }), portalContainerProp);
|
|
285
136
|
}
|
|
286
137
|
return dialog;
|
|
287
138
|
};
|
|
288
|
-
|
|
289
139
|
//# sourceMappingURL=DisplayConditionModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text, ThemeProvider } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { createPortal } from 'react-dom';\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 LogicalOperator,\n} from './types';\nimport {\n ConditionalsOpenHandler,\n ConditionFormSelectHandler,\n useConditionForms,\n} from './useConditionForms';\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 /**\n * Optional portal target. Prefer leaving unset so the dialog stays under the host\n * `AnvilProvider` (`.anvil2` CSS scope). When set (e.g. a host-controlled container),\n * content is wrapped in `ThemeProvider` so Anvil2 styles still apply after portaling.\n */\n portalContainer?: Element | DocumentFragment | null;\n onConditionFormSelect?: ConditionFormSelectHandler;\n onConditionalsOpen?: ConditionalsOpenHandler;\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 { formFieldOptions, forms, isFieldDataLoading, loadForms, requestFormFields } =\n useConditionForms({ onConditionFormSelect, onConditionalsOpen });\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);\n const allFieldOptions = useMemo(\n () => [...dataPointOptions, ...formFieldOptions],\n [dataPointOptions, formFieldOptions],\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\n loadForms(initialState.groups);\n setState(initialState);\n setMatchType(deriveMatchType(initialState));\n setIsOpen(true);\n });\n }, [loadForms]);\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 (!isOpen) {\n return null;\n }\n\n /*\n * Render in-place by default (same as pdf-editor). Anvil2 3.x CSS is nested under\n * `.anvil2`; portaling to `document.body` / bare shadow root drops that ancestor and\n * styles disappear in MFE prod. Native `<dialog>` top-layer still stacks correctly.\n */\n const dialog = (\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\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 appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>\n );\n\n if (portalContainerProp) {\n return createPortal(<ThemeProvider>{dialog}</ThemeProvider>, portalContainerProp);\n }\n\n return dialog;\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","ThemeProvider","useCallback","useEffect","useMemo","useState","createPortal","ConditionGroupsSection","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","useConditionForms","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","portalContainer","portalContainerProp","schema","request","setRequest","isOpen","setIsOpen","state","setState","setMatchType","formFieldOptions","forms","isFieldDataLoading","loadForms","requestFormFields","dataPointOptions","allFieldOptions","nextRequest","existing","data","parsed","initialState","handleClose","handleSave","finalState","condition","done","updateGroup","index","prev","next","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","handleFormSelect","formId","canSave","dataPointKey","operator","trimmedValue","trim","fieldType","fullKey","test","dialog","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,EAAEC,aAAa,QAAQ,uBAAuB;AAC3F,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAQ;AAClE,SAASC,YAAY,QAAQ,YAAY;AACzC,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;AAO/D,SAGIC,iBAAiB,QACd,sBAAsB;AAE7B,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;AAcA,OAAO,MAAMK,wBAAwB,CAACC;IAClC,MAAM,EACFC,qBAAqB,EACrBC,kBAAkB,EAClBC,iBAAiBC,mBAAmB,EACpCC,MAAM,EACT,GAAGL;IACJ,MAAM,CAACM,SAASC,WAAW,GAAGvC,SAAyC;IACvE,MAAM,CAACwC,QAAQC,UAAU,GAAGzC,SAAS;IACrC,MAAM,CAAC0C,OAAOC,SAAS,GAAG3C,SAASG;IACnC,MAAM,CAACsB,WAAWmB,aAAa,GAAG5C,SAAoB;IACtD,MAAM,EAAE6C,gBAAgB,EAAEC,KAAK,EAAEC,kBAAkB,EAAEC,SAAS,EAAEC,iBAAiB,EAAE,GAC/ExC,kBAAkB;QAAEwB;QAAuBC;IAAmB;IAElE,MAAMgB,mBAAmBnD,QAAQ,IAAMS,0BAA0B6B,SAAS;QAACA;KAAO;IAClF,MAAMc,kBAAkBpD,QACpB,IAAM;eAAImD;eAAqBL;SAAiB,EAChD;QAACK;QAAkBL;KAAiB;IAGxC/C,UAAU;QACN,OAAOO,mBAAmB+C,CAAAA;YACtBb,WAAWa;YACX,MAAMC,WAAWD,YAAYE,IAAI;YACjC,MAAMC,SAAShD,6BAA6B8C;YAC5C,MAAMG,eAAeD,mBAAAA,oBAAAA,SAAUpD;YAE/B6C,UAAUQ,aAAavC,MAAM;YAC7B0B,SAASa;YACTZ,aAAa9B,gBAAgB0C;YAC7Bf,UAAU;QACd;IACJ,GAAG;QAACO;KAAU;IAEd,MAAMS,cAAc5D,YAAY;QAC5B0C,WAAW;QACXE,UAAU;IACd,GAAG,EAAE;IAEL,MAAMiB,aAAa7D,YAAY;QAC3B,IAAI,CAACyC,SAAS;YACV;QACJ;QACA,MAAMqB,aAAanC,sBAAsBkB,OAAOjB;QAChD,MAAMmC,YAAYtD,6BAA6BqD;QAC/C,IAAIC,WAAW;YACXtB,QAAQuB,IAAI,CAACD;QACjB,OAAO;YACHtB,QAAQuB,IAAI,CAAC;QACjB;QACAtB,WAAW;QACXE,UAAU;IACd,GAAG;QAAChB;QAAWa;QAASI;KAAM;IAE9B,MAAMoB,cAAcjE,YAAY,CAACkE,OAAenC;QAC5Ce,SAASqB,CAAAA;YACL,MAAMC,OAAO;mBAAID,KAAK/C,MAAM;aAAC;YAC7BgD,IAAI,CAACF,MAAM,GAAGnC;YACd,OAAO;gBAAE,GAAGoC,IAAI;gBAAE/C,QAAQgD;YAAK;QACnC;IACJ,GAAG,EAAE;IAEL,MAAMC,mBAAmBnE,QACrB;YAAMW;gBAAAA,yBAAAA,iBAAiByD,IAAI,CAACC,CAAAA,MAAOA,IAAIxD,KAAK,KAAK8B,MAAM2B,QAAQ,eAAzD3D,oCAAAA,yBAA8DA,gBAAgB,CAAC,EAAE;OACvF;QAACgC,MAAM2B,QAAQ;KAAC;IAGpB,MAAMC,uBAAuBzE,YAAY,CAAC0E;QACtC,IAAIA,MAAM;YACN5B,SAASqB,CAAAA,OAAS,CAAA;oBAAE,GAAGA,IAAI;oBAAEK,UAAUE,KAAK3D,KAAK;gBAAoB,CAAA;QACzE;IACJ,GAAG,EAAE;IAEL,MAAM4D,mBAAmB3E,YACrB,CAAC4E;QACGxB,kBAAkBwB;IACtB,GACA;QAACxB;KAAkB;IAGvB,MAAMyB,UAAU3E,QAAQ;QACpB,IAAIgD,oBAAoB;YACpB,OAAO;QACX;QACA,KAAK,MAAMnB,SAASc,MAAMzB,MAAM,CAAE;YAC9B,KAAK,MAAM2C,aAAahC,MAAMV,UAAU,CAAE;;oBAYlCiC;gBAXJ,IAAI,CAACS,UAAUe,YAAY,EAAE;oBACzB,OAAO;gBACX;gBACA,IAAIf,UAAUgB,QAAQ,KAAK,cAAchB,UAAUgB,QAAQ,KAAK,gBAAgB;oBAC5E;gBACJ;gBACA,MAAMC,eAAejB,UAAUhD,KAAK,CAACkE,IAAI;gBACzC,IAAI,CAACD,cAAc;oBACf,OAAO;gBACX;gBACA,MAAME,qBACF5B,wBAAAA,gBAAgBgB,IAAI,CAACC,CAAAA,MAAOA,IAAIY,OAAO,KAAKpB,UAAUe,YAAY,eAAlExB,4CAAAA,sBACM4B,SAAS,uCAAI;gBACvB,IAAIA,cAAc,YAAY,CAAClE,iBAAiBoE,IAAI,CAACJ,eAAe;oBAChE,OAAO;gBACX;YACJ;QACJ;QACA,OAAOnC,MAAMzB,MAAM,CAACE,MAAM,GAAG;IACjC,GAAG;QAACgC;QAAiBJ;QAAoBL,MAAMzB,MAAM;KAAC;IAEtD,IAAI,CAACuB,QAAQ;QACT,OAAO;IACX;IAEA;;;;KAIC,GACD,MAAM0C,uBACF,MAACzF;QAAO0F,MAAM3C;QAAQ4C,SAAS3B;QAAa4B,MAAK;;0BAC7C,KAAC5F,OAAO6F,MAAM;0BAAC;;0BACf,KAAC7F,OAAO8F,OAAO;0BACX,cAAA,KAAC7F;oBACG8F,WAAU;oBACVC,KAAI;oBACJC,OAAO;wBACHC,WAAWvF;wBACXwF,WAAW;wBACXC,cAAc;wBACdC,OAAO;oBACX;8BAEA,cAAA,KAAC5F;wBACG6F,+BACI,MAACrG;4BACG8F,WAAU;4BACVQ,YAAW;4BACXP,KAAI;4BACJC,OAAO;gCAAEO,UAAU;4BAAO;;8CAE1B,KAACtG;oCAAK0F,MAAK;oCAAQa,OAAO;oCAACC,SAAQ;8CAAO;;8CAG1C,KAACC;oCAAIV,OAAO;wCAAEI,OAAO;oCAAG;8CACpB,cAAA,MAACtG,SAAS6G,MAAM;wCACZC,qBAAqB;wCACrBC,WAAW,CAAChC;;2DACRA,iBAAAA,2BAAAA,KAAM3D,KAAK,uCAAI;;wCAEnB4F,cAAc,CAACjC;;2DACXA,iBAAAA,2BAAAA,KAAM5D,KAAK,uCAAI;;wCAEnB8F,OAAO;+CAAI/F;yCAAiB;wCAC5BgG,cAAcxC;wCACdyC,UAAUrC;;0DAEV,KAAC9E,SAASoH,aAAa;gDACnBjG,OAAM;gDACNkG,aAAY;gDACZxB,MAAK;;0DAET,KAAC7F,SAAS+F,OAAO;0DACZ,CAAC,EACEkB,KAAK,EAGR,iBACG,KAACjH,SAASsH,IAAI;kEACTL,MAAM9E,GAAG,CAAC,CAAC4C,MAAMzC,kBACd,KAACtC,SAASuH,IAAI;gEACVhD,OAAOjC;gEACPyC,MAAMA;0EAGLA,KAAK5D,KAAK;+DAFN4D,KAAK3D,KAAK;;;;;;;;wBAYnDsC,kBAAkBA;wBAClBL,kBAAkBA;wBAClBC,OAAOA;wBACP7B,QAAQyB,MAAMzB,MAAM;wBACpBQ,WAAWA;wBACXuF,cAAcxC;wBACdyC,mBAAmBrE;wBACnBsE,eAAepD;;;;0BAI3B,KAACrE,OAAO0H,MAAM;gBAACC,MAAM;0BACjB,cAAA,MAAC1H;oBACG2H,gBAAe;oBACfrB,YAAW;oBACXP,KAAI;oBACJC,OAAO;wBAAEI,OAAO;oBAAO;;sCAEvB,KAACvG;4BAAO+H,YAAW;4BAAYC,SAAS9D;sCAAa;;sCAGrD,KAAClE;4BAAO+H,YAAW;4BAAUE,UAAU,CAAC9C;4BAAS6C,SAAS7D;sCAAY;;;;;;;IAQtF,IAAItB,qBAAqB;QACrB,qBAAOnC,2BAAa,KAACL;sBAAesF;YAAyB9C;IACjE;IAEA,OAAO8C;AACX,EAAE"}
|
|
1
|
+
{"version":3,"file":"DisplayConditionModal.js","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAa,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAA2B,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAO/D,OAAO,EAGH,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,gBAAgB,GAAG;IACrB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CAC1B,CAAC;AACX,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAGnD,SAAS,eAAe,CAAC,cAAqC;IAC1D,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC;IAC1E,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACjC,CAAC;AAED,SAAS,qBAAqB,CAC1B,cAAqC,EACrC,SAAoB;IAEpB,MAAM,SAAS,GAAoB,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,OAAO;QACH,GAAG,cAAc;QACjB,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;YACpD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,OAAO;gBACH,GAAG,KAAK;gBACR,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACtC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CACrD;aACJ,CAAC;QACN,CAAC,CAAC;KACL,CAAC;AACN,CAAC;AAcD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAiC,EAAE,EAAE;IACvE,MAAM,EACF,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EAAE,mBAAmB,EACpC,MAAM,GACT,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAiC,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,KAAK,CAAC,CAAC;IAC7D,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAC/E,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAErE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,CAAC,GAAG,gBAAgB,EAAE,GAAG,gBAAgB,CAAC,EAChD,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CACvC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,OAAO,kBAAkB,CAAC,WAAW,CAAC,EAAE;YACpC,UAAU,CAAC,WAAW,CAAC,CAAC;YACxB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC;YAClC,MAAM,MAAM,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,YAAY,EAAE,CAAC;YAE9C,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/B,QAAQ,CAAC,YAAY,CAAC,CAAC;YACvB,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,SAAS,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO;QACX,CAAC;QACD,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,SAAS,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAEhC,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,KAAyB,EAAE,EAAE;QACzE,QAAQ,CAAC,IAAI,CAAC,EAAE;YACZ,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;YACpB,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,gBAAgB,GAAG,OAAO,CAC5B,GAAG,EAAE,WAAC,OAAA,MAAA,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,CAAC,mCAAI,gBAAgB,CAAC,CAAC,CAAC,CAAA,EAAA,EACvF,CAAC,KAAK,CAAC,QAAQ,CAAC,CACnB,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,CAAC,IAA2B,EAAE,EAAE;QACrE,IAAI,IAAI,EAAE,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAwB,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,gBAAgB,GAAG,WAAW,CAChC,CAAC,MAAc,EAAE,EAAE;QACf,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC,EACD,CAAC,iBAAiB,CAAC,CACtB,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE;;QACzB,IAAI,kBAAkB,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC/B,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACvC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;oBAC1B,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,IAAI,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,SAAS,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;oBAC7E,SAAS;gBACb,CAAC;gBACD,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,CAAC,YAAY,EAAE,CAAC;oBAChB,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,MAAM,SAAS,GACX,MAAA,MAAA,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,YAAY,CAAC,0CAC7D,SAAS,mCAAI,QAAQ,CAAC;gBAChC,IAAI,SAAS,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;oBACjE,OAAO,KAAK,CAAC;gBACjB,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAExD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,MAAM,MAAM,GAAG,CACX,MAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAC,QAAQ,aACrD,KAAC,MAAM,CAAC,MAAM,6BAA2B,EACzC,KAAC,MAAM,CAAC,OAAO,cACX,KAAC,IAAI,IACD,SAAS,EAAC,QAAQ,EAClB,GAAG,EAAC,GAAG,EACP,KAAK,EAAE;wBACH,SAAS,EAAE,wBAAwB;wBACnC,SAAS,EAAE,MAAM;wBACjB,YAAY,EAAE,CAAC;wBACf,KAAK,EAAE,MAAM;qBAChB,YAED,KAAC,sBAAsB,IACnB,eAAe,EACX,MAAC,IAAI,IACD,SAAS,EAAC,KAAK,EACf,UAAU,EAAC,QAAQ,EACnB,GAAG,EAAC,GAAG,EACP,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,aAE3B,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,EAAC,OAAO,QAAC,OAAO,EAAC,MAAM,qEAElC,EACP,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,YACrB,MAAC,QAAQ,CAAC,MAAM,IACZ,qBAAqB,QACrB,SAAS,EAAE,CAAC,IAA2B,EAAE,EAAE,WACvC,OAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,mCAAI,EAAE,CAAA,EAAA,EAErB,YAAY,EAAE,CAAC,IAA2B,EAAE,EAAE,WAC1C,OAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,mCAAI,EAAE,CAAA,EAAA,EAErB,KAAK,EAAE,CAAC,GAAG,gBAAgB,CAAC,EAC5B,YAAY,EAAE,gBAAgB,EAC9B,QAAQ,EAAE,oBAAoB,aAE9B,KAAC,QAAQ,CAAC,aAAa,IACnB,KAAK,EAAC,EAAE,EACR,WAAW,EAAC,WAAW,EACvB,IAAI,EAAC,OAAO,GACd,EACF,KAAC,QAAQ,CAAC,OAAO,cACZ,CAAC,EACE,KAAK,GAGR,EAAE,EAAE,CAAC,CACF,KAAC,QAAQ,CAAC,IAAI,cACT,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,KAAC,QAAQ,CAAC,IAAI,IACV,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,IAAI,YAGT,IAAI,CAAC,KAAK,IAFN,IAAI,CAAC,KAAK,CAGH,CACnB,CAAC,GACU,CACnB,GACc,IACL,GAChB,IACH,EAEX,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,gBAAgB,EAClC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,gBAAgB,EAC9B,iBAAiB,EAAE,YAAY,EAC/B,aAAa,EAAE,WAAW,GAC5B,GACC,GACM,EACjB,KAAC,MAAM,CAAC,MAAM,IAAC,MAAM,kBACjB,MAAC,IAAI,IACD,cAAc,EAAC,UAAU,EACzB,UAAU,EAAC,QAAQ,EACnB,GAAG,EAAC,GAAG,EACP,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAExB,KAAC,MAAM,IAAC,UAAU,EAAC,WAAW,EAAC,OAAO,EAAE,WAAW,uBAE1C,EACT,KAAC,MAAM,IAAC,UAAU,EAAC,SAAS,EAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,6BAE3D,IACN,GACK,IACX,CACZ,CAAC;IAEF,IAAI,mBAAmB,EAAE,CAAC;QACtB,OAAO,YAAY,CAAC,KAAC,aAAa,cAAE,MAAM,GAAiB,EAAE,mBAAmB,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
|
|
@@ -3,21 +3,22 @@ import { TextField } from '@servicetitan/anvil2';
|
|
|
3
3
|
import { SelectField, SelectFieldSync } from '@servicetitan/anvil2/beta';
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { useLookupOptions } from './useLookupOptions';
|
|
6
|
-
const toOption = (option)=>({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const toOption = (option) => ({
|
|
7
|
+
id: option.key,
|
|
8
|
+
label: option.label,
|
|
9
|
+
});
|
|
10
10
|
/*
|
|
11
11
|
* Searchable sources return nothing until the user types, which would make the
|
|
12
12
|
* dropdown show its built-in "No match found" empty state on open — confusing
|
|
13
13
|
* before any search has happened. Render a disabled hint instead so the list is
|
|
14
14
|
* never mistaken for "no results".
|
|
15
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
const SEARCH_HINT_OPTION = {
|
|
16
17
|
id: '__lookup_search_hint__',
|
|
17
18
|
label: 'Start typing to search…',
|
|
18
|
-
disabled: true
|
|
19
|
+
disabled: true,
|
|
19
20
|
};
|
|
20
|
-
const sanitizeNumericInput = (raw)=>{
|
|
21
|
+
const sanitizeNumericInput = (raw) => {
|
|
21
22
|
let value = raw.replaceAll(/[^0-9.-]/g, '');
|
|
22
23
|
const isNegative = value.startsWith('-');
|
|
23
24
|
value = value.replaceAll('-', '');
|
|
@@ -39,66 +40,48 @@ const sanitizeNumericInput = (raw)=>{
|
|
|
39
40
|
* Unlayer persists conditions as a Nunjucks string, so a saved searchable value
|
|
40
41
|
* has no stored label — we display the saved key as the label until the user
|
|
41
42
|
* re-searches and re-selects.
|
|
42
|
-
*/
|
|
43
|
+
*/
|
|
44
|
+
export function LookupValueControl({ fieldType, lookupSource, onChange, value, }) {
|
|
43
45
|
const { loadOptions, options, resolveOptions, status } = useLookupOptions(lookupSource);
|
|
44
|
-
const staticOptions = useMemo(()=>options.map(toOption), [
|
|
45
|
-
options
|
|
46
|
-
]);
|
|
46
|
+
const staticOptions = useMemo(() => options.map(toOption), [options]);
|
|
47
47
|
/*
|
|
48
48
|
* Fall back to the raw value so a saved key that the host omits from its list
|
|
49
49
|
* (e.g. an inactive/renamed option) still shows on edit instead of vanishing.
|
|
50
|
-
*/
|
|
51
|
-
|
|
50
|
+
*/
|
|
51
|
+
const staticSelected = useMemo(() => {
|
|
52
|
+
var _a;
|
|
52
53
|
if (!value) {
|
|
53
54
|
return null;
|
|
54
55
|
}
|
|
55
|
-
return (
|
|
56
|
-
|
|
57
|
-
label: value
|
|
58
|
-
};
|
|
59
|
-
}, [
|
|
60
|
-
staticOptions,
|
|
61
|
-
value
|
|
62
|
-
]);
|
|
56
|
+
return ((_a = staticOptions.find(option => String(option.id) === value)) !== null && _a !== void 0 ? _a : { id: value, label: value });
|
|
57
|
+
}, [staticOptions, value]);
|
|
63
58
|
/*
|
|
64
59
|
* Ensure the saved value is present in the list so it is visible/selectable
|
|
65
60
|
* even when the host did not return it.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
];
|
|
61
|
+
*/
|
|
62
|
+
const staticOptionsWithSelected = useMemo(() => {
|
|
63
|
+
if (staticSelected &&
|
|
64
|
+
!staticOptions.some(option => String(option.id) === String(staticSelected.id))) {
|
|
65
|
+
return [staticSelected, ...staticOptions];
|
|
72
66
|
}
|
|
73
67
|
return staticOptions;
|
|
74
|
-
}, [
|
|
75
|
-
|
|
76
|
-
staticSelected
|
|
77
|
-
]);
|
|
78
|
-
const [searchableSelected, setSearchableSelected] = useState(value ? {
|
|
79
|
-
id: value,
|
|
80
|
-
label: value
|
|
81
|
-
} : null);
|
|
68
|
+
}, [staticOptions, staticSelected]);
|
|
69
|
+
const [searchableSelected, setSearchableSelected] = useState(value ? { id: value, label: value } : null);
|
|
82
70
|
// Tracks the key we've already turned into a human-readable label so we don't re-resolve it.
|
|
83
71
|
const resolvedKeyRef = useRef(null);
|
|
84
|
-
useEffect(()=>{
|
|
85
|
-
setSearchableSelected(
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
setSearchableSelected(prev => {
|
|
86
74
|
if (!value) {
|
|
87
75
|
return null;
|
|
88
76
|
}
|
|
89
77
|
if ((prev === null || prev === void 0 ? void 0 : prev.id) === value) {
|
|
90
78
|
return prev;
|
|
91
79
|
}
|
|
92
|
-
return {
|
|
93
|
-
id: value,
|
|
94
|
-
label: value
|
|
95
|
-
};
|
|
80
|
+
return { id: value, label: value };
|
|
96
81
|
});
|
|
97
|
-
}, [
|
|
98
|
-
value
|
|
99
|
-
]);
|
|
82
|
+
}, [value]);
|
|
100
83
|
// On open (or when a saved searchable value appears), ask the host to resolve key -> label.
|
|
101
|
-
useEffect(()=>{
|
|
84
|
+
useEffect(() => {
|
|
102
85
|
if (status !== 'searchable' || !value) {
|
|
103
86
|
resolvedKeyRef.current = null;
|
|
104
87
|
return;
|
|
@@ -107,90 +90,44 @@ const sanitizeNumericInput = (raw)=>{
|
|
|
107
90
|
return;
|
|
108
91
|
}
|
|
109
92
|
let cancelled = false;
|
|
110
|
-
resolveOptions([
|
|
111
|
-
value
|
|
112
|
-
]).then((result)=>{
|
|
93
|
+
resolveOptions([value]).then(result => {
|
|
113
94
|
if (cancelled) {
|
|
114
95
|
return;
|
|
115
96
|
}
|
|
116
|
-
const match = result.find(
|
|
97
|
+
const match = result.find(option => option.key === value);
|
|
117
98
|
if (match) {
|
|
118
99
|
resolvedKeyRef.current = value;
|
|
119
|
-
setSearchableSelected({
|
|
120
|
-
id: match.key,
|
|
121
|
-
label: match.label
|
|
122
|
-
});
|
|
100
|
+
setSearchableSelected({ id: match.key, label: match.label });
|
|
123
101
|
}
|
|
124
102
|
});
|
|
125
|
-
return ()=>{
|
|
103
|
+
return () => {
|
|
126
104
|
cancelled = true;
|
|
127
105
|
};
|
|
128
|
-
}, [
|
|
129
|
-
|
|
130
|
-
value,
|
|
131
|
-
resolveOptions
|
|
132
|
-
]);
|
|
133
|
-
const handleLoadOptions = useCallback(async (query)=>{
|
|
106
|
+
}, [status, value, resolveOptions]);
|
|
107
|
+
const handleLoadOptions = useCallback(async (query) => {
|
|
134
108
|
if (!query.trim()) {
|
|
135
|
-
return [
|
|
136
|
-
SEARCH_HINT_OPTION
|
|
137
|
-
];
|
|
109
|
+
return [SEARCH_HINT_OPTION];
|
|
138
110
|
}
|
|
139
111
|
const result = await loadOptions(query);
|
|
140
112
|
return result.map(toOption);
|
|
141
|
-
}, [
|
|
142
|
-
loadOptions
|
|
143
|
-
]);
|
|
113
|
+
}, [loadOptions]);
|
|
144
114
|
if (status === 'loading') {
|
|
145
|
-
return
|
|
146
|
-
label: "Value",
|
|
147
|
-
flex: 1,
|
|
148
|
-
disabled: true,
|
|
149
|
-
value: "",
|
|
150
|
-
placeholder: "",
|
|
151
|
-
"aria-label": "Value"
|
|
152
|
-
});
|
|
115
|
+
return (_jsx(TextField, { label: "Value", flex: 1, disabled: true, value: "", placeholder: "", "aria-label": "Value" }));
|
|
153
116
|
}
|
|
154
117
|
if (status === 'static') {
|
|
155
|
-
return
|
|
156
|
-
flex: 1,
|
|
157
|
-
label: "Value",
|
|
158
|
-
placeholder: "Search value...",
|
|
159
|
-
options: staticOptionsWithSelected,
|
|
160
|
-
value: staticSelected,
|
|
161
|
-
onSelectedOptionChange: (option)=>onChange(option ? String(option.id) : '')
|
|
162
|
-
});
|
|
118
|
+
return (_jsx(SelectFieldSync, { flex: 1, label: "Value", placeholder: "Search value...", options: staticOptionsWithSelected, value: staticSelected, onSelectedOptionChange: option => onChange(option ? String(option.id) : '') }));
|
|
163
119
|
}
|
|
164
120
|
if (status === 'searchable') {
|
|
165
|
-
return
|
|
166
|
-
flex: 1,
|
|
167
|
-
label: "Value",
|
|
168
|
-
placeholder: "Type to search...",
|
|
169
|
-
initialLoad: "open",
|
|
170
|
-
loadOptions: handleLoadOptions,
|
|
171
|
-
value: searchableSelected,
|
|
172
|
-
onSelectedOptionChange: (option)=>{
|
|
121
|
+
return (_jsx(SelectField, { flex: 1, label: "Value", placeholder: "Type to search...", initialLoad: "open", loadOptions: handleLoadOptions, value: searchableSelected, onSelectedOptionChange: option => {
|
|
173
122
|
resolvedKeyRef.current = option ? String(option.id) : null;
|
|
174
123
|
setSearchableSelected(option);
|
|
175
124
|
onChange(option ? String(option.id) : '');
|
|
176
|
-
}
|
|
177
|
-
});
|
|
125
|
+
} }));
|
|
178
126
|
}
|
|
179
127
|
// idle / fallback (no source, empty, error, or timeout) -> free text.
|
|
180
|
-
const handleTextChange = (raw)=>{
|
|
128
|
+
const handleTextChange = (raw) => {
|
|
181
129
|
onChange(fieldType === 'number' ? sanitizeNumericInput(raw) : raw);
|
|
182
130
|
};
|
|
183
|
-
return
|
|
184
|
-
label: "Value",
|
|
185
|
-
flex: 1,
|
|
186
|
-
value: value,
|
|
187
|
-
onChange: (e)=>handleTextChange(e.target.value),
|
|
188
|
-
placeholder: fieldType === 'number' ? 'e.g. 1.5' : 'Enter value...',
|
|
189
|
-
"aria-label": "Value",
|
|
190
|
-
...fieldType === 'number' && {
|
|
191
|
-
inputMode: 'decimal'
|
|
192
|
-
}
|
|
193
|
-
});
|
|
131
|
+
return (_jsx(TextField, { label: "Value", flex: 1, value: value, onChange: e => handleTextChange(e.target.value), placeholder: fieldType === 'number' ? 'e.g. 1.5' : 'Enter value...', "aria-label": "Value", ...(fieldType === 'number' && { inputMode: 'decimal' }) }));
|
|
194
132
|
}
|
|
195
|
-
|
|
196
133
|
//# sourceMappingURL=LookupValueControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/display-conditions/LookupValueControl.tsx"],"sourcesContent":["import { TextField } from '@servicetitan/anvil2';\nimport { SelectField, SelectFieldOption, SelectFieldSync } from '@servicetitan/anvil2/beta';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { LookupOption } from './lookupOptionsController';\nimport { useLookupOptions } from './useLookupOptions';\n\nexport interface LookupValueControlProps {\n value: string;\n fieldType: 'number' | 'string';\n /** The selected data point's `options.fieldLookupSource`; empty -> free-text input. */\n lookupSource?: string;\n onChange: (value: string) => void;\n}\n\nconst toOption = (option: LookupOption): SelectFieldOption => ({\n id: option.key,\n label: option.label,\n});\n\n/*\n * Searchable sources return nothing until the user types, which would make the\n * dropdown show its built-in \"No match found\" empty state on open — confusing\n * before any search has happened. Render a disabled hint instead so the list is\n * never mistaken for \"no results\".\n */\nconst SEARCH_HINT_OPTION: SelectFieldOption = {\n id: '__lookup_search_hint__',\n label: 'Start typing to search…',\n disabled: true,\n};\n\nconst sanitizeNumericInput = (raw: string): string => {\n let value = raw.replaceAll(/[^0-9.-]/g, '');\n const isNegative = value.startsWith('-');\n value = value.replaceAll('-', '');\n if (isNegative) {\n value = `-${value}`;\n }\n const firstDot = value.indexOf('.');\n if (firstDot >= 0) {\n value = `${value.slice(0, firstDot + 1)}${value.slice(firstDot + 1).replaceAll('.', '')}`;\n }\n return value;\n};\n\n/**\n * Renders the value control for a single condition based on the field's lookup source:\n * - `static` -> full list returned by the host, filtered locally (`SelectFieldSync`).\n * - `searchable` -> host searches per typed query (`SelectField` + `loadOptions`).\n * - `idle`/`fallback`/`loading` -> free-text input (never block the user).\n *\n * Unlayer persists conditions as a Nunjucks string, so a saved searchable value\n * has no stored label — we display the saved key as the label until the user\n * re-searches and re-selects.\n */\nexport function LookupValueControl({\n fieldType,\n lookupSource,\n onChange,\n value,\n}: Readonly<LookupValueControlProps>) {\n const { loadOptions, options, resolveOptions, status } = useLookupOptions(lookupSource);\n\n const staticOptions = useMemo<SelectFieldOption[]>(() => options.map(toOption), [options]);\n\n /*\n * Fall back to the raw value so a saved key that the host omits from its list\n * (e.g. an inactive/renamed option) still shows on edit instead of vanishing.\n */\n const staticSelected = useMemo<SelectFieldOption | null>(() => {\n if (!value) {\n return null;\n }\n return (\n staticOptions.find(option => String(option.id) === value) ?? { id: value, label: value }\n );\n }, [staticOptions, value]);\n\n /*\n * Ensure the saved value is present in the list so it is visible/selectable\n * even when the host did not return it.\n */\n const staticOptionsWithSelected = useMemo<SelectFieldOption[]>(() => {\n if (\n staticSelected &&\n !staticOptions.some(option => String(option.id) === String(staticSelected.id))\n ) {\n return [staticSelected, ...staticOptions];\n }\n return staticOptions;\n }, [staticOptions, staticSelected]);\n\n const [searchableSelected, setSearchableSelected] = useState<SelectFieldOption | null>(\n value ? { id: value, label: value } : null,\n );\n\n // Tracks the key we've already turned into a human-readable label so we don't re-resolve it.\n const resolvedKeyRef = useRef<string | null>(null);\n\n useEffect(() => {\n setSearchableSelected(prev => {\n if (!value) {\n return null;\n }\n if (prev?.id === value) {\n return prev;\n }\n return { id: value, label: value };\n });\n }, [value]);\n\n // On open (or when a saved searchable value appears), ask the host to resolve key -> label.\n useEffect(() => {\n if (status !== 'searchable' || !value) {\n resolvedKeyRef.current = null;\n return;\n }\n if (resolvedKeyRef.current === value) {\n return;\n }\n\n let cancelled = false;\n resolveOptions([value]).then(result => {\n if (cancelled) {\n return;\n }\n const match = result.find(option => option.key === value);\n if (match) {\n resolvedKeyRef.current = value;\n setSearchableSelected({ id: match.key, label: match.label });\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [status, value, resolveOptions]);\n\n const handleLoadOptions = useCallback(\n async (query: string) => {\n if (!query.trim()) {\n return [SEARCH_HINT_OPTION];\n }\n const result = await loadOptions(query);\n return result.map(toOption);\n },\n [loadOptions],\n );\n\n if (status === 'loading') {\n return (\n <TextField label=\"Value\" flex={1} disabled value=\"\" placeholder=\"\" aria-label=\"Value\" />\n );\n }\n\n if (status === 'static') {\n return (\n <SelectFieldSync\n flex={1}\n label=\"Value\"\n placeholder=\"Search value...\"\n options={staticOptionsWithSelected}\n value={staticSelected}\n onSelectedOptionChange={option => onChange(option ? String(option.id) : '')}\n />\n );\n }\n\n if (status === 'searchable') {\n return (\n <SelectField\n flex={1}\n label=\"Value\"\n placeholder=\"Type to search...\"\n initialLoad=\"open\"\n loadOptions={handleLoadOptions}\n value={searchableSelected}\n onSelectedOptionChange={option => {\n resolvedKeyRef.current = option ? String(option.id) : null;\n setSearchableSelected(option);\n onChange(option ? String(option.id) : '');\n }}\n />\n );\n }\n\n // idle / fallback (no source, empty, error, or timeout) -> free text.\n const handleTextChange = (raw: string) => {\n onChange(fieldType === 'number' ? sanitizeNumericInput(raw) : raw);\n };\n\n return (\n <TextField\n label=\"Value\"\n flex={1}\n value={value}\n onChange={e => handleTextChange(e.target.value)}\n placeholder={fieldType === 'number' ? 'e.g. 1.5' : 'Enter value...'}\n aria-label=\"Value\"\n {...(fieldType === 'number' && { inputMode: 'decimal' })}\n />\n );\n}\n"],"names":["TextField","SelectField","SelectFieldSync","useCallback","useEffect","useMemo","useRef","useState","useLookupOptions","toOption","option","id","key","label","SEARCH_HINT_OPTION","disabled","sanitizeNumericInput","raw","value","replaceAll","isNegative","startsWith","firstDot","indexOf","slice","LookupValueControl","fieldType","lookupSource","onChange","loadOptions","options","resolveOptions","status","staticOptions","map","staticSelected","find","String","staticOptionsWithSelected","some","searchableSelected","setSearchableSelected","resolvedKeyRef","prev","current","cancelled","then","result","match","handleLoadOptions","query","trim","flex","placeholder","aria-label","onSelectedOptionChange","initialLoad","handleTextChange","e","target","inputMode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LookupValueControl.js","sourceRoot":"","sources":["../../src/display-conditions/LookupValueControl.tsx"],"names":[],"mappings":"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"}
|