@adcops/autocore-react 3.3.50 → 3.3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/tis/ResultHistoryTable.d.ts +14 -2
- package/dist/components/tis/ResultHistoryTable.d.ts.map +1 -1
- package/dist/components/tis/ResultHistoryTable.js +1 -1
- package/dist/components/tis/TestDataView.d.ts +9 -5
- package/dist/components/tis/TestDataView.d.ts.map +1 -1
- package/dist/components/tis/TestDataView.js +1 -1
- package/dist/components/tis/TestRawDataView.d.ts +9 -5
- package/dist/components/tis/TestRawDataView.d.ts.map +1 -1
- package/dist/components/tis/TestRawDataView.js +1 -1
- package/dist/components/tis/TestSetupForm.d.ts +15 -4
- package/dist/components/tis/TestSetupForm.d.ts.map +1 -1
- package/dist/components/tis/TestSetupForm.js +1 -1
- package/dist/components/tis/TisProvider.d.ts +93 -0
- package/dist/components/tis/TisProvider.d.ts.map +1 -0
- package/dist/components/tis/TisProvider.js +1 -0
- package/dist/hub/HubWebSocket.d.ts +13 -0
- package/dist/hub/HubWebSocket.d.ts.map +1 -1
- package/dist/hub/HubWebSocket.js +1 -1
- package/package.json +1 -1
- package/src/components/index.ts +22 -1
- package/src/components/tis/ResultHistoryTable.tsx +133 -48
- package/src/components/tis/TestDataView.tsx +70 -36
- package/src/components/tis/TestRawDataView.tsx +39 -22
- package/src/components/tis/TestSetupForm.tsx +155 -96
- package/src/components/tis/TisProvider.tsx +405 -0
- package/src/hub/HubWebSocket.ts +66 -3
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { TisProvider, TisContext, useTis, useTisSchemas, useTisState, useTisSelection, useTisRuns, useTisRun, } from './tis/TisProvider';
|
|
2
|
+
export type { TisProviderProps, TisContextValue, TisLiveState, TisSelection, TisSelectionPatch, TisRunCacheEntry, SchemaRegistry, TisMethodSchema, } from './tis/TisProvider';
|
|
1
3
|
export { TestSetupForm } from './tis/TestSetupForm';
|
|
2
4
|
export type { TestSetupFormProps } from './tis/TestSetupForm';
|
|
3
5
|
export { ResultHistoryTable } from './tis/ResultHistoryTable';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAY,qBAAqB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAO,0BAA0B,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAa,oBAAoB,CAAC;AACzD,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"}
|
|
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,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACR,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,MAAY,qBAAqB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAO,0BAA0B,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAa,oBAAoB,CAAC;AACzD,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"}
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{TestSetupForm}from"./tis/TestSetupForm";export{ResultHistoryTable}from"./tis/ResultHistoryTable";export{TestDataView}from"./tis/TestDataView";export{TestRawDataView}from"./tis/TestRawDataView";
|
|
1
|
+
export{TisProvider,TisContext,useTis,useTisSchemas,useTisState,useTisSelection,useTisRuns,useTisRun}from"./tis/TisProvider";export{TestSetupForm}from"./tis/TestSetupForm";export{ResultHistoryTable}from"./tis/ResultHistoryTable";export{TestDataView}from"./tis/TestDataView";export{TestRawDataView}from"./tis/TestRawDataView";
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface ResultHistoryTableProps {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Override the project scope. When omitted, the table reads from
|
|
5
|
+
* `useTisSelection().projectId` and follows the active project.
|
|
6
|
+
*/
|
|
7
|
+
projectId?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional method-id filter. When omitted, the table aggregates every
|
|
10
|
+
* run under the project regardless of which method it belongs to —
|
|
11
|
+
* that's the default the operator wants on the History tab so that
|
|
12
|
+
* switching the loaded method on the Setup tab doesn't hide
|
|
13
|
+
* already-recorded data. When supplied, the table is scoped to that
|
|
14
|
+
* single method.
|
|
15
|
+
*/
|
|
16
|
+
methodId?: string;
|
|
5
17
|
}
|
|
6
18
|
export declare const ResultHistoryTable: React.FC<ResultHistoryTableProps>;
|
|
7
19
|
//# sourceMappingURL=ResultHistoryTable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResultHistoryTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ResultHistoryTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ResultHistoryTable.d.ts","sourceRoot":"","sources":["../../../src/components/tis/ResultHistoryTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAQ/D,MAAM,WAAW,uBAAuB;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAwDD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqMhE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import{DataTable}from"primereact/datatable";import{Column}from"primereact/column";import{Button}from"primereact/button";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";const rawBlobToCsv=e=>{if(!e||"object"!=typeof e)return"";const t=Object.entries(e).filter(([,e])=>Array.isArray(e));if(0===t.length)return"";t.sort(([e],[t])=>"t"===e?-1:"t"===t?1:0);const r=t.map(([e])=>e),o=t.reduce((e,[,t])=>Math.min(e,t.length),1/0),s=e=>{if(null==e)return"";const t=String(e);return/[",\n\r]/.test(t)?`"${t.replace(/"/g,'""')}"`:t},i=[r.join(",")];for(let e=0;e<o;e++)i.push(t.map(([,t])=>s(t[e])).join(","));return i.join("\n")},downloadCsv=(e,t)=>{const r=new Blob([t],{type:"text/csv;charset=utf-8;"}),o=URL.createObjectURL(r),s=document.createElement("a");s.href=o,s.download=e,document.body.appendChild(s),s.click(),s.remove(),URL.revokeObjectURL(o)};export const ResultHistoryTable=e=>{const t=useTis(),r=e.projectId??t.selection.projectId,o=e.methodId,[s,i]=useState([]),[n,a]=useState(!1),[l,d]=useState(null),{invoke:c}=useContext(EventEmitterContext),m=async()=>{if(r){a(!0);try{const e={project_id:r};o&&(e.method_id=o);const t=await c("tis.list_tests",MessageType.Request,e);t.success&&t.data&&t.data.tests&&i(t.data.tests)}catch(e){}a(!1)}else i([])};useEffect(()=>{m()},[r,o,t.state.activeRunId]);const u=async(e,t)=>{const s=e?.run_id,i=e?.method_id??o;if(!s||!i)return;const n="raw"===t?"tis.read_raw":"tis.read_filtered",a="raw"===t?"raw trace":"filtered trace",l="raw"===t?"raw":"filtered";d({runId:s,kind:t});try{const e=await c(n,MessageType.Request,{project_id:r,method_id:i,run_id:s,name:"trace"});if(!e?.success||!e.data)return void alert(`No ${a} available for ${s}`+(e?.error_message?`: ${e.error_message}`:""));const t=rawBlobToCsv(e.data);if(!t)return void alert(`${a} for ${s} is empty or has no array columns.`);downloadCsv(`${r}_${i}_${s}_${l}.csv`,t)}catch(e){alert(`Download failed: ${e instanceof Error?e.message:String(e)}`)}finally{d(null)}},p=e=>{const t="string"==typeof e?.sample_id?e.sample_id:"";if(t)return t;const r=e?.config;return r&&"object"==typeof r&&"string"==typeof r.sample_id?r.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"},children:[_jsx("h3",{style:{margin:0},children:r?`Test History: ${r}${o?` / ${o}`:""}`:"Test History (no project selected)"}),_jsx(Button,{icon:"pi pi-refresh",label:"Refresh",onClick:m,disabled:n})]}),_jsxs(DataTable,{value:s,loading:n,paginator:!0,rows:10,emptyMessage:"No tests found.",scrollable:!0,scrollHeight:"flex",tableStyle:{minWidth:0},style:{width:"100%"},selectionMode:"single",onSelectionChange:e=>{const r=e.value;r?.run_id&&t.setSelection({projectId:r.project_id??null,methodId:r.method_id??null,runId:r.run_id})},children:[_jsx(Column,{header:"Sample ID",sortable:!0,body:p,sortFunction:e=>{const t=[...e.data];return t.sort((t,r)=>p(t).localeCompare(p(r))*(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,{field:"run_id",header:"Run ID",sortable:!0,style:{minWidth:"12rem"}}),_jsx(Column,{header:"Download",style:{width:"14rem"},body:e=>{const t=l?.runId===e.run_id&&"raw"===l?.kind,r=l?.runId===e.run_id&&"filtered"===l?.kind,o=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:o,onClick:()=>u(e,"raw"),tooltip:"Download raw_data/trace.json as CSV",tooltipOptions:{position:"left"}}),_jsx(Button,{icon:r?"pi pi-spin pi-spinner":"pi pi-download",label:"Filtered",size:"small",outlined:!0,disabled:o,onClick:()=>u(e,"filtered"),tooltip:"Download filtered_data/trace.json as CSV",tooltipOptions:{position:"left"}})]})}})]})]})};
|
|
@@ -30,7 +30,7 @@ export interface RawDataShape {
|
|
|
30
30
|
[col: string]: string;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
export interface
|
|
33
|
+
export interface TestMethod {
|
|
34
34
|
project_fields: TestFieldDef[];
|
|
35
35
|
config_fields: TestFieldDef[];
|
|
36
36
|
cycle_fields: TestFieldDef[];
|
|
@@ -41,10 +41,14 @@ export interface TestDefinition {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
export interface TestDataViewProps {
|
|
44
|
-
projectId
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
/** Optional override; defaults to `useTisSelection().projectId`. */
|
|
45
|
+
projectId?: string;
|
|
46
|
+
/** Optional override; defaults to `useTisSelection().methodId`. */
|
|
47
|
+
methodId?: string;
|
|
48
|
+
/** Optional override; defaults to `useTisSelection().runId`. */
|
|
49
|
+
runId?: string;
|
|
50
|
+
/** Optional override; defaults to `useTisSchemas()[methodId]`. */
|
|
51
|
+
schema?: TestMethod;
|
|
48
52
|
/** Minimum ms between display updates when broadcasts arrive. Default 100. */
|
|
49
53
|
throttleMs?: number;
|
|
50
54
|
/** Fixed cycle-table scroll height. Default "400px". */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestDataView.tsx"],"names":[],"mappings":"AAUA,OAAO,KAA2D,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TestDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestDataView.tsx"],"names":[],"mappings":"AAUA,OAAO,KAA2D,MAAM,OAAO,CAAC;AA6BhF,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IAAI,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAAE;AAChF,MAAM,WAAW,WAAW;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAAE;AAC5G,MAAM,WAAW,SAAS;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,GAAG,WAAW,CAAC;IACpC,CAAC,EAAE,SAAS,CAAC;IACb,CAAC,EAAE,WAAW,EAAE,CAAC;CACpB;AACD,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACrC;AACD,MAAM,WAAW,UAAU;IACvB,cAAc,EAAG,YAAY,EAAE,CAAC;IAChC,aAAa,EAAI,YAAY,EAAE,CAAC;IAChC,YAAY,EAAK,YAAY,EAAE,CAAC;IAChC,cAAc,EAAG,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAQ,YAAY,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,EAAW;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CAClD;AAED,MAAM,WAAW,iBAAiB;IAC9B,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAG,MAAM,CAAC;IACnB,gEAAgE;IAChE,KAAK,CAAC,EAAM,MAAM,CAAC;IACnB,kEAAkE;IAClE,MAAM,CAAC,EAAK,UAAU,CAAC;IACvB,8EAA8E;IAC9E,UAAU,CAAC,EAAG,MAAM,CAAC;IACrB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgPpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{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{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{TestRawDataView}from"./TestRawDataView";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin);export const TestDataView=(
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{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{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{TestRawDataView}from"./TestRawDataView";import{useTis}from"./TisProvider";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin);export const TestDataView=e=>{const t=useTis(),r=e.projectId??t.selection.projectId,s=e.methodId??t.selection.methodId,a=e.runId??t.selection.runId,i=e.schema??(s?t.schemas[s]:void 0),{throttleMs:l=100,cycleTableHeight:n="400px"}=e,{invoke:o,subscribe:c,unsubscribe:d}=useContext(EventEmitterContext),[m,u]=useState(null),[p,h]=useState([]),[f,y]=useState({}),[g,x]=useState(!1),_=useMemo(()=>{const e=[];for(const[t,r]of Object.entries(i?.views??{}))"cycle_scatter"===r.type&&e.push({name:t,view:r});return e},[i]),[j,v]=useState(_.length>0?_[0].name:null),b=useRef([]),w=useRef(null),C=useRef(null),R=()=>{C.current||(C.current=setTimeout(()=>{if(C.current=null,b.current.length>0){const e=b.current;b.current=[],h(t=>[...e.slice().reverse(),...t])}w.current&&(y(w.current),w.current=null)},l))};useEffect(()=>{if(!r||!s||!a)return u(null),h([]),void y({});let e=!1;return(async()=>{try{const t=await o("tis.read_test",MessageType.Request,{project_id:r,method_id:s,run_id:a});!e&&t?.success&&(u(t.data),y(t.data.results??{}));const i=await o("tis.read_cycles",MessageType.Request,{project_id:r,method_id:s,run_id:a,offset:0,limit:200,order:"desc"});!e&&i?.success&&h(i.data.cycles??[])}catch(e){}})(),()=>{e=!0}},[r,s,a,o]),useEffect(()=>{const e=e=>e?.project_id===r&&e?.method_id===s&&e?.run_id===a,t=c("tis.cycle_added",t=>{e(t)&&t.cycle&&(b.current.push(t.cycle),R())}),i=c("tis.results_updated",t=>{e(t)&&(w.current=t.results??{},R())});return()=>{d(t),d(i),C.current&&(clearTimeout(C.current),C.current=null)}},[r,s,a,l]);const T=useMemo(()=>{if(!j||0===_.length)return null;const e=_.find(e=>e.name===j)?.view;if(!e)return null;const t=e.x.field,r=[...p].reverse();return{labels:r.map(e=>e[t]),datasets:e.y.map((e,t)=>({label:e.label??e.field,data:r.map(t=>t[e.field]),yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(t),backgroundColor:palette(t),tension:.1,pointRadius:2}))}},[p,j,_]),S=_.find(e=>e.name===j)?.view,I=S?.y.some(e=>"right"===e.y_axis)??!1,D=useMemo(()=>({responsive:!0,maintainAspectRatio:!1,scales:{x:{title:{display:!!S?.x.label,text:S?.x.label}},y:{position:"left",title:{display:!0,text:leftAxisLabel(S)}},...I?{y1:{position:"right",grid:{drawOnChartArea:!1},title:{display:!0,text:rightAxisLabel(S)}}}:{}},plugins:{legend:{display:!0},zoom:{pan:{enabled:!0,mode:"xy"},zoom:{wheel:{enabled:!0},pinch:{enabled:!0},mode:"xy"}}}}),[S,I]);return r&&s&&a&&i?_jsxs("div",{className:"vblock",style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[_jsx(Header,{meta:m,config:m?.config,runId:a,projectId:r,methodId:s,canViewRaw:!!i.raw_data,onViewRaw:()=>x(!0)}),_.length>0&&_jsxs("div",{className:"p-card",style:{padding:"1rem"},children:[_jsxs("div",{className:"flex",style:{gap:"1rem",alignItems:"center",marginBottom:"0.5rem"},children:[_jsx(Dropdown,{value:j,options:_.map(e=>({label:e.view.title??e.name,value:e.name})),onChange:e=>v(e.value),placeholder:"Select a view"}),_jsx("h3",{style:{margin:0},children:S?.title??""})]}),_jsx("div",{style:{height:320},children:T&&_jsx(Line,{data:T,options:D})})]}),_jsxs("div",{className:"p-card",style:{padding:"1rem"},children:[_jsxs("h3",{style:{marginTop:0},children:["Cycle Data (",p.length,")"]}),_jsx(DataTable,{value:p,scrollable:!0,scrollHeight:n,virtualScrollerOptions:{itemSize:38},emptyMessage:"No cycles yet.",children:i.cycle_fields.map(e=>_jsx(Column,{field:e.name,header:e.units?`${e.name} (${e.units})`:e.name,body:t=>formatCell(t[e.name],e.type)},e.name))})]}),_jsxs("div",{className:"p-card",style:{padding:"1rem"},children:[_jsx("h3",{style:{marginTop:0},children:"Results"}),_jsx(ResultsGrid,{schema:i.results_fields,values:f})]}),i.raw_data&&_jsx(Dialog,{visible:g,onHide:()=>x(!1),header:"Raw Data",style:{width:"90vw",height:"80vh"},maximizable:!0,children:_jsx(TestRawDataView,{projectId:r,methodId:s,runId:a,schema:i})})]}):_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:s,methodId:a,canViewRaw:i,onViewRaw:l})=>{const n="string"==typeof e?.sample_id&&e.sample_id||"string"==typeof e?.config?.sample_id&&e.config.sample_id||"",o=t&&"object"==typeof t?Object.fromEntries(Object.entries(t).filter(([e])=>"sample_id"!==e)):{};return _jsxs("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:[_jsx("h2",{style:{margin:0},children:n||r}),_jsxs("div",{style:{color:"var(--text-secondary-color)",fontSize:"0.85em"},children:["project: ",s," · method: ",a," · run: ",r,e?.start_time&&_jsxs(_Fragment,{children:[" · started: ",new Date(e.start_time).toLocaleString()]})]})]}),i&&_jsx(Button,{icon:"pi pi-chart-line",label:"View Raw Data",onClick:l,outlined:!0})]}),Object.keys(o).length>0&&_jsx("div",{style:{marginTop:"0.75rem",display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:"0.25rem 1rem",fontSize:"0.9em"},children:Object.entries(o).map(([e,t])=>_jsxs("div",{children:[_jsxs("strong",{children:[e,":"]})," ",formatCell(t,"string")]},e))})]})},ResultsGrid=({schema:e,values:t})=>t&&0!==Object.keys(t).length?_jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:"0.5rem 1rem"},children:e.map(e=>_jsxs("div",{children:[_jsxs("div",{style:{fontSize:"0.8em",color:"var(--text-secondary-color)"},children:[e.name,e.units?` (${e.units})`:""]}),_jsx("div",{children:formatCell(t[e.name],e.type)})]},e.name))}):_jsx("div",{style:{color:"var(--text-secondary-color)"},children:"No results yet."}),CHART_COLORS=["#4ea8de","#f59e0b","#22c55e","#a855f7","#ef4444","#14b8a6","#eab308","#ec4899"],palette=e=>CHART_COLORS[e%CHART_COLORS.length],leftAxisLabel=e=>e?.y.filter(e=>"right"!==e.y_axis).map(e=>e.label??e.field).join(" / ")??"",rightAxisLabel=e=>e?.y.filter(e=>"right"===e.y_axis).map(e=>e.label??e.field).join(" / ")??"",formatCell=(e,t)=>null==e?"":"f32"===t||"f64"===t?"number"==typeof e?e.toFixed(4):String(e):"object"==typeof e?JSON.stringify(e):String(e);
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TestMethod } from './TestDataView';
|
|
3
3
|
export interface TestRawDataViewProps {
|
|
4
|
-
projectId
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/** Optional override; defaults to `useTisSelection().projectId`. */
|
|
5
|
+
projectId?: string;
|
|
6
|
+
/** Optional override; defaults to `useTisSelection().methodId`. */
|
|
7
|
+
methodId?: string;
|
|
8
|
+
/** Optional override; defaults to `useTisSelection().runId`. */
|
|
9
|
+
runId?: string;
|
|
10
|
+
/** Optional override; defaults to `useTisSchemas()[methodId]`. */
|
|
11
|
+
schema?: TestMethod;
|
|
8
12
|
/** Override the blob name (default: schema.raw_data.blob_name). */
|
|
9
13
|
blobName?: string;
|
|
10
14
|
/** Fixed chart height. Default "60vh". */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestRawDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestRawDataView.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAahF,OAAO,KAAK,EAAa,
|
|
1
|
+
{"version":3,"file":"TestRawDataView.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestRawDataView.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAahF,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,MAAM,WAAW,oBAAoB;IACjC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAG,MAAM,CAAC;IACnB,gEAAgE;IAChE,KAAK,CAAC,EAAM,MAAM,CAAC;IACnB,kEAAkE;IAClE,MAAM,CAAC,EAAK,UAAU,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAuJ1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useContext,useEffect,useMemo,useRef,useState}from"react";import{Button}from"primereact/button";import{Dropdown}from"primereact/dropdown";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin);export const TestRawDataView=(
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useContext,useEffect,useMemo,useRef,useState}from"react";import{Button}from"primereact/button";import{Dropdown}from"primereact/dropdown";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend}from"chart.js";import zoomPlugin from"chartjs-plugin-zoom";import{Line}from"react-chartjs-2";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";import{useTis}from"./TisProvider";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,zoomPlugin);export const TestRawDataView=e=>{const t=useTis(),a=e.projectId??t.selection.projectId,s=e.methodId??t.selection.methodId,o=e.runId??t.selection.runId,i=e.schema??(s?t.schemas[s]:void 0),{blobName:r,chartHeight:n="60vh"}=e,{invoke:l}=useContext(EventEmitterContext),[m,d]=useState(null),[c,p]=useState(!0),[u,h]=useState(null),x=useRef(null),y=useMemo(()=>{const e=[];for(const[t,a]of Object.entries(i?.views??{}))"raw_trace"===a.type&&e.push({name:t,view:a});return e},[i]),[f,g]=useState(y.length>0?y[0].name:null),_=r??i?.raw_data?.blob_name??"trace";useEffect(()=>{if(!a||!s||!o)return d(null),p(!1),void h(null);let e=!1;return p(!0),h(null),(async()=>{try{const t=await l("tis.read_raw",MessageType.Request,{project_id:a,method_id:s,run_id:o,name:_});if(e)return;t?.success?d(t.data??{}):h(t?.error_message??"Failed to read raw data")}catch(t){e||h(String(t?.message??t))}finally{e||p(!1)}})(),()=>{e=!0}},[a,s,o,_,l]);const v=useMemo(()=>{if(!m||!f)return null;const e=y.find(e=>e.name===f)?.view;if(!e)return null;const t=e.x.column,a=m[t]??[];return{datasets:e.y.map((e,t)=>({label:e.label??e.column,data:(m[e.column]??[]).map((e,t)=>({x:a[t],y:e})),yAxisID:"right"===e.y_axis?"y1":"y",borderColor:palette(t),backgroundColor:palette(t),pointRadius:0,borderWidth:1.5,showLine:!0}))}},[m,f,y]),j=y.find(e=>e.name===f)?.view,b=j?.y.some(e=>"right"===e.y_axis)??!1,w=useMemo(()=>({responsive:!0,maintainAspectRatio:!1,parsing:!1,scales:{x:{type:"linear",title:{display:!!j?.x.label,text:j?.x.label}},y:{position:"left",title:{display:!0,text:axisLabel(j,"left")}},...b?{y1:{position:"right",grid:{drawOnChartArea:!1},title:{display:!0,text:axisLabel(j,"right")}}}:{}},plugins:{legend:{display:!0},zoom:{pan:{enabled:!0,mode:"xy"},zoom:{wheel:{enabled:!0},pinch:{enabled:!0},drag:{enabled:!0,modifierKey:"shift"},mode:"xy"}}}}),[j,b]);return a&&s&&o?i?i.raw_data?0===y.length?_jsx(EmptyState,{message:"No raw_trace views declared. Add one to schema.views in project.json."}):_jsxs("div",{className:"vblock",style:{display:"flex",flexDirection:"column",gap:"1rem",height:"100%"},children:[_jsxs("div",{className:"flex",style:{gap:"1rem",alignItems:"center"},children:[_jsx(Dropdown,{value:f,options:y.map(e=>({label:e.view.title??e.name,value:e.name})),onChange:e=>g(e.value),placeholder:"Select a view"}),_jsx("h3",{style:{margin:0},children:j?.title??""}),_jsx("div",{style:{flex:1}}),_jsx(Button,{icon:"pi pi-refresh",label:"Reset Zoom",outlined:!0,onClick:()=>x.current?.resetZoom?.()})]}),_jsxs("div",{style:{flex:1,minHeight:0,height:n,position:"relative"},children:[c&&_jsx(Overlay,{children:"Loading raw data…"}),u&&_jsx(Overlay,{children:u}),v&&!c&&!u&&_jsx(Line,{ref:x,data:v,options:w})]})]}):_jsx(EmptyState,{message:"No raw_data is declared for this test method."}):_jsx(EmptyState,{message:"Schema not loaded yet."}):_jsx(EmptyState,{message:"No test selected."})};const Overlay=({children:e})=>_jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--text-secondary-color)",pointerEvents:"none"},children:e}),EmptyState=({message:e})=>_jsx("div",{style:{padding:"1rem",color:"var(--text-secondary-color)"},children:e}),CHART_COLORS=["#4ea8de","#f59e0b","#22c55e","#a855f7","#ef4444","#14b8a6","#eab308","#ec4899"],palette=e=>CHART_COLORS[e%CHART_COLORS.length],axisLabel=(e,t)=>e?.y.filter(e=>(e.y_axis??"left")===t).map(e=>e.label??e.column).join(" / ")??"";
|
|
@@ -6,18 +6,29 @@ export interface TestFieldDef {
|
|
|
6
6
|
required?: boolean;
|
|
7
7
|
source?: string;
|
|
8
8
|
}
|
|
9
|
-
export interface
|
|
9
|
+
export interface TestMethod {
|
|
10
10
|
project_fields: TestFieldDef[];
|
|
11
11
|
config_fields: TestFieldDef[];
|
|
12
12
|
cycle_fields: TestFieldDef[];
|
|
13
13
|
results_fields: TestFieldDef[];
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Props are all optional overrides — by default the form drives itself
|
|
17
|
+
* from the surrounding `<TisProvider>`. Pass any of these to lock that
|
|
18
|
+
* particular axis.
|
|
19
|
+
*
|
|
20
|
+
* - `schema`: bypass `useTisSchemas()` for the selected method.
|
|
21
|
+
* - `defaultProjectId` / `defaultMethodId`: seed the form's local
|
|
22
|
+
* state when the corresponding TIS-context fields are blank.
|
|
23
|
+
* - `onProjectChange` / `onMethodChange` / `onValidationChange`:
|
|
24
|
+
* receive callbacks in addition to the provider's selection state.
|
|
25
|
+
*/
|
|
15
26
|
export interface TestSetupFormProps {
|
|
16
|
-
schema
|
|
27
|
+
schema?: TestMethod;
|
|
17
28
|
defaultProjectId?: string;
|
|
18
|
-
|
|
29
|
+
defaultMethodId?: string;
|
|
19
30
|
onProjectChange?: (projectId: string) => void;
|
|
20
|
-
|
|
31
|
+
onMethodChange?: (methodId: string) => void;
|
|
21
32
|
onValidationChange?: (isValid: boolean, config: any) => void;
|
|
22
33
|
}
|
|
23
34
|
export declare const TestSetupForm: React.FC<TestSetupFormProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"TestSetupForm.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TestSetupForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,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;CAClC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,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;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA2QtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import React,{useState,useEffect,useContext}from"react";import{AutoComplete}from"primereact/autocomplete";import{EventEmitterContext}from"../../core/EventEmitterContext";import{AutoCoreTagContext}from"../../core/AutoCoreTagContext";import{MessageType}from"../../hub/CommandMessage";import{ValueInput}from"../ValueInput";import{TextInput}from"../TextInput";import{
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import React,{useState,useEffect,useContext,useMemo}from"react";import{AutoComplete}from"primereact/autocomplete";import{SelectButton}from"primereact/selectbutton";import{EventEmitterContext}from"../../core/EventEmitterContext";import{AutoCoreTagContext}from"../../core/AutoCoreTagContext";import{MessageType}from"../../hub/CommandMessage";import{ValueInput}from"../ValueInput";import{TextInput}from"../TextInput";import{useTis}from"./TisProvider";export const TestSetupForm=({schema:e,defaultProjectId:t,defaultMethodId:s,onProjectChange:a,onMethodChange:n,onValidationChange:o})=>{const r=useTis(),{invoke:i,write:c}=useContext(EventEmitterContext),{rawValues:l,findTagByFqdn:m}=useContext(AutoCoreTagContext),d=useMemo(()=>Object.keys(r.schemas),[r.schemas]),[p,u]=useState(r.selection.projectId||t||""),[f,h]=useState(r.selection.methodId||s||r.defaultMethodId||""),[x,g]=useState(""),[j,_]=useState({}),v=e??(f?r.schemas[f]:void 0);useEffect(()=>{r.selection.projectId!==p&&r.setSelection({projectId:p}),a&&a(p)},[p]),useEffect(()=>{r.selection.methodId!==f&&f&&r.setSelection({methodId:f}),n&&n(f)},[f]),useEffect(()=>{r.selection.sampleId!==x&&r.setSelection({sampleId:x})},[x]),useEffect(()=>{r.state.stagedSampleId&&r.state.stagedSampleId!==x&&g(r.state.stagedSampleId)},[r.state.stagedSampleId]);const[I,C]=useState([]),[y,N]=useState([]),[S,T]=useState(!1);useEffect(()=>{if(!v)return;const e=[...v.project_fields,...v.config_fields];_(t=>{let s=t;for(const a of e){if("sample_id"===a.name)continue;if(!a.source)continue;const e=m(a.source);if(!e)continue;const n=l[e.tagName];null!=n&&(s[a.name]!==n&&(s===t&&(s={...t}),s[a.name]=n))}return s})},[v,l,m]),useEffect(()=>{(async()=>{try{const e=await i("tis.list_projects",MessageType.Request,{});e.success&&e.data&&e.data.projects&&C(e.data.projects)}catch(e){}})()},[i]);useEffect(()=>{if(!v)return void T(!1);let e=!0;p.trim()||(e=!1),f.trim()||(e=!1),x.trim()||(e=!1);const t=[...v.project_fields,...v.config_fields];for(const s of t)if("sample_id"!==s.name&&s.required){const t=j[s.name];if(void 0===t||""===t||null===t){e=!1;break}}if(T(e),o&&o(e,j),e){const{sample_id:e,...t}=j??{};i("tis.stage_test",MessageType.Request,{project_id:p,method_id:f,sample_id:x,config:t}).catch(e=>{})}},[j,v,p,f,x,o,i]);const E=async(e,t)=>{if(_({...j,[e.name]:t}),e.source)try{await c(e.source,t)}catch(e){}},b=e=>{if("sample_id"===e.name)return null;const t=(e=>{if(!e.required)return!0;const t=j[e.name];return void 0!==t&&""!==t&&null!==t})(e),s="string"!==e.type&&"bool"!==e.type;return _jsxs(React.Fragment,{children:[_jsx("span",{className:"ac-form-label",children:e.name}),s?_jsx(ValueInput,{label:void 0,value:null!=j[e.name]?Number(j[e.name]):null,onValueChanged:t=>E(e,t),className:t?"":"p-invalid"}):_jsx(TextInput,{label:void 0,value:null!=j[e.name]?String(j[e.name]):"",onValueChanged:t=>E(e,t),className:t?"":"p-invalid"}),_jsx("span",{className:"ac-form-units",children:e.units??""}),_jsx("span",{style:{color:t?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:t?"pi pi-check":"pi pi-times"})})]},e.name)};return v?_jsxs("div",{className:"ac-form-grid",style:{padding:"1.25rem"},children:[_jsxs("h3",{className:"ac-form-section",style:{display:"flex",alignItems:"center",gap:"10px"},children:["Project & Method",_jsx("span",{style:{color:S?"var(--green-500)":"var(--red-500)"},children:_jsx("i",{className:S?"pi pi-check-circle":"pi pi-exclamation-circle"})})]}),_jsx("span",{className:"ac-form-label",children:"Project ID"}),_jsx(AutoComplete,{value:p,suggestions:y,completeMethod:e=>{const t=e.query.toLowerCase();N(I.filter(e=>e.toLowerCase().includes(t)))},onChange:e=>(e=>{const t=(e||"").replace(/[^a-zA-Z0-9_]/g,"");u(t)})(e.value),dropdown:!0,placeholder:"Enter or select Project ID",className:p.trim()?"":"p-invalid"}),_jsx("span",{}),_jsx("span",{style:{color:p.trim()?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:p.trim()?"pi pi-check":"pi pi-times"})}),_jsx("span",{className:"ac-form-label",children:"Sample ID"}),_jsx(TextInput,{label:void 0,value:x,onValueChanged:e=>{g(e)},className:x.trim()?"":"p-invalid"}),_jsx("span",{}),_jsx("span",{style:{color:x.trim()?"var(--green-500)":"var(--red-500)",display:"flex",alignItems:"center"},children:_jsx("i",{className:x.trim()?"pi pi-check":"pi pi-times"})}),d.length>1&&_jsxs(_Fragment,{children:[_jsx("span",{className:"ac-form-label",children:"Test Method"}),_jsx(SelectButton,{value:f,options:d.map(e=>({label:e,value:e})),onChange:e=>e.value&&h(e.value)}),_jsx("span",{}),_jsx("span",{})]}),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Project Information"}),v.project_fields.map(b),_jsx("h3",{className:"ac-form-section",style:{marginTop:"1rem"},children:"Test Configuration"}),v.config_fields.map(b)]}):_jsx("div",{className:"ac-form-grid",style:{padding:"1.25rem"},children:_jsx("h3",{className:"ac-form-section",children:r.schemasLoaded?"No Test Method Selected":"Loading test methods…"})})};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One slot in the schema registry. Kept as an opaque object so the
|
|
4
|
+
* provider doesn't have to mirror every schema field — components that
|
|
5
|
+
* need typed access import the schema constants from the per-project
|
|
6
|
+
* generated `autocore/tis.ts` instead.
|
|
7
|
+
*/
|
|
8
|
+
export type TisMethodSchema = any;
|
|
9
|
+
export type SchemaRegistry = {
|
|
10
|
+
[methodId: string]: TisMethodSchema;
|
|
11
|
+
};
|
|
12
|
+
export interface TisLiveState {
|
|
13
|
+
staged: boolean;
|
|
14
|
+
stagedProjectId: string;
|
|
15
|
+
stagedMethodId: string;
|
|
16
|
+
stagedSampleId: string;
|
|
17
|
+
active: boolean;
|
|
18
|
+
activeProjectId: string;
|
|
19
|
+
activeMethodId: string;
|
|
20
|
+
activeSampleId: string;
|
|
21
|
+
activeRunId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TisSelection {
|
|
24
|
+
projectId: string;
|
|
25
|
+
methodId: string;
|
|
26
|
+
sampleId: string;
|
|
27
|
+
runId: string;
|
|
28
|
+
}
|
|
29
|
+
/** Partial setter — pass `null` for a field to clear the pin and let
|
|
30
|
+
* the active scalar drive that field again. */
|
|
31
|
+
export type TisSelectionPatch = {
|
|
32
|
+
projectId?: string | null;
|
|
33
|
+
methodId?: string | null;
|
|
34
|
+
sampleId?: string | null;
|
|
35
|
+
runId?: string | null;
|
|
36
|
+
};
|
|
37
|
+
export interface TisRunCacheEntry {
|
|
38
|
+
meta: any | null;
|
|
39
|
+
cycles: any[];
|
|
40
|
+
results: any;
|
|
41
|
+
rawData: {
|
|
42
|
+
[blobName: string]: any;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface TisContextValue {
|
|
46
|
+
schemas: SchemaRegistry;
|
|
47
|
+
defaultMethodId: string;
|
|
48
|
+
schemasLoaded: boolean;
|
|
49
|
+
state: TisLiveState;
|
|
50
|
+
selection: TisSelection;
|
|
51
|
+
setSelection: (patch: TisSelectionPatch) => void;
|
|
52
|
+
/** Fetch the run list for a (project, method?) pair. Method may be
|
|
53
|
+
* omitted to aggregate runs across every method in the project —
|
|
54
|
+
* the History tab uses this. */
|
|
55
|
+
fetchRuns: (projectId: string, methodId?: string) => Promise<any[]>;
|
|
56
|
+
/** Fetch the full bundle (test.json + cycles + results) for one run.
|
|
57
|
+
* Subsequent broadcast deltas land in the cache automatically. */
|
|
58
|
+
fetchRun: (projectId: string, methodId: string, runId: string) => Promise<TisRunCacheEntry | null>;
|
|
59
|
+
runCache: {
|
|
60
|
+
[runId: string]: TisRunCacheEntry;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
declare const TisContext: React.Context<TisContextValue>;
|
|
64
|
+
export interface TisProviderProps {
|
|
65
|
+
children: ReactNode;
|
|
66
|
+
/**
|
|
67
|
+
* Initial method_id when the schemas haven't loaded yet, or when the
|
|
68
|
+
* server's reported `default_method_id` is empty. Falls through to
|
|
69
|
+
* the first key of `tis.list_schemas` if not supplied.
|
|
70
|
+
*/
|
|
71
|
+
defaultMethodId?: string;
|
|
72
|
+
}
|
|
73
|
+
export declare const TisProvider: React.FC<TisProviderProps>;
|
|
74
|
+
export declare const useTis: () => TisContextValue;
|
|
75
|
+
export declare const useTisSchemas: () => SchemaRegistry;
|
|
76
|
+
export declare const useTisState: () => TisLiveState;
|
|
77
|
+
export declare const useTisSelection: () => readonly [TisSelection, (patch: TisSelectionPatch) => void];
|
|
78
|
+
export declare const useTisRuns: (projectId?: string, methodId?: string) => {
|
|
79
|
+
runs: any[];
|
|
80
|
+
loading: boolean;
|
|
81
|
+
refresh: () => Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
export declare const useTisRun: (runId?: string) => {
|
|
84
|
+
meta: any;
|
|
85
|
+
cycles: any[];
|
|
86
|
+
results: any;
|
|
87
|
+
rawData: {
|
|
88
|
+
[blobName: string]: any;
|
|
89
|
+
};
|
|
90
|
+
loading: boolean;
|
|
91
|
+
};
|
|
92
|
+
export { TisContext };
|
|
93
|
+
//# sourceMappingURL=TisProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TisProvider.d.ts","sourceRoot":"","sources":["../../../src/components/tis/TisProvider.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,EASV,KAAK,SAAS,EACjB,MAAM,OAAO,CAAC;AAQf;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,cAAc,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IAEvB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;gDACgD;AAChD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACjB,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,cAAc,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IAEvB,KAAK,EAAE,YAAY,CAAC;IAEpB,SAAS,EAAE,YAAY,CAAC;IACxB,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAEjD;;qCAEiC;IACjC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpE;uEACmE;IACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACnG,QAAQ,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAAA;KAAE,CAAC;CACnD;AAeD,QAAA,MAAM,UAAU,gCAUd,CAAC;AAmCH,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAmLlD,CAAC;AAMF,eAAO,MAAM,MAAM,uBAAyC,CAAC;AAC7D,eAAO,MAAM,aAAa,sBAA0C,CAAC;AACrE,eAAO,MAAM,WAAW,oBAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,wCA5QF,iBAAiB,KAAK,IAAI,CA+QnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,YAAY,MAAM,EAAE,WAAW,MAAM;;;;CAY/D,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM;;;;;;;;CAuBvC,CAAC;AAIF,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as _jsx}from"react/jsx-runtime";import React,{createContext,useCallback,useContext,useEffect,useMemo,useReducer,useRef,useState}from"react";import{EventEmitterContext}from"../../core/EventEmitterContext";import{MessageType}from"../../hub/CommandMessage";const EMPTY_STATE={staged:!1,stagedProjectId:"",stagedMethodId:"",stagedSampleId:"",active:!1,activeProjectId:"",activeMethodId:"",activeSampleId:"",activeRunId:""},EMPTY_SELECTION={projectId:"",methodId:"",sampleId:"",runId:""},TisContext=createContext({schemas:{},defaultMethodId:"",schemasLoaded:!1,state:EMPTY_STATE,selection:EMPTY_SELECTION,setSelection:()=>{},fetchRuns:async()=>[],fetchRun:async()=>null,runCache:{}});function liveReducer(e,t){switch(t.kind){case"staged":return{...e,staged:t.value};case"staged_project_id":return{...e,stagedProjectId:t.value};case"staged_method_id":return{...e,stagedMethodId:t.value};case"staged_sample_id":return{...e,stagedSampleId:t.value};case"active":return{...e,active:t.value};case"active_project_id":return{...e,activeProjectId:t.value};case"active_method_id":return{...e,activeMethodId:t.value};case"active_sample_id":return{...e,activeSampleId:t.value};case"active_run_id":return{...e,activeRunId:t.value}}}export const TisProvider=({children:e,defaultMethodId:t})=>{const{invoke:s,subscribe:a,unsubscribe:c}=useContext(EventEmitterContext),[d,r]=useState({}),[u,n]=useState(t??""),[i,o]=useState(!1),[l,m]=useReducer(liveReducer,EMPTY_STATE),[_,v]=useState({projectId:null,methodId:null,sampleId:null,runId:null});useEffect(()=>{let e=!1;return(async()=>{try{const a=await s("tis.list_schemas",MessageType.Request,{});if(e)return;if(a?.success&&a.data){const e=a.data.test_methods??{},s=a.data.default_method_id??"";r(e),!t&&s&&n(s),o(!0)}}catch(e){}})(),()=>{e=!0}},[]),useEffect(()=>{const e=[a("tis.staged",e=>m({kind:"staged",value:!!e})),a("tis.staged_project_id",e=>m({kind:"staged_project_id",value:String(e??"")})),a("tis.staged_method_id",e=>m({kind:"staged_method_id",value:String(e??"")})),a("tis.staged_sample_id",e=>m({kind:"staged_sample_id",value:String(e??"")})),a("tis.active",e=>m({kind:"active",value:!!e})),a("tis.active_project_id",e=>m({kind:"active_project_id",value:String(e??"")})),a("tis.active_method_id",e=>m({kind:"active_method_id",value:String(e??"")})),a("tis.active_sample_id",e=>m({kind:"active_sample_id",value:String(e??"")})),a("tis.active_run_id",e=>m({kind:"active_run_id",value:String(e??"")}))];return()=>{e.forEach(c)}},[a,c]);const I=useRef({}),[p,h]=useState(0),f=useCallback(()=>h(e=>e+1),[]),C=useCallback((e,t)=>{if(!e)return;const s=I.current[e]??{meta:null,cycles:[],results:{},rawData:{}};I.current[e]={...s,cycles:[...s.cycles,t]},f()},[f]),g=useCallback((e,t)=>{if(!e)return;const s=I.current[e]??{meta:null,cycles:[],results:{},rawData:{}};I.current[e]={...s,results:t},f()},[f]);useEffect(()=>{const e=a("tis.cycle_added",e=>{e?.run_id&&e.cycle&&C(e.run_id,e.cycle)}),t=a("tis.results_updated",e=>{e?.run_id&&g(e.run_id,e.results??{})});return()=>{c(e),c(t)}},[a,c,C,g]);const x=useMemo(()=>({projectId:_.projectId??l.activeProjectId,methodId:_.methodId??(l.activeMethodId||u),sampleId:_.sampleId??l.activeSampleId,runId:_.runId??l.activeRunId}),[_,l,u]),T=useCallback(e=>{v(t=>({projectId:void 0===e.projectId?t.projectId:e.projectId,methodId:void 0===e.methodId?t.methodId:e.methodId,sampleId:void 0===e.sampleId?t.sampleId:e.sampleId,runId:void 0===e.runId?t.runId:e.runId}))},[]),S=useCallback(async(e,t)=>{if(!e)return[];const a={project_id:e};t&&(a.method_id=t);try{const e=await s("tis.list_tests",MessageType.Request,a);if(e?.success&&e.data?.tests)return e.data.tests}catch(e){}return[]},[s]),y=useCallback(async(e,t,a)=>{if(!e||!t||!a)return null;try{const c=await s("tis.read_test",MessageType.Request,{project_id:e,method_id:t,run_id:a}),d=await s("tis.read_cycles",MessageType.Request,{project_id:e,method_id:t,run_id:a,offset:0,limit:1e3,order:"asc"});if(!c?.success)return null;const r={meta:c.data??null,cycles:d?.success?d.data?.cycles??[]:[],results:c.data?.results??{},rawData:I.current[a]?.rawData??{}};return I.current[a]=r,f(),r}catch(e){return null}},[s,f]),j=useMemo(()=>({...I.current}),[p]),E=useMemo(()=>({schemas:d,defaultMethodId:u,schemasLoaded:i,state:l,selection:x,setSelection:T,fetchRuns:S,fetchRun:y,runCache:j}),[d,u,i,l,x,T,S,y,j]);return _jsx(TisContext.Provider,{value:E,children:e})};export const useTis=()=>useContext(TisContext);export const useTisSchemas=()=>useContext(TisContext).schemas;export const useTisState=()=>useContext(TisContext).state;export const useTisSelection=()=>{const{selection:e,setSelection:t}=useContext(TisContext);return[e,t]};export const useTisRuns=(e,t)=>{const{fetchRuns:s}=useContext(TisContext),[a,c]=useState([]),[d,r]=useState(!1),u=useCallback(async()=>{if(e){r(!0);try{c(await s(e,t))}finally{r(!1)}}else c([])},[e,t,s]);return useEffect(()=>{u()},[u]),{runs:a,loading:d,refresh:u}};export const useTisRun=e=>{const{selection:t,fetchRun:s,runCache:a}=useContext(TisContext),[c,d]=useState(!1),r=e??t.runId;useEffect(()=>{if(!r)return;if(a[r]?.meta)return;const e=t.projectId,c=t.methodId;e&&c&&(d(!0),s(e,c,r).finally(()=>d(!1)))},[r,t.projectId,t.methodId,s,a]);const u=r?a[r]:null;return{meta:u?.meta??null,cycles:u?.cycles??[],results:u?.results??{},rawData:u?.rawData??{},loading:c}};export{TisContext};
|
|
@@ -30,6 +30,19 @@ export declare class HubWebSocket extends HubBase {
|
|
|
30
30
|
* Used to match asynchronous WebSocket responses to their original requests.
|
|
31
31
|
*/
|
|
32
32
|
private pendingRequests;
|
|
33
|
+
/**
|
|
34
|
+
* Messages queued while the WebSocket is still in CONNECTING state.
|
|
35
|
+
* Flushed in `socket.onopen`. Without this queue, an `invoke()` fired
|
|
36
|
+
* from a React `useEffect` on first mount races the WS handshake —
|
|
37
|
+
* `socket.send()` on a non-OPEN socket throws a synchronous
|
|
38
|
+
* DOMException ("object not, or is no longer, usable"), which the
|
|
39
|
+
* caller sees as an opaque rejection and the underlying request is
|
|
40
|
+
* never sent.
|
|
41
|
+
*
|
|
42
|
+
* Each entry carries the request id so we can reject the matching
|
|
43
|
+
* pending Promise if the WS closes before we ever flush.
|
|
44
|
+
*/
|
|
45
|
+
private sendQueue;
|
|
33
46
|
/**
|
|
34
47
|
* Initializes the WebSocket connection immediately.
|
|
35
48
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HubWebSocket.d.ts","sourceRoot":"","sources":["../../src/hub/HubWebSocket.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA+DpE;;GAEG;AACH,qBAAa,YAAa,SAAQ,OAAO;IACrC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAK;IAEtB;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAoC;IAE3D;;OAEG;;
|
|
1
|
+
{"version":3,"file":"HubWebSocket.d.ts","sourceRoot":"","sources":["../../src/hub/HubWebSocket.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA+DpE;;GAEG;AACH,qBAAa,YAAa,SAAQ,OAAO;IACrC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAK;IAEtB;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAoC;IAE3D;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,SAAS,CAA2C;IAE5D;;OAEG;;IAqHH;;;;;OAKG;IACH,MAAM,GAAI,OAAO,MAAM,EAAE,aAAa,WAAW,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,cAAc,CAAC,CA6C5F;IAED;;;OAGG;IACH,wBAAwB,GAAI,KAAK,cAAc,UAO9C;IAED,UAAU,QAAO,IAAI,CAEpB;IAED,SAAS,CAAC,IAAI,GAAI,WAAW,MAAM,EAAE,UAAU,MAAM,KAAG,IAAI,CAE3D;CACJ"}
|
package/dist/hub/HubWebSocket.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{HubBase}from"./HubBase";import{MessageType}from"./CommandMessage";import{getDebugPanel}from"./DebugPanel";function b64toBlob(e,t="application/octet-stream",s=512){const n=atob(e),o=[];for(let e=0;e<n.length;e+=s){const t=n.slice(e,e+s),a=new Array(t.length);for(let e=0;e<t.length;e++)a[e]=t.charCodeAt(e);const i=new Uint8Array(a);o.push(i.buffer)}return new Blob(o,{type:t})}function downloadBlob(e,t){const s=window.URL.createObjectURL(e),n=document.createElement("a");n.href=s,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),window.URL.revokeObjectURL(s)}export class HubWebSocket extends HubBase{constructor(){super(),Object.defineProperty(this,"socket",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"requestId",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"pendingRequests",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"invoke",{enumerable:!0,configurable:!0,writable:!0,value:(e,t,s)=>new Promise((n,o)=>{const a=++this.requestId;this.pendingRequests.set(a,{resolve:n,reject:o});const i={transaction_id:a,topic:e,data:s||{},timecode:Date.now(),message_type:t,success:!1,error_message:""};getDebugPanel().messageSent(MessageType[t],e,a)
|
|
1
|
+
import{HubBase}from"./HubBase";import{MessageType}from"./CommandMessage";import{getDebugPanel}from"./DebugPanel";function b64toBlob(e,t="application/octet-stream",s=512){const n=atob(e),o=[];for(let e=0;e<n.length;e+=s){const t=n.slice(e,e+s),a=new Array(t.length);for(let e=0;e<t.length;e++)a[e]=t.charCodeAt(e);const i=new Uint8Array(a);o.push(i.buffer)}return new Blob(o,{type:t})}function downloadBlob(e,t){const s=window.URL.createObjectURL(e),n=document.createElement("a");n.href=s,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),window.URL.revokeObjectURL(s)}export class HubWebSocket extends HubBase{constructor(){super(),Object.defineProperty(this,"socket",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"requestId",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"pendingRequests",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"sendQueue",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"invoke",{enumerable:!0,configurable:!0,writable:!0,value:(e,t,s)=>new Promise((n,o)=>{const a=++this.requestId;this.pendingRequests.set(a,{resolve:n,reject:o});const i={transaction_id:a,topic:e,data:s||{},timecode:Date.now(),message_type:t,success:!1,error_message:""};getDebugPanel().messageSent(MessageType[t],e,a);const r=JSON.stringify(i);switch(this.socket.readyState){case WebSocket.OPEN:this.socket.send(r);break;case WebSocket.CONNECTING:this.sendQueue.push({id:a,json:r});break;default:this.pendingRequests.delete(a),o(new Error(`WebSocket not open (readyState=${this.socket.readyState}); cannot send '${e}'`))}})}),Object.defineProperty(this,"handleUnsolicitedMessage",{enumerable:!0,configurable:!0,writable:!0,value:e=>{e.message_type==MessageType.Broadcast&&e.topic.length>1&&this.publish(e.topic,e.data)}}),Object.defineProperty(this,"disconnect",{enumerable:!0,configurable:!0,writable:!0,value:()=>{this.socket.close()}}),Object.defineProperty(this,"emit",{enumerable:!0,configurable:!0,writable:!0,value:(e,t)=>{this.socket.send(JSON.stringify({eventName:e,payload:t}))}}),getDebugPanel().hubCreated();const e=window.location.hostname,t=window.location.port,s=`${"https:"===window.location.protocol?"wss://":"ws://"}${e}${t?":"+t:""}/ws/`;this.socket=new WebSocket(s);let n=this;this.socket.onopen=function(){if(getDebugPanel().wsOpened(s),n.sendQueue.length>0){for(const{json:e}of n.sendQueue)n.socket.send(e);n.sendQueue=[]}n.publish("HUB/connected",!0),n.setIsConnected(!0)},this.socket.onmessage=e=>{const t=JSON.parse(e.data);if(getDebugPanel().messageReceived(MessageType[t.message_type]||String(t.message_type),t.topic,t.transaction_id),t.transaction_id&&this.pendingRequests.has(t.transaction_id)){const{resolve:e,reject:s}=this.pendingRequests.get(t.transaction_id);if("FILE_DOWNLOAD"===t.topic&&void 0!==t.data.file_name&&null!==t.data.file_name&&t.data.file_name.length>0){let n=t.data.file_name.split("/");const o=n[n.length-1];if(t.success){downloadBlob(b64toBlob(t.data),o),t.data=o,e(t)}else s(new Error(t.error_message))}else t.success?e(t):s(new Error(t.error_message));this.pendingRequests.delete(t.transaction_id)}else this.handleUnsolicitedMessage(t)},this.socket.onerror=e=>{getDebugPanel().wsError(String(e))},this.socket.onclose=e=>{if(n.setIsConnected(!1),getDebugPanel().wsClosed(e.code,e.reason||"No reason"),n.sendQueue.length>0){for(const{id:e}of n.sendQueue){const t=n.pendingRequests.get(e);t&&(t.reject(new Error("WebSocket closed before message could be sent")),n.pendingRequests.delete(e))}n.sendQueue=[]}}}}
|
package/package.json
CHANGED
package/src/components/index.ts
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
// Re-exports for convenience. Components in `tis/` (Test Information System)
|
|
2
2
|
// each declare their own types; a couple are duplicated across files
|
|
3
|
-
// (`TestFieldDef`, `
|
|
3
|
+
// (`TestFieldDef`, `TestMethod` exist in both `TestSetupForm` and
|
|
4
4
|
// `TestDataView`), so we re-export components and prop types explicitly
|
|
5
5
|
// instead of using `export *`.
|
|
6
6
|
//
|
|
7
7
|
// Callers can also deep-import: `from '@adcops/autocore-react/components/tis/<Name>'`.
|
|
8
8
|
|
|
9
|
+
export {
|
|
10
|
+
TisProvider,
|
|
11
|
+
TisContext,
|
|
12
|
+
useTis,
|
|
13
|
+
useTisSchemas,
|
|
14
|
+
useTisState,
|
|
15
|
+
useTisSelection,
|
|
16
|
+
useTisRuns,
|
|
17
|
+
useTisRun,
|
|
18
|
+
} from './tis/TisProvider';
|
|
19
|
+
export type {
|
|
20
|
+
TisProviderProps,
|
|
21
|
+
TisContextValue,
|
|
22
|
+
TisLiveState,
|
|
23
|
+
TisSelection,
|
|
24
|
+
TisSelectionPatch,
|
|
25
|
+
TisRunCacheEntry,
|
|
26
|
+
SchemaRegistry,
|
|
27
|
+
TisMethodSchema,
|
|
28
|
+
} from './tis/TisProvider';
|
|
29
|
+
|
|
9
30
|
export { TestSetupForm } from './tis/TestSetupForm';
|
|
10
31
|
export type { TestSetupFormProps } from './tis/TestSetupForm';
|
|
11
32
|
|