@servicetitan/dte-unlayer 0.144.0 → 0.146.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 CHANGED
@@ -45,7 +45,7 @@ export class UnlayerCoreApi {
45
45
  try {
46
46
  var _dteTool_getModel;
47
47
  return (_dteTool_getModel = dteTool.getModel()) !== null && _dteTool_getModel !== void 0 ? _dteTool_getModel : {};
48
- } catch (e) {
48
+ } catch (unused) {
49
49
  return {};
50
50
  }
51
51
  }
@@ -57,7 +57,7 @@ export class UnlayerCoreApi {
57
57
  try {
58
58
  var _dteTool_dataSources;
59
59
  return (_dteTool_dataSources = dteTool.dataSources(tool.values)) !== null && _dteTool_dataSources !== void 0 ? _dteTool_dataSources : [];
60
- } catch (e) {
60
+ } catch (unused) {
61
61
  return [];
62
62
  }
63
63
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api-core.ts"],"sourcesContent":["import { editorCoreScript } from './editor-core';\nimport { loadScriptSource } from './loadScript';\nimport { UnlayerStore } from './shared/tools';\nimport { UnlayerDesignTool } from './unlayer-interface';\n\nconst dummyStore: UnlayerStore = {\n renderHtml() {\n return '';\n },\n sendData() {},\n getTool() {\n return undefined;\n },\n};\n\nexport class UnlayerCoreApi {\n private loaded = new Set<string>();\n\n private get dteStore(): UnlayerStore {\n return (window as any).dteStore ?? dummyStore;\n }\n\n clean() {\n this.loaded = new Set();\n }\n\n preloadCore() {\n if (this.loaded.has('_core')) {\n return;\n }\n this.loaded.add('_core');\n\n loadScriptSource(editorCoreScript);\n }\n\n getCustomToolModel(key: string): object {\n const dteTool = this.dteStore.getTool(key);\n\n if (!dteTool) {\n return {};\n }\n\n try {\n return dteTool.getModel() ?? {};\n } catch {\n return {};\n }\n }\n\n getToolDataSources(tool: UnlayerDesignTool): string[] {\n const dteTool = tool.slug ? this.dteStore.getTool(tool.slug) : undefined;\n\n if (!dteTool) {\n return [];\n }\n\n try {\n return dteTool.dataSources(tool.values) ?? [];\n } catch {\n return [];\n }\n }\n}\n"],"names":["editorCoreScript","loadScriptSource","dummyStore","renderHtml","sendData","getTool","undefined","UnlayerCoreApi","dteStore","window","clean","loaded","Set","preloadCore","has","add","getCustomToolModel","key","dteTool","getModel","getToolDataSources","tool","slug","dataSources","values"],"mappings":";;;;;;;;;;;;;AAAA,SAASA,gBAAgB,QAAQ,gBAAgB;AACjD,SAASC,gBAAgB,QAAQ,eAAe;AAIhD,MAAMC,aAA2B;IAC7BC;QACI,OAAO;IACX;IACAC,aAAY;IACZC;QACI,OAAOC;IACX;AACJ;AAEA,OAAO,MAAMC;IAGT,IAAYC,WAAyB;YAC1B;QAAP,OAAO,CAAA,mBAAA,AAACC,OAAeD,QAAQ,cAAxB,8BAAA,mBAA4BN;IACvC;IAEAQ,QAAQ;QACJ,IAAI,CAACC,MAAM,GAAG,IAAIC;IACtB;IAEAC,cAAc;QACV,IAAI,IAAI,CAACF,MAAM,CAACG,GAAG,CAAC,UAAU;YAC1B;QACJ;QACA,IAAI,CAACH,MAAM,CAACI,GAAG,CAAC;QAEhBd,iBAAiBD;IACrB;IAEAgB,mBAAmBC,GAAW,EAAU;QACpC,MAAMC,UAAU,IAAI,CAACV,QAAQ,CAACH,OAAO,CAACY;QAEtC,IAAI,CAACC,SAAS;YACV,OAAO,CAAC;QACZ;QAEA,IAAI;gBACOA;YAAP,OAAOA,CAAAA,oBAAAA,QAAQC,QAAQ,gBAAhBD,+BAAAA,oBAAsB,CAAC;QAClC,EAAE,UAAM;YACJ,OAAO,CAAC;QACZ;IACJ;IAEAE,mBAAmBC,IAAuB,EAAY;QAClD,MAAMH,UAAUG,KAAKC,IAAI,GAAG,IAAI,CAACd,QAAQ,CAACH,OAAO,CAACgB,KAAKC,IAAI,IAAIhB;QAE/D,IAAI,CAACY,SAAS;YACV,OAAO,EAAE;QACb;QAEA,IAAI;gBACOA;YAAP,OAAOA,CAAAA,uBAAAA,QAAQK,WAAW,CAACF,KAAKG,MAAM,eAA/BN,kCAAAA,uBAAoC,EAAE;QACjD,EAAE,UAAM;YACJ,OAAO,EAAE;QACb;IACJ;;QA7CA,uBAAQP,UAAS,IAAIC;;AA8CzB"}
1
+ {"version":3,"sources":["../src/api-core.ts"],"sourcesContent":["import { editorCoreScript } from './editor-core';\nimport { loadScriptSource } from './loadScript';\nimport { UnlayerStore } from './shared/tools';\nimport { UnlayerDesignTool } from './unlayer-interface';\n\nconst dummyStore: UnlayerStore = {\n renderHtml() {\n return '';\n },\n sendData() {},\n getTool() {\n return undefined;\n },\n};\n\nexport class UnlayerCoreApi {\n private loaded = new Set<string>();\n\n private get dteStore(): UnlayerStore {\n return (window as any).dteStore ?? dummyStore;\n }\n\n clean() {\n this.loaded = new Set();\n }\n\n preloadCore() {\n if (this.loaded.has('_core')) {\n return;\n }\n this.loaded.add('_core');\n\n loadScriptSource(editorCoreScript);\n }\n\n getCustomToolModel(key: string): object {\n const dteTool = this.dteStore.getTool(key);\n\n if (!dteTool) {\n return {};\n }\n\n try {\n return dteTool.getModel() ?? {};\n } catch {\n return {};\n }\n }\n\n getToolDataSources(tool: UnlayerDesignTool): string[] {\n const dteTool = tool.slug ? this.dteStore.getTool(tool.slug) : undefined;\n\n if (!dteTool) {\n return [];\n }\n\n try {\n return dteTool.dataSources(tool.values) ?? [];\n } catch {\n return [];\n }\n }\n}\n"],"names":["editorCoreScript","loadScriptSource","dummyStore","renderHtml","sendData","getTool","undefined","UnlayerCoreApi","dteStore","window","clean","loaded","Set","preloadCore","has","add","getCustomToolModel","key","dteTool","getModel","getToolDataSources","tool","slug","dataSources","values"],"mappings":";;;;;;;;;;;;;AAAA,SAASA,gBAAgB,QAAQ,gBAAgB;AACjD,SAASC,gBAAgB,QAAQ,eAAe;AAIhD,MAAMC,aAA2B;IAC7BC;QACI,OAAO;IACX;IACAC,aAAY;IACZC;QACI,OAAOC;IACX;AACJ;AAEA,OAAO,MAAMC;IAGT,IAAYC,WAAyB;YAC1B;QAAP,QAAO,mBAAA,AAACC,OAAeD,QAAQ,cAAxB,8BAAA,mBAA4BN;IACvC;IAEAQ,QAAQ;QACJ,IAAI,CAACC,MAAM,GAAG,IAAIC;IACtB;IAEAC,cAAc;QACV,IAAI,IAAI,CAACF,MAAM,CAACG,GAAG,CAAC,UAAU;YAC1B;QACJ;QACA,IAAI,CAACH,MAAM,CAACI,GAAG,CAAC;QAEhBd,iBAAiBD;IACrB;IAEAgB,mBAAmBC,GAAW,EAAU;QACpC,MAAMC,UAAU,IAAI,CAACV,QAAQ,CAACH,OAAO,CAACY;QAEtC,IAAI,CAACC,SAAS;YACV,OAAO,CAAC;QACZ;QAEA,IAAI;gBACOA;YAAP,QAAOA,oBAAAA,QAAQC,QAAQ,gBAAhBD,+BAAAA,oBAAsB,CAAC;QAClC,EAAE,eAAM;YACJ,OAAO,CAAC;QACZ;IACJ;IAEAE,mBAAmBC,IAAuB,EAAY;QAClD,MAAMH,UAAUG,KAAKC,IAAI,GAAG,IAAI,CAACd,QAAQ,CAACH,OAAO,CAACgB,KAAKC,IAAI,IAAIhB;QAE/D,IAAI,CAACY,SAAS;YACV,OAAO,EAAE;QACb;QAEA,IAAI;gBACOA;YAAP,QAAOA,uBAAAA,QAAQK,WAAW,CAACF,KAAKG,MAAM,eAA/BN,kCAAAA,uBAAoC,EAAE;QACjD,EAAE,eAAM;YACJ,OAAO,EAAE;QACb;IACJ;;QA7CA,uBAAQP,UAAS,IAAIC;;AA8CzB"}
@@ -6,6 +6,7 @@ import { parseFormFieldKey } from '../shared/forms';
6
6
  import { LookupValueControl } from './LookupValueControl';
7
7
  import { NUMBER_OPERATORS, STRING_OPERATORS, VALUE_LESS_OPERATORS } from './types';
8
8
  export function ConditionRow({ canRemove, condition, dataPointOptions, formFieldOptions, forms, onChange, onFormSelect, onRemove }) {
9
+ var _ref;
9
10
  const selectedFormFieldMeta = useMemo(()=>parseFormFieldKey(condition.dataPointKey), [
10
11
  condition.dataPointKey
11
12
  ]);
@@ -24,7 +25,7 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
24
25
  forms
25
26
  ]);
