@qoretechnologies/reqraft 0.10.16 → 0.10.18

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 (43) hide show
  1. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  2. package/dist/components/form/engine/CompactRow.js +82 -3
  3. package/dist/components/form/engine/CompactRow.js.map +1 -1
  4. package/dist/components/form/engine/FormEngine.d.ts +37 -11
  5. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  6. package/dist/components/form/engine/FormEngine.js +187 -116
  7. package/dist/components/form/engine/FormEngine.js.map +1 -1
  8. package/dist/components/form/engine/compactRowContext.d.ts +8 -0
  9. package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
  10. package/dist/components/form/engine/compactRowContext.js.map +1 -1
  11. package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
  12. package/dist/components/form/engine/compactRowStyles.js +1 -1
  13. package/dist/components/form/engine/compactRowStyles.js.map +1 -1
  14. package/dist/components/form/engine/optionActions.d.ts +28 -0
  15. package/dist/components/form/engine/optionActions.d.ts.map +1 -0
  16. package/dist/components/form/engine/optionActions.js +18 -0
  17. package/dist/components/form/engine/optionActions.js.map +1 -0
  18. package/dist/components/form/engine/readFirst.d.ts +9 -2
  19. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  20. package/dist/components/form/engine/readFirst.js +15 -3
  21. package/dist/components/form/engine/readFirst.js.map +1 -1
  22. package/dist/components/form/engine/rendererTypes.d.ts +35 -0
  23. package/dist/components/form/engine/rendererTypes.d.ts.map +1 -0
  24. package/dist/components/form/engine/rendererTypes.js +63 -0
  25. package/dist/components/form/engine/rendererTypes.js.map +1 -0
  26. package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
  27. package/dist/components/form/fields/auto/AutoFormField.js +6 -1
  28. package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
  29. package/dist/components/form/index.d.ts +2 -0
  30. package/dist/components/form/index.d.ts.map +1 -1
  31. package/dist/components/form/index.js +2 -0
  32. package/dist/components/form/index.js.map +1 -1
  33. package/package.json +3 -3
  34. package/src/components/form/engine/CompactRow.tsx +139 -0
  35. package/src/components/form/engine/FormEngine.tsx +229 -70
  36. package/src/components/form/engine/FormEngineRemote.stories.tsx +329 -0
  37. package/src/components/form/engine/compactRowContext.ts +8 -0
  38. package/src/components/form/engine/compactRowStyles.ts +30 -0
  39. package/src/components/form/engine/optionActions.ts +40 -0
  40. package/src/components/form/engine/readFirst.ts +25 -6
  41. package/src/components/form/engine/rendererTypes.ts +55 -0
  42. package/src/components/form/fields/auto/AutoFormField.tsx +6 -1
  43. package/src/components/form/index.tsx +2 -0
@@ -102,6 +102,8 @@ var react_1 = require("react");
102
102
  var jsx_runtime_1 = require("react/jsx-runtime");
103
103
  var reqore_1 = require("@qoretechnologies/reqore");
104
104
  var colors_1 = require("@qoretechnologies/reqore/dist/helpers/colors");
105
+ var optionActions_1 = require("./optionActions");
106
+ var rendererTypes_1 = require("./rendererTypes");
105
107
  var lodash_1 = require("lodash");
106
108
  var isArray_1 = __importDefault(require("lodash/isArray"));
107
109
  var map_1 = __importDefault(require("lodash/map"));
@@ -200,7 +202,10 @@ var StyledCommitDock = styled_components_1.default.div(templateObject_2 || (temp
200
202
  });
201
203
  var getType = function (type, operators, operator) {
202
204
  var finalType = getTypeFromOperator(operators, (0, exports.fixOperatorValue)(operator)) || type;
203
- return ((0, isArray_1.default)(finalType) ? finalType[0] : finalType);
205
+ var resolvedType = (0, isArray_1.default)(finalType) ? finalType[0] : finalType;
206
+ // A value can be received before its server-driven option schema. Keep the
207
+ // renderer type-safe during that transition without guessing a concrete type.
208
+ return (resolvedType || 'any');
204
209
  };
205
210
  exports.getType = getType;
