feat: scoped responsibility selectors, home card layouts and network topology
This commit is contained in:
+19
-4
@@ -12,10 +12,10 @@
|
||||
function catalog(state){return [
|
||||
...(state.assets||[]).map(x=>({...x,source:'camera',deviceType:'摄像机'})),
|
||||
...(state.recorders||[]).map(x=>({...x,source:'recorder',deviceType:'录像机'})),
|
||||
...(state.devices||[]).map(x=>({...x,source:'device'}))];}
|
||||
...(state.devices||[]).map(x=>({...x,source:'device'}))].map(x=>({...x,networkHosts:network(x,state).hosts}));}
|
||||
function matches(device,query,sites){
|
||||
const words=String(query||'').trim().toLowerCase().split(/\s+/).filter(Boolean);
|
||||
const text=[device.name,device.deviceType,device.brand,device.model,device.serial,device.ownerName,device.managerName,...(device.tags||[]),...path(sites,device.siteId).map(s=>s.name)].join(' ').toLowerCase();
|
||||
const text=[device.name,device.deviceType,device.brand,device.model,device.serial,device.ownerName,device.managerName,device.managementHost,device.host,device.tailscaleHost,device.networkCidr,...(device.networkHosts||[]),...(device.tags||[]),...path(sites,device.siteId).map(s=>s.name)].join(' ').toLowerCase();
|
||||
return words.every(word=>text.includes(word));
|
||||
}
|
||||
function groups(devices,dimensions,sites){
|
||||
@@ -28,7 +28,8 @@
|
||||
const parts=path(sites,device.siteId);options=[parts.length?parts.map(s=>({key:'space:'+s.id,label:s.name})):[{key:'space:none',label:'未指定区域'}]];
|
||||
}else{
|
||||
const values=dimension==='tag'?(device.tags?.length?device.tags:['未标记']):[dimension==='type'?device.deviceType:dimension==='manager'?(device.managerName||'负责人待指定'):(device.ownerName||'所有人待指定')];
|
||||
options=[...new Set(values)].map(value=>[{key:dimension+':'+value,label:value}]);
|
||||
const ref=dimension==='manager'?device.managerRef:dimension==='owner'?device.ownerRef:'';
|
||||
options=[...new Set(values)].map(value=>[{key:dimension+':'+(ref||value),label:value}]);
|
||||
}
|
||||
branches=branches.flatMap(branch=>options.map(option=>branch.concat(option)));
|
||||
}
|
||||
@@ -36,5 +37,19 @@
|
||||
}
|
||||
return [...result.values()].sort((a,b)=>a.labels.join('/').localeCompare(b.labels.join('/'),'zh-CN'));
|
||||
}
|
||||
return {path,descendants,catalog,groups,matches};
|
||||
function network(device,state){
|
||||
const channels=(state.cameras||[]).filter(c=>c.assetId===device.id);
|
||||
const direct=channels.filter(c=>c.sourceKind!=='recorder'&&c.host).map(c=>c.host);
|
||||
const hosts=[...new Set((device.source==='recorder'?[device.host]:direct.length?direct:[device.managementHost,device.host]).filter(Boolean))];
|
||||
const via=[...new Set(channels.filter(c=>c.sourceKind==='recorder'&&c.recorderId).map(c=>c.recorderId))];
|
||||
const archiveVia=[...new Set(channels.filter(c=>c.archiveSource==='recorder'&&c.archiveRecorderId).map(c=>c.archiveRecorderId))];
|
||||
return {hosts,via,archiveVia,access:device.networkAccess||'unknown',channels};
|
||||
}
|
||||
function topology(devices){
|
||||
const map=new Map(devices.map(d=>[d.id,d])),parents=new Map();
|
||||
for(const d of devices){let parent=d.uplinkId||'',cursor=parent,seen=new Set([d.id]);while(cursor&&map.has(cursor)){if(seen.has(cursor)){parent='';break;}seen.add(cursor);cursor=map.get(cursor).uplinkId;}parents.set(d.id,map.has(parent)?parent:'');}
|
||||
const children=new Map();for(const d of devices){const parent=parents.get(d.id);if(!children.has(parent))children.set(parent,[]);children.get(parent).push(d);}
|
||||
return {parents,children};
|
||||
}
|
||||
return {path,descendants,catalog,groups,matches,network,topology};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user