@adcops/autocore-react 3.5.3 → 3.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ams/AmsProvider.d.ts +14 -0
- package/dist/components/ams/AmsProvider.d.ts.map +1 -1
- package/dist/components/ams/AmsProvider.js +1 -1
- package/dist/components/ams/AssetDetailView.d.ts.map +1 -1
- package/dist/components/ams/AssetDetailView.js +1 -1
- package/dist/components/ams/AssetNameplateGrid.d.ts +13 -0
- package/dist/components/ams/AssetNameplateGrid.d.ts.map +1 -0
- package/dist/components/ams/AssetNameplateGrid.js +1 -0
- package/dist/components/ams/AssetRegistryTable.d.ts.map +1 -1
- package/dist/components/ams/AssetRegistryTable.js +1 -1
- package/dist/components/ams/InstalledAssetPicker.d.ts +35 -0
- package/dist/components/ams/InstalledAssetPicker.d.ts.map +1 -0
- package/dist/components/ams/InstalledAssetPicker.js +1 -0
- package/dist/components/ams/index.d.ts +5 -0
- package/dist/components/ams/index.d.ts.map +1 -1
- package/dist/components/ams/index.js +1 -1
- package/dist/components/ams/useInstalledAsset.d.ts +26 -0
- package/dist/components/ams/useInstalledAsset.d.ts.map +1 -0
- package/dist/components/ams/useInstalledAsset.js +1 -0
- package/dist/components/tis/TestFieldRow.d.ts +19 -0
- package/dist/components/tis/TestFieldRow.d.ts.map +1 -1
- package/dist/components/tis/TestFieldRow.js +1 -1
- package/dist/components/tis-editor/editor/TestFieldDialog.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/TestFieldDialog.js +1 -1
- package/dist/components/tis-editor/types.d.ts +11 -2
- package/dist/components/tis-editor/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ams/AmsProvider.tsx +36 -1
- package/src/components/ams/AssetDetailView.tsx +2 -20
- package/src/components/ams/AssetNameplateGrid.tsx +62 -0
- package/src/components/ams/AssetRegistryTable.tsx +40 -9
- package/src/components/ams/InstalledAssetPicker.tsx +209 -0
- package/src/components/ams/index.ts +7 -0
- package/src/components/ams/useInstalledAsset.ts +108 -0
- package/src/components/tis/TestFieldRow.tsx +31 -0
- package/src/components/tis-editor/editor/TestFieldDialog.tsx +59 -20
- package/src/components/tis-editor/types.ts +11 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { useContext, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { Dialog } from 'primereact/dialog';
|
|
3
3
|
import { Button } from 'primereact/button';
|
|
4
4
|
import { InputText } from 'primereact/inputtext';
|
|
@@ -8,6 +8,11 @@ import { Checkbox } from 'primereact/checkbox';
|
|
|
8
8
|
import { InputNumber } from 'primereact/inputnumber';
|
|
9
9
|
import { FormRow } from '../../forms/FormRow';
|
|
10
10
|
import type { TestField, AggFn, AggFrom, AggScope, AggregateSpec } from '../types';
|
|
11
|
+
// One home for bound parsing/formatting — shared with the operator-facing
|
|
12
|
+
// form so the editor and the runtime can never disagree on what a bound is.
|
|
13
|
+
import { boundText, parseBound, boundInvalid } from '../../tis/TestFieldRow';
|
|
14
|
+
import { AutoCoreTagContext } from '../../../core/AutoCoreTagContext';
|
|
15
|
+
|
|
11
16
|
|
|
12
17
|
const FIELD_TYPES: { label: string; value: string }[] = [
|
|
13
18
|
{ label: 'string', value: 'string' },
|
|
@@ -83,6 +88,17 @@ export const TestFieldDialog: React.FC<TestFieldDialogProps> = ({
|
|
|
83
88
|
const [defaultText, setDefaultText] = useState<string>('');
|
|
84
89
|
const [error, setError] = useState<string | null>(null);
|
|
85
90
|
|
|
91
|
+
// The quantity names this machine actually declares, from the resolved
|
|
92
|
+
// units table. Offered as a dropdown so an author picks a row that exists
|
|
93
|
+
// instead of typing one that silently never resolves — but `editable`, so a
|
|
94
|
+
// method can still be authored against a quantity the bench machine has yet
|
|
95
|
+
// to declare.
|
|
96
|
+
const { scales } = useContext(AutoCoreTagContext);
|
|
97
|
+
const quantityOptions = useMemo(
|
|
98
|
+
() => Object.keys(scales ?? {}).sort().map(q => ({ label: q, value: q })),
|
|
99
|
+
[scales],
|
|
100
|
+
);
|
|
101
|
+
|
|
86
102
|
useEffect(() => {
|
|
87
103
|
if (visible) {
|
|
88
104
|
setDraft(initial ? { ...initial } : { ...blank });
|
|
@@ -116,6 +132,13 @@ export const TestFieldDialog: React.FC<TestFieldDialogProps> = ({
|
|
|
116
132
|
if (typeof f.min === 'number' && typeof f.max === 'number' && f.min > f.max) {
|
|
117
133
|
return `Min (${f.min}) cannot be greater than Max (${f.max}).`;
|
|
118
134
|
}
|
|
135
|
+
// A bound that is neither a number nor a well-formed token resolves to
|
|
136
|
+
// NO bound at run time — silently unlimited. Refuse the save instead.
|
|
137
|
+
for (const which of ['min', 'max'] as const) {
|
|
138
|
+
if (boundInvalid(f[which])) {
|
|
139
|
+
return `${which === 'min' ? 'Min' : 'Max'} must be a number or an FQDN token like \${gm.some_var} — "${f[which]}" is neither.`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
119
142
|
if (f.aggregate && f.aggregate.fn !== 'count' && !f.aggregate.of?.trim()) {
|
|
120
143
|
return `Aggregate "${f.aggregate.fn}" needs a target field (the field to ${f.aggregate.fn} across tests).`;
|
|
121
144
|
}
|
|
@@ -189,7 +212,23 @@ export const TestFieldDialog: React.FC<TestFieldDialogProps> = ({
|
|
|
189
212
|
editable
|
|
190
213
|
/>
|
|
191
214
|
</FormRow>
|
|
192
|
-
<FormRow
|
|
215
|
+
<FormRow
|
|
216
|
+
label="Quantity"
|
|
217
|
+
hint="Ties this field to a row of the machine's units.json, so it follows the operator's Metric/Imperial choice and takes its unit label from the active system. Set this in preference to Units/Scale, which are fixed."
|
|
218
|
+
>
|
|
219
|
+
<Dropdown
|
|
220
|
+
value={draft.quantity ?? ''}
|
|
221
|
+
options={quantityOptions}
|
|
222
|
+
onChange={(e) => setDraft({ ...draft, quantity: e.value || undefined })}
|
|
223
|
+
placeholder="— none (fixed Units/Scale below) —"
|
|
224
|
+
showClear
|
|
225
|
+
editable
|
|
226
|
+
/>
|
|
227
|
+
</FormRow>
|
|
228
|
+
<FormRow
|
|
229
|
+
label="Units"
|
|
230
|
+
hint="Fixed display label appended to form labels (e.g. m/s). Ignored when Quantity is set — the active unit system supplies the label."
|
|
231
|
+
>
|
|
193
232
|
<InputText
|
|
194
233
|
value={draft.units ?? ''}
|
|
195
234
|
onChange={(e) => setDraft({ ...draft, units: e.target.value || undefined })}
|
|
@@ -241,26 +280,26 @@ export const TestFieldDialog: React.FC<TestFieldDialogProps> = ({
|
|
|
241
280
|
maxFractionDigits={9}
|
|
242
281
|
/>
|
|
243
282
|
</FormRow>
|
|
244
|
-
<FormRow
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
283
|
+
<FormRow
|
|
284
|
+
label="Min"
|
|
285
|
+
hint="Optional lower bound the operator can enter (display units). Blank = no minimum. Or bind it to the machine with an FQDN token like ${gm.press_force_min_n} — for a bound that moves, e.g. a load-cell force ceiling."
|
|
286
|
+
>
|
|
287
|
+
<InputText
|
|
288
|
+
value={boundText(draft.min)}
|
|
289
|
+
onChange={(e) => setDraft({ ...draft, min: parseBound(e.target.value) })}
|
|
290
|
+
className={boundInvalid(draft.min) ? 'p-invalid' : ''}
|
|
291
|
+
placeholder="number or ${gm.…}"
|
|
253
292
|
/>
|
|
254
293
|
</FormRow>
|
|
255
|
-
<FormRow
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
294
|
+
<FormRow
|
|
295
|
+
label="Max"
|
|
296
|
+
hint="Optional upper bound the operator can enter (display units). Blank = no maximum. Or bind it to the machine with an FQDN token like ${gm.press_force_max_n}."
|
|
297
|
+
>
|
|
298
|
+
<InputText
|
|
299
|
+
value={boundText(draft.max)}
|
|
300
|
+
onChange={(e) => setDraft({ ...draft, max: parseBound(e.target.value) })}
|
|
301
|
+
className={boundInvalid(draft.max) ? 'p-invalid' : ''}
|
|
302
|
+
placeholder="number or ${gm.…}"
|
|
264
303
|
/>
|
|
265
304
|
</FormRow>
|
|
266
305
|
<FormRow label="Default" hint="Applied every time the method loads (operator can override). A literal (display units) like 5, or an FQDN token like ${gm.safe_speed} that snapshots that value on load.">
|
|
@@ -15,6 +15,11 @@ export type FieldType =
|
|
|
15
15
|
export interface TestField {
|
|
16
16
|
name: string;
|
|
17
17
|
type: FieldType | string;
|
|
18
|
+
/** Scale-group name from the machine's `units.json` ("force", "position",
|
|
19
|
+
* …). What makes this field follow the operator's Metric/Imperial choice;
|
|
20
|
+
* supersedes `units` / `scale`. Declared here so the editor round-trips it
|
|
21
|
+
* — see `TestFieldDialog`'s Quantity row. */
|
|
22
|
+
quantity?: string;
|
|
18
23
|
units?: string;
|
|
19
24
|
required?: boolean;
|
|
20
25
|
source?: string;
|
|
@@ -25,8 +30,12 @@ export interface TestField {
|
|
|
25
30
|
/** Optional inclusive bounds for the operator's numeric value, authored
|
|
26
31
|
* in display units (same convention as `default`/`scale`). The form's
|
|
27
32
|
* numeric input rejects values outside `[min, max]`. */
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
/** Inclusive bounds. A number is in display units; a string is an FQDN
|
|
34
|
+
* token `"${gm.<var>}"` resolved live from the machine — see
|
|
35
|
+
* `TestFieldRow.resolveBound`. The editor must preserve a token it does
|
|
36
|
+
* not understand rather than coercing it to a number. */
|
|
37
|
+
min?: number | string;
|
|
38
|
+
max?: number | string;
|
|
30
39
|
/** results_fields only: a cross-test rollup derived server-side over the
|
|
31
40
|
* non-excluded runs sharing this test's sample_id. When set, the field
|
|
32
41
|
* is NOT supplied by the analysis script — the server computes it. */
|