@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.
Files changed (147) hide show
  1. package/dist/api-core.js +22 -29
  2. package/dist/api-core.js.map +1 -1
  3. package/dist/api-custom-tools.js +23 -29
  4. package/dist/api-custom-tools.js.map +1 -1
  5. package/dist/business-calendar/BusinessCalendarDrawer.d.ts +19 -0
  6. package/dist/business-calendar/BusinessCalendarDrawer.d.ts.map +1 -0
  7. package/dist/business-calendar/BusinessCalendarDrawer.js +41 -0
  8. package/dist/business-calendar/BusinessCalendarDrawer.js.map +1 -0
  9. package/dist/business-calendar/business-calendar-requests.d.ts +25 -0
  10. package/dist/business-calendar/business-calendar-requests.d.ts.map +1 -0
  11. package/dist/business-calendar/business-calendar-requests.js +46 -0
  12. package/dist/business-calendar/business-calendar-requests.js.map +1 -0
  13. package/dist/business-calendar/business-calendar-state.d.ts +22 -0
  14. package/dist/business-calendar/business-calendar-state.d.ts.map +1 -0
  15. package/dist/business-calendar/business-calendar-state.js +74 -0
  16. package/dist/business-calendar/business-calendar-state.js.map +1 -0
  17. package/dist/business-calendar/useBusinessCalendarRequests.d.ts +15 -0
  18. package/dist/business-calendar/useBusinessCalendarRequests.d.ts.map +1 -0
  19. package/dist/business-calendar/useBusinessCalendarRequests.js +30 -0
  20. package/dist/business-calendar/useBusinessCalendarRequests.js.map +1 -0
  21. package/dist/display-conditions/ConditionGroup.js +15 -89
  22. package/dist/display-conditions/ConditionGroup.js.map +1 -1
  23. package/dist/display-conditions/ConditionGroupsSection.js +2 -70
  24. package/dist/display-conditions/ConditionGroupsSection.js.map +1 -1
  25. package/dist/display-conditions/ConditionRow.js +63 -205
  26. package/dist/display-conditions/ConditionRow.js.map +1 -1
  27. package/dist/display-conditions/DisplayConditionModal.js +40 -190
  28. package/dist/display-conditions/DisplayConditionModal.js.map +1 -1
  29. package/dist/display-conditions/LookupValueControl.js +42 -105
  30. package/dist/display-conditions/LookupValueControl.js.map +1 -1
  31. package/dist/display-conditions/SeparatorWithChip.js +1 -10
  32. package/dist/display-conditions/SeparatorWithChip.js.map +1 -1
  33. package/dist/display-conditions/constants.js +15 -20
  34. package/dist/display-conditions/constants.js.map +1 -1
  35. package/dist/display-conditions/displayConditionController.js +5 -8
  36. package/dist/display-conditions/displayConditionController.js.map +1 -1
  37. package/dist/display-conditions/lookupOptionsController.js +16 -16
  38. package/dist/display-conditions/lookupOptionsController.js.map +1 -1
  39. package/dist/display-conditions/nunjucks.js +98 -116
  40. package/dist/display-conditions/nunjucks.js.map +1 -1
  41. package/dist/display-conditions/schemaDataPoints.js +13 -11
  42. package/dist/display-conditions/schemaDataPoints.js.map +1 -1
  43. package/dist/display-conditions/types.js +23 -67
  44. package/dist/display-conditions/types.js.map +1 -1
  45. package/dist/display-conditions/useConditionForms.js +38 -56
  46. package/dist/display-conditions/useConditionForms.js.map +1 -1
  47. package/dist/display-conditions/useLookupOptions.js +24 -44
  48. package/dist/display-conditions/useLookupOptions.js.map +1 -1
  49. package/dist/e-sign-offset/ESignDateSignedOffsetModal.js +37 -150
  50. package/dist/e-sign-offset/ESignDateSignedOffsetModal.js.map +1 -1
  51. package/dist/e-sign-offset/ESignOffsetRuleRow.js +12 -73
  52. package/dist/e-sign-offset/ESignOffsetRuleRow.js.map +1 -1
  53. package/dist/e-sign-offset/eSignOffsetController.js +5 -8
  54. package/dist/e-sign-offset/eSignOffsetController.js.map +1 -1
  55. package/dist/editor-core-source.d.ts +2 -2
  56. package/dist/editor-core-source.d.ts.map +1 -1
  57. package/dist/editor-core-source.js +3 -3
  58. package/dist/editor-core-source.js.map +1 -1
  59. package/dist/editor-core.js +2 -2
  60. package/dist/editor-core.js.map +1 -1
  61. package/dist/editor.d.ts.map +1 -1
  62. package/dist/editor.js +56 -118
  63. package/dist/editor.js.map +1 -1
  64. package/dist/image-upload-error.js +3 -3
  65. package/dist/image-upload-error.js.map +1 -1
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +0 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/loadScript.js +7 -8
  71. package/dist/loadScript.js.map +1 -1
  72. package/dist/log.js +2 -3
  73. package/dist/log.js.map +1 -1
  74. package/dist/merge-tags.js +18 -17
  75. package/dist/merge-tags.js.map +1 -1
  76. package/dist/shared/configs.js +1 -2
  77. package/dist/shared/configs.js.map +1 -1
  78. package/dist/shared/const.d.ts +70 -0
  79. package/dist/shared/const.d.ts.map +1 -1
  80. package/dist/shared/const.js +13 -4
  81. package/dist/shared/const.js.map +1 -1
  82. package/dist/shared/date-calc.js +47 -38
  83. package/dist/shared/date-calc.js.map +1 -1
  84. package/dist/shared/e-sign-offset.js +46 -63
  85. package/dist/shared/e-sign-offset.js.map +1 -1
  86. package/dist/shared/edit-icon.js +0 -1
  87. package/dist/shared/edit-icon.js.map +1 -1
  88. package/dist/shared/fonts.js +16 -17
  89. package/dist/shared/fonts.js.map +1 -1
  90. package/dist/shared/forms.js +16 -38
  91. package/dist/shared/forms.js.map +1 -1
  92. package/dist/shared/instance-id.js +6 -9
  93. package/dist/shared/instance-id.js.map +1 -1
  94. package/dist/shared/nunjucks-helpers.js +2 -5
  95. package/dist/shared/nunjucks-helpers.js.map +1 -1
  96. package/dist/shared/schema.js +52 -96
  97. package/dist/shared/schema.js.map +1 -1
  98. package/dist/shared/tools.js +6 -13
  99. package/dist/shared/tools.js.map +1 -1
  100. package/dist/store.d.ts +15 -1
  101. package/dist/store.d.ts.map +1 -1
  102. package/dist/store.js +851 -548
  103. package/dist/store.js.map +1 -1
  104. package/dist/tools.js +133 -143
  105. package/dist/tools.js.map +1 -1
  106. package/dist/unlayer-interface.d.ts +15 -4
  107. package/dist/unlayer-interface.d.ts.map +1 -1
  108. package/dist/unlayer-interface.js +1 -2
  109. package/dist/unlayer-interface.js.map +1 -1
  110. package/dist/unlayer.js +86 -113
  111. package/dist/unlayer.js.map +1 -1
  112. package/dist/vendor/dte-shared/business-calendar-validation.utils.d.ts +25 -0
  113. package/dist/vendor/dte-shared/business-calendar-validation.utils.js +80 -0
  114. package/dist/vendor/dte-shared/components/business-calendar-section.d.ts +15 -0
  115. package/dist/vendor/dte-shared/components/business-calendar-section.js +14 -0
  116. package/dist/vendor/dte-shared/components/schedule-drawer.d.ts +18 -0
  117. package/dist/vendor/dte-shared/components/schedule-drawer.js +119 -0
  118. package/dist/vendor/dte-shared/components/schedule-picker.d.ts +8 -0
  119. package/dist/vendor/dte-shared/components/schedule-picker.js +88 -0
  120. package/dist/vendor/dte-shared/constants.d.ts +31 -0
  121. package/dist/vendor/dte-shared/constants.js +34 -0
  122. package/dist/vendor/dte-shared/field-schedule-editor-context.d.ts +31 -0
  123. package/dist/vendor/dte-shared/field-schedule-editor-context.js +110 -0
  124. package/dist/vendor/dte-shared/index.d.ts +8 -0
  125. package/dist/vendor/dte-shared/index.js +7 -0
  126. package/dist/vendor/dte-shared/schedule-bindings.utils.d.ts +22 -0
  127. package/dist/vendor/dte-shared/schedule-bindings.utils.js +31 -0
  128. package/dist/vendor/dte-shared/styles/schedule.css +19 -0
  129. package/dist/vendor/dte-shared/types.d.ts +129 -0
  130. package/dist/vendor/dte-shared/types.js +1 -0
  131. package/package.json +7 -1
  132. package/src/__tests__/business-calendar-drawer.test.tsx +183 -0
  133. package/src/__tests__/business-calendar-requests.test.ts +166 -0
  134. package/src/__tests__/business-calendar-state.test.tsx +142 -0
  135. package/src/__tests__/store.business-calendar.test.ts +185 -0
  136. package/src/__tests__/unlayer.e-sign-types.test.ts +30 -0
  137. package/src/business-calendar/BusinessCalendarDrawer.tsx +76 -0
  138. package/src/business-calendar/business-calendar-requests.ts +80 -0
  139. package/src/business-calendar/business-calendar-state.ts +113 -0
  140. package/src/business-calendar/useBusinessCalendarRequests.ts +49 -0
  141. package/src/editor-core-source.ts +2 -2
  142. package/src/editor.tsx +15 -0
  143. package/src/index.ts +10 -0
  144. package/src/shared/const.ts +59 -0
  145. package/src/store.ts +67 -5
  146. package/src/unlayer-interface.tsx +15 -4
  147. 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
