@qoretechnologies/reqraft 0.10.2 → 0.10.5
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/design/COMPACT_ENGINE_REDESIGN.md +156 -0
- package/design/FORM_ENGINE_COMPACT_UX_PLAN.md +353 -0
- package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
- package/dist/components/form/engine/CompactRow.js +158 -101
- 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 +122 -105
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +9 -1
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +272 -82
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/compactRowStyles.d.ts +6 -3
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +76 -49
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.d.ts +1 -0
- package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
- package/dist/components/form/engine/readFirst.d.ts +19 -0
- package/dist/components/form/engine/readFirst.d.ts.map +1 -1
- package/dist/components/form/engine/readFirst.js +22 -1
- package/dist/components/form/engine/readFirst.js.map +1 -1
- package/dist/components/form/engine/variants/VariantCalmTable.d.ts +6 -0
- package/dist/components/form/engine/variants/VariantCalmTable.d.ts.map +1 -0
- package/dist/components/form/engine/variants/VariantCalmTable.js +94 -0
- package/dist/components/form/engine/variants/VariantCalmTable.js.map +1 -0
- package/dist/components/form/engine/variants/VariantCards.d.ts +6 -0
- package/dist/components/form/engine/variants/VariantCards.d.ts.map +1 -0
- package/dist/components/form/engine/variants/VariantCards.js +80 -0
- package/dist/components/form/engine/variants/VariantCards.js.map +1 -0
- package/dist/components/form/engine/variants/VariantFocus.d.ts +7 -0
- package/dist/components/form/engine/variants/VariantFocus.d.ts.map +1 -0
- package/dist/components/form/engine/variants/VariantFocus.js +138 -0
- package/dist/components/form/engine/variants/VariantFocus.js.map +1 -0
- package/dist/components/form/engine/variants/VariantMinimal.d.ts +6 -0
- package/dist/components/form/engine/variants/VariantMinimal.d.ts.map +1 -0
- package/dist/components/form/engine/variants/VariantMinimal.js +73 -0
- package/dist/components/form/engine/variants/VariantMinimal.js.map +1 -0
- package/dist/components/form/engine/variants/focusDemo.d.ts +13 -0
- package/dist/components/form/engine/variants/focusDemo.d.ts.map +1 -0
- package/dist/components/form/engine/variants/focusDemo.js +139 -0
- package/dist/components/form/engine/variants/focusDemo.js.map +1 -0
- package/dist/components/form/engine/variants/variantModel.d.ts +70 -0
- package/dist/components/form/engine/variants/variantModel.d.ts.map +1 -0
- package/dist/components/form/engine/variants/variantModel.js +133 -0
- package/dist/components/form/engine/variants/variantModel.js.map +1 -0
- package/dist/components/form/engine/variants/variantParts.d.ts +79 -0
- package/dist/components/form/engine/variants/variantParts.d.ts.map +1 -0
- package/dist/components/form/engine/variants/variantParts.js +191 -0
- package/dist/components/form/engine/variants/variantParts.js.map +1 -0
- package/dist/components/form/fields/auto/AutoFormField.d.ts +3 -0
- package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.js +5 -2
- package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/engine/CompactRow.tsx +273 -258
- package/src/components/form/engine/CompactToolbar.tsx +112 -85
- package/src/components/form/engine/FormEngine.stories.tsx +239 -115
- package/src/components/form/engine/FormEngine.tsx +332 -83
- package/src/components/form/engine/compactRowStyles.ts +221 -144
- package/src/components/form/engine/compactToolbarContext.ts +1 -0
- package/src/components/form/engine/readFirst.ts +35 -0
- package/src/components/form/engine/variants/FormEngineVariants.stories.tsx +119 -0
- package/src/components/form/engine/variants/VariantCalmTable.tsx +242 -0
- package/src/components/form/engine/variants/VariantCards.tsx +212 -0
- package/src/components/form/engine/variants/VariantFocus.tsx +382 -0
- package/src/components/form/engine/variants/VariantMinimal.tsx +170 -0
- package/src/components/form/engine/variants/focusDemo.ts +145 -0
- package/src/components/form/engine/variants/variantModel.ts +216 -0
- package/src/components/form/engine/variants/variantParts.tsx +313 -0
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +9 -2
- package/src/components/form/fields/auto/AutoFormField.tsx +8 -0
|
@@ -3,11 +3,8 @@ import {
|
|
|
3
3
|
ReqoreControlGroup,
|
|
4
4
|
ReqoreDropdown,
|
|
5
5
|
ReqoreInput,
|
|
6
|
-
ReqoreMessage,
|
|
7
|
-
ReqoreProgress,
|
|
8
|
-
ReqoreSpan,
|
|
9
|
-
ReqoreTag,
|
|
10
6
|
} from '@qoretechnologies/reqore';
|
|
7
|
+
import { useReqoreTheme } from '@qoretechnologies/reqore/dist/hooks/useTheme';
|
|
11
8
|
import { IReqoreControlGroupProps } from '@qoretechnologies/reqore/dist/components/ControlGroup';
|
|
12
9
|
import {
|
|
13
10
|
IReqoreDropdownItem,
|
|
@@ -28,20 +25,73 @@ const SORT_MODES: { value: TCompactSort; label: string; tooltip: string }[] = [
|
|
|
28
25
|
{ value: 'invalid', label: 'Invalid first', tooltip: 'Fields needing attention first' },
|
|
29
26
|
];
|
|
30
27
|
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// `flex: 1; min-width: 0` makes only the bar yield as the row narrows.
|
|
28
|
+
// "Focus" header: a summary line ({pct}% complete · {set}/{total} set ·
|
|
29
|
+
// {attention} need attention →) above a SEGMENTED meter — a green run (set) then
|
|
30
|
+
// an amber run (needs attention) then the empty remainder.
|
|
35
31
|
const StyledCompletion = styled.div`
|
|
36
32
|
display: flex;
|
|
37
|
-
|
|
38
|
-
gap:
|
|
33
|
+
flex-flow: column;
|
|
34
|
+
gap: 8px;
|
|
39
35
|
padding: 0 2px;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
`;
|
|
37
|
+
const StyledCompletionLine = styled.div`
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: baseline;
|
|
40
|
+
gap: 10px;
|
|
41
|
+
flex-wrap: wrap;
|
|
42
|
+
`;
|
|
43
|
+
const StyledMeter = styled.div<{ $set: number; $attention: number; $track: string; $set_c: string; $att_c: string }>`
|
|
44
|
+
position: relative;
|
|
45
|
+
height: 4px;
|
|
46
|
+
border-radius: 3px;
|
|
47
|
+
width: 100%;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
background: ${({ $track }) => $track};
|
|
50
|
+
/* No per-segment radius — the container's overflow:hidden + radius rounds only
|
|
51
|
+
the OUTER corners, so the green/amber runs meet flush (no notch). */
|
|
52
|
+
&::before,
|
|
53
|
+
&::after {
|
|
54
|
+
content: '';
|
|
55
|
+
position: absolute;
|
|
56
|
+
top: 0;
|
|
57
|
+
bottom: 0;
|
|
58
|
+
}
|
|
59
|
+
/* green run: 0 → set% */
|
|
60
|
+
&::before {
|
|
61
|
+
left: 0;
|
|
62
|
+
width: ${({ $set }) => $set}%;
|
|
63
|
+
background: ${({ $set_c }) => $set_c};
|
|
64
|
+
}
|
|
65
|
+
/* amber run: set% → set%+attention% */
|
|
66
|
+
&::after {
|
|
67
|
+
left: ${({ $set }) => $set}%;
|
|
68
|
+
width: ${({ $attention }) => $attention}%;
|
|
69
|
+
background: ${({ $att_c }) => $att_c};
|
|
43
70
|
}
|
|
44
71
|
`;
|
|
72
|
+
// One shared text size for the whole summary line, so "Draft", "1/6 set" and
|
|
73
|
+
// "N need attention" all read at the same scale (no chips, no size jumps).
|
|
74
|
+
const StyledSummary = styled.span<{ $color?: string }>`
|
|
75
|
+
font-size: 13px;
|
|
76
|
+
white-space: nowrap;
|
|
77
|
+
color: ${({ $color }) => $color || 'inherit'};
|
|
78
|
+
`;
|
|
79
|
+
const StyledAttentionLink = styled.span<{ $color: string }>`
|
|
80
|
+
color: ${({ $color }) => $color};
|
|
81
|
+
font-size: 13px;
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
&:hover {
|
|
85
|
+
text-decoration: underline;
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
// The percentage, pushed to the far right of the summary line.
|
|
89
|
+
const StyledPct = styled.span`
|
|
90
|
+
margin-left: auto;
|
|
91
|
+
font-weight: 700;
|
|
92
|
+
font-size: 17px;
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
`;
|
|
45
95
|
|
|
46
96
|
/**
|
|
47
97
|
* The compact form's sticky toolbar (completion meter + field filter + "Fields"
|
|
@@ -55,8 +105,8 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
55
105
|
const {
|
|
56
106
|
readOnly,
|
|
57
107
|
invalidCount,
|
|
108
|
+
attentionCount,
|
|
58
109
|
completion,
|
|
59
|
-
showInvalidOnly,
|
|
60
110
|
onToggleInvalidOnly,
|
|
61
111
|
hasMultipleOptions,
|
|
62
112
|
compactQuery,
|
|
@@ -70,7 +120,6 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
70
120
|
showAllDescriptions,
|
|
71
121
|
onToggleAllDescriptions,
|
|
72
122
|
filteredCount,
|
|
73
|
-
optionalFields,
|
|
74
123
|
canRevert,
|
|
75
124
|
onAddOptionalField,
|
|
76
125
|
onAddAll,
|
|
@@ -78,51 +127,53 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
78
127
|
onRevertAll,
|
|
79
128
|
} = useContext(CompactToolbarContext);
|
|
80
129
|
|
|
130
|
+
const theme = useReqoreTheme();
|
|
131
|
+
const intents = (theme.intents || {}) as Record<string, string>;
|
|
132
|
+
const cSuccess = intents.success || '#4a7110';
|
|
133
|
+
const cWarning = intents.warning || '#d17c29';
|
|
134
|
+
const cText = (theme.text?.color as string) || '#e8e8e8';
|
|
135
|
+
const cTrack = `${cText}1f`;
|
|
136
|
+
const setPct = completion.total ? (completion.set / completion.total) * 100 : 0;
|
|
137
|
+
const attentionPct = completion.total ? (attentionCount / completion.total) * 100 : 0;
|
|
138
|
+
|
|
81
139
|
return (
|
|
82
140
|
<ReqoreControlGroup {...reqoreProps} vertical fluid fixed={false} gapSize='big'>
|
|
83
141
|
{completion.total ?
|
|
84
142
|
<StyledCompletion className='options-readfirst-completion'>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<
|
|
143
|
+
<StyledCompletionLine>
|
|
144
|
+
{!readOnly ?
|
|
145
|
+
<StyledSummary
|
|
88
146
|
className='options-readfirst-status'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
: null}
|
|
113
|
-
<ReqoreSpan size='small' effect={{ opacity: 0.7, noWrap: true }}>
|
|
114
|
-
{completion.set} / {completion.total} fields set
|
|
115
|
-
</ReqoreSpan>
|
|
116
|
-
<ReqoreProgress
|
|
147
|
+
$color={invalidCount ? cWarning : cSuccess}
|
|
148
|
+
style={{ fontWeight: 600 }}
|
|
149
|
+
>
|
|
150
|
+
{invalidCount ? 'Draft' : 'Ready'}
|
|
151
|
+
</StyledSummary>
|
|
152
|
+
: null}
|
|
153
|
+
<StyledSummary style={{ opacity: 0.5 }}>
|
|
154
|
+
{!readOnly ? '· ' : ''}
|
|
155
|
+
{completion.set}/{completion.total} set
|
|
156
|
+
{!readOnly && attentionCount ? ' ·' : ''}
|
|
157
|
+
</StyledSummary>
|
|
158
|
+
{!readOnly && attentionCount ?
|
|
159
|
+
<StyledAttentionLink
|
|
160
|
+
$color={cWarning}
|
|
161
|
+
className='options-readfirst-attention-link'
|
|
162
|
+
onClick={onToggleInvalidOnly}
|
|
163
|
+
>
|
|
164
|
+
{attentionCount} need attention →
|
|
165
|
+
</StyledAttentionLink>
|
|
166
|
+
: null}
|
|
167
|
+
<StyledPct>{completion.pct}%</StyledPct>
|
|
168
|
+
</StyledCompletionLine>
|
|
169
|
+
<StyledMeter
|
|
117
170
|
className='options-readfirst-completion-bar'
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
171
|
+
$set={setPct}
|
|
172
|
+
$attention={attentionPct}
|
|
173
|
+
$track={cTrack}
|
|
174
|
+
$set_c={cSuccess}
|
|
175
|
+
$att_c={cWarning}
|
|
122
176
|
/>
|
|
123
|
-
<ReqoreSpan size='small' effect={{ opacity: 0.7, noWrap: true }}>
|
|
124
|
-
{completion.pct}%
|
|
125
|
-
</ReqoreSpan>
|
|
126
177
|
</StyledCompletion>
|
|
127
178
|
: null}
|
|
128
179
|
|
|
@@ -147,10 +198,10 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
147
198
|
{!readOnly ?
|
|
148
199
|
<ReqoreDropdown
|
|
149
200
|
fixed
|
|
150
|
-
|
|
201
|
+
flat
|
|
151
202
|
filterable
|
|
152
203
|
icon='Filter3Line'
|
|
153
|
-
|
|
204
|
+
tooltip='Fields'
|
|
154
205
|
className='options-readfirst-fields'
|
|
155
206
|
intent={requiredOnly ? 'info' : undefined}
|
|
156
207
|
badge={requiredOnly ? 'Required only' : undefined}
|
|
@@ -216,29 +267,18 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
216
267
|
disabled: !canRevert,
|
|
217
268
|
onClick: onRevertAll,
|
|
218
269
|
},
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
readOnly: true,
|
|
224
|
-
disabled: true,
|
|
225
|
-
icon: 'AddLine',
|
|
226
|
-
},
|
|
227
|
-
]
|
|
228
|
-
: []),
|
|
229
|
-
...optionalFields.map((field) => ({
|
|
230
|
-
label: field.display_name || field.value,
|
|
231
|
-
value: field.value,
|
|
232
|
-
description: field.short_desc,
|
|
233
|
-
disabled: field.disabled,
|
|
234
|
-
})),
|
|
270
|
+
// The individual not-yet-added fields are no longer listed here —
|
|
271
|
+
// they render as addable rows in the Optional box instead. The
|
|
272
|
+
// menu keeps only the bulk actions above (Select all / Default
|
|
273
|
+
// fields / filters).
|
|
235
274
|
] as TReqoreDropdownItems
|
|
236
275
|
}
|
|
237
276
|
/>
|
|
238
277
|
: null}
|
|
239
278
|
<ReqoreButton
|
|
240
279
|
fixed
|
|
241
|
-
|
|
280
|
+
flat
|
|
281
|
+
minimal={showAllDescriptions === true}
|
|
242
282
|
icon={showAllDescriptions ? 'InformationFill' : 'InformationLine'}
|
|
243
283
|
className='options-readfirst-descriptions'
|
|
244
284
|
active={showAllDescriptions}
|
|
@@ -248,19 +288,6 @@ export const CompactToolbar = memo((reqoreProps: Partial<IReqoreControlGroupProp
|
|
|
248
288
|
/>
|
|
249
289
|
</ReqoreControlGroup>
|
|
250
290
|
: null}
|
|
251
|
-
{invalidCount && !readOnly ?
|
|
252
|
-
<ReqoreMessage
|
|
253
|
-
intent={showInvalidOnly ? 'info' : 'danger'}
|
|
254
|
-
opaque={false}
|
|
255
|
-
size='small'
|
|
256
|
-
className='options-readfirst-invalid-banner'
|
|
257
|
-
onClick={onToggleInvalidOnly}
|
|
258
|
-
>
|
|
259
|
-
{showInvalidOnly ?
|
|
260
|
-
'Showing invalid fields only. Click here again to show all fields.'
|
|
261
|
-
: `${invalidCount < 2 ? 'A field is not valid and requires' : `${invalidCount} fields are not valid and require`} attention. Click here to only show invalid fields.`}
|
|
262
|
-
</ReqoreMessage>
|
|
263
|
-
: null}
|
|
264
291
|
</ReqoreControlGroup>
|
|
265
292
|
: null}
|
|
266
293
|
</ReqoreControlGroup>
|