Add hierarchical View policy administration

This commit is contained in:
2026-08-04 08:21:49 +02:00
parent 86c95f85bb
commit fc6d333a64
7 changed files with 682 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui";
export type ViewPolicyScope = "system" | "tenant" | "group" | "user";
export type ViewPolicyItem = {
allow_view?: boolean;
allow_select?: boolean;
allow_assign?: boolean;
allow_edit?: boolean;
allow_derive?: boolean;
allow_workflow_activate?: boolean;
allowed_view_ids?: string[];
visible_surface_ids?: string[];
};
export type EffectiveViewPolicy = {
allow_view: boolean;
allow_select: boolean;
allow_assign: boolean;
allow_edit: boolean;
allow_derive: boolean;
allow_workflow_activate: boolean;
allowed_view_ids?: string[] | null;
visible_surface_ids?: string[] | null;
};
export type ViewPolicyScopeResponse = {
scope_type: ViewPolicyScope;
scope_id?: string | null;
id?: string | null;
revision?: number | null;
policy: ViewPolicyItem;
effective_policy: EffectiveViewPolicy;
parent_policy: EffectiveViewPolicy;
source_path: Array<{
scope_type: string;
scope_id?: string | null;
source_id?: string | null;
fields?: string[];
}>;
diagnostics: Array<Record<string, unknown>>;
};
export type ViewPolicyReferenceData = {
views: Array<{ id: string; name: string; scope_type?: string }>;
surfaces: Array<{ id: string; label: string; module_id: string; kind: string }>;
};
export function fetchViewPolicy(
settings: ApiSettings,
scope: ViewPolicyScope,
scopeId?: string | null
): Promise<ViewPolicyScopeResponse> {
return apiFetch(settings, apiPath(`/api/v1/admin/view-policies/${scope}`, {
scope_id: scopeId || undefined
}));
}
export function updateViewPolicy(
settings: ApiSettings,
scope: ViewPolicyScope,
scopeId: string | null | undefined,
policy: ViewPolicyItem
): Promise<ViewPolicyScopeResponse> {
return apiFetch(settings, apiPath(`/api/v1/admin/view-policies/${scope}`, {
scope_id: scopeId || undefined
}), {
method: "PUT",
body: JSON.stringify({ policy })
});
}
export function deleteViewPolicy(
settings: ApiSettings,
scope: ViewPolicyScope,
scopeId?: string | null
): Promise<ViewPolicyScopeResponse> {
return apiFetch(settings, apiPath(`/api/v1/admin/view-policies/${scope}`, {
scope_id: scopeId || undefined
}), { method: "DELETE" });
}
export async function fetchViewPolicyReferences(settings: ApiSettings): Promise<ViewPolicyReferenceData> {
const [definitionResult, surfaceResult] = await Promise.allSettled([
apiFetch<{ definitions: Array<{ id: string; name: string; scope_type?: string }> }>(
settings,
apiPath("/api/v1/views/definitions", { scope_type: "tenant", include_inherited: true })
),
apiFetch<{ surfaces: Array<{ id: string; label: string; module_id: string; kind: string }> }>(
settings,
"/api/v1/views/surfaces"
)
]);
return {
views: definitionResult.status === "fulfilled" ? definitionResult.value.definitions : [],
surfaces: surfaceResult.status === "fulfilled" ? surfaceResult.value.surfaces : []
};
}