@adcops/autocore-react 3.3.113 → 3.3.116
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/index.d.ts +10 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/tis/CycleConfigDialog.d.ts +39 -0
- package/dist/components/tis/CycleConfigDialog.d.ts.map +1 -0
- package/dist/components/tis/CycleConfigDialog.js +1 -0
- package/dist/components/tis/CycleConfigForm.d.ts +22 -0
- package/dist/components/tis/CycleConfigForm.d.ts.map +1 -0
- package/dist/components/tis/CycleConfigForm.js +1 -0
- package/dist/components/tis/CycleStatusStrip.d.ts +10 -0
- package/dist/components/tis/CycleStatusStrip.d.ts.map +1 -0
- package/dist/components/tis/CycleStatusStrip.js +1 -0
- package/dist/components/tis/ResultHistoryTable.d.ts.map +1 -1
- package/dist/components/tis/ResultHistoryTable.js +1 -1
- package/dist/components/tis/ScienceTable.d.ts +15 -0
- package/dist/components/tis/ScienceTable.d.ts.map +1 -1
- package/dist/components/tis/ScienceTable.js +1 -1
- package/dist/components/tis/TestDataView.d.ts +14 -4
- package/dist/components/tis/TestDataView.d.ts.map +1 -1
- package/dist/components/tis/TestDataView.js +1 -1
- package/dist/components/tis/TestFieldRow.d.ts +151 -0
- package/dist/components/tis/TestFieldRow.d.ts.map +1 -0
- package/dist/components/tis/TestFieldRow.js +1 -0
- package/dist/components/tis/TestSetupForm.d.ts +15 -51
- package/dist/components/tis/TestSetupForm.d.ts.map +1 -1
- package/dist/components/tis/TestSetupForm.js +1 -1
- package/dist/components/tis/TestSetupView.d.ts.map +1 -1
- package/dist/components/tis/TestSetupView.js +1 -1
- package/dist/components/tis/TisProvider.d.ts +80 -0
- package/dist/components/tis/TisProvider.d.ts.map +1 -1
- package/dist/components/tis/TisProvider.js +1 -1
- package/dist/components/tis-editor/TisConfigEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/TisConfigEditor.js +1 -1
- package/dist/components/tis-editor/editor/CycleConfigSection.d.ts +19 -0
- package/dist/components/tis-editor/editor/CycleConfigSection.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/CycleConfigSection.js +1 -0
- package/dist/components/tis-editor/editor/FieldArrayEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/FieldArrayEditor.js +1 -1
- package/dist/components/tis-editor/editor/MethodFormEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/MethodFormEditor.js +1 -1
- package/dist/components/tis-editor/editor/TestFieldDialog.d.ts +3 -0
- 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/editor/ViewsEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/ViewsEditor.js +1 -1
- package/dist/components/tis-editor/types.d.ts +28 -1
- package/dist/components/tis-editor/types.d.ts.map +1 -1
- package/dist/components/tis-editor/validation.d.ts.map +1 -1
- package/dist/components/tis-editor/validation.js +1 -1
- package/package.json +110 -110
- package/src/components/index.ts +14 -0
- package/src/components/tis/CycleConfigDialog.tsx +173 -0
- package/src/components/tis/CycleConfigForm.tsx +192 -0
- package/src/components/tis/CycleStatusStrip.tsx +84 -0
- package/src/components/tis/ResultHistoryTable.tsx +141 -1
- package/src/components/tis/ScienceTable.tsx +71 -12
- package/src/components/tis/TestDataView.tsx +82 -7
- package/src/components/tis/TestFieldRow.tsx +297 -0
- package/src/components/tis/TestSetupForm.tsx +52 -212
- package/src/components/tis/TestSetupView.tsx +60 -3
- package/src/components/tis/TisProvider.tsx +191 -0
- package/src/components/tis-editor/TisConfigEditor.tsx +1 -0
- package/src/components/tis-editor/editor/CycleConfigSection.tsx +93 -0
- package/src/components/tis-editor/editor/FieldArrayEditor.tsx +10 -0
- package/src/components/tis-editor/editor/MethodFormEditor.tsx +10 -4
- package/src/components/tis-editor/editor/TestFieldDialog.tsx +22 -2
- package/src/components/tis-editor/editor/ViewsEditor.tsx +3 -0
- package/src/components/tis-editor/types.ts +34 -1
- package/src/components/tis-editor/validation.ts +20 -2
|
@@ -25,6 +25,15 @@ export interface TestField {
|
|
|
25
25
|
* non-excluded runs sharing this test's sample_id. When set, the field
|
|
26
26
|
* is NOT supplied by the analysis script — the server computes it. */
|
|
27
27
|
aggregate?: AggregateSpec;
|
|
28
|
+
/** cycle_fields only: operator-correctable after recording. Measured
|
|
29
|
+
* columns must stay unflagged. cycle_config_fields don't need it —
|
|
30
|
+
* they're annotation and are always correctable. */
|
|
31
|
+
editable?: boolean;
|
|
32
|
+
/** cycle_config_fields only: clear the operator's entry once a row has
|
|
33
|
+
* recorded it, so the next row can't inherit a stale annotation. Pair
|
|
34
|
+
* it with `required` — on its own it turns stale data into silently
|
|
35
|
+
* missing data. */
|
|
36
|
+
autoclear?: boolean;
|
|
28
37
|
}
|
|
29
38
|
export type AggFn = 'avg' | 'min' | 'max' | 'stddev' | 'count';
|
|
30
39
|
export type AggFrom = 'cycle_fields' | 'results';
|
|
@@ -93,11 +102,29 @@ export interface TestConfiguration {
|
|
|
93
102
|
description?: string;
|
|
94
103
|
defaults?: Record<string, unknown>;
|
|
95
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Which boundary an operator annotates `cycle_config_fields` at.
|
|
107
|
+
*
|
|
108
|
+
* 'run' one latch per Start — the same values stamp every cycle of the
|
|
109
|
+
* run and clear when it closes. Default; correct for a machine
|
|
110
|
+
* that records many cycles from one Start.
|
|
111
|
+
* 'cycle' one latch per cycle — values clear after each recorded row and
|
|
112
|
+
* the gate re-arms, so every row is annotated separately.
|
|
113
|
+
*/
|
|
114
|
+
export type CycleConfigScope = 'run' | 'cycle';
|
|
96
115
|
export interface TestMethod {
|
|
97
116
|
label?: string;
|
|
98
117
|
description?: string;
|
|
99
118
|
project_fields?: TestField[];
|
|
100
119
|
config_fields?: TestField[];
|
|
120
|
+
/** Operator-entered per-row annotation, recorded as the first Cycle Data
|
|
121
|
+
* columns after the row index. */
|
|
122
|
+
cycle_config_fields?: TestField[];
|
|
123
|
+
/** Boundary at which cycle_config_fields latch and autoclear. */
|
|
124
|
+
cycle_config_scope?: CycleConfigScope;
|
|
125
|
+
/** Open the Cycle Configuration dialog at the boundary rather than
|
|
126
|
+
* relying on the operator having filled the Cycle tab. */
|
|
127
|
+
prompt_before_cycle?: boolean;
|
|
101
128
|
cycle_fields?: TestField[];
|
|
102
129
|
results_fields?: TestField[];
|
|
103
130
|
raw_data?: RawDataShape | null;
|
|
@@ -107,5 +134,5 @@ export interface TestMethod {
|
|
|
107
134
|
configurations?: TestConfiguration[];
|
|
108
135
|
[key: string]: unknown;
|
|
109
136
|
}
|
|
110
|
-
export type FieldArrayKey = 'project_fields' | 'config_fields' | 'cycle_fields' | 'results_fields';
|
|
137
|
+
export type FieldArrayKey = 'project_fields' | 'config_fields' | 'cycle_config_fields' | 'cycle_fields' | 'results_fields';
|
|
111
138
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,SAAS,GACf,QAAQ,GACR,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAC7B,KAAK,GAAG,KAAK,GACb,MAAM,CAAC;AAEb,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;6DAEyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;2EAEuE;IACvE,SAAS,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/validation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACG,UAAU,EACxB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/validation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACG,UAAU,EACxB,MAAM,SAAS,CAAC;AAMjB,MAAM,WAAW,eAAe;IAC5B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAG,eAAe,EAAE,CAyJjF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAOtG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const FIELD_ARRAY_KEYS=["project_fields","config_fields","cycle_fields","results_fields"];export function validateMethod(e,a){const s=[];for(const
|
|
1
|
+
const FIELD_ARRAY_KEYS=["project_fields","config_fields","cycle_config_fields","cycle_fields","results_fields"];export function validateMethod(e,a){const s=[];for(const n of FIELD_ARRAY_KEYS){const t=a[n]??[],o=new Set;t.forEach((a,t)=>{a.name&&""!==a.name.trim()?o.has(a.name)?s.push({path:`${n}.${t}.name`,message:`${e}.${n}: duplicate field name "${a.name}"`}):o.add(a.name):s.push({path:`${n}.${t}.name`,message:`${e}.${n}: empty field name`}),"number"==typeof a.min&&"number"==typeof a.max&&a.min>a.max&&s.push({path:`${n}.${t}.min`,message:`${e}.${n}.${a.name}: min (${a.min}) is greater than max (${a.max})`})})}const n=new Set(["i32","i64","u32","u64","f32","f64"]),t=new Map((a.cycle_fields??[]).map(e=>[e.name,String(e.type)])),o=new Map((a.results_fields??[]).map(e=>[e.name,String(e.type)]));for(const n of["project_fields","config_fields","cycle_config_fields","cycle_fields"])(a[n]??[]).forEach((a,t)=>{a.aggregate&&s.push({path:`${n}.${t}.aggregate`,message:`${e}.${n}.${a.name}: aggregate is only valid on results_fields`})});(a.results_fields??[]).forEach((a,i)=>{const c=a.aggregate;if(!c||"count"===c.fn)return;const f=c.of?.trim();if(!f)return void s.push({path:`results_fields.${i}.aggregate`,message:`${e}.results_fields.${a.name}: aggregate "${c.fn}" requires a target field (of)`});const r="results"===(c.from??"cycle_fields")?o:t,l="results"===(c.from??"cycle_fields")?"results_fields":"cycle_fields",m=r.get(f);void 0===m?s.push({path:`results_fields.${i}.aggregate`,message:`${e}.results_fields.${a.name}: aggregate "of" references "${f}" which is not a ${l} of this method`}):n.has(m)||s.push({path:`results_fields.${i}.aggregate`,message:`${e}.results_fields.${a.name}: aggregate target "${f}" has non-numeric type "${m}"`})});const i=new Set((a.cycle_fields??[]).map(e=>e.name).filter(Boolean));(a.cycle_config_fields??[]).forEach((a,n)=>{a.name&&i.has(a.name)&&s.push({path:`cycle_config_fields.${n}.name`,message:`${e}: "${a.name}" is declared as both a cycle_config_field and a cycle_field. They share one row namespace; rename one.`})});const c=new Set;for(const e of FIELD_ARRAY_KEYS){(a[e]??[]).forEach(e=>e.name&&c.add(e.name))}const f=new Set(Object.keys(a.raw_data?.columns??{})),r=e=>e.field&&e.field.trim()?{key:e.field,ok:c.has(e.field)}:e.column&&e.column.trim()?{key:e.column,ok:f.has(e.column)}:null,l=a.views??{};for(const[a,n]of Object.entries(l)){if(n?.x){const t=r(n.x);t&&!t.ok&&s.push({path:`views.${a}.x`,message:`${e}.views.${a}: x.field/column "${t.key}" does not match any field or raw_data column`})}(n?.y??[]).forEach((n,t)=>{const o=r(n);o&&!o.ok&&s.push({path:`views.${a}.y.${t}`,message:`${e}.views.${a}.y[${t}]: field/column "${o.key}" does not match any field or raw_data column`})})}const m=a.raw_data;m&&(m.blob_name&&""!==String(m.blob_name).trim()||s.push({path:"raw_data.blob_name",message:`${e}.raw_data: blob_name is empty`}));const d=new Set((a.config_fields??[]).map(e=>e.name).filter(Boolean)),g=a.configurations??[],u=new Set;return g.forEach((a,n)=>{const t="string"==typeof a?.name?a.name.trim():"";t?u.has(t)?s.push({path:`configurations.${n}.name`,message:`${e}.configurations: duplicate configuration name "${t}"`}):u.add(t):s.push({path:`configurations.${n}.name`,message:`${e}.configurations[${n}]: empty configuration name`});const o=a?.defaults??{};for(const a of Object.keys(o))d.has(a)||s.push({path:`configurations.${n}.defaults.${a}`,message:`${e}.configurations.${t||n}: override "${a}" does not match any config_field`})}),s}export function validateMethods(e){const a={};for(const[s,n]of Object.entries(e)){const e=validateMethod(s,n);e.length>0&&(a[s]=e)}return a}
|
package/package.json
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
2
|
+
"name": "@adcops/autocore-react",
|
|
3
|
+
"version": "3.3.116",
|
|
4
|
+
"description": "A React component library for industrial user interfaces.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"clean": "rimraf ./dist",
|
|
9
|
+
"minify": "node ./tools/minify.cjs",
|
|
10
|
+
"tsc": "tsc",
|
|
11
|
+
"build-themes": "node ./tools/build-themes.cjs",
|
|
12
|
+
"generate-docs": "typedoc",
|
|
13
|
+
"build": "npm run clean && tsc && node ./tools/copy-distribution-files.cjs && npm run build-themes && npm run minify",
|
|
14
|
+
"build:dev": "npm run clean && tsc && node ./tools/copy-distribution-files.cjs",
|
|
15
|
+
"dev": "vite",
|
|
16
|
+
"playground": "vite",
|
|
17
|
+
"playground:build": "vite build",
|
|
18
|
+
"prestart": "tsc",
|
|
19
|
+
"publish-package": "npm run build && npm version patch && npm publish",
|
|
20
|
+
"prepublishOnly": "npm run build",
|
|
21
|
+
"release:patch": "npm version patch && npm publish",
|
|
22
|
+
"release:minor": "npm version minor && npm publish",
|
|
23
|
+
"release:major": "npm version major && npm publish",
|
|
24
|
+
"convert-assets": "npx @svgr/cli --typescript --out-dir src/assets/ src/assets/svg/ --jsx-runtime automatic --ignore-existing"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://adc360.visualstudio.com/AutoCore-React/_git/autocore-react"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"react",
|
|
32
|
+
"autocore",
|
|
33
|
+
"component-library",
|
|
34
|
+
"industrial-ui",
|
|
35
|
+
"typescript",
|
|
36
|
+
"primereact"
|
|
37
|
+
],
|
|
38
|
+
"author": "Automated Design Corp.",
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://automateddesign.com"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://automateddesign.com",
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@types/react": "^18",
|
|
46
|
+
"primereact": ">=10.9.7",
|
|
47
|
+
"react": "^18",
|
|
48
|
+
"react-dom": "^18"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@types/react": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@monaco-editor/react": "^4.7.0",
|
|
57
|
+
"@tauri-apps/api": "^2.9.1",
|
|
58
|
+
"chart.js": "^4.5.1",
|
|
59
|
+
"chartjs-plugin-annotation": "^3.1.0",
|
|
60
|
+
"chartjs-plugin-zoom": "^2.2.0",
|
|
61
|
+
"clsx": "^2.1.1",
|
|
62
|
+
"numerable": "^0.3.15",
|
|
63
|
+
"react-blockly": "^8.1.2",
|
|
64
|
+
"react-chartjs-2": "^5.3.0",
|
|
65
|
+
"react-number-format": "^5.4.5",
|
|
66
|
+
"react-simple-keyboard": "^3.8.120",
|
|
67
|
+
"react-transition-group": "^4.4.5",
|
|
68
|
+
"sass": "^1.92.1",
|
|
69
|
+
"socket.io-client": "^4.8.1",
|
|
70
|
+
"use-fit-text": "^2.4.0"
|
|
71
|
+
},
|
|
72
|
+
"sideEffects": [
|
|
73
|
+
"**/*.css",
|
|
74
|
+
"**/*.scss"
|
|
75
|
+
],
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=20.0.0"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@svgr/cli": "^8.1.0",
|
|
81
|
+
"@types/react": "^18.2.15",
|
|
82
|
+
"@types/react-dom": "^18.2.7",
|
|
83
|
+
"@types/react-transition-group": "^4.4.12",
|
|
84
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
85
|
+
"primereact": "^10.9.7",
|
|
86
|
+
"rimraf": "^6.0.1",
|
|
87
|
+
"terser": "^5.44.0",
|
|
88
|
+
"typedoc": "^0.28.12",
|
|
89
|
+
"typescript": "^5.9.2",
|
|
90
|
+
"vite": "^8.0.13"
|
|
91
|
+
},
|
|
92
|
+
"exports": {
|
|
93
|
+
"./core/*": {
|
|
94
|
+
"import": "./dist/core/*",
|
|
95
|
+
"types": "./dist/core/*.d.ts"
|
|
49
96
|
},
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
97
|
+
"./components/*": {
|
|
98
|
+
"import": "./dist/components/*",
|
|
99
|
+
"types": "./dist/components/*.d.ts"
|
|
54
100
|
},
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"chart.js": "^4.5.1",
|
|
59
|
-
"chartjs-plugin-annotation": "^3.1.0",
|
|
60
|
-
"chartjs-plugin-zoom": "^2.2.0",
|
|
61
|
-
"clsx": "^2.1.1",
|
|
62
|
-
"numerable": "^0.3.15",
|
|
63
|
-
"react-blockly": "^8.1.2",
|
|
64
|
-
"react-chartjs-2": "^5.3.0",
|
|
65
|
-
"react-number-format": "^5.4.5",
|
|
66
|
-
"react-simple-keyboard": "^3.8.120",
|
|
67
|
-
"react-transition-group": "^4.4.5",
|
|
68
|
-
"sass": "^1.92.1",
|
|
69
|
-
"socket.io-client": "^4.8.1",
|
|
70
|
-
"use-fit-text": "^2.4.0"
|
|
101
|
+
"./assets/*": {
|
|
102
|
+
"import": "./dist/assets/*",
|
|
103
|
+
"types": "./dist/assets/*.d.ts"
|
|
71
104
|
},
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
],
|
|
76
|
-
"engines": {
|
|
77
|
-
"node": ">=20.0.0"
|
|
105
|
+
"./hooks/*": {
|
|
106
|
+
"import": "./dist/hooks/*",
|
|
107
|
+
"types": "./dist/hooks/*.d.ts"
|
|
78
108
|
},
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"@types/react-dom": "^18.2.7",
|
|
83
|
-
"@types/react-transition-group": "^4.4.12",
|
|
84
|
-
"@vitejs/plugin-react": "^6.0.2",
|
|
85
|
-
"primereact": "^10.9.7",
|
|
86
|
-
"rimraf": "^6.0.1",
|
|
87
|
-
"terser": "^5.44.0",
|
|
88
|
-
"typedoc": "^0.28.12",
|
|
89
|
-
"typescript": "^5.9.2",
|
|
90
|
-
"vite": "^8.0.13"
|
|
109
|
+
"./themes/*": {
|
|
110
|
+
"import": "./dist/themes/*",
|
|
111
|
+
"types": "./dist/themes/*.d.ts"
|
|
91
112
|
},
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"types": "./dist/core/*.d.ts"
|
|
96
|
-
},
|
|
97
|
-
"./components/*": {
|
|
98
|
-
"import": "./dist/components/*",
|
|
99
|
-
"types": "./dist/components/*.d.ts"
|
|
100
|
-
},
|
|
101
|
-
"./assets/*": {
|
|
102
|
-
"import": "./dist/assets/*",
|
|
103
|
-
"types": "./dist/assets/*.d.ts"
|
|
104
|
-
},
|
|
105
|
-
"./hooks/*": {
|
|
106
|
-
"import": "./dist/hooks/*",
|
|
107
|
-
"types": "./dist/hooks/*.d.ts"
|
|
108
|
-
},
|
|
109
|
-
"./themes/*": {
|
|
110
|
-
"import": "./dist/themes/*",
|
|
111
|
-
"types": "./dist/themes/*.d.ts"
|
|
112
|
-
},
|
|
113
|
-
"./hub/*": {
|
|
114
|
-
"import": "./dist/hub/*",
|
|
115
|
-
"types": "./dist/hub/*.d.ts"
|
|
116
|
-
}
|
|
113
|
+
"./hub/*": {
|
|
114
|
+
"import": "./dist/hub/*",
|
|
115
|
+
"types": "./dist/hub/*.d.ts"
|
|
117
116
|
}
|
|
117
|
+
}
|
|
118
118
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export {
|
|
|
15
15
|
useTisSelection,
|
|
16
16
|
useTisRuns,
|
|
17
17
|
useTisRun,
|
|
18
|
+
useTisCycleConfig,
|
|
18
19
|
} from './tis/TisProvider';
|
|
19
20
|
export type {
|
|
20
21
|
TisProviderProps,
|
|
@@ -25,6 +26,7 @@ export type {
|
|
|
25
26
|
TisRunCacheEntry,
|
|
26
27
|
SchemaRegistry,
|
|
27
28
|
TisMethodSchema,
|
|
29
|
+
TisCycleConfigState,
|
|
28
30
|
} from './tis/TisProvider';
|
|
29
31
|
|
|
30
32
|
export { ProjectSelector } from './tis/ProjectSelector';
|
|
@@ -36,6 +38,18 @@ export type { TestSetupFormProps } from './tis/TestSetupForm';
|
|
|
36
38
|
export { TestSetupView } from './tis/TestSetupView';
|
|
37
39
|
export type { TestSetupViewProps } from './tis/TestSetupView';
|
|
38
40
|
|
|
41
|
+
export { TestFieldRow } from './tis/TestFieldRow';
|
|
42
|
+
export type { TestFieldRowProps, CycleConfigScope } from './tis/TestFieldRow';
|
|
43
|
+
|
|
44
|
+
export { CycleConfigForm, cycleConfigSummary } from './tis/CycleConfigForm';
|
|
45
|
+
export type { CycleConfigFormProps } from './tis/CycleConfigForm';
|
|
46
|
+
|
|
47
|
+
export { CycleConfigDialog, useCycleConfigGate } from './tis/CycleConfigDialog';
|
|
48
|
+
export type { CycleConfigDialogProps, CycleConfigGate } from './tis/CycleConfigDialog';
|
|
49
|
+
|
|
50
|
+
export { CycleStatusStrip } from './tis/CycleStatusStrip';
|
|
51
|
+
export type { CycleStatusStripProps } from './tis/CycleStatusStrip';
|
|
52
|
+
|
|
39
53
|
export { ProjectInfoDialog } from './tis/ProjectInfoDialog';
|
|
40
54
|
export type { ProjectInfoDialogProps, ProjectInfoMode } from './tis/ProjectInfoDialog';
|
|
41
55
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2026 Automated Design Corp. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* <CycleConfigDialog> — the `prompt_before_cycle` entry dialog.
|
|
5
|
+
*
|
|
6
|
+
* Some methods can't tolerate a mislabelled row: getting the position
|
|
7
|
+
* wrong means re-running the sample. Those declare
|
|
8
|
+
* `prompt_before_cycle: true`, and this dialog puts the entry in front of
|
|
9
|
+
* the operator at the boundary instead of trusting them to have filled
|
|
10
|
+
* the Cycle tab. It opens on the server-computed `prompt_due` edge — a
|
|
11
|
+
* boundary reached with nothing latched — so the scope rules stay in one
|
|
12
|
+
* place (the server) rather than being re-derived here.
|
|
13
|
+
*
|
|
14
|
+
* Two ways to use it:
|
|
15
|
+
*
|
|
16
|
+
* 1. Mounted plainly, it opens by itself whenever a prompt comes due:
|
|
17
|
+
*
|
|
18
|
+
* <CycleConfigDialog />
|
|
19
|
+
*
|
|
20
|
+
* 2. Driven from your Start handler, so the press itself opens it when
|
|
21
|
+
* the annotation is missing and runs the start when it isn't:
|
|
22
|
+
*
|
|
23
|
+
* const gate = useCycleConfigGate();
|
|
24
|
+
* <Button label="Start" onClick={() => gate.run(startTest)} />
|
|
25
|
+
* <CycleConfigDialog controller={gate} />
|
|
26
|
+
*
|
|
27
|
+
* The second form is the one to reach for on a machine whose Start lives
|
|
28
|
+
* in the footer: the press is never silently swallowed — it either starts
|
|
29
|
+
* the test or explains, in a dialog, exactly what is missing.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
33
|
+
import { Button } from 'primereact/button';
|
|
34
|
+
import { Dialog } from 'primereact/dialog';
|
|
35
|
+
import { useTis } from './TisProvider';
|
|
36
|
+
import { CycleConfigForm } from './CycleConfigForm';
|
|
37
|
+
import { labelOf } from './TestFieldRow';
|
|
38
|
+
|
|
39
|
+
/** Handle returned by [`useCycleConfigGate`]. */
|
|
40
|
+
export interface CycleConfigGate {
|
|
41
|
+
/** True while the dialog should be open. */
|
|
42
|
+
open: boolean;
|
|
43
|
+
setOpen: (open: boolean) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Gate an action on the annotation being complete. When the entry is
|
|
46
|
+
* ready, `action` runs immediately. When it isn't, the dialog opens
|
|
47
|
+
* instead and `action` is held until the operator completes the fields
|
|
48
|
+
* and confirms — so a Start press is deferred, never dropped.
|
|
49
|
+
*/
|
|
50
|
+
run: (action: () => void) => void;
|
|
51
|
+
/** Run the held action and close. Called by the dialog's confirm. */
|
|
52
|
+
confirm: () => void;
|
|
53
|
+
/** Drop the held action and close. */
|
|
54
|
+
cancel: () => void;
|
|
55
|
+
/** True when the gate is blocking (required fields empty). */
|
|
56
|
+
blocked: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wire a Start affordance to the Cycle Configuration gate.
|
|
61
|
+
*
|
|
62
|
+
* Deliberately does NOT return a `disabled` flag for Start. A greyed-out
|
|
63
|
+
* Start in the corner of a touchscreen reads as "the machine is broken"
|
|
64
|
+
* and the operator's next move is a phone call; a press that opens a
|
|
65
|
+
* dialog naming the missing field teaches the workflow in one go.
|
|
66
|
+
*/
|
|
67
|
+
export const useCycleConfigGate = (): CycleConfigGate => {
|
|
68
|
+
const tis = useTis();
|
|
69
|
+
const [open, setOpen] = useState(false);
|
|
70
|
+
// Held across the dialog's lifetime rather than kept in state: it is
|
|
71
|
+
// never rendered, and re-rendering on every Start press would reopen
|
|
72
|
+
// the question of whether the action is stale.
|
|
73
|
+
const held = useRef<(() => void) | null>(null);
|
|
74
|
+
const blocked = tis.cycleConfigFields.length > 0 && !tis.cycleConfig.ready;
|
|
75
|
+
|
|
76
|
+
const run = useCallback((action: () => void) => {
|
|
77
|
+
const needsEntry = tis.cycleConfigFields.length > 0
|
|
78
|
+
&& (!tis.cycleConfig.ready || tis.cycleConfig.promptDue);
|
|
79
|
+
if (!needsEntry) { action(); return; }
|
|
80
|
+
held.current = action;
|
|
81
|
+
setOpen(true);
|
|
82
|
+
}, [tis.cycleConfigFields.length, tis.cycleConfig.ready, tis.cycleConfig.promptDue]);
|
|
83
|
+
|
|
84
|
+
const confirm = useCallback(() => {
|
|
85
|
+
const action = held.current;
|
|
86
|
+
held.current = null;
|
|
87
|
+
setOpen(false);
|
|
88
|
+
action?.();
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
const cancel = useCallback(() => {
|
|
92
|
+
held.current = null;
|
|
93
|
+
setOpen(false);
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
return { open, setOpen, run, confirm, cancel, blocked };
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export interface CycleConfigDialogProps {
|
|
100
|
+
/** Gate handle from [`useCycleConfigGate`]. Omit to let the dialog
|
|
101
|
+
* open itself on the server's `prompt_due` edge. */
|
|
102
|
+
controller?: CycleConfigGate;
|
|
103
|
+
/** Label on the confirm button. Default "Continue". Set it to
|
|
104
|
+
* "Start" when the dialog is gating a Start press. */
|
|
105
|
+
confirmLabel?: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const CycleConfigDialog: React.FC<CycleConfigDialogProps> = ({
|
|
109
|
+
controller, confirmLabel = 'Continue',
|
|
110
|
+
}) => {
|
|
111
|
+
const tis = useTis();
|
|
112
|
+
const cfg = tis.cycleConfig;
|
|
113
|
+
const fields = tis.cycleConfigFields;
|
|
114
|
+
|
|
115
|
+
const [selfOpen, setSelfOpen] = useState(false);
|
|
116
|
+
const open = controller ? controller.open : selfOpen;
|
|
117
|
+
|
|
118
|
+
// Self-opening mode: follow the server's prompt_due edge. Rising edge
|
|
119
|
+
// only — an operator who dismisses the dialog isn't re-prompted until
|
|
120
|
+
// the next boundary, and the `tis.cycle_ready` gate still stops the
|
|
121
|
+
// machine in the meantime.
|
|
122
|
+
const prevPromptDue = useRef(false);
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (controller) return;
|
|
125
|
+
const due = cfg.promptBeforeCycle && cfg.promptDue && fields.length > 0;
|
|
126
|
+
if (due && !prevPromptDue.current) setSelfOpen(true);
|
|
127
|
+
prevPromptDue.current = due;
|
|
128
|
+
}, [controller, cfg.promptBeforeCycle, cfg.promptDue, fields.length]);
|
|
129
|
+
|
|
130
|
+
// With a controller, confirming releases the held action (the Start
|
|
131
|
+
// press that was deferred). Self-opening, there's nothing to release.
|
|
132
|
+
const confirm = () => (controller ? controller.confirm() : setSelfOpen(false));
|
|
133
|
+
const cancel = () => (controller ? controller.cancel() : setSelfOpen(false));
|
|
134
|
+
|
|
135
|
+
const missingLabels = cfg.missing
|
|
136
|
+
.map(n => fields.find(f => f.name === n))
|
|
137
|
+
.filter((f): f is NonNullable<typeof f> => !!f)
|
|
138
|
+
.map(labelOf);
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<Dialog
|
|
142
|
+
header="Cycle Configuration"
|
|
143
|
+
visible={open}
|
|
144
|
+
onHide={cancel}
|
|
145
|
+
style={{ width: '34rem', maxWidth: '95vw' }}
|
|
146
|
+
modal
|
|
147
|
+
footer={
|
|
148
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '1rem' }}>
|
|
149
|
+
<span style={{ color: 'var(--text-secondary-color)', textAlign: 'left' }}>
|
|
150
|
+
{cfg.ready
|
|
151
|
+
? 'Recorded on the next cycle.'
|
|
152
|
+
: `Still required: ${missingLabels.join(', ')}`}
|
|
153
|
+
</span>
|
|
154
|
+
<span>
|
|
155
|
+
<Button label="Cancel" text onClick={cancel} />
|
|
156
|
+
<Button
|
|
157
|
+
label={confirmLabel}
|
|
158
|
+
icon="pi pi-check"
|
|
159
|
+
// The only place a disabled control is right:
|
|
160
|
+
// this button *is* the start, and starting with
|
|
161
|
+
// the entry incomplete is what we're preventing.
|
|
162
|
+
// The reason is spelled out beside it.
|
|
163
|
+
disabled={!cfg.ready}
|
|
164
|
+
onClick={confirm}
|
|
165
|
+
/>
|
|
166
|
+
</span>
|
|
167
|
+
</div>
|
|
168
|
+
}
|
|
169
|
+
>
|
|
170
|
+
<CycleConfigForm compact />
|
|
171
|
+
</Dialog>
|
|
172
|
+
);
|
|
173
|
+
};
|