Fix onboard BLE admission and stage wireless device enrollment
This commit is contained in:
@@ -105,7 +105,6 @@ export interface DevicePluginConnectionProps {
|
||||
export interface DeviceUiPlugin {
|
||||
sensorUi?: {
|
||||
contributions: readonly import('../../../../../packages/sensor-ui/src/extensions').SensorUiContribution[];
|
||||
Enrollment?: ComponentType<import('../../../../../packages/sensor-ui/src/extensions').SensorEnrollmentProps>;
|
||||
};
|
||||
manifest: DevicePluginManifest;
|
||||
RuntimeProvider: ComponentType<{
|
||||
|
||||
@@ -7,8 +7,6 @@ import {fleetRequest} from '../../core/fleet/useFleet';
|
||||
export function VehicleSensors({vehicleID,enabled,onDetailChange}:{vehicleID:string;enabled:boolean;onDetailChange:(open:boolean)=>void}){
|
||||
const {registry}=useDevicePluginHost();
|
||||
const sensorContributions=useMemo(()=>registry.plugins.flatMap(plugin=>plugin.sensorUi?.contributions??[]),[registry]);
|
||||
const enrollmentViews=registry.plugins.flatMap(plugin=>plugin.sensorUi?.Enrollment?[plugin.sensorUi.Enrollment]:[]);
|
||||
const SensorEnrollmentView=enrollmentViews.length===1?enrollmentViews[0]:undefined;
|
||||
const transport=useMemo<SensorTransport>(()=>({
|
||||
enrollment:{
|
||||
state:()=>fleetRequest(`/${encodeURIComponent(vehicleID)}/devices/enrollment`),
|
||||
@@ -20,5 +18,5 @@ export function VehicleSensors({vehicleID,enabled,onDetailChange}:{vehicleID:str
|
||||
submit:value=>fleetRequest(`/${encodeURIComponent(vehicleID)}/devices/operations`,'POST',value),
|
||||
operation:id=>fleetRequest(`/${encodeURIComponent(vehicleID)}/devices/operations/${encodeURIComponent(id)}`),
|
||||
}),[vehicleID]);
|
||||
return <SensorWorkspace contributions={sensorContributions} EnrollmentView={SensorEnrollmentView} createRerunHost={createIsolatedRerunHost} key={vehicleID} transport={transport} enabled={enabled} onDetailChange={onDetailChange}/>;
|
||||
return <SensorWorkspace contributions={sensorContributions} createRerunHost={createIsolatedRerunHost} key={vehicleID} transport={transport} enabled={enabled} onDetailChange={onDetailChange}/>;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ import assert from 'node:assert/strict';
|
||||
import {before,after,test} from 'node:test';
|
||||
import {readFileSync,readdirSync} from 'node:fs';
|
||||
import {createServer} from 'vite';
|
||||
let server,api,resolveContribution;
|
||||
let server,api,resolveContribution,wirelessContributions;
|
||||
before(async()=>{
|
||||
server=await createServer({appType:'custom',logLevel:'silent',server:{middlewareMode:true}});
|
||||
api=await server.ssrLoadModule('@xgrids-k1/frontend/sensors/enrollment.ts');
|
||||
({sensorContribution:resolveContribution}=await server.ssrLoadModule('../../packages/sensor-ui/src/extensions.ts'));
|
||||
({wirelessContributions}=await server.ssrLoadModule('../../packages/sensor-ui/src/extensions.ts'));
|
||||
});
|
||||
after(async()=>{await server?.close();});
|
||||
const initial={node_id:'node-one',available:true,fresh:true,runtime_id:'runtime-one',snapshot_revision:1,runtime_started_at:'2026-09-06T00:00:00Z',selected_device_id:'synthetic-ble'};
|
||||
@@ -87,6 +88,14 @@ test('sensor host can resolve zero or unrelated integrations and rejects ambigui
|
||||
assert.doesNotMatch(readFileSync(new URL('../../../packages/sensor-ui/src/'+name,import.meta.url),'utf8'),/xgrids|lixel|\bk1\b|K1Detail/,'vendor dependency in '+name);
|
||||
}
|
||||
});
|
||||
test('wireless device choices come from installed contributions without a single-vendor slot',()=>{
|
||||
const wired={kind:'wired',Detail:()=>null};
|
||||
const alpha={kind:'alpha',wirelessEnrollment:{label:'Device alpha',View:()=>null}};
|
||||
const beta={kind:'beta',wirelessEnrollment:{label:'Device beta',View:()=>null}};
|
||||
assert.deepEqual(wirelessContributions([]),[]);
|
||||
assert.deepEqual(wirelessContributions([wired,alpha,beta]),[alpha,beta]);
|
||||
assert.deepEqual(wirelessContributions([alpha,{...alpha},beta]),[beta]);
|
||||
});
|
||||
test('onboard actions use current server policy and never infer authority from readiness',()=>{
|
||||
const state={...initial,connected:true,allowed_actions:['verify-control-read-only']};
|
||||
assert.equal(api.enrollmentAllowed(state,'connect'),false);
|
||||
|
||||
@@ -11,7 +11,7 @@ import sys
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
VERSION = "0.8.0"
|
||||
VERSION = "0.8.1"
|
||||
sys.path.insert(0, str(ROOT.parents[1] / "scripts/packaging"))
|
||||
from debian import package
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {xgridsK1SensorUi,K1EnrollmentWindow} from '../../../../plugins/xgrids-k1/frontend/src/sensors/plugin';
|
||||
import {xgridsK1SensorUi} from '../../../../plugins/xgrids-k1/frontend/src/sensors/plugin';
|
||||
import {createIsolatedRerunHost} from '../../../control-station/src/components/rerun/isolatedRerunHost';
|
||||
import {SensorWorkspace} from '../../../../packages/sensor-ui/src/SensorWorkspace';
|
||||
import type {SensorTransport} from '../../../../packages/sensor-ui/src/contracts';
|
||||
import {request} from './api';
|
||||
const transport:SensorTransport={enrollment:{state:()=>request("/api/devices/enrollment"),submit:value=>request("/api/devices/enrollment/operations","POST",value),operation:id=>request("/api/devices/enrollment/operations/"+encodeURIComponent(id))},subscribe:(receive,unavailable)=>{const events=new EventSource('/api/devices/events');events.onmessage=e=>{try{receive(JSON.parse(e.data));}catch{unavailable();}};events.onerror=unavailable;return()=>events.close();},inventory:()=>request('/api/devices'),submit:value=>request('/api/devices/operations','POST',value),operation:id=>request('/api/devices/operations/'+encodeURIComponent(id))};
|
||||
export function NodeSensors(){return <SensorWorkspace contributions={[xgridsK1SensorUi]} EnrollmentView={K1EnrollmentWindow} createRerunHost={createIsolatedRerunHost} transport={transport}/>;}
|
||||
export function NodeSensors(){return <SensorWorkspace contributions={[xgridsK1SensorUi]} createRerunHost={createIsolatedRerunHost} transport={transport}/>;}
|
||||
|
||||
Reference in New Issue
Block a user