Added ldap and pam authentication
This commit is contained in:
@@ -2,6 +2,7 @@ import { h } from 'preact';
|
||||
import { useState, useEffect, useRef } from 'preact/hooks';
|
||||
import { useAuth, canWrite } from './lib/auth';
|
||||
import type { Interface, InterfaceListItem, Folder } from './lib/types';
|
||||
import { ScopeFilter, bucketOf, type Bucket } from './lib/scope';
|
||||
import ShareDialog from './ShareDialog';
|
||||
|
||||
interface Props {
|
||||
@@ -50,6 +51,11 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
const dragId = useRef<string | null>(null);
|
||||
const me = useAuth();
|
||||
const writable = canWrite(me.level);
|
||||
// Mine/Group/Global visibility filter. Default to Global so the primary
|
||||
// navigation list isn't empty for users who own no panels; legacy/public
|
||||
// panels live there.
|
||||
const [bucket, setBucket] = useState<Bucket>('global');
|
||||
const [scopeGroup, setScopeGroup] = useState('');
|
||||
|
||||
// Panels in a folder ('' = root), sorted by their stored order then name.
|
||||
function panelsIn(folder: string): InterfaceListItem[] {
|
||||
@@ -58,6 +64,26 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || (a.name || a.id).localeCompare(b.name || b.id));
|
||||
}
|
||||
|
||||
// Whether a panel falls in the active visibility bucket. In group mode a
|
||||
// chosen group narrows to panels shared with that specific group.
|
||||
function inScope(item: InterfaceListItem): boolean {
|
||||
if (bucketOf(item, me) !== bucket) return false;
|
||||
if (bucket === 'group' && scopeGroup) return (item.groups ?? []).includes(scopeGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Panels in a folder that pass the active visibility filter.
|
||||
function visiblePanelsIn(folder: string): InterfaceListItem[] {
|
||||
return panelsIn(folder).filter(inScope);
|
||||
}
|
||||
|
||||
// A folder is shown when it (recursively) contains any in-scope panel, so
|
||||
// empty branches collapse out under the active filter.
|
||||
function folderHasVisible(id: string): boolean {
|
||||
if (visiblePanelsIn(id).length > 0) return true;
|
||||
return folders.some(f => f.parent === id && folderHasVisible(f.id));
|
||||
}
|
||||
|
||||
// Persist a new ordering for a folder's panels (also moves panels between folders).
|
||||
async function reorder(folder: string, ids: string[]) {
|
||||
const res = await fetch('/api/v1/interfaces/reorder', {
|
||||
@@ -116,6 +142,8 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
folder: item.folder ? String(item.folder) : '',
|
||||
order: Number(item.order || 0),
|
||||
perm: (item.perm as InterfaceListItem['perm']) || 'write',
|
||||
scope: item.scope ? String(item.scope) : '',
|
||||
groups: Array.isArray(item.groups) ? item.groups.map(String) : [],
|
||||
})).filter((item: InterfaceListItem) => item.id);
|
||||
setInterfaces(normalized);
|
||||
setFolders(Array.isArray(folderData) ? folderData : []);
|
||||
@@ -222,9 +250,11 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
}
|
||||
|
||||
// Render a folder and everything beneath it (subfolders first, then panels).
|
||||
// Folders with no in-scope descendant panels are hidden under the filter.
|
||||
function renderFolder(folder: Folder) {
|
||||
if (!folderHasVisible(folder.id)) return null;
|
||||
const children = folders.filter(f => f.parent === folder.id);
|
||||
const panels = panelsIn(folder.id);
|
||||
const panels = visiblePanelsIn(folder.id);
|
||||
const open = expanded[folder.id] !== false; // default expanded
|
||||
const canDrop = folder.perm === 'write';
|
||||
return (
|
||||
@@ -256,7 +286,7 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
}
|
||||
|
||||
const rootFolders = folders.filter(f => !f.parent);
|
||||
const rootPanels = panelsIn('');
|
||||
const rootPanels = visiblePanelsIn('');
|
||||
|
||||
return (
|
||||
<aside class={`panel${collapsed ? ' collapsed' : ''}`} style={!collapsed && width ? `width:${width}px;min-width:${width}px;` : undefined}>
|
||||
@@ -289,6 +319,9 @@ export default function InterfaceList({ onLoad, onSelect, onEdit, onNewPlot, onE
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ScopeFilter me={me} value={bucket} onChange={setBucket}
|
||||
group={scopeGroup} onGroupChange={setScopeGroup} />
|
||||
|
||||
<div class="panel-list">
|
||||
{loading ? (
|
||||
<p class="hint">Loading…</p>
|
||||
|
||||
Reference in New Issue
Block a user