@adcops/autocore-react 3.3.23 → 3.3.25
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.
|
@@ -13,11 +13,12 @@ export interface TestDefinition {
|
|
|
13
13
|
results_fields: TestFieldDef[];
|
|
14
14
|
}
|
|
15
15
|
export interface TestSetupFormProps {
|
|
16
|
-
projectId: string;
|
|
17
|
-
definitionId: string;
|
|
18
16
|
schema: TestDefinition;
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
defaultProjectId?: string;
|
|
18
|
+
defaultDefinitionId?: string;
|
|
19
|
+
onProjectChange?: (projectId: string) => void;
|
|
20
|
+
onDefinitionChange?: (definitionId: string) => void;
|
|
21
|
+
onValidationChange?: (isValid: boolean, config: any) => void;
|
|
21
22
|
}
|
|
22
23
|
export declare const TestSetupForm: React.FC<TestSetupFormProps>;
|
|
23
24
|
//# sourceMappingURL=TestSetupForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../src/components/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../src/components/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAO/D,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,cAAc,EAAE,YAAY,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAChE;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAgKtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect}from"react";import{
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import{InputText}from"primereact/inputtext";import{AutoComplete}from"primereact/autocomplete";import{EventEmitterContext}from"../core/EventEmitterContext";import{MessageType}from"../hub/CommandMessage";export const TestSetupForm=({schema:e,defaultProjectId:s="",defaultDefinitionId:a="default",onProjectChange:t,onDefinitionChange:n,onValidationChange:r})=>{const[i,o]=useState({}),[c,p]=useState(s),[l,m]=useState(a);useEffect(()=>{t&&t(c)},[c,t]),useEffect(()=>{n&&n(l)},[l,n]);const[u,d]=useState([]),[f,x]=useState([]),[j,g]=useState(!1),{invoke:h}=useContext(EventEmitterContext);useEffect(()=>{(async()=>{try{const e=await h("results.list_projects",MessageType.Request,{});e.success&&e.data&&e.data.projects&&d(e.data.projects)}catch(e){}})()},[h]);useEffect(()=>{let s=!0;c&&""!==c.trim()||(s=!1),l&&""!==l.trim()||(s=!1);const a=[...e.project_fields,...e.config_fields];for(const e of a)if(e.required&&!e.source&&(void 0===i[e.name]||""===i[e.name])){s=!1;break}g(s),r&&r(s,i)},[i,e,c,l,r]);const _=e=>{if(e.source)return _jsxs("div",{className:"ac-form-span p-inputgroup",children:[_jsx("span",{className:"p-inputgroup-addon",children:e.name}),_jsx(InputText,{value:`Auto-fetched from ${e.source}`,disabled:!0}),e.units&&_jsx("span",{className:"p-inputgroup-addon",children:e.units}),_jsx("span",{className:"p-inputgroup-addon",style:{color:"var(--green-500)"},children:_jsx("i",{className:"pi pi-check"})})]},e.name);const s=(e=>!(e.required&&!e.source)||void 0!==i[e.name]&&""!==i[e.name])(e);return _jsxs("div",{className:"ac-form-span p-inputgroup",children:[_jsx("span",{className:"p-inputgroup-addon",children:e.name}),_jsx(InputText,{value:i[e.name]||"",onChange:s=>o({...i,[e.name]:s.target.value}),placeholder:`Enter ${e.name}`,className:s?"":"p-invalid"}),e.units&&_jsx("span",{className:"p-inputgroup-addon",children:e.units}),_jsx("span",{className:"p-inputgroup-addon",style:{color:s?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:s?"pi pi-check":"pi pi-times"})})]},e.name)};return _jsxs("div",{className:"ac-form-grid",style:{padding:"1.25rem"},children:[_jsxs("h3",{className:"ac-form-section",style:{display:"flex",alignItems:"center",gap:"10px"},children:["Project & Definition",_jsx("span",{style:{color:j?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:j?"pi pi-check-circle":"pi pi-exclamation-circle"})})]}),_jsxs("div",{className:"ac-form-span p-inputgroup",children:[_jsx("span",{className:"p-inputgroup-addon",children:"Project ID"}),_jsx(AutoComplete,{value:c,suggestions:f,completeMethod:e=>{const s=e.query.toLowerCase();x(u.filter(e=>e.toLowerCase().includes(s)))},onChange:e=>(e=>{const s=e.replace(/[^a-zA-Z0-9_]/g,"");p(s)})(e.value),dropdown:!0,placeholder:"Enter or select Project ID",className:c&&""!==c.trim()?"":"p-invalid"}),_jsx("span",{className:"p-inputgroup-addon",style:{color:c&&""!==c.trim()?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:c&&""!==c.trim()?"pi pi-check":"pi pi-times"})})]}),_jsxs("div",{className:"ac-form-span p-inputgroup",children:[_jsx("span",{className:"p-inputgroup-addon",children:"Definition ID"}),_jsx(InputText,{value:l,onChange:e=>(e=>{const s=e.replace(/[^a-zA-Z0-9_]/g,"");m(s)})(e.target.value),placeholder:"Enter Definition ID",className:l&&""!==l.trim()?"":"p-invalid"}),_jsx("span",{className:"p-inputgroup-addon",style:{color:l&&""!==l.trim()?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:l&&""!==l.trim()?"pi pi-check":"pi pi-times"})})]}),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Project Information"}),e.project_fields.map(_),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Test Configuration"}),e.config_fields.map(_)]})};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adcops/autocore-react",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.25",
|
|
4
4
|
"description": "A React component library for industrial user interfaces.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"homepage": "https://automateddesign.com",
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@types/react": "^18",
|
|
43
|
-
"primereact": ">=10.
|
|
43
|
+
"primereact": ">=10.9.7",
|
|
44
44
|
"react": "^18",
|
|
45
45
|
"react-dom": "^18"
|
|
46
46
|
},
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { Button } from 'primereact/button';
|
|
1
|
+
import React, { useState, useEffect, useContext } from 'react';
|
|
3
2
|
import { InputText } from 'primereact/inputtext';
|
|
3
|
+
import { AutoComplete } from 'primereact/autocomplete';
|
|
4
|
+
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
|
|
5
|
+
import { EventEmitterContext } from '../core/EventEmitterContext';
|
|
6
|
+
import { MessageType } from '../hub/CommandMessage';
|
|
4
7
|
|
|
5
8
|
export interface TestFieldDef {
|
|
6
9
|
name: string;
|
|
@@ -18,19 +21,75 @@ export interface TestDefinition {
|
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export interface TestSetupFormProps {
|
|
21
|
-
projectId: string;
|
|
22
|
-
definitionId: string;
|
|
23
24
|
schema: TestDefinition;
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
defaultProjectId?: string;
|
|
26
|
+
defaultDefinitionId?: string;
|
|
27
|
+
onProjectChange?: (projectId: string) => void;
|
|
28
|
+
onDefinitionChange?: (definitionId: string) => void;
|
|
29
|
+
onValidationChange?: (isValid: boolean, config: any) => void;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
32
|
+
export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
33
|
+
schema,
|
|
34
|
+
defaultProjectId = "",
|
|
35
|
+
defaultDefinitionId = "default",
|
|
36
|
+
onProjectChange,
|
|
37
|
+
onDefinitionChange,
|
|
38
|
+
onValidationChange
|
|
39
|
+
}) => {
|
|
29
40
|
const [config, setConfig] = useState<any>({});
|
|
41
|
+
const [projectId, setProjectId] = useState<string>(defaultProjectId);
|
|
42
|
+
const [definitionId, setDefinitionId] = useState<string>(defaultDefinitionId);
|
|
43
|
+
|
|
44
|
+
// Notify parent when projectId or definitionId changes
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (onProjectChange) onProjectChange(projectId);
|
|
47
|
+
}, [projectId, onProjectChange]);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (onDefinitionChange) onDefinitionChange(definitionId);
|
|
51
|
+
}, [definitionId, onDefinitionChange]);
|
|
52
|
+
|
|
53
|
+
const [existingProjects, setExistingProjects] = useState<string[]>([]);
|
|
54
|
+
const [filteredProjects, setFilteredProjects] = useState<string[]>([]);
|
|
55
|
+
|
|
30
56
|
const [isValid, setIsValid] = useState(false);
|
|
57
|
+
const { invoke } = useContext(EventEmitterContext);
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const fetchProjects = async () => {
|
|
61
|
+
try {
|
|
62
|
+
const resp: any = await invoke('results.list_projects' as any, MessageType.Request as any, {} as any);
|
|
63
|
+
if (resp.success && resp.data && resp.data.projects) {
|
|
64
|
+
setExistingProjects(resp.data.projects);
|
|
65
|
+
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error("Failed to list projects", err);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
fetchProjects();
|
|
71
|
+
}, [invoke]);
|
|
72
|
+
|
|
73
|
+
const searchProjects = (event: AutoCompleteCompleteEvent) => {
|
|
74
|
+
const query = event.query.toLowerCase();
|
|
75
|
+
setFilteredProjects(existingProjects.filter(p => p.toLowerCase().includes(query)));
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const handleProjectIdChange = (value: string) => {
|
|
79
|
+
const sanitized = value.replace(/[^a-zA-Z0-9_]/g, '');
|
|
80
|
+
setProjectId(sanitized);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const handleDefinitionIdChange = (value: string) => {
|
|
84
|
+
const sanitized = value.replace(/[^a-zA-Z0-9_]/g, '');
|
|
85
|
+
setDefinitionId(sanitized);
|
|
86
|
+
};
|
|
31
87
|
|
|
32
88
|
useEffect(() => {
|
|
33
89
|
let valid = true;
|
|
90
|
+
if (!projectId || projectId.trim() === '') valid = false;
|
|
91
|
+
if (!definitionId || definitionId.trim() === '') valid = false;
|
|
92
|
+
|
|
34
93
|
const allFields = [...schema.project_fields, ...schema.config_fields];
|
|
35
94
|
|
|
36
95
|
for (const field of allFields) {
|
|
@@ -42,7 +101,15 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({ schema, onStartTes
|
|
|
42
101
|
}
|
|
43
102
|
}
|
|
44
103
|
setIsValid(valid);
|
|
45
|
-
|
|
104
|
+
if (onValidationChange) {
|
|
105
|
+
onValidationChange(valid, config);
|
|
106
|
+
}
|
|
107
|
+
}, [config, schema, projectId, definitionId, onValidationChange]);
|
|
108
|
+
|
|
109
|
+
const isFieldValid = (field: TestFieldDef) => {
|
|
110
|
+
if (!field.required || field.source) return true;
|
|
111
|
+
return config[field.name] !== undefined && config[field.name] !== '';
|
|
112
|
+
};
|
|
46
113
|
|
|
47
114
|
const renderField = (field: TestFieldDef) => {
|
|
48
115
|
if (field.source) {
|
|
@@ -51,48 +118,75 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({ schema, onStartTes
|
|
|
51
118
|
<span className="p-inputgroup-addon">{field.name}</span>
|
|
52
119
|
<InputText value={`Auto-fetched from ${field.source}`} disabled />
|
|
53
120
|
{field.units && <span className="p-inputgroup-addon">{field.units}</span>}
|
|
121
|
+
<span className="p-inputgroup-addon" style={{ color: 'var(--green-500)' }}>
|
|
122
|
+
<i className="pi pi-check"></i>
|
|
123
|
+
</span>
|
|
54
124
|
</div>
|
|
55
125
|
);
|
|
56
126
|
}
|
|
57
127
|
|
|
128
|
+
const valid = isFieldValid(field);
|
|
129
|
+
|
|
58
130
|
return (
|
|
59
131
|
<div key={field.name} className="ac-form-span p-inputgroup">
|
|
60
|
-
<span className="p-inputgroup-addon">{field.name}
|
|
132
|
+
<span className="p-inputgroup-addon">{field.name}</span>
|
|
61
133
|
<InputText
|
|
62
134
|
value={config[field.name] || ''}
|
|
63
135
|
onChange={(e) => setConfig({...config, [field.name]: e.target.value})}
|
|
64
136
|
placeholder={`Enter ${field.name}`}
|
|
137
|
+
className={!valid ? 'p-invalid' : ''}
|
|
65
138
|
/>
|
|
66
139
|
{field.units && <span className="p-inputgroup-addon">{field.units}</span>}
|
|
140
|
+
<span className="p-inputgroup-addon" style={{ color: valid ? 'var(--green-500)' : 'var(--red-500)' }}>
|
|
141
|
+
<i className={valid ? "pi pi-check" : "pi pi-times"}></i>
|
|
142
|
+
</span>
|
|
67
143
|
</div>
|
|
68
144
|
);
|
|
69
145
|
};
|
|
70
146
|
|
|
71
147
|
return (
|
|
72
148
|
<div className="ac-form-grid" style={{ padding: '1.25rem' }}>
|
|
73
|
-
<h3 className="ac-form-section"
|
|
149
|
+
<h3 className="ac-form-section" style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
|
150
|
+
Project & Definition
|
|
151
|
+
<span style={{ color: isValid ? 'var(--green-500)' : 'var(--red-500)' }}>
|
|
152
|
+
<i className={isValid ? "pi pi-check-circle" : "pi pi-exclamation-circle"}></i>
|
|
153
|
+
</span>
|
|
154
|
+
</h3>
|
|
155
|
+
|
|
156
|
+
<div className="ac-form-span p-inputgroup">
|
|
157
|
+
<span className="p-inputgroup-addon">Project ID</span>
|
|
158
|
+
<AutoComplete
|
|
159
|
+
value={projectId}
|
|
160
|
+
suggestions={filteredProjects}
|
|
161
|
+
completeMethod={searchProjects}
|
|
162
|
+
onChange={(e) => handleProjectIdChange(e.value)}
|
|
163
|
+
dropdown
|
|
164
|
+
placeholder="Enter or select Project ID"
|
|
165
|
+
className={!projectId || projectId.trim() === '' ? 'p-invalid' : ''}
|
|
166
|
+
/>
|
|
167
|
+
<span className="p-inputgroup-addon" style={{ color: projectId && projectId.trim() !== '' ? 'var(--green-500)' : 'var(--red-500)' }}>
|
|
168
|
+
<i className={projectId && projectId.trim() !== '' ? "pi pi-check" : "pi pi-times"}></i>
|
|
169
|
+
</span>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<div className="ac-form-span p-inputgroup">
|
|
173
|
+
<span className="p-inputgroup-addon">Definition ID</span>
|
|
174
|
+
<InputText
|
|
175
|
+
value={definitionId}
|
|
176
|
+
onChange={(e) => handleDefinitionIdChange(e.target.value)}
|
|
177
|
+
placeholder="Enter Definition ID"
|
|
178
|
+
className={!definitionId || definitionId.trim() === '' ? 'p-invalid' : ''}
|
|
179
|
+
/>
|
|
180
|
+
<span className="p-inputgroup-addon" style={{ color: definitionId && definitionId.trim() !== '' ? 'var(--green-500)' : 'var(--red-500)' }}>
|
|
181
|
+
<i className={definitionId && definitionId.trim() !== '' ? "pi pi-check" : "pi pi-times"}></i>
|
|
182
|
+
</span>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<h3 className="ac-form-section" style={{ marginTop: '1rem' }}>Project Information</h3>
|
|
74
186
|
{schema.project_fields.map(renderField)}
|
|
75
187
|
|
|
76
188
|
<h3 className="ac-form-section" style={{ marginTop: '1rem' }}>Test Configuration</h3>
|
|
77
189
|
{schema.config_fields.map(renderField)}
|
|
78
|
-
|
|
79
|
-
<div className="ac-form-wide" style={{ display: 'flex', gap: '1rem', marginTop: '2rem' }}>
|
|
80
|
-
<Button
|
|
81
|
-
label="Start Test"
|
|
82
|
-
icon="pi pi-play"
|
|
83
|
-
severity="success"
|
|
84
|
-
disabled={!isValid}
|
|
85
|
-
onClick={() => onStartTest(config)}
|
|
86
|
-
/>
|
|
87
|
-
{onCancel && (
|
|
88
|
-
<Button
|
|
89
|
-
label="Cancel"
|
|
90
|
-
icon="pi pi-times"
|
|
91
|
-
severity="secondary"
|
|
92
|
-
onClick={onCancel}
|
|
93
|
-
/>
|
|
94
|
-
)}
|
|
95
|
-
</div>
|
|
96
190
|
</div>
|
|
97
191
|
);
|
|
98
192
|
};
|