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);
|
||||
|
||||
Reference in New Issue
Block a user