Initialize governed Views module
This commit is contained in:
70
webui/src/components/ViewSelector.tsx
Normal file
70
webui/src/components/ViewSelector.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Eye, LockKeyhole } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
dispatchPlatformViewChanged,
|
||||
useUnsavedChanges,
|
||||
type ViewSelectorProps
|
||||
} from "@govoplan/core-webui";
|
||||
import { selectEffectiveView } from "../api/views";
|
||||
|
||||
|
||||
export default function ViewSelector({
|
||||
settings,
|
||||
projection
|
||||
}: ViewSelectorProps) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const { requestNavigation } = useUnsavedChanges();
|
||||
const options = projection?.availableViews ?? [];
|
||||
|
||||
if (!projection?.activeViewId && options.length === 0) return null;
|
||||
|
||||
async function performSelect(viewId: string) {
|
||||
setBusy(true);
|
||||
setError("");
|
||||
try {
|
||||
await selectEffectiveView(settings, viewId || null);
|
||||
dispatchPlatformViewChanged();
|
||||
} catch (caught) {
|
||||
setError(caught instanceof Error ? caught.message : "View selection failed");
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
function select(viewId: string) {
|
||||
requestNavigation(() => {
|
||||
void performSelect(viewId);
|
||||
});
|
||||
}
|
||||
|
||||
const locked = Boolean(projection?.locked);
|
||||
const diagnostic = projection?.diagnostics.find((item) => item.severity === "error")
|
||||
?? projection?.diagnostics[0];
|
||||
const title = error || diagnostic?.message || (
|
||||
locked
|
||||
? "This View is required by an administrator."
|
||||
: "Choose which parts of GovOPlaN are shown."
|
||||
);
|
||||
|
||||
return (
|
||||
<label className="titlebar-view-selector" title={title}>
|
||||
{locked
|
||||
? <LockKeyhole size={16} aria-hidden="true" />
|
||||
: <Eye size={16} aria-hidden="true" />}
|
||||
<span className="sr-only">Current View</span>
|
||||
<select
|
||||
value={projection?.activeViewId ?? ""}
|
||||
disabled={busy || locked}
|
||||
aria-label="Current View"
|
||||
aria-invalid={Boolean(error) || undefined}
|
||||
onChange={(event) => select(event.target.value)}
|
||||
>
|
||||
{!locked && <option value="">Full interface</option>}
|
||||
{options.map((option) => (
|
||||
<option key={option.id} value={option.id}>{option.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user