@adcops/autocore-react 3.5.9 → 3.5.11
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 +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/tis-editor/TisConfigEditor.css +11 -0
- 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/AuthoringContext.d.ts +37 -0
- package/dist/components/tis-editor/editor/AuthoringContext.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/AuthoringContext.js +1 -0
- package/dist/components/tis-editor/editor/ChartViewDialog.d.ts +11 -0
- package/dist/components/tis-editor/editor/ChartViewDialog.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/ChartViewDialog.js +1 -1
- 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/RawDataEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/RawDataEditor.js +1 -1
- package/dist/components/tis-editor/editor/TestFieldDialog.d.ts +7 -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/varpick/VariableInput.d.ts +41 -0
- package/dist/components/varpick/VariableInput.d.ts.map +1 -0
- package/dist/components/varpick/VariableInput.js +1 -0
- package/dist/components/varpick/VariablePicker.d.ts +45 -0
- package/dist/components/varpick/VariablePicker.d.ts.map +1 -0
- package/dist/components/varpick/VariablePicker.js +1 -0
- package/dist/components/varpick/index.d.ts +16 -0
- package/dist/components/varpick/index.d.ts.map +1 -0
- package/dist/components/varpick/index.js +1 -0
- package/dist/components/varpick/tisCatalogs.d.ts +85 -0
- package/dist/components/varpick/tisCatalogs.d.ts.map +1 -0
- package/dist/components/varpick/tisCatalogs.js +1 -0
- package/dist/components/varpick/varpick.css +167 -0
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
- package/dist/core/AutoCoreTagContext.js +1 -1
- package/dist/core/AutoCoreTagTypes.d.ts +13 -0
- package/dist/core/AutoCoreTagTypes.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useGmVariables.d.ts +57 -0
- package/dist/hooks/useGmVariables.d.ts.map +1 -0
- package/dist/hooks/useGmVariables.js +1 -0
- package/dist/hooks/useSequenceProducers.d.ts +38 -0
- package/dist/hooks/useSequenceProducers.d.ts.map +1 -0
- package/dist/hooks/useSequenceProducers.js +1 -0
- package/package.json +5 -2
- package/src/components/index.ts +17 -0
- package/src/components/tis-editor/TisConfigEditor.css +11 -0
- package/src/components/tis-editor/TisConfigEditor.tsx +31 -0
- package/src/components/tis-editor/editor/AuthoringContext.tsx +43 -0
- package/src/components/tis-editor/editor/ChartViewDialog.tsx +24 -7
- package/src/components/tis-editor/editor/FieldArrayEditor.tsx +1 -0
- package/src/components/tis-editor/editor/RawDataEditor.tsx +7 -2
- package/src/components/tis-editor/editor/TestFieldDialog.tsx +66 -12
- package/src/components/tis-editor/editor/ViewsEditor.tsx +25 -0
- package/src/components/varpick/VariableInput.tsx +126 -0
- package/src/components/varpick/VariablePicker.tsx +168 -0
- package/src/components/varpick/index.ts +22 -0
- package/src/components/varpick/tisCatalogs.ts +235 -0
- package/src/components/varpick/varpick.css +167 -0
- package/src/core/AutoCoreTagContext.tsx +3 -1
- package/src/core/AutoCoreTagTypes.ts +14 -0
- package/src/hooks/index.ts +11 -0
- package/src/hooks/useGmVariables.ts +142 -0
- package/src/hooks/useSequenceProducers.ts +104 -0
- package/tools/tests/dist/TestFieldDialog-C4mKVh7q.js +32817 -0
- package/tools/tests/dist/autocore-react.css +257 -0
- package/tools/tests/dist/tis-editor.entry.js +8431 -40567
- package/tools/tests/dist/varpick.entry.js +113 -0
- package/tools/tests/live-server.probe.mjs +172 -0
- package/tools/tests/varpick.entry.tsx +81 -0
- package/tools/tests/varpick.test.mjs +208 -0
- package/tools/tests/vite.config.mjs +7 -2
- package/tools/tests/dist/tis-editor.entry.css +0 -90
|
@@ -47,4 +47,8 @@ export { NetworkPanel } from './network/NetworkPanel';
|
|
|
47
47
|
export type { NetworkPanelProps } from './network/NetworkPanel';
|
|
48
48
|
export { StagedChangeBanner } from './network/StagedChangeBanner';
|
|
49
49
|
export type { StagedChangeBannerProps } from './network/StagedChangeBanner';
|
|
50
|
+
export { VariablePicker, VariableInput } from './varpick';
|
|
51
|
+
export type { VariablePickerProps, VariableInputProps } from './varpick';
|
|
52
|
+
export { boundCatalog, chartFieldCatalog, configSourceCatalog, cycleSourceCatalog, rawSourceCatalog, } from './varpick';
|
|
53
|
+
export type { TisCatalogContext } from './varpick';
|
|
50
54
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{TisProvider,TisContext,useTis,useTisSchemas,useTisState,useTisSelection,useTisRuns,useTisRun,useTisCycleConfig}from"./tis/TisProvider";export{ProjectSelector}from"./tis/ProjectSelector";export{TestSetupForm}from"./tis/TestSetupForm";export{TestSetupView}from"./tis/TestSetupView";export{orderedViews,renumberViews,moveView}from"./tis/chartViews";export{TestFieldRow}from"./tis/TestFieldRow";export{CycleConfigForm,cycleConfigSummary}from"./tis/CycleConfigForm";export{CycleConfigDialog,useCycleConfigGate}from"./tis/CycleConfigDialog";export{CycleStatusStrip}from"./tis/CycleStatusStrip";export{ProjectInfoDialog}from"./tis/ProjectInfoDialog";export{TestMethodDialog}from"./tis/TestMethodDialog";export{ResultHistoryTable}from"./tis/ResultHistoryTable";export{SampleSummaryPanel}from"./tis/SampleSummaryPanel";export{TestDataView,DEFAULT_X_DECIMALS}from"./tis/TestDataView";export{UnitSystemSelector}from"./UnitSystemSelector";export{UnitsEditor}from"./UnitsEditor";export{TestRawDataView}from"./tis/TestRawDataView";export{ProjectManager}from"./tis/ProjectManager";export{AmsProvider,useAms,useAmsSchemas,useAmsAlerts,useAmsAssets,useAmsSelection}from"./ams/AmsProvider";export{AssetRegistryTable}from"./ams/AssetRegistryTable";export{AssetDetailView}from"./ams/AssetDetailView";export{CalibrationEntryDialog}from"./ams/CalibrationEntryDialog";export{SubLocationPicker}from"./ams/SubLocationPicker";export{NetworkProvider,useNetwork}from"./network/NetworkProvider";export{NetworkPanel}from"./network/NetworkPanel";export{StagedChangeBanner}from"./network/StagedChangeBanner";
|
|
1
|
+
export{TisProvider,TisContext,useTis,useTisSchemas,useTisState,useTisSelection,useTisRuns,useTisRun,useTisCycleConfig}from"./tis/TisProvider";export{ProjectSelector}from"./tis/ProjectSelector";export{TestSetupForm}from"./tis/TestSetupForm";export{TestSetupView}from"./tis/TestSetupView";export{orderedViews,renumberViews,moveView}from"./tis/chartViews";export{TestFieldRow}from"./tis/TestFieldRow";export{CycleConfigForm,cycleConfigSummary}from"./tis/CycleConfigForm";export{CycleConfigDialog,useCycleConfigGate}from"./tis/CycleConfigDialog";export{CycleStatusStrip}from"./tis/CycleStatusStrip";export{ProjectInfoDialog}from"./tis/ProjectInfoDialog";export{TestMethodDialog}from"./tis/TestMethodDialog";export{ResultHistoryTable}from"./tis/ResultHistoryTable";export{SampleSummaryPanel}from"./tis/SampleSummaryPanel";export{TestDataView,DEFAULT_X_DECIMALS}from"./tis/TestDataView";export{UnitSystemSelector}from"./UnitSystemSelector";export{UnitsEditor}from"./UnitsEditor";export{TestRawDataView}from"./tis/TestRawDataView";export{ProjectManager}from"./tis/ProjectManager";export{AmsProvider,useAms,useAmsSchemas,useAmsAlerts,useAmsAssets,useAmsSelection}from"./ams/AmsProvider";export{AssetRegistryTable}from"./ams/AssetRegistryTable";export{AssetDetailView}from"./ams/AssetDetailView";export{CalibrationEntryDialog}from"./ams/CalibrationEntryDialog";export{SubLocationPicker}from"./ams/SubLocationPicker";export{NetworkProvider,useNetwork}from"./network/NetworkProvider";export{NetworkPanel}from"./network/NetworkPanel";export{StagedChangeBanner}from"./network/StagedChangeBanner";export{VariablePicker,VariableInput}from"./varpick";export{boundCatalog,chartFieldCatalog,configSourceCatalog,cycleSourceCatalog,rawSourceCatalog}from"./varpick";
|
|
@@ -105,6 +105,17 @@
|
|
|
105
105
|
font-size: 0.8rem;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/* A degradation, not a failure: the editor works, it just knows less. Amber
|
|
109
|
+
* rather than the red used for a real error. */
|
|
110
|
+
.tis-editor__notice {
|
|
111
|
+
background: #fffbeb;
|
|
112
|
+
color: #92400e;
|
|
113
|
+
border-left: 3px solid #d97706;
|
|
114
|
+
padding: 0.5rem 1rem;
|
|
115
|
+
margin: 0.5rem 1rem;
|
|
116
|
+
font-size: 0.875rem;
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
.tis-editor__empty {
|
|
109
120
|
flex: 1;
|
|
110
121
|
display: flex;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TisConfigEditor.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/TisConfigEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAWH,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM5E,OAAO,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"TisConfigEditor.d.ts","sourceRoot":"","sources":["../../../src/components/tis-editor/TisConfigEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAWH,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM5E,OAAO,uBAAuB,CAAC;AAM/B,MAAM,WAAW,oBAAoB;IACjC;+EAC2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,CAAC;CAC3B;AAmBD,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoS1D,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useEffect,useMemo,useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{Dialog}from"primereact/dialog";import{useContext}from"react";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTisConfig}from"../../hooks/useTisConfig";import{useAmsAssetTypes}from"../../hooks/useAmsAssetTypes";import{MethodFormEditor}from"./editor/MethodFormEditor";import{SaveDiffDialog}from"./editor/SaveDiffDialog";import"./TisConfigEditor.css";const EMPTY_METHOD={label:"",description:"",project_fields:[],config_fields:[],cycle_config_fields:[],cycle_fields:[],results_fields:[],views:{},asset_refs:[]};export const TisConfigEditor=({projectId:e,invoker:t})=>{const s=useContext(EventEmitterContext),i=useMemo(()=>t??(async(e,t)=>await s.invoke(e,MessageType.Request,t)),[t,s]),o=useTisConfig(e,{invoker:i}),a=useAmsAssetTypes({invoker:i}),[
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useEffect,useMemo,useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{Dialog}from"primereact/dialog";import{useContext}from"react";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTisConfig}from"../../hooks/useTisConfig";import{useAmsAssetTypes}from"../../hooks/useAmsAssetTypes";import{MethodFormEditor}from"./editor/MethodFormEditor";import{SaveDiffDialog}from"./editor/SaveDiffDialog";import"./TisConfigEditor.css";import{useGmVariables}from"../../hooks/useGmVariables";import{useSequenceProducers}from"../../hooks/useSequenceProducers";import{AuthoringContext}from"./editor/AuthoringContext";import{AutoCoreTagContext}from"../../core/AutoCoreTagContext";const EMPTY_METHOD={label:"",description:"",project_fields:[],config_fields:[],cycle_config_fields:[],cycle_fields:[],results_fields:[],views:{},asset_refs:[]};export const TisConfigEditor=({projectId:e,invoker:t})=>{const s=useContext(EventEmitterContext),i=useMemo(()=>t??(async(e,t)=>await s.invoke(e,MessageType.Request,t)),[t,s]),o=useTisConfig(e,{invoker:i}),{tags:a}=useContext(AutoCoreTagContext),r=useGmVariables({invoker:i,fallbackTags:a}),n=useAmsAssetTypes({invoker:i}),[l,d]=useState(null),[c,m]=useState(null),[u,f]=useState(!1),[p,h]=useState(!1),[g,_]=useState(!1),[x,y]=useState(""),b=useMemo(()=>o.config?Object.entries(o.config.methods).map(([e,t])=>({id:e,label:t?.label??""})):[],[o.config]);useEffect(()=>{if(!l&&o.config){const e=o.config.defaultMethodId||Object.keys(o.config.methods)[0]||null;d(e)}},[o.config,l]),useEffect(()=>{m(null)},[l]);const{producedNames:v}=useSequenceProducers(l),j=useMemo(()=>({variables:r.variables,producedNames:v,partial:r.partial}),[r.variables,v,r.partial]);return _jsx(AuthoringContext.Provider,{value:j,children:_jsxs("div",{className:"tis-editor",children:[_jsxs("header",{className:"tis-editor__header",children:[_jsxs("h2",{children:["Test Methods"," ",o.config?.dirty&&_jsx("span",{className:"tis-editor__dirty-pill",children:"unsaved"})]}),_jsxs("div",{className:"tis-editor__header-actions",children:[_jsx(Button,{label:"Save…",icon:"pi pi-save",disabled:u||!o.config?.dirty,onClick:()=>h(!0)}),_jsx(Button,{label:"Revert",icon:"pi pi-undo",className:"p-button-secondary",disabled:u||!o.config?.dirty,onClick:async()=>{if(window.confirm("Discard all in-progress edits? This cannot be undone.")){f(!0);try{await o.revert()}catch(e){m(String(e?.message??e))}finally{f(!1)}}}})]})]}),o.error&&_jsxs("div",{className:"tis-editor__error",children:[_jsx("strong",{children:"Error:"})," ",_jsx("pre",{children:o.error})]}),r.partial&&_jsx("div",{className:"tis-editor__notice",children:"This server cannot describe its own variables, so the pickers are listing only the variables published to this HMI, without descriptions. Update autocore_server to get the full list."}),_jsxs("div",{className:"tis-editor__body",children:[_jsxs("aside",{className:"tis-editor__sidebar",children:[_jsxs("div",{className:"tis-editor__sidebar-actions",children:[_jsx(Button,{label:"New",icon:"pi pi-plus",disabled:u,onClick:()=>_(!0)}),_jsx(Button,{label:"Duplicate",icon:"pi pi-clone",className:"p-button-secondary",disabled:u||!l,onClick:async()=>{if(!l||!o.config)return;const e=o.config.methods[l];if(!e)return;let t=`${l}_copy`,s=2;for(;o.config.methods[t];)t=`${l}_copy_${s++}`;f(!0);try{await o.putMethod(t,JSON.parse(JSON.stringify(e))),d(t)}catch(e){m(String(e?.message??e))}finally{f(!1)}}}),_jsx(Button,{label:"Delete",icon:"pi pi-trash",className:"p-button-danger",disabled:u||!l,onClick:async()=>{if(l&&window.confirm(`Remove method "${l}"? This is staged — Save persists it.`)){f(!0);try{await o.removeMethod(l),d(null)}catch(e){m(String(e?.message??e))}finally{f(!1)}}}})]}),_jsxs(DataTable,{value:b,selection:b.find(e=>e.id===l)??null,onSelectionChange:e=>d(e.value?.id??null),selectionMode:"single",dataKey:"id",scrollable:!0,scrollHeight:"flex",emptyMessage:o.loading?"Loading…":"No test methods defined.",children:[_jsx(Column,{field:"id",header:"Method ID"}),_jsx(Column,{field:"label",header:"Label"})]})]}),_jsx("section",{className:"tis-editor__detail",children:l&&o.config?.methods[l]?_jsxs(_Fragment,{children:[c&&_jsx("div",{className:"tis-editor__error",children:_jsx("pre",{children:c})}),_jsx(MethodFormEditor,{methodId:l,method:o.config.methods[l],onApply:async e=>{if(l){f(!0);try{await o.putMethod(l,e),m(null)}catch(e){m(String(e?.message??e))}finally{f(!1)}}},busy:u,knownAssetTypes:n.types})]}):_jsx("div",{className:"tis-editor__empty",children:"Select a test method on the left, or create a new one."})})]}),_jsxs(Dialog,{header:"New Test Method",visible:g,onHide:()=>_(!1),style:{width:"24rem"},children:[_jsxs("label",{className:"tis-editor__new-method-label",children:["Method ID",_jsx(InputText,{value:x,onChange:e=>y(e.target.value),placeholder:"e.g. translational_traction",autoFocus:!0})]}),_jsx("small",{children:"Canonical key — appears in wire payloads, on-disk paths, and generated code."}),_jsxs("div",{style:{display:"flex",gap:"0.5rem",justifyContent:"flex-end",marginTop:"1rem"},children:[_jsx(Button,{label:"Cancel",className:"p-button-text",onClick:()=>_(!1)}),_jsx(Button,{label:"Create",disabled:!x.trim()||u,onClick:async()=>{const e=x.trim();if(e)if(o.config?.methods[e])m(`A method named "${e}" already exists.`);else{f(!0);try{await o.putMethod(e,EMPTY_METHOD),d(e),_(!1),y("")}catch(e){m(String(e?.message??e))}finally{f(!1)}}}})]})]}),_jsx(SaveDiffDialog,{visible:p,staged:o.config?.methods??{},invoker:i,onConfirm:async()=>{f(!0);try{await o.save(),h(!1)}catch(e){m(String(e?.message??e))}finally{f(!1)}},onCancel:()=>h(!1)})]})})};export default TisConfigEditor;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the method editor's pickers can offer.
|
|
3
|
+
*
|
|
4
|
+
* A context rather than props because the fields that need it — a field
|
|
5
|
+
* dialog's Source, a bound, a chart axis, a raw column — sit three and four
|
|
6
|
+
* levels below the editor that fetches it, and threading the same two values
|
|
7
|
+
* through every intermediate component is how a prop list becomes noise.
|
|
8
|
+
*
|
|
9
|
+
* Everything here is optional. With none of it the pickers still open; they just
|
|
10
|
+
* have nothing to list, which is exactly the state the editor was in before they
|
|
11
|
+
* existed.
|
|
12
|
+
*/
|
|
13
|
+
import type { GmVariable } from '@adcops/autocore-varpick';
|
|
14
|
+
export interface AuthoringCatalogs {
|
|
15
|
+
/** The machine's GM variable table, from `gm.get_variables`. */
|
|
16
|
+
variables: GmVariable[];
|
|
17
|
+
/**
|
|
18
|
+
* `store_value` names in the selected method's sequence.
|
|
19
|
+
*
|
|
20
|
+
* `undefined` means "not looked up" — the host could not read the
|
|
21
|
+
* `.seq.json`, or this product has no sequencer. That is deliberately
|
|
22
|
+
* different from `[]`, which means "read it, and it stores nothing": the
|
|
23
|
+
* first must not claim a cycle field has no producer.
|
|
24
|
+
*/
|
|
25
|
+
producedNames?: string[];
|
|
26
|
+
/**
|
|
27
|
+
* True when `variables` came from the generated tag spec rather than the
|
|
28
|
+
* server — names and types, no descriptions, `ux: true` only.
|
|
29
|
+
*
|
|
30
|
+
* Worth surfacing: a picker that silently lists two thirds of the machine
|
|
31
|
+
* is worse than one that says it is listing two thirds of the machine.
|
|
32
|
+
*/
|
|
33
|
+
partial?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare const AuthoringContext: import("react").Context<AuthoringCatalogs>;
|
|
36
|
+
export declare const useAuthoringCatalogs: () => AuthoringCatalogs;
|
|
37
|
+
//# sourceMappingURL=AuthoringContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthoringContext.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/AuthoringContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAC9B,gEAAgE;IAChE,SAAS,EAAE,UAAU,EAAE,CAAC;IAExB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,4CAAsD,CAAC;AAEpF,eAAO,MAAM,oBAAoB,QAAO,iBAAiD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createContext,useContext}from"react";export const AuthoringContext=createContext({variables:[]});export const useAuthoringCatalogs=()=>useContext(AuthoringContext);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ChartView } from '../types';
|
|
2
|
+
import type { Catalog } from '@adcops/autocore-varpick';
|
|
2
3
|
export interface ChartViewDialogProps {
|
|
3
4
|
visible: boolean;
|
|
4
5
|
initial: {
|
|
@@ -9,6 +10,16 @@ export interface ChartViewDialogProps {
|
|
|
9
10
|
onSave: (viewId: string, view: ChartView) => void;
|
|
10
11
|
/** Known field/column names; offered as datalist suggestions. */
|
|
11
12
|
knownKeys: string[];
|
|
13
|
+
/**
|
|
14
|
+
* The same names, grouped and described, for the picker button.
|
|
15
|
+
*
|
|
16
|
+
* Takes the view TYPE because it decides which list is the likely answer:
|
|
17
|
+
* a `raw_trace` plots trace columns, a `cycle_scatter` plots cycle fields.
|
|
18
|
+
* A datalist alone was not enough — it only appears once you start typing,
|
|
19
|
+
* which is no help when you do not know what to type, and it does not open
|
|
20
|
+
* at all on a touchscreen.
|
|
21
|
+
*/
|
|
22
|
+
fieldCatalog?: (viewType: string) => Catalog;
|
|
12
23
|
/** Other view ids already in use — for uniqueness validation. */
|
|
13
24
|
siblingIds: string[];
|
|
14
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartViewDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/ChartViewDialog.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAA0B,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ChartViewDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/ChartViewDialog.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAA0B,SAAS,EAAE,MAAM,UAAU,CAAC;AAElE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAiBxD,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC;IACpD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAClD,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,iEAAiE;IACjE,UAAU,EAAE,MAAM,EAAE,CAAC;CACxB;AAQD,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4K1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useEffect,useState}from"react";import{Dialog}from"primereact/dialog";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{Dropdown}from"primereact/dropdown";import{InputNumber}from"primereact/inputnumber";import{FormRow}from"../../forms/FormRow";import{useEditDraft}from"../../forms/useEditDraft";import{DEFAULT_X_DECIMALS}from"../../tis/TestDataView";const MAX_X_DECIMALS=8,VIEW_TYPES=[{label:"Cycle scatter",value:"cycle_scatter"},{label:"Raw trace",value:"raw_trace"}],Y_AXES=[{label:"Left",value:"left"},{label:"Right",value:"right"}],blank=()=>({title:"",type:"cycle_scatter",x:{field:"",label:""},y:[]});export const ChartViewDialog=({visible:e,initial:t,onCancel:l,onSave:a,knownKeys:i,siblingIds:r})=>{const{draft:
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useEffect,useState}from"react";import{Dialog}from"primereact/dialog";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{Dropdown}from"primereact/dropdown";import{InputNumber}from"primereact/inputnumber";import{FormRow}from"../../forms/FormRow";import{useEditDraft}from"../../forms/useEditDraft";import{DEFAULT_X_DECIMALS}from"../../tis/TestDataView";import{VariableInput}from"../../varpick";const MAX_X_DECIMALS=8,VIEW_TYPES=[{label:"Cycle scatter",value:"cycle_scatter"},{label:"Raw trace",value:"raw_trace"}],Y_AXES=[{label:"Left",value:"left"},{label:"Right",value:"right"}],blank=()=>({title:"",type:"cycle_scatter",x:{field:"",label:""},y:[]});export const ChartViewDialog=({visible:e,initial:t,onCancel:l,onSave:a,knownKeys:i,siblingIds:r,fieldCatalog:n})=>{const{draft:o,setDraft:s,token:c}=useEditDraft(e,t?.viewId??"",()=>({viewId:t?.viewId??"",view:t?JSON.parse(JSON.stringify(t.view)):blank()})),m=o.viewId,d=o.view,u=e=>s(t=>({...t,view:e})),[p,x]=useState(null);useEffect(()=>{x(null)},[c]);const _="raw_trace"===d.type,h=_?"column":"field",v=e=>{u({...d,x:{...d.x,...e}})},f=(e,t)=>{const l=[...d.y];l[e]={...l[e],...t},u({...d,y:l})};return _jsxs(Dialog,{header:t?`Edit view: ${t.viewId}`:"New chart view",visible:e,onHide:l,style:{width:"42rem"},children:[p&&_jsx("div",{style:{color:"#dc2626",marginBottom:"0.5rem"},children:p}),_jsx(FormRow,{label:"View ID",required:!0,hint:"Stable key (e.g. cof_scatter). Cannot collide with other views.",children:_jsx(InputText,{value:m,onChange:e=>{return t=e.target.value,s(e=>({...e,viewId:t}));var t}})}),_jsx(FormRow,{label:"Title",children:_jsx(InputText,{value:d.title??"",onChange:e=>u({...d,title:e.target.value})})}),_jsx(FormRow,{label:"Type",required:!0,children:_jsx(Dropdown,{value:d.type,options:VIEW_TYPES,onChange:e=>u({...d,type:e.value})})}),_jsx(FormRow,{label:_?"X column":"X field",required:!0,children:_jsx(VariableInput,{value:d.x[h]??"",onChange:e=>v({[h]:e}),catalog:()=>n?.(d.type)??[],ariaLabel:"Choose the X axis column",pickerTitle:"X axis",pickerHint:"A chart naming a column that does not exist draws an empty plot with no error, which reads as “the machine recorded nothing”."})}),_jsx(FormRow,{label:"X label",children:_jsx(InputText,{value:d.x.label??"",onChange:e=>v({label:e.target.value})})}),_jsx(FormRow,{label:"X decimals",hint:`Decimal places on X-axis tick labels. Blank uses the default (${DEFAULT_X_DECIMALS}). Display only — stored data keeps full precision.`,children:_jsx(InputNumber,{value:d.x_decimals??null,onValueChange:e=>{const t={...d};null==e.value?delete t.x_decimals:t.x_decimals=e.value,u(t)},min:0,max:8,placeholder:String(DEFAULT_X_DECIMALS),showButtons:!0})}),_jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",margin:"1rem 0 0.5rem"},children:[_jsx("strong",{children:"Y series"}),_jsx(Button,{label:"Add series",icon:"pi pi-plus",size:"small",onClick:()=>{u({...d,y:[...d.y,{[h]:"",label:"",y_axis:"left"}]})}})]}),0===d.y.length&&_jsx("small",{children:"No series — add at least one."}),d.y.map((e,t)=>_jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr 6rem 2rem",gap:"0.5rem",marginBottom:"0.25rem",alignItems:"center"},children:[_jsx(VariableInput,{placeholder:_?"column":"field",value:e[h]??"",onChange:e=>f(t,{[h]:e}),catalog:()=>n?.(d.type)??[],ariaLabel:`Choose the column for series ${t+1}`,pickerTitle:"Y series"}),_jsx(InputText,{placeholder:"label",value:e.label??"",onChange:e=>f(t,{label:e.target.value})}),_jsx(Dropdown,{value:e.y_axis??"left",options:Y_AXES,onChange:e=>f(t,{y_axis:e.value})}),_jsx(Button,{icon:"pi pi-trash",className:"p-button-text p-button-danger p-button-sm",onClick:()=>(e=>{u({...d,y:d.y.filter((t,l)=>l!==e)})})(t),"aria-label":"Remove series"})]},t)),_jsx("datalist",{id:"known-keys",children:i.map(e=>_jsx("option",{value:e},e))}),_jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:"0.5rem",marginTop:"1rem"},children:[_jsx(Button,{label:"Cancel",className:"p-button-text",onClick:l}),_jsx(Button,{label:"Save",onClick:()=>{const e=m.trim()?r.includes(m)&&m!==t?.viewId?`A view named "${m}" already exists.`:null:"View ID is required.";e?x(e):a(m,d)}})]})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldArrayEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/FieldArrayEditor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyBrE,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"FieldArrayEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/FieldArrayEditor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyBrE,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAyH5D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{FormSection}from"../../forms/FormSection";import{TestFieldDialog}from"./TestFieldDialog";const TITLES={project_fields:"Project Fields",config_fields:"Config Fields",cycle_config_fields:"Cycle Configuration Fields",cycle_fields:"Cycle Fields",results_fields:"Results Fields"},DESCRIPTIONS={project_fields:"System-level fields (operator, station). Filled by the HMI but not cycled.",config_fields:"Operator-input config (speeds, loads). Snapshotted into test.json on start.",cycle_config_fields:"Operator-entered annotation recorded onto every cycle row (e.g. which of six positions this is). Shown on the HMI Cycle tab and written as the first Cycle Data columns after the row index. Mark them Required so the machine cannot start unannotated, and Autoclear so the next row cannot inherit a stale value.",cycle_fields:"Per-cycle capture. One row appended to cycles.jsonl per cycle.",results_fields:"Post-test summary (min/max/avg, pass/fail). Written once at finish. A field can also be a cross-test Aggregate (avg/min/max/stddev/count over tests sharing a sample_id)."},aggregateLabel=e=>{const t=e.aggregate;return t?"count"===t.fn?"count":`${t.fn}(${t.of??"?"})`:""};export const FieldArrayEditor=({arrayKey:e,method:t,onChange:
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{FormSection}from"../../forms/FormSection";import{TestFieldDialog}from"./TestFieldDialog";const TITLES={project_fields:"Project Fields",config_fields:"Config Fields",cycle_config_fields:"Cycle Configuration Fields",cycle_fields:"Cycle Fields",results_fields:"Results Fields"},DESCRIPTIONS={project_fields:"System-level fields (operator, station). Filled by the HMI but not cycled.",config_fields:"Operator-input config (speeds, loads). Snapshotted into test.json on start.",cycle_config_fields:"Operator-entered annotation recorded onto every cycle row (e.g. which of six positions this is). Shown on the HMI Cycle tab and written as the first Cycle Data columns after the row index. Mark them Required so the machine cannot start unannotated, and Autoclear so the next row cannot inherit a stale value.",cycle_fields:"Per-cycle capture. One row appended to cycles.jsonl per cycle.",results_fields:"Post-test summary (min/max/avg, pass/fail). Written once at finish. A field can also be a cross-test Aggregate (avg/min/max/stddev/count over tests sharing a sample_id)."},aggregateLabel=e=>{const t=e.aggregate;return t?"count"===t.fn?"count":`${t.fn}(${t.of??"?"})`:""};export const FieldArrayEditor=({arrayKey:e,method:t,onChange:l})=>{const s=t[e]??[],[i,o]=useState(!1),[n,a]=useState(null),r=(i,o)=>{const n=i+o;if(n<0||n>=s.length)return;const a=[...s];[a[i],a[n]]=[a[n],a[i]],l({...t,[e]:a})};return _jsxs(_Fragment,{children:[_jsx(FormSection,{title:TITLES[e],description:DESCRIPTIONS[e],actions:_jsx(Button,{label:"Add field",icon:"pi pi-plus",size:"small",onClick:()=>{a(null),o(!0)}}),children:_jsxs(DataTable,{value:s,dataKey:"name",emptyMessage:"No fields defined.",children:[_jsx(Column,{field:"name",header:"Name"}),_jsx(Column,{field:"type",header:"Type",style:{width:"6rem"}}),_jsx(Column,{field:"units",header:"Units",style:{width:"6rem"}}),_jsx(Column,{header:"Req",body:e=>e.required?"✓":"",style:{width:"4rem"}}),_jsx(Column,{field:"label",header:"Label"}),"results_fields"===e&&_jsx(Column,{header:"Aggregate",body:e=>aggregateLabel(e),style:{width:"8rem"}}),"cycle_config_fields"===e&&_jsx(Column,{header:"Autoclear",body:e=>e.autoclear?"✓":"",style:{width:"6rem"}}),_jsx(Column,{header:"",body:(i,n)=>_jsxs("div",{style:{display:"flex",gap:"0.25rem"},children:[_jsx(Button,{icon:"pi pi-arrow-up",className:"p-button-text p-button-sm",disabled:0===n.rowIndex,onClick:()=>r(n.rowIndex,-1),"aria-label":"Move up"}),_jsx(Button,{icon:"pi pi-arrow-down",className:"p-button-text p-button-sm",disabled:n.rowIndex===s.length-1,onClick:()=>r(n.rowIndex,1),"aria-label":"Move down"}),_jsx(Button,{icon:"pi pi-pencil",className:"p-button-text p-button-sm",onClick:()=>{return e=n.rowIndex,a(e),void o(!0);var e},"aria-label":"Edit"}),_jsx(Button,{icon:"pi pi-trash",className:"p-button-text p-button-danger p-button-sm",onClick:()=>(i=>{const o=s[i];if(!o)return;if(!window.confirm(`Remove field "${o.name}"?`))return;const n=s.filter((e,t)=>t!==i);l({...t,[e]:n})})(n.rowIndex),"aria-label":"Remove"})]}),style:{width:"10rem"}})]})}),_jsx(TestFieldDialog,{visible:i,initial:null!==n?s[n]??null:null,siblingNames:s.map(e=>e.name),isResultsField:"results_fields"===e,isCycleConfigField:"cycle_config_fields"===e,isCycleField:"cycle_fields"===e,cycleFieldNames:(t.cycle_fields??[]).map(e=>e.name).filter(Boolean),resultsFieldNames:(t.results_fields??[]).map(e=>e.name).filter(Boolean),onCancel:()=>o(!1),onSave:i=>{const a=[...s];null===n?a.push(i):a[n]=i,l({...t,[e]:a}),o(!1)}})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RawDataEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/RawDataEditor.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"RawDataEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/RawDataEditor.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,UAAU,CAAC;AAGpE,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAID,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA0GtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{InputText}from"primereact/inputtext";import{Button}from"primereact/button";import{Checkbox}from"primereact/checkbox";import{FormSection}from"../../forms/FormSection";import{FormRow}from"../../forms/FormRow";const emptyRawData=()=>({blob_name:"trace",columns:{}});export const RawDataEditor=({method:e,onChange:
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{InputText}from"primereact/inputtext";import{Button}from"primereact/button";import{Checkbox}from"primereact/checkbox";import{FormSection}from"../../forms/FormSection";import{FormRow}from"../../forms/FormRow";import{VariableInput,rawSourceCatalog}from"../../varpick";const emptyRawData=()=>({blob_name:"trace",columns:{}});export const RawDataEditor=({method:e,onChange:o})=>{const n=e.raw_data,t=!!n,r=n=>{o({...e,raw_data:n})},a=(e,o)=>{n&&r({...n,columns:{...n.columns,[e]:o}})};return _jsxs(FormSection,{title:"Raw Data",description:"Columnar blob shape captured per cycle under raw_data/. Required only when the method records DAQ traces.",actions:_jsx(Checkbox,{checked:t,onChange:e=>r(e.checked?emptyRawData():null)}),children:[!t&&_jsx("small",{children:"Raw data capture disabled. Tick the box above to enable."}),t&&n&&_jsxs(_Fragment,{children:[_jsx(FormRow,{label:"Blob name",required:!0,hint:"Base filename under raw_data/, no extension.",children:_jsx(InputText,{value:n.blob_name,onChange:e=>r({...n,blob_name:e.target.value})})}),_jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:"0.75rem"},children:[_jsx("strong",{children:"Columns"}),_jsx(Button,{label:"Add column",icon:"pi pi-plus",size:"small",onClick:()=>{if(!n)return;let e="column",o=1;for(;n.columns[`${e}${o}`];)o++;r({...n,columns:{...n.columns,[`${e}${o}`]:{source:"time"}}})}})]}),0===Object.keys(n.columns).length&&_jsx("small",{children:"No columns defined."}),Object.entries(n.columns).map(([e,o])=>_jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1.5fr 1.5fr 2rem",gap:"0.5rem",marginTop:"0.25rem",alignItems:"center"},children:[_jsx(InputText,{placeholder:"column name",defaultValue:e,onBlur:o=>((e,o)=>{if(!n||!o.trim()||o===e)return;if(n.columns[o])return;const t={...n.columns};t[o]=t[e],delete t[e],r({...n,columns:t})})(e,o.target.value.trim())}),_jsx(VariableInput,{placeholder:"source (time / ni.<daq>.channels.<name> / derived)",value:o.source,onChange:n=>a(e,{...o,source:n}),catalog:()=>rawSourceCatalog(),ariaLabel:`Choose the source for column ${e}`,pickerTitle:"Column source",pickerHint:"A DAQ channel is named ni.<daq>.channels.<name> and is not listed here — the editor has no channel catalog, so type it."}),_jsx(InputText,{placeholder:"formula (only when source=derived)",value:o.formula??"",onChange:n=>a(e,{...o,formula:n.target.value||void 0}),disabled:"derived"!==o.source}),_jsx(Button,{icon:"pi pi-trash",className:"p-button-text p-button-danger p-button-sm",onClick:()=>(e=>{if(!n)return;if(!window.confirm(`Remove column "${e}"?`))return;const o={...n.columns};delete o[e],r({...n,columns:o})})(e),"aria-label":"Remove column"})]},e))]})]})};
|
|
@@ -15,6 +15,13 @@ export interface TestFieldDialogProps {
|
|
|
15
15
|
/** Candidate target field names for an aggregate's `of`, by source. */
|
|
16
16
|
cycleFieldNames?: string[];
|
|
17
17
|
resultsFieldNames?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* True when this field belongs to `cycle_fields`. Only there does Source
|
|
20
|
+
* have two possible producers — a GM tag read at record time, or the
|
|
21
|
+
* sequence storing a value under this column's NAME — so only there is the
|
|
22
|
+
* picker a producer picker rather than a variable list.
|
|
23
|
+
*/
|
|
24
|
+
isCycleField?: boolean;
|
|
18
25
|
}
|
|
19
26
|
export declare const TestFieldDialog: React.FC<TestFieldDialogProps>;
|
|
20
27
|
//# sourceMappingURL=TestFieldDialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestFieldDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/TestFieldDialog.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAA2C,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"TestFieldDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/TestFieldDialog.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAA2C,MAAM,UAAU,CAAC;AAqDnF,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,8EAA8E;IAC9E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;8CAC0C;IAC1C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;0EACsE;IACtE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA+W1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";import{useContext,useEffect,useMemo,useState}from"react";import{Dialog}from"primereact/dialog";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{InputTextarea}from"primereact/inputtextarea";import{Dropdown}from"primereact/dropdown";import{Checkbox}from"primereact/checkbox";import{InputNumber}from"primereact/inputnumber";import{FormRow}from"../../forms/FormRow";import{useEditDraft}from"../../forms/useEditDraft";import{boundText,parseBound,boundInvalid}from"../../tis/TestFieldRow";import{AutoCoreTagContext}from"../../../core/AutoCoreTagContext";const FIELD_TYPES=[{label:"string",value:"string"},{label:"i32",value:"i32"},{label:"i64",value:"i64"},{label:"u32",value:"u32"},{label:"u64",value:"u64"},{label:"f32",value:"f32"},{label:"f64",value:"f64"},{label:"bool",value:"bool"}],AGG_FNS=[{label:"— none (analysis-fed) —",value:""},{label:"avg",value:"avg"},{label:"min",value:"min"},{label:"max",value:"max"},{label:"stddev",value:"stddev"},{label:"count (how many went into the rollup)",value:"count"}],AGG_FROMS=[{label:"cycle field (every cycle, every test)",value:"cycle_fields"},{label:"result (one value per test)",value:"results"}],COUNT_CHOICES=[{label:"cycles in this test",value:"test_cycles",scope:"test",from:"cycle_fields"},{label:"cycles for this sample, all tests",value:"project_cycles",scope:"project",from:"cycle_fields"},{label:"tests for this sample",value:"project_tests",scope:"project",from:"results"}],AGG_SCOPES=[{label:"this test only",value:"test"},{label:"this sample, every test in the project",value:"project"}],blank={name:"",type:"f32"};export const TestFieldDialog=({visible:e,initial:t,onCancel:a,onSave:o,siblingNames:l,isResultsField:r=!1,isCycleConfigField:n=!1,cycleFieldNames:i=[],resultsFieldNames:s=[]})=>{const{draft:u,setDraft:d,token:c}=useEditDraft(e,t?.name??"",()=>({field:t?{...t}:{...blank},defaultText:null==t?.default?"":String(t.default)})),m=u.field,h=u.defaultText,p=e=>d(t=>({...t,field:e})),[f,g]=useState(null);useEffect(()=>{g(null)},[c]);const{scales:v}=useContext(AutoCoreTagContext),b=useMemo(()=>Object.keys(v??{}).sort().map(e=>({label:e,value:e})),[v]),x=m.aggregate,_=x?.from??"cycle_fields",y=x?.scope??"test",j=COUNT_CHOICES.find(e=>e.scope===y&&e.from===_)?.value??"test_cycles",w=("results"===_?s:i).filter(e=>e&&e!==m.name).map(e=>({label:e,value:e}));return _jsxs(Dialog,{header:t?`Edit field: ${t.name}`:"New field",visible:e,onHide:a,style:{width:"36rem"},children:[f&&_jsx("div",{style:{color:"#dc2626",marginBottom:"0.75rem"},children:f}),_jsx(FormRow,{label:"Name",required:!0,hint:"Wire-format key. Also the column name in CSV exports.",children:_jsx(InputText,{value:m.name,onChange:e=>p({...m,name:e.target.value})})}),_jsx(FormRow,{label:"Type",required:!0,children:_jsx(Dropdown,{value:m.type,options:FIELD_TYPES,onChange:e=>p({...m,type:e.value}),editable:!0})}),_jsx(FormRow,{label:"Quantity",hint:"Ties this field to a row of the machine's units.json, so it follows the operator's Metric/Imperial choice and takes its unit label from the active system. Set this in preference to Units/Scale, which are fixed.",children:_jsx(Dropdown,{value:m.quantity??"",options:b,onChange:e=>p({...m,quantity:e.value||void 0}),placeholder:"— none (fixed Units/Scale below) —",showClear:!0,editable:!0})}),_jsx(FormRow,{label:"Units",hint:"Fixed display label appended to form labels (e.g. m/s). Ignored when Quantity is set — the active unit system supplies the label.",children:_jsx(InputText,{value:m.units??"",onChange:e=>p({...m,units:e.target.value||void 0})})}),_jsx(FormRow,{label:"Label",hint:"Pretty form label. Falls back to name when empty.",children:_jsx(InputText,{value:m.label??"",onChange:e=>p({...m,label:e.target.value||void 0})})}),_jsx(FormRow,{label:"Required",hint:n?"Blocks the machine until the operator fills this in — tis.cycle_ready stays false and start_test is refused. This is what stops an unannotated row from being recorded.":void 0,children:_jsx(Checkbox,{checked:!!m.required,onChange:e=>p({...m,required:!!e.checked})})}),n&&_jsx(FormRow,{label:"Autoclear",hint:"Clear the operator's entry once a row has recorded it, so the next row can't inherit a stale value. Fires after each cycle under 'cycle' scope, at the end of the run under 'run' scope. Pair with Required — on its own it turns stale data into silently missing data.",children:_jsx(Checkbox,{checked:!!m.autoclear,onChange:e=>p({...m,autoclear:!!e.checked})})}),_jsx(FormRow,{label:"Source",hint:"Optional gm.* variable to bind this field to.",children:_jsx(InputText,{value:m.source??"",onChange:e=>p({...m,source:e.target.value||void 0}),placeholder:"gm.<variable_name>"})}),_jsx(FormRow,{label:"Scale",hint:"display = raw × scale. Leave blank for 1.0 (no conversion).",children:_jsx(InputNumber,{value:m.scale??null,onValueChange:e=>p({...m,scale:"number"==typeof e.value?e.value:void 0}),mode:"decimal",minFractionDigits:0,maxFractionDigits:9})}),_jsx(FormRow,{label:"Min",hint:"Optional lower bound the operator can enter (display units). Blank = no minimum. Or bind it to the machine with an FQDN token like ${gm.press_force_min_n} — for a bound that moves, e.g. a load-cell force ceiling.",children:_jsx(InputText,{value:boundText(m.min),onChange:e=>p({...m,min:parseBound(e.target.value)}),className:boundInvalid(m.min)?"p-invalid":"",placeholder:"number or ${gm.…}"})}),_jsx(FormRow,{label:"Max",hint:"Optional upper bound the operator can enter (display units). Blank = no maximum. Or bind it to the machine with an FQDN token like ${gm.press_force_max_n}.",children:_jsx(InputText,{value:boundText(m.max),onChange:e=>p({...m,max:parseBound(e.target.value)}),className:boundInvalid(m.max)?"p-invalid":"",placeholder:"number or ${gm.…}"})}),_jsx(FormRow,{label:"Default",hint:"Applied every time the method loads (operator can override). A literal (display units) like 5, or an FQDN token like ${gm.safe_speed} that snapshots that value on load.",children:_jsx(InputText,{value:h,onChange:e=>(e=>d(t=>({...t,defaultText:e})))(e.target.value),placeholder:"e.g. 5 or ${gm.safe_speed}"})}),r&&_jsxs(_Fragment,{children:[_jsx("div",{style:{borderTop:"1px solid #e5e7eb",margin:"0.75rem 0 0.25rem"}}),_jsx(FormRow,{label:"Aggregate",hint:"Cross-test rollup. When set, this result is derived server-side over the non-excluded tests sharing the same sample_id — the analysis script does not supply it.",children:_jsx(Dropdown,{value:x?.fn??"",options:AGG_FNS,onChange:e=>(e=>{if(""===e)return void p({...m,aggregate:void 0});if("count"===e)return void p({...m,aggregate:{fn:"count",from:m.aggregate?.from??"cycle_fields",scope:m.aggregate?.scope??"test"}});const t={fn:e,of:m.aggregate?.of,from:m.aggregate?.from??"cycle_fields",scope:m.aggregate?.scope??"test"};p({...m,aggregate:t})})(e.value)})}),x&&"count"===x.fn&&_jsx(FormRow,{label:"Count",hint:"What is being counted. A test's own cycles is the usual choice — it's the number the operator can see in the Cycle Data table.",children:_jsx(Dropdown,{value:j,options:COUNT_CHOICES,onChange:e=>{const t=COUNT_CHOICES.find(t=>t.value===e.value);t&&p({...m,aggregate:{...x,scope:t.scope,from:t.from}})}})}),x&&"count"!==x.fn&&_jsxs(_Fragment,{children:[_jsx(FormRow,{label:"Scope",hint:"How wide the reduction reaches. 'This test only' is the default: a value on a test's own results panel or report describes that test.",children:_jsx(Dropdown,{value:y,options:AGG_SCOPES,onChange:e=>p({...m,aggregate:{...x,scope:e.value}})})}),_jsx(FormRow,{label:"Aggregate from",hint:"Which per-test source the target field is read from.",children:_jsx(Dropdown,{value:_,options:AGG_FROMS,onChange:e=>p({...m,aggregate:{...x,from:e.value}})})}),_jsx(FormRow,{label:"Aggregate of",required:!0,hint:"The field to reduce across tests.",children:_jsx(Dropdown,{value:x.of??null,options:w,onChange:e=>p({...m,aggregate:{...x,of:e.value||void 0}}),editable:!0,placeholder:w.length?"Select a field":`No ${_} defined yet`})})]})]}),_jsx(FormRow,{label:"Description",hint:"Hover tooltip in the form.",children:_jsx(InputTextarea,{rows:2,value:m.description??"",onChange:e=>p({...m,description:e.target.value||void 0})})}),_jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:"0.5rem",marginTop:"1rem"},children:[_jsx(Button,{label:"Cancel",className:"p-button-text",onClick:a}),_jsx(Button,{label:"Save",onClick:()=>{const e={...m},a=(e=>{const t=e.trim();if(""!==t){if(t.startsWith("${"))return t;if("true"===t)return!0;if("false"===t)return!1;if(/^-?\d*\.?\d+$/.test(t)){const e=Number(t);if(Number.isFinite(e))return e}return t}})(h);void 0===a?delete e.default:e.default=a;const r=(e=>{if(!e.name.trim())return"Field name is required.";if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e.name))return"Name must be a valid identifier (letters, digits, underscore; cannot start with a digit).";if(l.some(a=>a===e.name&&a!==t?.name))return`A field named "${e.name}" already exists in this array.`;if("number"==typeof e.min&&"number"==typeof e.max&&e.min>e.max)return`Min (${e.min}) cannot be greater than Max (${e.max}).`;for(const t of["min","max"])if(boundInvalid(e[t]))return`${"min"===t?"Min":"Max"} must be a number or an FQDN token like \${gm.some_var} — "${e[t]}" is neither.`;return e.aggregate&&"count"!==e.aggregate.fn&&!e.aggregate.of?.trim()?`Aggregate "${e.aggregate.fn}" needs a target field (the field to ${e.aggregate.fn} across tests).`:null})(e);r?g(r):o(e)}})]})]})};
|
|
1
|
+
import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";import{useContext,useEffect,useMemo,useState}from"react";import{Dialog}from"primereact/dialog";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{InputTextarea}from"primereact/inputtextarea";import{Dropdown}from"primereact/dropdown";import{Checkbox}from"primereact/checkbox";import{InputNumber}from"primereact/inputnumber";import{FormRow}from"../../forms/FormRow";import{useEditDraft}from"../../forms/useEditDraft";import{boundText,parseBound,boundInvalid}from"../../tis/TestFieldRow";import{AutoCoreTagContext}from"../../../core/AutoCoreTagContext";import{VariableInput}from"../../varpick";import{boundCatalog,configSourceCatalog,cycleSourceCatalog}from"../../varpick";import{useAuthoringCatalogs}from"./AuthoringContext";const FIELD_TYPES=[{label:"string",value:"string"},{label:"i32",value:"i32"},{label:"i64",value:"i64"},{label:"u32",value:"u32"},{label:"u64",value:"u64"},{label:"f32",value:"f32"},{label:"f64",value:"f64"},{label:"bool",value:"bool"}],AGG_FNS=[{label:"— none (analysis-fed) —",value:""},{label:"avg",value:"avg"},{label:"min",value:"min"},{label:"max",value:"max"},{label:"stddev",value:"stddev"},{label:"count (how many went into the rollup)",value:"count"}],AGG_FROMS=[{label:"cycle field (every cycle, every test)",value:"cycle_fields"},{label:"result (one value per test)",value:"results"}],COUNT_CHOICES=[{label:"cycles in this test",value:"test_cycles",scope:"test",from:"cycle_fields"},{label:"cycles for this sample, all tests",value:"project_cycles",scope:"project",from:"cycle_fields"},{label:"tests for this sample",value:"project_tests",scope:"project",from:"results"}],AGG_SCOPES=[{label:"this test only",value:"test"},{label:"this sample, every test in the project",value:"project"}],blank={name:"",type:"f32"};export const TestFieldDialog=({visible:e,initial:t,onCancel:a,onSave:o,siblingNames:l,isResultsField:r=!1,isCycleConfigField:i=!1,isCycleField:n=!1,cycleFieldNames:s=[],resultsFieldNames:c=[]})=>{const{variables:u,producedNames:d}=useAuthoringCatalogs(),{draft:m,setDraft:h,token:p}=useEditDraft(e,t?.name??"",()=>({field:t?{...t}:{...blank},defaultText:null==t?.default?"":String(t.default)})),g=m.field,f=m.defaultText,b=e=>h(t=>({...t,field:e})),[v,x]=useState(null);useEffect(()=>{x(null)},[p]);const{scales:_}=useContext(AutoCoreTagContext),y=useMemo(()=>Object.keys(_??{}).sort().map(e=>({label:e,value:e})),[_]),w=useMemo(()=>({variables:u,unitFor:e=>_?.[e]?.label}),[u,_]),C=g.aggregate,j=C?.from??"cycle_fields",F=C?.scope??"test",k=COUNT_CHOICES.find(e=>e.scope===F&&e.from===j)?.value??"test_cycles",T=("results"===j?c:s).filter(e=>e&&e!==g.name).map(e=>({label:e,value:e}));return _jsxs(Dialog,{header:t?`Edit field: ${t.name}`:"New field",visible:e,onHide:a,style:{width:"36rem"},children:[v&&_jsx("div",{style:{color:"#dc2626",marginBottom:"0.75rem"},children:v}),_jsx(FormRow,{label:"Name",required:!0,hint:"Wire-format key. Also the column name in CSV exports.",children:_jsx(InputText,{value:g.name,onChange:e=>b({...g,name:e.target.value})})}),_jsx(FormRow,{label:"Type",required:!0,children:_jsx(Dropdown,{value:g.type,options:FIELD_TYPES,onChange:e=>b({...g,type:e.value}),editable:!0})}),_jsx(FormRow,{label:"Quantity",hint:"Ties this field to a row of the machine's units.json, so it follows the operator's Metric/Imperial choice and takes its unit label from the active system. Set this in preference to Units/Scale, which are fixed.",children:_jsx(Dropdown,{value:g.quantity??"",options:y,onChange:e=>b({...g,quantity:e.value||void 0}),placeholder:"— none (fixed Units/Scale below) —",showClear:!0,editable:!0})}),_jsx(FormRow,{label:"Units",hint:"Fixed display label appended to form labels (e.g. m/s). Ignored when Quantity is set — the active unit system supplies the label.",children:_jsx(InputText,{value:g.units??"",onChange:e=>b({...g,units:e.target.value||void 0})})}),_jsx(FormRow,{label:"Label",hint:"Pretty form label. Falls back to name when empty.",children:_jsx(InputText,{value:g.label??"",onChange:e=>b({...g,label:e.target.value||void 0})})}),_jsx(FormRow,{label:"Required",hint:i?"Blocks the machine until the operator fills this in — tis.cycle_ready stays false and start_test is refused. This is what stops an unannotated row from being recorded.":void 0,children:_jsx(Checkbox,{checked:!!g.required,onChange:e=>b({...g,required:!!e.checked})})}),i&&_jsx(FormRow,{label:"Autoclear",hint:"Clear the operator's entry once a row has recorded it, so the next row can't inherit a stale value. Fires after each cycle under 'cycle' scope, at the end of the run under 'run' scope. Pair with Required — on its own it turns stale data into silently missing data.",children:_jsx(Checkbox,{checked:!!g.autoclear,onChange:e=>b({...g,autoclear:!!e.checked})})}),_jsx(FormRow,{label:"Source",hint:n?"Where this column’s value comes from. Leave empty when the sequence records it — a store_value step is matched to this column by NAME, not by a binding.":"Optional gm.* variable this field reads and writes.",children:_jsx(VariableInput,{value:g.source??"",onChange:e=>b({...g,source:e||void 0}),catalog:()=>n?cycleSourceCatalog(w,{producedNames:d,fieldName:g.name}):configSourceCatalog(w),ariaLabel:"Choose a source for this field",pickerTitle:"Where does this value come from?",pickerHint:n?"A column filled by the sequence needs no Source — choosing one below clears it, which is correct.":"The Test Setup form writes the operator’s entry to this variable, so only variables a UI may write are listed.",placeholder:"gm.<variable_name>"})}),_jsx(FormRow,{label:"Scale",hint:"display = raw × scale. Leave blank for 1.0 (no conversion).",children:_jsx(InputNumber,{value:g.scale??null,onValueChange:e=>b({...g,scale:"number"==typeof e.value?e.value:void 0}),mode:"decimal",minFractionDigits:0,maxFractionDigits:9})}),_jsx(FormRow,{label:"Min",hint:"Optional lower bound the operator can enter (display units). Blank = no minimum. Or bind it to the machine with an FQDN token like ${gm.press_force_min_n} — for a bound that moves, e.g. a load-cell force ceiling.",children:_jsx(VariableInput,{value:boundText(g.min),onChange:e=>b({...g,min:parseBound(e)}),invalid:boundInvalid(g.min),catalog:()=>boundCatalog(w),ariaLabel:"Bind Min to a machine variable",pickerTitle:"Bind Min to a machine value",pickerHint:"The bound then follows the machine — a load-cell ceiling that changes with the fitted cell, rather than a number that goes stale.",placeholder:"number or ${gm.…}"})}),_jsx(FormRow,{label:"Max",hint:"Optional upper bound the operator can enter (display units). Blank = no maximum. Or bind it to the machine with an FQDN token like ${gm.press_force_max_n}.",children:_jsx(VariableInput,{value:boundText(g.max),onChange:e=>b({...g,max:parseBound(e)}),invalid:boundInvalid(g.max),catalog:()=>boundCatalog(w),ariaLabel:"Bind Max to a machine variable",pickerTitle:"Bind Max to a machine value",pickerHint:"The bound then follows the machine — a load-cell ceiling that changes with the fitted cell, rather than a number that goes stale.",placeholder:"number or ${gm.…}"})}),_jsx(FormRow,{label:"Default",hint:"Applied every time the method loads (operator can override). A literal (display units) like 5, or an FQDN token like ${gm.safe_speed} that snapshots that value on load.",children:_jsx(VariableInput,{value:f,onChange:e=>h(t=>({...t,defaultText:e})),catalog:()=>boundCatalog(w),ariaLabel:"Use a machine variable as the default",pickerTitle:"Default from a machine value",pickerHint:"A token default SNAPSHOTS the value when the method loads. It is not a live binding — that is what Source is.",placeholder:"e.g. 5 or ${gm.safe_speed}"})}),r&&_jsxs(_Fragment,{children:[_jsx("div",{style:{borderTop:"1px solid #e5e7eb",margin:"0.75rem 0 0.25rem"}}),_jsx(FormRow,{label:"Aggregate",hint:"Cross-test rollup. When set, this result is derived server-side over the non-excluded tests sharing the same sample_id — the analysis script does not supply it.",children:_jsx(Dropdown,{value:C?.fn??"",options:AGG_FNS,onChange:e=>(e=>{if(""===e)return void b({...g,aggregate:void 0});if("count"===e)return void b({...g,aggregate:{fn:"count",from:g.aggregate?.from??"cycle_fields",scope:g.aggregate?.scope??"test"}});const t={fn:e,of:g.aggregate?.of,from:g.aggregate?.from??"cycle_fields",scope:g.aggregate?.scope??"test"};b({...g,aggregate:t})})(e.value)})}),C&&"count"===C.fn&&_jsx(FormRow,{label:"Count",hint:"What is being counted. A test's own cycles is the usual choice — it's the number the operator can see in the Cycle Data table.",children:_jsx(Dropdown,{value:k,options:COUNT_CHOICES,onChange:e=>{const t=COUNT_CHOICES.find(t=>t.value===e.value);t&&b({...g,aggregate:{...C,scope:t.scope,from:t.from}})}})}),C&&"count"!==C.fn&&_jsxs(_Fragment,{children:[_jsx(FormRow,{label:"Scope",hint:"How wide the reduction reaches. 'This test only' is the default: a value on a test's own results panel or report describes that test.",children:_jsx(Dropdown,{value:F,options:AGG_SCOPES,onChange:e=>b({...g,aggregate:{...C,scope:e.value}})})}),_jsx(FormRow,{label:"Aggregate from",hint:"Which per-test source the target field is read from.",children:_jsx(Dropdown,{value:j,options:AGG_FROMS,onChange:e=>b({...g,aggregate:{...C,from:e.value}})})}),_jsx(FormRow,{label:"Aggregate of",required:!0,hint:"The field to reduce across tests.",children:_jsx(Dropdown,{value:C.of??null,options:T,onChange:e=>b({...g,aggregate:{...C,of:e.value||void 0}}),editable:!0,placeholder:T.length?"Select a field":`No ${j} defined yet`})})]})]}),_jsx(FormRow,{label:"Description",hint:"Hover tooltip in the form.",children:_jsx(InputTextarea,{rows:2,value:g.description??"",onChange:e=>b({...g,description:e.target.value||void 0})})}),_jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:"0.5rem",marginTop:"1rem"},children:[_jsx(Button,{label:"Cancel",className:"p-button-text",onClick:a}),_jsx(Button,{label:"Save",onClick:()=>{const e={...g},a=(e=>{const t=e.trim();if(""!==t){if(t.startsWith("${"))return t;if("true"===t)return!0;if("false"===t)return!1;if(/^-?\d*\.?\d+$/.test(t)){const e=Number(t);if(Number.isFinite(e))return e}return t}})(f);void 0===a?delete e.default:e.default=a;const r=(e=>{if(!e.name.trim())return"Field name is required.";if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e.name))return"Name must be a valid identifier (letters, digits, underscore; cannot start with a digit).";if(l.some(a=>a===e.name&&a!==t?.name))return`A field named "${e.name}" already exists in this array.`;if("number"==typeof e.min&&"number"==typeof e.max&&e.min>e.max)return`Min (${e.min}) cannot be greater than Max (${e.max}).`;for(const t of["min","max"])if(boundInvalid(e[t]))return`${"min"===t?"Min":"Max"} must be a number or an FQDN token like \${gm.some_var} — "${e[t]}" is neither.`;return e.aggregate&&"count"!==e.aggregate.fn&&!e.aggregate.of?.trim()?`Aggregate "${e.aggregate.fn}" needs a target field (the field to ${e.aggregate.fn} across tests).`:null})(e);r?x(r):o(e)}})]})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewsEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/ViewsEditor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ViewsEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/tis-editor/editor/ViewsEditor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,UAAU,CAAC;AAIjE,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAQD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAwIlD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{FormSection}from"../../forms/FormSection";import{moveView,orderedViews}from"../../tis/chartViews";import{ChartViewDialog}from"./ChartViewDialog";export const ViewsEditor=({method:e,onChange:t})=>{const i=e.views??{},
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{FormSection}from"../../forms/FormSection";import{moveView,orderedViews}from"../../tis/chartViews";import{ChartViewDialog}from"./ChartViewDialog";import{chartFieldCatalog}from"../../varpick";export const ViewsEditor=({method:e,onChange:t})=>{const i=e.views??{},a=orderedViews(i).map(({name:e,view:t})=>({id:e,title:t.title??"",type:t.type??""})),[o,s]=useState(!1),[n,l]=useState(null),r=[...(e.project_fields??[]).map(e=>e.name),...(e.config_fields??[]).map(e=>e.name),...(e.cycle_config_fields??[]).map(e=>e.name),...(e.cycle_fields??[]).map(e=>e.name),...(e.results_fields??[]).map(e=>e.name),...Object.keys(e.raw_data?.columns??{}),"cycle_index","timestamp"],m=(a,o)=>{const s=moveView(i,a,o);s!==i&&t({...e,views:s})};return _jsxs(_Fragment,{children:[_jsx(FormSection,{title:"Views",description:"Named chart definitions rendered by <TestDataView> (cycle_scatter) and <TestRawDataView> (raw_trace). Top to bottom is the order the operator sees in the view picker, and the first one is the chart the Data tab opens on.",actions:_jsx(Button,{label:"Add view",icon:"pi pi-plus",size:"small",onClick:()=>{l(null),s(!0)}}),children:_jsxs(DataTable,{value:a,dataKey:"id",emptyMessage:"No views defined.",children:[_jsx(Column,{field:"id",header:"View ID"}),_jsx(Column,{field:"title",header:"Title"}),_jsx(Column,{field:"type",header:"Type",style:{width:"8rem"}}),_jsx(Column,{header:"",body:(o,n)=>_jsxs("div",{style:{display:"flex",gap:"0.25rem"},children:[_jsx(Button,{icon:"pi pi-arrow-up",className:"p-button-text p-button-sm",disabled:0===n.rowIndex,onClick:()=>m(n.rowIndex,-1),"aria-label":"Move up"}),_jsx(Button,{icon:"pi pi-arrow-down",className:"p-button-text p-button-sm",disabled:n.rowIndex===a.length-1,onClick:()=>m(n.rowIndex,1),"aria-label":"Move down"}),_jsx(Button,{icon:"pi pi-pencil",className:"p-button-text p-button-sm",onClick:()=>{return e=o.id,l(e),void s(!0);var e},"aria-label":"Edit"}),_jsx(Button,{icon:"pi pi-trash",className:"p-button-text p-button-danger p-button-sm",onClick:()=>(a=>{if(!window.confirm(`Remove view "${a}"?`))return;const o={...i};delete o[a],t({...e,views:o})})(o.id),"aria-label":"Remove"})]}),style:{width:"10rem"}})]})}),_jsx(ChartViewDialog,{visible:o,initial:n?{viewId:n,view:i[n]}:null,knownKeys:r,fieldCatalog:t=>chartFieldCatalog({viewType:t,cycleFields:[...(e.cycle_config_fields??[]).map(e=>e.name),...(e.cycle_fields??[]).map(e=>e.name),"cycle_index","timestamp"].filter(Boolean),resultsFields:(e.results_fields??[]).map(e=>e.name).filter(Boolean),rawColumns:Object.keys(e.raw_data?.columns??{}),testFields:[...(e.project_fields??[]).map(e=>e.name),...(e.config_fields??[]).map(e=>e.name)].filter(Boolean)}),siblingIds:Object.keys(i),onCancel:()=>s(!1),onSave:(a,o)=>{const l={...i};n&&n!==a&&delete l[n],l[a]=o,t({...e,views:l}),s(!1)}})]})};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VariableInput — a text input with a picker button.
|
|
3
|
+
*
|
|
4
|
+
* A drop-in replacement for the `<InputText>` inside a `FormRow`, so adding a
|
|
5
|
+
* picker to a field is a one-line change and the field keeps its label, hint and
|
|
6
|
+
* error handling.
|
|
7
|
+
*
|
|
8
|
+
* Typing still works exactly as before. That is the point: an author who knows
|
|
9
|
+
* the name types it, and an author who does not gets a list instead of a guess.
|
|
10
|
+
*/
|
|
11
|
+
import * as React from 'react';
|
|
12
|
+
import { type Catalog, type InsertMode } from '@adcops/autocore-varpick';
|
|
13
|
+
import './varpick.css';
|
|
14
|
+
export interface VariableInputProps {
|
|
15
|
+
value: string;
|
|
16
|
+
onChange: (value: string) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Built when the dialog opens, not on every render — a machine's variable
|
|
19
|
+
* table is ~100 rows and this sits inside a dialog that re-renders on live
|
|
20
|
+
* tag traffic.
|
|
21
|
+
*/
|
|
22
|
+
catalog: () => Catalog;
|
|
23
|
+
/**
|
|
24
|
+
* `replace` when the whole field IS one binding (a `source`, a bound);
|
|
25
|
+
* `caret` when the field is an expression and the pick is one term of it.
|
|
26
|
+
* Defaults to `replace`, which is what every TIS field is.
|
|
27
|
+
*/
|
|
28
|
+
mode?: InsertMode;
|
|
29
|
+
/** Dialog heading and the line under it. */
|
|
30
|
+
pickerTitle?: string;
|
|
31
|
+
pickerHint?: React.ReactNode;
|
|
32
|
+
/** Accessible name for the button — it is icon-only, so this is required. */
|
|
33
|
+
ariaLabel: string;
|
|
34
|
+
placeholder?: string;
|
|
35
|
+
className?: string;
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
invalid?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export declare const VariableInput: React.FC<VariableInputProps>;
|
|
40
|
+
export default VariableInput;
|
|
41
|
+
//# sourceMappingURL=VariableInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariableInput.d.ts","sourceRoot":"","sources":["../../../src/components/varpick/VariableInput.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAGH,KAAK,OAAO,EACZ,KAAK,UAAU,EAElB,MAAM,0BAA0B,CAAC;AAElC,OAAO,eAAe,CAAC;AAEvB,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyEtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import*as React from"react";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{applyInsert,queryFromCaret}from"@adcops/autocore-varpick";import{VariablePicker}from"./VariablePicker";import"./varpick.css";export const VariableInput=({value:e,onChange:t,catalog:a,mode:r="replace",pickerTitle:n,pickerHint:c,ariaLabel:i,placeholder:s,className:l,disabled:o,invalid:u})=>{const p=React.useRef(null),m=React.useRef({start:0,end:0}),[d,b]=React.useState(!1),[x,v]=React.useState([]),f=()=>{const e=p.current;e&&(m.current={start:e.selectionStart??e.value.length,end:e.selectionEnd??e.value.length})};return _jsxs("div",{className:"ac-varpick__input",children:[_jsx(InputText,{ref:p,value:e,placeholder:s,disabled:o,className:`${l??""}${u?" p-invalid":""}`,onChange:e=>t(e.target.value),onSelect:f,onFocus:f}),_jsx(Button,{type:"button",icon:"pi pi-list","aria-label":i,disabled:o,className:"p-button-outlined",onClick:()=>{v(a()),b(!0)}}),d&&_jsx(VariablePicker,{visible:!0,catalog:x,title:n,hint:c,initialQuery:"caret"===r?queryFromCaret(e,m.current.start,m.current.end):"",onCancel:()=>b(!1),onPick:a=>{const{start:n,end:c}=m.current,i=applyInsert(e,a,r,n,c);t(i.value),b(!1),requestAnimationFrame(()=>{const e=p.current;e&&(e.focus(),e.setSelectionRange(i.caret,i.caret),m.current={start:i.caret,end:i.caret})})}})]})};export default VariableInput;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VariablePicker — a searchable, described list of the machine's variables.
|
|
3
|
+
*
|
|
4
|
+
* ## Why
|
|
5
|
+
*
|
|
6
|
+
* Every place the TIS method editor asks an author to name a machine value was
|
|
7
|
+
* a bare text box: a field's `Source` hinting `gm.<variable_name>`, a bound
|
|
8
|
+
* hinting `${gm.…}`. Nobody can type a variable out of a program they cannot
|
|
9
|
+
* see, and a wrong name fails SILENTLY in both directions — a `source` that
|
|
10
|
+
* names nothing never binds, a bound that resolves to nothing is simply
|
|
11
|
+
* unbounded.
|
|
12
|
+
*
|
|
13
|
+
* Typing is still allowed. The button is additive: it opens the list, shows what
|
|
14
|
+
* each variable MEANS, and writes the right spelling for the field it came from.
|
|
15
|
+
*
|
|
16
|
+
* ## Rules honoured here
|
|
17
|
+
*
|
|
18
|
+
* - **No tooltips, no `title`.** Half the installed base is a touchscreen with
|
|
19
|
+
* no hover, so the description is on the row, not behind it.
|
|
20
|
+
* - **Pick-then-Insert.** A stray tap in a list must not rewrite a method.
|
|
21
|
+
* - **A disabled entry is shown with its reason**, never omitted — hiding it
|
|
22
|
+
* answers "where is my variable?" with the same silence as a text box.
|
|
23
|
+
*
|
|
24
|
+
* The dialog's own state is deliberately trivial (a query and a selection) and
|
|
25
|
+
* it is unmounted between openings, so there is no draft here to reseed — see
|
|
26
|
+
* `useEditDraft` for the fields that DO have one.
|
|
27
|
+
*/
|
|
28
|
+
import * as React from 'react';
|
|
29
|
+
import { type Catalog, type VariableEntry } from '@adcops/autocore-varpick';
|
|
30
|
+
import './varpick.css';
|
|
31
|
+
export interface VariablePickerProps {
|
|
32
|
+
visible: boolean;
|
|
33
|
+
catalog: Catalog;
|
|
34
|
+
/** Dialog heading. */
|
|
35
|
+
title?: string;
|
|
36
|
+
/** One line saying what picking will do to the field. */
|
|
37
|
+
hint?: React.ReactNode;
|
|
38
|
+
/** Seeds the search box — usually the word the caret was sitting in. */
|
|
39
|
+
initialQuery?: string;
|
|
40
|
+
onCancel: () => void;
|
|
41
|
+
onPick: (entry: VariableEntry) => void;
|
|
42
|
+
}
|
|
43
|
+
export declare const VariablePicker: React.FC<VariablePickerProps>;
|
|
44
|
+
export default VariablePicker;
|
|
45
|
+
//# sourceMappingURL=VariablePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariablePicker.d.ts","sourceRoot":"","sources":["../../../src/components/varpick/VariablePicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAGH,KAAK,OAAO,EACZ,KAAK,aAAa,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,eAAe,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgHxD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import*as React from"react";import{Dialog}from"primereact/dialog";import{Button}from"primereact/button";import{InputText}from"primereact/inputtext";import{firstChoosable,searchCatalog}from"@adcops/autocore-varpick";import"./varpick.css";export const VariablePicker=({visible:a,catalog:e,title:i,hint:s,initialQuery:c,onCancel:t,onPick:r})=>{const[l,n]=React.useState(c??""),[o,p]=React.useState(null);React.useEffect(()=>{a&&n(c??"")},[a,c]);const d=React.useMemo(()=>searchCatalog(e,l),[e,l]);React.useEffect(()=>{p(firstChoosable(d)?.id??null)},[d]);const _=a=>null===a?void 0:d.flatMap(a=>a.entries).find(e=>e.id===a),m=a=>{const e=a??_(o);e&&!e.disabled&&r(e)},h=_jsxs("div",{className:"ac-varpick__foot",children:[_jsx(Button,{label:"Cancel",className:"p-button-text",onClick:t}),_jsx(Button,{label:"Insert",disabled:void 0===_(o),onClick:()=>m()})]});return _jsxs(Dialog,{header:i??"Insert a variable",visible:a,onHide:t,footer:h,style:{width:"44rem",maxWidth:"95vw"},children:[s&&_jsx("div",{className:"ac-varpick__hint",children:s}),_jsx(InputText,{className:"ac-varpick__search",value:l,autoFocus:!0,placeholder:"name, or what it means — try “load” or “EL3356”",onChange:a=>n(a.target.value),onKeyDown:a=>{"Enter"===a.key&&(a.preventDefault(),m())}}),0===d.length?_jsx("div",{className:"ac-varpick__empty",children:0===e.length?"Nothing to pick from. The machine published no variables — the server may be an older build without gm.get_variables.":`No variable matches “${l}”.`}):_jsx("div",{className:"ac-varpick__list",children:d.map(a=>_jsxs("div",{className:"ac-varpick__group",children:[_jsxs("div",{className:"ac-varpick__grouphead",children:[_jsx("span",{className:"ac-varpick__grouptitle",children:a.title}),a.hint&&_jsx("span",{className:"ac-varpick__grouphint",children:a.hint})]}),a.entries.map(a=>_jsxs("button",{type:"button",className:"ac-varpick__row"+(a.id===o?" ac-varpick__row--on":"")+(a.disabled?" ac-varpick__row--off":""),"aria-pressed":a.id===o,disabled:!!a.disabled,onClick:()=>p(a.id),onDoubleClick:()=>m(a),children:[_jsxs("span",{className:"ac-varpick__line",children:[_jsx("code",{className:"ac-varpick__name",children:a.name}),a.label&&_jsx("span",{className:"ac-varpick__label",children:a.label}),a.unit&&_jsx("span",{className:"ac-varpick__chip",children:a.unit}),a.type&&_jsx("span",{className:"ac-varpick__chip",children:a.type}),void 0!==a.live&&_jsxs("span",{className:"ac-varpick__live",children:["now ",a.live]})]}),a.description&&_jsx("span",{className:"ac-varpick__desc",children:a.description}),a.disabled&&_jsx("span",{className:"ac-varpick__why",children:a.disabled}),a.note&&_jsx("span",{className:"ac-varpick__note",children:a.note})]},a.id))]},a.id))})]})};export default VariablePicker;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The variable picker: a field with a button that opens a searchable, described
|
|
3
|
+
* list of the machine's variables.
|
|
4
|
+
*
|
|
5
|
+
* The model (catalog shape, search ranking, caret-aware insertion, the `${fqdn}`
|
|
6
|
+
* token grammar) lives in `@adcops/autocore-varpick`, which has no UI in it —
|
|
7
|
+
* the sequence editor renders the same model with a different widget layer, and
|
|
8
|
+
* neither package may import the other's.
|
|
9
|
+
*/
|
|
10
|
+
export { VariablePicker } from './VariablePicker';
|
|
11
|
+
export type { VariablePickerProps } from './VariablePicker';
|
|
12
|
+
export { VariableInput } from './VariableInput';
|
|
13
|
+
export type { VariableInputProps } from './VariableInput';
|
|
14
|
+
export { boundCatalog, chartFieldCatalog, configSourceCatalog, cycleSourceCatalog, rawSourceCatalog, } from './tisCatalogs';
|
|
15
|
+
export type { TisCatalogContext } from './tisCatalogs';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/varpick/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EACH,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{VariablePicker}from"./VariablePicker";export{VariableInput}from"./VariableInput";export{boundCatalog,chartFieldCatalog,configSourceCatalog,cycleSourceCatalog,rawSourceCatalog}from"./tisCatalogs";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The catalogs the TIS method editor's pickers offer.
|
|
3
|
+
*
|
|
4
|
+
* Each field wants a different list, spelled differently, and getting either
|
|
5
|
+
* wrong fails SILENTLY:
|
|
6
|
+
*
|
|
7
|
+
* - a `config_fields` **Source** is written by the Test Setup form, so a
|
|
8
|
+
* hardware-owned variable there would have the operator's entry overwritten
|
|
9
|
+
* by the module on the next scan;
|
|
10
|
+
* - a **bound** is `${gm.…}` and an unresolvable one means NO bound — the
|
|
11
|
+
* field is simply unlimited, with nothing on screen to say so;
|
|
12
|
+
* - a `cycle_fields` **Source** has two possible producers and the editor used
|
|
13
|
+
* to show neither.
|
|
14
|
+
*
|
|
15
|
+
* Which is why the spelling and the filter live here, next to each other, rather
|
|
16
|
+
* than at each call site.
|
|
17
|
+
*/
|
|
18
|
+
import { type Catalog, type GmVariable } from '@adcops/autocore-varpick';
|
|
19
|
+
export interface TisCatalogContext {
|
|
20
|
+
/** From `gm.get_variables` (or the tag-spec fallback). */
|
|
21
|
+
variables: GmVariable[];
|
|
22
|
+
/** Unit label for a quantity, from the machine's resolved units.json. */
|
|
23
|
+
unitFor?: (quantity: string) => string | undefined;
|
|
24
|
+
/** Current value, formatted, by FQDN. */
|
|
25
|
+
liveFor?: (fqdn: string) => string | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Variables a form field may WRITE — a `config_fields` source.
|
|
29
|
+
*
|
|
30
|
+
* `TestSetupForm` writes the operator's entry straight to this tag, so a
|
|
31
|
+
* variable produced by a module is not a candidate: the write would land and
|
|
32
|
+
* then be overwritten before anything read it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function configSourceCatalog(ctx: TisCatalogContext): Catalog;
|
|
35
|
+
/** Variables a bound (`min`/`max`) or a token default may READ. */
|
|
36
|
+
export declare function boundCatalog(ctx: TisCatalogContext): Catalog;
|
|
37
|
+
/**
|
|
38
|
+
* Where a **cycle field's** value comes from.
|
|
39
|
+
*
|
|
40
|
+
* The one catalog that is not just a variable list, because a cycle field has
|
|
41
|
+
* two possible producers and picking the wrong kind is invisible:
|
|
42
|
+
*
|
|
43
|
+
* 1. `source: "gm.<var>"` — the generated `add_cycle()` reads the tag.
|
|
44
|
+
* 2. `source: null` — whoever records the row supplies it by NAME. On gen4_ac
|
|
45
|
+
* that is the sequencer: a `store_value` step fills a row buffer keyed by
|
|
46
|
+
* name, and `tis.add_cycle` writes `cycle_data` verbatim without checking it
|
|
47
|
+
* against `cycle_fields`. So a declared column with no producer is blank on
|
|
48
|
+
* every row, forever, and nothing says why.
|
|
49
|
+
*
|
|
50
|
+
* Offering only FQDNs — which is what a plain variable picker would do — lets an
|
|
51
|
+
* author wire a binding that never fills. So the sequence's own `store_value`
|
|
52
|
+
* names are offered as a first-class group, and choosing one CLEARS the source
|
|
53
|
+
* (its `insert` is the empty string) rather than setting a binding.
|
|
54
|
+
*/
|
|
55
|
+
export declare function cycleSourceCatalog(ctx: TisCatalogContext, opts: {
|
|
56
|
+
/** `store_value` names in this method's `.seq.json`, if the host read it. */
|
|
57
|
+
producedNames?: string[];
|
|
58
|
+
/** The cycle field being edited, so its own name can be highlighted. */
|
|
59
|
+
fieldName?: string;
|
|
60
|
+
}): Catalog;
|
|
61
|
+
/**
|
|
62
|
+
* Columns a chart axis or series may plot.
|
|
63
|
+
*
|
|
64
|
+
* A chart naming a column that does not exist renders an empty plot with no
|
|
65
|
+
* error, which reads as "the machine recorded nothing".
|
|
66
|
+
*/
|
|
67
|
+
export declare function chartFieldCatalog(opts: {
|
|
68
|
+
cycleFields?: string[];
|
|
69
|
+
resultsFields?: string[];
|
|
70
|
+
rawColumns?: string[];
|
|
71
|
+
/** Project/config fields — one value for the whole test. */
|
|
72
|
+
testFields?: string[];
|
|
73
|
+
/** `raw_trace` views plot raw columns; `cycle_scatter` plots cycle fields. */
|
|
74
|
+
viewType?: string;
|
|
75
|
+
}): Catalog;
|
|
76
|
+
/**
|
|
77
|
+
* Sources a raw-data column may read.
|
|
78
|
+
*
|
|
79
|
+
* `time` and `derived` are the two the server always understands; everything
|
|
80
|
+
* else is a module channel FQDN. The channel list is not modelled here — the
|
|
81
|
+
* editor has no NI catalog — so the two known values are offered by name and
|
|
82
|
+
* the field stays free text for the rest.
|
|
83
|
+
*/
|
|
84
|
+
export declare function rawSourceCatalog(channels?: string[]): Catalog;
|
|
85
|
+
//# sourceMappingURL=tisCatalogs.d.ts.map
|