@adcops/autocore-react 3.3.123 → 3.5.3

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.
Files changed (55) hide show
  1. package/dist/components/UnitSystemSelector.d.ts +17 -0
  2. package/dist/components/UnitSystemSelector.d.ts.map +1 -0
  3. package/dist/components/UnitSystemSelector.js +1 -0
  4. package/dist/components/UnitsEditor.d.ts +11 -0
  5. package/dist/components/UnitsEditor.d.ts.map +1 -0
  6. package/dist/components/UnitsEditor.js +1 -0
  7. package/dist/components/index.d.ts +5 -1
  8. package/dist/components/index.d.ts.map +1 -1
  9. package/dist/components/index.js +1 -1
  10. package/dist/components/tis/ResultHistoryTable.d.ts.map +1 -1
  11. package/dist/components/tis/ResultHistoryTable.js +1 -1
  12. package/dist/components/tis/ScienceTable.d.ts +14 -0
  13. package/dist/components/tis/ScienceTable.d.ts.map +1 -1
  14. package/dist/components/tis/ScienceTable.js +1 -1
  15. package/dist/components/tis/TestDataView.d.ts +33 -4
  16. package/dist/components/tis/TestDataView.d.ts.map +1 -1
  17. package/dist/components/tis/TestDataView.js +1 -1
  18. package/dist/components/tis/TestFieldRow.d.ts +69 -7
  19. package/dist/components/tis/TestFieldRow.d.ts.map +1 -1
  20. package/dist/components/tis/TestFieldRow.js +1 -1
  21. package/dist/components/tis/TestSetupForm.d.ts.map +1 -1
  22. package/dist/components/tis/TestSetupForm.js +1 -1
  23. package/dist/components/tis/TisProvider.d.ts.map +1 -1
  24. package/dist/components/tis/TisProvider.js +1 -1
  25. package/dist/components/tis-editor/editor/ChartViewDialog.d.ts.map +1 -1
  26. package/dist/components/tis-editor/editor/ChartViewDialog.js +1 -1
  27. package/dist/components/tis-editor/types.d.ts +6 -0
  28. package/dist/components/tis-editor/types.d.ts.map +1 -1
  29. package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
  30. package/dist/core/AutoCoreTagContext.js +1 -1
  31. package/dist/core/AutoCoreTagTypes.d.ts +82 -7
  32. package/dist/core/AutoCoreTagTypes.d.ts.map +1 -1
  33. package/dist/core/formatScaled.d.ts +16 -0
  34. package/dist/core/formatScaled.d.ts.map +1 -0
  35. package/dist/core/formatScaled.js +1 -0
  36. package/dist/hooks/useAutoCoreTag.d.ts +11 -3
  37. package/dist/hooks/useAutoCoreTag.d.ts.map +1 -1
  38. package/dist/hooks/useAutoCoreTag.js +1 -1
  39. package/package.json +1 -1
  40. package/src/components/UnitSystemSelector.tsx +88 -0
  41. package/src/components/UnitsEditor.tsx +317 -0
  42. package/src/components/index.ts +5 -1
  43. package/src/components/tis/ResultHistoryTable.tsx +96 -6
  44. package/src/components/tis/ScienceTable.tsx +33 -1
  45. package/src/components/tis/TestDataView.tsx +203 -33
  46. package/src/components/tis/TestFieldRow.tsx +126 -19
  47. package/src/components/tis/TestSetupForm.tsx +35 -7
  48. package/src/components/tis/TisProvider.tsx +46 -3
  49. package/src/components/tis-editor/editor/ChartViewDialog.tsx +27 -0
  50. package/src/components/tis-editor/types.ts +6 -0
  51. package/src/core/AutoCoreTagContext.tsx +165 -16
  52. package/src/core/AutoCoreTagTypes.ts +91 -7
  53. package/src/core/formatScaled.ts +72 -0
  54. package/src/hooks/useAutoCoreTag.ts +51 -3
  55. package/todo.md +6 -0
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ export interface UnitSystemSelectorProps {
3
+ /**
4
+ * `"buttons"` (default) renders a segmented control — right for a
5
+ * touchscreen with two or three systems. `"dropdown"` is better past that.
6
+ */
7
+ variant?: "buttons" | "dropdown";
8
+ /** Optional label rendered above the control. */
9
+ label?: string;
10
+ /** Disable interaction (e.g. while a test is running). */
11
+ disabled?: boolean;
12
+ className?: string;
13
+ style?: React.CSSProperties;
14
+ }
15
+ export declare const UnitSystemSelector: React.FC<UnitSystemSelectorProps>;
16
+ export default UnitSystemSelector;
17
+ //# sourceMappingURL=UnitSystemSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnitSystemSelector.d.ts","sourceRoot":"","sources":["../../src/components/UnitSystemSelector.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAK1C,MAAM,WAAW,uBAAuB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACjC,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC/B;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAkDhE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useContext}from"react";import{SelectButton}from"primereact/selectbutton";import{Dropdown}from"primereact/dropdown";import{AutoCoreTagContext}from"../core/AutoCoreTagContext";export const UnitSystemSelector=({variant:t="buttons",label:e,disabled:s=!1,className:o,style:r})=>{const n=useContext(AutoCoreTagContext),a=n.units,l=n.activeSystem??a?.default_system??null;if(!a||!Array.isArray(a.systems)||0===a.systems.length)return null;const m=a.systems.map(t=>({label:t,value:t})),i=t=>{t&&t!==l&&n.setUnitSystem?.(t)};return _jsxs("div",{className:o,style:r,children:[e?_jsx("div",{style:{marginBottom:"0.35rem",fontWeight:600},children:e}):null,"dropdown"===t?_jsx(Dropdown,{value:l,options:m,disabled:s,onChange:t=>i(t.value),style:{minWidth:"10rem"}}):_jsx(SelectButton,{value:l,options:m,disabled:s,onChange:t=>i(t.value),allowEmpty:!1})]})};export default UnitSystemSelector;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import type { UnitsTable } from "../core/AutoCoreTagTypes";
3
+ export interface UnitsEditorProps {
4
+ /** Heading text. Omit for none. */
5
+ title?: string;
6
+ /** Called after a successful save. */
7
+ onSaved?: (units: UnitsTable) => void;
8
+ }
9
+ export declare const UnitsEditor: React.FC<UnitsEditorProps>;
10
+ export default UnitsEditor;
11
+ //# sourceMappingURL=UnitsEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnitsEditor.d.ts","sourceRoot":"","sources":["../../src/components/UnitsEditor.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAWrF,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAmB1E,MAAM,WAAW,gBAAgB;IAC7B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA6PlD,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useCallback,useContext,useEffect,useMemo,useState}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{InputText}from"primereact/inputtext";import{InputNumber}from"primereact/inputnumber";import{Dropdown}from"primereact/dropdown";import{Button}from"primereact/button";import{SelectButton}from"primereact/selectbutton";import{Message}from"primereact/message";import{EventEmitterContext}from"../core/EventEmitterContext";import{MessageType}from"../hub/CommandMessage";const PRECISION_MODES=[{label:"Decimals",value:"decimals"},{label:"Significant",value:"significant"}];export const UnitsEditor=({title:e="Units",onSaved:t})=>{const{invoke:s}=useContext(EventEmitterContext),[a,i]=useState(null),[n,l]=useState(null),[r,o]=useState(!1),[u,c]=useState(!1),[m,d]=useState(null),[p,y]=useState(null),h=useCallback(async()=>{c(!0),d(null);try{const e=await s("system.get_units",MessageType.Request,{}),t=e?.data??e,a=t?.units;a?(i(a),l(e=>e&&a.systems.includes(e)?e:a.default_system),o(!1)):(d("This machine has no units.json. Display values are shown in backend units until one is installed."),i(null))}catch(e){d(`Could not read units: ${e instanceof Error?e.message:String(e)}`)}c(!1)},[s]);useEffect(()=>{h()},[h]);const f=useMemo(()=>a&&n?Object.entries(a.scales).map(([e,t])=>{const s=t?.[n]??{};return{quantity:e,backend:t?.backend??"",kind:t?.kind??"delta",label:s.label??"",scalar:"number"==typeof s.scalar?s.scalar:1,offset:"number"==typeof s.offset?s.offset:0,precision:"number"==typeof s.precision?s.precision:3,precisionMode:s.precision_mode??"decimals"}}).sort((e,t)=>e.quantity.localeCompare(t.quantity)):[],[a,n]),x=(e,t,s)=>{if(!a||!n)return;const l=JSON.parse(JSON.stringify(a)),r=l.scales[e];if(!r)return;const u={...r[n]??{}};switch(t){case"label":u.label=s;break;case"scalar":u.scalar=s;break;case"offset":u.offset=s;break;case"precision":u.precision=s;break;case"precisionMode":u.precision_mode=s;break;default:return}r[n]=u,i(l),o(!0),y(null)};return _jsxs("div",a?{children:[e?_jsx("h3",{style:{marginTop:0},children:e}):null,_jsxs("div",{style:{display:"flex",alignItems:"center",gap:"1rem",flexWrap:"wrap",marginBottom:"0.75rem"},children:[_jsxs("div",{children:[_jsx("div",{style:{fontWeight:600,marginBottom:"0.3rem"},children:"Editing system"}),_jsx(SelectButton,{value:n,options:a.systems.map(e=>({label:e,value:e})),onChange:e=>{e.value&&l(e.value)},allowEmpty:!1})]}),_jsxs("div",{style:{marginLeft:"auto",display:"flex",gap:"0.5rem"},children:[_jsx(Button,{label:"Revert",icon:"pi pi-undo",className:"p-button-text",disabled:!r||u,onClick:()=>{h()}}),_jsx(Button,{label:"Save",icon:"pi pi-check",disabled:!r||u,loading:u,onClick:()=>{(async()=>{if(a){c(!0),d(null),y(null);try{const e=await s("system.save_units",MessageType.Request,{units:a});if(!e?.success)return void d(e?.error_message??"Save was refused.");o(!1),y("Saved."),t?.(a)}catch(e){d(`Save failed: ${e instanceof Error?e.message:String(e)}`)}finally{c(!1)}}})()}})]})]}),m?_jsx(Message,{severity:"error",text:m,style:{marginBottom:"0.5rem"}}):null,p?_jsx(Message,{severity:"success",text:p,style:{marginBottom:"0.5rem"}}):null,_jsx(Message,{severity:"info",style:{marginBottom:"0.75rem"},text:"Display only — these settings never change what the machine stores or how it moves. 'Backend' is the unit the controller holds and is set at commissioning."}),_jsxs(DataTable,{value:f,size:"small",stripedRows:!0,scrollable:!0,scrollHeight:"26rem",children:[_jsx(Column,{field:"quantity",header:"Quantity",style:{minWidth:"11rem"}}),_jsx(Column,{field:"backend",header:"Backend",style:{width:"7rem"},body:e=>_jsxs("span",{style:{opacity:.7},children:[e.backend||"—","absolute"===e.kind?" (abs)":""]})}),_jsx(Column,{header:"Label",style:{width:"8rem"},body:e=>_jsx(InputText,{value:e.label,style:{width:"100%"},onChange:t=>x(e.quantity,"label",t.target.value)})}),_jsx(Column,{header:"Scalar",style:{width:"11rem"},body:e=>_jsx(InputNumber,{value:e.scalar,minFractionDigits:0,maxFractionDigits:10,style:{width:"100%"},inputStyle:{width:"100%"},onValueChange:t=>x(e.quantity,"scalar",t.value??1)})}),_jsx(Column,{header:"Offset",style:{width:"8rem"},body:e=>"absolute"===e.kind?_jsx(InputNumber,{value:e.offset,minFractionDigits:0,maxFractionDigits:6,style:{width:"100%"},inputStyle:{width:"100%"},onValueChange:t=>x(e.quantity,"offset",t.value??0)}):_jsx("span",{style:{opacity:.4},children:"n/a"})}),_jsx(Column,{header:"Precision",style:{width:"7rem"},body:e=>_jsx(InputNumber,{value:e.precision,min:0,max:12,showButtons:!0,style:{width:"100%"},inputStyle:{width:"100%"},onValueChange:t=>x(e.quantity,"precision",t.value??0)})}),_jsx(Column,{header:"Mode",style:{width:"9rem"},body:e=>_jsx(Dropdown,{value:e.precisionMode,options:PRECISION_MODES,style:{width:"100%"},onChange:t=>x(e.quantity,"precisionMode",t.value)})})]})]}:{children:[e?_jsx("h3",{style:{marginTop:0},children:e}):null,m?_jsx(Message,{severity:"warn",text:m}):null,_jsx("div",{style:{marginTop:"0.75rem"},children:_jsx(Button,{label:"Reload",icon:"pi pi-refresh",onClick:()=>{h()},loading:u})})]})};export default UnitsEditor;
@@ -22,7 +22,11 @@ export { ResultHistoryTable } from './tis/ResultHistoryTable';
22
22
  export type { ResultHistoryTableProps } from './tis/ResultHistoryTable';
23
23
  export { SampleSummaryPanel } from './tis/SampleSummaryPanel';
24
24
  export type { SampleSummaryPanelProps } from './tis/SampleSummaryPanel';
25
- export { TestDataView } from './tis/TestDataView';
25
+ export { TestDataView, DEFAULT_X_DECIMALS } from './tis/TestDataView';
26
+ export { UnitSystemSelector } from './UnitSystemSelector';
27
+ export type { UnitSystemSelectorProps } from './UnitSystemSelector';
28
+ export { UnitsEditor } from './UnitsEditor';
29
+ export type { UnitsEditorProps } from './UnitsEditor';
26
30
  export type { TestDataViewProps, ChartAxis, ChartSeries, ChartView, RawDataShape } from './tis/TestDataView';
