@adcops/autocore-react 3.3.42 → 3.3.44
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/TestSetupForm.d.ts.map +1 -1
- package/dist/components/TestSetupForm.js +1 -1
- package/dist/components/TextInput.d.ts.map +1 -1
- package/dist/components/TextInput.js +1 -1
- package/dist/components/ValueInput.js +1 -1
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
- package/dist/core/AutoCoreTagContext.js +1 -1
- package/dist/core/AutoCoreTagTypes.d.ts +9 -0
- package/dist/core/AutoCoreTagTypes.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/TestSetupForm.tsx +57 -13
- package/src/components/TextInput.tsx +9 -3
- package/src/components/ValueInput.tsx +4 -4
- package/src/core/AutoCoreTagContext.tsx +20 -1
- package/src/core/AutoCoreTagTypes.ts +10 -0
|
@@ -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;AAU/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,CAuPtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
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:
|
|
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{AutoCoreTagContext}from"../core/AutoCoreTagContext";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:a="default",onProjectChange:s,onDefinitionChange:n,onValidationChange:r})=>{const[i,o]=useState({}),[c,l]=useState(t),[m,p]=useState(a);useEffect(()=>{s&&s(c)},[c,s]),useEffect(()=>{n&&n(m)},[m,n]);const[u,d]=useState([]),[f,x]=useState([]),[g,j]=useState(!1),{invoke:h,write:_,subscribe:v,unsubscribe:y}=useContext(EventEmitterContext),{findTagByFqdn:C}=useContext(AutoCoreTagContext);useEffect(()=>{if(!e)return;const t=[...e.project_fields,...e.config_fields],a=[];for(const e of t){if(!e.source)continue;const t=e.source,s=e.name,n=C(t);if(n){const e=v(n.tagName,e=>{o(t=>t[s]!==e?{...t,[s]:e}:t)});a.push(e)}else;(async()=>{try{const e=await h(t,MessageType.Read,{}),a=void 0!==e?.data?e.data:e;null!=a&&o(e=>void 0===e[s]||null===e[s]||""===e[s]?{...e,[s]:a}:e)}catch(e){}})()}return()=>{for(const e of a)y(e)}},[e,v,y,h,C]),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(()=>{if(!e)return;let t=!0;c&&""!==c.trim()||(t=!1),m&&""!==m.trim()||(t=!1);const a=[...e.project_fields,...e.config_fields];for(const e of a)if(e.required&&(void 0===i[e.name]||""===i[e.name]||null===i[e.name])){t=!1;break}j(t),r&&r(t,i)},[i,e,c,m,r]);const N=async(e,t)=>{if(o({...i,[e.name]:t}),e.source)try{await _(e.source,t)}catch(e){}},I=e=>{const t=(e=>!e.required||void 0!==i[e.name]&&""!==i[e.name]&&null!==i[e.name])(e),a="string"!==e.type&&"bool"!==e.type;return _jsxs(React.Fragment,{children:[_jsx("span",{className:"ac-form-label",children:e.name}),a?_jsx(ValueInput,{label:void 0,value:null!=i[e.name]?Number(i[e.name]):null,onValueChanged:t=>N(e,t),className:t?"":"p-invalid"}):_jsx(TextInput,{label:void 0,value:null!=i[e.name]?String(i[e.name]):"",onValueChanged:t=>N(e,t),className:t?"":"p-invalid"}),_jsx("span",{children:e.units?` ${e.units}`:void 0}),_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:g?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:g?"pi pi-check-circle":"pi pi-exclamation-circle"})})]}),_jsx("span",{className:"ac-form-label",children:"Project ID"}),_jsx(AutoComplete,{value:c,suggestions:f,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(I),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Test Configuration"}),e.config_fields.map(I)]}):_jsx("div",{className:"ac-form-grid",style:{padding:"1.25rem"},children:_jsx("h3",{className:"ac-form-section",children:"No Test Definition Selected"})})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../src/components/TextInput.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,UAAU,cAAe,SAAQ,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IAClF,mDAAmD;IACnD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6DAA6D;IAC7D,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../src/components/TextInput.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,UAAU,cAAe,SAAQ,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IAClF,mDAAmD;IACnD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6DAA6D;IAC7D,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CA2G9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useEffect,useMemo,useState}from"react";import{InputText}from"primereact/inputtext";import{Button}from"primereact/button";function toStr(e){return e??""}export const TextInput=e=>{const{label:t,value:s,keyfilter:n,prefix:a,suffix:i,description:o,disabled:r=!1,placeholder:c,onValueChanged:
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useEffect,useMemo,useState}from"react";import{InputText}from"primereact/inputtext";import{Button}from"primereact/button";function toStr(e){return e??""}export const TextInput=e=>{const{label:t,value:s,keyfilter:n,prefix:a,suffix:i,description:o,disabled:r=!1,placeholder:c,onValueChanged:l,validator:u,...p}=e,[d,m]=useState(toStr(s)),[x,f]=useState(!1),[j,v]=useState(!s||h(s,u));function h(e,t){return!t||t.test(e)}function _(){const e=d,t=h(e,u);v(t),t&&(f(!1),l?.(e))}function b(){const e=toStr(s);m(e),f(!1),v(!e||h(e,u))}useEffect(()=>{m(toStr(s)),f(!1),v(!s||h(s,u))},[s,u]);const N=useMemo(()=>toStr(d),[d]);return _jsxs("div",{children:[_jsxs("div",{className:"p-inputgroup",children:[null!=t&&""!==t&&_jsx("span",{className:"p-inputgroup-addon",children:t}),void 0!==a&&_jsx("span",{className:"p-inputgroup-addon",children:a}),_jsx(InputText,{...p,keyfilter:n,placeholder:c,value:N,onChange:e=>{m(e.target.value),f(!0)},className:j?p.className??"":`${p.className??""} p-invalid`,onKeyDown:e=>{"Enter"===e.key?_():"Escape"===e.key&&b()},disabled:r}),void 0!==i&&_jsx("span",{className:"p-inputgroup-addon",children:i}),_jsx(Button,{icon:"pi pi-check",disabled:r||!x,className:"p-button-success",onClick:_,visible:!0}),_jsx(Button,{icon:"pi pi-times",disabled:r||!x,className:"p-button-danger",onClick:b,visible:!0})]}),void 0!==o&&_jsx("small",{children:o})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useRef,useEffect,useContext}from"react";import clsx from"clsx";import{InputNumber}from"primereact/inputnumber";import{EventEmitterContext}from"../core/EventEmitterContext";import{Button}from"primereact/button";import"./ValueInput.css";export const ValueInput=({label:e
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useRef,useEffect,useContext}from"react";import clsx from"clsx";import{InputNumber}from"primereact/inputnumber";import{EventEmitterContext}from"../core/EventEmitterContext";import{Button}from"primereact/button";import"./ValueInput.css";export const ValueInput=({label:e,value:t=null,min:s,max:i,minPrecision:n=0,maxPrecision:a=3,mode:o="decimal",currency:u="USD",prefix:l,suffix:r,showButtons:c=!1,step:p=1,locale:m="en-US",description:d,disabled:x=!1,dispatchTopic:f,placeholder:v,onValueChanged:b,size:h="normal",...j})=>{const[C,E]=useState(t),[_,N]=useState(t),[S,g]=useState(t),[y,k]=useState(!1),[B,I]=useState(!1),D=useRef(null),F=useContext(EventEmitterContext);useEffect(()=>{null!==S?(N(S),g(null),I(!1)):t!==_&&(N(t),E(t),k(!1),I(!1))},[t,_]);const V=()=>{var e;y&&null!==C&&(e=C,void 0!==i&&e>i||void 0!==s&&e<s?I(!0):(N(C),k(!1),b?.(C),I(!1),f&&F.dispatch({topic:f,payload:C})))},w=()=>{y&&(E(null),N(null),k(!1),I(!1))};return _jsxs("div",{children:[_jsxs("div",{className:"p-inputgroup",children:[null!=e&&""!==e&&_jsx("span",{className:"p-inputgroup-addon",children:e}),_jsx(InputNumber,{...j,ref:D,className:clsx("value-input-field",`size-${h}`,j.className),invalid:B,min:s,max:i,minFractionDigits:n,maxFractionDigits:a,mode:o,prefix:l,suffix:r,showButtons:c,step:p,placeholder:v,value:_,onChange:e=>{return t=e.value,y||(g(_),k(!0)),void E(t);var t},locale:m,currency:u,onKeyDown:e=>{"Enter"===e.key?V():"Escape"===e.key&&w()},disabled:x}),_jsx(Button,{icon:"pi pi-check",disabled:x||!y,className:"p-button-success",onClick:()=>V(),visible:!0,autoFocus:!1}),_jsx(Button,{icon:"pi pi-times",disabled:x||!y,className:"p-button-danger",onClickCapture:()=>w(),visible:!0,autoFocus:!1})]}),d&&_jsx("small",{children:d})]})};export default ValueInput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoCoreTagContext.d.ts","sourceRoot":"","sources":["../../src/core/AutoCoreTagContext.tsx"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,EAQV,KAAK,SAAS,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EACd,MAAM,oBAAoB,CAAC;AAI5B;;;GAGG;AACH,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"AutoCoreTagContext.d.ts","sourceRoot":"","sources":["../../src/core/AutoCoreTagContext.tsx"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,EAQV,KAAK,SAAS,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EACd,MAAM,oBAAoB,CAAC;AAI5B;;;GAGG;AACH,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB,8CAW7B,CAAC;AAsBH;;;;GAIG;AAIH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,CAygBA,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx}from"react/jsx-runtime";import React,{useRef,createContext,useCallback,useContext,useEffect,useMemo,useState}from"react";import{EventEmitterContext}from"./EventEmitterContext";import{MessageType}from"../hub/CommandMessage";export const AutoCoreTagContext=createContext({values:{},rawValues:{},isLoading:!0,write:async()=>{},tap:async()=>{},press:async()=>{},release:async()=>{},scales:{},updateScale:async()=>{}});const sleep=e=>new Promise(t=>setTimeout(t,e));export const AutoCoreTagProvider=({children:e,tags:t,scales:a,eagerRead:s=!0})=>{const n=useRef(!1),c=useMemo(()=>({}),[]),r=a??c,{invoke:o,read:l,write:u,serverSubscribe:i,isConnected:f,subscribe:m,unsubscribe:y}=useContext(EventEmitterContext),[b,d]=useState(()=>{const e={};for(const a of t)void 0!==a.initialValue&&(e[a.tagName]=a.initialValue);return e}),[g,p]=useState({}),[v,C]=useState(r),N=useRef(v),h=useRef(b);useEffect(()=>{N.current=v},[v]),useEffect(()=>{h.current=b},[b]);const[T,w]=useState(!0),x=useCallback((e,t)=>{const{valueType:a,scale:s,codec:n}=e;if("number"===a&&"number"==typeof t&&s){const e=N.current[s];return t*(e?.scale??1)}if("json"===a&&n?.fromServer)try{return n.fromServer(t)}catch{}return t},[]),
|
|
1
|
+
import{jsx as _jsx}from"react/jsx-runtime";import React,{useRef,createContext,useCallback,useContext,useEffect,useMemo,useState}from"react";import{EventEmitterContext}from"./EventEmitterContext";import{MessageType}from"../hub/CommandMessage";export const AutoCoreTagContext=createContext({values:{},rawValues:{},isLoading:!0,write:async()=>{},tap:async()=>{},press:async()=>{},release:async()=>{},scales:{},updateScale:async()=>{},findTagByFqdn:()=>{}});const sleep=e=>new Promise(t=>setTimeout(t,e));export const AutoCoreTagProvider=({children:e,tags:t,scales:a,eagerRead:s=!0})=>{const n=useRef(!1),c=useMemo(()=>({}),[]),r=a??c,{invoke:o,read:l,write:u,serverSubscribe:i,isConnected:f,subscribe:m,unsubscribe:y}=useContext(EventEmitterContext),[b,d]=useState(()=>{const e={};for(const a of t)void 0!==a.initialValue&&(e[a.tagName]=a.initialValue);return e}),[g,p]=useState({}),[v,C]=useState(r),N=useRef(v),h=useRef(b);useEffect(()=>{N.current=v},[v]),useEffect(()=>{h.current=b},[b]);const[T,w]=useState(!0),x=useCallback((e,t)=>{const{valueType:a,scale:s,codec:n}=e;if("number"===a&&"number"==typeof t&&s){const e=N.current[s];return t*(e?.scale??1)}if("json"===a&&n?.fromServer)try{return n.fromServer(t)}catch{}return t},[]),k=useCallback((e,t)=>{const{valueType:a,scale:s,codec:n}=e;if("json"===a&&n?.toServer)try{t=n.toServer(t)}catch{}if("number"===a&&"number"==typeof t&&s){const e=N.current[s];return t/(e?.scale??1)}return t},[]),E=useCallback(e=>{const a=t.filter(t=>t.scale===e);a.length&&p(e=>{const t={...e};for(const e of a){const a=h.current[e.tagName];if("number"!=typeof a)continue;const s=x(e,a);t[e.tagName]!==s&&(t[e.tagName]=s)}return t})},[t,x]),q=useCallback((e,t)=>{d(a=>a[e.tagName]===t?a:{...a,[e.tagName]:t});const a=x(e,t);p(t=>t[e.tagName]===a?t:{...t,[e.tagName]:a})},[x]),M=useCallback(async(e,t,a)=>{const s=a?.concurrency??4,n=a?.minDelayMs??20,c=a?.jitterMs??40;let r=0;const u=Array.from({length:s},()=>(async()=>{for(;;){const a=r++;if(a>=t.length)return;const s=t[a];try{let t=!1;try{await o(s.fqdn,MessageType.Request,{action:"refresh"}),t=!0}catch{}if(!t){const t="GNV"===e.toUpperCase()?{group:"ux"}:{};try{const e=await l(s.fqdn,t);e?.success&&q(s,e.data)}catch(e){}}}catch(e){}finally{const e=Math.floor(Math.random()*c);await sleep(n+e)}}})());await Promise.all(u)},[o,l,q]),S=useCallback(async()=>{for(const[e,t]of Object.entries(r)){if(!t.serverTag)continue;const{domain:a,symbolName:s}=t.serverTag;try{const t=await l(`${a}.${s}`,{group:"ux"});if(t.data&&(t.success??1)&&(t.valid??1)){const a=JSON.parse(t.data);if(a&&"number"==typeof a.scale){const{scale:t,label:s}=a;C(a=>({...a,[e]:{...a[e],scale:t,label:s??a[e]?.label??"---"}})),E(e)}}}catch{}}},[l,r,E]);useEffect(()=>{let e=!0;const a=[],c=async()=>{if(e&&!n.current){n.current=!0;try{await(async()=>{try{await S();for(const n of t){await i(n.tagName,n.fqdn,n.subscriptionOptions);const t=m(n.tagName,t=>{e&&q(n,t)});a.push(t),s&&l(n.fqdn).then(t=>{e&&t?.success&&q(n,t.data)}).catch(e=>{})}}finally{e&&setTimeout(()=>e&&w(!1),100)}})()}finally{e&&setTimeout(()=>e&&w(!1),100)}}};if(f())c();else{const e=m("HUB/connected",()=>{y(e),c()});a.push(e)}return()=>{e=!1,a.forEach(y),n.current=!1}},[m,y,f,o,i,s,t,S,M,q]);const j=useMemo(()=>Object.entries(r).filter(([,e])=>e.serverTag).map(([e,t])=>({scaleName:e,domain:t.serverTag.domain,symbolName:t.serverTag.symbolName})),[r]);useEffect(()=>{let e=!0;const t=[];for(const{scaleName:a,domain:s,symbolName:n}of j){const c=m(`${s}.${n}`,t=>{if(!e)return;const s=t?.value;if(s&&"object"==typeof s&&"number"==typeof s.scale){const{scale:e,label:t}=s;C(s=>({...s,[a]:{...s[a],scale:e,label:t??s[a]?.label??"---"}})),E(a)}});t.push(c)}return()=>{e=!1,t.forEach(y)}},[m,y,j,E]);const R=useCallback(async(e,a)=>{const s=t.find(t=>t.tagName===e);if(!s)return;const n=k(s,a);await u(s.fqdn,n)},[t,u,k]),$=useCallback(async e=>{const a=t.find(t=>t.tagName===e);a&&"boolean"===a.valueType&&(u(a.fqdn,!0).catch(e=>{}),await sleep(300),u(a.fqdn,!1).catch(e=>{}))},[t,u]),V=useCallback(async e=>{const a=t.find(t=>t.tagName===e);a&&"boolean"===a.valueType&&await u(a.fqdn,!0)},[t,u]),A=useCallback(async e=>{const a=t.find(t=>t.tagName===e);a&&"boolean"===a.valueType&&await u(a.fqdn,!1)},[t,u]),O=useCallback(async(e,t,a)=>{const s=v[e];if(s){if(s.serverTag){const n=`${s.serverTag.domain}.${s.serverTag.symbolName}`;await u(n,{name:e,scale:t,label:a})}C(s=>({...s,[e]:{...s[e],scale:t,label:a}})),E(e)}},[v,u,E]);useEffect(()=>{p(e=>{const a={...e};for(const e of t){const t=h.current[e.tagName];if(void 0===t)continue;const s=x(e,t);a[e.tagName]!==s&&(a[e.tagName]=s)}return a})},[t,x,v]);const P=useMemo(()=>{const e=new Map;for(const a of t)e.set(a.fqdn,a);return e},[t]),B=useCallback(e=>P.get(e),[P]),F=useMemo(()=>({values:g,rawValues:b,isLoading:T,write:R,tap:$,press:V,release:A,scales:v,updateScale:O,findTagByFqdn:B}),[g,b,T,R,$,V,A,v,O,B]);return _jsx(AutoCoreTagContext.Provider,{value:F,children:e})};
|
|
@@ -286,6 +286,15 @@ export interface BaseContextValue<VMap extends Record<string, any>> {
|
|
|
286
286
|
* @param newLabel - New units label (e.g., "inches")
|
|
287
287
|
*/
|
|
288
288
|
updateScale: (scaleName: string, newScale: number, newLabel: string) => Promise<void>;
|
|
289
|
+
/**
|
|
290
|
+
* Look up a tag's full configuration by its FQDN (e.g., "gm.x_cycle_move_speed").
|
|
291
|
+
*
|
|
292
|
+
* Useful for subscribers that only know the remote topic (e.g., a
|
|
293
|
+
* `test_definitions` schema's `source` field) and need to resolve it to a
|
|
294
|
+
* local `tagName` before calling `subscribe(tagName, …)`. Returns undefined
|
|
295
|
+
* if no tag is registered for the given FQDN.
|
|
296
|
+
*/
|
|
297
|
+
findTagByFqdn: (fqdn: string) => TagConfig | undefined;
|
|
289
298
|
}
|
|
290
299
|
export {};
|
|
291
300
|
//# sourceMappingURL=AutoCoreTagTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoCoreTagTypes.d.ts","sourceRoot":"","sources":["../../src/core/AutoCoreTagTypes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AutoCoreTagTypes.d.ts","sourceRoot":"","sources":["../../src/core/AutoCoreTagTypes.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useContext } from 'react';
|
|
|
2
2
|
import { AutoComplete } from 'primereact/autocomplete';
|
|
3
3
|
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
|
|
4
4
|
import { EventEmitterContext } from '../core/EventEmitterContext';
|
|
5
|
+
import { AutoCoreTagContext } from '../core/AutoCoreTagContext';
|
|
5
6
|
import { MessageType } from '../hub/CommandMessage';
|
|
6
7
|
import { ValueInput } from './ValueInput';
|
|
7
8
|
import { TextInput } from './TextInput';
|
|
@@ -57,35 +58,77 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
57
58
|
|
|
58
59
|
const [isValid, setIsValid] = useState(false);
|
|
59
60
|
const { invoke, write, subscribe, unsubscribe } = useContext(EventEmitterContext);
|
|
61
|
+
const { findTagByFqdn } = useContext(AutoCoreTagContext);
|
|
60
62
|
|
|
61
|
-
// Subscribe to external tags if a field defines a source
|
|
63
|
+
// Subscribe to external tags if a field defines a source, and seed the
|
|
64
|
+
// current value once on mount so the form reflects existing GM state
|
|
65
|
+
// instead of staying blank until the next broadcast.
|
|
66
|
+
//
|
|
67
|
+
// The schema's `source` is the remote FQDN (e.g. "gm.x_cycle_move_speed"),
|
|
68
|
+
// but the frontend event bus dispatches on the local `tagName` that the
|
|
69
|
+
// AutoCoreTagProvider registered with the Hub. We resolve FQDN → tagName
|
|
70
|
+
// via `findTagByFqdn` before subscribing; otherwise the callback never
|
|
71
|
+
// fires. Initial reads still go by FQDN — the Hub accepts that directly.
|
|
62
72
|
useEffect(() => {
|
|
63
73
|
if (!schema) return;
|
|
64
|
-
|
|
74
|
+
|
|
65
75
|
const allFields = [...schema.project_fields, ...schema.config_fields];
|
|
66
76
|
const subs: any[] = [];
|
|
67
|
-
|
|
77
|
+
|
|
68
78
|
for (const field of allFields) {
|
|
69
|
-
if (field.source)
|
|
70
|
-
|
|
79
|
+
if (!field.source) continue;
|
|
80
|
+
|
|
81
|
+
const source = field.source;
|
|
82
|
+
const fieldName = field.name;
|
|
83
|
+
|
|
84
|
+
const tag = findTagByFqdn(source);
|
|
85
|
+
if (!tag) {
|
|
86
|
+
console.warn(
|
|
87
|
+
`TestSetupForm: no tag registered for source "${source}" ` +
|
|
88
|
+
`(field "${fieldName}"). Add it to acTagSpec with "ux": true ` +
|
|
89
|
+
`in project.json, or live updates for this field won't arrive.`
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
const subId = subscribe(tag.tagName, (newVal: any) => {
|
|
71
93
|
setConfig((prev: any) => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return { ...prev, [field.name]: newVal };
|
|
94
|
+
if (prev[fieldName] !== newVal) {
|
|
95
|
+
return { ...prev, [fieldName]: newVal };
|
|
75
96
|
}
|
|
76
97
|
return prev;
|
|
77
98
|
});
|
|
78
99
|
});
|
|
79
100
|
subs.push(subId);
|
|
80
101
|
}
|
|
102
|
+
|
|
103
|
+
// Pub/sub only delivers future changes, not the current value.
|
|
104
|
+
// Fetch it explicitly so reloading the page doesn't blank the form.
|
|
105
|
+
(async () => {
|
|
106
|
+
try {
|
|
107
|
+
const resp: any = await invoke(
|
|
108
|
+
source as any,
|
|
109
|
+
MessageType.Read as any,
|
|
110
|
+
{} as any,
|
|
111
|
+
);
|
|
112
|
+
const current = resp?.data !== undefined ? resp.data : resp;
|
|
113
|
+
if (current !== undefined && current !== null) {
|
|
114
|
+
setConfig((prev: any) => (
|
|
115
|
+
prev[fieldName] === undefined || prev[fieldName] === null || prev[fieldName] === ''
|
|
116
|
+
? { ...prev, [fieldName]: current }
|
|
117
|
+
: prev
|
|
118
|
+
));
|
|
119
|
+
}
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.warn(`TestSetupForm: failed to seed "${fieldName}" from "${source}":`, err);
|
|
122
|
+
}
|
|
123
|
+
})();
|
|
81
124
|
}
|
|
82
|
-
|
|
125
|
+
|
|
83
126
|
return () => {
|
|
84
127
|
for (const subId of subs) {
|
|
85
128
|
unsubscribe(subId);
|
|
86
129
|
}
|
|
87
130
|
};
|
|
88
|
-
}, [schema, subscribe, unsubscribe]);
|
|
131
|
+
}, [schema, subscribe, unsubscribe, invoke, findTagByFqdn]);
|
|
89
132
|
|
|
90
133
|
useEffect(() => {
|
|
91
134
|
const fetchProjects = async () => {
|
|
@@ -165,8 +208,7 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
165
208
|
{isNum ? (
|
|
166
209
|
<ValueInput
|
|
167
210
|
label={undefined}
|
|
168
|
-
value={config[field.name] != null ? Number(config[field.name]) : null}
|
|
169
|
-
suffix={field.units ? ` ${field.units}` : undefined}
|
|
211
|
+
value={config[field.name] != null ? Number(config[field.name]) : null}
|
|
170
212
|
onValueChanged={(val) => handleFieldChange(field, val)}
|
|
171
213
|
className={!valid ? 'p-invalid' : ''}
|
|
172
214
|
/>
|
|
@@ -174,11 +216,13 @@ export const TestSetupForm: React.FC<TestSetupFormProps> = ({
|
|
|
174
216
|
<TextInput
|
|
175
217
|
label={undefined}
|
|
176
218
|
value={config[field.name] != null ? String(config[field.name]) : ''}
|
|
177
|
-
suffix={field.units ? ` ${field.units}` : undefined}
|
|
178
219
|
onValueChanged={(val) => handleFieldChange(field, val)}
|
|
179
220
|
className={!valid ? 'p-invalid' : ''}
|
|
180
221
|
/>
|
|
181
222
|
)}
|
|
223
|
+
|
|
224
|
+
<span>{field.units ? ` ${field.units}` : undefined}</span>
|
|
225
|
+
|
|
182
226
|
<span style={{ color: valid ? 'var(--green-500)' : 'var(--red-500)', display: 'flex', alignItems: 'center' }}>
|
|
183
227
|
<i className={valid ? "pi pi-check" : "pi pi-times"}></i>
|
|
184
228
|
</span>
|
|
@@ -147,10 +147,16 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
|
|
147
147
|
// Keep the DOM value a string at all times (no uncontrolled→controlled flip)
|
|
148
148
|
const domValue = useMemo(() => toStr(entryValue), [entryValue]);
|
|
149
149
|
|
|
150
|
+
const isLabelDefined = () => {
|
|
151
|
+
return label !== undefined && label !== null && label !== '';
|
|
152
|
+
}
|
|
153
|
+
|
|
150
154
|
return (
|
|
151
155
|
<div>
|
|
152
156
|
<div className="p-inputgroup">
|
|
153
|
-
|
|
157
|
+
{ isLabelDefined() &&
|
|
158
|
+
<span className="p-inputgroup-addon">{label}</span>
|
|
159
|
+
}
|
|
154
160
|
|
|
155
161
|
{prefix !== undefined && <span className="p-inputgroup-addon">{prefix}</span>}
|
|
156
162
|
|
|
@@ -178,14 +184,14 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
|
|
178
184
|
disabled={disabled || !editing}
|
|
179
185
|
className="p-button-success"
|
|
180
186
|
onClick={accept}
|
|
181
|
-
visible={
|
|
187
|
+
visible={true}
|
|
182
188
|
/>
|
|
183
189
|
<Button
|
|
184
190
|
icon="pi pi-times"
|
|
185
191
|
disabled={disabled || !editing}
|
|
186
192
|
className="p-button-danger"
|
|
187
193
|
onClick={reset}
|
|
188
|
-
visible={
|
|
194
|
+
visible={true}
|
|
189
195
|
/>
|
|
190
196
|
</div>
|
|
191
197
|
|
|
@@ -205,7 +205,7 @@ interface ValueInputProps extends Omit<InputNumberProps, 'value' | 'size'> {
|
|
|
205
205
|
* accepting and rejecting values and keyboard management.
|
|
206
206
|
*/
|
|
207
207
|
export const ValueInput: React.FC<ValueInputProps> = ({
|
|
208
|
-
label
|
|
208
|
+
label,
|
|
209
209
|
value = null,
|
|
210
210
|
min = undefined,
|
|
211
211
|
max = undefined,
|
|
@@ -322,7 +322,7 @@ export const ValueInput: React.FC<ValueInputProps> = ({
|
|
|
322
322
|
};
|
|
323
323
|
|
|
324
324
|
const isLabelDefined = () => {
|
|
325
|
-
return label !== undefined && label !== null;
|
|
325
|
+
return label !== undefined && label !== null && label !== '';
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
return (
|
|
@@ -365,7 +365,7 @@ export const ValueInput: React.FC<ValueInputProps> = ({
|
|
|
365
365
|
disabled={disabled || !editing}
|
|
366
366
|
className="p-button-success"
|
|
367
367
|
onClick={() => handleAcceptValue()}
|
|
368
|
-
visible={
|
|
368
|
+
visible={true}
|
|
369
369
|
autoFocus={false}
|
|
370
370
|
/>
|
|
371
371
|
|
|
@@ -374,7 +374,7 @@ export const ValueInput: React.FC<ValueInputProps> = ({
|
|
|
374
374
|
disabled={disabled || !editing}
|
|
375
375
|
className="p-button-danger"
|
|
376
376
|
onClickCapture={() => handleResetValue()}
|
|
377
|
-
visible={
|
|
377
|
+
visible={true}
|
|
378
378
|
autoFocus={false}
|
|
379
379
|
/>
|
|
380
380
|
|
|
@@ -108,6 +108,7 @@ export const AutoCoreTagContext = createContext<BaseContextValue<VMapRuntime>>({
|
|
|
108
108
|
release: async () => { },
|
|
109
109
|
scales: {},
|
|
110
110
|
updateScale: async () => { },
|
|
111
|
+
findTagByFqdn: () => undefined,
|
|
111
112
|
});
|
|
112
113
|
|
|
113
114
|
/**
|
|
@@ -636,6 +637,23 @@ export const AutoCoreTagProvider: React.FC<{
|
|
|
636
637
|
});
|
|
637
638
|
}, [tags, toDisplay, scaleValues]);
|
|
638
639
|
|
|
640
|
+
/**
|
|
641
|
+
* FQDN → TagConfig index, rebuilt whenever the `tags` prop changes.
|
|
642
|
+
* Used by `findTagByFqdn` below so consumers (e.g., TestSetupForm) can
|
|
643
|
+
* resolve a remote topic string to the local tagName the event bus
|
|
644
|
+
* dispatches on.
|
|
645
|
+
*/
|
|
646
|
+
const tagsByFqdn = useMemo(() => {
|
|
647
|
+
const m = new Map<string, TagConfig>();
|
|
648
|
+
for (const t of tags) m.set(t.fqdn, t);
|
|
649
|
+
return m;
|
|
650
|
+
}, [tags]);
|
|
651
|
+
|
|
652
|
+
const findTagByFqdn = useCallback(
|
|
653
|
+
(fqdn: string): TagConfig | undefined => tagsByFqdn.get(fqdn),
|
|
654
|
+
[tagsByFqdn],
|
|
655
|
+
);
|
|
656
|
+
|
|
639
657
|
/**
|
|
640
658
|
* Construct context value. Memoized to prevent consumers from re-rendering
|
|
641
659
|
* unless actual data changes.
|
|
@@ -651,7 +669,8 @@ export const AutoCoreTagProvider: React.FC<{
|
|
|
651
669
|
release,
|
|
652
670
|
scales: scaleValues,
|
|
653
671
|
updateScale,
|
|
654
|
-
|
|
672
|
+
findTagByFqdn,
|
|
673
|
+
}), [values, rawValues, isLoading, write, tap, press, release, scaleValues, updateScale, findTagByFqdn]);
|
|
655
674
|
|
|
656
675
|
|
|
657
676
|
return (
|
|
@@ -341,4 +341,14 @@ export interface BaseContextValue<VMap extends Record<string, any>> {
|
|
|
341
341
|
* @param newLabel - New units label (e.g., "inches")
|
|
342
342
|
*/
|
|
343
343
|
updateScale: (scaleName: string, newScale: number, newLabel: string) => Promise<void>;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Look up a tag's full configuration by its FQDN (e.g., "gm.x_cycle_move_speed").
|
|
347
|
+
*
|
|
348
|
+
* Useful for subscribers that only know the remote topic (e.g., a
|
|
349
|
+
* `test_definitions` schema's `source` field) and need to resolve it to a
|
|
350
|
+
* local `tagName` before calling `subscribe(tagName, …)`. Returns undefined
|
|
351
|
+
* if no tag is registered for the given FQDN.
|
|
352
|
+
*/
|
|
353
|
+
findTagByFqdn: (fqdn: string) => TagConfig | undefined;
|
|
344
354
|
}
|