@qoretechnologies/reqraft 0.10.4 → 0.10.6
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/.claude/CLAUDE.md +5 -0
- package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
- package/dist/components/form/engine/CompactRow.js +7 -9
- package/dist/components/form/engine/CompactRow.js.map +1 -1
- package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
- package/dist/components/form/engine/CompactToolbar.js +8 -27
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +10 -2
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +127 -44
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +8 -3
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.js +4 -1
- package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
- package/package.json +4 -3
- package/src/components/form/engine/CompactRow.tsx +18 -25
- package/src/components/form/engine/CompactToolbar.tsx +4 -17
- package/src/components/form/engine/FormEngine.stories.tsx +219 -10
- package/src/components/form/engine/FormEngine.tsx +126 -16
- package/src/components/form/engine/compactRowStyles.ts +33 -29
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +9 -2
- package/src/components/form/fields/auto/AutoFormField.tsx +3 -0
|
@@ -129,6 +129,35 @@ var compactRowStyles_1 = require("./compactRowStyles");
|
|
|
129
129
|
var OptionFieldMessages_1 = require("./OptionFieldMessages");
|
|
130
130
|
var OptionsHelpDialog_1 = require("./OptionsHelpDialog");
|
|
131
131
|
var readFirst_1 = require("./readFirst");
|
|
132
|
+
/**
|
|
133
|
+
* Resolve a field's `inherit_props` map against the current available
|
|
134
|
+
* options, producing a `{ propName: siblingValue }` hash suitable for
|
|
135
|
+
* spreading onto the field's renderer.
|
|
136
|
+
*
|
|
137
|
+
* For each entry `<prop-name-on-renderer> -> <sibling-field-name>`, the
|
|
138
|
+
* sibling's current value (`availableOptions[siblingName]?.value`) is
|
|
139
|
+
* forwarded under the receiving prop name. Missing siblings emit
|
|
140
|
+
* `undefined`, which the renderer's prop type can treat as "no hint".
|
|
141
|
+
*
|
|
142
|
+
* Designed to be JSON-pure: no closures, no transformations. Renderers
|
|
143
|
+
* decide how to use the forwarded value (e.g. the consumer-injected
|
|
144
|
+
* `code-editor` renderer maps a `language: "qore"` prop to its
|
|
145
|
+
* highlighter mode).
|
|
146
|
+
*
|
|
147
|
+
* Mirrored in qorus-ide `src/components/Field/systemOptions.tsx`; keep
|
|
148
|
+
* the two in sync (see qorus-ide's `.claude/CLAUDE.md`).
|
|
149
|
+
*/
|
|
150
|
+
var resolveInheritProps = function (inheritProps, availableOptions) {
|
|
151
|
+
var _a;
|
|
152
|
+
if (!inheritProps || !availableOptions)
|
|
153
|
+
return {};
|
|
154
|
+
var out = {};
|
|
155
|
+
for (var propName in inheritProps) {
|
|
156
|
+
var siblingName = inheritProps[propName];
|
|
157
|
+
out[propName] = (_a = availableOptions[siblingName]) === null || _a === void 0 ? void 0 : _a.value;
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
};
|
|
132
161
|
var NegativeColorEffect = {
|
|
133
162
|
gradient: {
|
|
134
163
|
colors: { 0: 'danger', 100: 'danger:darken:2' },
|
|
@@ -297,44 +326,44 @@ var FormEngine = function (_a) {
|
|
|
297
326
|
var _b, _c, _d, _f, _g;
|
|
298
327
|
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
|
|
299
328
|
isValid = _a.isValid, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
300
|
-
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.commitMode, commitMode =
|
|
301
|
-
var
|
|
329
|
+
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, _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, 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", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "componentOverrides"]);
|
|
330
|
+
var _p = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _p[0], setOptions = _p[1];
|
|
302
331
|
// optionsLoader lifecycle: loading feeds the skeleton gate, error the banner.
|
|
303
|
-
var
|
|
304
|
-
var
|
|
332
|
+
var _q = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _q[0], setOptionsLoading = _q[1];
|
|
333
|
+
var _r = (0, react_2.useState)(), optionsError = _r[0], setOptionsError = _r[1];
|
|
305
334
|
// Operators: prop-provided (compact) or fetched via operatorsUrl (dpql,
|
|
306
335
|
// ported from IDE Options) — the fetch overrides the seeded prop value.
|
|
307
|
-
var
|
|
336
|
+
var _s = (0, react_2.useState)(operatorsProp), operators = _s[0], setOperators = _s[1];
|
|
308
337
|
// Remote-fetch loading (ported from IDE Options); only relevant when one of
|
|
309
338
|
// the fetch urls is set — schema-as-props consumers never see the skeleton.
|
|
310
|
-
var
|
|
339
|
+
var _t = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _t[0], setLoading = _t[1];
|
|
311
340
|
var confirmAction = (0, reqore_1.useReqoreProperty)('confirmAction');
|
|
312
341
|
var theme = (0, reqore_1.useReqoreTheme)();
|
|
313
|
-
var
|
|
314
|
-
var
|
|
342
|
+
var _u = (0, react_2.useState)(), focusedEditing = _u[0], setFocusedEditing = _u[1];
|
|
343
|
+
var _v = (0, react_2.useState)(false), showFieldTypes = _v[0], setShowFieldTypes = _v[1];
|
|
315
344
|
// Global toggle (toolbar ⓘ): reveal the short-description info panel on every
|
|
316
345
|
// field that has a short_desc. Per-row ⓘ overrides still win over it.
|
|
317
346
|
// Global field-info visibility, tri-state: `undefined` = default (critical
|
|
318
347
|
// messages auto-open, the rest closed); `true` = show all; `false` = hide all
|
|
319
348
|
// (even message fields). The toolbar ⓘ drives it.
|
|
320
|
-
var
|
|
321
|
-
var
|
|
322
|
-
var
|
|
349
|
+
var _w = (0, react_2.useState)(undefined), showAllDescriptions = _w[0], setShowAllDescriptions = _w[1];
|
|
350
|
+
var _x = (0, react_2.useState)(), showHelpForOption = _x[0], setShowHelpForOption = _x[1];
|
|
351
|
+
var _y = (0, react_2.useState)(false), showInvalidOptionsOnly = _y[0], setShowInvalidOptionsOnly = _y[1];
|
|
323
352
|
// Which options are expanded into their editor (several can be open at once).
|
|
324
|
-
var
|
|
353
|
+
var _z = (0, react_2.useState)([]), expandedOptions = _z[0], setExpandedOptions = _z[1];
|
|
325
354
|
// Remembers each row's last settled status box, so an actively-edited field
|
|
326
355
|
// stays put when its status flips (e.g. becomes valid) instead of jumping to
|
|
327
356
|
// another box mid-edit and stealing focus. Keyed by option name.
|
|
328
357
|
var settledBucket = (0, react_2.useRef)({});
|
|
329
358
|
// Measured form width (not viewport — the form lives in drawers/panels of
|
|
330
359
|
// arbitrary width) drives the stacked narrow layout.
|
|
331
|
-
var
|
|
360
|
+
var _0 = (0, react_use_1.useMeasure)(), compactWrapRef = _0[0], compactWrapWidth = _0[1].width;
|
|
332
361
|
// Own handle on the scroll wrap (useMeasure's ref is a callback, no `.current`)
|
|
333
362
|
// so the label-column measurement can publish its CSS var on the element. It's
|
|
334
363
|
// STATE, not a ref: the wrap mounts only after the loading-skeleton gate
|
|
335
364
|
// resolves, so the measurement effect must re-run when the node appears — a
|
|
336
365
|
// ref wouldn't retrigger it.
|
|
337
|
-
var
|
|
366
|
+
var _1 = (0, react_2.useState)(null), compactWrapNode = _1[0], setCompactWrapNode = _1[1];
|
|
338
367
|
var setCompactWrap = (0, react_2.useCallback)(function (node) {
|
|
339
368
|
compactWrapRef(node);
|
|
340
369
|
setCompactWrapNode(function (prev) { return (prev === node ? prev : node); });
|
|
@@ -371,15 +400,21 @@ var FormEngine = function (_a) {
|
|
|
371
400
|
var readRowHeights = (0, react_2.useRef)({});
|
|
372
401
|
// Required-groups linkage: hovering a group chip highlights every member row;
|
|
373
402
|
// clicking a sibling in the chip's popover scrolls to it and flashes it.
|
|
374
|
-
var
|
|
375
|
-
var
|
|
403
|
+
var _2 = (0, react_2.useState)([]), highlightedOptions = _2[0], setHighlightedOptions = _2[1];
|
|
404
|
+
var _3 = (0, react_2.useState)([]), flashedOptions = _3[0], setFlashedOptions = _3[1];
|
|
376
405
|
var flashTimeout = (0, react_2.useRef)();
|
|
377
406
|
var flashOptions = (0, react_2.useCallback)(function (optionNames, scrollToFirst) {
|
|
378
|
-
var _a;
|
|
379
407
|
if (scrollToFirst === void 0) { scrollToFirst = false; }
|
|
380
408
|
if (scrollToFirst && optionNames[0]) {
|
|
381
|
-
|
|
382
|
-
|
|
409
|
+
// Defer to the next frame: when this fires for a field that just changed
|
|
410
|
+
// panels, its row has only just re-mounted in the new box — scrolling in the
|
|
411
|
+
// same tick targets the stale (pre-move) layout, so the page doesn't budge.
|
|
412
|
+
// A rAF lets the new position settle first.
|
|
413
|
+
requestAnimationFrame(function () {
|
|
414
|
+
var _a;
|
|
415
|
+
(_a = document
|
|
416
|
+
.querySelector(".readfirst-row[data-field=\"".concat(optionNames[0], "\"]"))) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
|
417
|
+
});
|
|
383
418
|
}
|
|
384
419
|
setFlashedOptions(optionNames);
|
|
385
420
|
clearTimeout(flashTimeout.current);
|
|
@@ -387,18 +422,37 @@ var FormEngine = function (_a) {
|
|
|
387
422
|
}, []);
|
|
388
423
|
var flashOption = (0, react_2.useCallback)(function (optionName) { return flashOptions([optionName], true); }, [flashOptions]);
|
|
389
424
|
(0, react_2.useEffect)(function () { return function () { return clearTimeout(flashTimeout.current); }; }, []);
|
|
425
|
+
// Follow a field across panels: when its status bucket changes — e.g. you fill
|
|
426
|
+
// an optional field and it jumps to Set / Needs attention — scroll to its new
|
|
427
|
+
// row and flash it so it's easy to keep track of. `settledBucket` holds each
|
|
428
|
+
// field's current panel (frozen while the field is being edited, it re-buckets
|
|
429
|
+
// on collapse), so diffing it after every render catches the move the instant it
|
|
430
|
+
// lands in the new panel. Runs every render; the diff is cheap and only fires a
|
|
431
|
+
// scroll on an ACTUAL move of a non-expanded field.
|
|
432
|
+
var prevSettledBucket = (0, react_2.useRef)({});
|
|
433
|
+
(0, react_2.useEffect)(function () {
|
|
434
|
+
if (!compact)
|
|
435
|
+
return;
|
|
436
|
+
var cur = settledBucket.current;
|
|
437
|
+
var prev = prevSettledBucket.current;
|
|
438
|
+
var moved = Object.keys(cur).find(function (name) { return prev[name] && prev[name] !== cur[name] && !expandedOptions.includes(name); });
|
|
439
|
+
prevSettledBucket.current = __assign({}, cur);
|
|
440
|
+
if (moved) {
|
|
441
|
+
flashOptions([moved], true);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
390
444
|
var compactNarrow = !!compactWrapWidth && compactWrapWidth < 480;
|
|
391
445
|
// Info panels auto-open on Tier-1 content; the per-row user override sticks.
|
|
392
|
-
var
|
|
446
|
+
var _4 = (0, react_2.useState)({}), infoPanelOverrides = _4[0], setInfoPanelOverrides = _4[1];
|
|
393
447
|
// Toolbar filters affect the listed rows only — the meter reflects the full set.
|
|
394
|
-
var
|
|
395
|
-
var
|
|
448
|
+
var _5 = (0, react_2.useState)(false), requiredOnly = _5[0], setRequiredOnly = _5[1];
|
|
449
|
+
var _6 = (0, react_2.useState)(''), compactQuery = _6[0], setCompactQuery = _6[1];
|
|
396
450
|
// Compact field sort (Fields menu → "Sort by"); 'schema' = declared order.
|
|
397
|
-
var
|
|
398
|
-
var
|
|
451
|
+
var _7 = (0, react_2.useState)('schema'), compactSort = _7[0], setCompactSort = _7[1];
|
|
452
|
+
var _8 = (0, react_2.useState)(function () { return ({
|
|
399
453
|
fields: (0, exports.fixOptions)(value, options || {}),
|
|
400
454
|
meta: undefined,
|
|
401
|
-
}); }), localValue =
|
|
455
|
+
}); }), localValue = _8[0], setLocalValue = _8[1];
|
|
402
456
|
var originalValue = (0, react_2.useRef)();
|
|
403
457
|
// Track the last value we emitted via onChange so we can skip re-applying fixOptions
|
|
404
458
|
// when the parent echoes it back as the new value prop (controlled component loop prevention)
|
|
@@ -407,7 +461,7 @@ var FormEngine = function (_a) {
|
|
|
407
461
|
originalValue.current = localValue.fields;
|
|
408
462
|
}
|
|
409
463
|
var unavailableOptionsCount = (0, react_2.useRef)(0);
|
|
410
|
-
var
|
|
464
|
+
var _9 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _9.compactValue, typesLoading = _9.loading;
|
|
411
465
|
var templates = (0, useTemplates_1.useTemplates)(allowTemplates, rest.stringTemplates, interfaceContext);
|
|
412
466
|
(0, react_2.useEffect)(function () {
|
|
413
467
|
if ((0, lodash_1.isEqual)(localValue.fields, value)) {
|
|
@@ -730,6 +784,10 @@ var FormEngine = function (_a) {
|
|
|
730
784
|
meta: undefined,
|
|
731
785
|
};
|
|
732
786
|
});
|
|
787
|
+
// Collapse it too: a removed field drops back to the (collapsed) Optional box
|
|
788
|
+
// as a quiet addable row — if it was being edited, that editor must close
|
|
789
|
+
// rather than linger as an open editor for a field that's no longer added.
|
|
790
|
+
setExpandedOptions(function (prev) { return prev.filter(function (name) { return name !== optionName; }); });
|
|
733
791
|
}, []);
|
|
734
792
|
var handleAddOptionalFieldChange = (0, react_2.useCallback)(function (_name, optionName) {
|
|
735
793
|
var _a, _b, _c;
|
|
@@ -1076,7 +1134,7 @@ var FormEngine = function (_a) {
|
|
|
1076
1134
|
// The info panel below the row keeps showing schema messages while editing —
|
|
1077
1135
|
// rendering them in the editor too would balloon a one-line edit.
|
|
1078
1136
|
suppressSchemaMessages) {
|
|
1079
|
-
var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
1137
|
+
var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
1080
1138
|
var type = _a.type, other = __rest(_a, ["type"]);
|
|
1081
1139
|
var operatorParts = (0, exports.fixOperatorValue)(other.op);
|
|
1082
1140
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(function () {
|
|
@@ -1111,22 +1169,22 @@ var FormEngine = function (_a) {
|
|
|
1111
1169
|
(0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { disabled: readOnly, icon: 'DeleteBinLine', effect: NegativeColorEffect, fixed: true, onClick: function () { return handleRemoveOperator(optionName, fixedValue, index); } })
|
|
1112
1170
|
: null] }, index));
|
|
1113
1171
|
}) }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 })] })
|
|
1114
|
-
: null, (0, react_1.createElement)(TemplateField_1.TemplateField, __assign({ fluid: true }, options === null || options === void 0 ? void 0 : options[optionName], {
|
|
1172
|
+
: 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), {
|
|
1115
1173
|
// Propagate compact so an arg_schema field renders a COMPACT sub-form
|
|
1116
1174
|
// (consistent with the parent) rather than the classic FormEngine.
|
|
1117
1175
|
compact: compact,
|
|
1118
1176
|
// SEAM: forwarded through TemplateField's rest-spread to AutoFormField,
|
|
1119
1177
|
// which renders consumer-injected editors by field type/ui_type.
|
|
1120
|
-
componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((
|
|
1178
|
+
componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.supports_templates)), allowFunctions: !!((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.supports_expressions),
|
|
1121
1179
|
// reqraft: form-level expression fields get the Visual/Text shell
|
|
1122
1180
|
// (DPQL text mode); opt out per-form via `templateFieldProps`.
|
|
1123
|
-
allowTextExpressions: true, allowCustomValues: ((
|
|
1181
|
+
allowTextExpressions: true, allowCustomValues: ((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.supports_custom_values) !== false && type !== 'any', templates: templates.value }, (0, exports.getTypeAndCanBeNull)(type, (_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.allowed_values, other.op), { ui_type: type, name: optionName, uniqueName: "".concat(uniqueName ? "".concat(uniqueName, ".") : "".concat(name ? "".concat(name, ".") : '')).concat(optionName), onChange:
|
|
1124
1182
|
// Identity-stable on purpose: the typed fields debounce on
|
|
1125
1183
|
// `[localValue, onChange]` — an inline lambda resets the pending emit
|
|
1126
1184
|
// every render and the typed value can starve.
|
|
1127
|
-
handleValueChange, key: optionName, arg_schema: (
|
|
1185
|
+
handleValueChange, key: optionName, arg_schema: (_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.arg_schema, noSoft: !!(rest === null || rest === void 0 ? void 0 : rest.options), value: other.value, isFunction: other.is_expression, isDefaultFunction: ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.default_view) === 'expression', sensitive: (_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.sensitive, default_value: (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), isDefaultTemplate: ((_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.default_view) === 'template', allowed_values: (_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.allowed_values, disabled: ((_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.disabled) ||
|
|
1128
1186
|
readOnly ||
|
|
1129
|
-
!(0, validations_1.hasAllDependenciesFullfilled)((
|
|
1187
|
+
!(0, validations_1.hasAllDependenciesFullfilled)((_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.ui_type) === 'any' ?
|
|
1130
1188
|
getCustomMenuTemplateItems(optionName)
|
|
1131
1189
|
: 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) ?
|
|
1132
1190
|
(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 ?
|
|
@@ -1349,15 +1407,18 @@ var FormEngine = function (_a) {
|
|
|
1349
1407
|
pushRow(optionName, false);
|
|
1350
1408
|
}
|
|
1351
1409
|
});
|
|
1352
|
-
//
|
|
1353
|
-
//
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1410
|
+
// Surface EVERY not-yet-added optional field as an addable (hidden) row, so
|
|
1411
|
+
// the whole schema is browsable inline — they all land in the Optional box
|
|
1412
|
+
// (hidden ⇒ 'optional' bucket) instead of being buried in the Fields menu.
|
|
1413
|
+
// Narrowed by the same filters as the listed rows (search query + required-
|
|
1414
|
+
// only). availableOptions (listed) and filteredOptions (these) are disjoint —
|
|
1415
|
+
// the former is built from fixedValue keys, the latter excludes them — so a
|
|
1416
|
+
// field is never both a listed and a hidden row.
|
|
1417
|
+
(0, lodash_1.forEach)(filteredOptions, function (_schema, optionName) {
|
|
1418
|
+
if (matchesFilters(optionName)) {
|
|
1419
|
+
pushRow(optionName, true);
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1361
1422
|
// User sort (Fields menu → "Sort by"), applied WITHIN each group so the
|
|
1362
1423
|
// group sections and the required-group rails are preserved. Schema order is
|
|
1363
1424
|
// the default and the stable tiebreaker (Array.sort is stable, and each
|
|
@@ -1492,11 +1553,25 @@ var FormEngine = function (_a) {
|
|
|
1492
1553
|
return ((0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledRequiredClusterBox, { className: 'options-readfirst-required-cluster', "$border": "".concat(cWarning, "33"), "$tint": "".concat(cWarning, "0d"), children: [(0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledRequiredClusterHeader, { "$color": cWarning, children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreIcon, { icon: 'LinkM', size: '11px', style: { color: cWarning } }), "One of the below is required"] }), railed] }, grp));
|
|
1493
1554
|
});
|
|
1494
1555
|
};
|
|
1495
|
-
return ((0, jsx_runtime_1.jsx)(exports.OptionsContext.Provider, { value: { schema: options, value: availableOptions }, children: (0, jsx_runtime_1.jsx)(compactRowContext_1.CompactRowContext.Provider, { value: compactRowContextValue, children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreErrorBoundary, { children: [showHelpForOption && ((0, jsx_runtime_1.jsx)(OptionsHelpDialog_1.OptionsHelpDialog, { onClose: function () { return setShowHelpForOption(undefined); }, option: options[showHelpForOption] })), (0, jsx_runtime_1.jsx)(compactToolbarContext_1.CompactToolbarContext.Provider, { value: compactToolbarContextValue, children: (0, jsx_runtime_1.jsxs)(StyledCompactWrap, { ref: setCompactWrap, className: 'options-readfirst-scroll', "$flush": compactFlush, children: [(0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledCompactPanel
|
|
1556
|
+
return ((0, jsx_runtime_1.jsx)(exports.OptionsContext.Provider, { value: { schema: options, value: availableOptions }, children: (0, jsx_runtime_1.jsx)(compactRowContext_1.CompactRowContext.Provider, { value: compactRowContextValue, children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreErrorBoundary, { children: [showHelpForOption && ((0, jsx_runtime_1.jsx)(OptionsHelpDialog_1.OptionsHelpDialog, { onClose: function () { return setShowHelpForOption(undefined); }, option: options[showHelpForOption] })), (0, jsx_runtime_1.jsx)(compactToolbarContext_1.CompactToolbarContext.Provider, { value: compactToolbarContextValue, children: (0, jsx_runtime_1.jsxs)(StyledCompactWrap, { ref: setCompactWrap, className: 'options-readfirst-scroll', "$flush": compactFlush || compactNested, children: [(0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledCompactPanel
|
|
1557
|
+
// The top-level form scrolls, so its toolbar STICKS and carries a
|
|
1558
|
+
// dark blurred backdrop so content ghosts cleanly beneath it. A
|
|
1559
|
+
// nested (arg_schema) sub-form owns no scroll context — drop the
|
|
1560
|
+
// sticky, the backdrop, and the stacking context so its header is
|
|
1561
|
+
// transparent inside the parent's card.
|
|
1562
|
+
, { "$headerBg": compactNested ? 'transparent' : headerBg, "$nested": compactNested, flat: true,
|
|
1563
|
+
// No panel background: the form sits transparently on whatever
|
|
1564
|
+
// hosts it (page, drawer, or — for an arg_schema field — the
|
|
1565
|
+
// parent's edit card) instead of stacking its own dark surface.
|
|
1566
|
+
// The status boxes keep their own tints; the sticky toolbar keeps
|
|
1567
|
+
// its blurred header via the $headerBg override.
|
|
1568
|
+
transparent: true, stickyHeader: !compactNested, padded: false, actions: compactHeaderActions, contentStyle: {
|
|
1496
1569
|
display: 'flex',
|
|
1497
1570
|
flexFlow: 'column',
|
|
1498
1571
|
gap: '10px',
|
|
1499
|
-
|
|
1572
|
+
// Nested sub-form: no surrounding panel padding (it's flush in
|
|
1573
|
+
// the parent card); top-level keeps a small bottom gutter.
|
|
1574
|
+
padding: compactNested ? '0' : '0 0 12px',
|
|
1500
1575
|
}, children: [(0, size_1.default)(groupKeys) === 0 ?
|
|
1501
1576
|
(0, jsx_runtime_1.jsx)(reqore_1.ReqoreMessage, { flat: true, opaque: false, size: 'small', children: "No fields match the current filters." })
|
|
1502
1577
|
: null, STATUS_BOXES.map(function (box) {
|
|
@@ -1513,7 +1588,15 @@ var FormEngine = function (_a) {
|
|
|
1513
1588
|
var boxBg = box.key === 'optional' ?
|
|
1514
1589
|
(0, colors_1.changeDarkness)((0, colors_1.getMainBackgroundColor)(theme), 0.06)
|
|
1515
1590
|
: undefined;
|
|
1516
|
-
return ((0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBox, { "$accent": accent, "$bg": boxBg, flat: true, minimal: true, collapseButtonProps: { flat: true, minimal: true, size: 'small' }, collapsible: true,
|
|
1591
|
+
return ((0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBox, { "$accent": accent, "$bg": boxBg, flat: true, minimal: true, collapseButtonProps: { flat: true, minimal: true, size: 'small' }, collapsible: true,
|
|
1592
|
+
// The Optional box now holds every not-yet-added field, so
|
|
1593
|
+
// it starts COLLAPSED to keep the form focused on what's in
|
|
1594
|
+
// use. But a SEARCH must surface matching addable fields —
|
|
1595
|
+
// and ReqorePanel unmounts collapsed content — so force it
|
|
1596
|
+
// open whenever a query is active. (isCollapsed is the
|
|
1597
|
+
// panel's controllable state; manual toggling still works
|
|
1598
|
+
// when no query is set.)
|
|
1599
|
+
isCollapsed: box.key === 'optional' && !query, label: (0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledGroupHeader, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { effect: { weight: 'bold' }, size: 'normal', children: box.label }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', minimal: true, compact: true, intent: box.intent, label: String(count) })] }), icon: box.icon, className: 'options-readfirst-group', padded: false, contentStyle: { padding: '4px 4px 6px' }, children: (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledGroupBody, { "$divider": cDivider, "$hover": cHover, "$focus": cWarning, "$success": cSuccess, "$rowBg": cRowBg, "$lineColor": cGroupLine, className: compactNarrow ? 'readfirst-narrow' : undefined, children: groupsInBox.map(function (groupName) {
|
|
1517
1600
|
var groupConfig = groups === null || groups === void 0 ? void 0 : groups[groupName];
|
|
1518
1601
|
return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [showGroupSubLabel(groupName) ?
|
|
1519
1602
|
(0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBoxGroupLabel, { children: (0, readFirst_1.getOptionGroupLabel)(groupName, groups) })
|