206
211
  var getTypeFromOperator = function (operators, operatorData) {
@@ -214,15 +219,36 @@ var fixOperatorValue = function (operator) {
214
219
  return (0, isArray_1.default)(operator) ? operator : [operator];
215
220
  };
216
221
  exports.fixOperatorValue = fixOperatorValue;
222
+ var getOptionSchemaStorageType = function (option, isRendererOnly) {
223
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
224
+ return ((isRendererOnly(option === null || option === void 0 ? void 0 : option.ui_type)
225
+ ? (option === null || option === void 0 ? void 0 : option.type) || (option === null || option === void 0 ? void 0 : option.ui_type)
226
+ : (option === null || option === void 0 ? void 0 : option.ui_type) || (option === null || option === void 0 ? void 0 : option.type)) || 'any');
227
+ };
228
+ var getOptionFieldStorageType = function (optionName, fieldType, schema, operators, operatorData, isRendererOnly) {
229
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
230
+ var schemaOption = schema === null || schema === void 0 ? void 0 : schema[optionName];
231
+ var storedType = fieldType && !(fieldType === (schemaOption === null || schemaOption === void 0 ? void 0 : schemaOption.ui_type) && isRendererOnly(fieldType))
232
+ ? fieldType
233
+ : getOptionSchemaStorageType(schemaOption, isRendererOnly);
234
+ return (0, exports.getType)(storedType, operators, operatorData);
235
+ };
217
236
  var hasRequiredOptions = function (options) {
218
237
  if (options === void 0) { options = {}; }
219
238
  return !!(0, lodash_1.findKey)(options, function (option) { return option.required; });
220
239
  };
221
240
  exports.hasRequiredOptions = hasRequiredOptions;
222
241
  exports.OptionsContext = (0, use_context_selector_1.createContext)({});
223
- var fixOptions = function (value, options, operators) {
242
+ var fixOptions = function (value, options, operators, isRendererOnly) {
224
243
  if (value === void 0) { value = {}; }
244
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
225
245
  var fixedValue = (0, lodash_1.cloneDeep)(value);
246
+ // Server-driven schemas can arrive after the persisted value. Preserve that
247
+ // value verbatim until its schema is available instead of manufacturing
248
+ // partially typed form fields that can crash the following render.
249
+ if (!(0, size_1.default)(options)) {
250
+ return fixedValue;
251
+ }
226
252
  (0, lodash_1.forEach)(options, function (option, name) {
227
253
  var _a, _b, _c, _d, _f, _g, _h;
228
254
  if (option.value ||
@@ -230,7 +256,7 @@ var fixOptions = function (value, options, operators) {
230
256
  ((option.required || option.preselected) && !fixedValue[name]) ||
231
257
  ((option.required || option.preselected) && option.default_value && !option.value)) {
232
258
  var obj = void 0;
233
- var type = (0, exports.getType)((option.ui_type || option.type), operators, (_a = fixedValue[name]) === null || _a === void 0 ? void 0 : _a.op);
259
+ var type = (0, exports.getType)(getOptionSchemaStorageType(option, isRendererOnly), operators, (_a = fixedValue[name]) === null || _a === void 0 ? void 0 : _a.op);
234
260
  if (((_b = option.default_value) === null || _b === void 0 ? void 0 : _b.is_expression) &&
235
261
  ((_c = fixedValue[name]) === null || _c === void 0 ? void 0 : _c.value) === undefined) {
236
262
  obj = option.default_value;
@@ -251,29 +277,32 @@ var fixOptions = function (value, options, operators) {
251
277
  });
252
278
  var res = (0, reduce_1.default)(fixedValue, function (newValue, option, optionName) {
253
279
  var _a;
254
- var _b, _c, _d, _f, _g, _h, _j, _k, _l;
280
+ var _b, _c, _d, _f, _g, _h, _j, _k;
255
281
  var newOption = option;
256
282
  if (!(0, lodash_1.isPlainObject)(newOption) || !(newOption === null || newOption === void 0 ? void 0 : newOption.type)) {
257
- var fixedOption = {
258
- type: (0, exports.getType)((((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) || ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type)), operators, newOption === null || newOption === void 0 ? void 0 : newOption.op),
259
- value: newOption,
260
- };
261
- if (newOption === null || newOption === void 0 ? void 0 : newOption.is_expression) {
262
- fixedOption.is_expression = true;
263
- }
283
+ var isUntypedEnvelope = (0, lodash_1.isPlainObject)(newOption) && 'value' in newOption;
284
+ var untypedFieldValue = isUntypedEnvelope ? newOption.value : newOption;
285
+ // Spread the original envelope first so every key it carried survives —
286
+ // rebuilding from just {type, value} silently dropped `op`, `is_expression`
287
+ // and anything else a field needs to render, which emptied the card.
288
+ var fixedOption = __assign(__assign({}, ((0, lodash_1.isPlainObject)(newOption) ? newOption : {})), { type: (0, exports.getType)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), operators, newOption === null || newOption === void 0 ? void 0 : newOption.op), value: untypedFieldValue });
264
289
  newOption = fixedOption;
265
290
  }
291
+ else if (newOption.type === ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) &&
292
+ isRendererOnly(newOption.type)) {
293
+ newOption = __assign(__assign({}, newOption), { type: (0, exports.getType)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), operators, newOption.op) });
294
+ }
266
295
  if (newOption.value !== undefined &&
267
- ((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.allowed_values) &&
268
- !((_g = (_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.allowed_values) === null || _g === void 0 ? void 0 : _g.find(function (allowedValue) { var _a; return ((_a = allowedValue.value) === null || _a === void 0 ? void 0 : _a.value) === newOption.value || allowedValue.name === newOption.value; })) &&
296
+ ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values) &&
297
+ !((_f = (_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.allowed_values) === null || _f === void 0 ? void 0 : _f.find(function (allowedValue) { var _a; return ((_a = allowedValue.value) === null || _a === void 0 ? void 0 : _a.value) === newOption.value || allowedValue.name === newOption.value; })) &&
269
298
  !(0, TemplateField_1.isValueTemplate)(newOption.value) &&
270
- !((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.multiselect) &&
271
- !((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.allowed_values_creatable)) {
299
+ !((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.multiselect) &&
300
+ !((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.allowed_values_creatable)) {
272
301
  newOption.value = undefined;
273
302
  }
274
303
  if (newOption.value &&
275
- ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.readonly) &&
276
- ((_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.default_value) &&
304
+ ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.readonly) &&
305
+ ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.default_value) &&
277
306
  (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]) !== newOption.value) {
278
307
  newOption.value = (0, common_1.getDefaultValue)(options[optionName]);
279
308
  }
@@ -329,47 +358,64 @@ exports.getTypeAndCanBeNull = getTypeAndCanBeNull;
329
358
  // Option types rendered full-width (IDE Options parity, commit 8e6b7781).
330
359
  var STRECHABLE_TYPES = new Set(['tool-catalog']);
331
360
  var FormEngine = function (_a) {
332
- var _b, _c, _d, _f, _g;
361
+ var _b, _c, _d, _f, _g, _h;
333
362
  var name = _a.name, uniqueName = _a.uniqueName, value = _a.value, onChange = _a.onChange, onSingleOptionsChange = _a.onSingleOptionsChange, onDependableOptionChange = _a.onDependableOptionChange, placeholder = _a.placeholder, noValueString = _a.noValueString, // eslint-disable-line @typescript-eslint/no-unused-vars
334
363
  isValid = _a.isValid, // eslint-disable-line @typescript-eslint/no-unused-vars
335
- url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _h = _a.allowTemplates, allowTemplates = _h === void 0 ? true : _h, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, _j = _a.showTypeToggle, showTypeToggle = _j === void 0 ? true : _j, compact = _a.compact, _k = _a.compactFlush, compactFlush = _k === void 0 ? false : _k, _l = _a.compactNested, compactNested = _l === void 0 ? false : _l, compactPanelProps = _a.compactPanelProps, _m = _a.commitMode, commitMode = _m === void 0 ? 'immediate' : _m, _o = _a.expandMode, expandMode = _o === void 0 ? 'single' : _o, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, componentOverrides = _a.componentOverrides, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, initialExpandedOptions = _a.initialExpandedOptions, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "componentOverrides", "inheritedFromParent", "autoFocusFirstRequired", "initialExpandedOptions"]);
336
- var _p = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _p[0], setOptions = _p[1];
364
+ url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _j = _a.allowTemplates, allowTemplates = _j === void 0 ? true : _j, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, _k = _a.showTypeToggle, showTypeToggle = _k === void 0 ? true : _k, compact = _a.compact, _l = _a.compactFlush, compactFlush = _l === void 0 ? false : _l, _m = _a.compactNested, compactNested = _m === void 0 ? false : _m, compactPanelProps = _a.compactPanelProps, _o = _a.commitMode, commitMode = _o === void 0 ? 'immediate' : _o, _p = _a.expandMode, expandMode = _p === void 0 ? 'single' : _p, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, _q = _a.optionActionsCollapse, optionActionsCollapse = _q === void 0 ? 'auto' : _q, componentOverrides = _a.componentOverrides, rendererOnlyUiTypes = _a.rendererOnlyUiTypes, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, initialExpandedOptions = _a.initialExpandedOptions, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "optionActionsCollapse", "componentOverrides", "rendererOnlyUiTypes", "inheritedFromParent", "autoFocusFirstRequired", "initialExpandedOptions"]);
365
+ // Built-ins + whatever the consumer declared for its own injected editors.
366
+ var isRendererOnly = (0, react_2.useMemo)(function () { return (0, rendererTypes_1.createRendererOnlyUiTypeCheck)(rendererOnlyUiTypes); }, [JSON.stringify(rendererOnlyUiTypes)]);
367
+ // Pointer CAPABILITY and viewport WIDTH are different questions and both
368
+ // matter here: a hover-gated action is unreachable without a hover, and a
369
+ // phone-width row has no space for a button strip either way. Both now come
370
+ // from Reqore's context (one subscription for the whole app) rather than a
371
+ // reqraft-local matchMedia hook.
372
+ //
373
+ // `isHoverCapable` defaults to `true` in Reqore, but fall back explicitly so
374
+ // an older Reqore — where the property does not exist — degrades to "this
375
+ // pointer hovers" (the pre-existing behaviour) instead of collapsing every
376
+ // action into a menu for everyone.
377
+ var isHoverCapable = (_b = (0, reqore_1.useReqoreProperty)('isHoverCapable')) !== null && _b !== void 0 ? _b : true;
378
+ var isMobile = (0, reqore_1.useReqoreProperty)('isMobile');
379
+ var collapseOptionActions = optionActionsCollapse === 'always' ? true
380
+ : optionActionsCollapse === 'never' ? false
381
+ : !isHoverCapable || !!isMobile;
382
+ var _r = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _r[0], setOptions = _r[1];
337
383
  // optionsLoader lifecycle: loading feeds the skeleton gate, error the banner.
338
- var _q = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _q[0], setOptionsLoading = _q[1];
339
- var _r = (0, react_2.useState)(), optionsError = _r[0], setOptionsError = _r[1];
384
+ var _s = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _s[0], setOptionsLoading = _s[1];
385
+ var _t = (0, react_2.useState)(), optionsError = _t[0], setOptionsError = _t[1];
340
386
  // Operators: prop-provided (compact) or fetched via operatorsUrl (dpql,
341
387
  // ported from IDE Options) — the fetch overrides the seeded prop value.
342
- var _s = (0, react_2.useState)(operatorsProp), operators = _s[0], setOperators = _s[1];
388
+ var _u = (0, react_2.useState)(operatorsProp), operators = _u[0], setOperators = _u[1];
343
389
  // Remote-fetch loading (ported from IDE Options); only relevant when one of
344
390
  // the fetch urls is set — schema-as-props consumers never see the skeleton.
345
- var _t = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _t[0], setLoading = _t[1];
391
+ var _v = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _v[0], setLoading = _v[1];
346
392
  var confirmAction = (0, reqore_1.useReqoreProperty)('confirmAction');
347
393
  var theme = (0, reqore_1.useReqoreTheme)();
348
- var _u = (0, react_2.useState)(), focusedEditing = _u[0], setFocusedEditing = _u[1];
349
- var _v = (0, react_2.useState)(false), showFieldTypes = _v[0], setShowFieldTypes = _v[1];
394
+ var _w = (0, react_2.useState)(), focusedEditing = _w[0], setFocusedEditing = _w[1];
395
+ var _x = (0, react_2.useState)(false), showFieldTypes = _x[0], setShowFieldTypes = _x[1];
350
396
  // Global toggle (toolbar ⓘ): reveal the short-description info panel on every
351
397
  // field that has a short_desc. Per-row ⓘ overrides still win over it.
352
398
  // Global field-info visibility, tri-state: `undefined` = default (critical
353
399
  // messages auto-open, the rest closed); `true` = show all; `false` = hide all
354
400
  // (even message fields). The toolbar ⓘ drives it.
355
- var _w = (0, react_2.useState)(undefined), showAllDescriptions = _w[0], setShowAllDescriptions = _w[1];
356
- var _x = (0, react_2.useState)(), showHelpForOption = _x[0], setShowHelpForOption = _x[1];
357
- var _y = (0, react_2.useState)(false), showInvalidOptionsOnly = _y[0], setShowInvalidOptionsOnly = _y[1];
401
+ var _y = (0, react_2.useState)(undefined), showAllDescriptions = _y[0], setShowAllDescriptions = _y[1];
402
+ var _z = (0, react_2.useState)(), showHelpForOption = _z[0], setShowHelpForOption = _z[1];
403
+ var _0 = (0, react_2.useState)(false), showInvalidOptionsOnly = _0[0], setShowInvalidOptionsOnly = _0[1];
358
404
  // Which options are expanded into their editor (several can be open at once).
359
- var _z = (0, react_2.useState)([]), expandedOptions = _z[0], setExpandedOptions = _z[1];
405
+ var _1 = (0, react_2.useState)([]), expandedOptions = _1[0], setExpandedOptions = _1[1];
360
406
  // Remembers each row's last settled status box, so an actively-edited field
361
407
  // stays put when its status flips (e.g. becomes valid) instead of jumping to
362
408
  // another box mid-edit and stealing focus. Keyed by option name.
363
409
  var settledBucket = (0, react_2.useRef)({});
364
410
  // Measured form width (not viewport — the form lives in drawers/panels of
365
411
  // arbitrary width) drives the stacked narrow layout.
366
- var _0 = (0, react_use_1.useMeasure)(), compactWrapRef = _0[0], compactWrapWidth = _0[1].width;
412
+ var _2 = (0, react_use_1.useMeasure)(), compactWrapRef = _2[0], compactWrapWidth = _2[1].width;
367
413
  // Own handle on the scroll wrap (useMeasure's ref is a callback, no `.current`)
368
414
  // so the label-column measurement can publish its CSS var on the element. It's
369
415
  // STATE, not a ref: the wrap mounts only after the loading-skeleton gate
370
416
  // resolves, so the measurement effect must re-run when the node appears — a
371
417
  // ref wouldn't retrigger it.
372
- var _1 = (0, react_2.useState)(null), compactWrapNode = _1[0], setCompactWrapNode = _1[1];
418
+ var _3 = (0, react_2.useState)(null), compactWrapNode = _3[0], setCompactWrapNode = _3[1];
373
419
  var setCompactWrap = (0, react_2.useCallback)(function (node) {
374
420
  compactWrapRef(node);
375
421
  setCompactWrapNode(function (prev) { return (prev === node ? prev : node); });
@@ -406,8 +452,8 @@ var FormEngine = function (_a) {
406
452
  var readRowHeights = (0, react_2.useRef)({});
407
453
  // Required-groups linkage: hovering a group chip highlights every member row;
408
454
  // clicking a sibling in the chip's popover scrolls to it and flashes it.
409
- var _2 = (0, react_2.useState)([]), highlightedOptions = _2[0], setHighlightedOptions = _2[1];
410
- var _3 = (0, react_2.useState)([]), flashedOptions = _3[0], setFlashedOptions = _3[1];
455
+ var _4 = (0, react_2.useState)([]), highlightedOptions = _4[0], setHighlightedOptions = _4[1];
456
+ var _5 = (0, react_2.useState)([]), flashedOptions = _5[0], setFlashedOptions = _5[1];
411
457
  var flashTimeout = (0, react_2.useRef)();
412
458
  var flashOptions = (0, react_2.useCallback)(function (optionNames, scrollToFirst) {
413
459
  if (scrollToFirst === void 0) { scrollToFirst = false; }
@@ -449,16 +495,16 @@ var FormEngine = function (_a) {
449
495
  });
450
496
  var compactNarrow = !!compactWrapWidth && compactWrapWidth < 480;
451
497
  // Info panels auto-open on Tier-1 content; the per-row user override sticks.
452
- var _4 = (0, react_2.useState)({}), infoPanelOverrides = _4[0], setInfoPanelOverrides = _4[1];
498
+ var _6 = (0, react_2.useState)({}), infoPanelOverrides = _6[0], setInfoPanelOverrides = _6[1];
453
499
  // Toolbar filters affect the listed rows only — the meter reflects the full set.
454
- var _5 = (0, react_2.useState)(false), requiredOnly = _5[0], setRequiredOnly = _5[1];
455
- var _6 = (0, react_2.useState)(''), compactQuery = _6[0], setCompactQuery = _6[1];
500
+ var _7 = (0, react_2.useState)(false), requiredOnly = _7[0], setRequiredOnly = _7[1];
501
+ var _8 = (0, react_2.useState)(''), compactQuery = _8[0], setCompactQuery = _8[1];
456
502
  // Compact field sort (Fields menu → "Sort by"); 'schema' = declared order.
457
- var _7 = (0, react_2.useState)('schema'), compactSort = _7[0], setCompactSort = _7[1];
458
- var _8 = (0, react_2.useState)(function () { return ({
459
- fields: (0, exports.fixOptions)(value, options || {}),
503
+ var _9 = (0, react_2.useState)('schema'), compactSort = _9[0], setCompactSort = _9[1];
504
+ var _10 = (0, react_2.useState)(function () { return ({
505
+ fields: (0, exports.fixOptions)(value, options || {}, undefined, isRendererOnly),
460
506
  meta: undefined,
461
- }); }), localValue = _8[0], setLocalValue = _8[1];
507
+ }); }), localValue = _10[0], setLocalValue = _10[1];
462
508
  var originalValue = (0, react_2.useRef)();
463
509
  // Track the last value we emitted via onChange so we can skip re-applying fixOptions
464
510
  // when the parent echoes it back as the new value prop (controlled component loop prevention)
@@ -467,7 +513,7 @@ var FormEngine = function (_a) {
467
513
  originalValue.current = localValue.fields;
468
514
  }
469
515
  var unavailableOptionsCount = (0, react_2.useRef)(0);
470
- var _9 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _9.compactValue, typesLoading = _9.loading;
516
+ var _11 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _11.compactValue, typesLoading = _11.loading;
471
517
  var templates = (0, useTemplates_1.useTemplates)(allowTemplates, rest.stringTemplates, interfaceContext);
472
518
  (0, react_2.useEffect)(function () {
473
519
  if ((0, lodash_1.isEqual)(localValue.fields, value)) {
@@ -541,7 +587,7 @@ var FormEngine = function (_a) {
541
587
  setOptions({});
542
588
  return [2 /*return*/];
543
589
  }
544
- setLocalValue({ fields: (0, exports.fixOptions)(value, data.data), meta: undefined });
590
+ setLocalValue({ fields: (0, exports.fixOptions)(value, data.data, undefined, isRendererOnly), meta: undefined });
545
591
  if (!operatorsUrl) {
546
592
  setLoading(false);
547
593
  }
@@ -600,7 +646,7 @@ var FormEngine = function (_a) {
600
646
  }
601
647
  setOptions(data.data);
602
648
  onOptionsLoaded === null || onOptionsLoaded === void 0 ? void 0 : onOptionsLoaded(data.data);
603
- setLocalValue({ fields: (0, exports.fixOptions)({}, data.data), meta: undefined });
649
+ setLocalValue({ fields: (0, exports.fixOptions)({}, data.data, undefined, isRendererOnly), meta: undefined });
604
650
  return [2 /*return*/];
605
651
  }
606
652
  });
@@ -633,7 +679,7 @@ var FormEngine = function (_a) {
633
679
  }
634
680
  }, [operatorsUrl]);
635
681
  (0, react_use_1.useUpdateEffect)(function () {
636
- var fixedValue = (0, exports.fixOptions)(value, options || {});
682
+ var fixedValue = (0, exports.fixOptions)(value, options || {}, undefined, isRendererOnly);
637
683
  // When the value we're receiving is the one we just emitted AND fixOptions has nothing to
638
684
  // meaningfully add or change, skip the update. This breaks the controlled-component loop for
639
685
  // arg_schema fields while still allowing required/preselected options to be restored (in that
@@ -652,21 +698,23 @@ var FormEngine = function (_a) {
652
698
  originalValue.current = fixedValue;
653
699
  }
654
700
  setLocalValue === null || setLocalValue === void 0 ? void 0 : setLocalValue({ fields: fixedValue, meta: undefined });
655
- }, [JSON.stringify(options), JSON.stringify(value)]);
701
+ }, [JSON.stringify(options), JSON.stringify(value), isRendererOnly]);
656
702
  var handleValueChange = (0, react_2.useCallback)(function (optionName, val, _type, isFunction) {
657
703
  setLocalValue(function (_a) {
658
704
  var _b, _c;
659
- var _d, _f, _g, _h, _j, _k, _l, _m, _o;
660
- var _p = _a.fields, fields = _p === void 0 ? {} : _p;
661
- var schemaType = (((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.ui_type) ||
662
- ((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.type));
705
+ var _d, _f, _g, _h, _j, _k, _l, _m, _o, _p;
706
+ var _q = _a.fields, fields = _q === void 0 ? {} : _q;
707
+ var schemaType = getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly);
663
708
  var isAnyLike = schemaType === 'any' || schemaType === 'auto';
664
709
  // For any/auto schema types, preserve the user's chosen type stored in the field
665
- var resolvedSchemaType = isAnyLike && ((_g = fields[optionName]) === null || _g === void 0 ? void 0 : _g.type) ?
666
- fields[optionName].type
667
- : schemaType || ((_h = fields[optionName]) === null || _h === void 0 ? void 0 : _h.type);
710
+ var resolvedSchemaType = isAnyLike && ((_d = fields[optionName]) === null || _d === void 0 ? void 0 : _d.type)
711
+ ? fields[optionName].type
712
+ : ((_f = fields[optionName]) === null || _f === void 0 ? void 0 : _f.type) === ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.ui_type) &&
713
+ isRendererOnly((_h = fields[optionName]) === null || _h === void 0 ? void 0 : _h.type)
714
+ ? schemaType
715
+ : schemaType || ((_j = fields[optionName]) === null || _j === void 0 ? void 0 : _j.type);
668
716
  var type = _type ||
669
- (0, exports.getTypeAndCanBeNull)(resolvedSchemaType, (_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.allowed_values).type;
717
+ (0, exports.getTypeAndCanBeNull)(resolvedSchemaType, (_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.allowed_values).type;
670
718
  if (!fields[optionName]) {
671
719
  var defaultOperators = (0, reduce_1.default)(operators || {}, function (filteredOperators, operator, operatorKey) {
672
720
  if (operator.selected) {
@@ -695,9 +743,9 @@ var FormEngine = function (_a) {
695
743
  delete updatedValue[optionName].is_expression;
696
744
  }
697
745
  var meta = {};
698
- if (((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.has_dependents) &&
746
+ if (((_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.has_dependents) &&
699
747
  val !== undefined &&
700
- val !== ((_l = fields[optionName]) === null || _l === void 0 ? void 0 : _l.value)) {
748
+ val !== ((_m = fields[optionName]) === null || _m === void 0 ? void 0 : _m.value)) {
701
749
  (0, lodash_1.forEach)(options, function (option, depName) {
702
750
  if (option.depends_on &&
703
751
  (0, lodash_1.flatten)(option.depends_on).includes(optionName) &&
@@ -707,8 +755,8 @@ var FormEngine = function (_a) {
707
755
  });
708
756
  onDependableOptionChange === null || onDependableOptionChange === void 0 ? void 0 : onDependableOptionChange(optionName, val, updatedValue, options);
709
757
  }
710
- if ((0, size_1.default)((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.on_change)) {
711
- meta.events = (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.on_change;
758
+ if ((0, size_1.default)((_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.on_change)) {
759
+ meta.events = (_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.on_change;
712
760
  }
713
761
  onSingleOptionsChange === null || onSingleOptionsChange === void 0 ? void 0 : onSingleOptionsChange(optionName, updatedValue[optionName]);
714
762
  return {
@@ -719,6 +767,7 @@ var FormEngine = function (_a) {
719
767
  }, [
720
768
  onSingleOptionsChange,
721
769
  onDependableOptionChange,
770
+ isRendererOnly,
722
771
  JSON.stringify(options),
723
772
  JSON.stringify(operators),
724
773
  ]);
@@ -796,9 +845,8 @@ var FormEngine = function (_a) {
796
845
  setExpandedOptions(function (prev) { return prev.filter(function (name) { return name !== optionName; }); });
797
846
  }, []);
798
847
  var handleAddOptionalFieldChange = (0, react_2.useCallback)(function (_name, optionName) {
799
- var _a, _b, _c;
800
- handleValueChange(optionName, (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), (0, exports.getTypeAndCanBeNull)((((_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
801
- ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.type)), (_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values).type);
848
+ var _a;
849
+ handleValueChange(optionName, (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), (0, exports.getTypeAndCanBeNull)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), (_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.allowed_values).type);
802
850
  }, [JSON.stringify(options), handleValueChange]);
803
851
  var availableOptions = (0, react_2.useMemo)(function () {
804
852
  if (!options) {
@@ -820,22 +868,18 @@ var FormEngine = function (_a) {
820
868
  removeSelectedOption(optionName);
821
869
  return newValue;
822
870
  }
823
- var schemaType = (0, exports.getType)((options[optionName].ui_type || options[optionName].type), operators, option === null || option === void 0 ? void 0 : option.op);
871
+ var rendererType = (0, exports.getType)((options[optionName].ui_type || options[optionName].type), operators, option === null || option === void 0 ? void 0 : option.op);
872
+ var storageType = getOptionFieldStorageType(optionName, option === null || option === void 0 ? void 0 : option.type, options, operators, option === null || option === void 0 ? void 0 : option.op, isRendererOnly);
824
873
  if (!(0, lodash_1.isPlainObject)(option)) {
825
874
  return __assign(__assign({}, newValue), (_a = {}, _a[optionName] = {
826
- type: schemaType,
875
+ type: storageType || rendererType,
827
876
  value: option,
828
877
  }, _a));
829
878
  }
830
- // any/auto: preserve the user-picked type; otherwise normalize to the
831
- // schema type (ui_type wins) so rendering and validation agree.
832
- var isAnyLike = schemaType === 'any' || schemaType === 'auto';
833
- var effectiveType = isAnyLike && (option === null || option === void 0 ? void 0 : option.type) ?
834
- option.type
835
- : schemaType;
836
- return __assign(__assign({}, newValue), (_b = {}, _b[optionName] = __assign(__assign({}, option), { type: effectiveType }), _b));
879
+ return __assign(__assign({}, newValue), (_b = {}, _b[optionName] = __assign(__assign({}, option), { type: storageType || rendererType }), _b));
837
880
  }, {});
838
881
  }, [
882
+ isRendererOnly,
839
883
  JSON.stringify(fixedValue),
840
884
  JSON.stringify(options),
841
885
  unavailableOptionsCount.current,
@@ -904,13 +948,11 @@ var FormEngine = function (_a) {
904
948
  }, [JSON.stringify(options), JSON.stringify(availableOptions), JSON.stringify(localValue.fields)]);
905
949
  var getValidityData = (0, react_2.useCallback)(function () {
906
950
  var fields = (0, reduce_1.default)(availableOptions, function (result, option, optionName) {
907
- var _a, _b, _c, _d;
908
- var type = option.type ||
909
- ((_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
910
- ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.type);
951
+ var _a, _b;
952
+ var type = getOptionFieldStorageType(optionName, option.type, options, operators, option.op, isRendererOnly);
911
953
  var optionValue = option.value;
912
- var isRequired = (_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.required;
913
- var hasRequiredGroups = !!((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.required_groups);
954
+ var isRequired = (_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.required;
955
+ var hasRequiredGroups = !!((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.required_groups);
914
956
  var isEmpty = optionValue === undefined || optionValue === '';
915
957
  var validation;
916
958
  if (!isRequired && !hasRequiredGroups && isEmpty) {
@@ -936,8 +978,10 @@ var FormEngine = function (_a) {
936
978
  invalidFields: invalidFields,
937
979
  };
938
980
  }, [
981
+ isRendererOnly,
939
982
  JSON.stringify(availableOptions),
940
983
  JSON.stringify(options),
984
+ JSON.stringify(operators),
941
985
  JSON.stringify(localValue.fields),
942
986
  ]);
943
987
  var validityData = (0, react_2.useMemo)(function () { return getValidityData(); }, [getValidityData]);
@@ -948,15 +992,19 @@ var FormEngine = function (_a) {
948
992
  var shownOptions = (0, react_2.useMemo)(function () {
949
993
  return (0, reduce_1.default)(availableOptions, function (newValue, option, optionName) {
950
994
  var _a;
951
- var _b, _c;
952
995
  if (showInvalidOptionsOnly &&
953
- isOptionValid(optionName, ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) ||
954
- ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type), option.value)) {
996
+ isOptionValid(optionName, getOptionFieldStorageType(optionName, option.type, options, operators, option.op, isRendererOnly), option.value)) {
955
997
  return newValue;
956
998
  }
957
999
  return __assign(__assign({}, newValue), (_a = {}, _a[optionName] = option, _a));
958
1000
  }, {});
959
- }, [showInvalidOptionsOnly, JSON.stringify(availableOptions)]);
1001
+ }, [
1002
+ showInvalidOptionsOnly,
1003
+ isRendererOnly,
1004
+ JSON.stringify(availableOptions),
1005
+ JSON.stringify(options),
1006
+ JSON.stringify(operators),
1007
+ ]);
960
1008
  // Read-first STATUS / BOX for one option — lifted to component scope so the
961
1009
  // status boxes (renderCompact) and the header's "needs attention" count share
962
1010
  // exactly one definition. One-of group members travel together (bucket by the
@@ -971,13 +1019,13 @@ var FormEngine = function (_a) {
971
1019
  return undefined;
972
1020
  }, [JSON.stringify(options)]);
973
1021
  var getOptionStatus = (0, react_2.useCallback)(function (name, hidden) {
974
- var _a;
1022
+ var _a, _b, _c;
975
1023
  if (hidden === void 0) { hidden = false; }
976
1024
  if (hidden)
977
1025
  return 'optional';
978
1026
  var schema = options === null || options === void 0 ? void 0 : options[name];
979
- var type = ((schema === null || schema === void 0 ? void 0 : schema.ui_type) || (schema === null || schema === void 0 ? void 0 : schema.type));
980
- var value = (_a = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _a === void 0 ? void 0 : _a.value;
1027
+ var type = getOptionFieldStorageType(name, (_a = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _a === void 0 ? void 0 : _a.type, options, operators, (_b = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _b === void 0 ? void 0 : _b.op, isRendererOnly);
1028
+ var value = (_c = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _c === void 0 ? void 0 : _c.value;
981
1029
  var empty = (0, readFirst_1.isOptionValueEmpty)(value);
982
1030
  var reqGroups = (schema === null || schema === void 0 ? void 0 : schema.required_groups) || [];
983
1031
  var required = !!((schema === null || schema === void 0 ? void 0 : schema.required) || reqGroups.length);
@@ -996,8 +1044,10 @@ var FormEngine = function (_a) {
996
1044
  warned: msgIntent === 'warning',
997
1045
  });
998
1046
  }, [
1047
+ isRendererOnly,
999
1048
  JSON.stringify(options),
1000
1049
  JSON.stringify(availableOptions),
1050
+ JSON.stringify(operators),
1001
1051
  isOptionValid,
1002
1052
  requiredGroupsInfo,
1003
1053
  schemaMsgIntent,
@@ -1223,10 +1273,10 @@ var FormEngine = function (_a) {
1223
1273
  next[optionName] = value;
1224
1274
  }
1225
1275
  });
1226
- return { fields: (0, exports.fixOptions)(next, options || {}, operators), meta: undefined };
1276
+ return { fields: (0, exports.fixOptions)(next, options || {}, operators, isRendererOnly), meta: undefined };
1227
1277
  });
1228
1278
  setRequiredOnly(false);
1229
- }, [JSON.stringify(options), JSON.stringify(operators)]);
1279
+ }, [JSON.stringify(options), JSON.stringify(operators), isRendererOnly]);
1230
1280
  var getCustomMenuTemplateItems = (0, react_2.useCallback)(function (optionName) {
1231
1281
  return compactValue === null || compactValue === void 0 ? void 0 : compactValue.map(function (type) { return ({
1232
1282
  label: type.display_name,
@@ -1245,9 +1295,27 @@ var FormEngine = function (_a) {
1245
1295
  // The info panel below the row keeps showing schema messages while editing —
1246
1296
  // rendering them in the editor too would balloon a one-line edit.
1247
1297
  suppressSchemaMessages) {
1248
- var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1298
+ var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1249
1299
  var type = _a.type, other = __rest(_a, ["type"]);
1250
1300
  var operatorParts = (0, exports.fixOperatorValue)(other.op);
1301
+ // The RENDERER type for this row — which editor mounts. Distinct from the
1302
+ // storage type on the value envelope: a `richtext` field stores a string
1303
+ // but must render the richtext editor, so `ui_type` wins here.
1304
+ //
1305
+ // The exception is an any-like `ui_type`. Those schemas say
1306
+ // `ui_type: 'any'` precisely so the user can pick a concrete type, and
1307
+ // that pick lives on the field's stored `type` — letting 'any' win would
1308
+ // pin the row to the untyped editor forever.
1309
+ //
1310
+ // The trailing fallbacks keep the row rendering when a server-driven
1311
+ // schema has not arrived yet (`type` undefined) instead of crashing.
1312
+ var schemaUiType = (_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type;
1313
+ var uiTypeIsAnyLike = schemaUiType === 'any' || schemaUiType === 'auto';
1314
+ var resolvedType = (schemaUiType && !uiTypeIsAnyLike ? schemaUiType : undefined) ||
1315
+ type ||
1316
+ schemaUiType ||
1317
+ ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type) ||
1318
+ 'any';
1251
1319
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(function () {
1252
1320
  var _a;
1253
1321
  var schemaMsgs = (suppressSchemaMessages ?
@@ -1282,7 +1350,7 @@ var FormEngine = function (_a) {
1282
1350
  (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { disabled: readOnly, icon: 'DeleteBinLine', effect: NegativeColorEffect, fixed: true, onClick: function () { return handleRemoveOperator(optionName, fixedValue, index); } })
1283
1351
  : null] }, index));
1284
1352
  }) }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 })] })
1285
- : null, (0, react_1.createElement)(TemplateField_1.TemplateField, __assign({ fluid: true }, options === null || options === void 0 ? void 0 : options[optionName], resolveInheritProps((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.inherit_props, availableOptions, inheritedFromParent), {
1353
+ : null, (0, react_1.createElement)(TemplateField_1.TemplateField, __assign({ fluid: true }, options === null || options === void 0 ? void 0 : options[optionName], resolveInheritProps((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.inherit_props, availableOptions, inheritedFromParent), {
1286
1354
  // qorus#347-followup (scope forwarding): merge accumulated
1287
1355
  // inheritance (`inheritedFromParent`) with THIS field's freshly
1288
1356
  // resolved inherit_props, and pass down as a single bag so any
@@ -1294,26 +1362,30 @@ var FormEngine = function (_a) {
1294
1362
  // `inherit_props: { language: 'language' }`, the list renderer
1295
1363
  // forwards it into each row, and the row's body resolves against
1296
1364
  // the accumulated bag.
1297
- inheritedFromParent: __assign(__assign({}, inheritedFromParent), resolveInheritProps((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.inherit_props, availableOptions, inheritedFromParent)),
1365
+ inheritedFromParent: __assign(__assign({}, inheritedFromParent), resolveInheritProps((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.inherit_props, availableOptions, inheritedFromParent)),
1298
1366
  // Propagate compact so an arg_schema field renders a COMPACT sub-form
1299
1367
  // (consistent with the parent) rather than the classic FormEngine.
1300
1368
  compact: compact,
1301
1369
  // SEAM: forwarded through TemplateField's rest-spread to AutoFormField,
1302
1370
  // which renders consumer-injected editors by field type/ui_type.
1303
- componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.supports_templates)), allowFunctions: !!((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.supports_expressions),
1371
+ componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.supports_templates)), allowFunctions: !!((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.supports_expressions),
1304
1372
  // reqraft: form-level expression fields get the Visual/Text shell
1305
1373
  // (DPQL text mode); opt out per-form via `templateFieldProps`.
1306
- allowTextExpressions: true, allowCustomValues: ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.supports_custom_values) !== false && type !== 'any', templates: templates.value }, (0, exports.getTypeAndCanBeNull)(type, (_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.allowed_values, other.op), { ui_type: type, name: optionName, uniqueName: "".concat(uniqueName ? "".concat(uniqueName, ".") : "".concat(name ? "".concat(name, ".") : '')).concat(optionName), onChange:
1374
+ allowTextExpressions: true, allowCustomValues: ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.supports_custom_values) !== false && resolvedType !== 'any', templates: templates.value }, (0, exports.getTypeAndCanBeNull)(
1375
+ // The RENDERER type picks the editor — the storage type lives on
1376
+ // the value envelope. Passing storage here rendered a `richtext`
1377
+ // field as a plain string input.
1378
+ resolvedType, (_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.allowed_values, other.op), { ui_type: resolvedType, name: optionName, uniqueName: "".concat(uniqueName ? "".concat(uniqueName, ".") : "".concat(name ? "".concat(name, ".") : '')).concat(optionName), onChange:
1307
1379
  // Identity-stable on purpose: the typed fields debounce on
1308
1380
  // `[localValue, onChange]` — an inline lambda resets the pending emit
1309
1381
  // every render and the typed value can starve.
1310
- handleValueChange, key: optionName, arg_schema: (_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.arg_schema, noSoft: !!(rest === null || rest === void 0 ? void 0 : rest.options), value: other.value, isFunction: other.is_expression, isDefaultFunction: ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.default_view) === 'expression', sensitive: (_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.sensitive, default_value: (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), isDefaultTemplate: ((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.default_view) === 'template', allowed_values: (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.allowed_values, disabled: ((_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.disabled) ||
1382
+ handleValueChange, key: optionName, arg_schema: (_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.arg_schema, noSoft: !!(rest === null || rest === void 0 ? void 0 : rest.options), value: other.value, isFunction: other.is_expression, isDefaultFunction: ((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.default_view) === 'expression', sensitive: (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.sensitive, default_value: (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), isDefaultTemplate: ((_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.default_view) === 'template', allowed_values: (_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.allowed_values, disabled: ((_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.disabled) ||
1311
1383
  readOnly ||
1312
- !(0, validations_1.hasAllDependenciesFullfilled)((_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.ui_type) === 'any' ?
1384
+ !(0, validations_1.hasAllDependenciesFullfilled)((_s = options === null || options === void 0 ? void 0 : options[optionName]) === null || _s === void 0 ? void 0 : _s.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_t = options === null || options === void 0 ? void 0 : options[optionName]) === null || _t === void 0 ? void 0 : _t.ui_type) === 'any' ?
1313
1385
  getCustomMenuTemplateItems(optionName)
1314
- : undefined }, templateFieldProps)), (0, jsx_runtime_1.jsx)(OptionFieldMessages_1.OptionFieldMessages, { schema: options || {}, allOptions: availableOptions, name: optionName, option: __assign({ type: type }, other), getType: getTypeForOption }), operators && (0, size_1.default)(operators) && (0, size_1.default)(other.op) ?
1386
+ : undefined }, templateFieldProps)), (0, jsx_runtime_1.jsx)(OptionFieldMessages_1.OptionFieldMessages, { schema: options || {}, allOptions: availableOptions, name: optionName, option: __assign({ type: resolvedType }, other), getType: getTypeForOption }), operators && (0, size_1.default)(operators) && (0, size_1.default)(other.op) ?
1315
1387
  (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreMessage, { size: 'small', children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreTagGroup, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', labelKey: 'WHERE', label: optionName }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', labelKey: 'IS', label: operatorParts.join(' ') }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', intent: 'info', label: other.value ?
1316
- type === 'richtext' ?
1388
+ resolvedType === 'richtext' ?
1317
1389
  (0, common_1.richtextToString)(other.value)
1318
1390
  : JSON.stringify(other.value)
1319
1391
  : '' })] }) })] })
@@ -1343,7 +1415,7 @@ var FormEngine = function (_a) {
1343
1415
  ]);
1344
1416
  // Compact (read-first) rendering.
1345
1417
  // Theme-derived colours so the flat-row layout adapts to light/dark/custom themes.
1346
- var cText = ((_b = theme === null || theme === void 0 ? void 0 : theme.text) === null || _b === void 0 ? void 0 : _b.color) || '#f1f0ee';
1418
+ var cText = ((_c = theme === null || theme === void 0 ? void 0 : theme.text) === null || _c === void 0 ? void 0 : _c.color) || '#f1f0ee';
1347
1419
  // Text emphasis tiers via reqore's readable-colour helper (key = full readable
1348
1420
  // text, muted = its dimmed variant, faint = the dimmed variant softened
1349
1421
  // further) instead of hand-rolled hex-alpha suffixes on the raw text colour.
@@ -1352,10 +1424,10 @@ var FormEngine = function (_a) {
1352
1424
  var cFaint = "".concat(cMuted, "99");
1353
1425
  var cDivider = "".concat(cText, "14");
1354
1426
  var cHover = "".concat(cText, "0d");
1355
- var cDanger = ((_c = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _c === void 0 ? void 0 : _c.danger) || '#e35a5a';
1356
- var cWarning = ((_d = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _d === void 0 ? void 0 : _d.warning) || '#ffdf34';
1357
- var cInfo = ((_f = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _f === void 0 ? void 0 : _f.info) || '#3b8eea';
1358
- var cSuccess = ((_g = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _g === void 0 ? void 0 : _g.success) || '#36b37e';
1427
+ var cDanger = ((_d = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _d === void 0 ? void 0 : _d.danger) || '#e35a5a';
1428
+ var cWarning = ((_f = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _f === void 0 ? void 0 : _f.warning) || '#ffdf34';
1429
+ var cInfo = ((_g = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _g === void 0 ? void 0 : _g.info) || '#3b8eea';
1430
+ var cSuccess = ((_h = theme === null || theme === void 0 ? void 0 : theme.intents) === null || _h === void 0 ? void 0 : _h.success) || '#36b37e';
1359
1431
  var cBg = (theme === null || theme === void 0 ? void 0 : theme.main) || '#181818';
1360
1432
  var cRowBg = (0, colors_1.changeDarkness)((0, colors_1.getMainBackgroundColor)(theme), 0.01);
1361
1433
  var cGroupLine = "".concat(cText, "1f");
@@ -1394,6 +1466,8 @@ var FormEngine = function (_a) {
1394
1466
  getTypeForOption: getTypeForOption,
1395
1467
  isOptionValid: isOptionValid,
1396
1468
  confirmAction: confirmAction,
1469
+ optionActions: optionActions,
1470
+ collapseOptionActions: collapseOptionActions,
1397
1471
  renderOption: renderOption,
1398
1472
  theme: theme,
1399
1473
  cText: cText,
@@ -1438,6 +1512,8 @@ var FormEngine = function (_a) {
1438
1512
  getTypeForOption,
1439
1513
  isOptionValid,
1440
1514
  confirmAction,
1515
+ optionActions,
1516
+ collapseOptionActions,
1441
1517
  renderOption,
1442
1518
  theme,
1443
1519
  cText,
@@ -1560,7 +1636,7 @@ var FormEngine = function (_a) {
1560
1636
  var isUnset_1 = function (name) { var _a; return (0, readFirst_1.isOptionValueEmpty)((_a = shownOptions[name]) === null || _a === void 0 ? void 0 : _a.value); };
1561
1637
  var isFieldInvalid_1 = function (name) {
1562
1638
  var _a, _b, _c;
1563
- return !isOptionValid(name, (((_a = options === null || options === void 0 ? void 0 : options[name]) === null || _a === void 0 ? void 0 : _a.ui_type) || ((_b = options === null || options === void 0 ? void 0 : options[name]) === null || _b === void 0 ? void 0 : _b.type)), (_c = shownOptions[name]) === null || _c === void 0 ? void 0 : _c.value);
1639
+ return !isOptionValid(name, getOptionFieldStorageType(name, (_a = shownOptions[name]) === null || _a === void 0 ? void 0 : _a.type, options, operators, (_b = shownOptions[name]) === null || _b === void 0 ? void 0 : _b.op, isRendererOnly), (_c = shownOptions[name]) === null || _c === void 0 ? void 0 : _c.value);
1564
1640
  };
1565
1641
  var comparator_1 = function (a, b) {
1566
1642
  switch (compactSort) {
@@ -1648,15 +1724,12 @@ var FormEngine = function (_a) {
1648
1724
  // rows — no wrapper — so the value surface applies normally; the rail + nodes
1649
1725
  // are drawn per member). Narrow stacks fall back to flat rows.
1650
1726
  var renderGroupRows = function (names) {
1651
- var renderRow = function (entry, clustered, clusterFirst, clusterLast) {
1652
- var _a, _b;
1653
- return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1654
- {
1655
- type: (((_a = options === null || options === void 0 ? void 0 : options[entry.name]) === null || _a === void 0 ? void 0 : _a.ui_type) || ((_b = options === null || options === void 0 ? void 0 : options[entry.name]) === null || _b === void 0 ? void 0 : _b.type)),
1656
- value: undefined,
1657
- }
1658
- : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name));
1659
- };
1727
+ var renderRow = function (entry, clustered, clusterFirst, clusterLast) { return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1728
+ {
1729
+ type: getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[entry.name], isRendererOnly),
1730
+ value: undefined,
1731
+ }
1732
+ : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name)); };
1660
1733
  // (Clustering runs in narrow mode too now — the "One of the below is
1661
1734
  // required" box wraps the members regardless of width; it no longer relies
1662
1735
  // on a contiguous rail.)
@@ -1822,13 +1895,11 @@ var FormEngine = function (_a) {
1822
1895
  options[optionName].stretch,
1823
1896
  size: 'small',
1824
1897
  floatingActions: true,
1825
- actions: __spreadArray(__spreadArray([], (typeof optionActions === 'function' ?
1826
- optionActions({
1827
- name: optionName,
1828
- schema: options[optionName],
1829
- value: availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[optionName],
1830
- })
1831
- : (optionActions !== null && optionActions !== void 0 ? optionActions : [])), true), [
1898
+ actions: __spreadArray(__spreadArray([], (0, optionActions_1.resolveOptionActions)(optionActions, {
1899
+ name: optionName,
1900
+ schema: options[optionName],
1901
+ value: availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[optionName],
1902
+ }), true), [
1832
1903
  {
1833
1904
  size: 'tiny',
1834
1905
  icon: 'FullscreenLine',