@adcops/autocore-react 3.3.85 → 3.3.89
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/assets/AxisC.d.ts +4 -0
- package/dist/assets/AxisC.d.ts.map +1 -0
- package/dist/assets/AxisC.js +1 -0
- package/dist/assets/AxisX.js +1 -1
- package/dist/assets/AxisY.js +1 -1
- package/dist/assets/AxisZ.js +1 -1
- package/dist/components/ValueInput.css +9 -12
- package/dist/components/ValueInput.d.ts +45 -154
- package/dist/components/ValueInput.d.ts.map +1 -1
- package/dist/components/ValueInput.js +1 -1
- package/dist/components/ams/AmsProvider.d.ts +10 -0
- package/dist/components/ams/AmsProvider.d.ts.map +1 -1
- package/dist/components/ams/AssetRegistryTable.d.ts.map +1 -1
- package/dist/components/ams/AssetRegistryTable.js +1 -1
- package/dist/components/forms/FormRow.d.ts +20 -0
- package/dist/components/forms/FormRow.d.ts.map +1 -0
- package/dist/components/forms/FormRow.js +1 -0
- package/dist/components/forms/FormSection.d.ts +19 -0
- package/dist/components/forms/FormSection.d.ts.map +1 -0
- package/dist/components/forms/FormSection.js +1 -0
- package/dist/components/forms/forms.css +89 -0
- package/dist/components/forms/index.d.ts +3 -0
- package/dist/components/forms/index.d.ts.map +1 -0
- package/dist/components/forms/index.js +1 -0
- package/dist/components/tis-editor/TisConfigEditor.css +121 -0
- package/dist/components/tis-editor/TisConfigEditor.d.ts +28 -0
- package/dist/components/tis-editor/TisConfigEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/TisConfigEditor.js +1 -0
- package/dist/components/tis-editor/editor/AnalysisEditor.d.ts +7 -0
- package/dist/components/tis-editor/editor/AnalysisEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/AnalysisEditor.js +1 -0
- package/dist/components/tis-editor/editor/AssetRefsEditor.d.ts +10 -0
- package/dist/components/tis-editor/editor/AssetRefsEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/AssetRefsEditor.js +1 -0
- package/dist/components/tis-editor/editor/ChartViewDialog.d.ts +16 -0
- package/dist/components/tis-editor/editor/ChartViewDialog.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/ChartViewDialog.js +1 -0
- package/dist/components/tis-editor/editor/FieldArrayEditor.d.ts +8 -0
- package/dist/components/tis-editor/editor/FieldArrayEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/FieldArrayEditor.js +1 -0
- package/dist/components/tis-editor/editor/IdentitySection.d.ts +7 -0
- package/dist/components/tis-editor/editor/IdentitySection.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/IdentitySection.js +1 -0
- package/dist/components/tis-editor/editor/MethodFormEditor.d.ts +20 -0
- package/dist/components/tis-editor/editor/MethodFormEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/MethodFormEditor.js +1 -0
- package/dist/components/tis-editor/editor/RawDataEditor.d.ts +7 -0
- package/dist/components/tis-editor/editor/RawDataEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/RawDataEditor.js +1 -0
- package/dist/components/tis-editor/editor/SaveDiffDialog.d.ts +22 -0
- package/dist/components/tis-editor/editor/SaveDiffDialog.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/SaveDiffDialog.js +1 -0
- package/dist/components/tis-editor/editor/TestFieldDialog.d.ts +11 -0
- package/dist/components/tis-editor/editor/TestFieldDialog.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/TestFieldDialog.js +1 -0
- package/dist/components/tis-editor/editor/ViewsEditor.d.ts +7 -0
- package/dist/components/tis-editor/editor/ViewsEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/ViewsEditor.js +1 -0
- package/dist/components/tis-editor/types.d.ts +78 -0
- package/dist/components/tis-editor/types.d.ts.map +1 -0
- package/dist/components/tis-editor/types.js +1 -0
- package/dist/components/tis-editor/validation.d.ts +20 -0
- package/dist/components/tis-editor/validation.d.ts.map +1 -0
- package/dist/components/tis-editor/validation.js +1 -0
- package/dist/hooks/useAmsAssetTypes.d.ts +23 -0
- package/dist/hooks/useAmsAssetTypes.d.ts.map +1 -0
- package/dist/hooks/useAmsAssetTypes.js +1 -0
- package/dist/hooks/useTisConfig.d.ts +51 -0
- package/dist/hooks/useTisConfig.d.ts.map +1 -0
- package/dist/hooks/useTisConfig.js +1 -0
- package/package.json +9 -3
- package/src/assets/AxisC.tsx +38 -0
- package/src/assets/AxisX.tsx +32 -32
- package/src/assets/AxisY.tsx +34 -34
- package/src/assets/AxisZ.tsx +31 -31
- package/src/components/ValueInput.css +9 -12
- package/src/components/ValueInput.tsx +132 -317
- package/src/components/ams/AmsProvider.tsx +10 -0
- package/src/components/ams/AssetRegistryTable.tsx +53 -8
- package/src/components/forms/FormRow.tsx +37 -0
- package/src/components/forms/FormSection.tsx +39 -0
- package/src/components/forms/forms.css +89 -0
- package/src/components/forms/index.ts +2 -0
- package/src/components/tis-editor/TisConfigEditor.css +121 -0
- package/src/components/tis-editor/TisConfigEditor.tsx +321 -0
- package/src/components/tis-editor/editor/AnalysisEditor.tsx +54 -0
- package/src/components/tis-editor/editor/AssetRefsEditor.tsx +187 -0
- package/src/components/tis-editor/editor/ChartViewDialog.tsx +170 -0
- package/src/components/tis-editor/editor/FieldArrayEditor.tsx +131 -0
- package/src/components/tis-editor/editor/IdentitySection.tsx +36 -0
- package/src/components/tis-editor/editor/MethodFormEditor.tsx +176 -0
- package/src/components/tis-editor/editor/RawDataEditor.tsx +117 -0
- package/src/components/tis-editor/editor/SaveDiffDialog.tsx +160 -0
- package/src/components/tis-editor/editor/TestFieldDialog.tsx +134 -0
- package/src/components/tis-editor/editor/ViewsEditor.tsx +101 -0
- package/src/components/tis-editor/types.ts +95 -0
- package/src/components/tis-editor/validation.ts +104 -0
- package/src/hooks/useAmsAssetTypes.ts +70 -0
- package/src/hooks/useTisConfig.ts +164 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AxisC.d.ts","sourceRoot":"","sources":["../../src/assets/AxisC.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,eAAO,MAAM,QAAQ,GAAI,OAAO,QAAQ,CAAC,aAAa,CAAC,4CAuBtD,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisC=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("path",{d:"M15 10a4 4 1 1 0 0 6"}),_jsx("path",{d:"M12 2a10 10 0 1 0 9.5 7"}),_jsx("path",{d:"m11 5 4-5-4-4",transform:"translate(0 2)"})]});export default SvgAxisC;
|
package/dist/assets/AxisX.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisX=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("path",{d:"
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisX=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("path",{d:"M4 18h16M4 18l4-4M4 18l4 4M20 18l-4-4M20 18l-4 4"}),_jsx("path",{d:"M9 2l6 6m0-6l-6 6"})]});export default SvgAxisX;
|
package/dist/assets/AxisY.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisY=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("g",{transform:"rotate(-45
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisY=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("g",{transform:"rotate(-45 6 12)",children:_jsx("path",{d:"M4 12h16M4 12l4-4M4 12l4 4M20 12l-4-4M20 12l-4 4"})}),_jsx("path",{d:"M15 12l3 4v5 M21 12l-3 4"})]});export default SvgAxisY;
|
package/dist/assets/AxisZ.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisZ=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("path",{d:"M18
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const SvgAxisZ=s=>_jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:[_jsx("path",{d:"M18 4v16M14 8l4-4 4 4M14 16l4 4 4-4"}),_jsx("path",{d:"M2 10h6l-6 6h6"})]});export default SvgAxisZ;
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* ValueInput sizing.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* accept/cancel buttons keep their
|
|
4
|
+
* NumericFormat with customInput=InputText renders a plain <input class="p-inputtext">
|
|
5
|
+
* (no .p-inputwrapper span like PrimeReact's InputNumber). In a .p-inputgroup the
|
|
6
|
+
* input defaults to flex: 1 1 auto; we override that so the field stays at a
|
|
7
|
+
* fixed width while the label addon and accept/cancel buttons keep their
|
|
8
|
+
* natural sizes.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
|
-
.value-input-field.p-
|
|
11
|
+
.value-input-field.p-inputtext {
|
|
11
12
|
flex: 0 0 auto;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.value-input-field.p-inputwrapper .p-inputtext {
|
|
15
|
-
width: 100%;
|
|
16
13
|
box-sizing: border-box;
|
|
17
14
|
}
|
|
18
15
|
|
|
19
|
-
.value-input-field.size-small.p-
|
|
16
|
+
.value-input-field.size-small.p-inputtext {
|
|
20
17
|
width: 30mm;
|
|
21
18
|
}
|
|
22
19
|
|
|
23
|
-
.value-input-field.size-normal.p-
|
|
20
|
+
.value-input-field.size-normal.p-inputtext {
|
|
24
21
|
width: 55mm;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
.value-input-field.size-large.p-
|
|
24
|
+
.value-input-field.size-large.p-inputtext {
|
|
28
25
|
width: 70mm;
|
|
29
26
|
}
|
|
@@ -1,167 +1,58 @@
|
|
|
1
1
|
/** @file
|
|
2
|
-
* `ValueInput` is a React component for
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* with configurable precision and optional prefix/suffix text.
|
|
2
|
+
* `ValueInput` is a React component for numeric entry built on top of
|
|
3
|
+
* `react-number-format`. It wraps a PrimeReact `InputText` so the field
|
|
4
|
+
* inherits the standard inputgroup styling and integrates with the
|
|
5
|
+
* accept/cancel button row below.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* - `mode`: Determines whether the input is treated as a plain decimal or currency. Defaults to "decimal".
|
|
16
|
-
* - `currency`: ISO 4217 currency code for formatting the value as currency.
|
|
17
|
-
* - `prefix`: String to display before the value.
|
|
18
|
-
* - `suffix`: String to display after the value.
|
|
19
|
-
* - `showButtons`: Whether to display increment and decrement buttons.
|
|
20
|
-
* - `step`: The amount by which the value should be incremented or decremented.
|
|
21
|
-
* - `locale`: Locale code for formatting the value.
|
|
22
|
-
* - `description`: Additional descriptive text to display below the input.
|
|
23
|
-
* - `disabled`: Whether the input is disabled.
|
|
24
|
-
* - `dispatchTopic`: Event topic to dispatch on value change.
|
|
25
|
-
* - `placeholder`: Placeholder text when the input is empty.
|
|
26
|
-
* - `onValueChanged`: Callback function that is called when the user accepts a new value.
|
|
27
|
-
*
|
|
28
|
-
* Example Usage:
|
|
29
|
-
* ```tsx
|
|
30
|
-
* <ValueInput
|
|
31
|
-
* label="Quantity"
|
|
32
|
-
* value={10}
|
|
33
|
-
* min={1}
|
|
34
|
-
* max={100}
|
|
35
|
-
* minPrecision={0}
|
|
36
|
-
* maxPrecision={2}
|
|
37
|
-
* mode="decimal"
|
|
38
|
-
* showButtons={true}
|
|
39
|
-
* step={1}
|
|
40
|
-
* locale="en-US"
|
|
41
|
-
* onValueChanged={(newValue) => console.log("New Value:", newValue)}
|
|
42
|
-
* />
|
|
43
|
-
* ```
|
|
7
|
+
* Why react-number-format and not PrimeReact's `InputNumber`:
|
|
8
|
+
* - `InputNumber` handles the `-` key via `onKeyDown` (sign-toggle action).
|
|
9
|
+
* On Wayland on-screen keyboards (Ubuntu 24 virtual keyboard) keydown is
|
|
10
|
+
* not always delivered, so negative entry was broken on touch HMIs.
|
|
11
|
+
* - `NumericFormat` treats the input as text and validates it against a
|
|
12
|
+
* numeric format. The user can simply type `-`, `2`, `0`, `0` to get
|
|
13
|
+
* `-200` on every input device.
|
|
44
14
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
15
|
+
* Properties:
|
|
16
|
+
* - `label`: Optional label addon shown before the field.
|
|
17
|
+
* - `value`: Externally controlled value.
|
|
18
|
+
* - `min` / `max`: Range validation, applied on accept.
|
|
19
|
+
* - `minPrecision` / `maxPrecision`: Decimal precision. (Aliases
|
|
20
|
+
* `minFractionDigits` / `maxFractionDigits` are also accepted for
|
|
21
|
+
* compatibility with older call sites.)
|
|
22
|
+
* - `prefix` / `suffix`: Inline string before/after the number.
|
|
23
|
+
* - `description`: Small advisory text below the field.
|
|
24
|
+
* - `disabled`: Disable all interaction.
|
|
25
|
+
* - `dispatchTopic`: Topic dispatched on accept via the EventEmitter context.
|
|
26
|
+
* - `placeholder`: Placeholder when empty.
|
|
27
|
+
* - `onValueChanged`: Called with the new numeric value when the user accepts.
|
|
28
|
+
* - `size`: Field width — small (30mm), normal (55mm), large (70mm).
|
|
48
29
|
*/
|
|
49
30
|
import React from 'react';
|
|
50
|
-
import
|
|
51
|
-
import "./ValueInput.css";
|
|
31
|
+
import './ValueInput.css';
|
|
52
32
|
export type ValueInputSize = 'small' | 'normal' | 'large';
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
-
interface ValueInputProps extends Omit<InputNumberProps, 'value' | 'size'> {
|
|
57
|
-
/**
|
|
58
|
-
* The label for the ValueInput field.
|
|
59
|
-
*/
|
|
60
|
-
label: React.ReactNode | undefined | null;
|
|
61
|
-
/**
|
|
62
|
-
* The value for the field.
|
|
63
|
-
*/
|
|
33
|
+
export interface ValueInputProps {
|
|
34
|
+
label?: React.ReactNode | null;
|
|
64
35
|
value: number | null;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
minPrecision?: number | undefined;
|
|
82
|
-
/**
|
|
83
|
-
* Maximum number of decimal points.
|
|
84
|
-
* Set to 0 for integer-only. Must be greater or equal to than minPrecision, or
|
|
85
|
-
* the component will throw an error.
|
|
86
|
-
* @default 3
|
|
87
|
-
*/
|
|
88
|
-
maxPrecision?: number | undefined;
|
|
89
|
-
/**
|
|
90
|
-
* Defines the behavior of the component.
|
|
91
|
-
* If set to "currency", then you need to specify the
|
|
92
|
-
* currency type using the currency property.
|
|
93
|
-
* @default "decimal"
|
|
94
|
-
*/
|
|
95
|
-
mode?: "currency" | "decimal" | undefined;
|
|
96
|
-
/**
|
|
97
|
-
* The currency to use in currency formatting. Possible values are the
|
|
98
|
-
* [ISO 4217 currency codes](https://www.six-group.com/en/products-services/financial-information/data-standards.html#scrollTo=maintenance-agency),
|
|
99
|
-
* such as "USD" for the US dollar, "EUR" for the euro, or "CNY" for the Chinese RMB.
|
|
100
|
-
* If the mode is "currency", the currency property must be provided.
|
|
101
|
-
*
|
|
102
|
-
* @default "USD"
|
|
103
|
-
*/
|
|
104
|
-
currency?: string;
|
|
105
|
-
/**
|
|
106
|
-
* An optional prefix before the value of the field.
|
|
107
|
-
* Unlike the TextInput control, this prefix is internal to the field.
|
|
108
|
-
*/
|
|
109
|
-
prefix?: string | undefined;
|
|
110
|
-
/**
|
|
111
|
-
* An optional suffix after the value of the field.
|
|
112
|
-
* Unlike the TextInput control, this prefix is internal to the field.
|
|
113
|
-
*/
|
|
114
|
-
suffix?: string | undefined;
|
|
115
|
-
/**
|
|
116
|
-
* Set true to display buttons to increment/decrement the value.
|
|
117
|
-
* Use the step property to adjust the amount that the value will change.
|
|
118
|
-
*
|
|
119
|
-
* @default false
|
|
120
|
-
*/
|
|
121
|
-
showButtons?: boolean;
|
|
122
|
-
/**
|
|
123
|
-
* The amount clicking an increment/decrement buttion will change the value.
|
|
124
|
-
*/
|
|
125
|
-
step?: number | undefined;
|
|
126
|
-
/**
|
|
127
|
-
* Locale to be used in formatting. Changes how the numbers/separators are displayed
|
|
128
|
-
* for international users. The typical locale codes are used.
|
|
129
|
-
*
|
|
130
|
-
* @default "en-US"
|
|
131
|
-
*/
|
|
132
|
-
locale?: string | undefined;
|
|
133
|
-
/**
|
|
134
|
-
* A small, advisory text below the field.
|
|
135
|
-
*/
|
|
136
|
-
description?: React.ReactNode | undefined;
|
|
137
|
-
/**
|
|
138
|
-
* If true, all functions of the field will be disabled.
|
|
139
|
-
*/
|
|
140
|
-
disabled?: boolean | undefined;
|
|
141
|
-
/** Topic on which the value will be dispatched through the user interfave on successful data entry. */
|
|
142
|
-
dispatchTopic?: string | undefined;
|
|
143
|
-
/**
|
|
144
|
-
* Placeholder string to display if the value is empty.
|
|
145
|
-
*/
|
|
146
|
-
placeholder?: string | undefined;
|
|
147
|
-
/**
|
|
148
|
-
* The user has accepted a new value.
|
|
149
|
-
* @param newValue New value accepted by the user.
|
|
150
|
-
*/
|
|
36
|
+
min?: number;
|
|
37
|
+
max?: number;
|
|
38
|
+
/** Minimum decimal places displayed. @default 0 */
|
|
39
|
+
minPrecision?: number;
|
|
40
|
+
/** Maximum decimal places allowed. @default 3 */
|
|
41
|
+
maxPrecision?: number;
|
|
42
|
+
/** Alias for `minPrecision` (compat with older call sites). */
|
|
43
|
+
minFractionDigits?: number;
|
|
44
|
+
/** Alias for `maxPrecision` (compat with older call sites). */
|
|
45
|
+
maxFractionDigits?: number;
|
|
46
|
+
prefix?: string;
|
|
47
|
+
suffix?: string;
|
|
48
|
+
description?: React.ReactNode;
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
dispatchTopic?: string;
|
|
51
|
+
placeholder?: string;
|
|
151
52
|
onValueChanged?(newValue: number): void;
|
|
152
|
-
/**
|
|
153
|
-
* Width of the InputNumber field. The label addon and accept/cancel buttons
|
|
154
|
-
* keep their natural size; only the numeric input is constrained.
|
|
155
|
-
* Widths: small=30mm, normal=55mm, large=70mm.
|
|
156
|
-
* @default 'normal'
|
|
157
|
-
*/
|
|
158
53
|
size?: ValueInputSize;
|
|
54
|
+
className?: string;
|
|
159
55
|
}
|
|
160
|
-
/**
|
|
161
|
-
* A convenient field with all the usual features of inputing numbers.
|
|
162
|
-
* Wraps the common features of use of a InputNumber, p-inputgroup, some icon buttons,
|
|
163
|
-
* accepting and rejecting values and keyboard management.
|
|
164
|
-
*/
|
|
165
56
|
export declare const ValueInput: React.FC<ValueInputProps>;
|
|
166
57
|
export default ValueInput;
|
|
167
58
|
//# sourceMappingURL=ValueInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValueInput.d.ts","sourceRoot":"","sources":["../../src/components/ValueInput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ValueInput.d.ts","sourceRoot":"","sources":["../../src/components/ValueInput.tsx"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAA0C,MAAM,OAAO,CAAC;AAO/D,OAAO,kBAAkB,CAAC;AAE1B,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8HhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import clsx from"clsx";import{NumericFormat}from"react-number-format";import{InputText}from"primereact/inputtext";import{Button}from"primereact/button";import{EventEmitterContext}from"../core/EventEmitterContext";import"./ValueInput.css";export const ValueInput=({label:e,value:t=null,min:i,max:a,minPrecision:s,maxPrecision:o,minFractionDigits:n,maxFractionDigits:r,prefix:c,suffix:u,description:l,disabled:m=!1,dispatchTopic:p,placeholder:d,onValueChanged:x,size:f="normal",className:v})=>{const h=s??n??0,j=o??r??3,[N,b]=useState(t),[E,C]=useState(!1),[_,g]=useState(!1),S=useContext(EventEmitterContext);useEffect(()=>{E||(b(t),g(!1))},[t,E]);const F=()=>{if(!E)return;if(null===(e=N)||Number.isNaN(e)||void 0!==i&&e<i||void 0!==a&&e>a)return void g(!0);var e;const t=N;x?.(t),p&&S.dispatch({topic:p,payload:t}),C(!1),g(!1)},I=()=>{b(t),C(!1),g(!1)},V=void 0===i||i<0;return _jsxs("div",{children:[_jsxs("div",{className:"p-inputgroup",children:[null!=e&&""!==e&&_jsx("span",{className:"p-inputgroup-addon",children:e}),_jsx(NumericFormat,{value:N??"",onValueChange:(e,t)=>{"event"===t.source&&(b(e.floatValue??null),C(!0),g(!1))},decimalScale:j,fixedDecimalScale:h>0&&!E,allowNegative:V,decimalSeparator:".",thousandSeparator:!1,prefix:c,suffix:u,placeholder:d,disabled:m,customInput:InputText,className:clsx("value-input-field",`size-${f}`,v),invalid:_||void 0,onKeyDown:e=>{"Enter"===e.key?F():"Escape"===e.key&&I()}}),_jsx(Button,{icon:"pi pi-check",disabled:m||!E,className:"p-button-success",onClick:F,autoFocus:!1}),_jsx(Button,{icon:"pi pi-times",disabled:m||!E,className:"p-button-danger",onClick:I,autoFocus:!1})]}),l&&_jsx("small",{children:l})]})};export default ValueInput;
|
|
@@ -25,6 +25,16 @@ export interface AmsRole {
|
|
|
25
25
|
* feeding NI bridge channel calibration). Empty for purely
|
|
26
26
|
* test-method-driven roles. */
|
|
27
27
|
used_by_modules: string[];
|
|
28
|
+
/** Optional per-field seed values declared on the asset_ref's
|
|
29
|
+
* `defaults` map. AIS uses these to pre-fill nameplate inputs when
|
|
30
|
+
* the operator creates a new asset for this role — the operator
|
|
31
|
+
* confirms or edits, the values are never enforced. Absent when no
|
|
32
|
+
* asset_ref declared defaults (the common case, since built-in
|
|
33
|
+
* load_cell etc. didn't support defaults before the feature
|
|
34
|
+
* landed). Keys are field names from the asset_type's schema;
|
|
35
|
+
* values are untyped JSON (numbers, strings, booleans) matching
|
|
36
|
+
* the field's declared `type`. */
|
|
37
|
+
defaults?: Record<string, any>;
|
|
28
38
|
}
|
|
29
39
|
export type AmsRoleRegistry = {
|
|
30
40
|
[assetType: string]: AmsRole[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmsProvider.d.ts","sourceRoot":"","sources":["../../../src/components/ams/AmsProvider.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,EAOV,KAAK,SAAS,EACjB,MAAM,OAAO,CAAC;AAQf,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC;AAChC,MAAM,MAAM,iBAAiB,GAAG;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACpB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;oCAKgC;IAChC,eAAe,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"AmsProvider.d.ts","sourceRoot":"","sources":["../../../src/components/ams/AmsProvider.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,EAOV,KAAK,SAAS,EACjB,MAAM,OAAO,CAAC;AAQf,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC;AAChC,MAAM,MAAM,iBAAiB,GAAG;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACpB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;oCAKgC;IAChC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;;uCAQmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AACD,MAAM,MAAM,eAAe,GAAG;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAAA;CAAE,CAAC;AAEjE,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,iBAAiB,CAAC;IACjD,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACpD,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACzE,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACpD,SAAS,EAAE,YAAY,CAAC;IACxB,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;CACxD;AA0BD,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACvB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAoIlD,CAAC;AAMF,eAAO,MAAM,MAAM,uBAAwC,CAAC;AAC5D,eAAO,MAAM,aAAa,yBAAyC,CAAC;AACpE,eAAO,MAAM,WAAW,uBAAyC,CAAC;AAClE,eAAO,MAAM,YAAY,iBAAyC,CAAC;AACnE,eAAO,MAAM,YAAY,uBAAyC,CAAC;AACnE,eAAO,MAAM,eAAe,wCA9KF,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAiLvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetRegistryTable.d.ts","sourceRoot":"","sources":["../../../src/components/ams/AssetRegistryTable.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAmD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AssetRegistryTable.d.ts","sourceRoot":"","sources":["../../../src/components/ams/AssetRegistryTable.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAuJxE,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAwgBtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{useContext,useEffect,useMemo,useState}from"react";import{Button}from"primereact/button";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Dropdown}from"primereact/dropdown";import{InputText}from"primereact/inputtext";import{Dialog}from"primereact/dialog";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useAms}from"./AmsProvider";const ROLE_OTHER="__other__",EMPTY_ADD={open:!1,assetType:"",serial:"",roleSelection:"",location:"",customFields:{},subLocationFields:{}};function roleLabel(e){return e.label??e.location}function roleUsageSummary(e){const s=[];return e.used_by.length>0&&s.push(`Used by test method${1===e.used_by.length?"":"s"}: ${e.used_by.join(", ")}`),e.used_by_modules.length>0&&s.push(`Used by module${1===e.used_by_modules.length?"":"s"}: ${e.used_by_modules.join(", ")}`),0===s.length?"Not referenced by any test method or module.":s.join(" • ")}function fieldsFor(e,s){const t=e?.[s]?.fields;return Array.isArray(t)?t:[]}function subLocationsFor(e,s){const t=e?.[s]?.sub_locations;return t&&Array.isArray(t.keys)&&Array.isArray(t.fields)?t:null}function coerceField(e,s){if(void 0!==s&&""!==s)switch(e.type){case"f32":case"f64":case"i8":case"i16":case"i32":case"i64":case"u8":case"u16":case"u32":case"u64":{const e=Number(s);return Number.isFinite(e)?e:void 0}case"bool":return"true"===s||"1"===s;default:return s}}export const AssetRegistryTable=()=>{const{schemas:e,roles:s,assets:t,refreshAssets:o,setSelection:l,selection:a}=useAms(),{invoke:r}=useContext(EventEmitterContext),[i,n]=useState(null),[c,d]=useState(null),[u,m]=useState(EMPTY_ADD);useEffect(()=>{const e=e=>{const s=e.detail,t=s?.assetType??"",o=s?.location??"";t&&m({...EMPTY_ADD,open:!0,assetType:t,roleSelection:o,location:o})};return window.addEventListener("ams:prefill-add",e),()=>window.removeEventListener("ams:prefill-add",e)},[]);const p=useMemo(()=>Object.keys(e).map(s=>({label:e[s]?.label??s,value:s})),[e]),y=useMemo(()=>u.assetType?s[u.assetType]??[]:[],[u.assetType,s]),_=y.length>0,h=useMemo(()=>{const e=y.map(e=>({label:roleLabel(e),value:e.location}));return e.push({label:"Other (advanced — type a custom role)",value:ROLE_OTHER}),e},[y]),b=useMemo(()=>u.roleSelection===ROLE_OTHER?null:y.find(e=>e.location===u.roleSelection)??null,[u.roleSelection,y]),f=useMemo(()=>t.filter(e=>(!i||e.asset_type===i)&&(!c||e.status===c)),[t,i,c]),x=useMemo(()=>fieldsFor(e,u.assetType),[e,u.assetType]),g=useMemo(()=>subLocationsFor(e,u.assetType),[e,u.assetType]),j=!u.assetType||_&&(""===u.roleSelection||u.roleSelection===ROLE_OTHER&&!u.location.trim())||x.some(e=>e.required&&!u.customFields[e.name]?.toString().trim())||(g?.keys.some(e=>g.fields.some(s=>s.required&&!u.subLocationFields[e]?.[s.name]?.toString().trim()))??!1);return _jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[_jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center"},children:[_jsx(Dropdown,{value:i,options:[{label:"All Types",value:null},...p],onChange:e=>n(e.value),placeholder:"Filter by type"}),_jsx(Dropdown,{value:c,options:[{label:"All Statuses",value:null},{label:"Active",value:"active"},{label:"Out for Service",value:"out_for_service"},{label:"Retired",value:"retired"}],onChange:e=>d(e.value),placeholder:"Filter by status"}),_jsx("span",{style:{marginLeft:"auto"},children:_jsx(Button,{icon:"pi pi-plus",label:"Add Asset",onClick:()=>m(e=>({...e,open:!0})),disabled:0===p.length})})]}),_jsxs(DataTable,{value:f,selectionMode:"single",selection:f.find(e=>e.asset_id===a.assetId)??null,onSelectionChange:e=>{const s=e.value;s&&l({assetType:s.asset_type,assetId:s.asset_id})},dataKey:"asset_id",emptyMessage:0===p.length?"AMS not enabled in this project (no asset_types declared).":"No assets registered yet.",size:"small",stripedRows:!0,children:[_jsx(Column,{field:"asset_id",header:"Asset ID"}),_jsx(Column,{field:"asset_type",header:"Type",body:s=>e[s.asset_type]?.label??s.asset_type}),_jsx(Column,{field:"serial",header:"Serial"}),_jsx(Column,{field:"location",header:"Role",body:e=>e.location?((e,t)=>{const o=(s[e]??[]).find(e=>e.location===t);return o?roleLabel(o):t})(e.asset_type,e.location):_jsx("span",{style:{color:"#9ca3af"},children:"—"})}),_jsx(Column,{field:"status",header:"Status"}),_jsx(Column,{header:"Calibration",body:e=>e.current_calibration_id?_jsx("span",{title:e.current_calibration_id,children:"✓"}):_jsx("span",{style:{color:"#f59e0b"},children:"none"})})]}),_jsxs(Dialog,{header:"Add New Asset",visible:u.open,style:{width:"32rem"},onHide:()=>m(EMPTY_ADD),footer:_jsxs(_Fragment,{children:[_jsx(Button,{label:"Cancel",severity:"secondary",onClick:()=>m(EMPTY_ADD)}),_jsx(Button,{label:"Create",icon:"pi pi-check",onClick:async()=>{if(!u.assetType)return;const e={};for(const s of x){const t=u.customFields[s.name];if(void 0!==t&&""!==t)switch(s.type){case"f32":case"f64":case"i8":case"i16":case"i32":case"i64":case"u8":case"u16":case"u32":case"u64":{const o=Number(t);Number.isFinite(o)&&(e[s.name]=o);break}case"bool":e[s.name]="true"===t||"1"===t;break;default:e[s.name]=t}}const s={};if(g)for(const e of g.keys){const t={};for(const s of g.fields){const o=coerceField(s,u.subLocationFields[e]?.[s.name]??"");void 0!==o&&(t[s.name]=o)}s[e]=t}const t={asset_type:u.assetType,serial:u.serial,location:u.location,custom:e};g&&(t.sub_locations=s);try{const e=await r("ams.create_asset",MessageType.Request,t);e?.success&&(m(EMPTY_ADD),await o(),e.data?.asset_id&&l({assetType:u.assetType,assetId:e.data.asset_id}))}catch(e){}},disabled:j})]}),children:[_jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"0.5rem 1rem",alignItems:"center"},children:[_jsx("label",{children:"Type *"}),_jsx(Dropdown,{value:u.assetType,options:p,onChange:e=>(e=>{const t=s[e]??[],o=1===t.length?{roleSelection:t[0].location,location:t[0].location}:{roleSelection:"",location:""};m(s=>({...s,assetType:e,...o,customFields:{},subLocationFields:{}}))})(e.value),placeholder:"Choose asset type"}),_jsx("label",{children:"Serial"}),_jsx(InputText,{value:u.serial,onChange:e=>m(s=>({...s,serial:e.target.value}))}),_&&_jsxs(_Fragment,{children:[_jsx("label",{children:"Role *"}),_jsx(Dropdown,{value:u.roleSelection,options:h,onChange:e=>{return s=e.value,void m(s===ROLE_OTHER?e=>({...e,roleSelection:ROLE_OTHER,location:""}):e=>({...e,roleSelection:s,location:s}));var s},placeholder:"Choose where this asset is mounted"}),u.roleSelection===ROLE_OTHER&&_jsxs(_Fragment,{children:[_jsx("label",{children:"Custom role"}),_jsx(InputText,{value:u.location,placeholder:"e.g. tsdr_secondary",onChange:e=>m(s=>({...s,location:e.target.value}))})]})]}),x.map(e=>{const s=e.label??e.name,t=e.units?`${s} [${e.units}]${e.required?" *":""}`:`${s}${e.required?" *":""}`,o="string"!==e.type&&"bool"!==e.type;return _jsxs(React.Fragment,{children:[_jsx("label",{title:e.description??void 0,children:t}),"bool"===e.type?_jsx(Dropdown,{value:u.customFields[e.name]??"",options:[{label:"true",value:"true"},{label:"false",value:"false"}],onChange:s=>m(t=>({...t,customFields:{...t.customFields,[e.name]:s.value}})),placeholder:"—"}):_jsx(InputText,{value:u.customFields[e.name]??"",keyfilter:o?"num":void 0,placeholder:e.description??void 0,onChange:s=>m(t=>({...t,customFields:{...t.customFields,[e.name]:s.target.value}}))})]},e.name)})]}),g&&_jsxs("div",{style:{marginTop:"1.5rem"},children:[_jsx("h4",{style:{margin:"0 0 0.5rem 0"},children:g.label??"Sub-locations"}),_jsx("div",{style:{overflowX:"auto"},children:_jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"0.875rem"},children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{style:{textAlign:"left",padding:"0.25rem 0.5rem",borderBottom:"1px solid var(--surface-border)"},children:g.key_label??"Key"}),g.fields.map(e=>_jsxs("th",{title:e.description??void 0,style:{textAlign:"left",padding:"0.25rem 0.5rem",borderBottom:"1px solid var(--surface-border)"},children:[e.label??e.name,e.units?` [${e.units}]`:"",e.required?" *":""]},e.name))]})}),_jsx("tbody",{children:g.keys.map(e=>_jsxs("tr",{children:[_jsx("td",{style:{padding:"0.25rem 0.5rem",fontWeight:600},children:e}),g.fields.map(s=>{const t=u.subLocationFields[e]?.[s.name]??"",o="string"!==s.type&&"bool"!==s.type;return _jsx("td",{style:{padding:"0.25rem 0.5rem"},children:_jsx(InputText,{value:t,keyfilter:o?"num":void 0,onChange:t=>{const o=t.target.value;m(t=>({...t,subLocationFields:{...t.subLocationFields,[e]:{...t.subLocationFields[e]??{},[s.name]:o}}}))},style:{width:"100%"}})},s.name)})]},e))})]})})]}),_jsxs("div",{style:{fontSize:"0.875rem",color:"#9ca3af",marginTop:"1rem"},children:[_&&b&&_jsxs(_Fragment,{children:[b.description&&_jsx("p",{style:{margin:"0 0 0.5rem 0"},children:b.description}),_jsxs("p",{style:{margin:"0 0 0.5rem 0",color:"#34d399"},children:["✓ ",roleUsageSummary(b)]})]}),_&&u.roleSelection===ROLE_OTHER&&_jsx("p",{style:{margin:"0 0 0.5rem 0",color:"#f59e0b"},children:"⚠ No test method on this machine references this custom role yet. The asset will be registered but won't be picked up at start_test unless you add an asset_ref to a test method's project.json."}),!_&&u.assetType&&_jsx("p",{style:{margin:"0 0 0.5rem 0"},children:"This asset type isn't selected by physical role on this machine — test methods reference it by ID instead. Just register the asset and pick it by ID on the Test Setup form when running a test."}),_jsxs("p",{style:{margin:0},children:["The asset_id is generated by the server (format:"," ",_jsxs("code",{children:[u.assetType?e[u.assetType]?.id_prefix??"A-":"A-","YYYYMMDDTHHMMSS"]}),"). Manufacturer serial is recorded for traceability but is not used as the unique key."]})]})]})]})};
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{useContext,useEffect,useMemo,useState}from"react";import{Button}from"primereact/button";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Dropdown}from"primereact/dropdown";import{InputText}from"primereact/inputtext";import{Dialog}from"primereact/dialog";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useAms}from"./AmsProvider";const ROLE_OTHER="__other__",EMPTY_ADD={open:!1,assetType:"",serial:"",roleSelection:"",location:"",customFields:{},subLocationFields:{}};function roleLabel(e){return e.label??e.location}function roleUsageSummary(e){const s=[];return e.used_by.length>0&&s.push(`Used by test method${1===e.used_by.length?"":"s"}: ${e.used_by.join(", ")}`),e.used_by_modules.length>0&&s.push(`Used by module${1===e.used_by_modules.length?"":"s"}: ${e.used_by_modules.join(", ")}`),0===s.length?"Not referenced by any test method or module.":s.join(" • ")}function fieldsFor(e,s){const t=e?.[s]?.fields;return Array.isArray(t)?t:[]}function subLocationsFor(e,s){const t=e?.[s]?.sub_locations;return t&&Array.isArray(t.keys)&&Array.isArray(t.fields)?t:null}function seedCustomFromRoleDefaults(e,s){const t={};if(!e||!e.defaults)return t;const o=new Set(s.map(e=>e.name));for(const[s,l]of Object.entries(e.defaults))o.has(s)&&null!=l&&(t[s]=String(l));return t}function coerceField(e,s){if(void 0!==s&&""!==s)switch(e.type){case"f32":case"f64":case"i8":case"i16":case"i32":case"i64":case"u8":case"u16":case"u32":case"u64":{const e=Number(s);return Number.isFinite(e)?e:void 0}case"bool":return"true"===s||"1"===s;default:return s}}export const AssetRegistryTable=()=>{const{schemas:e,roles:s,assets:t,refreshAssets:o,setSelection:l,selection:a}=useAms(),{invoke:n}=useContext(EventEmitterContext),[r,i]=useState(null),[c,d]=useState(null),[u,m]=useState(EMPTY_ADD);useEffect(()=>{const t=t=>{const o=t.detail,l=o?.assetType??"",a=o?.location??"";if(!l)return;const n=(s[l]??[]).find(e=>e.location===a),r=fieldsFor(e,l);m({...EMPTY_ADD,open:!0,assetType:l,roleSelection:a,location:a,customFields:seedCustomFromRoleDefaults(n,r)})};return window.addEventListener("ams:prefill-add",t),()=>window.removeEventListener("ams:prefill-add",t)},[s,e]);const p=useMemo(()=>Object.keys(e).map(s=>({label:e[s]?.label??s,value:s})),[e]),y=useMemo(()=>u.assetType?s[u.assetType]??[]:[],[u.assetType,s]),_=y.length>0,h=useMemo(()=>{const e=y.map(e=>({label:roleLabel(e),value:e.location}));return e.push({label:"Other (advanced — type a custom role)",value:ROLE_OTHER}),e},[y]),f=useMemo(()=>u.roleSelection===ROLE_OTHER?null:y.find(e=>e.location===u.roleSelection)??null,[u.roleSelection,y]),b=useMemo(()=>t.filter(e=>(!r||e.asset_type===r)&&(!c||e.status===c)),[t,r,c]),x=useMemo(()=>fieldsFor(e,u.assetType),[e,u.assetType]),g=useMemo(()=>subLocationsFor(e,u.assetType),[e,u.assetType]),j=!u.assetType||_&&(""===u.roleSelection||u.roleSelection===ROLE_OTHER&&!u.location.trim())||x.some(e=>e.required&&!u.customFields[e.name]?.toString().trim())||(g?.keys.some(e=>g.fields.some(s=>s.required&&!u.subLocationFields[e]?.[s.name]?.toString().trim()))??!1);return _jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[_jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center"},children:[_jsx(Dropdown,{value:r,options:[{label:"All Types",value:null},...p],onChange:e=>i(e.value),placeholder:"Filter by type"}),_jsx(Dropdown,{value:c,options:[{label:"All Statuses",value:null},{label:"Active",value:"active"},{label:"Out for Service",value:"out_for_service"},{label:"Retired",value:"retired"}],onChange:e=>d(e.value),placeholder:"Filter by status"}),_jsx("span",{style:{marginLeft:"auto"},children:_jsx(Button,{icon:"pi pi-plus",label:"Add Asset",onClick:()=>m(e=>({...e,open:!0})),disabled:0===p.length})})]}),_jsxs(DataTable,{value:b,selectionMode:"single",selection:b.find(e=>e.asset_id===a.assetId)??null,onSelectionChange:e=>{const s=e.value;s&&l({assetType:s.asset_type,assetId:s.asset_id})},dataKey:"asset_id",emptyMessage:0===p.length?"AMS not enabled in this project (no asset_types declared).":"No assets registered yet.",size:"small",stripedRows:!0,children:[_jsx(Column,{field:"asset_id",header:"Asset ID"}),_jsx(Column,{field:"asset_type",header:"Type",body:s=>e[s.asset_type]?.label??s.asset_type}),_jsx(Column,{field:"serial",header:"Serial"}),_jsx(Column,{field:"location",header:"Role",body:e=>e.location?((e,t)=>{const o=(s[e]??[]).find(e=>e.location===t);return o?roleLabel(o):t})(e.asset_type,e.location):_jsx("span",{style:{color:"#9ca3af"},children:"—"})}),_jsx(Column,{field:"status",header:"Status"}),_jsx(Column,{header:"Calibration",body:e=>e.current_calibration_id?_jsx("span",{title:e.current_calibration_id,children:"✓"}):_jsx("span",{style:{color:"#f59e0b"},children:"none"})})]}),_jsxs(Dialog,{header:"Add New Asset",visible:u.open,style:{width:"32rem"},onHide:()=>m(EMPTY_ADD),footer:_jsxs(_Fragment,{children:[_jsx(Button,{label:"Cancel",severity:"secondary",onClick:()=>m(EMPTY_ADD)}),_jsx(Button,{label:"Create",icon:"pi pi-check",onClick:async()=>{if(!u.assetType)return;const e={};for(const s of x){const t=u.customFields[s.name];if(void 0!==t&&""!==t)switch(s.type){case"f32":case"f64":case"i8":case"i16":case"i32":case"i64":case"u8":case"u16":case"u32":case"u64":{const o=Number(t);Number.isFinite(o)&&(e[s.name]=o);break}case"bool":e[s.name]="true"===t||"1"===t;break;default:e[s.name]=t}}const s={};if(g)for(const e of g.keys){const t={};for(const s of g.fields){const o=coerceField(s,u.subLocationFields[e]?.[s.name]??"");void 0!==o&&(t[s.name]=o)}s[e]=t}const t={asset_type:u.assetType,serial:u.serial,location:u.location,custom:e};g&&(t.sub_locations=s);try{const e=await n("ams.create_asset",MessageType.Request,t);e?.success&&(m(EMPTY_ADD),await o(),e.data?.asset_id&&l({assetType:u.assetType,assetId:e.data.asset_id}))}catch(e){}},disabled:j})]}),children:[_jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"0.5rem 1rem",alignItems:"center"},children:[_jsx("label",{children:"Type *"}),_jsx(Dropdown,{value:u.assetType,options:p,onChange:t=>(t=>{const o=s[t]??[],l=1===o.length?o[0]:void 0,a=l?{roleSelection:l.location,location:l.location}:{roleSelection:"",location:""},n=fieldsFor(e,t);m(e=>({...e,assetType:t,...a,customFields:seedCustomFromRoleDefaults(l,n),subLocationFields:{}}))})(t.value),placeholder:"Choose asset type"}),_jsx("label",{children:"Serial"}),_jsx(InputText,{value:u.serial,onChange:e=>m(s=>({...s,serial:e.target.value}))}),_&&_jsxs(_Fragment,{children:[_jsx("label",{children:"Role *"}),_jsx(Dropdown,{value:u.roleSelection,options:h,onChange:e=>(e=>{if(e===ROLE_OTHER)return void m(e=>({...e,roleSelection:ROLE_OTHER,location:""}));const s=y.find(s=>s.location===e);m(t=>({...t,roleSelection:e,location:e,customFields:seedCustomFromRoleDefaults(s,x)}))})(e.value),placeholder:"Choose where this asset is mounted"}),u.roleSelection===ROLE_OTHER&&_jsxs(_Fragment,{children:[_jsx("label",{children:"Custom role"}),_jsx(InputText,{value:u.location,placeholder:"e.g. tsdr_secondary",onChange:e=>m(s=>({...s,location:e.target.value}))})]})]}),x.map(e=>{const s=e.label??e.name,t=e.units?`${s} [${e.units}]${e.required?" *":""}`:`${s}${e.required?" *":""}`,o="string"!==e.type&&"bool"!==e.type;return _jsxs(React.Fragment,{children:[_jsx("label",{title:e.description??void 0,children:t}),"bool"===e.type?_jsx(Dropdown,{value:u.customFields[e.name]??"",options:[{label:"true",value:"true"},{label:"false",value:"false"}],onChange:s=>m(t=>({...t,customFields:{...t.customFields,[e.name]:s.value}})),placeholder:"—"}):_jsx(InputText,{value:u.customFields[e.name]??"",keyfilter:o?"num":void 0,placeholder:e.description??void 0,onChange:s=>m(t=>({...t,customFields:{...t.customFields,[e.name]:s.target.value}}))})]},e.name)})]}),g&&_jsxs("div",{style:{marginTop:"1.5rem"},children:[_jsx("h4",{style:{margin:"0 0 0.5rem 0"},children:g.label??"Sub-locations"}),_jsx("div",{style:{overflowX:"auto"},children:_jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"0.875rem"},children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{style:{textAlign:"left",padding:"0.25rem 0.5rem",borderBottom:"1px solid var(--surface-border)"},children:g.key_label??"Key"}),g.fields.map(e=>_jsxs("th",{title:e.description??void 0,style:{textAlign:"left",padding:"0.25rem 0.5rem",borderBottom:"1px solid var(--surface-border)"},children:[e.label??e.name,e.units?` [${e.units}]`:"",e.required?" *":""]},e.name))]})}),_jsx("tbody",{children:g.keys.map(e=>_jsxs("tr",{children:[_jsx("td",{style:{padding:"0.25rem 0.5rem",fontWeight:600},children:e}),g.fields.map(s=>{const t=u.subLocationFields[e]?.[s.name]??"",o="string"!==s.type&&"bool"!==s.type;return _jsx("td",{style:{padding:"0.25rem 0.5rem"},children:_jsx(InputText,{value:t,keyfilter:o?"num":void 0,onChange:t=>{const o=t.target.value;m(t=>({...t,subLocationFields:{...t.subLocationFields,[e]:{...t.subLocationFields[e]??{},[s.name]:o}}}))},style:{width:"100%"}})},s.name)})]},e))})]})})]}),_jsxs("div",{style:{fontSize:"0.875rem",color:"#9ca3af",marginTop:"1rem"},children:[_&&f&&_jsxs(_Fragment,{children:[f.description&&_jsx("p",{style:{margin:"0 0 0.5rem 0"},children:f.description}),_jsxs("p",{style:{margin:"0 0 0.5rem 0",color:"#34d399"},children:["✓ ",roleUsageSummary(f)]})]}),_&&u.roleSelection===ROLE_OTHER&&_jsx("p",{style:{margin:"0 0 0.5rem 0",color:"#f59e0b"},children:"⚠ No test method on this machine references this custom role yet. The asset will be registered but won't be picked up at start_test unless you add an asset_ref to a test method's project.json."}),!_&&u.assetType&&_jsx("p",{style:{margin:"0 0 0.5rem 0"},children:"This asset type isn't selected by physical role on this machine — test methods reference it by ID instead. Just register the asset and pick it by ID on the Test Setup form when running a test."}),_jsxs("p",{style:{margin:0},children:["The asset_id is generated by the server (format:"," ",_jsxs("code",{children:[u.assetType?e[u.assetType]?.id_prefix??"A-":"A-","YYYYMMDDTHHMMSS"]}),"). Manufacturer serial is recorded for traceability but is not used as the unique key."]})]})]})]})};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormRow — grid-aligned label/input pair with optional required marker
|
|
3
|
+
* and inline error text. Drop inside a FormSection.
|
|
4
|
+
*/
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import './forms.css';
|
|
7
|
+
export interface FormRowProps {
|
|
8
|
+
label: React.ReactNode;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
/** Optional descriptive hint shown beneath the label. */
|
|
11
|
+
hint?: React.ReactNode;
|
|
12
|
+
/** Inline error text shown beneath the input. */
|
|
13
|
+
error?: React.ReactNode;
|
|
14
|
+
/** Optional `htmlFor` association on the label tag. */
|
|
15
|
+
htmlFor?: string;
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export declare const FormRow: React.FC<FormRowProps>;
|
|
19
|
+
export default FormRow;
|
|
20
|
+
//# sourceMappingURL=FormRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRow.d.ts","sourceRoot":"","sources":["../../../src/components/forms/FormRow.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,iDAAiD;IACjD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAc1C,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import*as React from"react";import"./forms.css";export const FormRow=({label:r,required:s,hint:a,error:e,htmlFor:o,children:l})=>_jsxs("div",{className:"ac-formrow"+(e?" ac-formrow--error":""),children:[_jsxs("label",{className:"ac-formrow__label",htmlFor:o,children:[r,s&&_jsx("span",{className:"ac-formrow__required","aria-hidden":!0,children:" *"}),a&&_jsx("small",{className:"ac-formrow__hint",children:a})]}),_jsxs("div",{className:"ac-formrow__field",children:[l,e&&_jsx("small",{className:"ac-formrow__error",children:e})]})]});export default FormRow;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormSection — labeled bordered region containing a group of FormRow rows.
|
|
3
|
+
*
|
|
4
|
+
* Used by the TIS editor subforms and intended for app-level settings
|
|
5
|
+
* pages. Replaces the ad-hoc `.ac-form-grid` divs scattered across project
|
|
6
|
+
* settings views.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from 'react';
|
|
9
|
+
import './forms.css';
|
|
10
|
+
export interface FormSectionProps {
|
|
11
|
+
title?: React.ReactNode;
|
|
12
|
+
description?: React.ReactNode;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
/** Right-aligned controls (buttons, dirty pill, etc.). */
|
|
15
|
+
actions?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export declare const FormSection: React.FC<FormSectionProps>;
|
|
18
|
+
export default FormSection;
|
|
19
|
+
//# sourceMappingURL=FormSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSection.d.ts","sourceRoot":"","sources":["../../../src/components/forms/FormSection.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiBlD,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import*as React from"react";import"./forms.css";export const FormSection=({title:s,description:c,actions:e,children:a})=>_jsxs("section",{className:"ac-formsection",children:[(s||e)&&_jsxs("header",{className:"ac-formsection__header",children:[_jsxs("div",{children:[s&&_jsx("h3",{className:"ac-formsection__title",children:s}),c&&_jsx("small",{className:"ac-formsection__desc",children:c})]}),e&&_jsx("div",{className:"ac-formsection__actions",children:e})]}),_jsx("div",{className:"ac-formsection__body",children:a})]});export default FormSection;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.ac-formsection {
|
|
2
|
+
border: 1px solid var(--surface-d, #e2e8f0);
|
|
3
|
+
border-radius: 6px;
|
|
4
|
+
background: var(--surface-card, #fff);
|
|
5
|
+
margin-bottom: 1rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.ac-formsection__header {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: flex-start;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
padding: 0.5rem 1rem;
|
|
13
|
+
border-bottom: 1px solid var(--surface-d, #e2e8f0);
|
|
14
|
+
background: var(--surface-b, #f8fafc);
|
|
15
|
+
border-top-left-radius: 6px;
|
|
16
|
+
border-top-right-radius: 6px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.ac-formsection__title {
|
|
20
|
+
margin: 0;
|
|
21
|
+
font-size: 0.95rem;
|
|
22
|
+
font-weight: 600;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ac-formsection__desc {
|
|
26
|
+
color: var(--text-color-secondary, #64748b);
|
|
27
|
+
display: block;
|
|
28
|
+
margin-top: 0.15rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ac-formsection__actions {
|
|
32
|
+
display: flex;
|
|
33
|
+
gap: 0.5rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.ac-formsection__body {
|
|
37
|
+
padding: 0.75rem 1rem;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
gap: 0.5rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ac-formrow {
|
|
44
|
+
display: grid;
|
|
45
|
+
grid-template-columns: minmax(8rem, 14rem) 1fr;
|
|
46
|
+
gap: 0.5rem 1rem;
|
|
47
|
+
align-items: start;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ac-formrow--error .ac-formrow__field input,
|
|
51
|
+
.ac-formrow--error .ac-formrow__field .p-inputtext {
|
|
52
|
+
border-color: #dc2626;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ac-formrow__label {
|
|
56
|
+
font-weight: 500;
|
|
57
|
+
padding-top: 0.4rem;
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.ac-formrow__required {
|
|
63
|
+
color: #dc2626;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ac-formrow__hint {
|
|
67
|
+
color: var(--text-color-secondary, #64748b);
|
|
68
|
+
font-weight: 400;
|
|
69
|
+
font-size: 0.75rem;
|
|
70
|
+
margin-top: 0.15rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.ac-formrow__field {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
gap: 0.25rem;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.ac-formrow__field > input,
|
|
80
|
+
.ac-formrow__field > .p-inputtext,
|
|
81
|
+
.ac-formrow__field > .p-dropdown,
|
|
82
|
+
.ac-formrow__field > .p-inputtextarea {
|
|
83
|
+
width: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ac-formrow__error {
|
|
87
|
+
color: #dc2626;
|
|
88
|
+
font-size: 0.75rem;
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{FormSection}from"./FormSection";export{FormRow}from"./FormRow";
|