26
27
  const selectedSource = useMemo(()=>{
27
- var _sourceOptions_find, _ref;
28
+ var _ref, _sourceOptions_find;
28
29
  return (_ref = (_sourceOptions_find = sourceOptions.find((opt)=>opt.value === selectedSourceValue)) !== null && _sourceOptions_find !== void 0 ? _sourceOptions_find : sourceOptions[0]) !== null && _ref !== void 0 ? _ref : null;
29
30
  }, [
30
31
  selectedSourceValue,
@@ -60,8 +61,7 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
60
61
  activeDataPointOptions,
61
62
  condition.dataPointKey
62
63
  ]);
63
- var _selectedDataPoint_fieldType;
64
- const fieldType = (_selectedDataPoint_fieldType = selectedDataPoint === null || selectedDataPoint === void 0 ? void 0 : selectedDataPoint.fieldType) !== null && _selectedDataPoint_fieldType !== void 0 ? _selectedDataPoint_fieldType : 'string';
64
+ const fieldType = (_ref = selectedDataPoint === null || selectedDataPoint === void 0 ? void 0 : selectedDataPoint.fieldType) !== null && _ref !== void 0 ? _ref : 'string';
65
65
  const isValueLess = VALUE_LESS_OPERATORS.includes(condition.operator);
66
66
  const operatorItems = useMemo(()=>fieldType === 'number' ? [
67
67
  ...NUMBER_OPERATORS
@@ -78,33 +78,32 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
78
78
  condition.operator
79
79
  ]);
