Migrate Tenancy interface patterns
This commit is contained in:
@@ -1,10 +1,25 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import type { ApiSettings } from "@govoplan/core-webui";
|
||||
import { Button } from "@govoplan/core-webui";
|
||||
import { Card } from "@govoplan/core-webui";
|
||||
import { FormField } from "@govoplan/core-webui";
|
||||
import {
|
||||
ActionBlockerHint,
|
||||
AdminPageLayout,
|
||||
AdminSelectionList,
|
||||
Button,
|
||||
Card,
|
||||
DocumentationHelpLink,
|
||||
FormField,
|
||||
adminErrorMessage,
|
||||
useDeltaWatermarks,
|
||||
useUnsavedChanges,
|
||||
useUnsavedDraftGuard,
|
||||
type ApiSettings
|
||||
} from "@govoplan/core-webui";
|
||||
import { fetchTenantSettingsDelta, updateTenantSettings, type TenantSettingsDeltaSections, type TenantSettingsItem } from "../../api/tenancy";
|
||||
import { AdminPageLayout, AdminSelectionList, adminErrorMessage, useDeltaWatermarks, useUnsavedDraftGuard } from "@govoplan/core-webui";
|
||||
import {
|
||||
TENANCY_ADMIN_DOCUMENTATION,
|
||||
TENANCY_FIELD_DOCUMENTATION,
|
||||
TENANCY_INTERFACE_I18N,
|
||||
tenantMutationDisabledReason
|
||||
} from "./interfacePatterns";
|
||||
|
||||
const DELTA_KEY = "tenancy:tenant-settings";
|
||||
|
||||
@@ -31,6 +46,7 @@ export default function TenantSettingsPanel({
|
||||
|
||||
|
||||
}: {settings: ApiSettings;canWrite: boolean;onAuthRefresh: () => Promise<void>;}) {
|
||||
const { requestDiscard } = useUnsavedChanges();
|
||||
const [draft, setDraft] = useState<TenantSettingsItem>(fallback);
|
||||
const [savedDraft, setSavedDraft] = useState<TenantSettingsItem>(fallback);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -40,6 +56,13 @@ export default function TenantSettingsPanel({
|
||||
const { getDeltaWatermark, setDeltaWatermark, resetDeltaWatermark } = useDeltaWatermarks();
|
||||
const defaultLocaleOptions = localeOptions(draft.default_locale, draft.enabled_language_codes);
|
||||
const dirty = tenantSettingsDraftKey(draft) !== tenantSettingsDraftKey(savedDraft);
|
||||
const saveDisabledReason = tenantMutationDisabledReason({
|
||||
busy,
|
||||
permitted: canWrite,
|
||||
complete: Boolean(draft.default_locale.trim() && draft.enabled_language_codes.length),
|
||||
changed: dirty,
|
||||
permissionReason: TENANCY_INTERFACE_I18N.settingsWriteRequired
|
||||
});
|
||||
|
||||
useUnsavedDraftGuard({
|
||||
dirty,
|
||||
@@ -108,11 +131,26 @@ export default function TenantSettingsPanel({
|
||||
loading={loading}
|
||||
error={error}
|
||||
success={success}
|
||||
actions={<><Button onClick={() => void load()} disabled={loading}>i18n:govoplan-tenancy.reload.cce71553</Button><Button variant="primary" onClick={() => void save()} disabled={!canWrite || busy || !draft.default_locale.trim()}>{busy ? "i18n:govoplan-tenancy.saving.ae7e8875" : "i18n:govoplan-tenancy.save_general_settings.5c90f8c4"}</Button></>}>
|
||||
actions={<><DocumentationHelpLink reference={TENANCY_ADMIN_DOCUMENTATION} /><Button onClick={() => requestDiscard(() => void load())} disabled={loading || busy} disabledReason={loading ? TENANCY_INTERFACE_I18N.loading : busy ? TENANCY_INTERFACE_I18N.busy : undefined}>i18n:govoplan-tenancy.reload.cce71553</Button><Button variant="primary" onClick={() => void save()} disabled={Boolean(saveDisabledReason)} disabledReason={saveDisabledReason}>{busy ? "i18n:govoplan-tenancy.saving.ae7e8875" : "i18n:govoplan-tenancy.save_general_settings.5c90f8c4"}</Button></>}>
|
||||
|
||||
{!canWrite && <ActionBlockerHint
|
||||
reason={{
|
||||
summary: TENANCY_INTERFACE_I18N.readOnlySummary,
|
||||
requiredAction: TENANCY_INTERFACE_I18N.settingsPermissionGuidance,
|
||||
actor: TENANCY_INTERFACE_I18N.administratorActor,
|
||||
target: TENANCY_INTERFACE_I18N.tenantSettingsTarget
|
||||
}}
|
||||
labels={{
|
||||
requiredAction: TENANCY_INTERFACE_I18N.requiredActionLabel,
|
||||
actor: TENANCY_INTERFACE_I18N.actorLabel,
|
||||
target: TENANCY_INTERFACE_I18N.targetLabel
|
||||
}}
|
||||
documentation={TENANCY_ADMIN_DOCUMENTATION}
|
||||
/>}
|
||||
|
||||
<div className="admin-settings-form">
|
||||
<Card title="i18n:govoplan-tenancy.locale.8970f0e6">
|
||||
<FormField label="i18n:govoplan-tenancy.tenant_locale.8fc19914" help="i18n:govoplan-tenancy.used_as_this_tenant_s_locale_default_for_tenant_.cf298b8b">
|
||||
<FormField label="i18n:govoplan-tenancy.tenant_locale.8fc19914" help={!canWrite ? TENANCY_INTERFACE_I18N.settingsWriteRequired : "i18n:govoplan-tenancy.used_as_this_tenant_s_locale_default_for_tenant_.cf298b8b"} documentation={TENANCY_FIELD_DOCUMENTATION}>
|
||||
<select value={draft.default_locale} disabled={!canWrite || busy || defaultLocaleOptions.length === 0} onChange={(event) => setDraft({ ...draft, default_locale: event.target.value })}>
|
||||
{defaultLocaleOptions.map((code) => {
|
||||
const language = draft.available_languages.find((item) => item.code === code);
|
||||
@@ -128,7 +166,7 @@ export default function TenantSettingsPanel({
|
||||
selected={draft.enabled_language_codes}
|
||||
onChange={setEnabledLanguages}
|
||||
/>
|
||||
<p className="muted small-note">i18n:govoplan-tenancy.tenant_languages_help</p>
|
||||
<p className="muted small-note"><span>i18n:govoplan-tenancy.tenant_languages_help</span>{" "}<span>{TENANCY_INTERFACE_I18N.defaultLanguageRequired}</span></p>
|
||||
<dl className="detail-list">
|
||||
<div><dt>i18n:govoplan-tenancy.tenant.3ca93c78</dt><dd>{draft.name || "-"}</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.slug.094da9b9</dt><dd>{draft.slug || "-"}</dd></div>
|
||||
|
||||
@@ -1,16 +1,35 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Pencil, Plus, Search, Trash2 } from "lucide-react";
|
||||
import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
|
||||
import type { ApiSettings, AuthInfo, TenantAdminItem } from "@govoplan/core-webui";
|
||||
import {
|
||||
ActionBlockerHint,
|
||||
AdminIconButton,
|
||||
AdminPageLayout,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
DataGrid,
|
||||
Dialog,
|
||||
DocumentationHelpLink,
|
||||
FormField,
|
||||
StatusBadge,
|
||||
TableActionGroup,
|
||||
adminErrorMessage,
|
||||
formatAdminDateTime as formatDateTime,
|
||||
i18nMessage,
|
||||
useDeltaWatermarks,
|
||||
usePlatformLanguage,
|
||||
useUnsavedChanges,
|
||||
useUnsavedDraftGuard,
|
||||
type DataGridColumn
|
||||
} from "@govoplan/core-webui";
|
||||
import { createTenant, fetchSystemSettings, fetchTenantOwnerCandidates, fetchTenantsDelta, updateTenant, type SystemSettingsItem, type TenantOwnerCandidate } from "../../api/tenancy";
|
||||
import type { TenantAdminItem } from "@govoplan/core-webui";
|
||||
import { Button } from "@govoplan/core-webui";
|
||||
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
|
||||
import { Dialog } from "@govoplan/core-webui";
|
||||
import { FormField } from "@govoplan/core-webui";
|
||||
import { StatusBadge } from "@govoplan/core-webui";
|
||||
import { ConfirmDialog } from "@govoplan/core-webui";
|
||||
import { AdminIconButton, AdminPageLayout, TableActionGroup, adminErrorMessage, formatAdminDateTime as formatDateTime, i18nMessage, useDeltaWatermarks, useUnsavedDraftGuard } from "@govoplan/core-webui";
|
||||
import { loadDeltaRows } from "./utils/deltaRows";
|
||||
import {
|
||||
TENANCY_ADMIN_DOCUMENTATION,
|
||||
TENANCY_FIELD_DOCUMENTATION,
|
||||
TENANCY_INTERFACE_I18N,
|
||||
tenantMutationDisabledReason
|
||||
} from "./interfacePatterns";
|
||||
|
||||
type OverrideValue = "inherit" | "allow" | "deny";
|
||||
type TenantDraft = {
|
||||
@@ -64,6 +83,8 @@ export default function TenantsPanel({
|
||||
|
||||
|
||||
}: {settings: ApiSettings;auth: AuthInfo;canCreate: boolean;canUpdate: boolean;canSuspend: boolean;onAuthRefresh: () => Promise<void>;}) {
|
||||
const { translateText } = usePlatformLanguage();
|
||||
const { requestDiscard } = useUnsavedChanges();
|
||||
const [tenants, setTenants] = useState<TenantAdminItem[]>([]);
|
||||
const [systemSettings, setSystemSettings] = useState<SystemSettingsItem | null>(null);
|
||||
const [ownerCandidates, setOwnerCandidates] = useState<TenantOwnerCandidate[]>([]);
|
||||
@@ -144,6 +165,11 @@ export default function TenantsPanel({
|
||||
setSavedDraftKey(draftKey(emptyDraft));
|
||||
}
|
||||
|
||||
function requestCloseEditor() {
|
||||
if (busy) return;
|
||||
requestDiscard(closeEditor);
|
||||
}
|
||||
|
||||
async function save(): Promise<boolean> {
|
||||
setBusy(true);
|
||||
setError("");
|
||||
@@ -164,7 +190,7 @@ export default function TenantsPanel({
|
||||
...governance
|
||||
});
|
||||
const selectedOwner = ownerCandidates.find((candidate) => candidate.account_id === draft.ownerAccountId);
|
||||
setSuccess(i18nMessage("i18n:govoplan-tenancy.tenant_value_created_with_value_as_owner.1c18b6fb", { value0: created.name, value1: selectedOwner?.display_name || selectedOwner?.email || "i18n:govoplan-tenancy.the_selected_account.1211bfb9" }));
|
||||
setSuccess(i18nMessage("i18n:govoplan-tenancy.tenant_value_created_with_value_as_owner.1c18b6fb", { value0: created.name, value1: selectedOwner?.display_name || selectedOwner?.email || translateText("i18n:govoplan-tenancy.the_selected_account.1211bfb9") }));
|
||||
await onAuthRefresh();
|
||||
} else if (editing) {
|
||||
const payload: Parameters<typeof updateTenant>[2] = {};
|
||||
@@ -214,10 +240,17 @@ export default function TenantsPanel({
|
||||
const systemAllowsCustomRoles = systemSettings?.allow_tenant_custom_roles !== false;
|
||||
const systemAllowsApiKeys = systemSettings?.allow_tenant_api_keys !== false;
|
||||
const systemDeniedGovernance = [
|
||||
systemAllowsCustomGroups ? "" : "i18n:govoplan-tenancy.custom_groups.453a605c",
|
||||
systemAllowsCustomRoles ? "" : "i18n:govoplan-tenancy.custom_roles.d48dc976",
|
||||
systemAllowsApiKeys ? "" : "i18n:govoplan-tenancy.api_keys.94fcf3c2"].
|
||||
filter(Boolean).join(", ");
|
||||
systemAllowsCustomGroups ? "" : translateText("i18n:govoplan-tenancy.custom_groups.453a605c"),
|
||||
systemAllowsCustomRoles ? "" : translateText("i18n:govoplan-tenancy.custom_roles.d48dc976"),
|
||||
systemAllowsApiKeys ? "" : translateText("i18n:govoplan-tenancy.api_keys.94fcf3c2")
|
||||
].filter(Boolean).join(", ");
|
||||
const saveDisabledReason = tenantMutationDisabledReason({
|
||||
busy,
|
||||
permitted: editing === "new" ? canCreate : canUpdate,
|
||||
complete: Boolean(draft.name.trim() && draft.slug.trim() && (editing !== "new" || draft.ownerAccountId)),
|
||||
changed: editing === "new" || dirty,
|
||||
permissionReason: editing === "new" ? TENANCY_INTERFACE_I18N.createRequired : TENANCY_INTERFACE_I18N.updateRequired
|
||||
});
|
||||
const columns = useMemo<DataGridColumn<TenantAdminItem>[]>(() => [
|
||||
{ id: "name", header: "i18n:govoplan-tenancy.tenant.3ca93c78", width: "minmax(210px, 1fr)", minWidth: 190, resizable: true, sticky: "start", sortable: true, filterable: true, value: (row) => `${row.name} ${row.slug}`, render: (row) => <div><strong>{row.name}</strong><div className="muted small-note">{row.slug}</div></div> },
|
||||
{ id: "users", header: "i18n:govoplan-tenancy.users.57f2b181", width: 100, resizable: false, sortable: true, filterable: true, filterType: "integer", value: (row) => row.counts.users ?? 0, render: (row) => `${row.counts.active_users ?? 0}/${row.counts.users ?? 0}` },
|
||||
@@ -228,10 +261,10 @@ export default function TenantsPanel({
|
||||
{ id: "status", header: "i18n:govoplan-tenancy.status.bae7d5be", width: 120, resizable: false, sortable: true, filterable: true, value: (row) => row.is_active ? "active" : "inactive", render: (row) => <StatusBadge status={row.is_active ? "active" : "inactive"} /> },
|
||||
{ id: "actions", header: "i18n:govoplan-tenancy.actions.c3cd636a", width: 150, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[
|
||||
{ id: "inspect", label: i18nMessage("i18n:govoplan-tenancy.inspect_value.9d5d1071", { value0: row.name }), icon: <Search />, onClick: () => setViewing(row) },
|
||||
{ id: "edit", label: i18nMessage("i18n:govoplan-tenancy.edit_value.fad75899", { value0: row.name }), icon: <Pencil />, disabled: !canUpdate, onClick: () => openEdit(row) },
|
||||
{ id: "suspend", label: i18nMessage("i18n:govoplan-tenancy.suspend_value.03a74b32", { value0: row.name }), icon: <Trash2 />, variant: "danger", applicable: row.is_active, disabled: !canSuspend || row.id === activeTenantId, onClick: () => setConfirmSuspend(row) }
|
||||
]} /> }],
|
||||
[activeTenantId, canSuspend, canUpdate]);
|
||||
{ id: "edit", label: i18nMessage("i18n:govoplan-tenancy.edit_value.fad75899", { value0: row.name }), icon: <Pencil />, disabled: !canUpdate || busy, disabledReason: busy ? TENANCY_INTERFACE_I18N.busy : !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined, onClick: () => openEdit(row) },
|
||||
{ id: "suspend", label: i18nMessage("i18n:govoplan-tenancy.suspend_value.03a74b32", { value0: row.name }), icon: <Trash2 />, variant: "danger", disabled: !canSuspend || row.id === activeTenantId || !row.is_active || busy, disabledReason: busy ? TENANCY_INTERFACE_I18N.busy : !canSuspend ? TENANCY_INTERFACE_I18N.suspendRequired : row.id === activeTenantId ? TENANCY_INTERFACE_I18N.activeTenant : !row.is_active ? TENANCY_INTERFACE_I18N.alreadySuspended : undefined, onClick: () => setConfirmSuspend(row) }
|
||||
]} minimumSlots={3} /> }],
|
||||
[activeTenantId, busy, canSuspend, canUpdate]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -241,28 +274,43 @@ export default function TenantsPanel({
|
||||
loading={loading}
|
||||
error={error}
|
||||
success={success}
|
||||
actions={<><Button onClick={() => void load()} disabled={loading}>i18n:govoplan-tenancy.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-tenancy.add_tenant.b8e32af0" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} /></>}>
|
||||
actions={<><DocumentationHelpLink reference={TENANCY_ADMIN_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading || busy} disabledReason={loading ? TENANCY_INTERFACE_I18N.loading : busy ? TENANCY_INTERFACE_I18N.busy : undefined}>i18n:govoplan-tenancy.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-tenancy.add_tenant.b8e32af0" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate || busy} disabledReason={busy ? TENANCY_INTERFACE_I18N.busy : !canCreate ? TENANCY_INTERFACE_I18N.createRequired : undefined} /></>}>
|
||||
|
||||
{!canCreate && !canUpdate && !canSuspend && <ActionBlockerHint
|
||||
reason={{
|
||||
summary: TENANCY_INTERFACE_I18N.readOnlySummary,
|
||||
requiredAction: TENANCY_INTERFACE_I18N.registryPermissionGuidance,
|
||||
actor: TENANCY_INTERFACE_I18N.administratorActor,
|
||||
target: TENANCY_INTERFACE_I18N.tenantRegistryTarget
|
||||
}}
|
||||
labels={{
|
||||
requiredAction: TENANCY_INTERFACE_I18N.requiredActionLabel,
|
||||
actor: TENANCY_INTERFACE_I18N.actorLabel,
|
||||
target: TENANCY_INTERFACE_I18N.targetLabel
|
||||
}}
|
||||
documentation={TENANCY_ADMIN_DOCUMENTATION}
|
||||
/>}
|
||||
|
||||
<div className="admin-table-surface"><DataGrid id="admin-tenants-v3" rows={tenants} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-tenancy.no_tenants_found.72d04cf4" /></div>
|
||||
</AdminPageLayout>
|
||||
|
||||
<Dialog open={editing !== null} title={editing === "new" ? "i18n:govoplan-tenancy.create_tenant.4dbd55d9" : "i18n:govoplan-tenancy.edit_tenant.e2ba43f9"} onClose={() => !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<><Button onClick={() => setEditing(null)} disabled={busy}>i18n:govoplan-tenancy.cancel.77dfd213</Button><Button variant="primary" onClick={() => void save()} disabled={!(editing === "new" ? canCreate : canUpdate) || busy || !draft.name.trim() || !draft.slug.trim() || editing === "new" && !draft.ownerAccountId}>{busy ? "i18n:govoplan-tenancy.saving.56a2285c" : "i18n:govoplan-tenancy.save_tenant.9eb2ac74"}</Button></>}>
|
||||
<Dialog open={editing !== null} title={editing === "new" ? "i18n:govoplan-tenancy.create_tenant.4dbd55d9" : "i18n:govoplan-tenancy.edit_tenant.e2ba43f9"} onClose={requestCloseEditor} className="admin-dialog admin-dialog-wide" footer={<><Button onClick={requestCloseEditor} disabled={busy} disabledReason={busy ? TENANCY_INTERFACE_I18N.busy : undefined}>i18n:govoplan-tenancy.cancel.77dfd213</Button><Button variant="primary" onClick={() => void save()} disabled={Boolean(saveDisabledReason)} disabledReason={saveDisabledReason}>{busy ? "i18n:govoplan-tenancy.saving.56a2285c" : "i18n:govoplan-tenancy.save_tenant.9eb2ac74"}</Button></>}>
|
||||
<div className="admin-form-grid two-columns">
|
||||
<FormField label="i18n:govoplan-tenancy.name.709a2322"><input value={draft.name} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, name: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-tenancy.slug.094da9b9"><input value={draft.slug} disabled={editing !== "new" || !canCreate} onChange={(event) => setDraft({ ...draft, slug: event.target.value })} /></FormField>
|
||||
{editing === "new" && <FormField label="i18n:govoplan-tenancy.initial_tenant_owner.682291a9"><select value={draft.ownerAccountId} onChange={(event) => setDraft({ ...draft, ownerAccountId: event.target.value })}>{ownerCandidates.map((candidate) => <option key={candidate.account_id} value={candidate.account_id}>{candidate.display_name ? i18nMessage("i18n:govoplan-tenancy.value_value.c189e8bc", { value0: candidate.display_name, value1: candidate.email }) : candidate.email}</option>)}</select></FormField>}
|
||||
<FormField label="i18n:govoplan-tenancy.default_locale.b99d021f"><input value={draft.defaultLocale} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, defaultLocale: event.target.value })} /></FormField>
|
||||
{editing !== "new" && <FormField label="i18n:govoplan-tenancy.status.bae7d5be"><select value={draft.isActive ? "active" : "inactive"} disabled={!canSuspend} onChange={(event) => setDraft({ ...draft, isActive: event.target.value === "active" })}><option value="active">i18n:govoplan-tenancy.active.a733b809</option><option value="inactive">i18n:govoplan-tenancy.suspended.794696a7</option></select></FormField>}
|
||||
<FormField label="i18n:govoplan-tenancy.description.55f8ebc8"><textarea rows={4} value={draft.description} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, description: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-tenancy.name.709a2322" help={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} documentation={TENANCY_FIELD_DOCUMENTATION}><input value={draft.name} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, name: event.target.value })} /></FormField>
|
||||
<FormField label="i18n:govoplan-tenancy.slug.094da9b9" help={editing !== "new" ? "i18n:govoplan-tenancy.the_tenant_slug_is_immutable_after_creation.7c9a1025" : !canCreate ? TENANCY_INTERFACE_I18N.createRequired : undefined} documentation={TENANCY_FIELD_DOCUMENTATION}><input value={draft.slug} disabled={editing !== "new" || !canCreate} onChange={(event) => setDraft({ ...draft, slug: event.target.value })} /></FormField>
|
||||
{editing === "new" && <FormField label="i18n:govoplan-tenancy.initial_tenant_owner.682291a9" documentation={TENANCY_FIELD_DOCUMENTATION}><select value={draft.ownerAccountId} onChange={(event) => setDraft({ ...draft, ownerAccountId: event.target.value })}>{ownerCandidates.map((candidate) => <option key={candidate.account_id} value={candidate.account_id}>{candidate.display_name ? i18nMessage("i18n:govoplan-tenancy.value_value.c189e8bc", { value0: candidate.display_name, value1: candidate.email }) : candidate.email}</option>)}</select></FormField>}
|
||||
<FormField label="i18n:govoplan-tenancy.default_locale.b99d021f" help={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} documentation={TENANCY_FIELD_DOCUMENTATION}><input value={draft.defaultLocale} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, defaultLocale: event.target.value })} /></FormField>
|
||||
{editing !== "new" && <FormField label="i18n:govoplan-tenancy.status.bae7d5be" help={!canSuspend ? TENANCY_INTERFACE_I18N.suspendRequired : undefined} documentation={TENANCY_ADMIN_DOCUMENTATION}><select value={draft.isActive ? "active" : "inactive"} disabled={!canSuspend} onChange={(event) => setDraft({ ...draft, isActive: event.target.value === "active" })}><option value="active">i18n:govoplan-tenancy.active.a733b809</option><option value="inactive">i18n:govoplan-tenancy.suspended.794696a7</option></select></FormField>}
|
||||
<FormField label="i18n:govoplan-tenancy.description.55f8ebc8" help={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} documentation={TENANCY_FIELD_DOCUMENTATION}><textarea rows={4} value={draft.description} disabled={editing !== "new" && !canUpdate} onChange={(event) => setDraft({ ...draft, description: event.target.value })} /></FormField>
|
||||
</div>
|
||||
<h3>i18n:govoplan-tenancy.system_governance_overrides.97cdf3ce</h3>
|
||||
<div className="admin-form-grid two-columns">
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsCustomGroups} label="i18n:govoplan-tenancy.custom_tenant_groups.570ee603" value={draft.customGroups} onChange={(customGroups) => setDraft({ ...draft, customGroups })} />
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsCustomRoles} label="i18n:govoplan-tenancy.custom_tenant_roles.a738c37c" value={draft.customRoles} onChange={(customRoles) => setDraft({ ...draft, customRoles })} />
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} allowDisabled={!systemAllowsApiKeys} label="i18n:govoplan-tenancy.tenant_api_keys.4b1d81f8" value={draft.apiKeys} onChange={(apiKeys) => setDraft({ ...draft, apiKeys })} />
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} disabledReason={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} allowDisabled={!systemAllowsCustomGroups} label="i18n:govoplan-tenancy.custom_tenant_groups.570ee603" value={draft.customGroups} onChange={(customGroups) => setDraft({ ...draft, customGroups })} />
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} disabledReason={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} allowDisabled={!systemAllowsCustomRoles} label="i18n:govoplan-tenancy.custom_tenant_roles.a738c37c" value={draft.customRoles} onChange={(customRoles) => setDraft({ ...draft, customRoles })} />
|
||||
<GovernanceSelect disabled={editing !== "new" && !canUpdate} disabledReason={editing !== "new" && !canUpdate ? TENANCY_INTERFACE_I18N.updateRequired : undefined} allowDisabled={!systemAllowsApiKeys} label="i18n:govoplan-tenancy.tenant_api_keys.4b1d81f8" value={draft.apiKeys} onChange={(apiKeys) => setDraft({ ...draft, apiKeys })} />
|
||||
</div>
|
||||
<p className="muted small-note">i18n:govoplan-tenancy.inherit_follows_the_current_system_setting_expli.60d4d868</p>
|
||||
{systemDeniedGovernance && <p className="muted small-note">i18n:govoplan-tenancy.explicit_allow_is_unavailable_for.8d05fd4a {systemDeniedGovernance} i18n:govoplan-tenancy.because_the_current_system_setting_denies_it.3f59c244</p>}
|
||||
{systemDeniedGovernance && <p className="muted small-note"><span>i18n:govoplan-tenancy.explicit_allow_is_unavailable_for.8d05fd4a</span>{" "}{systemDeniedGovernance}{" "}<span>i18n:govoplan-tenancy.because_the_current_system_setting_denies_it.3f59c244</span></p>}
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={Boolean(viewing)} title="i18n:govoplan-tenancy.tenant_details.5976ba72" onClose={() => setViewing(null)} className="admin-dialog admin-dialog-wide" footer={<Button onClick={() => setViewing(null)}>i18n:govoplan-tenancy.close.bbfa773e</Button>}>
|
||||
@@ -270,10 +318,10 @@ export default function TenantsPanel({
|
||||
<div><dt>i18n:govoplan-tenancy.tenant.3ca93c78</dt><dd>{viewing.name}</dd></div><div><dt>i18n:govoplan-tenancy.slug.094da9b9</dt><dd>{viewing.slug}</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.status.bae7d5be</dt><dd>{viewing.is_active ? "i18n:govoplan-tenancy.active.a733b809" : "i18n:govoplan-tenancy.suspended.794696a7"}</dd></div><div><dt>i18n:govoplan-tenancy.default_locale.b99d021f</dt><dd>{viewing.default_locale}</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.created.accf40c8</dt><dd>{formatDateTime(viewing.created_at)}</dd></div><div><dt>i18n:govoplan-tenancy.updated.f2f8570d</dt><dd>{formatDateTime(viewing.updated_at)}</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.custom_groups.1f7b7c8f</dt><dd>{viewing.effective_governance.allow_custom_groups ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({fromOverride(viewing.allow_custom_groups)})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.custom_roles.e78ef63d</dt><dd>{viewing.effective_governance.allow_custom_roles ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({fromOverride(viewing.allow_custom_roles)})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.api_keys.94fcf3c2</dt><dd>{viewing.effective_governance.allow_api_keys ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({fromOverride(viewing.allow_api_keys)})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.objects.72a83add</dt><dd>{viewing.counts.users ?? 0} i18n:govoplan-tenancy.users.81651889 {viewing.counts.groups ?? 0} i18n:govoplan-tenancy.groups.07551586 {viewing.counts.campaigns ?? 0} i18n:govoplan-tenancy.campaigns.2282ffeb {viewing.counts.files ?? 0} files</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.custom_groups.1f7b7c8f</dt><dd>{viewing.effective_governance.allow_custom_groups ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({overrideLabel(fromOverride(viewing.allow_custom_groups))})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.custom_roles.e78ef63d</dt><dd>{viewing.effective_governance.allow_custom_roles ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({overrideLabel(fromOverride(viewing.allow_custom_roles))})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.api_keys.94fcf3c2</dt><dd>{viewing.effective_governance.allow_api_keys ? "i18n:govoplan-tenancy.allowed.77c7b490" : "i18n:govoplan-tenancy.denied.63b16bd4"} ({overrideLabel(fromOverride(viewing.allow_api_keys))})</dd></div>
|
||||
<div><dt>i18n:govoplan-tenancy.objects.72a83add</dt><dd>{viewing.counts.users ?? 0}{" "}<span>i18n:govoplan-tenancy.users.81651889</span>{" "}{viewing.counts.groups ?? 0}{" "}<span>i18n:govoplan-tenancy.groups.07551586</span>{" "}{viewing.counts.campaigns ?? 0}{" "}<span>i18n:govoplan-tenancy.campaigns.2282ffeb</span>{" "}{viewing.counts.files ?? 0}{" "}<span>i18n:govoplan-tenancy.files_lowercase.7c9a1026</span></dd></div>
|
||||
</dl>{viewing.description && <p>{viewing.description}</p>}</>}
|
||||
</Dialog>
|
||||
|
||||
@@ -282,8 +330,14 @@ export default function TenantsPanel({
|
||||
|
||||
}
|
||||
|
||||
function GovernanceSelect({ label, value, onChange, disabled = false, allowDisabled = false }: {label: string;value: OverrideValue;onChange: (value: OverrideValue) => void;disabled?: boolean;allowDisabled?: boolean;}) {
|
||||
return <FormField label={label}><select value={value} disabled={disabled} onChange={(event) => onChange(event.target.value as OverrideValue)}><option value="inherit">i18n:govoplan-tenancy.inherit_system_setting.7f125156</option><option value="allow" disabled={allowDisabled}>i18n:govoplan-tenancy.allow_when_system_allows.4c5178cb</option><option value="deny">i18n:govoplan-tenancy.explicitly_deny.17ad945a</option></select></FormField>;
|
||||
function GovernanceSelect({ label, value, onChange, disabled = false, disabledReason, allowDisabled = false }: {label: string;value: OverrideValue;onChange: (value: OverrideValue) => void;disabled?: boolean;disabledReason?: string;allowDisabled?: boolean;}) {
|
||||
return <FormField label={label} help={disabledReason ?? (allowDisabled ? TENANCY_INTERFACE_I18N.governanceSystemLimit : undefined)} documentation={TENANCY_FIELD_DOCUMENTATION}><select value={value} disabled={disabled} onChange={(event) => onChange(event.target.value as OverrideValue)}><option value="inherit">i18n:govoplan-tenancy.inherit_system_setting.7f125156</option><option value="allow" disabled={allowDisabled}>i18n:govoplan-tenancy.allow_when_system_allows.4c5178cb</option><option value="deny">i18n:govoplan-tenancy.explicitly_deny.17ad945a</option></select></FormField>;
|
||||
}
|
||||
|
||||
function overrideLabel(value: OverrideValue): string {
|
||||
if (value === "allow") return TENANCY_INTERFACE_I18N.allowLabel;
|
||||
if (value === "deny") return TENANCY_INTERFACE_I18N.denyLabel;
|
||||
return TENANCY_INTERFACE_I18N.inheritLabel;
|
||||
}
|
||||
|
||||
function draftKey(draft: TenantDraft): string {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { DocumentationHelpReference } from "@govoplan/core-webui";
|
||||
|
||||
export const TENANCY_ADMIN_DOCUMENTATION = {
|
||||
topicId: "tenancy.lifecycle-and-settings",
|
||||
documentationType: "admin"
|
||||
} satisfies DocumentationHelpReference;
|
||||
|
||||
export const TENANCY_FIELD_DOCUMENTATION = {
|
||||
topicId: "tenancy.reference.admin-fields",
|
||||
documentationType: "admin"
|
||||
} satisfies DocumentationHelpReference;
|
||||
|
||||
export const TENANCY_INTERFACE_I18N = {
|
||||
loading: "i18n:govoplan-tenancy.tenant_information_is_loading.7c9a1001",
|
||||
busy: "i18n:govoplan-tenancy.a_tenant_change_is_in_progress.7c9a1002",
|
||||
createRequired: "i18n:govoplan-tenancy.tenant_creation_permission_is_required.7c9a1003",
|
||||
updateRequired: "i18n:govoplan-tenancy.tenant_update_permission_is_required.7c9a1004",
|
||||
suspendRequired: "i18n:govoplan-tenancy.tenant_suspension_permission_is_required.7c9a1005",
|
||||
settingsWriteRequired: "i18n:govoplan-tenancy.tenant_settings_write_permission_is_required.7c9a1006",
|
||||
completeRequiredFields: "i18n:govoplan-tenancy.complete_all_required_tenant_fields_before_saving.7c9a1007",
|
||||
noPendingChanges: "i18n:govoplan-tenancy.make_a_change_before_saving.7c9a1008",
|
||||
activeTenant: "i18n:govoplan-tenancy.switch_to_another_tenant_before_suspending_the_active_tenant.7c9a1009",
|
||||
alreadySuspended: "i18n:govoplan-tenancy.this_tenant_is_already_suspended.7c9a1010",
|
||||
readOnlySummary: "i18n:govoplan-tenancy.tenant_administration_is_read_only.7c9a1011",
|
||||
requiredActionLabel: "i18n:govoplan-tenancy.required_action.7c9a1012",
|
||||
actorLabel: "i18n:govoplan-tenancy.responsible_actor.7c9a1013",
|
||||
targetLabel: "i18n:govoplan-tenancy.destination.7c9a1014",
|
||||
administratorActor: "i18n:govoplan-tenancy.a_system_or_tenant_owner_with_the_required_permission.7c9a1015",
|
||||
tenantRegistryTarget: "i18n:govoplan-tenancy.administration_tenants.7c9a1016",
|
||||
tenantSettingsTarget: "i18n:govoplan-tenancy.administration_tenant_settings.7c9a1017",
|
||||
registryPermissionGuidance: "i18n:govoplan-tenancy.request_a_tenant_management_permission_or_contact_a_system_owner.7c9a1018",
|
||||
settingsPermissionGuidance: "i18n:govoplan-tenancy.request_tenant_settings_write_permission_or_contact_a_tenant_owner.7c9a1019",
|
||||
defaultLanguageRequired: "i18n:govoplan-tenancy.the_default_language_must_remain_enabled.7c9a1020",
|
||||
governanceSystemLimit: "i18n:govoplan-tenancy.system_policy_prevents_this_tenant_from_enabling_the_capability.7c9a1021",
|
||||
inheritLabel: "i18n:govoplan-tenancy.inherit.7c9a1022",
|
||||
allowLabel: "i18n:govoplan-tenancy.allow.7c9a1023",
|
||||
denyLabel: "i18n:govoplan-tenancy.deny.7c9a1024"
|
||||
} as const;
|
||||
|
||||
export function tenantMutationDisabledReason({
|
||||
busy,
|
||||
permitted,
|
||||
complete = true,
|
||||
changed = true,
|
||||
permissionReason
|
||||
}: {
|
||||
busy: boolean;
|
||||
permitted: boolean;
|
||||
complete?: boolean;
|
||||
changed?: boolean;
|
||||
permissionReason: string;
|
||||
}): string | undefined {
|
||||
if (busy) return TENANCY_INTERFACE_I18N.busy;
|
||||
if (!permitted) return permissionReason;
|
||||
if (!complete) return TENANCY_INTERFACE_I18N.completeRequiredFields;
|
||||
if (!changed) return TENANCY_INTERFACE_I18N.noPendingChanges;
|
||||
return undefined;
|
||||
}
|
||||
@@ -2,79 +2,131 @@ import type { PlatformTranslations } from "@govoplan/core-webui";
|
||||
|
||||
export const generatedTranslations: PlatformTranslations = {
|
||||
"en": {
|
||||
"i18n:govoplan-tenancy.tenant_information_is_loading.7c9a1001": "Tenant information is loading.",
|
||||
"i18n:govoplan-tenancy.a_tenant_change_is_in_progress.7c9a1002": "A tenant change is in progress.",
|
||||
"i18n:govoplan-tenancy.tenant_creation_permission_is_required.7c9a1003": "Tenant creation permission is required.",
|
||||
"i18n:govoplan-tenancy.tenant_update_permission_is_required.7c9a1004": "Tenant update permission is required.",
|
||||
"i18n:govoplan-tenancy.tenant_suspension_permission_is_required.7c9a1005": "Tenant suspension permission is required.",
|
||||
"i18n:govoplan-tenancy.tenant_settings_write_permission_is_required.7c9a1006": "Tenant settings write permission is required.",
|
||||
"i18n:govoplan-tenancy.complete_all_required_tenant_fields_before_saving.7c9a1007": "Complete all required tenant fields before saving.",
|
||||
"i18n:govoplan-tenancy.make_a_change_before_saving.7c9a1008": "Make a change before saving.",
|
||||
"i18n:govoplan-tenancy.switch_to_another_tenant_before_suspending_the_active_tenant.7c9a1009": "Switch to another tenant before suspending the active tenant.",
|
||||
"i18n:govoplan-tenancy.this_tenant_is_already_suspended.7c9a1010": "This tenant is already suspended.",
|
||||
"i18n:govoplan-tenancy.tenant_administration_is_read_only.7c9a1011": "Tenant administration is read-only.",
|
||||
"i18n:govoplan-tenancy.required_action.7c9a1012": "Required action",
|
||||
"i18n:govoplan-tenancy.responsible_actor.7c9a1013": "Responsible actor",
|
||||
"i18n:govoplan-tenancy.destination.7c9a1014": "Destination",
|
||||
"i18n:govoplan-tenancy.a_system_or_tenant_owner_with_the_required_permission.7c9a1015": "A system or tenant owner with the required permission",
|
||||
"i18n:govoplan-tenancy.administration_tenants.7c9a1016": "Administration > Tenants",
|
||||
"i18n:govoplan-tenancy.administration_tenant_settings.7c9a1017": "Administration > Tenant settings",
|
||||
"i18n:govoplan-tenancy.request_a_tenant_management_permission_or_contact_a_system_owner.7c9a1018": "Request a tenant-management permission or contact a system owner.",
|
||||
"i18n:govoplan-tenancy.request_tenant_settings_write_permission_or_contact_a_tenant_owner.7c9a1019": "Request tenant-settings write permission or contact a tenant owner.",
|
||||
"i18n:govoplan-tenancy.the_default_language_must_remain_enabled.7c9a1020": "The default language must remain enabled.",
|
||||
"i18n:govoplan-tenancy.system_policy_prevents_this_tenant_from_enabling_the_capability.7c9a1021": "System policy prevents this tenant from enabling the capability.",
|
||||
"i18n:govoplan-tenancy.inherit.7c9a1022": "inherit",
|
||||
"i18n:govoplan-tenancy.allow.7c9a1023": "allow",
|
||||
"i18n:govoplan-tenancy.deny.7c9a1024": "deny",
|
||||
"i18n:govoplan-tenancy.the_tenant_slug_is_immutable_after_creation.7c9a1025": "The tenant slug is immutable after creation.",
|
||||
"i18n:govoplan-tenancy.files_lowercase.7c9a1026": "files",
|
||||
"i18n:govoplan-tenancy.actions.c3cd636a": "Actions",
|
||||
"i18n:govoplan-tenancy.active.a733b809": "Active",
|
||||
"i18n:govoplan-tenancy.add_tenant.b8e32af0": "Add tenant",
|
||||
"i18n:govoplan-tenancy.allow_when_system_allows.4c5178cb": "Allow when system allows",
|
||||
"i18n:govoplan-tenancy.allowed.77c7b490": "Allowed",
|
||||
"i18n:govoplan-tenancy.allow_when_system_allows.4c5178cb": "Erlauben, wenn systemweit zulässig",
|
||||
"i18n:govoplan-tenancy.allowed.77c7b490": "Erlaubt",
|
||||
"i18n:govoplan-tenancy.api_keys.94fcf3c2": "API keys",
|
||||
"i18n:govoplan-tenancy.available.7c62a142": "Available",
|
||||
"i18n:govoplan-tenancy.because_the_current_system_setting_denies_it.3f59c244": "because the current system setting denies it.",
|
||||
"i18n:govoplan-tenancy.because_the_current_system_setting_denies_it.3f59c244": "da die aktuelle Systemeinstellung dies verweigert.",
|
||||
"i18n:govoplan-tenancy.campaigns.01a23a28": "Campaigns",
|
||||
"i18n:govoplan-tenancy.campaigns.2282ffeb": "campaigns,",
|
||||
"i18n:govoplan-tenancy.campaigns.2282ffeb": "Kampagnen,",
|
||||
"i18n:govoplan-tenancy.cancel.77dfd213": "Cancel",
|
||||
"i18n:govoplan-tenancy.close.bbfa773e": "Close",
|
||||
"i18n:govoplan-tenancy.create_and_govern_tenant_spaces_suspension_retai.1b76d377": "Create and govern tenant spaces. Suspension retains campaigns, files and audit evidence; the tenant backing the current session cannot be suspended.",
|
||||
"i18n:govoplan-tenancy.create_and_govern_tenant_spaces_suspension_retai.1b76d377": "Mandantenbereiche erstellen und verwalten. Eine Sperrung bewahrt Kampagnen, Dateien und Nachweise; der Mandant der aktuellen Sitzung kann nicht gesperrt werden.",
|
||||
"i18n:govoplan-tenancy.create_tenant.4dbd55d9": "Create tenant",
|
||||
"i18n:govoplan-tenancy.created.accf40c8": "Created",
|
||||
"i18n:govoplan-tenancy.custom_groups.1f7b7c8f": "Custom groups",
|
||||
"i18n:govoplan-tenancy.custom_groups.453a605c": "custom groups",
|
||||
"i18n:govoplan-tenancy.custom_roles.d48dc976": "custom roles",
|
||||
"i18n:govoplan-tenancy.custom_roles.e78ef63d": "Custom roles",
|
||||
"i18n:govoplan-tenancy.custom_tenant_groups.570ee603": "Custom tenant groups",
|
||||
"i18n:govoplan-tenancy.custom_tenant_roles.a738c37c": "Custom tenant roles",
|
||||
"i18n:govoplan-tenancy.custom_groups.1f7b7c8f": "Eigene Gruppen",
|
||||
"i18n:govoplan-tenancy.custom_groups.453a605c": "eigene Gruppen",
|
||||
"i18n:govoplan-tenancy.custom_roles.d48dc976": "eigene Rollen",
|
||||
"i18n:govoplan-tenancy.custom_roles.e78ef63d": "Eigene Rollen",
|
||||
"i18n:govoplan-tenancy.custom_tenant_groups.570ee603": "Eigene Mandantengruppen",
|
||||
"i18n:govoplan-tenancy.custom_tenant_roles.a738c37c": "Eigene Mandantenrollen",
|
||||
"i18n:govoplan-tenancy.default_locale.b99d021f": "Default locale",
|
||||
"i18n:govoplan-tenancy.denied.63b16bd4": "Denied",
|
||||
"i18n:govoplan-tenancy.denied.63b16bd4": "Verweigert",
|
||||
"i18n:govoplan-tenancy.description.55f8ebc8": "Description",
|
||||
"i18n:govoplan-tenancy.edit_tenant.e2ba43f9": "Edit tenant",
|
||||
"i18n:govoplan-tenancy.edit_value.fad75899": "Edit {value0}",
|
||||
"i18n:govoplan-tenancy.explicit_allow_is_unavailable_for.8d05fd4a": "Explicit allow is unavailable for",
|
||||
"i18n:govoplan-tenancy.explicitly_deny.17ad945a": "Explicitly deny",
|
||||
"i18n:govoplan-tenancy.edit_value.fad75899": "{value0} bearbeiten",
|
||||
"i18n:govoplan-tenancy.explicit_allow_is_unavailable_for.8d05fd4a": "Eine ausdrückliche Erlaubnis ist nicht verfügbar für",
|
||||
"i18n:govoplan-tenancy.explicitly_deny.17ad945a": "Ausdrücklich verweigern",
|
||||
"i18n:govoplan-tenancy.files.6ce6c512": "Files",
|
||||
"i18n:govoplan-tenancy.general.9239ee2c": "General",
|
||||
"i18n:govoplan-tenancy.groups.07551586": "groups,",
|
||||
"i18n:govoplan-tenancy.groups.07551586": "Gruppen,",
|
||||
"i18n:govoplan-tenancy.groups.ae9629f4": "Groups",
|
||||
"i18n:govoplan-tenancy.inherit_follows_the_current_system_setting_expli.60d4d868": "Inherit follows the current system setting. Explicit deny narrows access; explicit allow is valid only while the system setting allows it.",
|
||||
"i18n:govoplan-tenancy.inherit_system_setting.7f125156": "Inherit system setting",
|
||||
"i18n:govoplan-tenancy.initial_tenant_owner.682291a9": "Initial tenant owner",
|
||||
"i18n:govoplan-tenancy.inspect_value.9d5d1071": "Inspect {value0}",
|
||||
"i18n:govoplan-tenancy.inherit_follows_the_current_system_setting_expli.60d4d868": "Vererben folgt der aktuellen Systemeinstellung. Eine ausdrückliche Verweigerung schränkt ein; eine ausdrückliche Erlaubnis gilt nur, solange sie systemweit zulässig ist.",
|
||||
"i18n:govoplan-tenancy.inherit_system_setting.7f125156": "Systemeinstellung vererben",
|
||||
"i18n:govoplan-tenancy.initial_tenant_owner.682291a9": "Anfängliche Mandanteneigentümerschaft",
|
||||
"i18n:govoplan-tenancy.inspect_value.9d5d1071": "{value0} anzeigen",
|
||||
"i18n:govoplan-tenancy.locale.8970f0e6": "Locale",
|
||||
"i18n:govoplan-tenancy.name.709a2322": "Name",
|
||||
"i18n:govoplan-tenancy.no_tenants_found.72d04cf4": "No tenants found.",
|
||||
"i18n:govoplan-tenancy.objects.72a83add": "Objects",
|
||||
"i18n:govoplan-tenancy.no_tenants_found.72d04cf4": "Keine Mandanten gefunden.",
|
||||
"i18n:govoplan-tenancy.objects.72a83add": "Objekte",
|
||||
"i18n:govoplan-tenancy.reload.cce71553": "Reload",
|
||||
"i18n:govoplan-tenancy.save_general_settings.5c90f8c4": "Save general settings",
|
||||
"i18n:govoplan-tenancy.save_general_settings.5c90f8c4": "Allgemeine Einstellungen speichern",
|
||||
"i18n:govoplan-tenancy.save_tenant.9eb2ac74": "Save tenant",
|
||||
"i18n:govoplan-tenancy.saving.56a2285c": "Saving…",
|
||||
"i18n:govoplan-tenancy.saving.ae7e8875": "Saving...",
|
||||
"i18n:govoplan-tenancy.settings_for_the_active_tenant_context.ad267b86": "Settings for the active tenant context.",
|
||||
"i18n:govoplan-tenancy.saving.56a2285c": "Speichern…",
|
||||
"i18n:govoplan-tenancy.saving.ae7e8875": "Speichern...",
|
||||
"i18n:govoplan-tenancy.settings_for_the_active_tenant_context.ad267b86": "Einstellungen für den aktiven Mandantenkontext.",
|
||||
"i18n:govoplan-tenancy.slug.094da9b9": "Slug",
|
||||
"i18n:govoplan-tenancy.status.bae7d5be": "Status",
|
||||
"i18n:govoplan-tenancy.suspend_tenant.151d283a": "Suspend tenant",
|
||||
"i18n:govoplan-tenancy.suspend_value.03a74b32": "Suspend {value0}",
|
||||
"i18n:govoplan-tenancy.suspend_value_existing_data_remains_retained_but.19bccd78": "Suspend {value0}? Existing data remains retained, but its members cannot use the tenant.",
|
||||
"i18n:govoplan-tenancy.suspended.794696a7": "Suspended",
|
||||
"i18n:govoplan-tenancy.system_governance_overrides.97cdf3ce": "System governance overrides",
|
||||
"i18n:govoplan-tenancy.suspend_tenant.151d283a": "Mandant sperren",
|
||||
"i18n:govoplan-tenancy.suspend_value.03a74b32": "{value0} sperren",
|
||||
"i18n:govoplan-tenancy.suspend_value_existing_data_remains_retained_but.19bccd78": "{value0} sperren? Bestehende Daten bleiben erhalten, aber Mitglieder können den Mandanten nicht mehr verwenden.",
|
||||
"i18n:govoplan-tenancy.suspended.794696a7": "Gesperrt",
|
||||
"i18n:govoplan-tenancy.system_governance_overrides.97cdf3ce": "Systemvorgaben",
|
||||
"i18n:govoplan-tenancy.tenancy": "Tenancy",
|
||||
"i18n:govoplan-tenancy.tenant.3ca93c78": "Tenant",
|
||||
"i18n:govoplan-tenancy.tenant_api_keys.4b1d81f8": "Tenant API keys",
|
||||
"i18n:govoplan-tenancy.tenant_details.5976ba72": "Tenant details",
|
||||
"i18n:govoplan-tenancy.tenant_general_settings.db1c3ba8": "Tenant general settings",
|
||||
"i18n:govoplan-tenancy.tenant_general_settings_saved.485e7681": "Tenant general settings saved.",
|
||||
"i18n:govoplan-tenancy.tenant_details.5976ba72": "Mandantendetails",
|
||||
"i18n:govoplan-tenancy.tenant_general_settings.db1c3ba8": "Allgemeine Mandanteneinstellungen",
|
||||
"i18n:govoplan-tenancy.tenant_general_settings_saved.485e7681": "Allgemeine Mandanteneinstellungen gespeichert.",
|
||||
"i18n:govoplan-tenancy.tenant_languages_help": "Tenant languages can only be selected from languages enabled by the system. Users can choose from the tenant-enabled set.",
|
||||
"i18n:govoplan-tenancy.tenant_locale.8fc19914": "Tenant locale",
|
||||
"i18n:govoplan-tenancy.tenant_value_created_with_value_as_owner.1c18b6fb": "Tenant {value0} created with {value1} as Owner.",
|
||||
"i18n:govoplan-tenancy.tenant_value_updated.25b2c855": "Tenant {value0} updated.",
|
||||
"i18n:govoplan-tenancy.tenant_locale.8fc19914": "Mandantensprache",
|
||||
"i18n:govoplan-tenancy.tenant_value_created_with_value_as_owner.1c18b6fb": "Mandant {value0} mit {value1} als Eigentümerschaft erstellt.",
|
||||
"i18n:govoplan-tenancy.tenant_value_updated.25b2c855": "Mandant {value0} aktualisiert.",
|
||||
"i18n:govoplan-tenancy.tenants.1f7ae776": "Tenants",
|
||||
"i18n:govoplan-tenancy.the_selected_account.1211bfb9": "the selected account",
|
||||
"i18n:govoplan-tenancy.the_selected_account.1211bfb9": "das ausgewählte Konto",
|
||||
"i18n:govoplan-tenancy.updated.f2f8570d": "Updated",
|
||||
"i18n:govoplan-tenancy.used_as_this_tenant_s_locale_default_for_tenant_.cf298b8b": "Used as this tenant's locale default for tenant-aware views and future formatting defaults.",
|
||||
"i18n:govoplan-tenancy.used_as_this_tenant_s_locale_default_for_tenant_.cf298b8b": "Wird als Standardsprache dieses Mandanten für mandantenbezogene Ansichten und Formatierungen verwendet.",
|
||||
"i18n:govoplan-tenancy.users.57f2b181": "Users",
|
||||
"i18n:govoplan-tenancy.users.81651889": "users,",
|
||||
"i18n:govoplan-tenancy.value_suspended.31731a28": "{value0} suspended.",
|
||||
"i18n:govoplan-tenancy.users.81651889": "Benutzer,",
|
||||
"i18n:govoplan-tenancy.value_suspended.31731a28": "{value0} gesperrt.",
|
||||
"i18n:govoplan-tenancy.value_value.c189e8bc": "{value0} ({value1})"
|
||||
},
|
||||
"de": {
|
||||
"i18n:govoplan-tenancy.tenant_information_is_loading.7c9a1001": "Mandanteninformationen werden geladen.",
|
||||
"i18n:govoplan-tenancy.a_tenant_change_is_in_progress.7c9a1002": "Eine Mandantenänderung wird gerade ausgeführt.",
|
||||
"i18n:govoplan-tenancy.tenant_creation_permission_is_required.7c9a1003": "Die Berechtigung zum Erstellen von Mandanten ist erforderlich.",
|
||||
"i18n:govoplan-tenancy.tenant_update_permission_is_required.7c9a1004": "Die Berechtigung zum Bearbeiten von Mandanten ist erforderlich.",
|
||||
"i18n:govoplan-tenancy.tenant_suspension_permission_is_required.7c9a1005": "Die Berechtigung zum Sperren von Mandanten ist erforderlich.",
|
||||
"i18n:govoplan-tenancy.tenant_settings_write_permission_is_required.7c9a1006": "Die Schreibberechtigung für Mandanteneinstellungen ist erforderlich.",
|
||||
"i18n:govoplan-tenancy.complete_all_required_tenant_fields_before_saving.7c9a1007": "Füllen Sie vor dem Speichern alle erforderlichen Mandantenfelder aus.",
|
||||
"i18n:govoplan-tenancy.make_a_change_before_saving.7c9a1008": "Nehmen Sie vor dem Speichern eine Änderung vor.",
|
||||
"i18n:govoplan-tenancy.switch_to_another_tenant_before_suspending_the_active_tenant.7c9a1009": "Wechseln Sie zu einem anderen Mandanten, bevor Sie den aktiven Mandanten sperren.",
|
||||
"i18n:govoplan-tenancy.this_tenant_is_already_suspended.7c9a1010": "Dieser Mandant ist bereits gesperrt.",
|
||||
"i18n:govoplan-tenancy.tenant_administration_is_read_only.7c9a1011": "Die Mandantenverwaltung ist schreibgeschützt.",
|
||||
"i18n:govoplan-tenancy.required_action.7c9a1012": "Erforderliche Aktion",
|
||||
"i18n:govoplan-tenancy.responsible_actor.7c9a1013": "Zuständige Stelle",
|
||||
"i18n:govoplan-tenancy.destination.7c9a1014": "Ziel",
|
||||
"i18n:govoplan-tenancy.a_system_or_tenant_owner_with_the_required_permission.7c9a1015": "Eine System- oder Mandanteneigentümerschaft mit der erforderlichen Berechtigung",
|
||||
"i18n:govoplan-tenancy.administration_tenants.7c9a1016": "Administration > Mandanten",
|
||||
"i18n:govoplan-tenancy.administration_tenant_settings.7c9a1017": "Administration > Mandanteneinstellungen",
|
||||
"i18n:govoplan-tenancy.request_a_tenant_management_permission_or_contact_a_system_owner.7c9a1018": "Fordern Sie eine Mandantenverwaltungsberechtigung an oder wenden Sie sich an eine Systemeigentümerschaft.",
|
||||
"i18n:govoplan-tenancy.request_tenant_settings_write_permission_or_contact_a_tenant_owner.7c9a1019": "Fordern Sie die Schreibberechtigung für Mandanteneinstellungen an oder wenden Sie sich an eine Mandanteneigentümerschaft.",
|
||||
"i18n:govoplan-tenancy.the_default_language_must_remain_enabled.7c9a1020": "Die Standardsprache muss aktiviert bleiben.",
|
||||
"i18n:govoplan-tenancy.system_policy_prevents_this_tenant_from_enabling_the_capability.7c9a1021": "Die Systemrichtlinie verhindert, dass dieser Mandant die Funktion aktiviert.",
|
||||
"i18n:govoplan-tenancy.inherit.7c9a1022": "vererbt",
|
||||
"i18n:govoplan-tenancy.allow.7c9a1023": "erlauben",
|
||||
"i18n:govoplan-tenancy.deny.7c9a1024": "verweigern",
|
||||
"i18n:govoplan-tenancy.the_tenant_slug_is_immutable_after_creation.7c9a1025": "Der Mandanten-Slug kann nach der Erstellung nicht geändert werden.",
|
||||
"i18n:govoplan-tenancy.files_lowercase.7c9a1026": "Dateien",
|
||||
"i18n:govoplan-tenancy.actions.c3cd636a": "Aktionen",
|
||||
"i18n:govoplan-tenancy.active.a733b809": "Aktiv",
|
||||
"i18n:govoplan-tenancy.add_tenant.b8e32af0": "Mandant hinzufügen",
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ const adminSections: AdminSectionsUiCapability = {
|
||||
export const tenancyModule: PlatformWebModule = {
|
||||
id: "tenancy",
|
||||
label: "i18n:govoplan-tenancy.tenancy",
|
||||
version: "1.0.0",
|
||||
version: "0.1.8",
|
||||
optionalDependencies: ["access"],
|
||||
translations: {
|
||||
en: generatedTranslations.en,
|
||||
@@ -64,14 +64,14 @@ export const tenancyModule: PlatformWebModule = {
|
||||
id: "tenancy.admin.system-tenants",
|
||||
moduleId: "tenancy",
|
||||
kind: "section",
|
||||
label: "System tenants",
|
||||
label: "i18n:govoplan-tenancy.tenants.1f7ae776",
|
||||
order: 10
|
||||
},
|
||||
{
|
||||
id: "tenancy.admin.tenant-settings",
|
||||
moduleId: "tenancy",
|
||||
kind: "section",
|
||||
label: "Tenant settings",
|
||||
label: "i18n:govoplan-tenancy.tenant_general_settings.db1c3ba8",
|
||||
order: 90
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user