Files
silo-server/web/src/components/LibraryAccessSelector.tsx
T

76 lines
2.7 KiB
TypeScript

import type { Library } from "@/api/types";
import { Badge } from "@/components/ui/badge";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
interface LibraryAccessSelectorProps {
libraries: Library[];
value: number[] | null;
onChange: (value: number[] | null) => void;
}
function sortByLibraryOrder(libraries: Library[], ids: number[]) {
const selected = new Set(ids);
return libraries.filter((library) => selected.has(library.id)).map((library) => library.id);
}
export function LibraryAccessSelector({ libraries, value, onChange }: LibraryAccessSelectorProps) {
const allLibraries = value === null;
function handleAllLibrariesChange(checked: boolean) {
onChange(checked ? null : libraries.map((library) => library.id));
}
function handleLibraryToggle(libraryId: number, checked: boolean) {
const current = value ?? libraries.map((library) => library.id);
const next = checked
? sortByLibraryOrder(libraries, [...current, libraryId])
: current.filter((id) => id !== libraryId);
onChange(next);
}
return (
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label>Library Access</Label>
<div className="flex items-center gap-2">
<span className="text-muted-foreground text-xs">All libraries</span>
<Switch checked={allLibraries} onCheckedChange={handleAllLibrariesChange} />
</div>
</div>
{!allLibraries && (
<div className="grid gap-1.5">
{libraries.length === 0 ? (
<p className="text-muted-foreground text-xs">No libraries available.</p>
) : (
libraries.map((library) => {
const checked = value?.includes(library.id) ?? false;
return (
<div
key={library.id}
className="border-border flex items-center justify-between gap-3 rounded-md border px-3 py-1.5"
>
<div className="flex min-w-0 items-center gap-2">
<span className="text-sm">{library.name}</span>
{!library.enabled && (
<Badge variant="outline" className="px-1 py-0 text-[10px]">
Disabled
</Badge>
)}
<span className="text-muted-foreground text-xs capitalize">{library.type}</span>
</div>
<Switch
checked={checked}
onCheckedChange={(nextChecked) => handleLibraryToggle(library.id, nextChecked)}
/>
</div>
);
})
)}
</div>
)}
</div>
);
}