feat: own tenant administration WebUI

This commit is contained in:
2026-07-31 04:21:34 +02:00
parent b40615f8ac
commit 118e96db43
12 changed files with 1040 additions and 3 deletions
+162
View File
@@ -0,0 +1,162 @@
import type {
ApiSettings,
DeltaDeletedItem,
PrivacyRetentionPolicy,
TenantAdminItem
} from "@govoplan/core-webui";
import {
apiFetch,
apiGetList,
apiQuery
} from "@govoplan/core-webui";
export type TenantOwnerCandidate = {
account_id: string;
email: string;
display_name?: string | null;
};
export type LanguagePackage = {
code: string;
label: string;
native_label?: string | null;
};
export type SystemSettingsItem = {
default_locale: string;
allow_tenant_custom_groups: boolean;
allow_tenant_custom_roles: boolean;
allow_tenant_api_keys: boolean;
privacy_retention_policy: PrivacyRetentionPolicy;
available_languages?: LanguagePackage[];
enabled_language_codes?: string[];
settings: Record<string, unknown>;
};
export type TenantSettingsItem = {
id: string;
slug: string;
name: string;
default_locale: string;
available_languages: LanguagePackage[];
system_enabled_language_codes: string[];
enabled_language_codes: string[];
settings: Record<string, unknown>;
};
export type TenantSettingsDeltaSections = Partial<{
identity: Pick<TenantSettingsItem, "id" | "slug" | "name">;
locale: Pick<TenantSettingsItem, "default_locale">;
languages: Pick<
TenantSettingsItem,
"available_languages" | "system_enabled_language_codes" | "enabled_language_codes"
>;
settings: TenantSettingsItem["settings"];
}>;
type DeltaResponseFields = {
deleted: DeltaDeletedItem[];
watermark?: string | null;
has_more: boolean;
full: boolean;
};
export type TenantListDeltaResponse = {
tenants: TenantAdminItem[];
} & DeltaResponseFields;
export type TenantSettingsDeltaResponse = {
item?: TenantSettingsItem | null;
sections: TenantSettingsDeltaSections;
changed_sections: string[];
} & DeltaResponseFields;
export function fetchTenantsDelta(
settings: ApiSettings,
options: { since?: string | null; limit?: number } = {}
): Promise<TenantListDeltaResponse> {
return apiFetch(
settings,
`/api/v1/admin/tenants/delta${apiQuery(options)}`
);
}
export async function fetchTenantOwnerCandidates(
settings: ApiSettings
): Promise<TenantOwnerCandidate[]> {
return apiGetList<TenantOwnerCandidate, "accounts">(
settings,
"/api/v1/admin/tenants/owner-candidates",
"accounts"
);
}
export function createTenant(
settings: ApiSettings,
payload: {
slug: string;
name: string;
owner_account_id?: string | null;
description?: string | null;
default_locale?: string;
settings?: Record<string, unknown>;
allow_custom_groups?: boolean | null;
allow_custom_roles?: boolean | null;
allow_api_keys?: boolean | null;
}
): Promise<TenantAdminItem> {
return apiFetch(settings, "/api/v1/admin/tenants", {
method: "POST",
body: JSON.stringify(payload)
});
}
export function updateTenant(
settings: ApiSettings,
tenantId: string,
payload: Partial<{
name: string;
description: string | null;
default_locale: string;
settings: Record<string, unknown>;
allow_custom_groups: boolean | null;
allow_custom_roles: boolean | null;
allow_api_keys: boolean | null;
is_active: boolean;
}>
): Promise<TenantAdminItem> {
return apiFetch(
settings,
`/api/v1/admin/tenants/${encodeURIComponent(tenantId)}`,
{ method: "PATCH", body: JSON.stringify(payload) }
);
}
export function fetchTenantSettingsDelta(
settings: ApiSettings,
options: { since?: string | null; limit?: number } = {}
): Promise<TenantSettingsDeltaResponse> {
return apiFetch(
settings,
`/api/v1/admin/tenant/settings/delta${apiQuery(options)}`
);
}
export function updateTenantSettings(
settings: ApiSettings,
payload: {
default_locale: string;
enabled_language_codes?: string[] | null;
}
): Promise<TenantSettingsItem> {
return apiFetch(settings, "/api/v1/admin/tenant/settings", {
method: "PATCH",
body: JSON.stringify(payload)
});
}
export function fetchSystemSettings(
settings: ApiSettings
): Promise<SystemSettingsItem> {
return apiFetch(settings, "/api/v1/admin/system/settings");
}