27
31
  export { TestRawDataView } from './tis/TestRawDataView';
28
32
  export type { TestRawDataViewProps } from './tis/TestRawDataView';
@@ -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":"AAQA,OAAO,EACH,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,WAAW,EACX,eAAe,EACf,UAAU,EACV,SAAS,EACT,iBAAiB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACR,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAU,uBAAuB,CAAC;AAC5D,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAY,qBAAqB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAY,qBAAqB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAa,oBAAoB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEvF,OAAO,EAAE,gBAAgB,EAAE,MAAS,wBAAwB,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAQ,yBAAyB,CAAC;AAC9D,YAAY,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEvF,OAAO,EAAE,gBAAgB,EAAE,MAAS,wBAAwB,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,MAAO,0BAA0B,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,kBAAkB,EAAE,MAAO,0BAA0B,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAO,sBAAsB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAc,eAAe,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7G,OAAO,EAAE,eAAe,EAAE,MAAU,uBAAuB,CAAC;AAC5D,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAW,sBAAsB,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAMhE,OAAO,EACH,WAAW,EACX,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,eAAe,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACR,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,aAAa,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAS,0BAA0B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAY,uBAAuB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAU,yBAAyB,CAAC;AAShE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACxE,YAAY,EACR,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,EACN,YAAY,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -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{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}from"./tis/TestDataView";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{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 +1 @@
1
- {"version":3,"file":"ResultHistoryTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ResultHistoryTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAWvE,OAAO,0BAA0B,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAyCD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAogBhE,CAAC"}
1
+ {"version":3,"file":"ResultHistoryTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ResultHistoryTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAWvE,OAAO,0BAA0B,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAyCD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA8lBhE,CAAC"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext,useRef}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{Badge}from"primereact/badge";import{Menu}from"primereact/menu";import{confirmDialog}from"primereact/confirmdialog";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";import{SampleSummaryPanel}from"./SampleSummaryPanel";import"./ResultHistoryTable.css";const downloadCsvBlob=(e,t)=>{const o=new Blob([t],{type:"text/csv;charset=utf-8;"}),i=URL.createObjectURL(o),s=document.createElement("a");s.href=i,s.download=e,document.body.appendChild(s),s.click(),s.remove(),URL.revokeObjectURL(i)},downloadViaUrl=(e,t)=>{const o=document.createElement("a");o.href=e,o.download=t,document.body.appendChild(o),o.click(),o.remove()};export const ResultHistoryTable=e=>{const t=useTis(),o=e.projectId??t.selection.projectId,i=e.methodId,[s,r]=useState([]),[a,n]=useState(!1),[l,d]=useState(null),[c,p]=useState(null),[u,m]=useState(null),f=useRef(null),[_,h]=useState(null),[y,b]=useState(null),{invoke:g}=useContext(EventEmitterContext),x=async()=>{if(o){n(!0);try{const e={project_id:o};i&&(e.method_id=i);const t=await g("tis.list_tests",MessageType.Request,e);t.success&&t.data&&t.data.tests&&r(t.data.tests)}catch(e){}n(!1)}else r([])};useEffect(()=>{x()},[o,i,t.state.activeRunId,t.state.active]);const v=async(e,t)=>{const s=e?.run_id,r=e?.method_id??i;if(!s||!r||!o)return;const a="report"===t?"tis.export_test_csv":"tis.export_test_data_csv",n="report"===t?"test report":"test data";d({runId:s,kind:t});try{const e=await g(a,MessageType.Request,{project_id:o,method_id:r,run_id:s});if(!e?.success)return void alert(`Failed to build ${n} for ${s}`+(e?.error_message?`: ${e.error_message}`:""));const i="string"==typeof e.data?.filename&&e.data.filename?e.data.filename:`${o}_${r}_${s}_${t}.csv`;if("report"===t){const t="string"==typeof e.data?.csv?e.data.csv:"";if(!t)return void alert(`${n} for ${s} is empty.`);downloadCsvBlob(i,t)}else{const t="string"==typeof e.data?.download_url?e.data.download_url:"";if(!t)return void alert(`Server did not return a download URL for ${n}.`);downloadViaUrl(t,i)}}catch(e){alert(`Download failed: ${e instanceof Error?e.message:String(e)}`)}finally{d(null)}},w=async(e,t)=>{const s=e?.run_id,r=e?.method_id??i;if(!s||!r||!o)return;const a="complete"===t?"tis.finish_test":"abandon"===t?"tis.reset_test":"tis.resume_test";b(s);try{const e=await g(a,MessageType.Request,{project_id:o,method_id:r,run_id:s});if(!e?.success)return void alert(`Could not ${t} ${s}`+(e?.error_message?`:\n\n${e.error_message}`:""));await x()}catch(e){alert(`${t} failed: ${e instanceof Error?e.message:String(e)}`)}finally{b(null)}},j=async e=>{if(!o)return;const t="report"===e?"tis.export_project_csv":"tis.export_project_zip",i="report"===e?"project report":"project archive";p(e);try{const s=await g(t,MessageType.Request,{project_id:o});if(!s?.success)return void alert(`Failed to build ${i}`+(s?.error_message?`: ${s.error_message}`:""));const r="string"==typeof s.data?.download_url?s.data.download_url:"";if(!r)return void alert(`Server did not return a download URL for ${i}.`);const a="report"===e?`${o}_project_report.csv`:`${o}_project_archive.zip`,n="string"==typeof s.data?.filename&&s.data.filename?s.data.filename:a;downloadViaUrl(r,n)}catch(e){alert(`Download failed: ${e instanceof Error?e.message:String(e)}`)}finally{p(null)}},C=e=>{const t="string"==typeof e?.sample_id?e.sample_id:"";if(t)return t;const o=e?.config;return o&&"object"==typeof o&&"string"==typeof o.sample_id?o.sample_id:""};return _jsxs("div",{style:{width:"100%",maxWidth:"100%",overflow:"hidden",boxSizing:"border-box"},children:[_jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem",gap:"0.5rem",flexWrap:"wrap"},children:[_jsx("h3",{style:{margin:0},children:o?`Test History: ${o}${i?` / ${i}`:""}`:"Test History (no project selected)"}),_jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[_jsx(Button,{icon:"report"===c?"pi pi-spin pi-spinner":"pi pi-file",label:"Download Report",size:"small",outlined:!0,disabled:!o||null!==c,onClick:()=>j("report"),tooltip:"Download a CSV report of every test in this project",tooltipOptions:{position:"bottom"}}),_jsx(Button,{icon:"archive"===c?"pi pi-spin pi-spinner":"pi pi-box",label:"Download Archive",size:"small",outlined:!0,disabled:!o||null!==c,onClick:()=>j("archive"),tooltip:"Download a ZIP of the entire project directory (all tests, raw data, configs)",tooltipOptions:{position:"bottom"}}),_jsx(Button,{icon:"pi pi-refresh",label:"Refresh",size:"small",onClick:x,disabled:a})]})]}),_jsx(SampleSummaryPanel,{projectId:o,methodId:i}),_jsxs(DataTable,{value:s,loading:a,paginator:!0,rows:10,emptyMessage:"No tests found.",scrollable:!0,scrollHeight:"flex",tableStyle:{minWidth:0},style:{width:"100%"},rowClassName:e=>!0===e?.excluded?"tis-row-excluded":"",selectionMode:"single",onSelectionChange:e=>{const o=e.value;o?.run_id&&t.setSelection({projectId:o.project_id??null,methodId:o.method_id??null,runId:o.run_id})},children:[_jsx(Column,{header:"Sample ID",sortable:!0,body:C,sortFunction:e=>{const t=[...e.data];return t.sort((t,o)=>C(t).localeCompare(C(o))*(e.order??1)),t},style:{minWidth:"8rem"}}),_jsx(Column,{field:"start_time",header:"Date/Time",sortable:!0,body:e=>{return(t=e.start_time)?new Date(t).toLocaleString():"";var t},style:{minWidth:"12rem"}}),_jsx(Column,{field:"method_id",header:"Test Method",sortable:!0,style:{minWidth:"10rem"}}),_jsx(Column,{header:"Status",field:"status",sortable:!0,body:e=>{const t=(e=>{if(!0===e?.finalized)return{label:"Abandoned",severity:"danger"};const t="string"==typeof e?.status?e.status:"completed";switch(t){case"in_progress":return{label:"In Progress",severity:"info"};case"paused":return{label:"Paused",severity:"warning"};case"completed":return{label:"Completed",severity:"success"};default:return{label:t,severity:void 0}}})(e);return _jsx(Badge,{value:t.label,severity:t.severity})},style:{minWidth:"6rem"}}),_jsx(Column,{header:"Incl.",align:"center",alignHeader:"center",style:{width:"4.5rem"},body:e=>{const t=!0===e?.excluded,s=u===e.run_id;return _jsx(Button,{icon:s?"pi pi-spin pi-spinner":t?"pi pi-eye-slash":"pi pi-check",rounded:!0,text:!0,size:"small",severity:t?"warning":"success",disabled:null!==u,onClick:()=>(async e=>{const t=e?.run_id,s=e?.method_id??i;if(!t||!s||!o)return;const r=!0!==e?.excluded;m(t);try{const e=await g("tis.set_test_excluded",MessageType.Request,{project_id:o,method_id:s,run_id:t,excluded:r});if(!e?.success)return void alert(`Failed to ${r?"exclude":"include"} ${t}`+(e?.error_message?`: ${e.error_message}`:""));await x()}catch(e){alert(`Exclude toggle failed: ${e instanceof Error?e.message:String(e)}`)}finally{m(null)}})(e),"aria-label":t?"Excluded — click to include":"Included — click to exclude",tooltip:t?"Excluded from cross-test results — click to include":"Included in cross-test results — click to exclude",tooltipOptions:{position:"left"}})}}),_jsx(Column,{header:"Download",style:{width:"14rem"},body:e=>{const t=l?.runId===e.run_id&&"data"===l?.kind,o=l?.runId===e.run_id&&"report"===l?.kind,i=null!==l;return _jsxs("div",{style:{display:"flex",gap:"0.4rem"},children:[_jsx(Button,{icon:t?"pi pi-spin pi-spinner":"pi pi-download",label:"Raw",size:"small",outlined:!0,disabled:i,onClick:()=>v(e,"data"),tooltip:"Download raw + filtered trace data as one CSV",tooltipOptions:{position:"left"}}),_jsx(Button,{icon:o?"pi pi-spin pi-spinner":"pi pi-file",label:"Results",size:"small",outlined:!0,disabled:i,onClick:()=>v(e,"report"),tooltip:"Download a CSV report (metadata + cycles + results) for this test",tooltipOptions:{position:"left"}})]})}}),_jsx(Column,{header:"",style:{width:"3rem"},body:e=>_jsx(Button,{icon:y===e.run_id?"pi pi-spin pi-spinner":"pi pi-ellipsis-v",text:!0,rounded:!0,size:"small",disabled:null!==y,"aria-label":"Test actions",tooltip:"Complete / abandon / reopen this test",tooltipOptions:{position:"left"},onClick:t=>{h(e),f.current?.toggle(t)}})})]}),_jsx(Menu,{model:_?(e=>{const t=e?.status,o=!0===e?.finalized,i=[];return"in_progress"===t||"paused"===t?(i.push({label:"Complete Test",icon:"pi pi-check-circle",command:()=>w(e,"complete")}),i.push({label:"Abandon Test",icon:"pi pi-ban",command:()=>confirmDialog({header:"Abandon Test",message:`Mark ${e?.sample_id||e?.run_id} as abandoned? Recorded data is kept, but the test can no longer be reopened.`,icon:"pi pi-exclamation-triangle",acceptClassName:"p-button-danger",acceptLabel:"Abandon",accept:()=>w(e,"abandon")})})):"completed"!==t||o?i.push({label:o?"Abandoned — cannot reopen":"No actions available",icon:"pi pi-info-circle",disabled:!0}):i.push({label:"Reopen Test",icon:"pi pi-replay",command:()=>confirmDialog({header:"Reopen Test",message:`Reopen ${e?.sample_id||e?.run_id} so new cycles are added to it? Cycle numbering continues from where it stopped. This changes where data is recorded — it does not start the machine.`,icon:"pi pi-replay",acceptLabel:"Reopen",accept:()=>w(e,"reopen")})}),i})(_):[],popup:!0,ref:f})]})};
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext,useRef}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{Badge}from"primereact/badge";import{Menu}from"primereact/menu";import{confirmDialog}from"primereact/confirmdialog";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";import{SampleSummaryPanel}from"./SampleSummaryPanel";import"./ResultHistoryTable.css";const downloadCsvBlob=(e,t)=>{const o=new Blob([t],{type:"text/csv;charset=utf-8;"}),i=URL.createObjectURL(o),s=document.createElement("a");s.href=i,s.download=e,document.body.appendChild(s),s.click(),s.remove(),URL.revokeObjectURL(i)},downloadViaUrl=(e,t)=>{const o=document.createElement("a");o.href=e,o.download=t,document.body.appendChild(o),o.click(),o.remove()};export const ResultHistoryTable=e=>{const t=useTis(),o=e.projectId??t.selection.projectId,i=e.methodId,[s,r]=useState([]),[a,n]=useState(!1),[l,d]=useState(null),[c,p]=useState(null),[u,m]=useState(null),f=useRef(null),[_,h]=useState(null),b=useRef(0),[g,y]=useState(null),{invoke:x}=useContext(EventEmitterContext),w=async()=>{if(o){n(!0);try{const e={project_id:o};i&&(e.method_id=i);const t=await x("tis.list_tests",MessageType.Request,e);t.success&&t.data&&t.data.tests&&r(t.data.tests)}catch(e){}n(!1)}else r([])};useEffect(()=>{w()},[o,i,t.state.activeRunId,t.state.active]),useEffect(()=>{_&&f.current?.show({currentTarget:_.anchor})},[_]);const v=async(e,t)=>{const s=e?.run_id,r=e?.method_id??i;if(!s||!r||!o)return;const a="report"===t?"tis.export_test_csv":"tis.export_test_data_csv",n="report"===t?"test report":"test data";d({runId:s,kind:t});try{const e=await x(a,MessageType.Request,{project_id:o,method_id:r,run_id:s});if(!e?.success)return void alert(`Failed to build ${n} for ${s}`+(e?.error_message?`: ${e.error_message}`:""));const i="string"==typeof e.data?.filename&&e.data.filename?e.data.filename:`${o}_${r}_${s}_${t}.csv`;if("report"===t){const t="string"==typeof e.data?.csv?e.data.csv:"";if(!t)return void alert(`${n} for ${s} is empty.`);downloadCsvBlob(i,t)}else{const t="string"==typeof e.data?.download_url?e.data.download_url:"";if(!t)return void alert(`Server did not return a download URL for ${n}.`);downloadViaUrl(t,i)}}catch(e){alert(`Download failed: ${e instanceof Error?e.message:String(e)}`)}finally{d(null)}},j=async(e,t)=>{const s=e?.run_id,r=e?.method_id??i;if(!s||!r||!o)return;const a="complete"===t?"tis.finish_test":"abandon"===t?"tis.reset_test":"tis.resume_test";y(s);try{const e=await x(a,MessageType.Request,{project_id:o,method_id:r,run_id:s});if(!e?.success)return void alert(`Could not ${t} ${s}`+(e?.error_message?`:\n\n${e.error_message}`:""));await w()}catch(e){alert(`${t} failed: ${e instanceof Error?e.message:String(e)}`)}finally{y(null)}},C=async e=>{if(!o)return;const t="report"===e?"tis.export_project_csv":"tis.export_project_zip",i="report"===e?"project report":"project archive";p(e);try{const s=await x(t,MessageType.Request,{project_id:o});if(!s?.success)return void alert(`Failed to build ${i}`+(s?.error_message?`: ${s.error_message}`:""));const r="string"==typeof s.data?.download_url?s.data.download_url:"";if(!r)return void alert(`Server did not return a download URL for ${i}.`);const a="report"===e?`${o}_project_report.csv`:`${o}_project_archive.zip`,n="string"==typeof s.data?.filename&&s.data.filename?s.data.filename:a;downloadViaUrl(r,n)}catch(e){alert(`Download failed: ${e instanceof Error?e.message:String(e)}`)}finally{p(null)}},T=e=>{const t="string"==typeof e?.sample_id?e.sample_id:"";if(t)return t;const o=e?.config;return o&&"object"==typeof o&&"string"==typeof o.sample_id?o.sample_id:""};return _jsxs("div",{style:{width:"100%",maxWidth:"100%",overflow:"hidden",boxSizing:"border-box"},children:[_jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem",gap:"0.5rem",flexWrap:"wrap"},children:[_jsx("h3",{style:{margin:0},children:o?`Test History: ${o}${i?` / ${i}`:""}`:"Test History (no project selected)"}),_jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[_jsx(Button,{icon:"report"===c?"pi pi-spin pi-spinner":"pi pi-file",label:"Download Report",size:"small",outlined:!0,disabled:!o||null!==c,onClick:()=>C("report"),tooltip:"Download a CSV report of every test in this project",tooltipOptions:{position:"bottom"}}),_jsx(Button,{icon:"archive"===c?"pi pi-spin pi-spinner":"pi pi-box",label:"Download Archive",size:"small",outlined:!0,disabled:!o||null!==c,onClick:()=>C("archive"),tooltip:"Download a ZIP of the entire project directory (all tests, raw data, configs)",tooltipOptions:{position:"bottom"}}),_jsx(Button,{icon:"pi pi-refresh",label:"Refresh",size:"small",onClick:w,disabled:a})]})]}),_jsx(SampleSummaryPanel,{projectId:o,methodId:i}),_jsxs(DataTable,{value:s,loading:a,paginator:!0,rows:10,emptyMessage:"No tests found.",scrollable:!0,scrollHeight:"flex",tableStyle:{minWidth:0},style:{width:"100%"},rowClassName:e=>!0===e?.excluded?"tis-row-excluded":"",selectionMode:"single",onSelectionChange:e=>{const o=e.value;o?.run_id&&t.setSelection({projectId:o.project_id??null,methodId:o.method_id??null,runId:o.run_id})},children:[_jsx(Column,{header:"Sample ID",sortable:!0,body:T,sortFunction:e=>{const t=[...e.data];return t.sort((t,o)=>T(t).localeCompare(T(o))*(e.order??1)),t},style:{minWidth:"8rem"}}),_jsx(Column,{field:"start_time",header:"Date/Time",sortable:!0,body:e=>{return(t=e.start_time)?new Date(t).toLocaleString():"";var t},style:{minWidth:"12rem"}}),_jsx(Column,{field:"method_id",header:"Test Method",sortable:!0,style:{minWidth:"10rem"}}),_jsx(Column,{header:"Status",field:"status",sortable:!0,body:e=>{const t=(e=>{if(!0===e?.finalized)return{label:"Abandoned",severity:"danger"};const t="string"==typeof e?.status?e.status:"completed";if("completed"===t&&!0===e?.auto_closed)return{label:"Interrupted",severity:"warning"};switch(t){case"in_progress":return{label:"In Progress",severity:"info"};case"paused":return{label:"Paused",severity:"warning"};case"completed":return{label:"Completed",severity:"success"};default:return{label:t,severity:void 0}}})(e);return _jsx(Badge,{value:t.label,severity:t.severity})},style:{minWidth:"6rem"}}),_jsx(Column,{header:"Incl.",align:"center",alignHeader:"center",style:{width:"4.5rem"},body:e=>{const t=!0===e?.excluded,s=u===e.run_id;return _jsx(Button,{icon:s?"pi pi-spin pi-spinner":t?"pi pi-eye-slash":"pi pi-check",rounded:!0,text:!0,size:"small",severity:t?"warning":"success",disabled:null!==u,onClick:()=>(async e=>{const t=e?.run_id,s=e?.method_id??i;if(!t||!s||!o)return;const r=!0!==e?.excluded;m(t);try{const e=await x("tis.set_test_excluded",MessageType.Request,{project_id:o,method_id:s,run_id:t,excluded:r});if(!e?.success)return void alert(`Failed to ${r?"exclude":"include"} ${t}`+(e?.error_message?`: ${e.error_message}`:""));await w()}catch(e){alert(`Exclude toggle failed: ${e instanceof Error?e.message:String(e)}`)}finally{m(null)}})(e),"aria-label":t?"Excluded — click to include":"Included — click to exclude",tooltip:t?"Excluded from cross-test results — click to include":"Included in cross-test results — click to exclude",tooltipOptions:{position:"left"}})}}),_jsx(Column,{header:"Download",style:{width:"14rem"},body:e=>{const t=l?.runId===e.run_id&&"data"===l?.kind,o=l?.runId===e.run_id&&"report"===l?.kind,i=null!==l;return _jsxs("div",{style:{display:"flex",gap:"0.4rem"},children:[_jsx(Button,{icon:t?"pi pi-spin pi-spinner":"pi pi-download",label:"Raw",size:"small",outlined:!0,disabled:i,onClick:()=>v(e,"data"),tooltip:"Download raw + filtered trace data as one CSV",tooltipOptions:{position:"left"}}),_jsx(Button,{icon:o?"pi pi-spin pi-spinner":"pi pi-file",label:"Results",size:"small",outlined:!0,disabled:i,onClick:()=>v(e,"report"),tooltip:"Download a CSV report (metadata + cycles + results) for this test",tooltipOptions:{position:"left"}})]})}}),_jsx(Column,{header:"",style:{width:"3rem"},body:e=>_jsx(Button,{icon:g===e.run_id?"pi pi-spin pi-spinner":"pi pi-ellipsis-v",text:!0,rounded:!0,size:"small",disabled:null!==g,"aria-label":"Test actions",tooltip:"Complete / abandon / reopen this test",tooltipOptions:{position:"left"},onClick:t=>{b.current+=1,h({row:e,anchor:t.currentTarget,seq:b.current})}})})]}),_jsx(Menu,{model:_?(e=>{const t=e?.status,o=!0===e?.finalized,i="in_progress"===t||"paused"===t,s="completed"===t&&!0===e?.auto_closed&&!o,r=[];return i?(r.push({label:"Complete Test",icon:"pi pi-check-circle",command:()=>j(e,"complete")}),r.push({label:"Abandon Test",icon:"pi pi-ban",command:()=>confirmDialog({header:"Abandon Test",message:`Mark ${e?.sample_id||e?.run_id} as abandoned? Recorded data is kept, but the test can no longer be reopened.`,icon:"pi pi-exclamation-triangle",acceptClassName:"p-button-danger",acceptLabel:"Abandon",accept:()=>j(e,"abandon")})})):s?(r.push({label:"Close Test",icon:"pi pi-check-circle",command:()=>confirmDialog({header:"Close Interrupted Test",message:`Close ${e?.sample_id||e?.run_id}? It was closed automatically when the software restarted mid-test. Closing it marks it Completed and keeps the recorded end time. Recorded data is not changed, and the test can still be reopened later.`,icon:"pi pi-check-circle",acceptLabel:"Close Test",accept:()=>j(e,"complete")})}),r.push({label:"Reopen Test",icon:"pi pi-replay",command:()=>confirmDialog({header:"Reopen Test",message:`Reopen ${e?.sample_id||e?.run_id} so new cycles are added to it? Cycle numbering continues from where it stopped. This changes where data is recorded — it does not start the machine.`,icon:"pi pi-replay",acceptLabel:"Reopen",accept:()=>j(e,"reopen")})}),r.push({label:"Abandon Test",icon:"pi pi-ban",command:()=>confirmDialog({header:"Abandon Test",message:`Mark ${e?.sample_id||e?.run_id} as abandoned? Recorded data is kept, but the test can no longer be reopened.`,icon:"pi pi-exclamation-triangle",acceptClassName:"p-button-danger",acceptLabel:"Abandon",accept:()=>j(e,"abandon")})})):"completed"!==t||o?r.push({label:o?"Abandoned — cannot reopen":"No actions available",icon:"pi pi-info-circle",disabled:!0}):r.push({label:"Reopen Test",icon:"pi pi-replay",command:()=>confirmDialog({header:"Reopen Test",message:`Reopen ${e?.sample_id||e?.run_id} so new cycles are added to it? Cycle numbering continues from where it stopped. This changes where data is recorded — it does not start the machine.`,icon:"pi pi-replay",acceptLabel:"Reopen",accept:()=>j(e,"reopen")})}),r})(_.row):[],popup:!0,ref:f})]})};
@@ -31,6 +31,20 @@ export interface ScienceTableProps {
31
31
  showIndex?: boolean;
32
32
  /** Header for the index column. Default "#". */
33
33
  indexHeader?: string;
34
+ /**
35
+ * Which way the row index counts.
36
+ *
37
+ * `'ascending'` (default) numbers top-to-bottom, 1..n — right for a table
38
+ * whose first row is its first record.
39
+ *
40
+ * `'descending'` numbers n..1, so the TOP row carries the highest number.
41
+ * Use it whenever `rows` is newest-first: the number then reads as "this is
42
+ * cycle 47 of 47" instead of restarting at 1 on every new arrival, which is
43
+ * what an operator watching a running test expects. Getting this wrong is
44
+ * actively misleading — an ascending index over newest-first rows labels the
45
+ * newest cycle "1" and the oldest one "47".
46
+ */
47
+ indexOrder?: 'ascending' | 'descending';
34
48
  emptyMessage?: string;
35
49
  /** Enable virtual scrolling; pair with `scrollHeight` for large runs. */
36
50
  scrollable?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"ScienceTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ScienceTable.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,oBAAoB,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC1B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,SAAS,CAAC;IACrC,iDAAiD;IACjD,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAC9B,oEAAoE;IACpE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8FpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ScienceTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ScienceTable.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,oBAAoB,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC1B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,SAAS,CAAC;IACrC,iDAAiD;IACjD,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAC9B,oEAAoE;IACpE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,WAAW,GAAG,YAAY,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgHpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{InputText}from"primereact/inputtext";import"./ScienceTable.css";const HeaderCell=({column:e})=>_jsxs("div",{className:"ac-sci-th",children:[_jsx("span",{className:"ac-sci-th-name",children:e.label}),e.units?_jsxs("span",{className:"ac-sci-th-unit",children:["[",e.units,"]"]}):null]});export const ScienceTable=({title:e,columns:a,rows:l,showIndex:s=!0,indexHeader:t="#",emptyMessage:i="No data.",scrollable:c=!1,scrollHeight:r,virtualItemSize:n=38,onCellEdit:o})=>{const d=c&&!!r,m=!!o&&a.some(e=>e.editable);return _jsxs("div",{className:"ac-science-table-wrap",children:[null!=e&&_jsx("div",{className:"ac-science-table-title",children:e}),_jsx("div",{className:"ac-science-table-scroll",children:_jsxs(DataTable,{className:"ac-science-table",value:l,scrollable:c,scrollHeight:r,virtualScrollerOptions:d?{itemSize:n}:void 0,emptyMessage:i,editMode:m?"cell":void 0,children:[s?_jsx(Column,{header:t,headerClassName:"ac-sci-index",bodyClassName:"ac-sci-index",align:"center",alignHeader:"center",style:{width:"3.5rem",maxWidth:"3.5rem"},body:(e,a)=>a.rowIndex+1}):null,a.map(e=>{const a=!!o&&!!e.editable;return _jsx(Column,{field:e.field,header:_jsx(HeaderCell,{column:e}),align:e.align??"center",alignHeader:"center",style:e.style,bodyClassName:a?"ac-sci-cell ac-sci-cell-editable":"ac-sci-cell",body:e.body?a=>e.body(a):void 0,editor:a?e=>_jsx(InputText,{value:e.value??"",autoFocus:!0,style:{width:"100%"},onChange:a=>e.editorCallback?.(a.target.value),onKeyDown:e=>e.stopPropagation()}):void 0,onCellEditComplete:a?a=>{const l=a.rowData?.[e.field];let s=a.newValue;if("number"==typeof l&&""!==s&&null!=s){const e=Number(s);Number.isNaN(e)||(s=e)}s!==l&&o(a.rowData,e.field,s)}:void 0},e.field)})]})})]})};export default ScienceTable;
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{InputText}from"primereact/inputtext";import"./ScienceTable.css";const HeaderCell=({column:e})=>_jsxs("div",{className:"ac-sci-th",children:[_jsx("span",{className:"ac-sci-th-name",children:e.label}),e.units?_jsxs("span",{className:"ac-sci-th-unit",children:["[",e.units,"]"]}):null]});export const ScienceTable=({title:e,columns:l,rows:a,showIndex:s=!0,indexHeader:t="#",indexOrder:i="ascending",emptyMessage:c="No data.",scrollable:n=!1,scrollHeight:r,virtualItemSize:o=38,onCellEdit:d})=>{const m=n&&!!r,u=l.map(e=>`${e.field}\0${e.label}\0${e.units??""}`).join(""),x=!!d&&l.some(e=>e.editable);return _jsxs("div",{className:"ac-science-table-wrap",children:[null!=e&&_jsx("div",{className:"ac-science-table-title",children:e}),_jsx("div",{className:"ac-science-table-scroll",children:_jsxs(DataTable,{className:"ac-science-table",value:a,scrollable:n,scrollHeight:r,virtualScrollerOptions:m?{itemSize:o}:void 0,emptyMessage:c,editMode:x?"cell":void 0,children:[s?_jsx(Column,{header:t,headerClassName:"ac-sci-index",bodyClassName:"ac-sci-index",align:"center",alignHeader:"center",style:{width:"3.5rem",maxWidth:"3.5rem"},body:(e,l)=>"descending"===i?a.length-l.rowIndex:l.rowIndex+1}):null,l.map(e=>{const l=!!d&&!!e.editable;return _jsx(Column,{field:e.field,header:_jsx(HeaderCell,{column:e}),align:e.align??"center",alignHeader:"center",style:e.style,bodyClassName:l?"ac-sci-cell ac-sci-cell-editable":"ac-sci-cell",body:e.body?l=>e.body(l):void 0,editor:l?e=>_jsx(InputText,{value:e.value??"",autoFocus:!0,style:{width:"100%"},onChange:l=>e.editorCallback?.(l.target.value),onKeyDown:e=>e.stopPropagation()}):void 0,onCellEditComplete:l?l=>{const a=l.rowData?.[e.field];let s=l.newValue;if("number"==typeof a&&""!==s&&null!=s){const e=Number(s);Number.isNaN(e)||(s=e)}s!==a&&d(l.rowData,e.field,s)}:void 0},e.field)})]},u)})]})};export default ScienceTable;
@@ -9,10 +9,22 @@ export interface TestFieldDef {
9
9
  * prefer it over `name`; a header reading `cycle_count` is the wire
10
10
  * key leaking into a screen that says "Cycles" everywhere else. */
11
11
  label?: string;
12
- /** Optional display-time scale multiplier. `display = raw * scale`,
13
- * default 1.0 = no conversion. Cycle Data and Results panels
14
- * apply this when formatting numeric cells. Charts plot raw
15
- * values (axis labels already carry units). Storage stays raw. */
12
+ /**
13
+ * The QUANTITY this field measures a scale-group name from the machine's
14
+ * `units.json` ("force", "position", …).
15
+ *
16
+ * When set, Cycle Data / Results render the value in the operator's ACTIVE
17
+ * unit system, at that system's precision, and the column header carries the
18
+ * active label. This is what makes a test run in Imperial read out in
19
+ * Imperial. Storage is untouched — conversion is a rendering step only.
20
+ *
21
+ * Takes precedence over `scale`/`units` below.
22
+ */
23
+ quantity?: string;
24
+ /**
25
+ * Legacy display-time scale multiplier. `display = raw * scale`, default
26
+ * 1.0. Superseded by `quantity`; kept for methods not yet annotated.
27
+ */
16
28
  scale?: number;
17
29
  /** Dropdown choices for this field. Each entry is either a bare scalar
18
30
  * (label === stored value) or an explicit { label, value } pair.
@@ -98,6 +110,17 @@ export interface ChartView {
98
110
  * count. Ignored when `smooth` is false.
99
111
  */
100
112
  smoothWindow?: number;
113
+ /**
114
+ * Maximum decimal places shown on X-axis tick labels. Default
115
+ * [`DEFAULT_X_DECIMALS`].
116
+ *
117
+ * Without a cap the labels print the stored double verbatim, so a value
118
+ * that is only *nearly* round — 0.30000000000000004, the ordinary result of
119
+ * accumulating a 0.1 step — renders as a 17-character tick and the axis
120
+ * becomes unreadable. This is a display cap only: the underlying data,
121
+ * table, CSV export and every calculation still see the full value.
122
+ */
123
+ x_decimals?: number;
101
124
  /**
102
125
  * Optional shaded X-range bands drawn over the plot, declared per view
103
126
  * in project.json (static). These are drawn on every cycle.
@@ -173,4 +196,10 @@ export interface TestDataViewProps {
173
196
  chartHeight?: string;
174
197
  }
175
198
  export declare const TestDataView: React.FC<TestDataViewProps>;
199
+ /**
200
+ * Decimal places on X-axis tick labels when a view doesn't say otherwise.
201
+ * Two is enough to separate adjacent ticks on every axis this renders
202
+ * (time in seconds, position in mm, load in N) without printing float noise.
203
+ */
204
+ export declare const DEFAULT_X_DECIMALS = 2;
176
205
  //# sourceMappingURL=TestDataView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TestDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestDataView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestDataView.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{useCallback,useContext,useEffect,useMemo,useRef,useState}from"react";import{Button}from"primereact/button";import{Column}from"primereact/column";import{DataTable}from"primereact/datatable";import{Dialog}from"primereact/dialog";import{Dropdown}from"primereact/dropdown";import{TabView,TabPanel}from"primereact/tabview";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import annotationPlugin from"chartjs-plugin-annotation";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";import{useRawCycleData}from"./useRawCycleData";import{ScienceTable}from"./ScienceTable";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin,annotationPlugin);export const TestDataView=e=>{const t=useTis(),r=e.projectId??t.selection.projectId,a=e.methodId??t.selection.methodId,n=e.runId??t.selection.runId,l=e.schema??(a?t.schemas[a]:void 0),{throttleMs:o=100,cycleTableHeight:s="400px",chartHeight:i="320px"}=e,{invoke:c,subscribe:d,unsubscribe:u}=useContext(EventEmitterContext),[m,p]=useState(null),[y,h]=useState([]),[f,g]=useState({}),[_,x]=useState({}),[b,j]=useState(!1),[v,w]=useState(!1),C=useCallback(async(e,t,l)=>{const o=e?.cycle_index;if(r&&a&&n&&o)try{const e=await c("tis.update_cycle",MessageType.Request,{project_id:r,method_id:a,run_id:n,cycle_index:o,fields:{[t]:l}});if(!1===e?.success)return;h(e=>e.map(e=>e?.cycle_index===o?{...e,[t]:l}:e))}catch(e){}},[c,r,a,n]),S=useRef(null),[T,R]=useState(null),[M,E]=useState(null),[L,I]=useState(!1),[A,O]=useState(null),[D,N]=useState(null),[k,F]=useState(!1),[H,P]=useState([]),[z,B]=useState(null),V=useMemo(()=>{const e=[];for(const[t,r]of Object.entries(l?.views??{}))e.push({name:t,view:r});return e},[l]),[$,G]=useState(V.length>0?V[0].name:null);useEffect(()=>{if(0===V.length)return;null!==$&&V.some(e=>e.name===$)||G(V[0].name)},[V,$]);const W=V.find(e=>e.name===$)?.view,q="raw_trace"===W?.type,U=useRef([]),J=useRef(null),Y=useRef(null),Z=()=>{Y.current||(Y.current=setTimeout(()=>{if(Y.current=null,U.current.length>0){const e=U.current;U.current=[],h(t=>[...e.slice().reverse(),...t])}J.current&&(g(J.current),J.current=null)},o))};useEffect(()=>{if(!r||!a||!n)return p(null),h([]),void g({});let e=!1;return(async()=>{try{const t=await c("tis.read_test",MessageType.Request,{project_id:r,method_id:a,run_id:n});!e&&t?.success&&(p(t.data),g(t.data.results??{}));const l=await c("tis.read_cycles",MessageType.Request,{project_id:r,method_id:a,run_id:n,offset:0,limit:200,order:"desc"});!e&&l?.success&&h(l.data.cycles??[])}catch(e){}})(),()=>{e=!0}},[r,a,n,c]),useEffect(()=>{const e=e=>e?.project_id===r&&e?.method_id===a&&e?.run_id===n,t=d("tis.cycle_added",t=>{e(t)&&t.cycle&&(U.current.push(t.cycle),Z())}),l=d("tis.results_updated",t=>{e(t)&&(J.current=t.results??{},Z())});return()=>{u(t),u(l),Y.current&&(clearTimeout(Y.current),Y.current=null)}},[r,a,n,o]);const K="string"==typeof m?.sample_id&&m.sample_id?m.sample_id:"string"==typeof m?.config?.sample_id?m.config.sample_id:"";useEffect(()=>{if(!r||!a||!K)return void x({});let e=!1;const t=async()=>{try{const t=await c("tis.sample_summary",MessageType.Request,{project_id:r,method_id:a,sample_id:K,run_id:n});!e&&t?.success&&x(t.data?.summary??{})}catch(e){}};t();const l=[d("tis.sample_summary_updated",e=>{e?.project_id===r&&e?.method_id===a&&e?.sample_id===K&&t()}),d("tis.cycle_added",e=>{e?.project_id===r&&e?.method_id===a&&t()})];return()=>{e=!0,l.forEach(u)}},[r,a,K,n,c,d,u]);const Q=useRawCycleData({projectId:r,methodId:a,runId:n,blobName:l?.raw_data?.blob_name??"trace",source:W?.source??"raw",enabled:q}),X=useMemo(()=>{if(!W)return null;if("cycle_scatter"===W.type){const e=W.x.field;if(!e)return null;const t=[...y].reverse();return{labels:t.map(t=>t[e]),datasets:W.y.map((e,r)=>({label:e.label??e.field,data:t.map(t=>t[e.field]),yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(r),backgroundColor:palette(r),tension:.1,pointRadius:2}))}}if("raw_trace"===W.type){if(!Q.raw)return null;const e=W.x.column;if(!e)return null;const t=Q.raw[e]??[],r=!1!==W.smooth;return{datasets:W.y.map((e,a)=>{const n=Q.raw[e.column]??[],l=r?smoothTraceForDisplay(t,n,W.smoothWindow):n.map((e,r)=>({x:t[r],y:e}));return{label:e.label??e.column,data:l,yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(a),backgroundColor:palette(a),pointRadius:0,borderWidth:1.5,showLine:!0,...r?{cubicInterpolationMode:"monotone"}:{}}})}}return null},[W,y,Q.raw]),ee=W?.y.some(e=>"right"===e.y_axis)??!1,te=useMemo(()=>{if(!q)return[];const e=Q.envelope,t=e?.regions??e?.context?.regions;return Array.isArray(t)?t:[]},[q,Q.envelope]),re=useMemo(()=>[...W?.regions??[],...te],[W,te]),ae=useMemo(()=>{const e="raw_trace"===W?.type;return{responsive:!0,maintainAspectRatio:!1,parsing:!e&&void 0,scales:{x:e?{type:"linear",title:{display:!!W?.x.label,text:W?.x.label}}:{title:{display:!!W?.x.label,text:W?.x.label}},y:{position:"left",title:{display:!0,text:leftAxisLabel(W)}},...ee?{y1:{position:"right",grid:{drawOnChartArea:!1},title:{display:!0,text:rightAxisLabel(W)}}}:{}},plugins:{legend:{display:!0},zoom:{pan:{enabled:!0,mode:"xy"},zoom:{wheel:{enabled:!0},pinch:{enabled:!0},mode:"xy"}},annotation:{annotations:buildRegionAnnotations(re)}}}},[W,ee,re]),ne=l?.raw_data?.blob_name??"trace",le=useRef(""),oe=useCallback(async()=>{if(!r||!a||!n)return[];try{const e=await c("tis.list_raw",MessageType.Request,{project_id:r,method_id:a,run_id:n});if(!e?.success)return[];const t=e.data?.cycles??[];return t.filter(e=>e?.name===ne&&"number"==typeof e?.cycle_index).map(e=>e.cycle_index).sort((e,t)=>e-t)}catch{return[]}},[r,a,n,ne,c]),se=useCallback(async e=>{if(!r||!a||!n)return;const t=`${r}|${a}|${n}|${ne}|${e??"latest"}`;if(le.current===t)return;le.current=t;const l={project_id:r,method_id:a,run_id:n,name:ne};null!=e&&(l.cycle_index=e),I(!0),E(null),R(null);try{const e=await c("tis.read_raw",MessageType.Request,l);e?.success?R(e.data??{}):E(e?.error_message??"No raw data on disk for this run.")}catch(e){E(String(e?.message??e))}finally{I(!1)}F(!0),N(null),O(null);try{const e=await c("tis.read_filtered",MessageType.Request,l);e?.success?O(e.data??{}):N(e?.error_message??"No filtered data on disk for this run.")}catch(e){N(String(e?.message??e))}finally{F(!1)}},[r,a,n,ne,c]);useEffect(()=>{le.current="",P([]),B(null)},[r,a,n,ne]);return useEffect(()=>{b&&null!=z&&se(z)},[b,z,se]),r&&a&&n&&l?_jsxs("div",{className:"vblock",style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[_jsx(Header,{meta:m,config:m?.config,runId:n,projectId:r,methodId:a,canViewRaw:!!l.raw_data,onViewRaw:async()=>{j(!0);let e=H;0===e.length&&(e=await oe(),P(e));const t=e.length>0?e[e.length-1]:null,r=z??t;z!==r&&B(r),await se(r)},onShowConfig:()=>w(!0)}),_jsxs("div",{className:"p-card",style:{padding:"1rem"},children:[_jsxs("div",{className:"flex",style:{gap:"1rem",alignItems:"center",marginBottom:"0.5rem",flexWrap:"wrap"},children:[_jsx(Dropdown,{value:$,options:V.map(e=>({label:e.view.title??e.name,value:e.name})),onChange:e=>G(e.value),placeholder:0===V.length?"No view defined":"Select a view",disabled:0===V.length}),_jsx("h3",{style:{margin:0},children:W?.title??""}),q&&Q.cycles.length>1&&_jsxs(_Fragment,{children:[_jsx("label",{htmlFor:"chart-cycle-picker",style:{color:"var(--text-secondary-color)"},children:"Cycle:"}),_jsx(Dropdown,{inputId:"chart-cycle-picker",value:Q.selectedCycle,options:Q.cycles.map(e=>({label:`Cycle ${e}`,value:e})),onChange:e=>Q.setSelectedCycle(Number(e.value)),style:{minWidth:"8rem"}}),_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:["of ",Q.cycles.length]})]}),_jsx("div",{style:{flex:1}}),_jsx(Button,{icon:"pi pi-th-large",outlined:!0,rounded:!0,size:"small",onClick:()=>S.current?.resetZoom?.(),disabled:!X,tooltip:"Reset chart zoom",tooltipOptions:{position:"left"},"aria-label":"Reset chart zoom"})]}),_jsxs("div",{style:{height:i,position:"relative"},children:[q&&Q.loading&&_jsx(ChartOverlay,{children:"Loading raw data…"}),q&&Q.error&&_jsx(ChartOverlay,{children:Q.error}),X&&_jsx(Line,{ref:S,data:X,options:ae})]})]}),(()=>{const e=y.length>CYCLE_VIRTUAL_THRESHOLD,t=[...(l.cycle_config_fields??[]).map(e=>toScienceColumn(e,!0)),...(l.cycle_fields??[]).map(e=>toScienceColumn(e,!!e.editable))];return _jsx(ScienceTable,{title:`Cycle Data (${y.length})`,columns:t,rows:y,scrollable:e,scrollHeight:e?s:void 0,emptyMessage:"No cycles yet.",onCellEdit:C})})(),(()=>{const e={...f,..._},t=Object.keys(e).length>0,r=l.results_fields??[],a=r.map(e=>toScienceColumn(e)),n=r.some(isProjectScoped);return _jsxs(_Fragment,{children:[_jsx(ScienceTable,{title:"Results",columns:a,rows:t?[e]:[],emptyMessage:"No results yet."}),n&&_jsx("div",{style:{fontSize:"0.8rem",color:"var(--text-secondary-color)",margin:"0.25rem 0 0.75rem"},children:"* across every test of this sample in the project. All other values describe this test."})]})})(),l.raw_data&&_jsxs(Dialog,{visible:b,onHide:()=>j(!1),header:`Run Data — ${n}`,style:{width:"90vw",height:"80vh"},maximizable:!0,children:[_jsx(CyclePickerBar,{cycles:H,selected:z,onChange:B}),_jsx(RawEnvelopeHeader,{envelope:T}),_jsxs(TabView,{style:{height:"100%"},children:[_jsx(TabPanel,{header:"Raw Data",children:_jsx(DataBlobTable,{blob:unwrapEnvelope(T),loading:L,error:M,rawData:l.raw_data})}),_jsx(TabPanel,{header:"Filtered Data",children:_jsx(DataBlobTable,{blob:unwrapEnvelope(A),loading:k,error:D,rawData:l.raw_data,emptyMessage:"Filtered data is written by post-processing — none on disk for this run yet."})})]})]}),_jsx(Dialog,{visible:v,onHide:()=>w(!1),header:"Test Configuration",style:{width:"min(640px, 90vw)"},modal:!0,children:_jsx(ConfigList,{config:m?.config})})]}):_jsx("div",{className:"p-card",style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"No test selected. Pick a row from the History tab or start a run."})};const Header=({meta:e,config:t,runId:r,projectId:a,methodId:n,canViewRaw:l,onViewRaw:o,onShowConfig:s})=>{const i="string"==typeof e?.sample_id&&e.sample_id||"string"==typeof e?.config?.sample_id&&e.config.sample_id||"",c=t&&"object"==typeof t&&Object.entries(t).some(([e])=>"sample_id"!==e);return _jsx("div",{className:"p-card",style:{padding:"1rem"},children:_jsxs("div",{className:"flex",style:{justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[_jsxs("div",{children:[_jsxs("h2",{style:{margin:0,display:"flex",alignItems:"center",gap:"0.5rem"},children:[i||r,c&&_jsx(Button,{icon:"pi pi-info-circle",type:"button",rounded:!0,text:!0,onClick:s,tooltip:"Show test configuration",tooltipOptions:{position:"top"},style:{width:"2rem",height:"2rem",padding:0},"aria-label":"Show test configuration"})]}),_jsxs("div",{style:{color:"var(--text-secondary-color)",fontSize:"0.85em"},children:["project: ",a," · method: ",n," · run: ",r,e?.start_time&&_jsxs(_Fragment,{children:[" · started: ",new Date(e.start_time).toLocaleString()]})]})]}),l&&_jsx(Button,{icon:"pi pi-table",label:"View Raw Data",onClick:o,outlined:!0})]})})},ConfigList=({config:e})=>{const t=e&&"object"==typeof e?Object.entries(e).filter(([e])=>"sample_id"!==e):[];return 0===t.length?_jsx("div",{style:{color:"var(--text-secondary-color)"},children:"No configuration recorded for this run."}):_jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"0.5rem 1rem",fontSize:"0.95em"},children:t.map(([e,t])=>_jsxs(React.Fragment,{children:[_jsx("div",{style:{color:"var(--text-secondary-color)"},children:e}),_jsx("div",{children:formatCell(t,"string")})]},e))})},unwrapEnvelope=e=>e&&"object"==typeof e&&"data"in e&&e.data&&"object"==typeof e.data&&Object.values(e.data).some(e=>Array.isArray(e))?e.data:e,CyclePickerBar=({cycles:e,selected:t,onChange:r})=>e.length<=1?null:_jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.25rem 0.5rem 0.5rem"},children:[_jsx("label",{htmlFor:"raw-cycle-picker",style:{color:"var(--text-secondary-color)"},children:"Cycle:"}),_jsx(Dropdown,{inputId:"raw-cycle-picker",value:t,options:e.map(e=>({label:`Cycle ${e}`,value:e})),onChange:e=>r(Number(e.value)),style:{minWidth:"8rem"}}),_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:["(",e.length," cycles recorded)"]})]}),RawEnvelopeHeader=({envelope:e})=>{if(!e||"object"!=typeof e)return null;const t=e.cycle_index,r=e.cycle_fields,a=e.context;if(null==t&&!r&&!a)return null;const n=e=>{if(!e||"object"!=typeof e)return null;const t=Object.entries(e).filter(([,e])=>null!==e&&"object"!=typeof e);return 0===t.length?null:t.map(([e,t])=>_jsxs("span",{style:{marginRight:"1rem"},children:[_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:[e,": "]}),_jsx("span",{children:String(t)})]},e))};return _jsxs("div",{style:{padding:"0.5rem",borderBottom:"1px solid var(--surface-border)",fontSize:"0.9rem"},children:[null!=t&&_jsx("div",{children:_jsxs("strong",{children:["Cycle ",t]})}),r&&_jsx("div",{style:{marginTop:"0.25rem"},children:n(r)}),a&&_jsx("div",{style:{marginTop:"0.25rem"},children:n(a)})]})},DataBlobTable=({blob:e,loading:t,error:r,rawData:a,emptyMessage:n})=>{if(t)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"Loading…"});if(r)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:n??r});if(!e||"object"!=typeof e)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"No data."});const l=Object.keys(a.columns??{}),o=Object.keys(e).filter(t=>Array.isArray(e[t])),s=[];for(const t of l)Array.isArray(e[t])&&s.push(t);for(const e of o)s.includes(e)||s.push(e);if(0===s.length)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:n??"No columnar data in this blob."});const i=s.reduce((t,r)=>Math.min(t,e[r].length),Number.POSITIVE_INFINITY),c=Number.isFinite(i)?i:0,d=Array.from({length:c},(t,r)=>{const a={__i:r};for(const t of s)a[t]=e[t][r];return a}),u=e=>{const t=a.units?.[e];return t?`${e} [${t}]`:e};return _jsxs(DataTable,{value:d,scrollable:!0,scrollHeight:"60vh",virtualScrollerOptions:{itemSize:32},emptyMessage:n??"No data.",size:"small",stripedRows:!0,children:[_jsx(Column,{field:"__i",header:"#",style:{width:"5rem",textAlign:"right"},bodyStyle:{fontVariantNumeric:"tabular-nums",textAlign:"right"}}),s.map(e=>_jsx(Column,{field:e,header:u(e),style:{minWidth:"8rem"},bodyStyle:{fontVariantNumeric:"tabular-nums",textAlign:"right"},body:t=>formatNumeric(t[e])},e))]})},formatNumeric=e=>null==e?"":"number"==typeof e&&Number.isFinite(e)?Number.parseFloat(e.toPrecision(6)).toString():String(e),CYCLE_VIRTUAL_THRESHOLD=30,CHART_COLORS=["#4ea8de","#f59e0b","#22c55e","#a855f7","#ef4444","#14b8a6","#eab308","#ec4899"],palette=e=>CHART_COLORS[e%CHART_COLORS.length],SG_ORDER=3,SMOOTH_TARGET_POINTS=800;function invertMatrix(e){const t=e.length,r=e.map((e,r)=>[...e,...Array.from({length:t},(e,t)=>r===t?1:0)]);for(let e=0;e<t;e++){let a=e;for(let n=e+1;n<t;n++)Math.abs(r[n][e])>Math.abs(r[a][e])&&(a=n);if(Math.abs(r[a][e])<1e-12)return null;[r[e],r[a]]=[r[a],r[e]];const n=r[e][e];for(let a=0;a<2*t;a++)r[e][a]/=n;for(let a=0;a<t;a++){if(a===e)continue;const n=r[a][e];if(0!==n)for(let l=0;l<2*t;l++)r[a][l]-=n*r[e][l]}}return r.map(e=>e.slice(t))}function sgWeights(e,t){const r=2*e+1,a=Math.min(t,r-1),n=[];for(let t=-e;t<=e;t++){const e=[];let r=1;for(let n=0;n<=a;n++)e.push(r),r*=t;n.push(e)}const l=a+1,o=Array.from({length:l},()=>new Array(l).fill(0));for(let e=0;e<l;e++)for(let t=0;t<l;t++){let a=0;for(let l=0;l<r;l++)a+=n[l][e]*n[l][t];o[e][t]=a}const s=invertMatrix(o);if(!s)return new Array(r).fill(1/r);const i=new Array(r);for(let e=0;e<r;e++){let t=0;for(let r=0;r<l;r++)t+=s[0][r]*n[e][r];i[e]=t}return i}function savitzkyGolay(e,t){const r=e.length;if(0===r||t<1)return e.slice();const a=new Map,n=e=>{let t=a.get(e);return t||(t=sgWeights(e,3),a.set(e,t)),t},l=new Array(r);for(let a=0;a<r;a++){const o=Math.min(t,a,r-1-a);if(o<1){l[a]=e[a];continue}const s=n(o);let i=0;for(let t=-o;t<=o;t++)i+=s[t+o]*e[a+t];l[a]=i}return l}function smoothTraceForDisplay(e,t,r){const a=Math.min(e.length,t.length);if(0===a)return[];const n=r&&r>1?Math.max(1,Math.floor((Math.min(r,a)-1)/2)):Math.max(2,Math.min(40,Math.round(a/250))),l=savitzkyGolay(t.slice(0,a),n),o=Math.max(1,Math.ceil(a/SMOOTH_TARGET_POINTS)),s=[];for(let t=0;t<a;t+=o)s.push({x:e[t],y:l[t]});return(a-1)%o!=0&&s.push({x:e[a-1],y:l[a-1]}),s}const DEFAULT_REGION_FILL="rgba(78, 168, 222, 0.15)",REGION_LABEL_COLOR="rgba(226, 232, 240, 0.85)";function buildRegionAnnotations(e){if(!e||0===e.length)return{};const t={};return e.forEach((e,r)=>{const a=!!e.borderColor;t[`region-${r}`]={type:"box",xScaleID:"x",xMin:e.xMin,xMax:e.xMax,backgroundColor:e.color??DEFAULT_REGION_FILL,borderColor:a?e.borderColor:"transparent",borderWidth:a?1:0,drawTime:"beforeDatasetsDraw",...e.label?{label:{display:!0,content:e.label,position:{x:"center",y:"start"},color:REGION_LABEL_COLOR,font:{size:11}}}:{}}}),t}const ChartOverlay=({children:e})=>_jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--text-secondary-color)",pointerEvents:"none"},children:e}),seriesLabel=e=>e.label??e.field??e.column??"",leftAxisLabel=e=>e?.y.filter(e=>"right"!==e.y_axis).map(seriesLabel).join(" / ")??"",rightAxisLabel=e=>e?.y.filter(e=>"right"===e.y_axis).map(seriesLabel).join(" / ")??"",isProjectScoped=e=>"project"===e.aggregate?.scope,toScienceColumn=(e,t=!1)=>({field:e.name,label:(e.label&&e.label.length>0?e.label:e.name)+(isProjectScoped(e)?" *":""),units:e.units,editable:t,body:t=>formatCell(t[e.name],e.type,e.scale)}),formatCell=(e,t,r)=>null==e?"":(r&&1!==r&&"number"==typeof e&&Number.isFinite(e)&&(e*=r),"f32"===t||"f64"===t?"number"==typeof e?e.toFixed(4):String(e):"object"==typeof e?JSON.stringify(e):String(e));
1
+ import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{useCallback,useContext,useEffect,useMemo,useRef,useState}from"react";import{Button}from"primereact/button";import{Column}from"primereact/column";import{DataTable}from"primereact/datatable";import{Dialog}from"primereact/dialog";import{Dropdown}from"primereact/dropdown";import{TabView,TabPanel}from"primereact/tabview";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import annotationPlugin from"chartjs-plugin-annotation";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";import{AutoCoreTagContext}from"../../core/AutoCoreTagContext";import{formatScaled}from"../../core/formatScaled";import{useRawCycleData}from"./useRawCycleData";import{ScienceTable}from"./ScienceTable";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin,annotationPlugin);export const TestDataView=e=>{const t=useTis(),r=e.projectId??t.selection.projectId,n=e.methodId??t.selection.methodId,a=e.runId??t.selection.runId,o=e.schema??(n?t.schemas[n]:void 0),{throttleMs:l=100,cycleTableHeight:i="400px",chartHeight:s="320px"}=e,{invoke:c,subscribe:d,unsubscribe:u}=useContext(EventEmitterContext),{scales:m}=useContext(AutoCoreTagContext),[p,y]=useState(null),[f,h]=useState([]),[g,_]=useState({}),[x,b]=useState({}),[j,v]=useState(!1),[w,C]=useState(!1),S=useCallback(async(e,t,o)=>{const l=e?.cycle_index;if(r&&n&&a&&l)try{const e=await c("tis.update_cycle",MessageType.Request,{project_id:r,method_id:n,run_id:a,cycle_index:l,fields:{[t]:o}});if(!1===e?.success)return;h(e=>e.map(e=>e?.cycle_index===l?{...e,[t]:o}:e))}catch(e){}},[c,r,n,a]),T=useRef(null),[R,O]=useState(null),[A,D]=useState(null),[M,E]=useState(!1),[L,I]=useState(null),[N,F]=useState(null),[k,q]=useState(!1),[H,P]=useState([]),[V,z]=useState(null),$=useMemo(()=>{const e=[];for(const[t,r]of Object.entries(o?.views??{}))e.push({name:t,view:r});return e},[o]),[B,G]=useState($.length>0?$[0].name:null);useEffect(()=>{if(0===$.length)return;null!==B&&$.some(e=>e.name===B)||G($[0].name)},[$,B]);const W=$.find(e=>e.name===B)?.view,U="raw_trace"===W?.type,J=useRef([]),X=useRef(null),Y=useRef(null),Z=()=>{Y.current||(Y.current=setTimeout(()=>{if(Y.current=null,J.current.length>0){const e=J.current;J.current=[],h(t=>[...e.slice().reverse(),...t])}X.current&&(_(X.current),X.current=null)},l))};useEffect(()=>{if(!r||!n||!a)return y(null),h([]),void _({});let e=!1;return(async()=>{try{const t=await c("tis.read_test",MessageType.Request,{project_id:r,method_id:n,run_id:a});!e&&t?.success&&(y(t.data),_(t.data.results??{}));const o=await c("tis.read_cycles",MessageType.Request,{project_id:r,method_id:n,run_id:a,offset:0,limit:200,order:"desc"});!e&&o?.success&&h(o.data.cycles??[])}catch(e){}})(),()=>{e=!0}},[r,n,a,c]),useEffect(()=>{const e=e=>e?.project_id===r&&e?.method_id===n&&e?.run_id===a,t=d("tis.cycle_added",t=>{e(t)&&t.cycle&&(J.current.push(t.cycle),Z())}),o=d("tis.results_updated",t=>{e(t)&&(X.current=t.results??{},Z())});return()=>{u(t),u(o),Y.current&&(clearTimeout(Y.current),Y.current=null)}},[r,n,a,l]);const K="string"==typeof p?.sample_id&&p.sample_id?p.sample_id:"string"==typeof p?.config?.sample_id?p.config.sample_id:"";useEffect(()=>{if(!r||!n||!K)return void b({});let e=!1;const t=async()=>{try{const t=await c("tis.sample_summary",MessageType.Request,{project_id:r,method_id:n,sample_id:K,run_id:a});!e&&t?.success&&b(t.data?.summary??{})}catch(e){}};t();const o=[d("tis.sample_summary_updated",e=>{e?.project_id===r&&e?.method_id===n&&e?.sample_id===K&&t()}),d("tis.cycle_added",e=>{e?.project_id===r&&e?.method_id===n&&t()})];return()=>{e=!0,o.forEach(u)}},[r,n,K,a,c,d,u]);const Q=useRawCycleData({projectId:r,methodId:n,runId:a,blobName:o?.raw_data?.blob_name??"trace",source:W?.source??"raw",enabled:U}),ee=useMemo(()=>{if(!W)return null;if("cycle_scatter"===W.type){const e=W.x.field;if(!e)return null;const t=[...f].reverse(),r=m?.[quantityOfField(o,e)??""],n=W.x_decimals??r?.precision??DEFAULT_X_DECIMALS;return{labels:t.map(t=>formatAxisTick(toDisplayValue(t[e],r),n)),datasets:W.y.map((e,r)=>({label:e.label??e.field,data:t.map(t=>toDisplayValue(t[e.field],m?.[quantityOfField(o,e.field)??""])),yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(r),backgroundColor:palette(r),tension:.1,pointRadius:2}))}}if("raw_trace"===W.type){if(!Q.raw)return null;const e=W.x.column;if(!e)return null;const t=m?.[quantityOfColumn(o,e)??""],r=Q.raw[e]??[],n=t?r.map(e=>toDisplayValue(e,t)):r,a=!1!==W.smooth;return{datasets:W.y.map((e,t)=>{const r=m?.[quantityOfColumn(o,e.column)??""],l=Q.raw[e.column]??[],i=r?l.map(e=>toDisplayValue(e,r)):l,s=a?smoothTraceForDisplay(n,i,W.smoothWindow):i.map((e,t)=>({x:n[t],y:e}));return{label:e.label??e.column,data:s,yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(t),backgroundColor:palette(t),pointRadius:0,borderWidth:1.5,showLine:!0,...a?{cubicInterpolationMode:"monotone"}:{}}})}}return null},[W,f,Q.raw,m,o]),te=W?.y.some(e=>"right"===e.y_axis)??!1,re=useMemo(()=>{if(!U)return[];const e=Q.envelope,t=e?.regions??e?.context?.regions;return Array.isArray(t)?t:[]},[U,Q.envelope]),ne=useMemo(()=>[...W?.regions??[],...re],[W,re]),ae=useMemo(()=>{const e="raw_trace"===W?.type,t=t=>{const r=e?quantityOfColumn(o,t.column):quantityOfField(o,t.field);return r?m?.[r]?.label:void 0},r=e?quantityOfColumn(o,W?.x.column):quantityOfField(o,W?.x.field),n=r?m?.[r]?.label:void 0,a=W?.x.label?n?`${W.x.label} [${n}]`:W.x.label:void 0,l=W?.x_decimals??(r?m?.[r]?.precision:void 0)??DEFAULT_X_DECIMALS,i={callback(t){const r=e?t:this?.getLabelForValue?.(t)??t;return formatAxisTick(r,l)}};return{responsive:!0,maintainAspectRatio:!1,parsing:!e&&void 0,scales:{x:e?{type:"linear",ticks:i,title:{display:!!a,text:a}}:{ticks:i,title:{display:!!a,text:a}},y:{position:"left",title:{display:!0,text:axisLabel(W,"left",t)}},...te?{y1:{position:"right",grid:{drawOnChartArea:!1},title:{display:!0,text:axisLabel(W,"right",t)}}}:{}},plugins:{legend:{display:!0},zoom:{pan:{enabled:!0,mode:"xy"},zoom:{wheel:{enabled:!0},pinch:{enabled:!0},mode:"xy"}},annotation:{annotations:buildRegionAnnotations(ne)}}}},[W,te,ne,m,o]),oe=o?.raw_data?.blob_name??"trace",le=useRef(""),ie=useCallback(async()=>{if(!r||!n||!a)return[];try{const e=await c("tis.list_raw",MessageType.Request,{project_id:r,method_id:n,run_id:a});if(!e?.success)return[];const t=e.data?.cycles??[];return t.filter(e=>e?.name===oe&&"number"==typeof e?.cycle_index).map(e=>e.cycle_index).sort((e,t)=>e-t)}catch{return[]}},[r,n,a,oe,c]),se=useCallback(async e=>{if(!r||!n||!a)return;const t=`${r}|${n}|${a}|${oe}|${e??"latest"}`;if(le.current===t)return;le.current=t;const o={project_id:r,method_id:n,run_id:a,name:oe};null!=e&&(o.cycle_index=e),E(!0),D(null),O(null);try{const e=await c("tis.read_raw",MessageType.Request,o);e?.success?O(e.data??{}):D(e?.error_message??"No raw data on disk for this run.")}catch(e){D(String(e?.message??e))}finally{E(!1)}q(!0),F(null),I(null);try{const e=await c("tis.read_filtered",MessageType.Request,o);e?.success?I(e.data??{}):F(e?.error_message??"No filtered data on disk for this run.")}catch(e){F(String(e?.message??e))}finally{q(!1)}},[r,n,a,oe,c]);useEffect(()=>{le.current="",P([]),z(null)},[r,n,a,oe]);return useEffect(()=>{j&&null!=V&&se(V)},[j,V,se]),r&&n&&a&&o?_jsxs("div",{className:"vblock",style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[_jsx(Header,{meta:p,config:p?.config,runId:a,projectId:r,methodId:n,canViewRaw:!!o.raw_data,onViewRaw:async()=>{v(!0);let e=H;0===e.length&&(e=await ie(),P(e));const t=e.length>0?e[e.length-1]:null,r=V??t;V!==r&&z(r),await se(r)},onShowConfig:()=>C(!0)}),_jsxs("div",{className:"p-card",style:{padding:"1rem"},children:[_jsxs("div",{className:"flex",style:{gap:"1rem",alignItems:"center",marginBottom:"0.5rem",flexWrap:"wrap"},children:[_jsx(Dropdown,{value:B,options:$.map(e=>({label:e.view.title??e.name,value:e.name})),onChange:e=>G(e.value),placeholder:0===$.length?"No view defined":"Select a view",disabled:0===$.length}),_jsx("h3",{style:{margin:0},children:W?.title??""}),U&&Q.cycles.length>1&&_jsxs(_Fragment,{children:[_jsx("label",{htmlFor:"chart-cycle-picker",style:{color:"var(--text-secondary-color)"},children:"Cycle:"}),_jsx(Dropdown,{inputId:"chart-cycle-picker",value:Q.selectedCycle,options:Q.cycles.map(e=>({label:`Cycle ${e}`,value:e})),onChange:e=>Q.setSelectedCycle(Number(e.value)),style:{minWidth:"8rem"}}),_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:["of ",Q.cycles.length]})]}),_jsx("div",{style:{flex:1}}),_jsx(Button,{icon:"pi pi-th-large",outlined:!0,rounded:!0,size:"small",onClick:()=>T.current?.resetZoom?.(),disabled:!ee,tooltip:"Reset chart zoom",tooltipOptions:{position:"left"},"aria-label":"Reset chart zoom"})]}),_jsxs("div",{style:{height:s,position:"relative"},children:[U&&Q.loading&&_jsx(ChartOverlay,{children:"Loading raw data…"}),U&&Q.error&&_jsx(ChartOverlay,{children:Q.error}),ee&&_jsx(Line,{ref:T,data:ee,options:ae})]})]}),(()=>{const e=f.length>CYCLE_VIRTUAL_THRESHOLD,t=[...(o.cycle_config_fields??[]).map(e=>toScienceColumn(e,!0,m)),...(o.cycle_fields??[]).map(e=>toScienceColumn(e,!!e.editable,m))];return _jsx(ScienceTable,{title:`Cycle Data (${f.length})`,columns:t,rows:f,indexOrder:"descending",scrollable:e,scrollHeight:e?i:void 0,emptyMessage:"No cycles yet.",onCellEdit:S})})(),(()=>{const e={...g,...x},t=Object.keys(e).length>0,r=o.results_fields??[],n=r.map(e=>toScienceColumn(e,!1,m)),a=r.some(isProjectScoped);return _jsxs(_Fragment,{children:[_jsx(ScienceTable,{title:"Results",columns:n,rows:t?[e]:[],emptyMessage:"No results yet."}),a&&_jsx("div",{style:{fontSize:"0.8rem",color:"var(--text-secondary-color)",margin:"0.25rem 0 0.75rem"},children:"* across every test of this sample in the project. All other values describe this test."})]})})(),o.raw_data&&_jsxs(Dialog,{visible:j,onHide:()=>v(!1),header:`Run Data — ${a}`,style:{width:"90vw",height:"80vh"},maximizable:!0,children:[_jsx(CyclePickerBar,{cycles:H,selected:V,onChange:z}),_jsx(RawEnvelopeHeader,{envelope:R}),_jsxs(TabView,{style:{height:"100%"},children:[_jsx(TabPanel,{header:"Raw Data",children:_jsx(DataBlobTable,{blob:unwrapEnvelope(R),loading:M,error:A,rawData:o.raw_data})}),_jsx(TabPanel,{header:"Filtered Data",children:_jsx(DataBlobTable,{blob:unwrapEnvelope(L),loading:k,error:N,rawData:o.raw_data,emptyMessage:"Filtered data is written by post-processing — none on disk for this run yet."})})]})]}),_jsx(Dialog,{visible:w,onHide:()=>C(!1),header:"Test Configuration",style:{width:"min(640px, 90vw)"},modal:!0,children:_jsx(ConfigList,{config:p?.config})})]}):_jsx("div",{className:"p-card",style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"No test selected. Pick a row from the History tab or start a run."})};const Header=({meta:e,config:t,runId:r,projectId:n,methodId:a,canViewRaw:o,onViewRaw:l,onShowConfig:i})=>{const s="string"==typeof e?.sample_id&&e.sample_id||"string"==typeof e?.config?.sample_id&&e.config.sample_id||"",c=t&&"object"==typeof t&&Object.entries(t).some(([e])=>"sample_id"!==e);return _jsx("div",{className:"p-card",style:{padding:"1rem"},children:_jsxs("div",{className:"flex",style:{justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[_jsxs("div",{children:[_jsxs("h2",{style:{margin:0,display:"flex",alignItems:"center",gap:"0.5rem"},children:[s||r,c&&_jsx(Button,{icon:"pi pi-info-circle",type:"button",rounded:!0,text:!0,onClick:i,tooltip:"Show test configuration",tooltipOptions:{position:"top"},style:{width:"2rem",height:"2rem",padding:0},"aria-label":"Show test configuration"})]}),_jsxs("div",{style:{color:"var(--text-secondary-color)",fontSize:"0.85em"},children:["project: ",n," · method: ",a," · run: ",r,e?.start_time&&_jsxs(_Fragment,{children:[" · started: ",new Date(e.start_time).toLocaleString()]})]})]}),o&&_jsx(Button,{icon:"pi pi-table",label:"View Raw Data",onClick:l,outlined:!0})]})})},ConfigList=({config:e})=>{const t=e&&"object"==typeof e?Object.entries(e).filter(([e])=>"sample_id"!==e):[];return 0===t.length?_jsx("div",{style:{color:"var(--text-secondary-color)"},children:"No configuration recorded for this run."}):_jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"0.5rem 1rem",fontSize:"0.95em"},children:t.map(([e,t])=>_jsxs(React.Fragment,{children:[_jsx("div",{style:{color:"var(--text-secondary-color)"},children:e}),_jsx("div",{children:formatCell(t,"string")})]},e))})},unwrapEnvelope=e=>e&&"object"==typeof e&&"data"in e&&e.data&&"object"==typeof e.data&&Object.values(e.data).some(e=>Array.isArray(e))?e.data:e,CyclePickerBar=({cycles:e,selected:t,onChange:r})=>e.length<=1?null:_jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.25rem 0.5rem 0.5rem"},children:[_jsx("label",{htmlFor:"raw-cycle-picker",style:{color:"var(--text-secondary-color)"},children:"Cycle:"}),_jsx(Dropdown,{inputId:"raw-cycle-picker",value:t,options:e.map(e=>({label:`Cycle ${e}`,value:e})),onChange:e=>r(Number(e.value)),style:{minWidth:"8rem"}}),_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:["(",e.length," cycles recorded)"]})]}),RawEnvelopeHeader=({envelope:e})=>{if(!e||"object"!=typeof e)return null;const t=e.cycle_index,r=e.cycle_fields,n=e.context;if(null==t&&!r&&!n)return null;const a=e=>{if(!e||"object"!=typeof e)return null;const t=Object.entries(e).filter(([,e])=>null!==e&&"object"!=typeof e);return 0===t.length?null:t.map(([e,t])=>_jsxs("span",{style:{marginRight:"1rem"},children:[_jsxs("span",{style:{color:"var(--text-secondary-color)"},children:[e,": "]}),_jsx("span",{children:String(t)})]},e))};return _jsxs("div",{style:{padding:"0.5rem",borderBottom:"1px solid var(--surface-border)",fontSize:"0.9rem"},children:[null!=t&&_jsx("div",{children:_jsxs("strong",{children:["Cycle ",t]})}),r&&_jsx("div",{style:{marginTop:"0.25rem"},children:a(r)}),n&&_jsx("div",{style:{marginTop:"0.25rem"},children:a(n)})]})},DataBlobTable=({blob:e,loading:t,error:r,rawData:n,emptyMessage:a})=>{if(t)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"Loading…"});if(r)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:a??r});if(!e||"object"!=typeof e)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:"No data."});const o=Object.keys(n.columns??{}),l=Object.keys(e).filter(t=>Array.isArray(e[t])),i=[];for(const t of o)Array.isArray(e[t])&&i.push(t);for(const e of l)i.includes(e)||i.push(e);if(0===i.length)return _jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:a??"No columnar data in this blob."});const s=i.reduce((t,r)=>Math.min(t,e[r].length),Number.POSITIVE_INFINITY),c=Number.isFinite(s)?s:0,d=Array.from({length:c},(t,r)=>{const n={__i:r};for(const t of i)n[t]=e[t][r];return n}),u=e=>{const t=n.units?.[e];return t?`${e} [${t}]`:e};return _jsxs(DataTable,{value:d,scrollable:!0,scrollHeight:"60vh",virtualScrollerOptions:{itemSize:32},emptyMessage:a??"No data.",size:"small",stripedRows:!0,children:[_jsx(Column,{field:"__i",header:"#",style:{width:"5rem",textAlign:"right"},bodyStyle:{fontVariantNumeric:"tabular-nums",textAlign:"right"}}),i.map(e=>_jsx(Column,{field:e,header:u(e),style:{minWidth:"8rem"},bodyStyle:{fontVariantNumeric:"tabular-nums",textAlign:"right"},body:t=>formatNumeric(t[e])},e))]})},formatNumeric=e=>null==e?"":"number"==typeof e&&Number.isFinite(e)?Number.parseFloat(e.toPrecision(6)).toString():String(e),CYCLE_VIRTUAL_THRESHOLD=30,CHART_COLORS=["#4ea8de","#f59e0b","#22c55e","#a855f7","#ef4444","#14b8a6","#eab308","#ec4899"],palette=e=>CHART_COLORS[e%CHART_COLORS.length],SG_ORDER=3,SMOOTH_TARGET_POINTS=800;function invertMatrix(e){const t=e.length,r=e.map((e,r)=>[...e,...Array.from({length:t},(e,t)=>r===t?1:0)]);for(let e=0;e<t;e++){let n=e;for(let a=e+1;a<t;a++)Math.abs(r[a][e])>Math.abs(r[n][e])&&(n=a);if(Math.abs(r[n][e])<1e-12)return null;[r[e],r[n]]=[r[n],r[e]];const a=r[e][e];for(let n=0;n<2*t;n++)r[e][n]/=a;for(let n=0;n<t;n++){if(n===e)continue;const a=r[n][e];if(0!==a)for(let o=0;o<2*t;o++)r[n][o]-=a*r[e][o]}}return r.map(e=>e.slice(t))}function sgWeights(e,t){const r=2*e+1,n=Math.min(t,r-1),a=[];for(let t=-e;t<=e;t++){const e=[];let r=1;for(let a=0;a<=n;a++)e.push(r),r*=t;a.push(e)}const o=n+1,l=Array.from({length:o},()=>new Array(o).fill(0));for(let e=0;e<o;e++)for(let t=0;t<o;t++){let n=0;for(let o=0;o<r;o++)n+=a[o][e]*a[o][t];l[e][t]=n}const i=invertMatrix(l);if(!i)return new Array(r).fill(1/r);const s=new Array(r);for(let e=0;e<r;e++){let t=0;for(let r=0;r<o;r++)t+=i[0][r]*a[e][r];s[e]=t}return s}function savitzkyGolay(e,t){const r=e.length;if(0===r||t<1)return e.slice();const n=new Map,a=e=>{let t=n.get(e);return t||(t=sgWeights(e,3),n.set(e,t)),t},o=new Array(r);for(let n=0;n<r;n++){const l=Math.min(t,n,r-1-n);if(l<1){o[n]=e[n];continue}const i=a(l);let s=0;for(let t=-l;t<=l;t++)s+=i[t+l]*e[n+t];o[n]=s}return o}function smoothTraceForDisplay(e,t,r){const n=Math.min(e.length,t.length);if(0===n)return[];const a=r&&r>1?Math.max(1,Math.floor((Math.min(r,n)-1)/2)):Math.max(2,Math.min(40,Math.round(n/250))),o=savitzkyGolay(t.slice(0,n),a),l=Math.max(1,Math.ceil(n/SMOOTH_TARGET_POINTS)),i=[];for(let t=0;t<n;t+=l)i.push({x:e[t],y:o[t]});return(n-1)%l!=0&&i.push({x:e[n-1],y:o[n-1]}),i}const DEFAULT_REGION_FILL="rgba(78, 168, 222, 0.15)",REGION_LABEL_COLOR="rgba(226, 232, 240, 0.85)";function buildRegionAnnotations(e){if(!e||0===e.length)return{};const t={};return e.forEach((e,r)=>{const n=!!e.borderColor;t[`region-${r}`]={type:"box",xScaleID:"x",xMin:e.xMin,xMax:e.xMax,backgroundColor:e.color??DEFAULT_REGION_FILL,borderColor:n?e.borderColor:"transparent",borderWidth:n?1:0,drawTime:"beforeDatasetsDraw",...e.label?{label:{display:!0,content:e.label,position:{x:"center",y:"start"},color:REGION_LABEL_COLOR,font:{size:11}}}:{}}}),t}const ChartOverlay=({children:e})=>_jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--text-secondary-color)",pointerEvents:"none"},children:e});export const DEFAULT_X_DECIMALS=2;const formatAxisTick=(e,t)=>{const r="number"==typeof e?e:Number(e);return Number.isFinite(r)?Number.parseFloat(r.toFixed(t)).toString():null==e?"":String(e)},quantityOfField=(e,t)=>{if(e&&t)for(const r of[e.cycle_config_fields,e.cycle_fields,e.results_fields]){const e=(r??[]).find(e=>e.name===t);if(e?.quantity)return e.quantity}},quantityOfColumn=(e,t)=>{if(e&&t)return e.raw_data?.columns?.[t]?.quantity},toDisplayValue=(e,t)=>t&&"number"==typeof e&&Number.isFinite(e)?e*t.scale+(t.offset??0):e,seriesLabel=e=>e.label??e.field??e.column??"",axisLabel=(e,t,r)=>{const n=e?.y.filter(e=>"right"===e.y_axis==("right"===t))??[],a=n.map(seriesLabel).join(" / "),o=Array.from(new Set(n.map(r).filter(Boolean)));return 1===o.length?`${a} [${o[0]}]`:a},isProjectScoped=e=>"project"===e.aggregate?.scope,toScienceColumn=(e,t=!1,r)=>{const n=e.quantity?r?.[e.quantity]:void 0;return{field:e.name,label:(e.label&&e.label.length>0?e.label:e.name)+(isProjectScoped(e)?" *":""),units:n?n.label:e.units,editable:t,body:t=>formatCell(t[e.name],e.type,e.scale,n)}},formatCell=(e,t,r,n)=>null==e?"":n&&"number"==typeof e&&Number.isFinite(e)?formatScaled(e*n.scale+(n.offset??0),n):(r&&1!==r&&"number"==typeof e&&Number.isFinite(e)&&(e*=r),"f32"===t||"f64"===t?"number"==typeof e?e.toFixed(4):String(e):"object"==typeof e?JSON.stringify(e):String(e));
@@ -8,6 +8,13 @@ export interface TestFieldDef {
8
8
  /** Canonical key — wire format, generated code, on-disk JSON. */
9
9
  name: string;
10
10
  type: string;
11
+ /**
12
+ * Scale-group name from the machine's `units.json` ("force", "position", …).
13
+ * When set, this field is displayed and entered in the operator's ACTIVE
14
+ * unit system and its label carries that unit; storage stays backend.
15
+ * Supersedes `units` / `scale` below.
16
+ */
17
+ quantity?: string;
11
18
  units?: string;
12
19
  required?: boolean;
13
20
  source?: string;
@@ -38,11 +45,20 @@ export interface TestFieldDef {
38
45
  * Cycle and results values are scaled by the corresponding paths
39
46
  * in TestDataView; the server scales CSV exports too. */
40
47
  scale?: number;
41
- /** Optional inclusive bounds (display units, same convention as `default`
42
- * and `scale`) for the operator's numeric entry. The numeric input
43
- * rejects values outside `[min, max]`; non-numeric fields ignore them. */
44
- min?: number;
45
- max?: number;
48
+ /** Optional inclusive bounds for the operator's numeric entry. The numeric
49
+ * input rejects values outside `[min, max]`; non-numeric fields ignore them.
50
+ *
51
+ * A `number` is authored in DISPLAY units (same convention as `default`
52
+ * and `scale`). A `string` is an FQDN token `"${gm.<var>}"`, resolved LIVE
53
+ * from that tag — for a bound that belongs to the MACHINE rather than the
54
+ * method, the load-cell force ceiling being the motivating case: hard-code
55
+ * it and it is wrong the moment a different cell is fitted, and the
56
+ * operator hits a wall the machine could have moved for them.
57
+ *
58
+ * `effectiveField` resolves tokens, so everything downstream of it
59
+ * (`rangeIssue`, the input's bounds) only ever sees numbers. */
60
+ min?: number | string;
61
+ max?: number | string;
46
62
  /** Optional fixed set of choices. When present, the field renders
47
63
  * as a dropdown and the operator must pick one of the declared
48
64
  * values rather than typing freely. Each entry is either a bare
@@ -86,8 +102,54 @@ export type CycleConfigScope = 'run' | 'cycle';
86
102
  * display value, so scales can change in project.json without
87
103
  * invalidating historical records.
88
104
  */
89
- export declare const rawToDisplay: (raw: any, scale: number | undefined) => any;
90
- export declare const displayToRaw: (display: any, scale: number | undefined) => any;
105
+ export declare const rawToDisplay: (raw: any, scale: number | undefined, offset?: number) => any;
106
+ export declare const displayToRaw: (display: any, scale: number | undefined, offset?: number) => any;
107
+ /**
108
+ * Resolve a field against the machine's units table.
109
+ *
110
+ * Returns the field with `scale` / `units` overridden by the operator's ACTIVE
111
+ * unit system when it declares a `quantity`. Doing it this way means every
112
+ * existing `rawToDisplay(v, f.scale)` / `labelOf(f)` call site keeps working and
113
+ * automatically follows a Metric/Imperial switch — the alternative was threading
114
+ * a units argument through a dozen call sites.
115
+ *
116
+ * A field with no `quantity` (or a machine with no units table) is returned
117
+ * unchanged, so an un-annotated method behaves exactly as before.
118
+ */
119
+ export declare const effectiveField: (f: TestFieldDef, unitScales?: Record<string, {
120
+ scale: number;
121
+ label: string;
122
+ offset?: number;
123
+ }>, tags?: TagLookup) => EffectiveField;
124
+ /** What `effectiveField` needs to resolve an `${fqdn}` bound. */
125
+ export interface TagLookup {
126
+ findTagByFqdn: (fqdn: string) => {
127
+ tagName: string;
128
+ } | undefined;
129
+ rawValues: Record<string, unknown>;
130
+ }
131
+ /**
132
+ * A declared bound resolved to a plain DISPLAY-unit number, or `undefined` for
133
+ * "no bound".
134
+ *
135
+ * A number passes through — it was already authored in display units. A token
136
+ * is looked up as a tag, whose value is RAW, and converted with the same scale
137
+ * and offset as the value it will be compared against; otherwise an imperial or
138
+ * affine field would compare two numbers from different spaces.
139
+ *
140
+ * An unresolvable token yields `undefined`, i.e. NO bound — never zero, which
141
+ * would silently reject every entry. Fail-open is deliberate here: this is an
142
+ * authoring aid, and walling off a field because a tag has not arrived yet would
143
+ * make a machine unusable at startup. The interlock that matters lives in the
144
+ * machine, not in this form.
145
+ */
146
+ export declare const resolveBound: (bound: number | string | undefined, scale: number | undefined, offset: number, tags?: TagLookup) => number | undefined;
147
+ /** A field with its units applied and its bounds resolved to numbers. */
148
+ export type EffectiveField = TestFieldDef & {
149
+ unitOffset?: number;
150
+ min?: number;
151
+ max?: number;
152
+ };
91
153
  /** Field label with `[units]` appended when declared. */
92
154
  export declare const labelOf: (f: TestFieldDef) => string;
93
155
  export declare const hasDescription: (f: TestFieldDef) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"TestFieldRow.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestFieldRow.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestFieldRow.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestFieldRow.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React from"react";import{Button}from"primereact/button";import{Dropdown}from"primereact/dropdown";import{ValueInput}from"../ValueInput";import{TextInput}from"../TextInput";export const rawToDisplay=(e,l)=>l&&1!==l&&"number"==typeof e&&Number.isFinite(e)?e*l:e;export const displayToRaw=(e,l)=>l&&1!==l&&"number"==typeof e&&Number.isFinite(e)?e/l:e;export const labelOf=e=>{const l=e.label&&e.label.length>0?e.label:e.name;return e.units?`${l} [${e.units}]`:l};export const hasDescription=e=>"string"==typeof e.description&&e.description.length>0;export const fieldValueIsEmpty=e=>null==e||"string"==typeof e&&""===e.trim();export const rangeIssue=(e,l)=>{if(fieldValueIsEmpty(l)||""===l)return null;if(null==e.min&&null==e.max)return null;const n=Number(rawToDisplay(Number(l),e.scale));if(!Number.isFinite(n))return null;const a=null!=e.min&&null!=e.max?Math.min(e.min,e.max):e.min,t=null!=e.min&&null!=e.max?Math.max(e.min,e.max):e.max;return null!=a&&n<a?`must be ≥ ${a}`:null!=t&&n>t?`must be ≤ ${t}`:null};export const fieldIssue=(e,l)=>e.required&&fieldValueIsEmpty(l)?"is required":rangeIssue(e,l);export const fieldIsValid=(e,l)=>null===fieldIssue(e,l);export const normalizeOptions=e=>(e??[]).map(e=>null!==e&&"object"==typeof e?{label:String(e.label??e.value),value:e.value}:{label:String(e),value:e});export const TestFieldRow=({field:e,value:l,onChange:n,valid:a,disabled:t,control:i,onInfo:r})=>{const s=a??fieldIsValid(e,l),o=!i&&Array.isArray(e.options)&&e.options.length>0?normalizeOptions(e.options):null,u=!i&&!o&&"string"!==e.type&&"bool"!==e.type,p=i??(o?_jsx(Dropdown,{value:l??null,options:o,onChange:e=>n(e.value),placeholder:`Select ${e.label??e.name}…`,className:"ac-dropdown-clearable"+(s?"":" p-invalid"),showClear:!e.required,disabled:t}):u?_jsx(ValueInput,{label:void 0,value:null!=l?Number(rawToDisplay(Number(l),e.scale)):null,min:e.min,max:e.max,onValueChanged:l=>n(displayToRaw(l,e.scale)),className:s?"":"p-invalid",disabled:t}):_jsx(TextInput,{label:void 0,value:null!=l?String(l):"",onValueChanged:e=>n(e),className:s?"":"p-invalid",disabled:t}));return _jsxs(React.Fragment,{children:[_jsx("span",{className:"ac-form-label",children:labelOf(e)}),p,r&&hasDescription(e)?_jsx(Button,{icon:"pi pi-info-circle",text:!0,rounded:!0,"aria-label":`About ${labelOf(e)}`,onClick:()=>r(e)}):_jsx("span",{"aria-hidden":"true"}),_jsx("span",{style:{color:s?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:s?"pi pi-check":"pi pi-times"})})]})};
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useContext}from"react";import{AutoCoreTagContext}from"../../core/AutoCoreTagContext";import{Button}from"primereact/button";import{Dropdown}from"primereact/dropdown";import{ValueInput}from"../ValueInput";import{TextInput}from"../TextInput";export const rawToDisplay=(e,t,n=0)=>(t&&1!==t||n)&&"number"==typeof e&&Number.isFinite(e)?e*(t??1)+n:e;export const displayToRaw=(e,t,n=0)=>(t&&1!==t||n)&&"number"==typeof e&&Number.isFinite(e)?(e-n)/(t??1):e;export const effectiveField=(e,t,n)=>{const l=e.quantity?t?.[e.quantity]:void 0,o=l?l.scale:e.scale,a=l?l.offset??0:0;return{...l?{...e,scale:o,units:l.label,unitOffset:a}:{...e},min:resolveBound(e.min,o,a,n),max:resolveBound(e.max,o,a,n)}};const BOUND_TOKEN_RE=/^\$\{\s*([^}]+?)\s*\}$/;export const resolveBound=(e,t,n,l)=>{if("number"==typeof e)return e;if("string"!=typeof e||!l)return;const o=e.match(BOUND_TOKEN_RE);if(!o)return;const a=l.findTagByFqdn(o[1]),i=a?l.rawValues[a.tagName]:void 0;if("number"!=typeof i||!Number.isFinite(i))return;const r=Number(rawToDisplay(i,t,n));return Number.isFinite(r)?r:void 0};export const labelOf=e=>{const t=e.label&&e.label.length>0?e.label:e.name;return e.units?`${t} [${e.units}]`:t};export const hasDescription=e=>"string"==typeof e.description&&e.description.length>0;export const fieldValueIsEmpty=e=>null==e||"string"==typeof e&&""===e.trim();export const rangeIssue=(e,t)=>{if(fieldValueIsEmpty(t)||""===t)return null;const n="number"==typeof e.min?e.min:void 0,l="number"==typeof e.max?e.max:void 0;if(null==n&&null==l)return null;const o=Number(rawToDisplay(Number(t),e.scale,e.unitOffset??0));if(!Number.isFinite(o))return null;const a=null!=n&&null!=l?Math.min(n,l):n,i=null!=n&&null!=l?Math.max(n,l):l;return null!=a&&o<a?`must be ≥ ${a}`:null!=i&&o>i?`must be ≤ ${i}`:null};export const fieldIssue=(e,t)=>e.required&&fieldValueIsEmpty(t)?"is required":rangeIssue(e,t);export const fieldIsValid=(e,t)=>null===fieldIssue(e,t);export const normalizeOptions=e=>(e??[]).map(e=>null!==e&&"object"==typeof e?{label:String(e.label??e.value),value:e.value}:{label:String(e),value:e});export const TestFieldRow=({field:e,value:t,onChange:n,valid:l,disabled:o,control:a,onInfo:i})=>{const{scales:r,rawValues:s,findTagByFqdn:u}=useContext(AutoCoreTagContext),p=effectiveField(e,r,{findTagByFqdn:u,rawValues:s}),m=p.unitOffset??0,c=l??fieldIsValid(p,t),d=!a&&Array.isArray(p.options)&&p.options.length>0?normalizeOptions(p.options):null,f=!a&&!d&&"string"!==p.type&&"bool"!==p.type,x=a??(d?_jsx(Dropdown,{value:t??null,options:d,onChange:e=>n(e.value),placeholder:`Select ${p.label??p.name}…`,className:"ac-dropdown-clearable"+(c?"":" p-invalid"),showClear:!p.required,disabled:o}):f?_jsx(ValueInput,{label:void 0,value:null!=t?Number(rawToDisplay(Number(t),p.scale,m)):null,min:p.min,max:p.max,onValueChanged:e=>n(displayToRaw(e,p.scale,m)),className:c?"":"p-invalid",disabled:o}):_jsx(TextInput,{label:void 0,value:null!=t?String(t):"",onValueChanged:e=>n(e),className:c?"":"p-invalid",disabled:o}));return _jsxs(React.Fragment,{children:[_jsx("span",{className:"ac-form-label",children:labelOf(p)}),x,i&&hasDescription(p)?_jsx(Button,{icon:"pi pi-info-circle",text:!0,rounded:!0,"aria-label":`About ${labelOf(p)}`,onClick:()=>i(p)}):_jsx("span",{"aria-hidden":"true"}),_jsx("span",{style:{color:c?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:c?"pi pi-check":"pi pi-times"})})]})};
@@ -1 +1 @@
1
- {"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAMH,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACpB,MAAM,gBAAgB,CAAC;AAMxB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,GAAG,aAAa,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,YAAY,EAAE,CAAC;IACrC;;0DAEsD;IACtD,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IACtC;+DAC2D;IAC3D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B;0CACsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2CACuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;gEAG4D;IAC5D,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf;;sDAEkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAC9B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAChE;AAwGD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAikBtD,CAAC"}
1
+ {"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAOH,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACpB,MAAM,gBAAgB,CAAC;AAMxB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,GAAG,aAAa,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,YAAY,EAAE,CAAC;IACrC;;0DAEsD;IACtD,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IACtC;+DAC2D;IAC3D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B;0CACsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2CACuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;gEAG4D;IAC5D,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf;;sDAEkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAC9B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAChE;AAwGD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA4lBtD,CAAC"}