@qoretechnologies/reqraft 0.10.45 → 0.10.46-pr.107.g08386aa

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.
@@ -1816,7 +1816,11 @@ var FormEngineImpl = function (_a) {
1816
1816
  var absorbedBy = {};
1817
1817
  (0, lodash_1.forEach)(options, function (option, optionName) {
1818
1818
  var absorb = option === null || option === void 0 ? void 0 : option.absorb_fields;
1819
- if (!(absorb === null || absorb === void 0 ? void 0 : absorb.length))
1819
+ // A read-only form absorbs nothing. A host row shows an absorbed
1820
+ // sibling only inside its EDITOR, and a read view never opens one — so
1821
+ // the language a code field had absorbed would be nowhere on the page.
1822
+ // Every set field gets a row of its own instead.
1823
+ if (!(absorb === null || absorb === void 0 ? void 0 : absorb.length) || readOnly)
1820
1824
  return;
1821
1825
  absorb.forEach(function (absorbedName) {
1822
1826
  // Only absorb a sibling that exists and is not already spoken for; a
@@ -1851,11 +1855,15 @@ var FormEngineImpl = function (_a) {
1851
1855
  // only). availableOptions (listed) and filteredOptions (these) are disjoint —
1852
1856
  // the former is built from fixedValue keys, the latter excludes them — so a
1853
1857
  // field is never both a listed and a hidden row.
1854
- (0, lodash_1.forEach)(filteredOptions, function (_schema, optionName) {
1855
- if (matchesFilters(optionName)) {
1856
- pushRow(optionName, true);
1857
- }
1858
- });
1858
+ // Not in a read-only form: a not-yet-added field is an offer to add it,
1859
+ // and a reader cannot take it up.
1860
+ if (!readOnly) {
1861
+ (0, lodash_1.forEach)(filteredOptions, function (_schema, optionName) {
1862
+ if (matchesFilters(optionName)) {
1863
+ pushRow(optionName, true);
1864
+ }
1865
+ });
1866
+ }
1859
1867
  // User sort (Fields menu → "Sort by"), applied WITHIN each group so the
1860
1868
  // group sections and the required-group rails are preserved. Schema order is
1861
1869
  // the default and the stable tiebreaker (Array.sort is stable, and each
@@ -1927,9 +1935,22 @@ var FormEngineImpl = function (_a) {
1927
1935
  settledBucket.current[entry.name] = fresh;
1928
1936
  return fresh;
1929
1937
  };
1938
+ // Read-only: one list, not three boxes. "Needs attention" is an
1939
+ // instruction, and a reader has nothing to do with it — a required field
1940
+ // nobody filled in is shown unset, without the amber. "Optional" holds
1941
+ // the fields nobody set, which in a read view is a list of things that
1942
+ // are not there, so it is left out altogether.
1943
+ var readBucketOf = function (entry) {
1944
+ var fresh = stableBucketOf(entry);
1945
+ if (!readOnly)
1946
+ return fresh;
1947
+ return fresh === 'optional' ? undefined : 'set';
1948
+ };
1930
1949
  groupKeys.forEach(function (groupName) {
1931
1950
  grouped[groupName].forEach(function (entry) {
1932
- var b = stableBucketOf(entry);
1951
+ var b = readBucketOf(entry);
1952
+ if (!b)
1953
+ return;
1933
1954
  if (!buckets[b][groupName]) {
1934
1955
  buckets[b][groupName] = [];
1935
1956
  bucketGroups[b].push(groupName);
@@ -2006,6 +2027,23 @@ var FormEngineImpl = function (_a) {
2006
2027
  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));
2007
2028
  });
2008
2029
  };
2030
+ // The rows of one box — or, read-only, of the whole form. ONE group body
2031
+ // per box: every field block (and the thin schema sub-labels) is a direct
2032
+ // flex child, so the inter-field gap is identical everywhere — including
2033
+ // across schema-group boundaries.
2034
+ var renderBoxBody = function (boxKey) { return ((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: bucketGroups[boxKey].map(function (groupName) {
2035
+ var groupConfig = groups === null || groups === void 0 ? void 0 : groups[groupName];
2036
+ return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [showGroupSubLabel(groupName) ?
2037
+ (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBoxGroupLabel, { children: (0, readFirst_1.getOptionGroupLabel)(groupName, groups) })
2038
+ : null, showGroupSubLabel(groupName) && (groupConfig === null || groupConfig === void 0 ? void 0 : groupConfig.subtitle) ?
2039
+ (0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { size: 'small', effect: { opacity: 0.6 }, style: {
2040
+ marginTop: 2,
2041
+ marginBottom: 8,
2042
+ marginLeft: compactRowStyles_1.GROUP_INDENT,
2043
+ paddingRight: 10,
2044
+ }, children: groupConfig.subtitle })
2045
+ : null, renderGroupRows(buckets[boxKey][groupName])] }, groupName));
2046
+ }) })); };
2009
2047
  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
2010
2048
  // Mirrors the toolbar's own search-row gate: when no search
2011
2049
  // row renders, the header is a thin strip and sits tight to
@@ -2016,64 +2054,57 @@ var FormEngineImpl = function (_a) {
2016
2054
  // parent's edit card) instead of stacking its own dark surface.
2017
2055
  // The status boxes keep their own tints; the sticky toolbar keeps
2018
2056
  // its blurred header via the $headerBg override.
2019
- stickyHeader: !compactNested }, compactPanelProps, { actions: compactHeaderActions, contentStyle: __assign({ display: 'flex', flexFlow: 'column', gap: '10px' }, compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.contentStyle), children: [(0, size_1.default)(groupKeys) === 0 ?
2020
- (0, jsx_runtime_1.jsx)(reqore_1.ReqoreMessage, { flat: true, opaque: false, size: 'small', children: "No fields match the current filters." })
2021
- : null, STATUS_BOXES.map(function (box) {
2022
- var groupsInBox = bucketGroups[box.key];
2023
- var count = bucketCount(box.key);
2024
- if (!count)
2025
- return null;
2026
- var accent = box.key === 'attention' ? cWarning
2027
- : box.key === 'set' ? cSuccess
2028
- : cMuted;
2029
- // The muted "Optional" box reads as a quieter, recessed
2030
- // surface — a touch darker than the page rather than the
2031
- // faint grey tint the accent would give.
2032
- var boxBg = box.key === 'optional' ?
2033
- (0, colors_1.changeDarkness)((0, colors_1.getMainBackgroundColor)(theme), 0.06)
2034
- : undefined;
2035
- return ((0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBox, { "$accent": accent, "$bg": boxBg, ref: function (node) {
2036
- statusBoxRefs.current[box.key] = node;
2037
- },
2038
- // Opening arms the reveal; collapsing disarms it, so a
2039
- // close never scrolls.
2040
- onCollapseChange: function (collapsed) {
2041
- return setOpenedStatusBox(collapsed ? undefined : box.key);
2042
- }, flat: true, minimal: true, collapseButtonProps: { flat: true, minimal: true, size: 'small' }, collapsible: true,
2043
- // Which boxes start closed is the consumer's call
2044
- // (`compactCollapsedGroups`, default `['optional']`: the
2045
- // Optional box holds every not-yet-added field, so a form
2046
- // opens on what is in use). Two rules override it:
2047
- //
2048
- // A SEARCH forces every box open — ReqorePanel unmounts
2049
- // collapsed content, so a match inside a closed box would
2050
- // be unreachable. (isCollapsed is the panel's controllable
2051
- // state; manual toggling still works with no query set.)
2052
- //
2053
- // The Optional box stays open when it is the ONLY box,
2054
- // because collapsing it renders a card that looks empty and
2055
- // broken: an auth profile's Authorization block, whose nine
2056
- // requirement fields are all optional, showed as a titled
2057
- // card containing one collapsed "Optional 9" strip and
2058
- // nothing else. This does not generalise to the other two —
2059
- // a lone Set box collapsed is a deliberate ask, and its
2060
- // header still reports what is in there.
2061
- isCollapsed: compactCollapsedGroups.includes(box.key) &&
2062
- !query &&
2063
- !(box.key === 'optional' && onlyOptionalRows), 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) {
2064
- var groupConfig = groups === null || groups === void 0 ? void 0 : groups[groupName];
2065
- return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [showGroupSubLabel(groupName) ?
2066
- (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBoxGroupLabel, { children: (0, readFirst_1.getOptionGroupLabel)(groupName, groups) })
2067
- : null, showGroupSubLabel(groupName) && (groupConfig === null || groupConfig === void 0 ? void 0 : groupConfig.subtitle) ?
2068
- (0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { size: 'small', effect: { opacity: 0.6 }, style: {
2069
- marginTop: 2,
2070
- marginBottom: 8,
2071
- marginLeft: compactRowStyles_1.GROUP_INDENT,
2072
- paddingRight: 10,
2073
- }, children: groupConfig.subtitle })
2074
- : null, renderGroupRows(buckets[box.key][groupName])] }, groupName));
2075
- }) }) }, box.key));
2076
- })] })), commitMode === 'batched' && !readOnly && dirtyOptionNames.length ?
2057
+ stickyHeader: !compactNested }, compactPanelProps, { actions: compactHeaderActions, contentStyle: __assign({ display: 'flex', flexFlow: 'column', gap: '10px' }, compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.contentStyle), children: [(0, size_1.default)(groupKeys) === 0 || (readOnly && !bucketCount('set')) ?
2058
+ (0, jsx_runtime_1.jsx)(reqore_1.ReqoreMessage, { flat: true, opaque: false, size: 'small', children: readOnly && !query ?
2059
+ 'Nothing is set.'
2060
+ : 'No fields match the current filters.' })
2061
+ : null, readOnly ?
2062
+ bucketCount('set') ?
2063
+ (0, jsx_runtime_1.jsx)("div", { className: 'options-readfirst-read', style: { padding: '4px 4px 6px' }, children: renderBoxBody('set') })
2064
+ : null
2065
+ : STATUS_BOXES.map(function (box) {
2066
+ var count = bucketCount(box.key);
2067
+ if (!count)
2068
+ return null;
2069
+ var accent = box.key === 'attention' ? cWarning
2070
+ : box.key === 'set' ? cSuccess
2071
+ : cMuted;
2072
+ // The muted "Optional" box reads as a quieter, recessed
2073
+ // surface — a touch darker than the page rather than the
2074
+ // faint grey tint the accent would give.
2075
+ var boxBg = box.key === 'optional' ?
2076
+ (0, colors_1.changeDarkness)((0, colors_1.getMainBackgroundColor)(theme), 0.06)
2077
+ : undefined;
2078
+ return ((0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBox, { "$accent": accent, "$bg": boxBg, ref: function (node) {
2079
+ statusBoxRefs.current[box.key] = node;
2080
+ },
2081
+ // Opening arms the reveal; collapsing disarms it, so a
2082
+ // close never scrolls.
2083
+ onCollapseChange: function (collapsed) {
2084
+ return setOpenedStatusBox(collapsed ? undefined : box.key);
2085
+ }, flat: true, minimal: true, collapseButtonProps: { flat: true, minimal: true, size: 'small' }, collapsible: true,
2086
+ // Which boxes start closed is the consumer's call
2087
+ // (`compactCollapsedGroups`, default `['optional']`: the
2088
+ // Optional box holds every not-yet-added field, so a form
2089
+ // opens on what is in use). Two rules override it:
2090
+ //
2091
+ // A SEARCH forces every box open — ReqorePanel unmounts
2092
+ // collapsed content, so a match inside a closed box would
2093
+ // be unreachable. (isCollapsed is the panel's controllable
2094
+ // state; manual toggling still works with no query set.)
2095
+ //
2096
+ // The Optional box stays open when it is the ONLY box,
2097
+ // because collapsing it renders a card that looks empty and
2098
+ // broken: an auth profile's Authorization block, whose nine
2099
+ // requirement fields are all optional, showed as a titled
2100
+ // card containing one collapsed "Optional 9" strip and
2101
+ // nothing else. This does not generalise to the other two —
2102
+ // a lone Set box collapsed is a deliberate ask, and its
2103
+ // header still reports what is in there.
2104
+ isCollapsed: compactCollapsedGroups.includes(box.key) &&
2105
+ !query &&
2106
+ !(box.key === 'optional' && onlyOptionalRows), 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: renderBoxBody(box.key) }, box.key));
2107
+ })] })), commitMode === 'batched' && !readOnly && dirtyOptionNames.length ?
2077
2108
  (0, jsx_runtime_1.jsx)(StyledCommitDock, { "$bg": cBg, "$border": cDivider, children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreControlGroup, { className: 'options-readfirst-commitbar', verticalAlign: 'center', wrap: true, children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'tiny', minimal: true, flat: true, compact: true, effect: { uppercase: true, spaced: 1 }, intent: 'warning', icon: 'EditLine', label: "".concat(dirtyOptionNames.length, " unsaved change").concat(dirtyOptionNames.length === 1 ? '' : 's') }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { size: 'small', intent: 'success', icon: 'CheckLine', fixed: true, className: 'options-readfirst-save', disabled: !validityData.isValid, tooltip: validityData.isValid ?
2078
2109
  'Apply the staged changes'
2079
2110
  : 'Resolve the invalid fields before saving', onClick: handleCommitClick, children: "Save" }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { size: 'small', minimal: true, flat: true, fixed: true, icon: 'HistoryLine', className: 'options-readfirst-discard', onClick: handleRevertChangesClick, children: "Discard" })] }) })