- label: 'Show',
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((c)=>c.logicalOperator === 'or');
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
- onConditionFormSelect,
56
- onConditionalsOpen
57
- });
58
- const dataPointOptions = useMemo(()=>getSchemaDataPointOptions(schema), [
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
- loadForms
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
- } else {
72
+ }
73
+ else {
95
74
  request.done(null);
96
75
  }
97
76
  setRequest(null);
98
77
  setIsOpen(false);
99
- }, [
100
- matchType,
101
- request,
102
- state
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
- var _BEHAVIOR_OPTIONS_find;
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((prev)=>({
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
- requestFormFields
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 = (_ref = (_allFieldOptions_find = allFieldOptions.find((opt)=>opt.fullKey === condition.dataPointKey)) === null || _allFieldOptions_find === void 0 ? void 0 : _allFieldOptions_find.fieldType) !== null && _ref !== void 0 ? _ref : 'string';
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
- */ const dialog = /*#__PURE__*/ _jsxs(Dialog, {
173
- open: isOpen,
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 /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsx(ThemeProvider, {
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":"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"}
1
+ {"version":3,"file":"DisplayConditionModal.js","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"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"}
@@ -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
- id: option.key,
8
- label: option.label
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
- */ const SEARCH_HINT_OPTION = {
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
- */ export function LookupValueControl({ fieldType, lookupSource, onChange, value }) {
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
- */ const staticSelected = useMemo(()=>{
51
- var _staticOptions_find;
50
+ */
51
+ const staticSelected = useMemo(() => {
52
+ var _a;
52
53
  if (!value) {
53
54
  return null;
54
55
  }
55
- return (_staticOptions_find = staticOptions.find((option)=>String(option.id) === value)) !== null && _staticOptions_find !== void 0 ? _staticOptions_find : {
56
- id: value,
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
- */ const staticOptionsWithSelected = useMemo(()=>{
67
- if (staticSelected && !staticOptions.some((option)=>String(option.id) === String(staticSelected.id))) {
68
- return [
69
- staticSelected,
70
- ...staticOptions
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
- staticOptions,
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((prev)=>{
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((option)=>option.key === value);
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
- status,
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 /*#__PURE__*/ _jsx(TextField, {
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 /*#__PURE__*/ _jsx(SelectFieldSync, {
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 /*#__PURE__*/ _jsx(SelectField, {
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 /*#__PURE__*/ _jsx(TextField, {
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":";AAAA,SAASA,SAAS,QAAQ,uBAAuB;AACjD,SAASC,WAAW,EAAqBC,eAAe,QAAQ,4BAA4B;AAC5F,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAE1E,SAASC,gBAAgB,QAAQ,qBAAqB;AAUtD,MAAMC,WAAW,CAACC,SAA6C,CAAA;QAC3DC,IAAID,OAAOE,GAAG;QACdC,OAAOH,OAAOG,KAAK;IACvB,CAAA;AAEA;;;;;CAKC,GACD,MAAMC,qBAAwC;IAC1CH,IAAI;IACJE,OAAO;IACPE,UAAU;AACd;AAEA,MAAMC,uBAAuB,CAACC;IAC1B,IAAIC,QAAQD,IAAIE,UAAU,CAAC,aAAa;IACxC,MAAMC,aAAaF,MAAMG,UAAU,CAAC;IACpCH,QAAQA,MAAMC,UAAU,CAAC,KAAK;IAC9B,IAAIC,YAAY;QACZF,QAAQ,CAAC,CAAC,EAAEA,OAAO;IACvB;IACA,MAAMI,WAAWJ,MAAMK,OAAO,CAAC;IAC/B,IAAID,YAAY,GAAG;QACfJ,QAAQ,GAAGA,MAAMM,KAAK,CAAC,GAAGF,WAAW,KAAKJ,MAAMM,KAAK,CAACF,WAAW,GAAGH,UAAU,CAAC,KAAK,KAAK;IAC7F;IACA,OAAOD;AACX;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASO,mBAAmB,EAC/BC,SAAS,EACTC,YAAY,EACZC,QAAQ,EACRV,KAAK,EAC2B;IAChC,MAAM,EAAEW,WAAW,EAAEC,OAAO,EAAEC,cAAc,EAAEC,MAAM,EAAE,GAAGxB,iBAAiBmB;IAE1E,MAAMM,gBAAgB5B,QAA6B,IAAMyB,QAAQI,GAAG,CAACzB,WAAW;QAACqB;KAAQ;IAEzF;;;KAGC,GACD,MAAMK,iBAAiB9B,QAAkC;YAKjD4B;QAJJ,IAAI,CAACf,OAAO;YACR,OAAO;QACX;QACA,QACIe,sBAAAA,cAAcG,IAAI,CAAC1B,CAAAA,SAAU2B,OAAO3B,OAAOC,EAAE,MAAMO,oBAAnDe,iCAAAA,sBAA6D;YAAEtB,IAAIO;YAAOL,OAAOK;QAAM;IAE/F,GAAG;QAACe;QAAef;KAAM;IAEzB;;;KAGC,GACD,MAAMoB,4BAA4BjC,QAA6B;QAC3D,IACI8B,kBACA,CAACF,cAAcM,IAAI,CAAC7B,CAAAA,SAAU2B,OAAO3B,OAAOC,EAAE,MAAM0B,OAAOF,eAAexB,EAAE,IAC9E;YACE,OAAO;gBAACwB;mBAAmBF;aAAc;QAC7C;QACA,OAAOA;IACX,GAAG;QAACA;QAAeE;KAAe;IAElC,MAAM,CAACK,oBAAoBC,sBAAsB,GAAGlC,SAChDW,QAAQ;QAAEP,IAAIO;QAAOL,OAAOK;IAAM,IAAI;IAG1C,6FAA6F;IAC7F,MAAMwB,iBAAiBpC,OAAsB;IAE7CF,UAAU;QACNqC,sBAAsBE,CAAAA;YAClB,IAAI,CAACzB,OAAO;gBACR,OAAO;YACX;YACA,IAAIyB,CAAAA,iBAAAA,2BAAAA,KAAMhC,EAAE,MAAKO,OAAO;gBACpB,OAAOyB;YACX;YACA,OAAO;gBAAEhC,IAAIO;gBAAOL,OAAOK;YAAM;QACrC;IACJ,GAAG;QAACA;KAAM;IAEV,4FAA4F;IAC5Fd,UAAU;QACN,IAAI4B,WAAW,gBAAgB,CAACd,OAAO;YACnCwB,eAAeE,OAAO,GAAG;YACzB;QACJ;QACA,IAAIF,eAAeE,OAAO,KAAK1B,OAAO;YAClC;QACJ;QAEA,IAAI2B,YAAY;QAChBd,eAAe;YAACb;SAAM,EAAE4B,IAAI,CAACC,CAAAA;YACzB,IAAIF,WAAW;gBACX;YACJ;YACA,MAAMG,QAAQD,OAAOX,IAAI,CAAC1B,CAAAA,SAAUA,OAAOE,GAAG,KAAKM;YACnD,IAAI8B,OAAO;gBACPN,eAAeE,OAAO,GAAG1B;gBACzBuB,sBAAsB;oBAAE9B,IAAIqC,MAAMpC,GAAG;oBAAEC,OAAOmC,MAAMnC,KAAK;gBAAC;YAC9D;QACJ;QAEA,OAAO;YACHgC,YAAY;QAChB;IACJ,GAAG;QAACb;QAAQd;QAAOa;KAAe;IAElC,MAAMkB,oBAAoB9C,YACtB,OAAO+C;QACH,IAAI,CAACA,MAAMC,IAAI,IAAI;YACf,OAAO;gBAACrC;aAAmB;QAC/B;QACA,MAAMiC,SAAS,MAAMlB,YAAYqB;QACjC,OAAOH,OAAOb,GAAG,CAACzB;IACtB,GACA;QAACoB;KAAY;IAGjB,IAAIG,WAAW,WAAW;QACtB,qBACI,KAAChC;YAAUa,OAAM;YAAQuC,MAAM;YAAGrC,QAAQ;YAACG,OAAM;YAAGmC,aAAY;YAAGC,cAAW;;IAEtF;IAEA,IAAItB,WAAW,UAAU;QACrB,qBACI,KAAC9B;YACGkD,MAAM;YACNvC,OAAM;YACNwC,aAAY;YACZvB,SAASQ;YACTpB,OAAOiB;YACPoB,wBAAwB7C,CAAAA,SAAUkB,SAASlB,SAAS2B,OAAO3B,OAAOC,EAAE,IAAI;;IAGpF;IAEA,IAAIqB,WAAW,cAAc;QACzB,qBACI,KAAC/B;YACGmD,MAAM;YACNvC,OAAM;YACNwC,aAAY;YACZG,aAAY;YACZ3B,aAAaoB;YACb/B,OAAOsB;YACPe,wBAAwB7C,CAAAA;gBACpBgC,eAAeE,OAAO,GAAGlC,SAAS2B,OAAO3B,OAAOC,EAAE,IAAI;gBACtD8B,sBAAsB/B;gBACtBkB,SAASlB,SAAS2B,OAAO3B,OAAOC,EAAE,IAAI;YAC1C;;IAGZ;IAEA,sEAAsE;IACtE,MAAM8C,mBAAmB,CAACxC;QACtBW,SAASF,cAAc,WAAWV,qBAAqBC,OAAOA;IAClE;IAEA,qBACI,KAACjB;QACGa,OAAM;QACNuC,MAAM;QACNlC,OAAOA;QACPU,UAAU8B,CAAAA,IAAKD,iBAAiBC,EAAEC,MAAM,CAACzC,KAAK;QAC9CmC,aAAa3B,cAAc,WAAW,aAAa;QACnD4B,cAAW;QACV,GAAI5B,cAAc,YAAY;YAAEkC,WAAW;QAAU,CAAC;;AAGnE"}
1
+ {"version":3,"file":"LookupValueControl.js","sourceRoot":"","sources":["../../src/display-conditions/LookupValueControl.tsx"],"names":[],"mappings":"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"}