useEffect(()=>{try{localStorage.setItem(storageKey,JSON.stringify(layout));}catch{/* The workspace remains usable without browser storage. */}},[storageKey,layout]);
return<>{headerToolsHost&&createPortal(<IconButtonlabel="К аппаратам"onClick={back}><Iconname="chevron-left"/></IconButton>,headerToolsHost)}<divref={frame}/>{createPortal(<sectionclassName={`observation-center${expanded?' observation-center--expanded':''}`}aria-label={`Центр наблюдения и управления · ${name}`}>
<headerclassName="observation-toolbar"><div><h2>Центрнаблюденияиуправления</h2><span>{name}</span></div><divclassName="observation-actions">{(!headerToolsHost||expanded)&&<IconButtonlabel="К аппаратам"onClick={back}><Iconname="chevron-left"/></IconButton>}<ButtononClick={configure}><Iconname="sliders"/>Конфигуратор</Button><ButtononClick={()=>{setFocused(null);setLayersOpen(true);}}><Iconname="grid"/>Доступныеслои</Button><IconButtonlabel={expanded?'Восстановить размер центра':'Развернуть центр наблюдения и управления'}onClick={()=>setExpanded(value=>!value)}><Iconname={expanded?'minimize':'expand'}/></IconButton></div></header>
<headerclassName="observation-toolbar"><div><h2>Центрнаблюденияиуправления</h2><span>{name}</span></div><divclassName="observation-actions">{(!headerToolsHost||expanded)&&<IconButtonlabel="К аппаратам"onClick={back}><Iconname="chevron-left"/></IconButton>}<ButtononClick={configure}><Iconname="sliders"/>Конфигуратор</Button><ButtononClick={()=>{setLayersOpen(true);}}><Iconname="grid"/>Доступныеслои</Button><IconButtonlabel={expanded?'Восстановить размер центра':'Развернуть центр наблюдения и управления'}onClick={()=>setExpanded(value=>!value)}><Iconname={expanded?'minimize':'expand'}/></IconButton></div></header>
<divclassName="observation-summary"><StatusBadgetone={enabled&&inventory&&inventory.fresh!==false?'success':'neutral'}>{!inventory?'Получение источников':!enabled||inventory.fresh===false?'Нет свежих данных с БК':`Устройства: ${groups.length} · Окна: ${visible.length}`}</StatusBadge>{effectiveFull&&<ButtononClick={()=>setFull(null)}>Всеокна</Button>}</div>
{!active&&<Selectlabel="Расположение окон"value={layout.arrangement}options={[{value:'auto',label:'Автоматически'},{value:'columns',label:'В ряд'},{value:'rows',label:'Друг под другом'}]}onChange={value=>setLayout(current=>({...current,arrangement:valueastypeoflayout.arrangement}))}/>}
<Selectlabel="Расположение окон"value={layout.arrangement}options={[{value:'auto',label:'Автоматически'},{value:'columns',label:'В ряд'},{value:'rows',label:'Друг под другом'}]}onChange={value=>setLayout(current=>({...current,arrangement:valueastypeoflayout.arrangement}))}/>
{ids.map(id=>{constsource=sources.find(item=>item.key===id)!;return<divclassName="observation-layer"key={id}><Switchlabel={source.catalog?`${source.view.label} · Источник не подключён`:source.view.label}checked={visible.includes(id)}onChange={value=>setVisible(id,value)}/><Selectlabel={`Позиция · ${source.view.label}`}value={String(ids.indexOf(id))}options={ids.map((_,i)=>({value:String(i),label:`Окно ${i+1}`}))}onChange={value=>setLayout(current=>moveObservation(current,ids,id,ids[Number(value)]))}/></div>;})}
return<SplitPaneclassName="observation-split"orientation={orientation}primarySize={layout.splits[key]??50}onPrimarySizeChange={value=>onSplit(key,value)}separatorLabel="Изменить размеры окон"primary={<ObservationDeckids={ids.slice(0,mid)}mounts={mounts}layout={layout}onSplit={onSplit}depth={depth+1}/>}secondary={<ObservationDeckids={ids.slice(mid)}mounts={mounts}layout={layout}onSplit={onSplit}depth={depth+1}/>}/>;
return<SplitPaneseparatorAppearance="invisible"className="observation-split"orientation={orientation}primarySize={layout.splits[key]??50}onPrimarySizeChange={value=>onSplit(key,value)}separatorLabel="Изменить размеры окон"primary={<ObservationDeckids={ids.slice(0,mid)}mounts={mounts}layout={layout}onSplit={onSplit}depth={depth+1}/>}secondary={<ObservationDeckids={ids.slice(mid)}mounts={mounts}layout={layout}onSplit={onSplit}depth={depth+1}/>}/>;
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.