80
80
  const handleDataPointChange = (item)=>{
81
+ var _ref;
81
82
  const nextIsNumber = (item === null || item === void 0 ? void 0 : item.fieldType) === 'number';
82
83
  const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;
83
84
  const operatorReset = !nextOperatorItems.some((op)=>op.value === condition.operator);
84
- var _item_fullKey;
85
85
  onChange({
86
86
  ...condition,
87
- dataPointKey: (_item_fullKey = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _item_fullKey !== void 0 ? _item_fullKey : '',
87
+ dataPointKey: (_ref = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _ref !== void 0 ? _ref : '',
88
88
  operator: operatorReset ? nextIsNumber ? 'num_eq' : 'is_equal_to' : condition.operator
89
89
  });
90
90
  };
91
91
  const handleSourceChange = (item)=>{
92
+ var _ref, _ref1, _ref2;
92
93
  if (!item) {
93
94
  return;
94
95
  }
95
96
  setSelectedSourceValue(item.value);
96
97
  if (!item.formId) {
97
- var _dataPointOptions_find;
98
+ var _dataPointOptions_find, _ref3, _ref4;
98
99
  const schemaField = (_dataPointOptions_find = dataPointOptions.find((opt)=>opt.fullKey === condition.dataPointKey)) !== null && _dataPointOptions_find !== void 0 ? _dataPointOptions_find : null;
99
- var _schemaField_fieldType;
100
- const nextFieldType = (_schemaField_fieldType = schemaField === null || schemaField === void 0 ? void 0 : schemaField.fieldType) !== null && _schemaField_fieldType !== void 0 ? _schemaField_fieldType : 'string';
100
+ const nextFieldType = (_ref3 = schemaField === null || schemaField === void 0 ? void 0 : schemaField.fieldType) !== null && _ref3 !== void 0 ? _ref3 : 'string';
101
101
  const nextIsNumber = nextFieldType === 'number';
102
102
  const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;
103
103
  const operatorReset = !nextOperatorItems.some((op)=>op.value === condition.operator);
104
- var _schemaField_fullKey;
105
104
  onChange({
106
105
  ...condition,
107
- dataPointKey: (_schemaField_fullKey = schemaField === null || schemaField === void 0 ? void 0 : schemaField.fullKey) !== null && _schemaField_fullKey !== void 0 ? _schemaField_fullKey : '',
106
+ dataPointKey: (_ref4 = schemaField === null || schemaField === void 0 ? void 0 : schemaField.fullKey) !== null && _ref4 !== void 0 ? _ref4 : '',
108
107
  operator: operatorReset ? nextIsNumber ? 'num_eq' : 'is_equal_to' : condition.operator
109
108
  });
110
109
  return;
@@ -112,17 +111,14 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
112
111
  onFormSelect(item.formId);
113
112
  const nextFormFieldOptions = formFieldOptions.filter((option)=>option.formId === item.formId);
114
113
  const currentSelected = nextFormFieldOptions.find((opt)=>opt.fullKey === condition.dataPointKey);
115
- var _ref;
116
114
  const nextSelected = (_ref = currentSelected !== null && currentSelected !== void 0 ? currentSelected : nextFormFieldOptions[0]) !== null && _ref !== void 0 ? _ref : null;
117
- var _nextSelected_fieldType;
118
- const nextFieldType = (_nextSelected_fieldType = nextSelected === null || nextSelected === void 0 ? void 0 : nextSelected.fieldType) !== null && _nextSelected_fieldType !== void 0 ? _nextSelected_fieldType : 'string';
115
+ const nextFieldType = (_ref1 = nextSelected === null || nextSelected === void 0 ? void 0 : nextSelected.fieldType) !== null && _ref1 !== void 0 ? _ref1 : 'string';
119
116
  const nextIsNumber = nextFieldType === 'number';
120
117
  const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;
121
118
  const operatorReset = !nextOperatorItems.some((op)=>op.value === condition.operator);
122
- var _nextSelected_fullKey;
123
119
  onChange({
124
120
  ...condition,
125
- dataPointKey: (_nextSelected_fullKey = nextSelected === null || nextSelected === void 0 ? void 0 : nextSelected.fullKey) !== null && _nextSelected_fullKey !== void 0 ? _nextSelected_fullKey : '',
121
+ dataPointKey: (_ref2 = nextSelected === null || nextSelected === void 0 ? void 0 : nextSelected.fullKey) !== null && _ref2 !== void 0 ? _ref2 : '',
126
122
  operator: operatorReset ? nextIsNumber ? 'num_eq' : 'is_equal_to' : condition.operator
127
123
  });
128
124
  };
@@ -140,12 +136,12 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
140
136
  children: /*#__PURE__*/ _jsxs(Combobox.Select, {
141
137
  disableClearSelection: true,
142
138
  itemToKey: (item)=>{
143
- var _item_value;
144
- return (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : '';
139
+ var _ref;
140
+ return (_ref = item === null || item === void 0 ? void 0 : item.value) !== null && _ref !== void 0 ? _ref : '';
145
141
  },
146
142
  itemToString: (item)=>{
147
- var _item_label;
148
- return (_item_label = item === null || item === void 0 ? void 0 : item.label) !== null && _item_label !== void 0 ? _item_label : '';
143
+ var _ref;
144
+ return (_ref = item === null || item === void 0 ? void 0 : item.label) !== null && _ref !== void 0 ? _ref : '';
149
145
  },
150
146
  items: sourceOptions,
151
147
  selectedItem: selectedSource,
@@ -202,12 +198,12 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
202
198
  },
203
199
  disableClearSelection: true,
204
200
  itemToKey: (item)=>{
205
- var _item_fullKey;
206
- return (_item_fullKey = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _item_fullKey !== void 0 ? _item_fullKey : '';
201
+ var _ref;
202
+ return (_ref = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _ref !== void 0 ? _ref : '';
207
203
  },
208
204
  itemToString: (item)=>{
209
- var _item_title;
210
- return (_item_title = item === null || item === void 0 ? void 0 : item.title) !== null && _item_title !== void 0 ? _item_title : '';
205
+ var _ref;
206
+ return (_ref = item === null || item === void 0 ? void 0 : item.title) !== null && _ref !== void 0 ? _ref : '';
211
207
  },
212
208
  items: activeDataPointOptions,
213
209
  selectedItem: selectedDataPoint,
@@ -242,20 +238,20 @@ export function ConditionRow({ canRemove, condition, dataPointOptions, formField
242
238
  },
243
239
  disableClearSelection: true,
244
240
  itemToKey: (item)=>{
245
- var _item_value;
246
- return (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : '';
241
+ var _ref;
242
+ return (_ref = item === null || item === void 0 ? void 0 : item.value) !== null && _ref !== void 0 ? _ref : '';
247
243
  },
248
244
  itemToString: (item)=>{
249
- var _item_label;
250
- return (_item_label = item === null || item === void 0 ? void 0 : item.label) !== null && _item_label !== void 0 ? _item_label : '';
245
+ var _ref;
246
+ return (_ref = item === null || item === void 0 ? void 0 : item.label) !== null && _ref !== void 0 ? _ref : '';
251
247
  },
252
248
  items: operatorItems,
253
249
  selectedItem: selectedOperator,
254
250
  onChange: (item)=>{
255
- var _item_value;
251
+ var _ref;
256
252
  return onChange({
257
253
  ...condition,
258
- operator: (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : 'is_equal_to'
254
+ operator: (_ref = item === null || item === void 0 ? void 0 : item.value) !== null && _ref !== void 0 ? _ref : 'is_equal_to'
259
255
  });
260
256
  },
261
257
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/display-conditions/ConditionRow.tsx"],"sourcesContent":["import { Button, Chip, Combobox, Flex } from '@servicetitan/anvil2';\nimport TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';\nimport { useEffect, useMemo, useState } from 'react';\nimport { FormInfo, parseFormFieldKey } from '../shared/forms';\nimport { LookupValueControl } from './LookupValueControl';\nimport { NUMBER_OPERATORS, SingleCondition, STRING_OPERATORS, VALUE_LESS_OPERATORS } from './types';\nimport type { DataPointOption, FormFieldOption } from './types';\n\nexport interface ConditionRowProps {\n canRemove: boolean;\n condition: SingleCondition;\n dataPointOptions: DataPointOption[];\n formFieldOptions: FormFieldOption[];\n forms: FormInfo[];\n onChange: (c: SingleCondition) => void;\n onFormSelect: (formId: number) => void;\n onRemove: () => void;\n}\n\ninterface OperatorOption {\n label: string;\n value: string;\n}\n\ninterface SourceOption {\n formId?: number;\n label: string;\n value: string;\n}\n\nexport function ConditionRow({\n canRemove,\n condition,\n dataPointOptions,\n formFieldOptions,\n forms,\n onChange,\n onFormSelect,\n onRemove,\n}: Readonly<ConditionRowProps>) {\n const selectedFormFieldMeta = useMemo(\n () => parseFormFieldKey(condition.dataPointKey),\n [condition.dataPointKey],\n );\n const [selectedSourceValue, setSelectedSourceValue] = useState<string>(\n selectedFormFieldMeta ? `form:${selectedFormFieldMeta.formId}` : 'schema',\n );\n\n const sourceOptions = useMemo<SourceOption[]>(\n () => [\n { label: 'Data point', value: 'schema' },\n ...forms.map(form => ({\n formId: form.id,\n label: form.name,\n value: `form:${form.id}`,\n })),\n ],\n [forms],\n );\n\n const selectedSource = useMemo<SourceOption | null>(() => {\n return (\n sourceOptions.find(opt => opt.value === selectedSourceValue) ?? sourceOptions[0] ?? null\n );\n }, [selectedSourceValue, sourceOptions]);\n\n useEffect(() => {\n if (selectedFormFieldMeta) {\n setSelectedSourceValue(`form:${selectedFormFieldMeta.formId}`);\n return;\n }\n if (!condition.dataPointKey) {\n return;\n }\n const hasSchemaMatch = dataPointOptions.some(opt => opt.fullKey === condition.dataPointKey);\n if (hasSchemaMatch) {\n setSelectedSourceValue('schema');\n }\n }, [condition.dataPointKey, dataPointOptions, selectedFormFieldMeta]);\n\n const currentFormId = selectedSource?.formId;\n const activeDataPointOptions = useMemo(\n () =>\n currentFormId\n ? formFieldOptions.filter(option => option.formId === currentFormId)\n : dataPointOptions,\n [currentFormId, dataPointOptions, formFieldOptions],\n );\n\n const selectedDataPoint = useMemo(\n () => activeDataPointOptions.find(opt => opt.fullKey === condition.dataPointKey) ?? null,\n [activeDataPointOptions, condition.dataPointKey],\n );\n\n const fieldType = selectedDataPoint?.fieldType ?? 'string';\n\n const isValueLess = VALUE_LESS_OPERATORS.includes(condition.operator);\n\n const operatorItems: OperatorOption[] = useMemo(\n () =>\n fieldType === 'number'\n ? ([...NUMBER_OPERATORS] as OperatorOption[])\n : ([...STRING_OPERATORS] as OperatorOption[]),\n [fieldType],\n );\n\n const selectedOperator = useMemo(\n () => operatorItems.find(op => op.value === condition.operator) ?? null,\n [operatorItems, condition.operator],\n );\n\n const handleDataPointChange = (item: DataPointOption | null) => {\n const nextIsNumber = item?.fieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n onChange({\n ...condition,\n dataPointKey: item?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n };\n\n const handleSourceChange = (item: SourceOption | null) => {\n if (!item) {\n return;\n }\n setSelectedSourceValue(item.value);\n\n if (!item.formId) {\n const schemaField =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey) ?? null;\n const nextFieldType = schemaField?.fieldType ?? 'string';\n const nextIsNumber = nextFieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n\n onChange({\n ...condition,\n dataPointKey: schemaField?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n return;\n }\n\n onFormSelect(item.formId);\n const nextFormFieldOptions = formFieldOptions.filter(\n option => option.formId === item.formId,\n );\n const currentSelected = nextFormFieldOptions.find(\n opt => opt.fullKey === condition.dataPointKey,\n );\n const nextSelected = currentSelected ?? nextFormFieldOptions[0] ?? null;\n const nextFieldType = nextSelected?.fieldType ?? 'string';\n const nextIsNumber = nextFieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n\n onChange({\n ...condition,\n dataPointKey: nextSelected?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n };\n\n return (\n <Flex direction=\"column\" gap=\"3\" style={{ width: '100%' }}>\n <div style={{ width: '100%' }}>\n <Combobox.Select\n disableClearSelection\n itemToKey={(item: SourceOption | null) => item?.value ?? ''}\n itemToString={(item: SourceOption | null) => item?.label ?? ''}\n items={sourceOptions}\n selectedItem={selectedSource}\n onChange={handleSourceChange}\n >\n <Combobox.SelectTrigger\n label=\"Data Type\"\n placeholder=\"Select source...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: SourceOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.value}>\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n <Flex\n direction=\"row\"\n alignItems=\"flex-end\"\n gap=\"2\"\n style={{ flexWrap: 'wrap', rowGap: 8, width: '100%' }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '4px 8px',\n }}\n >\n <Chip label=\"IF\" size=\"small\" />\n </div>\n <Flex flex={1} style={{ minWidth: 160 }}>\n <Combobox.Select\n flex={1}\n style={{ width: '100%' }}\n disableClearSelection\n itemToKey={(item: DataPointOption | null) => item?.fullKey ?? ''}\n itemToString={(item: DataPointOption | null) => item?.title ?? ''}\n items={activeDataPointOptions}\n selectedItem={selectedDataPoint}\n onChange={handleDataPointChange}\n >\n <Combobox.SelectTrigger\n label=\"Data Point\"\n placeholder={\n currentFormId ? 'Select form field...' : 'Select data point...'\n }\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: DataPointOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.fullKey}>\n {item.title}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </Flex>\n <Flex flex={1} style={{ minWidth: 160 }}>\n <Combobox.Select\n flex={1}\n style={{ width: '100%' }}\n disableClearSelection\n itemToKey={(item: OperatorOption | null) => item?.value ?? ''}\n itemToString={(item: OperatorOption | null) => item?.label ?? ''}\n items={operatorItems}\n selectedItem={selectedOperator}\n onChange={(item: OperatorOption | null) =>\n onChange({\n ...condition,\n operator: (item?.value ??\n 'is_equal_to') as SingleCondition['operator'],\n })\n }\n >\n <Combobox.SelectTrigger\n label=\"Condition\"\n placeholder=\"Select...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: OperatorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.value}>\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </Flex>\n {!isValueLess && (\n <Flex flex={1} style={{ minWidth: 160 }}>\n <LookupValueControl\n value={condition.value}\n fieldType={fieldType}\n lookupSource={selectedDataPoint?.lookupSource}\n onChange={value => onChange({ ...condition, value })}\n />\n </Flex>\n )}\n {canRemove && (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '4px 8px',\n }}\n >\n <Button\n appearance=\"secondary\"\n aria-label=\"Remove condition\"\n icon={{ before: TrashIcon }}\n size=\"small\"\n onClick={onRemove}\n />\n </div>\n )}\n </Flex>\n </Flex>\n );\n}\n"],"names":["Button","Chip","Combobox","Flex","TrashIcon","useEffect","useMemo","useState","parseFormFieldKey","LookupValueControl","NUMBER_OPERATORS","STRING_OPERATORS","VALUE_LESS_OPERATORS","ConditionRow","canRemove","condition","dataPointOptions","formFieldOptions","forms","onChange","onFormSelect","onRemove","selectedFormFieldMeta","dataPointKey","selectedSourceValue","setSelectedSourceValue","formId","sourceOptions","label","value","map","form","id","name","selectedSource","find","opt","hasSchemaMatch","some","fullKey","currentFormId","activeDataPointOptions","filter","option","selectedDataPoint","fieldType","isValueLess","includes","operator","operatorItems","selectedOperator","op","handleDataPointChange","item","nextIsNumber","nextOperatorItems","operatorReset","handleSourceChange","schemaField","nextFieldType","nextFormFieldOptions","currentSelected","nextSelected","direction","gap","style","width","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","SelectTrigger","placeholder","size","Content","List","i","Item","index","alignItems","flexWrap","rowGap","display","flexShrink","padding","flex","minWidth","title","lookupSource","appearance","aria-label","icon","before","onClick"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/display-conditions/ConditionRow.tsx"],"sourcesContent":["import { Button, Chip, Combobox, Flex } from '@servicetitan/anvil2';\nimport TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';\nimport { useEffect, useMemo, useState } from 'react';\nimport { FormInfo, parseFormFieldKey } from '../shared/forms';\nimport { LookupValueControl } from './LookupValueControl';\nimport { NUMBER_OPERATORS, SingleCondition, STRING_OPERATORS, VALUE_LESS_OPERATORS } from './types';\nimport type { DataPointOption, FormFieldOption } from './types';\n\nexport interface ConditionRowProps {\n canRemove: boolean;\n condition: SingleCondition;\n dataPointOptions: DataPointOption[];\n formFieldOptions: FormFieldOption[];\n forms: FormInfo[];\n onChange: (c: SingleCondition) => void;\n onFormSelect: (formId: number) => void;\n onRemove: () => void;\n}\n\ninterface OperatorOption {\n label: string;\n value: string;\n}\n\ninterface SourceOption {\n formId?: number;\n label: string;\n value: string;\n}\n\nexport function ConditionRow({\n canRemove,\n condition,\n dataPointOptions,\n formFieldOptions,\n forms,\n onChange,\n onFormSelect,\n onRemove,\n}: Readonly<ConditionRowProps>) {\n const selectedFormFieldMeta = useMemo(\n () => parseFormFieldKey(condition.dataPointKey),\n [condition.dataPointKey],\n );\n const [selectedSourceValue, setSelectedSourceValue] = useState<string>(\n selectedFormFieldMeta ? `form:${selectedFormFieldMeta.formId}` : 'schema',\n );\n\n const sourceOptions = useMemo<SourceOption[]>(\n () => [\n { label: 'Data point', value: 'schema' },\n ...forms.map(form => ({\n formId: form.id,\n label: form.name,\n value: `form:${form.id}`,\n })),\n ],\n [forms],\n );\n\n const selectedSource = useMemo<SourceOption | null>(() => {\n return (\n sourceOptions.find(opt => opt.value === selectedSourceValue) ?? sourceOptions[0] ?? null\n );\n }, [selectedSourceValue, sourceOptions]);\n\n useEffect(() => {\n if (selectedFormFieldMeta) {\n setSelectedSourceValue(`form:${selectedFormFieldMeta.formId}`);\n return;\n }\n if (!condition.dataPointKey) {\n return;\n }\n const hasSchemaMatch = dataPointOptions.some(opt => opt.fullKey === condition.dataPointKey);\n if (hasSchemaMatch) {\n setSelectedSourceValue('schema');\n }\n }, [condition.dataPointKey, dataPointOptions, selectedFormFieldMeta]);\n\n const currentFormId = selectedSource?.formId;\n const activeDataPointOptions = useMemo(\n () =>\n currentFormId\n ? formFieldOptions.filter(option => option.formId === currentFormId)\n : dataPointOptions,\n [currentFormId, dataPointOptions, formFieldOptions],\n );\n\n const selectedDataPoint = useMemo(\n () => activeDataPointOptions.find(opt => opt.fullKey === condition.dataPointKey) ?? null,\n [activeDataPointOptions, condition.dataPointKey],\n );\n\n const fieldType = selectedDataPoint?.fieldType ?? 'string';\n\n const isValueLess = VALUE_LESS_OPERATORS.includes(condition.operator);\n\n const operatorItems: OperatorOption[] = useMemo(\n () =>\n fieldType === 'number'\n ? ([...NUMBER_OPERATORS] as OperatorOption[])\n : ([...STRING_OPERATORS] as OperatorOption[]),\n [fieldType],\n );\n\n const selectedOperator = useMemo(\n () => operatorItems.find(op => op.value === condition.operator) ?? null,\n [operatorItems, condition.operator],\n );\n\n const handleDataPointChange = (item: DataPointOption | null) => {\n const nextIsNumber = item?.fieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n onChange({\n ...condition,\n dataPointKey: item?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n };\n\n const handleSourceChange = (item: SourceOption | null) => {\n if (!item) {\n return;\n }\n setSelectedSourceValue(item.value);\n\n if (!item.formId) {\n const schemaField =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey) ?? null;\n const nextFieldType = schemaField?.fieldType ?? 'string';\n const nextIsNumber = nextFieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n\n onChange({\n ...condition,\n dataPointKey: schemaField?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n return;\n }\n\n onFormSelect(item.formId);\n const nextFormFieldOptions = formFieldOptions.filter(\n option => option.formId === item.formId,\n );\n const currentSelected = nextFormFieldOptions.find(\n opt => opt.fullKey === condition.dataPointKey,\n );\n const nextSelected = currentSelected ?? nextFormFieldOptions[0] ?? null;\n const nextFieldType = nextSelected?.fieldType ?? 'string';\n const nextIsNumber = nextFieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n\n onChange({\n ...condition,\n dataPointKey: nextSelected?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n };\n\n return (\n <Flex direction=\"column\" gap=\"3\" style={{ width: '100%' }}>\n <div style={{ width: '100%' }}>\n <Combobox.Select\n disableClearSelection\n itemToKey={(item: SourceOption | null) => item?.value ?? ''}\n itemToString={(item: SourceOption | null) => item?.label ?? ''}\n items={sourceOptions}\n selectedItem={selectedSource}\n onChange={handleSourceChange}\n >\n <Combobox.SelectTrigger\n label=\"Data Type\"\n placeholder=\"Select source...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: SourceOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.value}>\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n <Flex\n direction=\"row\"\n alignItems=\"flex-end\"\n gap=\"2\"\n style={{ flexWrap: 'wrap', rowGap: 8, width: '100%' }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '4px 8px',\n }}\n >\n <Chip label=\"IF\" size=\"small\" />\n </div>\n <Flex flex={1} style={{ minWidth: 160 }}>\n <Combobox.Select\n flex={1}\n style={{ width: '100%' }}\n disableClearSelection\n itemToKey={(item: DataPointOption | null) => item?.fullKey ?? ''}\n itemToString={(item: DataPointOption | null) => item?.title ?? ''}\n items={activeDataPointOptions}\n selectedItem={selectedDataPoint}\n onChange={handleDataPointChange}\n >\n <Combobox.SelectTrigger\n label=\"Data Point\"\n placeholder={\n currentFormId ? 'Select form field...' : 'Select data point...'\n }\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: DataPointOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.fullKey}>\n {item.title}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </Flex>\n <Flex flex={1} style={{ minWidth: 160 }}>\n <Combobox.Select\n flex={1}\n style={{ width: '100%' }}\n disableClearSelection\n itemToKey={(item: OperatorOption | null) => item?.value ?? ''}\n itemToString={(item: OperatorOption | null) => item?.label ?? ''}\n items={operatorItems}\n selectedItem={selectedOperator}\n onChange={(item: OperatorOption | null) =>\n onChange({\n ...condition,\n operator: (item?.value ??\n 'is_equal_to') as SingleCondition['operator'],\n })\n }\n >\n <Combobox.SelectTrigger\n label=\"Condition\"\n placeholder=\"Select...\"\n size=\"small\"\n />\n <Combobox.Content>\n {({ items }: { items: OperatorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.value}>\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </Flex>\n {!isValueLess && (\n <Flex flex={1} style={{ minWidth: 160 }}>\n <LookupValueControl\n value={condition.value}\n fieldType={fieldType}\n lookupSource={selectedDataPoint?.lookupSource}\n onChange={value => onChange({ ...condition, value })}\n />\n </Flex>\n )}\n {canRemove && (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '4px 8px',\n }}\n >\n <Button\n appearance=\"secondary\"\n aria-label=\"Remove condition\"\n icon={{ before: TrashIcon }}\n size=\"small\"\n onClick={onRemove}\n />\n </div>\n )}\n </Flex>\n </Flex>\n );\n}\n"],"names":["Button","Chip","Combobox","Flex","TrashIcon","useEffect","useMemo","useState","parseFormFieldKey","LookupValueControl","NUMBER_OPERATORS","STRING_OPERATORS","VALUE_LESS_OPERATORS","ConditionRow","canRemove","condition","dataPointOptions","formFieldOptions","forms","onChange","onFormSelect","onRemove","selectedFormFieldMeta","dataPointKey","selectedSourceValue","setSelectedSourceValue","formId","sourceOptions","label","value","map","form","id","name","selectedSource","find","opt","hasSchemaMatch","some","fullKey","currentFormId","activeDataPointOptions","filter","option","selectedDataPoint","fieldType","isValueLess","includes","operator","operatorItems","selectedOperator","op","handleDataPointChange","item","nextIsNumber","nextOperatorItems","operatorReset","handleSourceChange","currentSelected","schemaField","nextFieldType","nextFormFieldOptions","nextSelected","direction","gap","style","width","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","SelectTrigger","placeholder","size","Content","List","i","Item","index","alignItems","flexWrap","rowGap","display","flexShrink","padding","flex","minWidth","title","lookupSource","appearance","aria-label","icon","before","onClick"],"mappings":"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"}
@@ -246,6 +246,7 @@ export const DisplayConditionModal = (props)=>{
246
246
  }
247
247
  for (const group of state.groups){
248
248
  for (const condition of group.conditions){
249
+ var _ref;
249
250
  var _allFieldOptions_find;
250
251
  if (!condition.dataPointKey) {
251
252
  return false;
@@ -257,8 +258,7 @@ export const DisplayConditionModal = (props)=>{
257
258
  if (!trimmedValue) {
258
259
  return false;
259
260
  }
260
- var _allFieldOptions_find_fieldType;
261
- const fieldType = (_allFieldOptions_find_fieldType = (_allFieldOptions_find = allFieldOptions.find((opt)=>opt.fullKey === condition.dataPointKey)) === null || _allFieldOptions_find === void 0 ? void 0 : _allFieldOptions_find.fieldType) !== null && _allFieldOptions_find_fieldType !== void 0 ? _allFieldOptions_find_fieldType : 'string';
261
+ 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';
262
262
  if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {
263
263
  return false;
264
264
  }
@@ -325,12 +325,12 @@ export const DisplayConditionModal = (props)=>{
325
325
  children: /*#__PURE__*/ _jsxs(Combobox.Select, {
326
326
  disableClearSelection: true,
327
327
  itemToKey: (item)=>{
328
- var _item_value;
329
- return (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : '';
328
+ var _ref;
329
+ return (_ref = item === null || item === void 0 ? void 0 : item.value) !== null && _ref !== void 0 ? _ref : '';
330
330
  },
331
331
  itemToString: (item)=>{
332
- var _item_label;
333
- return (_item_label = item === null || item === void 0 ? void 0 : item.label) !== null && _item_label !== void 0 ? _item_label : '';
332
+ var _ref;
333
+ return (_ref = item === null || item === void 0 ? void 0 : item.label) !== null && _ref !== void 0 ? _ref : '';
334
334
  },
335
335
  items: [
336
336
  ...BEHAVIOR_OPTIONS
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport {\n Fragment,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n buildFormFieldKey,\n FormFieldInfo,\n FormInfo,\n getConditionalFieldTypeFromFormItemType,\n parseFormFieldKey,\n} from '../shared/forms';\nimport { ConditionGroupsSection, MatchType } from './ConditionGroupsSection';\nimport { defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport {\n ConditionGroup as ConditionGroupType,\n DisplayBehavior,\n DisplayConditionState,\n FormFieldOption,\n LogicalOperator,\n} from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\n/** When the editor runs inside a shadow root (e.g. monolith MFE), portaling to `document.body` escapes the shadow tree and loses bundled styles. */\nfunction resolveDisplayConditionPortalContainer(anchor: HTMLElement): Element | DocumentFragment {\n const rootNode = anchor.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n return rootNode;\n }\n return document.body;\n}\n\nfunction deriveMatchType(conditionState: DisplayConditionState): MatchType {\n const firstGroup = conditionState.groups[0];\n if (!firstGroup || firstGroup.conditions.length <= 1) {\n return 'all';\n }\n const hasOr = firstGroup.conditions.some(c => c.logicalOperator === 'or');\n return hasOr ? 'any' : 'all';\n}\n\nfunction applyMatchTypeToState(\n conditionState: DisplayConditionState,\n matchType: MatchType,\n): DisplayConditionState {\n const logicalOp: LogicalOperator = matchType === 'all' ? 'and' : 'or';\n return {\n ...conditionState,\n groups: conditionState.groups.map((group, groupIndex) => {\n if (groupIndex !== 0) {\n return group;\n }\n return {\n ...group,\n conditions: group.conditions.map((c, i) =>\n i === 0 ? c : { ...c, logicalOperator: logicalOp },\n ),\n };\n }),\n };\n}\n\nexport interface DisplayConditionModalProps {\n /**\n * When set, the conditions dialog is portaled here instead of resolving from the DOM anchor.\n * Use when the host controls stacking context or shadow boundaries explicitly.\n */\n portalContainer?: Element | DocumentFragment | null;\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const {\n onConditionFormSelect,\n onConditionalsOpen,\n portalContainer: portalContainerProp,\n schema,\n } = props;\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n const [matchType, setMatchType] = useState<MatchType>('all');\n const [forms, setForms] = useState<FormInfo[]>([]);\n const [formFieldsByFormId, setFormFieldsByFormId] = useState<Record<number, FormFieldInfo[]>>(\n {},\n );\n const [loadingFormIds, setLoadingFormIds] = useState<number[]>([]);\n const [isFormsListLoading, setIsFormsListLoading] = useState(false);\n const formFieldsByFormIdRef = useRef<Record<number, FormFieldInfo[]>>({});\n const loadingFormIdsRef = useRef<number[]>([]);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);\n const formFieldOptions = useMemo<FormFieldOption[]>(() => {\n const nextOptions: FormFieldOption[] = [];\n for (const form of forms) {\n const fields = formFieldsByFormId[form.id];\n if (!fields) {\n continue;\n }\n for (const field of fields) {\n const fieldType = getConditionalFieldTypeFromFormItemType(field.itemType);\n if (!fieldType) {\n continue;\n }\n nextOptions.push({\n fieldType,\n formId: form.id,\n fullKey: buildFormFieldKey(form.id, field.id),\n title: field.header,\n });\n }\n }\n return nextOptions.sort((left, right) => left.title.localeCompare(right.title));\n }, [forms, formFieldsByFormId]);\n const allFieldOptions = useMemo(\n () => [...dataPointOptions, ...formFieldOptions],\n [dataPointOptions, formFieldOptions],\n );\n const isFieldDataLoading = isFormsListLoading || loadingFormIds.length > 0;\n\n useEffect(() => {\n formFieldsByFormIdRef.current = formFieldsByFormId;\n }, [formFieldsByFormId]);\n\n useEffect(() => {\n loadingFormIdsRef.current = loadingFormIds;\n }, [loadingFormIds]);\n\n const requestFormFields = useCallback(\n (formId: number) => {\n if (!onConditionFormSelect) {\n return;\n }\n if (\n formFieldsByFormIdRef.current[formId] ||\n loadingFormIdsRef.current.includes(formId)\n ) {\n return;\n }\n\n setLoadingFormIds(prev => (prev.includes(formId) ? prev : [...prev, formId]));\n onConditionFormSelect(formId, (selectedFormId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [selectedFormId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== selectedFormId));\n });\n },\n [onConditionFormSelect],\n );\n\n const portalAnchorRef = useRef<HTMLSpanElement>(null);\n const [resolvedPortalContainer, setResolvedPortalContainer] = useState<\n Element | DocumentFragment | null\n >(null);\n\n useLayoutEffect(() => {\n if (typeof document === 'undefined' || portalContainerProp !== undefined) {\n return;\n }\n const anchor = portalAnchorRef.current;\n if (!anchor) {\n return;\n }\n setResolvedPortalContainer(resolveDisplayConditionPortalContainer(anchor));\n }, [portalContainerProp]);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n const initialState = parsed ?? defaultState();\n const usedFormIds = Array.from(\n new Set(\n initialState.groups\n .flatMap(group => group.conditions)\n .map(condition => parseFormFieldKey(condition.dataPointKey)?.formId)\n .filter((formId): formId is number => formId != null),\n ),\n );\n\n setForms([]);\n setFormFieldsByFormId({});\n setIsFormsListLoading(!!onConditionalsOpen);\n setLoadingFormIds([]);\n\n if (onConditionalsOpen) {\n onConditionalsOpen(\n usedFormIds,\n nextForms => {\n setForms(nextForms);\n setIsFormsListLoading(false);\n },\n (formId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [formId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== formId));\n },\n );\n\n /*\n * Keep display-condition flow aligned with calculated-field flow:\n * when modal opens, request fields for already-used forms so labels\n * are available in edit mode.\n */\n usedFormIds.forEach(formId => requestFormFields(formId));\n } else {\n setIsFormsListLoading(false);\n setLoadingFormIds([]);\n }\n\n setState(initialState);\n setMatchType(deriveMatchType(initialState));\n setIsOpen(true);\n });\n }, [onConditionalsOpen, requestFormFields]);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const finalState = applyMatchTypeToState(state, matchType);\n const condition = buildUnlayerDisplayCondition(finalState);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [matchType, request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const handleFormSelect = useCallback(\n (formId: number) => {\n requestFormFields(formId);\n },\n [requestFormFields],\n );\n\n const canSave = useMemo(() => {\n if (isFieldDataLoading) {\n return false;\n }\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n allFieldOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [allFieldOptions, isFieldDataLoading, state.groups]);\n\n const portalTarget =\n portalContainerProp === undefined ? resolvedPortalContainer : portalContainerProp;\n\n return (\n <Fragment>\n {portalContainerProp === undefined ? (\n <span\n ref={portalAnchorRef}\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n width: 0,\n height: 0,\n clipPath: 'inset(50%)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }}\n />\n ) : null}\n {portalTarget && isOpen\n ? createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"4\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <ConditionGroupsSection\n behaviorSection={\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"2\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to include or exclude selected\n template/file.\n </Text>\n <div style={{ width: 90 }}>\n <Combobox.Select\n 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\n appearance=\"primary\"\n disabled={!canSave}\n onClick={handleSave}\n >\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n )\n : null}\n </Fragment>\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","Fragment","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","createPortal","buildFormFieldKey","getConditionalFieldTypeFromFormItemType","parseFormFieldKey","ConditionGroupsSection","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","resolveDisplayConditionPortalContainer","anchor","rootNode","getRootNode","ShadowRoot","document","body","deriveMatchType","conditionState","firstGroup","groups","conditions","length","hasOr","some","c","logicalOperator","applyMatchTypeToState","matchType","logicalOp","map","group","groupIndex","i","DisplayConditionModal","props","onConditionFormSelect","onConditionalsOpen","portalContainer","portalContainerProp","schema","request","setRequest","isOpen","setIsOpen","state","setState","setMatchType","forms","setForms","formFieldsByFormId","setFormFieldsByFormId","loadingFormIds","setLoadingFormIds","isFormsListLoading","setIsFormsListLoading","formFieldsByFormIdRef","loadingFormIdsRef","dataPointOptions","formFieldOptions","nextOptions","form","fields","id","field","fieldType","itemType","push","formId","fullKey","title","header","sort","left","right","localeCompare","allFieldOptions","isFieldDataLoading","current","requestFormFields","includes","prev","selectedFormId","filter","portalAnchorRef","resolvedPortalContainer","setResolvedPortalContainer","undefined","nextRequest","existing","data","parsed","initialState","usedFormIds","Array","from","Set","flatMap","condition","dataPointKey","nextForms","forEach","handleClose","handleSave","finalState","done","updateGroup","index","next","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","handleFormSelect","canSave","operator","trimmedValue","trim","test","portalTarget","span","ref","aria-hidden","style","position","width","height","clipPath","overflow","whiteSpace","open","onClose","size","Header","Content","direction","gap","maxHeight","overflowY","paddingRight","behaviorSection","alignItems","flexWrap","subdued","variant","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","Item","onFormSelect","onMatchTypeChange","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport {\n Fragment,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n buildFormFieldKey,\n FormFieldInfo,\n FormInfo,\n getConditionalFieldTypeFromFormItemType,\n parseFormFieldKey,\n} from '../shared/forms';\nimport { ConditionGroupsSection, MatchType } from './ConditionGroupsSection';\nimport { defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport {\n ConditionGroup as ConditionGroupType,\n DisplayBehavior,\n DisplayConditionState,\n FormFieldOption,\n LogicalOperator,\n} from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\n/** When the editor runs inside a shadow root (e.g. monolith MFE), portaling to `document.body` escapes the shadow tree and loses bundled styles. */\nfunction resolveDisplayConditionPortalContainer(anchor: HTMLElement): Element | DocumentFragment {\n const rootNode = anchor.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n return rootNode;\n }\n return document.body;\n}\n\nfunction deriveMatchType(conditionState: DisplayConditionState): MatchType {\n const firstGroup = conditionState.groups[0];\n if (!firstGroup || firstGroup.conditions.length <= 1) {\n return 'all';\n }\n const hasOr = firstGroup.conditions.some(c => c.logicalOperator === 'or');\n return hasOr ? 'any' : 'all';\n}\n\nfunction applyMatchTypeToState(\n conditionState: DisplayConditionState,\n matchType: MatchType,\n): DisplayConditionState {\n const logicalOp: LogicalOperator = matchType === 'all' ? 'and' : 'or';\n return {\n ...conditionState,\n groups: conditionState.groups.map((group, groupIndex) => {\n if (groupIndex !== 0) {\n return group;\n }\n return {\n ...group,\n conditions: group.conditions.map((c, i) =>\n i === 0 ? c : { ...c, logicalOperator: logicalOp },\n ),\n };\n }),\n };\n}\n\nexport interface DisplayConditionModalProps {\n /**\n * When set, the conditions dialog is portaled here instead of resolving from the DOM anchor.\n * Use when the host controls stacking context or shadow boundaries explicitly.\n */\n portalContainer?: Element | DocumentFragment | null;\n onConditionFormSelect?: (\n formId: number,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n onConditionalsOpen?: (\n usedFormIds: number[],\n sendFormList: (forms: FormInfo[]) => void,\n sendFormFields: (formId: number, fields: FormFieldInfo[]) => void,\n ) => void;\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const {\n onConditionFormSelect,\n onConditionalsOpen,\n portalContainer: portalContainerProp,\n schema,\n } = props;\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n const [matchType, setMatchType] = useState<MatchType>('all');\n const [forms, setForms] = useState<FormInfo[]>([]);\n const [formFieldsByFormId, setFormFieldsByFormId] = useState<Record<number, FormFieldInfo[]>>(\n {},\n );\n const [loadingFormIds, setLoadingFormIds] = useState<number[]>([]);\n const [isFormsListLoading, setIsFormsListLoading] = useState(false);\n const formFieldsByFormIdRef = useRef<Record<number, FormFieldInfo[]>>({});\n const loadingFormIdsRef = useRef<number[]>([]);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(schema), [schema]);\n const formFieldOptions = useMemo<FormFieldOption[]>(() => {\n const nextOptions: FormFieldOption[] = [];\n for (const form of forms) {\n const fields = formFieldsByFormId[form.id];\n if (!fields) {\n continue;\n }\n for (const field of fields) {\n const fieldType = getConditionalFieldTypeFromFormItemType(field.itemType);\n if (!fieldType) {\n continue;\n }\n nextOptions.push({\n fieldType,\n formId: form.id,\n fullKey: buildFormFieldKey(form.id, field.id),\n title: field.header,\n });\n }\n }\n return nextOptions.sort((left, right) => left.title.localeCompare(right.title));\n }, [forms, formFieldsByFormId]);\n const allFieldOptions = useMemo(\n () => [...dataPointOptions, ...formFieldOptions],\n [dataPointOptions, formFieldOptions],\n );\n const isFieldDataLoading = isFormsListLoading || loadingFormIds.length > 0;\n\n useEffect(() => {\n formFieldsByFormIdRef.current = formFieldsByFormId;\n }, [formFieldsByFormId]);\n\n useEffect(() => {\n loadingFormIdsRef.current = loadingFormIds;\n }, [loadingFormIds]);\n\n const requestFormFields = useCallback(\n (formId: number) => {\n if (!onConditionFormSelect) {\n return;\n }\n if (\n formFieldsByFormIdRef.current[formId] ||\n loadingFormIdsRef.current.includes(formId)\n ) {\n return;\n }\n\n setLoadingFormIds(prev => (prev.includes(formId) ? prev : [...prev, formId]));\n onConditionFormSelect(formId, (selectedFormId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [selectedFormId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== selectedFormId));\n });\n },\n [onConditionFormSelect],\n );\n\n const portalAnchorRef = useRef<HTMLSpanElement>(null);\n const [resolvedPortalContainer, setResolvedPortalContainer] = useState<\n Element | DocumentFragment | null\n >(null);\n\n useLayoutEffect(() => {\n if (typeof document === 'undefined' || portalContainerProp !== undefined) {\n return;\n }\n const anchor = portalAnchorRef.current;\n if (!anchor) {\n return;\n }\n setResolvedPortalContainer(resolveDisplayConditionPortalContainer(anchor));\n }, [portalContainerProp]);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n const initialState = parsed ?? defaultState();\n const usedFormIds = Array.from(\n new Set(\n initialState.groups\n .flatMap(group => group.conditions)\n .map(condition => parseFormFieldKey(condition.dataPointKey)?.formId)\n .filter((formId): formId is number => formId != null),\n ),\n );\n\n setForms([]);\n setFormFieldsByFormId({});\n setIsFormsListLoading(!!onConditionalsOpen);\n setLoadingFormIds([]);\n\n if (onConditionalsOpen) {\n onConditionalsOpen(\n usedFormIds,\n nextForms => {\n setForms(nextForms);\n setIsFormsListLoading(false);\n },\n (formId, fields) => {\n setFormFieldsByFormId(prev => ({ ...prev, [formId]: fields }));\n setLoadingFormIds(prev => prev.filter(id => id !== formId));\n },\n );\n\n /*\n * Keep display-condition flow aligned with calculated-field flow:\n * when modal opens, request fields for already-used forms so labels\n * are available in edit mode.\n */\n usedFormIds.forEach(formId => requestFormFields(formId));\n } else {\n setIsFormsListLoading(false);\n setLoadingFormIds([]);\n }\n\n setState(initialState);\n setMatchType(deriveMatchType(initialState));\n setIsOpen(true);\n });\n }, [onConditionalsOpen, requestFormFields]);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const finalState = applyMatchTypeToState(state, matchType);\n const condition = buildUnlayerDisplayCondition(finalState);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [matchType, request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const handleFormSelect = useCallback(\n (formId: number) => {\n requestFormFields(formId);\n },\n [requestFormFields],\n );\n\n const canSave = useMemo(() => {\n if (isFieldDataLoading) {\n return false;\n }\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n allFieldOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [allFieldOptions, isFieldDataLoading, state.groups]);\n\n const portalTarget =\n portalContainerProp === undefined ? resolvedPortalContainer : portalContainerProp;\n\n return (\n <Fragment>\n {portalContainerProp === undefined ? (\n <span\n ref={portalAnchorRef}\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n width: 0,\n height: 0,\n clipPath: 'inset(50%)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }}\n />\n ) : null}\n {portalTarget && isOpen\n ? createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"4\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <ConditionGroupsSection\n behaviorSection={\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"2\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to include or exclude selected\n template/file.\n </Text>\n <div style={{ width: 90 }}>\n <Combobox.Select\n 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\n appearance=\"primary\"\n disabled={!canSave}\n onClick={handleSave}\n >\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n )\n : null}\n </Fragment>\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","Fragment","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","createPortal","buildFormFieldKey","getConditionalFieldTypeFromFormItemType","parseFormFieldKey","ConditionGroupsSection","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","resolveDisplayConditionPortalContainer","anchor","rootNode","getRootNode","ShadowRoot","document","body","deriveMatchType","conditionState","firstGroup","groups","conditions","length","hasOr","some","c","logicalOperator","applyMatchTypeToState","matchType","logicalOp","map","group","groupIndex","i","DisplayConditionModal","props","onConditionFormSelect","onConditionalsOpen","portalContainer","portalContainerProp","schema","request","setRequest","isOpen","setIsOpen","state","setState","setMatchType","forms","setForms","formFieldsByFormId","setFormFieldsByFormId","loadingFormIds","setLoadingFormIds","isFormsListLoading","setIsFormsListLoading","formFieldsByFormIdRef","loadingFormIdsRef","dataPointOptions","formFieldOptions","nextOptions","form","fields","id","field","fieldType","itemType","push","formId","fullKey","title","header","sort","left","right","localeCompare","allFieldOptions","isFieldDataLoading","current","requestFormFields","includes","prev","selectedFormId","filter","portalAnchorRef","resolvedPortalContainer","setResolvedPortalContainer","undefined","nextRequest","existing","data","parsed","initialState","usedFormIds","Array","from","Set","flatMap","condition","dataPointKey","nextForms","forEach","handleClose","handleSave","finalState","done","updateGroup","index","next","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","handleFormSelect","canSave","operator","trimmedValue","trim","test","portalTarget","span","ref","aria-hidden","style","position","width","height","clipPath","overflow","whiteSpace","open","onClose","size","Header","Content","direction","gap","maxHeight","overflowY","paddingRight","behaviorSection","alignItems","flexWrap","subdued","variant","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","Item","onFormSelect","onMatchTypeChange","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"LookupValueControl.d.ts","sourceRoot":"","sources":["../../src/display-conditions/LookupValueControl.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EAC/B,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,KAAK,GACR,EAAE,QAAQ,CAAC,uBAAuB,CAAC,2CAsJnC"}
1
+ {"version":3,"file":"LookupValueControl.d.ts","sourceRoot":"","sources":["../../src/display-conditions/LookupValueControl.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAiCD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EAC/B,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,KAAK,GACR,EAAE,QAAQ,CAAC,uBAAuB,CAAC,2CAyJnC"}
@@ -7,6 +7,16 @@ const toOption = (option)=>({
7
7
  id: option.key,
8
8
  label: option.label
9
9
  });
10
+ /*
11
+ * Searchable sources return nothing until the user types, which would make the
12
+ * dropdown show its built-in "No match found" empty state on open — confusing
13
+ * before any search has happened. Render a disabled hint instead so the list is
14
+ * never mistaken for "no results".
15
+ */ const SEARCH_HINT_OPTION = {
16
+ id: '__lookup_search_hint__',
17
+ label: 'Start typing to search…',
18
+ disabled: true
19
+ };
10
20
  const sanitizeNumericInput = (raw)=>{
11
21
  let value = raw.replaceAll(/[^0-9.-]/g, '');
12
22
  const isNegative = value.startsWith('-');
@@ -38,10 +48,10 @@ const sanitizeNumericInput = (raw)=>{
38
48
  * Fall back to the raw value so a saved key that the host omits from its list
39
49
  * (e.g. an inactive/renamed option) still shows on edit instead of vanishing.
40
50
  */ const staticSelected = useMemo(()=>{
51
+ var _staticOptions_find;
41
52
  if (!value) {
42
53
  return null;
43
54
  }
44
- var _staticOptions_find;
45
55
  return (_staticOptions_find = staticOptions.find((option)=>String(option.id) === value)) !== null && _staticOptions_find !== void 0 ? _staticOptions_find : {
46
56
  id: value,
47
57
  label: value
@@ -121,6 +131,11 @@ const sanitizeNumericInput = (raw)=>{
121
131
  resolveOptions
122
132
  ]);
123
133
  const handleLoadOptions = useCallback(async (query)=>{
134
+ if (!query.trim()) {
135
+ return [
136
+ SEARCH_HINT_OPTION
137
+ ];
138
+ }
124
139
  const result = await loadOptions(query);
125
140
  return result.map(toOption);
126
141
  }, [
@@ -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\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 const result = await loadOptions(query);\n return result.map(toOption);\n },\n [loadOptions],\n );\n\n if (status === 'loading') {\n return (\n <TextField\n label=\"Value\"\n size=\"small\"\n flex={1}\n disabled\n value=\"\"\n placeholder=\"\"\n aria-label=\"Value\"\n />\n );\n }\n\n if (status === 'static') {\n return (\n <SelectFieldSync\n flex={1}\n size=\"small\"\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 size=\"small\"\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 size=\"small\"\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","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","size","flex","disabled","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,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,GAAGtB,iBAAiBiB;IAE1E,MAAMM,gBAAgB1B,QAA6B,IAAMuB,QAAQI,GAAG,CAACvB,WAAW;QAACmB;KAAQ;IAEzF;;;KAGC,GACD,MAAMK,iBAAiB5B,QAAkC;QACrD,IAAI,CAACW,OAAO;YACR,OAAO;QACX;YAEIe;QADJ,OACIA,CAAAA,sBAAAA,cAAcG,IAAI,CAACxB,CAAAA,SAAUyB,OAAOzB,OAAOC,EAAE,MAAMK,oBAAnDe,iCAAAA,sBAA6D;YAAEpB,IAAIK;YAAOH,OAAOG;QAAM;IAE/F,GAAG;QAACe;QAAef;KAAM;IAEzB;;;KAGC,GACD,MAAMoB,4BAA4B/B,QAA6B;QAC3D,IACI4B,kBACA,CAACF,cAAcM,IAAI,CAAC3B,CAAAA,SAAUyB,OAAOzB,OAAOC,EAAE,MAAMwB,OAAOF,eAAetB,EAAE,IAC9E;YACE,OAAO;gBAACsB;mBAAmBF;aAAc;QAC7C;QACA,OAAOA;IACX,GAAG;QAACA;QAAeE;KAAe;IAElC,MAAM,CAACK,oBAAoBC,sBAAsB,GAAGhC,SAChDS,QAAQ;QAAEL,IAAIK;QAAOH,OAAOG;IAAM,IAAI;IAG1C,6FAA6F;IAC7F,MAAMwB,iBAAiBlC,OAAsB;IAE7CF,UAAU;QACNmC,sBAAsBE,CAAAA;YAClB,IAAI,CAACzB,OAAO;gBACR,OAAO;YACX;YACA,IAAIyB,CAAAA,iBAAAA,2BAAAA,KAAM9B,EAAE,MAAKK,OAAO;gBACpB,OAAOyB;YACX;YACA,OAAO;gBAAE9B,IAAIK;gBAAOH,OAAOG;YAAM;QACrC;IACJ,GAAG;QAACA;KAAM;IAEV,4FAA4F;IAC5FZ,UAAU;QACN,IAAI0B,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,CAACxB,CAAAA,SAAUA,OAAOE,GAAG,KAAKI;YACnD,IAAI8B,OAAO;gBACPN,eAAeE,OAAO,GAAG1B;gBACzBuB,sBAAsB;oBAAE5B,IAAImC,MAAMlC,GAAG;oBAAEC,OAAOiC,MAAMjC,KAAK;gBAAC;YAC9D;QACJ;QAEA,OAAO;YACH8B,YAAY;QAChB;IACJ,GAAG;QAACb;QAAQd;QAAOa;KAAe;IAElC,MAAMkB,oBAAoB5C,YACtB,OAAO6C;QACH,MAAMH,SAAS,MAAMlB,YAAYqB;QACjC,OAAOH,OAAOb,GAAG,CAACvB;IACtB,GACA;QAACkB;KAAY;IAGjB,IAAIG,WAAW,WAAW;QACtB,qBACI,KAAC9B;YACGa,OAAM;YACNoC,MAAK;YACLC,MAAM;YACNC,QAAQ;YACRnC,OAAM;YACNoC,aAAY;YACZC,cAAW;;IAGvB;IAEA,IAAIvB,WAAW,UAAU;QACrB,qBACI,KAAC5B;YACGgD,MAAM;YACND,MAAK;YACLpC,OAAM;YACNuC,aAAY;YACZxB,SAASQ;YACTpB,OAAOiB;YACPqB,wBAAwB5C,CAAAA,SAAUgB,SAAShB,SAASyB,OAAOzB,OAAOC,EAAE,IAAI;;IAGpF;IAEA,IAAImB,WAAW,cAAc;QACzB,qBACI,KAAC7B;YACGiD,MAAM;YACND,MAAK;YACLpC,OAAM;YACNuC,aAAY;YACZG,aAAY;YACZ5B,aAAaoB;YACb/B,OAAOsB;YACPgB,wBAAwB5C,CAAAA;gBACpB8B,eAAeE,OAAO,GAAGhC,SAASyB,OAAOzB,OAAOC,EAAE,IAAI;gBACtD4B,sBAAsB7B;gBACtBgB,SAAShB,SAASyB,OAAOzB,OAAOC,EAAE,IAAI;YAC1C;;IAGZ;IAEA,sEAAsE;IACtE,MAAM6C,mBAAmB,CAACzC;QACtBW,SAASF,cAAc,WAAWV,qBAAqBC,OAAOA;IAClE;IAEA,qBACI,KAACf;QACGa,OAAM;QACNoC,MAAK;QACLC,MAAM;QACNlC,OAAOA;QACPU,UAAU+B,CAAAA,IAAKD,iBAAiBC,EAAEC,MAAM,CAAC1C,KAAK;QAC9CoC,aAAa5B,cAAc,WAAW,aAAa;QACnD6B,cAAW;QACV,GAAI7B,cAAc,YAAY;YAAEmC,WAAW;QAAU,CAAC;;AAGnE"}
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\n label=\"Value\"\n size=\"small\"\n flex={1}\n disabled\n value=\"\"\n placeholder=\"\"\n aria-label=\"Value\"\n />\n );\n }\n\n if (status === 'static') {\n return (\n <SelectFieldSync\n flex={1}\n size=\"small\"\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 size=\"small\"\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 size=\"small\"\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","size","flex","placeholder","aria-label","onSelectedOptionChange","initialLoad","handleTextChange","e","target","inputMode"],"mappings":"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"}