@adcops/autocore-react 3.3.40 → 3.3.42
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../src/components/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../src/components/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAS/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,CA4MtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import{
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import{AutoComplete}from"primereact/autocomplete";import{EventEmitterContext}from"../core/EventEmitterContext";import{MessageType}from"../hub/CommandMessage";import{ValueInput}from"./ValueInput";import{TextInput}from"./TextInput";import{InputText}from"primereact/inputtext";export const TestSetupForm=({schema:e,defaultProjectId:t="",defaultDefinitionId:s="default",onProjectChange:a,onDefinitionChange:n,onValidationChange:i})=>{const[r,o]=useState({}),[c,l]=useState(t),[m,p]=useState(s);useEffect(()=>{a&&a(c)},[c,a]),useEffect(()=>{n&&n(m)},[m,n]);const[u,f]=useState([]),[d,x]=useState([]),[j,g]=useState(!1),{invoke:h,write:_,subscribe:v,unsubscribe:y}=useContext(EventEmitterContext);useEffect(()=>{if(!e)return;const t=[...e.project_fields,...e.config_fields],s=[];for(const e of t)if(e.source){const t=v(e.source,t=>{o(s=>s[e.name]!==t?{...s,[e.name]:t}:s)});s.push(t)}return()=>{for(const e of s)y(e)}},[e,v,y]),useEffect(()=>{(async()=>{try{const e=await h("results.list_projects",MessageType.Request,{});e.success&&e.data&&e.data.projects&&f(e.data.projects)}catch(e){}})()},[h]);useEffect(()=>{if(!e)return;let t=!0;c&&""!==c.trim()||(t=!1),m&&""!==m.trim()||(t=!1);const s=[...e.project_fields,...e.config_fields];for(const e of s)if(e.required&&(void 0===r[e.name]||""===r[e.name]||null===r[e.name])){t=!1;break}g(t),i&&i(t,r)},[r,e,c,m,i]);const I=async(e,t)=>{if(o({...r,[e.name]:t}),e.source)try{await _(e.source,t)}catch(e){}},N=e=>{const t=(e=>!e.required||void 0!==r[e.name]&&""!==r[e.name]&&null!==r[e.name])(e),s="string"!==e.type&&"bool"!==e.type;return _jsxs(React.Fragment,{children:[_jsx("span",{className:"ac-form-label",children:e.name}),s?_jsx(ValueInput,{label:void 0,value:null!=r[e.name]?Number(r[e.name]):null,suffix:e.units?` ${e.units}`:void 0,onValueChanged:t=>I(e,t),className:t?"":"p-invalid"}):_jsx(TextInput,{label:void 0,value:null!=r[e.name]?String(r[e.name]):"",suffix:e.units?` ${e.units}`:void 0,onValueChanged:t=>I(e,t),className:t?"":"p-invalid"}),_jsx("span",{style:{color:t?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:t?"pi pi-check":"pi pi-times"})})]},e.name)};return e?_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"})})]}),_jsx("span",{className:"ac-form-label",children:"Project ID"}),_jsx(AutoComplete,{value:c,suggestions:d,completeMethod:e=>{const t=e.query.toLowerCase();x(u.filter(e=>e.toLowerCase().includes(t)))},onChange:e=>(e=>{const t=(e||"").replace(/[^a-zA-Z0-9_]/g,"");l(t)})(e.value),dropdown:!0,placeholder:"Enter or select Project ID",className:c&&""!==c.trim()?"":"p-invalid"}),_jsx("span",{style:{color:c&&""!==c.trim()?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:c&&""!==c.trim()?"pi pi-check":"pi pi-times"})}),_jsx("span",{className:"ac-form-label",children:"Definition ID"}),_jsx(InputText,{value:m,onChange:e=>(e=>{const t=e.replace(/[^a-zA-Z0-9_]/g,"");p(t)})(e.target.value),placeholder:"Enter Definition ID",className:m&&""!==m.trim()?"":"p-invalid"}),_jsx("span",{style:{color:m&&""!==m.trim()?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:m&&""!==m.trim()?"pi pi-check":"pi pi-times"})}),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Project Information"}),e.project_fields.map(N),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Test Configuration"}),e.config_fields.map(N)]}):_jsx("div",{className:"ac-form-grid",style:{padding:"1.25rem"},children:_jsx("h3",{className:"ac-form-section",children:"No Test Definition Selected"})})};
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, { useState, useEffect, useContext } from 'react';
|
|
2
|
-
import { InputText } from 'primereact/inputtext';
|
|
3
2
|
import { AutoComplete } from 'primereact/autocomplete';
|
|
4
3
|
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
|
|
5
4
|
import { EventEmitterContext } from '../core/EventEmitterContext';
|
|
6
5
|
import { MessageType } from '../hub/CommandMessage';
|
|
6
|
+
import { ValueInput } from './ValueInput';
|
|
7
|
+
import { TextInput } from './TextInput';
|
|
8
|
+
import { InputText } from 'primereact/inputtext';
|
|
7
9
|
|
|
8
10
|
export interface TestFieldDef {
|
|
9
11
|
name: string;
|
|
@@ -54,7 +56,36 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
54
56
|
const [filteredProjects, setFilteredProjects] = useState<string[]>([]);
|
|
55
57
|
|
|
56
58
|
const [isValid, setIsValid] = useState(false);
|
|
57
|
-
const { invoke } = useContext(EventEmitterContext);
|
|
59
|
+
const { invoke, write, subscribe, unsubscribe } = useContext(EventEmitterContext);
|
|
60
|
+
|
|
61
|
+
// Subscribe to external tags if a field defines a source
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!schema) return;
|
|
64
|
+
|
|
65
|
+
const allFields = [...schema.project_fields, ...schema.config_fields];
|
|
66
|
+
const subs: any[] = [];
|
|
67
|
+
|
|
68
|
+
for (const field of allFields) {
|
|
69
|
+
if (field.source) {
|
|
70
|
+
const subId = subscribe(field.source, (newVal: any) => {
|
|
71
|
+
setConfig((prev: any) => {
|
|
72
|
+
// Only update if it actually changed to prevent infinite loops
|
|
73
|
+
if (prev[field.name] !== newVal) {
|
|
74
|
+
return { ...prev, [field.name]: newVal };
|
|
75
|
+
}
|
|
76
|
+
return prev;
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
subs.push(subId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return () => {
|
|
84
|
+
for (const subId of subs) {
|
|
85
|
+
unsubscribe(subId);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}, [schema, subscribe, unsubscribe]);
|
|
58
89
|
|
|
59
90
|
useEffect(() => {
|
|
60
91
|
const fetchProjects = async () => {
|
|
@@ -89,8 +120,8 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
89
120
|
const allFields = [...schema.project_fields, ...schema.config_fields];
|
|
90
121
|
|
|
91
122
|
for (const field of allFields) {
|
|
92
|
-
if (field.required
|
|
93
|
-
if (config[field.name] === undefined || config[field.name] === '') {
|
|
123
|
+
if (field.required) {
|
|
124
|
+
if (config[field.name] === undefined || config[field.name] === '' || config[field.name] === null) {
|
|
94
125
|
valid = false;
|
|
95
126
|
break;
|
|
96
127
|
}
|
|
@@ -103,8 +134,8 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
103
134
|
}, [config, schema, projectId, definitionId, onValidationChange]);
|
|
104
135
|
|
|
105
136
|
const isFieldValid = (field: TestFieldDef) => {
|
|
106
|
-
if (!field.required
|
|
107
|
-
return config[field.name] !== undefined && config[field.name] !== '';
|
|
137
|
+
if (!field.required) return true;
|
|
138
|
+
return config[field.name] !== undefined && config[field.name] !== '' && config[field.name] !== null;
|
|
108
139
|
};
|
|
109
140
|
|
|
110
141
|
const handleProjectIdChange = (value: string | null | undefined) => {
|
|
@@ -113,36 +144,45 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
113
144
|
setProjectId(sanitized);
|
|
114
145
|
};
|
|
115
146
|
|
|
116
|
-
const
|
|
147
|
+
const handleFieldChange = async (field: TestFieldDef, val: any) => {
|
|
148
|
+
setConfig({...config, [field.name]: val});
|
|
117
149
|
if (field.source) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<span className="p-inputgroup-addon" style={{ color: 'var(--green-500)' }}>
|
|
124
|
-
<i className="pi pi-check"></i>
|
|
125
|
-
</span>
|
|
126
|
-
</div>
|
|
127
|
-
);
|
|
150
|
+
try {
|
|
151
|
+
await write(field.source, val);
|
|
152
|
+
} catch(e) {
|
|
153
|
+
console.error("Failed to write to source:", e);
|
|
154
|
+
}
|
|
128
155
|
}
|
|
156
|
+
};
|
|
129
157
|
|
|
158
|
+
const renderField = (field: TestFieldDef) => {
|
|
130
159
|
const valid = isFieldValid(field);
|
|
160
|
+
const isNum = field.type !== 'string' && field.type !== 'bool';
|
|
131
161
|
|
|
132
162
|
return (
|
|
133
|
-
<
|
|
134
|
-
<span className="
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
163
|
+
<React.Fragment key={field.name}>
|
|
164
|
+
<span className="ac-form-label">{field.name}</span>
|
|
165
|
+
{isNum ? (
|
|
166
|
+
<ValueInput
|
|
167
|
+
label={undefined}
|
|
168
|
+
value={config[field.name] != null ? Number(config[field.name]) : null}
|
|
169
|
+
suffix={field.units ? ` ${field.units}` : undefined}
|
|
170
|
+
onValueChanged={(val) => handleFieldChange(field, val)}
|
|
171
|
+
className={!valid ? 'p-invalid' : ''}
|
|
172
|
+
/>
|
|
173
|
+
) : (
|
|
174
|
+
<TextInput
|
|
175
|
+
label={undefined}
|
|
176
|
+
value={config[field.name] != null ? String(config[field.name]) : ''}
|
|
177
|
+
suffix={field.units ? ` ${field.units}` : undefined}
|
|
178
|
+
onValueChanged={(val) => handleFieldChange(field, val)}
|
|
179
|
+
className={!valid ? 'p-invalid' : ''}
|
|
180
|
+
/>
|
|
181
|
+
)}
|
|
182
|
+
<span style={{ color: valid ? 'var(--green-500)' : 'var(--red-500)', display: 'flex', alignItems: 'center' }}>
|
|
143
183
|
<i className={valid ? "pi pi-check" : "pi pi-times"}></i>
|
|
144
184
|
</span>
|
|
145
|
-
</
|
|
185
|
+
</React.Fragment>
|
|
146
186
|
);
|
|
147
187
|
};
|
|
148
188
|
|
|
@@ -163,34 +203,30 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
163
203
|
</span>
|
|
164
204
|
</h3>
|
|
165
205
|
|
|
166
|
-
<
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<
|
|
178
|
-
|
|
179
|
-
</span>
|
|
180
|
-
</div>
|
|
206
|
+
<span className="ac-form-label">Project ID</span>
|
|
207
|
+
<AutoComplete
|
|
208
|
+
value={projectId}
|
|
209
|
+
suggestions={filteredProjects}
|
|
210
|
+
completeMethod={searchProjects}
|
|
211
|
+
onChange={(e) => handleProjectIdChange(e.value)}
|
|
212
|
+
dropdown
|
|
213
|
+
placeholder="Enter or select Project ID"
|
|
214
|
+
className={!projectId || projectId.trim() === '' ? 'p-invalid' : ''}
|
|
215
|
+
/>
|
|
216
|
+
<span style={{ color: projectId && projectId.trim() !== '' ? 'var(--green-500)' : 'var(--red-500)', display: 'flex', alignItems: 'center' }}>
|
|
217
|
+
<i className={projectId && projectId.trim() !== '' ? "pi pi-check" : "pi pi-times"}></i>
|
|
218
|
+
</span>
|
|
181
219
|
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
</span>
|
|
193
|
-
</div>
|
|
220
|
+
<span className="ac-form-label">Definition ID</span>
|
|
221
|
+
<InputText
|
|
222
|
+
value={definitionId}
|
|
223
|
+
onChange={(e) => handleDefinitionIdChange(e.target.value)}
|
|
224
|
+
placeholder="Enter Definition ID"
|
|
225
|
+
className={!definitionId || definitionId.trim() === '' ? 'p-invalid' : ''}
|
|
226
|
+
/>
|
|
227
|
+
<span style={{ color: definitionId && definitionId.trim() !== '' ? 'var(--green-500)' : 'var(--red-500)', display: 'flex', alignItems: 'center' }}>
|
|
228
|
+
<i className={definitionId && definitionId.trim() !== '' ? "pi pi-check" : "pi pi-times"}></i>
|
|
229
|
+
</span>
|
|
194
230
|
|
|
195
231
|
<h3 className="ac-form-section" style={{ marginTop: '1rem' }}>Project Information</h3>
|
|
196
232
|
{schema.project_fields.map(renderField)}
|