3 Commits
v0.1.6 ... main

Author SHA1 Message Date
c9e1fb287f intermittent commit 2026-07-14 13:22:10 +02:00
11ecf362a3 Release v0.1.8 2026-07-11 16:49:00 +02:00
24edb7eb8a Release v0.1.7 2026-07-11 02:34:55 +02:00
13 changed files with 537 additions and 201 deletions

View File

@@ -1,5 +1,9 @@
# GovOPlaN Admin # GovOPlaN Admin
<!-- govoplan-repository-type:start -->
**Repository type:** module (platform).
<!-- govoplan-repository-type:end -->
`govoplan-admin` owns generic system administration API and WebUI contributions `govoplan-admin` owns generic system administration API and WebUI contributions
during the GovOPlaN module split. during the GovOPlaN module split.
@@ -43,3 +47,19 @@ Package mutation is intentionally not executed inside the FastAPI request. The
admin UI records operator intent and queues or renders commands for the trusted admin UI records operator intent and queues or renders commands for the trusted
installer process described in installer process described in
`/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`. `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
## Package Surfaces
The admin UI intentionally exposes two different package concepts:
- **Configuration packages** are import/export bundles for module-owned
configuration data. They support dry-run diagnostics, approval, apply, and
export workflows without installing Python or WebUI packages.
- **Module package catalog** and **operator install plan** live under
**Modules**. They describe approved release artifacts, install/update/remove
plans, preflight blockers, maintenance-mode requirements, installer-daemon
requests, and rollback visibility.
These surfaces should stay separate in navigation and copy. If future UI work
combines them visually, it must still preserve the operator distinction between
configuration mutation and package installation.

View File

@@ -1,6 +1,6 @@
{ {
"name": "@govoplan/admin-webui", "name": "@govoplan/admin-webui",
"version": "0.1.6", "version": "0.1.8",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "webui/src/index.ts", "main": "webui/src/index.ts",
@@ -18,7 +18,7 @@
"LICENSE" "LICENSE"
], ],
"peerDependencies": { "peerDependencies": {
"@govoplan/core-webui": "^0.1.6", "@govoplan/core-webui": "^0.1.8",
"lucide-react": "^1.23.0", "lucide-react": "^1.23.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",

View File

@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "govoplan-admin" name = "govoplan-admin"
version = "0.1.6" version = "0.1.8"
description = "GovOPlaN generic administration module." description = "GovOPlaN generic administration module."
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
authors = [{ name = "GovOPlaN" }] authors = [{ name = "GovOPlaN" }]
dependencies = [ dependencies = [
"govoplan-core>=0.1.6", "govoplan-core>=0.1.8",
"govoplan-access>=0.1.6", "govoplan-access>=0.1.8",
] ]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]

View File

@@ -31,6 +31,7 @@ from govoplan_core.core.configuration_control import (
) )
from govoplan_core.core.module_management import ( from govoplan_core.core.module_management import (
PROTECTED_MODULES, PROTECTED_MODULES,
ModuleInstallPlan,
ModuleInstallPlanItem, ModuleInstallPlanItem,
ModuleManagementError, ModuleManagementError,
configured_enabled_modules, configured_enabled_modules,
@@ -49,6 +50,7 @@ from govoplan_core.core.module_installer import (
default_installer_runtime_dir, default_installer_runtime_dir,
list_module_installer_runs, list_module_installer_runs,
list_module_installer_requests, list_module_installer_requests,
module_install_catalog_companion_module_ids,
module_installer_daemon_status, module_installer_daemon_status,
module_install_preflight, module_install_preflight,
module_installer_lock_status, module_installer_lock_status,
@@ -57,6 +59,12 @@ from govoplan_core.core.module_installer import (
read_module_installer_request, read_module_installer_request,
retry_module_installer_request, retry_module_installer_request,
) )
from govoplan_core.core.module_installer_notifications import (
emit_module_installer_notification,
installer_notification_body,
installer_notification_priority,
installer_notification_subject,
)
from govoplan_core.core.module_license import module_license_decision, module_license_diagnostics from govoplan_core.core.module_license import module_license_decision, module_license_diagnostics
from govoplan_core.core.module_package_catalog import record_module_package_catalog_acceptance, validate_module_package_catalog from govoplan_core.core.module_package_catalog import record_module_package_catalog_acceptance, validate_module_package_catalog
from govoplan_core.core.maintenance import MAINTENANCE_ACCESS_SCOPE, MaintenanceMode, saved_maintenance_mode, save_maintenance_mode from govoplan_core.core.maintenance import MAINTENANCE_ACCESS_SCOPE, MaintenanceMode, saved_maintenance_mode, save_maintenance_mode
@@ -145,6 +153,11 @@ def _request_registry(request: Request) -> PlatformRegistry:
return registry return registry
def _optional_request_registry(request: Request) -> PlatformRegistry | None:
registry = getattr(request.app.state, "govoplan_registry", None)
return registry if isinstance(registry, PlatformRegistry) else None
def _request_lifecycle(request: Request) -> ModuleLifecycleManager: def _request_lifecycle(request: Request) -> ModuleLifecycleManager:
lifecycle = getattr(request.app.state, "govoplan_lifecycle", None) lifecycle = getattr(request.app.state, "govoplan_lifecycle", None)
if not isinstance(lifecycle, ModuleLifecycleManager): if not isinstance(lifecycle, ModuleLifecycleManager):
@@ -152,6 +165,29 @@ def _request_lifecycle(request: Request) -> ModuleLifecycleManager:
return lifecycle return lifecycle
def _emit_installer_request_notification(
*,
session: Session,
registry: PlatformRegistry | None,
tenant_id: str | None,
request: dict[str, object],
event_kind: str,
recipient_id: str | None = None,
) -> None:
status_value = str(request.get("status") or event_kind.rsplit(".", 1)[-1])
emit_module_installer_notification(
session=session,
registry=registry,
tenant_id=tenant_id,
request=request,
event_kind=event_kind,
subject=installer_notification_subject(event_kind, request),
body_text=installer_notification_body(event_kind, request),
recipient_id=recipient_id,
priority=installer_notification_priority(status_value),
)
def _http_admin_error(exc: Exception) -> HTTPException: def _http_admin_error(exc: Exception) -> HTTPException:
if isinstance(exc, AdminConflictError): if isinstance(exc, AdminConflictError):
return HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) return HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc))
@@ -429,17 +465,27 @@ def _webui_root() -> Path | None:
def _upsert_install_plan_item(session: Session, item: ModuleInstallPlanItem): def _upsert_install_plan_item(session: Session, item: ModuleInstallPlanItem):
return _upsert_install_plan_items(session, [item])
def _upsert_install_plan_items(session: Session, items: list[ModuleInstallPlanItem]):
existing = saved_module_install_plan(session) existing = saved_module_install_plan(session)
replacement_ids = {item.module_id for item in items if item.status == "planned"}
retained = [ retained = [
current current
for current in existing.items for current in existing.items
if not (current.status == "planned" and current.module_id == item.module_id) if not (current.status == "planned" and current.module_id in replacement_ids)
] ]
return save_module_install_plan(session, [*retained, item]) return save_module_install_plan(session, [*retained, *items])
def _catalog_plan_item(module_id: str, available_module_ids: set[str]) -> tuple[ModuleInstallPlanItem, dict[str, object]]: def _catalog_plan_item(
result = validate_module_package_catalog() module_id: str,
available_module_ids: set[str],
*,
validation: dict[str, object] | None = None,
) -> tuple[ModuleInstallPlanItem, dict[str, object]]:
result = validation or validate_module_package_catalog()
if not result.get("valid"): if not result.get("valid"):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
@@ -651,6 +697,7 @@ def read_module_install_request_detail(
@router.post("/system/modules/install-requests", response_model=ModuleInstallerRequestItem) @router.post("/system/modules/install-requests", response_model=ModuleInstallerRequestItem)
def create_module_install_request( def create_module_install_request(
payload: ModuleInstallerRequestCreateRequest, payload: ModuleInstallerRequestCreateRequest,
request_context: Request,
session: Session = Depends(get_session), session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(require_scope("system:settings:write")), principal: ApiPrincipal = Depends(require_scope("system:settings:write")),
): ):
@@ -663,8 +710,17 @@ def create_module_install_request(
request = queue_module_installer_request( request = queue_module_installer_request(
runtime_dir=runtime_dir, runtime_dir=runtime_dir,
requested_by=principal.user.id, requested_by=principal.user.id,
tenant_id=principal.tenant_id,
options=payload.options.model_dump(exclude_none=True), options=payload.options.model_dump(exclude_none=True),
) )
_emit_installer_request_notification(
session=session,
registry=_optional_request_registry(request_context),
tenant_id=principal.tenant_id,
request=request,
event_kind="module_installer.request.queued",
recipient_id=principal.user.id,
)
audit_from_principal( audit_from_principal(
session, session,
principal, principal,
@@ -686,6 +742,7 @@ def create_module_install_request(
@router.post("/system/modules/install-requests/{request_id}/cancel", response_model=ModuleInstallerRequestItem) @router.post("/system/modules/install-requests/{request_id}/cancel", response_model=ModuleInstallerRequestItem)
def cancel_module_install_request( def cancel_module_install_request(
request_id: str, request_id: str,
request_context: Request,
session: Session = Depends(get_session), session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(require_scope("system:settings:write")), principal: ApiPrincipal = Depends(require_scope("system:settings:write")),
): ):
@@ -703,6 +760,14 @@ def cancel_module_install_request(
) )
except ModuleInstallerError as exc: except ModuleInstallerError as exc:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc
_emit_installer_request_notification(
session=session,
registry=_optional_request_registry(request_context),
tenant_id=str(request.get("tenant_id") or principal.tenant_id),
request=request,
event_kind="module_installer.request.cancelled",
recipient_id=str(request.get("requested_by") or principal.user.id),
)
audit_from_principal( audit_from_principal(
session, session,
principal, principal,
@@ -724,6 +789,7 @@ def cancel_module_install_request(
@router.post("/system/modules/install-requests/{request_id}/retry", response_model=ModuleInstallerRequestItem) @router.post("/system/modules/install-requests/{request_id}/retry", response_model=ModuleInstallerRequestItem)
def retry_module_install_request( def retry_module_install_request(
request_id: str, request_id: str,
request_context: Request,
session: Session = Depends(get_session), session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(require_scope("system:settings:write")), principal: ApiPrincipal = Depends(require_scope("system:settings:write")),
): ):
@@ -741,6 +807,14 @@ def retry_module_install_request(
) )
except ModuleInstallerError as exc: except ModuleInstallerError as exc:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc
_emit_installer_request_notification(
session=session,
registry=_optional_request_registry(request_context),
tenant_id=str(request.get("tenant_id") or principal.tenant_id),
request=request,
event_kind="module_installer.request.queued",
recipient_id=principal.user.id,
)
audit_from_principal( audit_from_principal(
session, session,
principal, principal,
@@ -801,7 +875,19 @@ def plan_module_install_from_catalog(
lifecycle = getattr(request.app.state, "govoplan_lifecycle", None) lifecycle = getattr(request.app.state, "govoplan_lifecycle", None)
available = dict(lifecycle.available_modules) if isinstance(lifecycle, ModuleLifecycleManager) else available_module_manifests(ignore_load_errors=True) available = dict(lifecycle.available_modules) if isinstance(lifecycle, ModuleLifecycleManager) else available_module_manifests(ignore_load_errors=True)
item, validation = _catalog_plan_item(module_id, set(available)) item, validation = _catalog_plan_item(module_id, set(available))
plan = _upsert_install_plan_item(session, item) existing = saved_module_install_plan(session)
retained = [
current
for current in existing.items
if not (current.status == "planned" and current.module_id == item.module_id)
]
candidate_plan = ModuleInstallPlan(items=tuple([*retained, item]))
companion_ids = module_install_catalog_companion_module_ids(candidate_plan, available, validation=validation)
companion_items = [
_catalog_plan_item(companion_id, set(available), validation=validation)[0]
for companion_id in companion_ids
]
plan = _upsert_install_plan_items(session, [item, *companion_items])
record_module_package_catalog_acceptance(validation) record_module_package_catalog_acceptance(validation)
except ModuleManagementError as exc: except ModuleManagementError as exc:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc
@@ -816,6 +902,7 @@ def plan_module_install_from_catalog(
module_id=module_id, module_id=module_id,
outcome="planned", outcome="planned",
items=[item.as_dict() for item in plan.items], items=[item.as_dict() for item in plan.items],
companion_module_ids=list(companion_ids),
catalog_validation={ catalog_validation={
"valid": validation.get("valid"), "valid": validation.get("valid"),
"channel": validation.get("channel"), "channel": validation.get("channel"),
@@ -825,7 +912,10 @@ def plan_module_install_from_catalog(
) )
session.commit() session.commit()
planned_action = "update" if item.action == "update" else "install" planned_action = "update" if item.action == "update" else "install"
return _module_install_plan_response(session, request, notes=[f"Catalog {planned_action} entry planned for {module_id}."]) notes = [f"Catalog {planned_action} entry planned for {module_id}."]
if companion_ids:
notes.append("Required companion catalog entries added: " + ", ".join(companion_ids))
return _module_install_plan_response(session, request, notes=notes)
@router.post("/system/modules/{module_id}/uninstall-plan", response_model=ModuleInstallPlanResponse) @router.post("/system/modules/{module_id}/uninstall-plan", response_model=ModuleInstallPlanResponse)

View File

@@ -3,61 +3,10 @@ from __future__ import annotations
from datetime import datetime from datetime import datetime
from typing import Any, Literal from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator from pydantic import BaseModel, ConfigDict, Field
from govoplan_core.api.v1.schemas import DeltaDeletedItem from govoplan_core.api.v1.schemas import DeltaDeletedItem
from govoplan_core.privacy.schemas import PrivacyRetentionPolicyItem
RETENTION_DAY_KEYS = (
"raw_campaign_json_retention_days",
"generated_eml_retention_days",
"stored_report_detail_retention_days",
"mock_mailbox_retention_days",
"audit_detail_retention_days",
)
RETENTION_POLICY_FIELD_KEYS = (
"store_raw_campaign_json",
*RETENTION_DAY_KEYS,
"audit_detail_level",
)
def default_allow_lower_level_limits() -> dict[str, bool]:
return {key: True for key in RETENTION_POLICY_FIELD_KEYS}
def normalize_allow_lower_level_limits(value: Any, *, fill_defaults: bool) -> dict[str, bool] | None:
if value in (None, ""):
return default_allow_lower_level_limits() if fill_defaults else None
if not isinstance(value, dict):
raise ValueError("allow_lower_level_limits must be an object")
normalized = default_allow_lower_level_limits() if fill_defaults else {}
for key, allowed in value.items():
clean_key = str(key)
if clean_key not in RETENTION_POLICY_FIELD_KEYS:
raise ValueError(f"Unknown retention policy field: {clean_key}")
normalized[clean_key] = bool(allowed)
return normalized
class PrivacyRetentionPolicyItem(BaseModel):
model_config = ConfigDict(extra="forbid")
store_raw_campaign_json: bool = True
raw_campaign_json_retention_days: int | None = Field(default=None, ge=0)
generated_eml_retention_days: int | None = Field(default=None, ge=0)
stored_report_detail_retention_days: int | None = Field(default=None, ge=0)
mock_mailbox_retention_days: int | None = Field(default=None, ge=0)
audit_detail_retention_days: int | None = Field(default=None, ge=0)
audit_detail_level: Literal["full", "redacted", "minimal"] = "full"
allow_lower_level_limits: dict[str, bool] = Field(default_factory=default_allow_lower_level_limits)
@field_validator("allow_lower_level_limits", mode="before")
@classmethod
def _normalize_allow_lower_level_limits(cls, value: Any) -> Any:
return normalize_allow_lower_level_limits(value, fill_defaults=True)
class MaintenanceModeItem(BaseModel): class MaintenanceModeItem(BaseModel):
@@ -182,6 +131,7 @@ class ModuleInstallPlanItem(BaseModel):
python_ref: str | None = Field(default=None, max_length=1000) python_ref: str | None = Field(default=None, max_length=1000)
webui_package: str | None = Field(default=None, max_length=200) webui_package: str | None = Field(default=None, max_length=200)
webui_ref: str | None = Field(default=None, max_length=1000) webui_ref: str | None = Field(default=None, max_length=1000)
data_safety_acknowledged: bool = False
destroy_data: bool = False destroy_data: bool = False
status: Literal["planned", "applied", "blocked"] = "planned" status: Literal["planned", "applied", "blocked"] = "planned"
notes: str | None = Field(default=None, max_length=1000) notes: str | None = Field(default=None, max_length=1000)
@@ -201,6 +151,63 @@ class ModuleInstallChecklistItem(BaseModel):
detail: str | None = None detail: str | None = None
class ModuleInstallTargetItem(BaseModel):
module_id: str
action: Literal["install", "update", "uninstall"]
source: Literal["manual", "catalog"]
current_version: str | None = None
target_version: str | None = None
python_package: str | None = None
python_ref: str | None = None
webui_package: str | None = None
webui_ref: str | None = None
migration_safety: Literal["automatic", "requires_review", "forward_only", "destructive"] = "automatic"
migration_notes: str | None = None
current_version_min: str | None = None
current_version_max_exclusive: str | None = None
bridge_release: bool = False
bridge_notes: str | None = None
allow_downgrade: bool = False
allow_same_version: bool = False
recovery_tested: bool = False
recovery_notes: str | None = None
data_safety_acknowledged: bool = False
class ModuleMigrationPlanStep(BaseModel):
module_id: str
action: Literal["install", "update", "uninstall"]
phase: Literal["upgrade", "retirement"]
source: Literal["manifest", "catalog", "pending"]
has_migration_metadata: bool = False
metadata_pending: bool = False
migration_safety: Literal["automatic", "requires_review", "forward_only", "destructive"] = "automatic"
current_version: str | None = None
target_version: str | None = None
reason: str | None = None
class ModuleMigrationTaskPlanItem(BaseModel):
module_id: str
task_id: str
phase: Literal["pre_migration_check", "pre_migration_prepare", "post_migration_backfill", "post_migration_verify"]
summary: str
task_version: str = "1"
safety: Literal["automatic", "requires_review", "forward_only", "destructive"] = "automatic"
idempotent: bool = True
timeout_seconds: int | None = None
source: Literal["manifest", "catalog", "pending"] = "manifest"
has_executor: bool = False
metadata_pending: bool = False
class ModuleMigrationExecutionPlan(BaseModel):
enabled_modules: list[str] = Field(default_factory=list)
requires_database_migration: bool = False
steps: list[ModuleMigrationPlanStep] = Field(default_factory=list)
tasks: list[ModuleMigrationTaskPlanItem] = Field(default_factory=list)
class ModuleInstallPreflightResponse(BaseModel): class ModuleInstallPreflightResponse(BaseModel):
allowed: bool allowed: bool
maintenance_mode: bool maintenance_mode: bool
@@ -210,6 +217,8 @@ class ModuleInstallPreflightResponse(BaseModel):
rollback_commands: list[str] = Field(default_factory=list) rollback_commands: list[str] = Field(default_factory=list)
issues: list[ModuleInstallPreflightIssue] = Field(default_factory=list) issues: list[ModuleInstallPreflightIssue] = Field(default_factory=list)
checklist: list[ModuleInstallChecklistItem] = Field(default_factory=list) checklist: list[ModuleInstallChecklistItem] = Field(default_factory=list)
target_plan: list[ModuleInstallTargetItem] = Field(default_factory=list)
migration_plan: ModuleMigrationExecutionPlan = Field(default_factory=ModuleMigrationExecutionPlan)
class ModuleInstallPlanResponse(BaseModel): class ModuleInstallPlanResponse(BaseModel):
@@ -328,6 +337,20 @@ class ModulePackageCatalogItem(BaseModel):
description: str | None = None description: str | None = None
version: str | None = None version: str | None = None
action: Literal["install", "update", "uninstall"] = "install" action: Literal["install", "update", "uninstall"] = "install"
dependencies: list[str] = Field(default_factory=list)
optional_dependencies: list[str] = Field(default_factory=list)
migration_safety: Literal["automatic", "requires_review", "forward_only", "destructive"] = "automatic"
migration_notes: str | None = None
migration_after: list[str] = Field(default_factory=list)
migration_before: list[str] = Field(default_factory=list)
current_version_min: str | None = None
current_version_max_exclusive: str | None = None
bridge_release: bool = False
bridge_notes: str | None = None
allow_downgrade: bool = False
allow_same_version: bool = False
recovery_tested: bool = False
recovery_notes: str | None = None
python_package: str | None = None python_package: str | None = None
python_ref: str | None = None python_ref: str | None = None
webui_package: str | None = None webui_package: str | None = None

View File

@@ -17,7 +17,7 @@ def _route_factory(context: ModuleContext):
manifest = ModuleManifest( manifest = ModuleManifest(
id="admin", id="admin",
name="Admin", name="Admin",
version="0.1.6", version="0.1.8",
required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR), required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR),
route_factory=_route_factory, route_factory=_route_factory,
migration_spec=MigrationSpec(module_id="admin", metadata=Base.metadata), migration_spec=MigrationSpec(module_id="admin", metadata=Base.metadata),

View File

@@ -1,6 +1,6 @@
{ {
"name": "@govoplan/admin-webui", "name": "@govoplan/admin-webui",
"version": "0.1.6", "version": "0.1.8",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
@@ -13,7 +13,7 @@
} }
}, },
"peerDependencies": { "peerDependencies": {
"@govoplan/core-webui": "^0.1.6", "@govoplan/core-webui": "^0.1.8",
"lucide-react": "^1.23.0", "lucide-react": "^1.23.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",

View File

@@ -1,74 +1,16 @@
import type { ApiSettings, DeltaDeletedItem } from "@govoplan/core-webui"; import type { ApiSettings, DeltaDeletedItem, PrivacyRetentionPolicy } from "@govoplan/core-webui";
import { apiFetch } from "@govoplan/core-webui"; import { apiFetch, apiGetList, apiPath, apiQuery } from "@govoplan/core-webui";
export { fetchAdminOverview, fetchPermissionCatalog, fetchTenants } from "@govoplan/core-webui";
export type PermissionItem = { export type {
scope: string; AdminOverview,
label: string; PrivacyRetentionLimitPermissionPatch,
description: string; PrivacyRetentionLimitPermissions,
category: string; PrivacyRetentionPolicy,
level: "tenant" | "system"; PrivacyRetentionPolicyFieldKey,
system_template_id?: string | null; PrivacyRetentionPolicyPatch,
system_required?: boolean; PermissionItem,
}; TenantAdminItem
} from "@govoplan/core-webui";
export type AdminOverview = {
active_tenant_id: string;
active_tenant_name: string;
tenant_count?: number | null;
system_account_count?: number | null;
system_group_template_count?: number | null;
system_role_template_count?: number | null;
user_count: number;
active_user_count: number;
group_count: number;
role_count: number;
active_api_key_count: number;
capabilities: string[];
};
export type TenantAdminItem = {
id: string;
slug: string;
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;
effective_governance: Record<string, boolean>;
is_active: boolean;
counts: Record<string, number>;
created_at: string;
updated_at: string;
};
export type PrivacyRetentionPolicyFieldKey =
| "store_raw_campaign_json"
| "raw_campaign_json_retention_days"
| "generated_eml_retention_days"
| "stored_report_detail_retention_days"
| "mock_mailbox_retention_days"
| "audit_detail_retention_days"
| "audit_detail_level";
export type PrivacyRetentionLimitPermissions = Record<PrivacyRetentionPolicyFieldKey, boolean>;
export type PrivacyRetentionLimitPermissionPatch = Partial<PrivacyRetentionLimitPermissions>;
export type PrivacyRetentionPolicy = {
store_raw_campaign_json: boolean;
raw_campaign_json_retention_days?: number | null;
generated_eml_retention_days?: number | null;
stored_report_detail_retention_days?: number | null;
mock_mailbox_retention_days?: number | null;
audit_detail_retention_days?: number | null;
audit_detail_level: "full" | "redacted" | "minimal";
allow_lower_level_limits: PrivacyRetentionLimitPermissions;
};
export type PrivacyRetentionPolicyPatch = Partial<Omit<PrivacyRetentionPolicy, "allow_lower_level_limits">> & {
allow_lower_level_limits?: PrivacyRetentionLimitPermissionPatch;
};
export type MaintenanceMode = { export type MaintenanceMode = {
enabled: boolean; enabled: boolean;
@@ -192,10 +134,7 @@ type DeltaResponseFields = {
}; };
function deltaSuffix(options: { since?: string | null; limit?: number } = {}): string { function deltaSuffix(options: { since?: string | null; limit?: number } = {}): string {
const params = new URLSearchParams(); return apiQuery(options);
if (options.since) params.set("since", options.since);
if (options.limit) params.set("limit", String(options.limit));
return params.toString() ? `?${params.toString()}` : "";
} }
export type SystemSettingsDeltaResponse = { export type SystemSettingsDeltaResponse = {
@@ -249,13 +188,14 @@ export type ModuleCatalogResponse = {
export type ModuleInstallPlanItem = { export type ModuleInstallPlanItem = {
module_id: string; module_id: string;
action: "install" | "uninstall"; action: "install" | "update" | "uninstall";
source: "manual" | "catalog"; source: "manual" | "catalog";
catalog?: Record<string, unknown> | null; catalog?: Record<string, unknown> | null;
python_package?: string | null; python_package?: string | null;
python_ref?: string | null; python_ref?: string | null;
webui_package?: string | null; webui_package?: string | null;
webui_ref?: string | null; webui_ref?: string | null;
data_safety_acknowledged: boolean;
destroy_data: boolean; destroy_data: boolean;
status: "planned" | "applied" | "blocked"; status: "planned" | "applied" | "blocked";
notes?: string | null; notes?: string | null;
@@ -275,6 +215,63 @@ export type ModuleInstallChecklistItem = {
detail?: string | null; detail?: string | null;
}; };
export type ModuleInstallTargetItem = {
module_id: string;
action: "install" | "update" | "uninstall";
source: "manual" | "catalog";
current_version?: string | null;
target_version?: string | null;
python_package?: string | null;
python_ref?: string | null;
webui_package?: string | null;
webui_ref?: string | null;
migration_safety: "automatic" | "requires_review" | "forward_only" | "destructive";
migration_notes?: string | null;
current_version_min?: string | null;
current_version_max_exclusive?: string | null;
bridge_release: boolean;
bridge_notes?: string | null;
allow_downgrade: boolean;
allow_same_version: boolean;
recovery_tested: boolean;
recovery_notes?: string | null;
data_safety_acknowledged: boolean;
};
export type ModuleMigrationPlanStep = {
module_id: string;
action: "install" | "update" | "uninstall";
phase: "upgrade" | "retirement";
source: "manifest" | "catalog" | "pending";
has_migration_metadata: boolean;
metadata_pending: boolean;
migration_safety: "automatic" | "requires_review" | "forward_only" | "destructive";
current_version?: string | null;
target_version?: string | null;
reason?: string | null;
};
export type ModuleMigrationTaskPlanItem = {
module_id: string;
task_id: string;
phase: "pre_migration_check" | "pre_migration_prepare" | "post_migration_backfill" | "post_migration_verify";
summary: string;
task_version: string;
safety: "automatic" | "requires_review" | "forward_only" | "destructive";
idempotent: boolean;
timeout_seconds?: number | null;
source: "manifest" | "catalog" | "pending";
has_executor: boolean;
metadata_pending: boolean;
};
export type ModuleMigrationExecutionPlan = {
enabled_modules: string[];
requires_database_migration: boolean;
steps: ModuleMigrationPlanStep[];
tasks: ModuleMigrationTaskPlanItem[];
};
export type ModuleInstallPreflight = { export type ModuleInstallPreflight = {
allowed: boolean; allowed: boolean;
maintenance_mode: boolean; maintenance_mode: boolean;
@@ -284,6 +281,8 @@ export type ModuleInstallPreflight = {
rollback_commands: string[]; rollback_commands: string[];
issues: ModuleInstallPreflightIssue[]; issues: ModuleInstallPreflightIssue[];
checklist: ModuleInstallChecklistItem[]; checklist: ModuleInstallChecklistItem[];
target_plan: ModuleInstallTargetItem[];
migration_plan: ModuleMigrationExecutionPlan;
}; };
export type ModuleInstallPlanResponse = { export type ModuleInstallPlanResponse = {
@@ -389,7 +388,21 @@ export type ModulePackageCatalogItem = {
name: string; name: string;
description?: string | null; description?: string | null;
version?: string | null; version?: string | null;
action: "install" | "uninstall"; action: "install" | "update" | "uninstall";
dependencies: string[];
optional_dependencies: string[];
migration_safety: "automatic" | "requires_review" | "forward_only" | "destructive";
migration_notes?: string | null;
migration_after: string[];
migration_before: string[];
current_version_min?: string | null;
current_version_max_exclusive?: string | null;
bridge_release: boolean;
bridge_notes?: string | null;
allow_downgrade: boolean;
allow_same_version: boolean;
recovery_tested: boolean;
recovery_notes?: string | null;
python_package?: string | null; python_package?: string | null;
python_ref?: string | null; python_ref?: string | null;
webui_package?: string | null; webui_package?: string | null;
@@ -467,20 +480,6 @@ export type GovernanceTemplateItem = {
updated_at: string; updated_at: string;
}; };
export function fetchAdminOverview(settings: ApiSettings): Promise<AdminOverview> {
return apiFetch(settings, "/api/v1/admin/overview");
}
export async function fetchPermissionCatalog(settings: ApiSettings): Promise<PermissionItem[]> {
const response = await apiFetch<{ permissions: PermissionItem[] }>(settings, "/api/v1/admin/permissions");
return response.permissions;
}
export async function fetchTenants(settings: ApiSettings): Promise<TenantAdminItem[]> {
const response = await apiFetch<{ tenants: TenantAdminItem[] }>(settings, "/api/v1/admin/tenants");
return response.tenants;
}
export function fetchSystemSettings(settings: ApiSettings): Promise<SystemSettingsItem> { export function fetchSystemSettings(settings: ApiSettings): Promise<SystemSettingsItem> {
return apiFetch(settings, "/api/v1/admin/system/settings"); return apiFetch(settings, "/api/v1/admin/system/settings");
} }
@@ -510,19 +509,11 @@ export function fetchModuleInstallPlan(settings: ApiSettings): Promise<ModuleIns
} }
export function fetchModuleInstallerRuns(settings: ApiSettings, options: { page_size?: number; cursor?: string | null } = {}): Promise<ModuleInstallerRunListResponse> { export function fetchModuleInstallerRuns(settings: ApiSettings, options: { page_size?: number; cursor?: string | null } = {}): Promise<ModuleInstallerRunListResponse> {
const params = new URLSearchParams(); return apiFetch(settings, apiPath("/api/v1/admin/system/modules/install-runs", options));
if (options.page_size) params.set("page_size", String(options.page_size));
if (options.cursor) params.set("cursor", options.cursor);
const suffix = params.toString() ? `?${params.toString()}` : "";
return apiFetch(settings, `/api/v1/admin/system/modules/install-runs${suffix}`);
} }
export function fetchModuleInstallerRequests(settings: ApiSettings, options: { page_size?: number; cursor?: string | null } = {}): Promise<ModuleInstallerRequestListResponse> { export function fetchModuleInstallerRequests(settings: ApiSettings, options: { page_size?: number; cursor?: string | null } = {}): Promise<ModuleInstallerRequestListResponse> {
const params = new URLSearchParams(); return apiFetch(settings, apiPath("/api/v1/admin/system/modules/install-requests", options));
if (options.page_size) params.set("page_size", String(options.page_size));
if (options.cursor) params.set("cursor", options.cursor);
const suffix = params.toString() ? `?${params.toString()}` : "";
return apiFetch(settings, `/api/v1/admin/system/modules/install-requests${suffix}`);
} }
export function createModuleInstallerRequest(settings: ApiSettings, options: ModuleInstallerRequestOptions): Promise<ModuleInstallerRequestItem> { export function createModuleInstallerRequest(settings: ApiSettings, options: ModuleInstallerRequestOptions): Promise<ModuleInstallerRequestItem> {
@@ -564,9 +555,7 @@ export function clearModuleInstallPlan(settings: ApiSettings): Promise<ModuleIns
} }
export async function fetchGovernanceTemplates(settings: ApiSettings, kind?: "group" | "role"): Promise<GovernanceTemplateItem[]> { export async function fetchGovernanceTemplates(settings: ApiSettings, kind?: "group" | "role"): Promise<GovernanceTemplateItem[]> {
const suffix = kind ? `?kind=${encodeURIComponent(kind)}` : ""; return apiGetList<GovernanceTemplateItem, "templates">(settings, "/api/v1/admin/system/governance-templates", "templates", { kind });
const response = await apiFetch<{ templates: GovernanceTemplateItem[] }>(settings, `/api/v1/admin/system/governance-templates${suffix}`);
return response.templates;
} }
export function createGovernanceTemplate(settings: ApiSettings, payload: Omit<GovernanceTemplateItem, "id" | "created_at" | "updated_at" | "effective_permission_count"> & { change_request_id?: string | null }): Promise<GovernanceTemplateItem> { export function createGovernanceTemplate(settings: ApiSettings, payload: Omit<GovernanceTemplateItem, "id" | "created_at" | "updated_at" | "effective_permission_count"> & { change_request_id?: string | null }): Promise<GovernanceTemplateItem> {
@@ -578,8 +567,7 @@ export function updateGovernanceTemplate(settings: ApiSettings, templateId: stri
} }
export function deleteGovernanceTemplate(settings: ApiSettings, templateId: string, changeRequestId?: string | null): Promise<void> { export function deleteGovernanceTemplate(settings: ApiSettings, templateId: string, changeRequestId?: string | null): Promise<void> {
const suffix = changeRequestId ? `?change_request_id=${encodeURIComponent(changeRequestId)}` : ""; return apiFetch(settings, apiPath(`/api/v1/admin/system/governance-templates/${templateId}`, { change_request_id: changeRequestId }), { method: "DELETE" });
return apiFetch(settings, `/api/v1/admin/system/governance-templates/${templateId}${suffix}`, { method: "DELETE" });
} }
export function fetchConfigurationChanges(settings: ApiSettings): Promise<{ requests: ConfigurationChangeRequest[]; history: ConfigurationChangeRecord[] }> { export function fetchConfigurationChanges(settings: ApiSettings): Promise<{ requests: ConfigurationChangeRequest[]; history: ConfigurationChangeRecord[] }> {

View File

@@ -43,7 +43,7 @@ export default function AdminOverviewPanel({ settings, onSelect, availableSectio
{hasAnySection(availableSections, platformSectionIds) && <Card title="ADMINISTRATION"> {hasAnySection(availableSections, platformSectionIds) && <Card title="ADMINISTRATION">
<div className="admin-overview-grid"> <div className="admin-overview-grid">
{availableSections.has("system-modules") && <AreaLink title="i18n:govoplan-admin.modules.04e9462c" text="i18n:govoplan-admin.installed_modules_runtime_state_and_startup_stat.38dd7028" onClick={() => onSelect("system-modules")} />} {availableSections.has("system-modules") && <AreaLink title="i18n:govoplan-admin.modules.04e9462c" text="i18n:govoplan-admin.installed_modules_runtime_state_and_startup_stat.38dd7028" onClick={() => onSelect("system-modules")} />}
{availableSections.has("system-configuration-packages") && <AreaLink title="i18n:govoplan-admin.packages.0a999012" text="i18n:govoplan-admin.preflight_approve_apply_and_export_configuration.276bd0f8" onClick={() => onSelect("system-configuration-packages")} />} {availableSections.has("system-configuration-packages") && <AreaLink title="i18n:govoplan-admin.configuration_packages.eb2f05f1" text="i18n:govoplan-admin.preflight_approve_apply_and_export_configuration.276bd0f8" onClick={() => onSelect("system-configuration-packages")} />}
{availableSections.has("system-settings") && <AreaLink title="i18n:govoplan-admin.maintenance.94de303b" text="i18n:govoplan-admin.instance_defaults_and_tenant_governance_capabili.99d6b2fa" onClick={() => onSelect("system-settings")} />} {availableSections.has("system-settings") && <AreaLink title="i18n:govoplan-admin.maintenance.94de303b" text="i18n:govoplan-admin.instance_defaults_and_tenant_governance_capabili.99d6b2fa" onClick={() => onSelect("system-settings")} />}
{availableSections.has("system-configuration-changes") && <AreaLink title="i18n:govoplan-admin.changes.8aa57de6" text="i18n:govoplan-admin.configuration_requests_approvals_and_version_his.19f37335" onClick={() => onSelect("system-configuration-changes")} />} {availableSections.has("system-configuration-changes") && <AreaLink title="i18n:govoplan-admin.changes.8aa57de6" text="i18n:govoplan-admin.configuration_requests_approvals_and_version_his.19f37335" onClick={() => onSelect("system-configuration-changes")} />}
{availableSections.has("system-audit") && <AreaLink title="i18n:govoplan-admin.audit.fa1703dd" text="i18n:govoplan-admin.system_level_administrative_history.49f76723" onClick={() => onSelect("system-audit")} />} {availableSections.has("system-audit") && <AreaLink title="i18n:govoplan-admin.audit.fa1703dd" text="i18n:govoplan-admin.system_level_administrative_history.49f76723" onClick={() => onSelect("system-audit")} />}

View File

@@ -19,7 +19,7 @@ import {
type PermissionItem, type PermissionItem,
type TenantAdminItem } from type TenantAdminItem } from
"../../api/admin"; "../../api/admin";
import { AdminIconButton, AdminPageLayout, AdminSelectionList, adminErrorMessage, joinLabels, i18nMessage, useUnsavedDraftGuard } from "@govoplan/core-webui"; import { AdminIconButton, AdminPageLayout, AdminSelectionList, adminErrorMessage, i18nMessage, useUnsavedDraftGuard } from "@govoplan/core-webui";
const emptyDraft = { const emptyDraft = {
slug: "", slug: "",
@@ -54,6 +54,7 @@ export default function GovernanceTemplatesPanel({
const [error, setError] = useState(""); const [error, setError] = useState("");
const [success, setSuccess] = useState(""); const [success, setSuccess] = useState("");
const dirty = editing !== null && draftKey(draft) !== savedDraftKey; const dirty = editing !== null && draftKey(draft) !== savedDraftKey;
const permissionsByScope = useMemo(() => new Map(permissions.map((permission) => [permission.scope, permission])), [permissions]);
useUnsavedDraftGuard({ useUnsavedDraftGuard({
dirty, dirty,
@@ -238,7 +239,7 @@ export default function GovernanceTemplatesPanel({
</Dialog> </Dialog>
<Dialog open={Boolean(viewing)} title={viewing?.name || "i18n:govoplan-admin.template_details.d5d75e4d"} onClose={() => setViewing(null)} className="admin-dialog admin-dialog-wide" footer={<Button onClick={() => setViewing(null)}>i18n:govoplan-admin.close.bbfa773e</Button>}> <Dialog open={Boolean(viewing)} title={viewing?.name || "i18n:govoplan-admin.template_details.d5d75e4d"} onClose={() => setViewing(null)} className="admin-dialog admin-dialog-wide" footer={<Button onClick={() => setViewing(null)}>i18n:govoplan-admin.close.bbfa773e</Button>}>
{viewing && <dl className="admin-details-grid"><div><dt>i18n:govoplan-admin.kind.e00ac23f</dt><dd>{viewing.kind}</dd></div><div><dt>i18n:govoplan-admin.slug.094da9b9</dt><dd>{viewing.slug}</dd></div><div><dt>i18n:govoplan-admin.status.bae7d5be</dt><dd>{viewing.is_active ? "i18n:govoplan-admin.active.a733b809" : "i18n:govoplan-admin.inactive.09af574c"}</dd></div><div><dt>i18n:govoplan-admin.tenants.1f7ae776</dt><dd>{viewing.assignments.length || "i18n:govoplan-admin.none.6eef6648"}</dd></div><div><dt>i18n:govoplan-admin.description.55f8ebc8</dt><dd>{viewing.description || "—"}</dd></div><div><dt>i18n:govoplan-admin.permissions.d06d5557</dt><dd>{viewing.permissions.length ? joinLabels(viewing.permissions.map((name) => ({ name }))) : "—"}</dd></div></dl>} {viewing && <dl className="admin-details-grid"><div><dt>i18n:govoplan-admin.kind.e00ac23f</dt><dd>{viewing.kind}</dd></div><div><dt>i18n:govoplan-admin.slug.094da9b9</dt><dd>{viewing.slug}</dd></div><div><dt>i18n:govoplan-admin.status.bae7d5be</dt><dd>{viewing.is_active ? "i18n:govoplan-admin.active.a733b809" : "i18n:govoplan-admin.inactive.09af574c"}</dd></div><div><dt>i18n:govoplan-admin.tenants.1f7ae776</dt><dd>{viewing.assignments.length || "i18n:govoplan-admin.none.6eef6648"}</dd></div><div><dt>i18n:govoplan-admin.description.55f8ebc8</dt><dd>{viewing.description || "—"}</dd></div><div><dt>i18n:govoplan-admin.permissions.d06d5557</dt><dd>{viewing.permissions.length ? <PermissionDetails scopes={viewing.permissions} permissionsByScope={permissionsByScope} /> : "—"}</dd></div></dl>}
</Dialog> </Dialog>
<ConfirmDialog open={Boolean(deleting)} title={kind === "group" ? "i18n:govoplan-admin.delete_group_template.8745d842" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} message={i18nMessage("i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d", { value0: deleting?.name })} confirmLabel={kind === "group" ? "i18n:govoplan-admin.delete_template.399bf72a" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} tone="danger" busy={busy} onCancel={() => setDeleting(null)} onConfirm={() => void remove()} /> <ConfirmDialog open={Boolean(deleting)} title={kind === "group" ? "i18n:govoplan-admin.delete_group_template.8745d842" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} message={i18nMessage("i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d", { value0: deleting?.name })} confirmLabel={kind === "group" ? "i18n:govoplan-admin.delete_template.399bf72a" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} tone="danger" busy={busy} onCancel={() => setDeleting(null)} onConfirm={() => void remove()} />
@@ -249,3 +250,31 @@ export default function GovernanceTemplatesPanel({
function draftKey(draft: typeof emptyDraft): string { function draftKey(draft: typeof emptyDraft): string {
return JSON.stringify(draft); return JSON.stringify(draft);
} }
function PermissionDetails({ scopes, permissionsByScope }: {scopes: string[];permissionsByScope: ReadonlyMap<string, PermissionItem>;}) {
const groups = groupPermissionScopes(scopes, permissionsByScope);
return (
<div className="admin-permission-details">
{groups.map((group) => <section key={group.module}>
<strong>{group.module}</strong>
<ul>
{group.permissions.map((permission) => <li key={permission.scope}>
<span>{permission.label}</span>
<code>{permission.scope}</code>
</li>)}
</ul>
</section>)}
</div>);
}
function groupPermissionScopes(scopes: string[], permissionsByScope: ReadonlyMap<string, PermissionItem>) {
const groups = new Map<string, {scope: string;label: string}[]>();
for (const scope of [...scopes].sort()) {
const moduleId = scope.split(":", 1)[0] || "other";
const permission = permissionsByScope.get(scope);
const group = groups.get(moduleId) ?? [];
group.push({ scope, label: permission?.label || scope });
groups.set(moduleId, group);
}
return [...groups.entries()].map(([module, permissions]) => ({ module, permissions }));
}

View File

@@ -26,6 +26,9 @@ import {
type ModuleInstallerRunListResponse, type ModuleInstallerRunListResponse,
type ModuleInstallPlanItem, type ModuleInstallPlanItem,
type ModuleInstallPlanResponse, type ModuleInstallPlanResponse,
type ModuleInstallTargetItem,
type ModuleMigrationPlanStep,
type ModuleMigrationTaskPlanItem,
type ModuleLicenseDiagnostics, type ModuleLicenseDiagnostics,
type ModulePackageCatalogResponse, type ModulePackageCatalogResponse,
type ModulePackageCatalogItem } from type ModulePackageCatalogItem } from
@@ -414,15 +417,25 @@ export default function ModuleManagementPanel({ settings, canWrite, canAccessMai
{item.python_package && <span>{item.python_package}</span>} {item.python_package && <span>{item.python_package}</span>}
{item.webui_package && <span>{item.webui_package}</span>} {item.webui_package && <span>{item.webui_package}</span>}
{item.tags.length > 0 && <span>{item.tags.join(", ")}</span>} {item.tags.length > 0 && <span>{item.tags.join(", ")}</span>}
{item.dependencies.length > 0 && <span>i18n:govoplan-admin.dependencies.9f4f78d1 {item.dependencies.join(", ")}</span>}
{item.migration_safety !== "automatic" && <span>i18n:govoplan-admin.migration_safety.729bdb3c {migrationSafetyLabel(item.migration_safety)}</span>}
{item.migration_after.length > 0 && <span>i18n:govoplan-admin.after.695c89be {item.migration_after.join(", ")}</span>}
{item.migration_before.length > 0 && <span>i18n:govoplan-admin.before.a11cf31f {item.migration_before.join(", ")}</span>}
{item.bridge_release && <span>i18n:govoplan-admin.bridge_release.176cf241</span>}
{(item.current_version_min || item.current_version_max_exclusive) && <span>i18n:govoplan-admin.current_window.73e25c9f {currentWindowLabel(item)}</span>}
{item.recovery_tested && <span>i18n:govoplan-admin.recovery_tested.e831e2f1</span>}
{item.license_features.length > 0 && <span>i18n:govoplan-admin.license.de13bf1a {item.license_features.join(", ")}</span>} {item.license_features.length > 0 && <span>i18n:govoplan-admin.license.de13bf1a {item.license_features.join(", ")}</span>}
{item.license_missing_features.length > 0 && <span>i18n:govoplan-admin.missing.feb2bbaa {item.license_missing_features.join(", ")}</span>} {item.license_missing_features.length > 0 && <span>i18n:govoplan-admin.missing.feb2bbaa {item.license_missing_features.join(", ")}</span>}
{item.provides_interfaces.length > 0 && <span>i18n:govoplan-admin.provides.221b70d9 {providedInterfacesLabel(item)}</span>} {item.provides_interfaces.length > 0 && <span>i18n:govoplan-admin.provides.221b70d9 {providedInterfacesLabel(item)}</span>}
{item.requires_interfaces.length > 0 && <span>i18n:govoplan-admin.requires.a4fc9357 {requiredInterfacesLabel(item)}</span>} {item.requires_interfaces.length > 0 && <span>i18n:govoplan-admin.requires.a4fc9357 {requiredInterfacesLabel(item)}</span>}
</div> </div>
{item.description && <p className="module-package-catalog-description">{item.description}</p>} {item.description && <p className="module-package-catalog-description">{item.description}</p>}
{item.migration_notes && <p className="module-package-catalog-description">{item.migration_notes}</p>}
{item.bridge_notes && <p className="module-package-catalog-description">{item.bridge_notes}</p>}
{item.recovery_notes && <p className="module-package-catalog-description">{item.recovery_notes}</p>}
{item.license_reason && <p className={`module-package-catalog-description${item.license_allowed ? "" : " alert warning"}`}>{item.license_reason}</p>} {item.license_reason && <p className={`module-package-catalog-description${item.license_allowed ? "" : " alert warning"}`}>{item.license_reason}</p>}
</div> </div>
<Button onClick={() => void addCatalogItem(item)} disabled={!canWrite || planBusy || !packageCatalog.valid || !item.license_allowed || item.action !== "install"}>i18n:govoplan-admin.plan_install.e82bffe6</Button> <Button onClick={() => void addCatalogItem(item)} disabled={!canWrite || planBusy || !packageCatalog.valid || !item.license_allowed || !["install", "update"].includes(item.action)}>{catalogPlanButtonLabel(item, catalog)}</Button>
</div> </div>
)} )}
</div>} </div>}
@@ -450,6 +463,43 @@ export default function ModuleManagementPanel({ settings, canWrite, canAccessMai
<span>{installPlan.preflight.restart_required ? "i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63" : "i18n:govoplan-admin.no_package_restart_pending.efe6b8ce"}</span> <span>{installPlan.preflight.restart_required ? "i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63" : "i18n:govoplan-admin.no_package_restart_pending.efe6b8ce"}</span>
{installPlan.preflight.frontend_rebuild_required && <span>i18n:govoplan-admin.webui_rebuild_required.010ce49f</span>} {installPlan.preflight.frontend_rebuild_required && <span>i18n:govoplan-admin.webui_rebuild_required.010ce49f</span>}
</div> </div>
{installPlan.preflight.target_plan.length > 0 && <div className="module-install-checklist">
<strong>i18n:govoplan-admin.target_plan.524ea0c8</strong>
{installPlan.preflight.target_plan.map((target) =>
<div key={`${target.module_id}-${target.action}`} className={`module-install-checklist-item status-${targetStatus(target)}`}>
<strong>{target.module_id} - {target.action}</strong>
<span>{targetVersionLabel(target)}</span>
<p>{migrationSafetyLabel(target.migration_safety)}{target.data_safety_acknowledged ? " - i18n:govoplan-admin.acknowledged.d08d7c6d" : ""}</p>
{target.bridge_release && <p>i18n:govoplan-admin.bridge_release.176cf241</p>}
{target.recovery_tested && <p>i18n:govoplan-admin.recovery_tested.e831e2f1</p>}
{target.python_ref && <p>{target.python_ref}</p>}
{target.migration_notes && <p>{target.migration_notes}</p>}
{target.bridge_notes && <p>{target.bridge_notes}</p>}
{target.recovery_notes && <p>{target.recovery_notes}</p>}
</div>
)}
</div>}
{(installPlan.preflight.migration_plan.steps.length > 0 || installPlan.preflight.migration_plan.tasks.length > 0) && <div className="module-install-checklist">
<strong>i18n:govoplan-admin.migration_plan.f42b9d90</strong>
<span>i18n:govoplan-admin.enabled_modules.3c38e9ff {installPlan.preflight.migration_plan.enabled_modules.join(", ")}</span>
{installPlan.preflight.migration_plan.steps.map((step, index) =>
<div key={`${step.module_id}-${step.phase}-${index}`} className={`module-install-checklist-item status-${migrationStepStatus(step)}`}>
<strong>{index + 1}. {step.module_id} - {migrationPhaseLabel(step.phase)}</strong>
<span>{migrationSourceLabel(step.source)}{step.metadata_pending ? " - i18n:govoplan-admin.metadata_pending.25190d87" : ""}</span>
<p>{migrationSafetyLabel(step.migration_safety)}</p>
{step.reason && <p>{step.reason}</p>}
</div>
)}
{installPlan.preflight.migration_plan.tasks.length > 0 && <strong>i18n:govoplan-admin.migration_tasks.a4410d3a</strong>}
{installPlan.preflight.migration_plan.tasks.map((task) =>
<div key={`${task.module_id}-${task.task_id}-${task.phase}`} className={`module-install-checklist-item status-${migrationTaskStatus(task)}`}>
<strong>{task.module_id} - {migrationTaskPhaseLabel(task.phase)}</strong>
<span>{task.summary}</span>
<p>{migrationSourceLabel(task.source)}{task.metadata_pending ? " - i18n:govoplan-admin.executor_pending.7633225b" : ""}{task.has_executor ? " - i18n:govoplan-admin.executor_available.507de429" : ""}</p>
<p>{migrationSafetyLabel(task.safety)} - {task.idempotent ? "i18n:govoplan-admin.idempotent.47a0f2d6" : "i18n:govoplan-admin.not_idempotent.d3014c71"} - i18n:govoplan-admin.task_version.f0f26b92 {task.task_version}</p>
</div>
)}
</div>}
{installPlan.preflight.issues.length > 0 && <div className="module-install-preflight-issues"> {installPlan.preflight.issues.length > 0 && <div className="module-install-preflight-issues">
{installPlan.preflight.issues.map((issue, index) => {installPlan.preflight.issues.map((issue, index) =>
<div key={`${issue.code}-${issue.module_id ?? "global"}-${index}`} className={`module-install-preflight-issue severity-${issue.severity}`}> <div key={`${issue.code}-${issue.module_id ?? "global"}-${index}`} className={`module-install-preflight-issue severity-${issue.severity}`}>
@@ -479,10 +529,11 @@ export default function ModuleManagementPanel({ settings, canWrite, canAccessMai
{item.catalog?.sequence !== null && item.catalog?.sequence !== undefined && <StatusBadge status="inactive" label={i18nMessage("i18n:govoplan-admin.seq_value.0ae5fa47", { value0: item.catalog.sequence })} />} {item.catalog?.sequence !== null && item.catalog?.sequence !== undefined && <StatusBadge status="inactive" label={i18nMessage("i18n:govoplan-admin.seq_value.0ae5fa47", { value0: item.catalog.sequence })} />}
{item.catalog?.key_id && <StatusBadge status="inactive" label={i18nMessage("i18n:govoplan-admin.key_value.847b914f", { value0: String(item.catalog.key_id) })} />} {item.catalog?.key_id && <StatusBadge status="inactive" label={i18nMessage("i18n:govoplan-admin.key_value.847b914f", { value0: String(item.catalog.key_id) })} />}
</div> </div>
<label><span>i18n:govoplan-admin.action.97c89a4d</span><select value={item.action} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { action: event.target.value as ModuleInstallPlanItem["action"] })}><option value="install">i18n:govoplan-admin.install.fd6c3ebf</option><option value="uninstall">i18n:govoplan-admin.uninstall.a735da1d</option></select></label> <label><span>i18n:govoplan-admin.action.97c89a4d</span><select value={item.action} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { action: event.target.value as ModuleInstallPlanItem["action"] })}><option value="install">i18n:govoplan-admin.install.fd6c3ebf</option><option value="update">i18n:govoplan-admin.update.503a059f</option><option value="uninstall">i18n:govoplan-admin.uninstall.a735da1d</option></select></label>
<label><span>i18n:govoplan-admin.module.b8ff0289</span><input value={item.module_id} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { module_id: event.target.value })} placeholder="files" /></label> <label><span>i18n:govoplan-admin.module.b8ff0289</span><input value={item.module_id} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { module_id: event.target.value })} placeholder="files" /></label>
<label><span>i18n:govoplan-admin.python_package.34591c71</span><input value={item.python_package ?? ""} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { python_package: event.target.value })} placeholder="govoplan-files" /></label> <label><span>i18n:govoplan-admin.python_package.34591c71</span><input value={item.python_package ?? ""} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { python_package: event.target.value })} placeholder="govoplan-files" /></label>
<ToggleSwitch label="i18n:govoplan-admin.destroy_data.34557c3c" checked={Boolean(item.destroy_data)} onChange={(checked) => updatePlanItem(index, { destroy_data: checked })} disabled={!canWrite || planBusy || item.action !== "uninstall"} /> <ToggleSwitch label="i18n:govoplan-admin.destroy_data.34557c3c" checked={Boolean(item.destroy_data)} onChange={(checked) => updatePlanItem(index, { destroy_data: checked })} disabled={!canWrite || planBusy || item.action !== "uninstall"} />
<ToggleSwitch label="i18n:govoplan-admin.data_safety_reviewed.b4774edc" checked={Boolean(item.data_safety_acknowledged)} onChange={(checked) => updatePlanItem(index, { data_safety_acknowledged: checked })} disabled={!canWrite || planBusy || item.action === "uninstall"} />
<label className="wide"><span>i18n:govoplan-admin.python_ref.1af35d0d</span><input value={item.python_ref ?? ""} disabled={!canWrite || planBusy || item.action === "uninstall"} onChange={(event) => updatePlanItem(index, { python_ref: event.target.value })} placeholder="govoplan-files @ git+ssh://...@v0.1.4" /></label> <label className="wide"><span>i18n:govoplan-admin.python_ref.1af35d0d</span><input value={item.python_ref ?? ""} disabled={!canWrite || planBusy || item.action === "uninstall"} onChange={(event) => updatePlanItem(index, { python_ref: event.target.value })} placeholder="govoplan-files @ git+ssh://...@v0.1.4" /></label>
<label><span>i18n:govoplan-admin.webui_package.19645536</span><input value={item.webui_package ?? ""} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { webui_package: event.target.value })} placeholder="@govoplan/files-webui" /></label> <label><span>i18n:govoplan-admin.webui_package.19645536</span><input value={item.webui_package ?? ""} disabled={!canWrite || planBusy} onChange={(event) => updatePlanItem(index, { webui_package: event.target.value })} placeholder="@govoplan/files-webui" /></label>
<label className="wide"><span>i18n:govoplan-admin.webui_ref.cbae3559</span><input value={item.webui_ref ?? ""} disabled={!canWrite || planBusy || item.action === "uninstall"} onChange={(event) => updatePlanItem(index, { webui_ref: event.target.value })} placeholder="git+ssh://...#v0.1.4" /></label> <label className="wide"><span>i18n:govoplan-admin.webui_ref.cbae3559</span><input value={item.webui_ref ?? ""} disabled={!canWrite || planBusy || item.action === "uninstall"} onChange={(event) => updatePlanItem(index, { webui_ref: event.target.value })} placeholder="git+ssh://...#v0.1.4" /></label>
@@ -644,6 +695,65 @@ function requiredInterfacesLabel(item: ModulePackageCatalogItem): string {
}).join(", "); }).join(", ");
} }
function migrationSafetyLabel(value: ModulePackageCatalogItem["migration_safety"] | ModuleInstallTargetItem["migration_safety"]): string {
if (value === "requires_review") return "i18n:govoplan-admin.requires_review.8ba0b8c6";
if (value === "forward_only") return "i18n:govoplan-admin.forward_only.6c107a46";
if (value === "destructive") return "i18n:govoplan-admin.destructive.0051026c";
return "i18n:govoplan-admin.automatic.d9a7260f";
}
function targetStatus(target: ModuleInstallTargetItem): "done" | "warning" | "blocked" {
if (target.migration_safety === "destructive" && !target.data_safety_acknowledged) return "blocked";
if (target.migration_safety === "forward_only" && !target.data_safety_acknowledged) return "blocked";
if (target.migration_safety !== "automatic") return "warning";
return "done";
}
function targetVersionLabel(target: ModuleInstallTargetItem): string {
const current = target.current_version ?? "none";
const next = target.action === "uninstall" ? "removed" : target.target_version ?? "unknown";
return `${current} -> ${next}`;
}
function migrationPhaseLabel(value: ModuleMigrationPlanStep["phase"]): string {
if (value === "retirement") return "i18n:govoplan-admin.retirement.6b680dd2";
return "i18n:govoplan-admin.upgrade.12c5007d";
}
function migrationTaskPhaseLabel(value: ModuleMigrationTaskPlanItem["phase"]): string {
if (value === "pre_migration_check") return "i18n:govoplan-admin.pre_migration_check.f654164a";
if (value === "pre_migration_prepare") return "i18n:govoplan-admin.pre_migration_prepare.d18fdd26";
if (value === "post_migration_backfill") return "i18n:govoplan-admin.post_migration_backfill.21043d74";
return "i18n:govoplan-admin.post_migration_verify.6af9f28b";
}
function migrationSourceLabel(value: ModuleMigrationPlanStep["source"] | ModuleMigrationTaskPlanItem["source"]): string {
if (value === "catalog") return "i18n:govoplan-admin.catalog_metadata.9b96c41a";
if (value === "pending") return "i18n:govoplan-admin.pending_metadata.a24cfeb0";
return "i18n:govoplan-admin.manifest_metadata.b9ae362a";
}
function migrationStepStatus(step: ModuleMigrationPlanStep): "done" | "pending" | "warning" | "blocked" {
if (step.metadata_pending) return "warning";
if (step.migration_safety !== "automatic") return "warning";
return "pending";
}
function migrationTaskStatus(task: ModuleMigrationTaskPlanItem): "done" | "pending" | "warning" | "blocked" {
if (!task.idempotent) return "blocked";
if (!task.metadata_pending && !task.has_executor) return "blocked";
if (task.safety === "forward_only" || task.safety === "destructive") return "warning";
if (task.metadata_pending || task.safety === "requires_review") return "warning";
return "pending";
}
function currentWindowLabel(item: Pick<ModulePackageCatalogItem, "current_version_min" | "current_version_max_exclusive">): string {
return [
item.current_version_min ? `>=${item.current_version_min}` : "",
item.current_version_max_exclusive ? `<${item.current_version_max_exclusive}` : "",
].filter(Boolean).join(" ") || "any";
}
function ModuleStatus({ module, desiredEnabled }: {module: ModuleCatalogItem;desiredEnabled: boolean;}) { function ModuleStatus({ module, desiredEnabled }: {module: ModuleCatalogItem;desiredEnabled: boolean;}) {
if (module.current_enabled && !desiredEnabled) return <StatusBadge status="warning" label="i18n:govoplan-admin.will_disable.14bb193a" />; if (module.current_enabled && !desiredEnabled) return <StatusBadge status="warning" label="i18n:govoplan-admin.will_disable.14bb193a" />;
if (!module.current_enabled && desiredEnabled) return <StatusBadge status="warning" label="i18n:govoplan-admin.will_enable.5d52d70b" />; if (!module.current_enabled && desiredEnabled) return <StatusBadge status="warning" label="i18n:govoplan-admin.will_enable.5d52d70b" />;
@@ -651,6 +761,12 @@ function ModuleStatus({ module, desiredEnabled }: {module: ModuleCatalogItem;des
return <StatusBadge status="inactive" label="i18n:govoplan-admin.inactive.09af574c" />; return <StatusBadge status="inactive" label="i18n:govoplan-admin.inactive.09af574c" />;
} }
function catalogPlanButtonLabel(item: ModulePackageCatalogItem, catalog: ModuleCatalogResponse | null): string {
if (item.action === "update") return "i18n:govoplan-admin.plan_update.86e6857a";
const installed = catalog?.modules.some((module) => module.id === item.module_id && module.installed) ?? false;
return installed ? "i18n:govoplan-admin.plan_update.86e6857a" : "i18n:govoplan-admin.plan_install.e82bffe6";
}
function sameSet(left: ReadonlySet<string>, right: ReadonlySet<string>) { function sameSet(left: ReadonlySet<string>, right: ReadonlySet<string>) {
if (left.size !== right.size) return false; if (left.size !== right.size) return false;
for (const item of left) { for (const item of left) {
@@ -669,6 +785,7 @@ function emptyPlanItem(): ModuleInstallPlanItem {
python_ref: "", python_ref: "",
webui_package: "", webui_package: "",
webui_ref: "", webui_ref: "",
data_safety_acknowledged: false,
destroy_data: false, destroy_data: false,
status: "planned", status: "planned",
notes: "" notes: ""
@@ -683,9 +800,10 @@ function normalizePlanItems(items: ModuleInstallPlanItem[]): ModuleInstallPlanIt
source: item.source === "catalog" ? "catalog" : "manual", source: item.source === "catalog" ? "catalog" : "manual",
catalog: item.source === "catalog" ? item.catalog ?? null : null, catalog: item.source === "catalog" ? item.catalog ?? null : null,
python_package: cleanOptional(item.python_package), python_package: cleanOptional(item.python_package),
python_ref: item.action === "install" ? cleanOptional(item.python_ref) : null, python_ref: item.action !== "uninstall" ? cleanOptional(item.python_ref) : null,
webui_package: cleanOptional(item.webui_package), webui_package: cleanOptional(item.webui_package),
webui_ref: item.action === "install" ? cleanOptional(item.webui_ref) : null, webui_ref: item.action !== "uninstall" ? cleanOptional(item.webui_ref) : null,
data_safety_acknowledged: item.action !== "uninstall" && Boolean(item.data_safety_acknowledged),
destroy_data: item.action === "uninstall" && Boolean(item.destroy_data), destroy_data: item.action === "uninstall" && Boolean(item.destroy_data),
status: item.status, status: item.status,
notes: cleanOptional(item.notes) notes: cleanOptional(item.notes)
@@ -701,10 +819,10 @@ function cleanOptional(value?: string | null): string | null {
function planValidationError(items: ModuleInstallPlanItem[]): string { function planValidationError(items: ModuleInstallPlanItem[]): string {
for (const item of normalizePlanItems(items)) { for (const item of normalizePlanItems(items)) {
if (!item.module_id) return "i18n:govoplan-admin.every_plan_item_needs_a_module_id.23a7f206"; if (!item.module_id) return "i18n:govoplan-admin.every_plan_item_needs_a_module_id.23a7f206";
if (item.action === "install" && !item.python_ref) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_reference.950b898e", { value0: item.module_id }); if (item.action !== "uninstall" && !item.python_ref) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_reference.950b898e", { value0: item.module_id });
if (item.action === "install" && item.python_ref && !item.python_package) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_name_for_rollback.6c89ed75", { value0: item.module_id }); if (item.action !== "uninstall" && item.python_ref && !item.python_package) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_name_for_rollback.6c89ed75", { value0: item.module_id });
if (item.action === "uninstall" && !item.python_package) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_name_for_uninstall.004ba6fa", { value0: item.module_id }); if (item.action === "uninstall" && !item.python_package) return i18nMessage("i18n:govoplan-admin.value_needs_a_python_package_name_for_uninstall.004ba6fa", { value0: item.module_id });
if (item.action === "install" && Boolean(item.webui_package) !== Boolean(item.webui_ref)) return i18nMessage("i18n:govoplan-admin.value_needs_both_webui_package_and_webui_referen.d2bab073", { value0: item.module_id }); if (item.action !== "uninstall" && Boolean(item.webui_package) !== Boolean(item.webui_ref)) return i18nMessage("i18n:govoplan-admin.value_needs_both_webui_package_and_webui_referen.d2bab073", { value0: item.module_id });
if (item.action === "uninstall" && item.webui_ref && !item.webui_package) return i18nMessage("i18n:govoplan-admin.value_has_a_webui_reference_but_no_webui_package.18f44149", { value0: item.module_id }); if (item.action === "uninstall" && item.webui_ref && !item.webui_package) return i18nMessage("i18n:govoplan-admin.value_has_a_webui_reference_but_no_webui_package.18f44149", { value0: item.module_id });
} }
return ""; return "";

View File

@@ -6,13 +6,15 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.action.97c89a4d": "Action", "i18n:govoplan-admin.action.97c89a4d": "Action",
"i18n:govoplan-admin.actions.c3cd636a": "Actions", "i18n:govoplan-admin.actions.c3cd636a": "Actions",
"i18n:govoplan-admin.activate_installs.731d22a1": "Activate installs", "i18n:govoplan-admin.activate_installs.731d22a1": "Activate installs",
"i18n:govoplan-admin.acknowledged.d08d7c6d": "Acknowledged",
"i18n:govoplan-admin.active_and_total_memberships.c0c20f10": "Active and total memberships.", "i18n:govoplan-admin.active_and_total_memberships.c0c20f10": "Active and total memberships.",
"i18n:govoplan-admin.active_tenant_automation_credentials.240c659e": "Active tenant automation credentials.", "i18n:govoplan-admin.active_tenant_automation_credentials.240c659e": "Active tenant automation credentials.",
"i18n:govoplan-admin.active_tenant.dfadf0aa": "Active tenant:", "i18n:govoplan-admin.active_tenant.dfadf0aa": "Active tenant:",
"i18n:govoplan-admin.active.a733b809": "Active", "i18n:govoplan-admin.active.a733b809": "Active",
"i18n:govoplan-admin.after.695c89be": "After:",
"i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template", "i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template",
"i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item", "i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add tenant role", "i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add role template",
"i18n:govoplan-admin.admin.4e7afebc": "Admin", "i18n:govoplan-admin.admin.4e7afebc": "Admin",
"i18n:govoplan-admin.administration.b8be3d12": "Administration", "i18n:govoplan-admin.administration.b8be3d12": "Administration",
"i18n:govoplan-admin.platform_administration": "Platform administration", "i18n:govoplan-admin.platform_administration": "Platform administration",
@@ -34,9 +36,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.audit.fa1703dd": "Audit", "i18n:govoplan-admin.audit.fa1703dd": "Audit",
"i18n:govoplan-admin.available.7c62a142": "Available", "i18n:govoplan-admin.available.7c62a142": "Available",
"i18n:govoplan-admin.blocked.99613c74": "Blocked", "i18n:govoplan-admin.blocked.99613c74": "Blocked",
"i18n:govoplan-admin.before.a11cf31f": "Before:",
"i18n:govoplan-admin.bridge_release.176cf241": "Bridge release",
"i18n:govoplan-admin.build_webui.ed5ef1fd": " --build-webui", "i18n:govoplan-admin.build_webui.ed5ef1fd": " --build-webui",
"i18n:govoplan-admin.build_webui.fe8ccad7": "Build WebUI", "i18n:govoplan-admin.build_webui.fe8ccad7": "Build WebUI",
"i18n:govoplan-admin.bypass_allowed.4e347c27": "Bypass allowed", "i18n:govoplan-admin.bypass_allowed.4e347c27": "Bypass allowed",
"i18n:govoplan-admin.catalog_metadata.9b96c41a": "Catalog metadata",
"i18n:govoplan-admin.bypass_denied.ab987400": "Bypass denied", "i18n:govoplan-admin.bypass_denied.ab987400": "Bypass denied",
"i18n:govoplan-admin.cached_from.d73c5b2a": "· cached from", "i18n:govoplan-admin.cached_from.d73c5b2a": "· cached from",
"i18n:govoplan-admin.cancel.77dfd213": "Cancel", "i18n:govoplan-admin.cancel.77dfd213": "Cancel",
@@ -70,10 +75,13 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.create_group_template.72407248": "Create group template", "i18n:govoplan-admin.create_group_template.72407248": "Create group template",
"i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply", "i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply",
"i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.", "i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Create tenant role", "i18n:govoplan-admin.create_tenant_role.f58db104": "Create role template",
"i18n:govoplan-admin.created.0c78dab1": "Created:", "i18n:govoplan-admin.created.0c78dab1": "Created:",
"i18n:govoplan-admin.created.accf40c8": "Created", "i18n:govoplan-admin.created.accf40c8": "Created",
"i18n:govoplan-admin.current_window.73e25c9f": "Current window:",
"i18n:govoplan-admin.automatic.d9a7260f": "Automatic",
"i18n:govoplan-admin.daemon_execution.cc0fad8d": "Daemon execution", "i18n:govoplan-admin.daemon_execution.cc0fad8d": "Daemon execution",
"i18n:govoplan-admin.data_safety_reviewed.b4774edc": "Data safety reviewed",
"i18n:govoplan-admin.daemon_offline.314f19a4": "Daemon offline", "i18n:govoplan-admin.daemon_offline.314f19a4": "Daemon offline",
"i18n:govoplan-admin.daemon_value.e54f5a31": "Daemon: {value0}", "i18n:govoplan-admin.daemon_value.e54f5a31": "Daemon: {value0}",
"i18n:govoplan-admin.db_backup_command.5bded3ac": "DB backup command", "i18n:govoplan-admin.db_backup_command.5bded3ac": "DB backup command",
@@ -92,11 +100,13 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Defaults for newly created tenants", "i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Defaults for newly created tenants",
"i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template", "i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template",
"i18n:govoplan-admin.delete_template.399bf72a": "Delete template", "i18n:govoplan-admin.delete_template.399bf72a": "Delete template",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete tenant role", "i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete role template",
"i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.", "i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.",
"i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}", "i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}",
"i18n:govoplan-admin.dependencies.9f4f78d1": "Dependencies:",
"i18n:govoplan-admin.dependents.072665c4": "Dependents:", "i18n:govoplan-admin.dependents.072665c4": "Dependents:",
"i18n:govoplan-admin.description.55f8ebc8": "Description", "i18n:govoplan-admin.description.55f8ebc8": "Description",
"i18n:govoplan-admin.destructive.0051026c": "Destructive",
"i18n:govoplan-admin.destroy_data.34557c3c": "Destroy data", "i18n:govoplan-admin.destroy_data.34557c3c": "Destroy data",
"i18n:govoplan-admin.disabled.f4f4473d": "Disabled", "i18n:govoplan-admin.disabled.f4f4473d": "Disabled",
"i18n:govoplan-admin.discovered_packages.660902de": "Discovered packages", "i18n:govoplan-admin.discovered_packages.660902de": "Discovered packages",
@@ -105,9 +115,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.", "i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.",
"i18n:govoplan-admin.dry_run.3d14659c": "Dry-run", "i18n:govoplan-admin.dry_run.3d14659c": "Dry-run",
"i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template", "i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit tenant role", "i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit role template",
"i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}", "i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}",
"i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode", "i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode",
"i18n:govoplan-admin.enabled_modules.3c38e9ff": "Enabled modules:",
"i18n:govoplan-admin.executor_available.507de429": "Executor available",
"i18n:govoplan-admin.executor_pending.7633225b": "Executor pending",
"i18n:govoplan-admin.enabled.df174a3f": "Enabled", "i18n:govoplan-admin.enabled.df174a3f": "Enabled",
"i18n:govoplan-admin.enabling_maintenance_mode_requires_system_mainte.062d3968": "Enabling maintenance mode requires system:maintenance:access.", "i18n:govoplan-admin.enabling_maintenance_mode_requires_system_mainte.062d3968": "Enabling maintenance mode requires system:maintenance:access.",
"i18n:govoplan-admin.enabling.2b8e03e6": "Enabling...", "i18n:govoplan-admin.enabling.2b8e03e6": "Enabling...",
@@ -121,6 +134,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.exported_tenant_access_configuration.9122c85c": "Exported tenant access configuration", "i18n:govoplan-admin.exported_tenant_access_configuration.9122c85c": "Exported tenant access configuration",
"i18n:govoplan-admin.features.5df81ffa": "Features:", "i18n:govoplan-admin.features.5df81ffa": "Features:",
"i18n:govoplan-admin.file_connections.1e362326": "File connections", "i18n:govoplan-admin.file_connections.1e362326": "File connections",
"i18n:govoplan-admin.forward_only.6c107a46": "Forward-only",
"i18n:govoplan-admin.finished.4b52fe3f": "Finished:", "i18n:govoplan-admin.finished.4b52fe3f": "Finished:",
"i18n:govoplan-admin.fragment.3f19d616": "Fragment", "i18n:govoplan-admin.fragment.3f19d616": "Fragment",
"i18n:govoplan-admin.front_office.d9dcfee1": "Front office", "i18n:govoplan-admin.front_office.d9dcfee1": "Front office",
@@ -142,6 +156,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.history.90ccd649": "History", "i18n:govoplan-admin.history.90ccd649": "History",
"i18n:govoplan-admin.id.474ae526": "Id", "i18n:govoplan-admin.id.474ae526": "Id",
"i18n:govoplan-admin.import_preflight_approve_apply_and_export_module.29aec929": "Import, preflight, approve, apply and export module-owned configuration packages.", "i18n:govoplan-admin.import_preflight_approve_apply_and_export_module.29aec929": "Import, preflight, approve, apply and export module-owned configuration packages.",
"i18n:govoplan-admin.idempotent.47a0f2d6": "Idempotent",
"i18n:govoplan-admin.inactive.09af574c": "Inactive", "i18n:govoplan-admin.inactive.09af574c": "Inactive",
"i18n:govoplan-admin.inspect_value.9d5d1071": "Inspect {value0}", "i18n:govoplan-admin.inspect_value.9d5d1071": "Inspect {value0}",
"i18n:govoplan-admin.install.fd6c3ebf": "Install", "i18n:govoplan-admin.install.fd6c3ebf": "Install",
@@ -169,6 +184,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.license.de13bf1a": "License:", "i18n:govoplan-admin.license.de13bf1a": "License:",
"i18n:govoplan-admin.locked.a798882f": "Locked", "i18n:govoplan-admin.locked.a798882f": "Locked",
"i18n:govoplan-admin.mail_servers.d627326a": "Mail servers", "i18n:govoplan-admin.mail_servers.d627326a": "Mail servers",
"i18n:govoplan-admin.manifest_metadata.b9ae362a": "Manifest metadata",
"i18n:govoplan-admin.maintenance_message.ca62571f": "Maintenance message", "i18n:govoplan-admin.maintenance_message.ca62571f": "Maintenance message",
"i18n:govoplan-admin.maintenance_mode_enabled_apply_the_module_state_.dda13e5c": "Maintenance mode enabled. Apply the module-state request when ready.", "i18n:govoplan-admin.maintenance_mode_enabled_apply_the_module_state_.dda13e5c": "Maintenance mode enabled. Apply the module-state request when ready.",
"i18n:govoplan-admin.maintenance_mode_is_off_package_changes_should_b.1d262629": "Maintenance mode is off. Package changes should be applied only after enabling maintenance mode.", "i18n:govoplan-admin.maintenance_mode_is_off_package_changes_should_b.1d262629": "Maintenance mode is off. Package changes should be applied only after enabling maintenance mode.",
@@ -177,6 +193,10 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.maintenance.94de303b": "Maintenance", "i18n:govoplan-admin.maintenance.94de303b": "Maintenance",
"i18n:govoplan-admin.membership_status_groups_and_direct_roles_in_the.ab6c10b6": "Membership status, groups and direct roles in the active tenant.", "i18n:govoplan-admin.membership_status_groups_and_direct_roles_in_the.ab6c10b6": "Membership status, groups and direct roles in the active tenant.",
"i18n:govoplan-admin.message.68f4145f": "Message", "i18n:govoplan-admin.message.68f4145f": "Message",
"i18n:govoplan-admin.metadata_pending.25190d87": "Metadata pending",
"i18n:govoplan-admin.migration_plan.f42b9d90": "Migration plan",
"i18n:govoplan-admin.migration_safety.729bdb3c": "Migration safety:",
"i18n:govoplan-admin.migration_tasks.a4410d3a": "Migration tasks",
"i18n:govoplan-admin.minimal_office_access.af48f49a": "Minimal office access", "i18n:govoplan-admin.minimal_office_access.af48f49a": "Minimal office access",
"i18n:govoplan-admin.missing_entitlement.0cafa611": "Missing entitlement", "i18n:govoplan-admin.missing_entitlement.0cafa611": "Missing entitlement",
"i18n:govoplan-admin.missing.feb2bbaa": "Missing:", "i18n:govoplan-admin.missing.feb2bbaa": "Missing:",
@@ -204,6 +224,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.none.6eef6648": "None", "i18n:govoplan-admin.none.6eef6648": "None",
"i18n:govoplan-admin.not_available.d1a17af1": "Not available", "i18n:govoplan-admin.not_available.d1a17af1": "Not available",
"i18n:govoplan-admin.not_configured.811931bb": "Not configured", "i18n:govoplan-admin.not_configured.811931bb": "Not configured",
"i18n:govoplan-admin.not_idempotent.d3014c71": "Not idempotent",
"i18n:govoplan-admin.not_recorded.9925ee3c": "not recorded", "i18n:govoplan-admin.not_recorded.9925ee3c": "not recorded",
"i18n:govoplan-admin.notes.70440046": "Notes", "i18n:govoplan-admin.notes.70440046": "Notes",
"i18n:govoplan-admin.object.2883f191": "Object", "i18n:govoplan-admin.object.2883f191": "Object",
@@ -223,8 +244,14 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.package.7431e3df": "Package", "i18n:govoplan-admin.package.7431e3df": "Package",
"i18n:govoplan-admin.packages.0a999012": "Packages", "i18n:govoplan-admin.packages.0a999012": "Packages",
"i18n:govoplan-admin.pending.c515ec74": " pending", "i18n:govoplan-admin.pending.c515ec74": " pending",
"i18n:govoplan-admin.pending_metadata.a24cfeb0": "Pending metadata",
"i18n:govoplan-admin.permissions.d06d5557": "Permissions", "i18n:govoplan-admin.permissions.d06d5557": "Permissions",
"i18n:govoplan-admin.plan_install.e82bffe6": "Plan install", "i18n:govoplan-admin.plan_install.e82bffe6": "Plan install",
"i18n:govoplan-admin.plan_update.86e6857a": "Plan update",
"i18n:govoplan-admin.post_migration_backfill.21043d74": "Post-migration backfill",
"i18n:govoplan-admin.post_migration_verify.6af9f28b": "Post-migration verify",
"i18n:govoplan-admin.pre_migration_check.f654164a": "Pre-migration check",
"i18n:govoplan-admin.pre_migration_prepare.d18fdd26": "Pre-migration prepare",
"i18n:govoplan-admin.plan_package_installs_and_removals_here_then_app.4aeb03bf": "Plan package installs and removals here, then apply the rendered commands from an operator shell during maintenance mode.", "i18n:govoplan-admin.plan_package_installs_and_removals_here_then_app.4aeb03bf": "Plan package installs and removals here, then apply the rendered commands from an operator shell during maintenance mode.",
"i18n:govoplan-admin.plan_uninstall.e62804ab": "Plan uninstall", "i18n:govoplan-admin.plan_uninstall.e62804ab": "Plan uninstall",
"i18n:govoplan-admin.plan.ae2f98a0": "Plan", "i18n:govoplan-admin.plan.ae2f98a0": "Plan",
@@ -241,6 +268,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.queued_daemon_handoffs_created_from_the_admin_ui.d7ae7914": "Queued daemon handoffs created from the admin UI or CLI.", "i18n:govoplan-admin.queued_daemon_handoffs_created_from_the_admin_ui.d7ae7914": "Queued daemon handoffs created from the admin UI or CLI.",
"i18n:govoplan-admin.queueing_installer_requests_requires_maintenance.ae81f9ac": "Queueing installer requests requires maintenance access.", "i18n:govoplan-admin.queueing_installer_requests_requires_maintenance.ae81f9ac": "Queueing installer requests requires maintenance access.",
"i18n:govoplan-admin.recent_supervised_installer_records_and_the_curr.29860245": "Recent supervised installer records and the current package-install lock.", "i18n:govoplan-admin.recent_supervised_installer_records_and_the_curr.29860245": "Recent supervised installer records and the current package-install lock.",
"i18n:govoplan-admin.recovery_tested.e831e2f1": "Recovery tested",
"i18n:govoplan-admin.registered_tenant_spaces.61e17d70": "Registered tenant spaces.", "i18n:govoplan-admin.registered_tenant_spaces.61e17d70": "Registered tenant spaces.",
"i18n:govoplan-admin.reload.cce71553": "Reload", "i18n:govoplan-admin.reload.cce71553": "Reload",
"i18n:govoplan-admin.remove.e963907d": "Remove", "i18n:govoplan-admin.remove.e963907d": "Remove",
@@ -253,10 +281,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.required.d5793988": "Required:", "i18n:govoplan-admin.required.d5793988": "Required:",
"i18n:govoplan-admin.required.eed6bfb4": "Required", "i18n:govoplan-admin.required.eed6bfb4": "Required",
"i18n:govoplan-admin.requires.a4fc9357": "Requires:", "i18n:govoplan-admin.requires.a4fc9357": "Requires:",
"i18n:govoplan-admin.requires_review.8ba0b8c6": "Review required",
"i18n:govoplan-admin.restart_commands.035997f9": "Restart commands", "i18n:govoplan-admin.restart_commands.035997f9": "Restart commands",
"i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63": "Restart/reload required after package changes", "i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63": "Restart/reload required after package changes",
"i18n:govoplan-admin.restrict_authenticated_api_access_to_maintenance.2bc47195": "Restrict authenticated API access to maintenance operators", "i18n:govoplan-admin.restrict_authenticated_api_access_to_maintenance.2bc47195": "Restrict authenticated API access to maintenance operators",
"i18n:govoplan-admin.retention.c7199d9e": "Retention", "i18n:govoplan-admin.retention.c7199d9e": "Retention",
"i18n:govoplan-admin.retirement.6b680dd2": "Retirement",
"i18n:govoplan-admin.retry_of.3a6bb304": "Retry of:", "i18n:govoplan-admin.retry_of.3a6bb304": "Retry of:",
"i18n:govoplan-admin.retry.9f5cd8a2": "Retry", "i18n:govoplan-admin.retry.9f5cd8a2": "Retry",
"i18n:govoplan-admin.reusable_encrypted_smtp_imap_profiles_and_mail_p.31f150d1": "Reusable encrypted SMTP/IMAP profiles and mail policy.", "i18n:govoplan-admin.reusable_encrypted_smtp_imap_profiles_and_mail_p.31f150d1": "Reusable encrypted SMTP/IMAP profiles and mail policy.",
@@ -272,7 +302,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.save_plan.842dc280": "Save plan", "i18n:govoplan-admin.save_plan.842dc280": "Save plan",
"i18n:govoplan-admin.save_settings.913aba9f": "Save settings", "i18n:govoplan-admin.save_settings.913aba9f": "Save settings",
"i18n:govoplan-admin.save_template.0885fab2": "Save template", "i18n:govoplan-admin.save_template.0885fab2": "Save template",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save tenant role", "i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save role template",
"i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Save the install plan before queueing a daemon request.", "i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Save the install plan before queueing a daemon request.",
"i18n:govoplan-admin.saved.c0ae8f6e": "Saved", "i18n:govoplan-admin.saved.c0ae8f6e": "Saved",
"i18n:govoplan-admin.saving.56a2285c": "Saving…", "i18n:govoplan-admin.saving.56a2285c": "Saving…",
@@ -302,6 +332,8 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.system_settings_saved.dac4f17b": "System settings saved.", "i18n:govoplan-admin.system_settings_saved.dac4f17b": "System settings saved.",
"i18n:govoplan-admin.system_wide_governance_and_tenant_local_access_m.cda72499": "System-wide governance and tenant-local access management, separated by scope and enforced by the backend.", "i18n:govoplan-admin.system_wide_governance_and_tenant_local_access_m.cda72499": "System-wide governance and tenant-local access management, separated by scope and enforced by the backend.",
"i18n:govoplan-admin.system.bc0792d8": "System", "i18n:govoplan-admin.system.bc0792d8": "System",
"i18n:govoplan-admin.target_plan.524ea0c8": "Target plan",
"i18n:govoplan-admin.task_version.f0f26b92": "Task version",
"i18n:govoplan-admin.target.61ad50a9": "Target", "i18n:govoplan-admin.target.61ad50a9": "Target",
"i18n:govoplan-admin.template_details.d5d75e4d": "Template details", "i18n:govoplan-admin.template_details.d5d75e4d": "Template details",
"i18n:govoplan-admin.tenant_administration_capabilities.5d265972": "Tenant administration capabilities", "i18n:govoplan-admin.tenant_administration_capabilities.5d265972": "Tenant administration capabilities",
@@ -315,9 +347,9 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.", "i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.",
"i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.", "i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.",
"i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.", "i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Tenant permissions", "i18n:govoplan-admin.tenant_permissions.246294bc": "Permissions",
"i18n:govoplan-admin.tenant_role.6b53115d": "Tenant role", "i18n:govoplan-admin.tenant_role.6b53115d": "Role template",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Tenant roles", "i18n:govoplan-admin.tenant_roles.51aca82d": "Role templates",
"i18n:govoplan-admin.tenant_users.cb800b38": "Tenant users", "i18n:govoplan-admin.tenant_users.cb800b38": "Tenant users",
"i18n:govoplan-admin.tenants.1f7ae776": "Tenants", "i18n:govoplan-admin.tenants.1f7ae776": "Tenants",
"i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "These settings are enforced by the backend. Central groups and tenant roles remain available even when local creation is disabled.", "i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "These settings are enforced by the backend. Central groups and tenant roles remain available even when local creation is disabled.",
@@ -328,6 +360,8 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.unlocked.b3da7025": "Unlocked", "i18n:govoplan-admin.unlocked.b3da7025": "Unlocked",
"i18n:govoplan-admin.unsigned.e91344ea": "Unsigned", "i18n:govoplan-admin.unsigned.e91344ea": "Unsigned",
"i18n:govoplan-admin.untrusted.cdc7838a": "Untrusted", "i18n:govoplan-admin.untrusted.cdc7838a": "Untrusted",
"i18n:govoplan-admin.upgrade.12c5007d": "Upgrade",
"i18n:govoplan-admin.update.503a059f": "Update",
"i18n:govoplan-admin.update_enabled_modules.9b7ae790": "Update enabled modules", "i18n:govoplan-admin.update_enabled_modules.9b7ae790": "Update enabled modules",
"i18n:govoplan-admin.updated.f2f8570d": "Updated", "i18n:govoplan-admin.updated.f2f8570d": "Updated",
"i18n:govoplan-admin.user_file_connector_policy_limits": "File connector policy limits for user-owned spaces.", "i18n:govoplan-admin.user_file_connector_policy_limits": "File connector policy limits for user-owned spaces.",
@@ -361,13 +395,15 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.action.97c89a4d": "Action", "i18n:govoplan-admin.action.97c89a4d": "Action",
"i18n:govoplan-admin.actions.c3cd636a": "Aktionen", "i18n:govoplan-admin.actions.c3cd636a": "Aktionen",
"i18n:govoplan-admin.activate_installs.731d22a1": "Installationen aktivieren", "i18n:govoplan-admin.activate_installs.731d22a1": "Installationen aktivieren",
"i18n:govoplan-admin.acknowledged.d08d7c6d": "Bestaetigt",
"i18n:govoplan-admin.active_and_total_memberships.c0c20f10": "Active and total memberships.", "i18n:govoplan-admin.active_and_total_memberships.c0c20f10": "Active and total memberships.",
"i18n:govoplan-admin.active_tenant_automation_credentials.240c659e": "Active tenant automation credentials.", "i18n:govoplan-admin.active_tenant_automation_credentials.240c659e": "Active tenant automation credentials.",
"i18n:govoplan-admin.active_tenant.dfadf0aa": "Active tenant:", "i18n:govoplan-admin.active_tenant.dfadf0aa": "Active tenant:",
"i18n:govoplan-admin.active.a733b809": "Aktiv", "i18n:govoplan-admin.active.a733b809": "Aktiv",
"i18n:govoplan-admin.after.695c89be": "Nach:",
"i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template", "i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template",
"i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item", "i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add tenant role", "i18n:govoplan-admin.add_tenant_role.fcd904ea": "Rollenvorlage hinzufügen",
"i18n:govoplan-admin.admin.4e7afebc": "Administration", "i18n:govoplan-admin.admin.4e7afebc": "Administration",
"i18n:govoplan-admin.administration.b8be3d12": "Administration", "i18n:govoplan-admin.administration.b8be3d12": "Administration",
"i18n:govoplan-admin.platform_administration": "Plattformadministration", "i18n:govoplan-admin.platform_administration": "Plattformadministration",
@@ -389,9 +425,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.audit.fa1703dd": "Audit", "i18n:govoplan-admin.audit.fa1703dd": "Audit",
"i18n:govoplan-admin.available.7c62a142": "Verfügbar", "i18n:govoplan-admin.available.7c62a142": "Verfügbar",
"i18n:govoplan-admin.blocked.99613c74": "Blockiert", "i18n:govoplan-admin.blocked.99613c74": "Blockiert",
"i18n:govoplan-admin.before.a11cf31f": "Vor:",
"i18n:govoplan-admin.bridge_release.176cf241": "Brueckenrelease",
"i18n:govoplan-admin.build_webui.ed5ef1fd": " --build-webui", "i18n:govoplan-admin.build_webui.ed5ef1fd": " --build-webui",
"i18n:govoplan-admin.build_webui.fe8ccad7": "WebUI bauen", "i18n:govoplan-admin.build_webui.fe8ccad7": "WebUI bauen",
"i18n:govoplan-admin.bypass_allowed.4e347c27": "Bypass allowed", "i18n:govoplan-admin.bypass_allowed.4e347c27": "Bypass allowed",
"i18n:govoplan-admin.catalog_metadata.9b96c41a": "Katalogmetadaten",
"i18n:govoplan-admin.bypass_denied.ab987400": "Bypass denied", "i18n:govoplan-admin.bypass_denied.ab987400": "Bypass denied",
"i18n:govoplan-admin.cached_from.d73c5b2a": "· cached from", "i18n:govoplan-admin.cached_from.d73c5b2a": "· cached from",
"i18n:govoplan-admin.cancel.77dfd213": "Abbrechen", "i18n:govoplan-admin.cancel.77dfd213": "Abbrechen",
@@ -425,10 +464,13 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.create_group_template.72407248": "Create group template", "i18n:govoplan-admin.create_group_template.72407248": "Create group template",
"i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply", "i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply",
"i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.", "i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Create tenant role", "i18n:govoplan-admin.create_tenant_role.f58db104": "Rollenvorlage erstellen",
"i18n:govoplan-admin.created.0c78dab1": "Created:", "i18n:govoplan-admin.created.0c78dab1": "Created:",
"i18n:govoplan-admin.created.accf40c8": "Erstellt", "i18n:govoplan-admin.created.accf40c8": "Erstellt",
"i18n:govoplan-admin.current_window.73e25c9f": "Aktuelles Fenster:",
"i18n:govoplan-admin.automatic.d9a7260f": "Automatisch",
"i18n:govoplan-admin.daemon_execution.cc0fad8d": "Daemon-Ausführung", "i18n:govoplan-admin.daemon_execution.cc0fad8d": "Daemon-Ausführung",
"i18n:govoplan-admin.data_safety_reviewed.b4774edc": "Datensicherheit geprueft",
"i18n:govoplan-admin.daemon_offline.314f19a4": "Daemon offline", "i18n:govoplan-admin.daemon_offline.314f19a4": "Daemon offline",
"i18n:govoplan-admin.daemon_value.e54f5a31": "Daemon: {value0}", "i18n:govoplan-admin.daemon_value.e54f5a31": "Daemon: {value0}",
"i18n:govoplan-admin.db_backup_command.5bded3ac": "DB-Backup-Befehl", "i18n:govoplan-admin.db_backup_command.5bded3ac": "DB-Backup-Befehl",
@@ -447,11 +489,13 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Standards für neu erstellte Mandanten", "i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Standards für neu erstellte Mandanten",
"i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template", "i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template",
"i18n:govoplan-admin.delete_template.399bf72a": "Delete template", "i18n:govoplan-admin.delete_template.399bf72a": "Delete template",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete tenant role", "i18n:govoplan-admin.delete_tenant_role.4efa0813": "Rollenvorlage löschen",
"i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.", "i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.",
"i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}", "i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}",
"i18n:govoplan-admin.dependencies.9f4f78d1": "Abhaengigkeiten:",
"i18n:govoplan-admin.dependents.072665c4": "Dependents:", "i18n:govoplan-admin.dependents.072665c4": "Dependents:",
"i18n:govoplan-admin.description.55f8ebc8": "Beschreibung", "i18n:govoplan-admin.description.55f8ebc8": "Beschreibung",
"i18n:govoplan-admin.destructive.0051026c": "Destruktiv",
"i18n:govoplan-admin.destroy_data.34557c3c": "Daten zerstören", "i18n:govoplan-admin.destroy_data.34557c3c": "Daten zerstören",
"i18n:govoplan-admin.disabled.f4f4473d": "Disabled", "i18n:govoplan-admin.disabled.f4f4473d": "Disabled",
"i18n:govoplan-admin.discovered_packages.660902de": "Discovered packages", "i18n:govoplan-admin.discovered_packages.660902de": "Discovered packages",
@@ -460,9 +504,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.", "i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.",
"i18n:govoplan-admin.dry_run.3d14659c": "Dry-run", "i18n:govoplan-admin.dry_run.3d14659c": "Dry-run",
"i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template", "i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit tenant role", "i18n:govoplan-admin.edit_tenant_role.c15a260d": "Rollenvorlage bearbeiten",
"i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}", "i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}",
"i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode", "i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode",
"i18n:govoplan-admin.enabled_modules.3c38e9ff": "Aktive Module:",
"i18n:govoplan-admin.executor_available.507de429": "Ausfuehrer verfuegbar",
"i18n:govoplan-admin.executor_pending.7633225b": "Ausfuehrer ausstehend",
"i18n:govoplan-admin.enabled.df174a3f": "Aktiviert", "i18n:govoplan-admin.enabled.df174a3f": "Aktiviert",
"i18n:govoplan-admin.enabling_maintenance_mode_requires_system_mainte.062d3968": "Enabling maintenance mode requires system:maintenance:access.", "i18n:govoplan-admin.enabling_maintenance_mode_requires_system_mainte.062d3968": "Enabling maintenance mode requires system:maintenance:access.",
"i18n:govoplan-admin.enabling.2b8e03e6": "Enabling...", "i18n:govoplan-admin.enabling.2b8e03e6": "Enabling...",
@@ -476,6 +523,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.exported_tenant_access_configuration.9122c85c": "Exported tenant access configuration", "i18n:govoplan-admin.exported_tenant_access_configuration.9122c85c": "Exported tenant access configuration",
"i18n:govoplan-admin.features.5df81ffa": "Features:", "i18n:govoplan-admin.features.5df81ffa": "Features:",
"i18n:govoplan-admin.file_connections.1e362326": "Dateiverbindungen", "i18n:govoplan-admin.file_connections.1e362326": "Dateiverbindungen",
"i18n:govoplan-admin.forward_only.6c107a46": "Nur vorwaerts",
"i18n:govoplan-admin.finished.4b52fe3f": "Finished:", "i18n:govoplan-admin.finished.4b52fe3f": "Finished:",
"i18n:govoplan-admin.fragment.3f19d616": "Fragment", "i18n:govoplan-admin.fragment.3f19d616": "Fragment",
"i18n:govoplan-admin.front_office.d9dcfee1": "Front office", "i18n:govoplan-admin.front_office.d9dcfee1": "Front office",
@@ -497,6 +545,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.history.90ccd649": "History", "i18n:govoplan-admin.history.90ccd649": "History",
"i18n:govoplan-admin.id.474ae526": "Id", "i18n:govoplan-admin.id.474ae526": "Id",
"i18n:govoplan-admin.import_preflight_approve_apply_and_export_module.29aec929": "Modul-eigene Konfigurationspakete importieren, prüfen, freigeben, anwenden und exportieren.", "i18n:govoplan-admin.import_preflight_approve_apply_and_export_module.29aec929": "Modul-eigene Konfigurationspakete importieren, prüfen, freigeben, anwenden und exportieren.",
"i18n:govoplan-admin.idempotent.47a0f2d6": "Idempotent",
"i18n:govoplan-admin.inactive.09af574c": "Inaktiv", "i18n:govoplan-admin.inactive.09af574c": "Inaktiv",
"i18n:govoplan-admin.inspect_value.9d5d1071": "Inspect {value0}", "i18n:govoplan-admin.inspect_value.9d5d1071": "Inspect {value0}",
"i18n:govoplan-admin.install.fd6c3ebf": "Installieren", "i18n:govoplan-admin.install.fd6c3ebf": "Installieren",
@@ -524,6 +573,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.license.de13bf1a": "License:", "i18n:govoplan-admin.license.de13bf1a": "License:",
"i18n:govoplan-admin.locked.a798882f": "Gesperrt", "i18n:govoplan-admin.locked.a798882f": "Gesperrt",
"i18n:govoplan-admin.mail_servers.d627326a": "Mail servers", "i18n:govoplan-admin.mail_servers.d627326a": "Mail servers",
"i18n:govoplan-admin.manifest_metadata.b9ae362a": "Manifestmetadaten",
"i18n:govoplan-admin.maintenance_message.ca62571f": "Wartungsmeldung", "i18n:govoplan-admin.maintenance_message.ca62571f": "Wartungsmeldung",
"i18n:govoplan-admin.maintenance_mode_enabled_apply_the_module_state_.dda13e5c": "Maintenance mode enabled. Apply the module-state request when ready.", "i18n:govoplan-admin.maintenance_mode_enabled_apply_the_module_state_.dda13e5c": "Maintenance mode enabled. Apply the module-state request when ready.",
"i18n:govoplan-admin.maintenance_mode_is_off_package_changes_should_b.1d262629": "Maintenance mode is off. Package changes should be applied only after enabling maintenance mode.", "i18n:govoplan-admin.maintenance_mode_is_off_package_changes_should_b.1d262629": "Maintenance mode is off. Package changes should be applied only after enabling maintenance mode.",
@@ -532,6 +582,10 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.maintenance.94de303b": "Wartung", "i18n:govoplan-admin.maintenance.94de303b": "Wartung",
"i18n:govoplan-admin.membership_status_groups_and_direct_roles_in_the.ab6c10b6": "Membership status, groups and direct roles in the active tenant.", "i18n:govoplan-admin.membership_status_groups_and_direct_roles_in_the.ab6c10b6": "Membership status, groups and direct roles in the active tenant.",
"i18n:govoplan-admin.message.68f4145f": "Nachricht", "i18n:govoplan-admin.message.68f4145f": "Nachricht",
"i18n:govoplan-admin.metadata_pending.25190d87": "Metadaten ausstehend",
"i18n:govoplan-admin.migration_plan.f42b9d90": "Migrationsplan",
"i18n:govoplan-admin.migration_safety.729bdb3c": "Migrationssicherheit:",
"i18n:govoplan-admin.migration_tasks.a4410d3a": "Migrationsaufgaben",
"i18n:govoplan-admin.minimal_office_access.af48f49a": "Minimal office access", "i18n:govoplan-admin.minimal_office_access.af48f49a": "Minimal office access",
"i18n:govoplan-admin.missing_entitlement.0cafa611": "Missing entitlement", "i18n:govoplan-admin.missing_entitlement.0cafa611": "Missing entitlement",
"i18n:govoplan-admin.missing.feb2bbaa": "Missing:", "i18n:govoplan-admin.missing.feb2bbaa": "Missing:",
@@ -559,6 +613,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.none.6eef6648": "Keine", "i18n:govoplan-admin.none.6eef6648": "Keine",
"i18n:govoplan-admin.not_available.d1a17af1": "Not available", "i18n:govoplan-admin.not_available.d1a17af1": "Not available",
"i18n:govoplan-admin.not_configured.811931bb": "Nicht konfiguriert", "i18n:govoplan-admin.not_configured.811931bb": "Nicht konfiguriert",
"i18n:govoplan-admin.not_idempotent.d3014c71": "Nicht idempotent",
"i18n:govoplan-admin.not_recorded.9925ee3c": "not recorded", "i18n:govoplan-admin.not_recorded.9925ee3c": "not recorded",
"i18n:govoplan-admin.notes.70440046": "Notes", "i18n:govoplan-admin.notes.70440046": "Notes",
"i18n:govoplan-admin.object.2883f191": "Object", "i18n:govoplan-admin.object.2883f191": "Object",
@@ -578,8 +633,14 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.package.7431e3df": "Package", "i18n:govoplan-admin.package.7431e3df": "Package",
"i18n:govoplan-admin.packages.0a999012": "Pakete", "i18n:govoplan-admin.packages.0a999012": "Pakete",
"i18n:govoplan-admin.pending.c515ec74": " pending", "i18n:govoplan-admin.pending.c515ec74": " pending",
"i18n:govoplan-admin.pending_metadata.a24cfeb0": "Ausstehende Metadaten",
"i18n:govoplan-admin.permissions.d06d5557": "Berechtigungen", "i18n:govoplan-admin.permissions.d06d5557": "Berechtigungen",
"i18n:govoplan-admin.plan_install.e82bffe6": "Plan install", "i18n:govoplan-admin.plan_install.e82bffe6": "Plan install",
"i18n:govoplan-admin.plan_update.86e6857a": "Aktualisierung planen",
"i18n:govoplan-admin.post_migration_backfill.21043d74": "Nach-Migration Backfill",
"i18n:govoplan-admin.post_migration_verify.6af9f28b": "Nach-Migration Pruefung",
"i18n:govoplan-admin.pre_migration_check.f654164a": "Vor-Migration Check",
"i18n:govoplan-admin.pre_migration_prepare.d18fdd26": "Vor-Migration Vorbereitung",
"i18n:govoplan-admin.plan_package_installs_and_removals_here_then_app.4aeb03bf": "Plan package installs and removals here, then apply the rendered commands from an operator shell during maintenance mode.", "i18n:govoplan-admin.plan_package_installs_and_removals_here_then_app.4aeb03bf": "Plan package installs and removals here, then apply the rendered commands from an operator shell during maintenance mode.",
"i18n:govoplan-admin.plan_uninstall.e62804ab": "Plan uninstall", "i18n:govoplan-admin.plan_uninstall.e62804ab": "Plan uninstall",
"i18n:govoplan-admin.plan.ae2f98a0": "Plan", "i18n:govoplan-admin.plan.ae2f98a0": "Plan",
@@ -596,6 +657,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.queued_daemon_handoffs_created_from_the_admin_ui.d7ae7914": "Queued daemon handoffs created from the admin UI or CLI.", "i18n:govoplan-admin.queued_daemon_handoffs_created_from_the_admin_ui.d7ae7914": "Queued daemon handoffs created from the admin UI or CLI.",
"i18n:govoplan-admin.queueing_installer_requests_requires_maintenance.ae81f9ac": "Das Einreihen von Installer-Anfragen erfordert Wartungszugriff.", "i18n:govoplan-admin.queueing_installer_requests_requires_maintenance.ae81f9ac": "Das Einreihen von Installer-Anfragen erfordert Wartungszugriff.",
"i18n:govoplan-admin.recent_supervised_installer_records_and_the_curr.29860245": "Aktuelle überwachte Installer-Datensätze und die aktuelle Paketinstallationssperre.", "i18n:govoplan-admin.recent_supervised_installer_records_and_the_curr.29860245": "Aktuelle überwachte Installer-Datensätze und die aktuelle Paketinstallationssperre.",
"i18n:govoplan-admin.recovery_tested.e831e2f1": "Recovery getestet",
"i18n:govoplan-admin.registered_tenant_spaces.61e17d70": "Registered tenant spaces.", "i18n:govoplan-admin.registered_tenant_spaces.61e17d70": "Registered tenant spaces.",
"i18n:govoplan-admin.reload.cce71553": "Neu laden", "i18n:govoplan-admin.reload.cce71553": "Neu laden",
"i18n:govoplan-admin.remove.e963907d": "Entfernen", "i18n:govoplan-admin.remove.e963907d": "Entfernen",
@@ -608,10 +670,12 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.required.d5793988": "Required:", "i18n:govoplan-admin.required.d5793988": "Required:",
"i18n:govoplan-admin.required.eed6bfb4": "Required", "i18n:govoplan-admin.required.eed6bfb4": "Required",
"i18n:govoplan-admin.requires.a4fc9357": "Requires:", "i18n:govoplan-admin.requires.a4fc9357": "Requires:",
"i18n:govoplan-admin.requires_review.8ba0b8c6": "Pruefung erforderlich",
"i18n:govoplan-admin.restart_commands.035997f9": "Neustartbefehle", "i18n:govoplan-admin.restart_commands.035997f9": "Neustartbefehle",
"i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63": "Restart/reload required after package changes", "i18n:govoplan-admin.restart_reload_required_after_package_changes.3a99cd63": "Restart/reload required after package changes",
"i18n:govoplan-admin.restrict_authenticated_api_access_to_maintenance.2bc47195": "Authentifizierten API-Zugriff auf Wartungsoperatoren beschränken", "i18n:govoplan-admin.restrict_authenticated_api_access_to_maintenance.2bc47195": "Authentifizierten API-Zugriff auf Wartungsoperatoren beschränken",
"i18n:govoplan-admin.retention.c7199d9e": "Retention", "i18n:govoplan-admin.retention.c7199d9e": "Retention",
"i18n:govoplan-admin.retirement.6b680dd2": "Stilllegung",
"i18n:govoplan-admin.retry_of.3a6bb304": "Retry of:", "i18n:govoplan-admin.retry_of.3a6bb304": "Retry of:",
"i18n:govoplan-admin.retry.9f5cd8a2": "Erneut versuchen", "i18n:govoplan-admin.retry.9f5cd8a2": "Erneut versuchen",
"i18n:govoplan-admin.reusable_encrypted_smtp_imap_profiles_and_mail_p.31f150d1": "Reusable encrypted SMTP/IMAP profiles and mail policy.", "i18n:govoplan-admin.reusable_encrypted_smtp_imap_profiles_and_mail_p.31f150d1": "Reusable encrypted SMTP/IMAP profiles and mail policy.",
@@ -627,7 +691,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.save_plan.842dc280": "Save plan", "i18n:govoplan-admin.save_plan.842dc280": "Save plan",
"i18n:govoplan-admin.save_settings.913aba9f": "Einstellungen speichern", "i18n:govoplan-admin.save_settings.913aba9f": "Einstellungen speichern",
"i18n:govoplan-admin.save_template.0885fab2": "Save template", "i18n:govoplan-admin.save_template.0885fab2": "Save template",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save tenant role", "i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Rollenvorlage speichern",
"i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Speichern Sie den Installationsplan, bevor eine Daemon-Anfrage eingereiht wird.", "i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Speichern Sie den Installationsplan, bevor eine Daemon-Anfrage eingereiht wird.",
"i18n:govoplan-admin.saved.c0ae8f6e": "Gespeichert", "i18n:govoplan-admin.saved.c0ae8f6e": "Gespeichert",
"i18n:govoplan-admin.saving.56a2285c": "Saving…", "i18n:govoplan-admin.saving.56a2285c": "Saving…",
@@ -657,6 +721,8 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.system_settings_saved.dac4f17b": "Systemeinstellungen gespeichert.", "i18n:govoplan-admin.system_settings_saved.dac4f17b": "Systemeinstellungen gespeichert.",
"i18n:govoplan-admin.system_wide_governance_and_tenant_local_access_m.cda72499": "System-wide governance and tenant-local access management, separated by scope and enforced by the backend.", "i18n:govoplan-admin.system_wide_governance_and_tenant_local_access_m.cda72499": "System-wide governance and tenant-local access management, separated by scope and enforced by the backend.",
"i18n:govoplan-admin.system.bc0792d8": "System", "i18n:govoplan-admin.system.bc0792d8": "System",
"i18n:govoplan-admin.target_plan.524ea0c8": "Zielplan",
"i18n:govoplan-admin.task_version.f0f26b92": "Aufgabenversion",
"i18n:govoplan-admin.target.61ad50a9": "Target", "i18n:govoplan-admin.target.61ad50a9": "Target",
"i18n:govoplan-admin.template_details.d5d75e4d": "Template details", "i18n:govoplan-admin.template_details.d5d75e4d": "Template details",
"i18n:govoplan-admin.tenant_administration_capabilities.5d265972": "Tenant administration capabilities", "i18n:govoplan-admin.tenant_administration_capabilities.5d265972": "Tenant administration capabilities",
@@ -670,9 +736,9 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.", "i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.",
"i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.", "i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.",
"i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.", "i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Tenant permissions", "i18n:govoplan-admin.tenant_permissions.246294bc": "Berechtigungen",
"i18n:govoplan-admin.tenant_role.6b53115d": "Tenant role", "i18n:govoplan-admin.tenant_role.6b53115d": "Rollenvorlage",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Mandantenrollen", "i18n:govoplan-admin.tenant_roles.51aca82d": "Rollenvorlagen",
"i18n:govoplan-admin.tenant_users.cb800b38": "Mandantenbenutzer", "i18n:govoplan-admin.tenant_users.cb800b38": "Mandantenbenutzer",
"i18n:govoplan-admin.tenants.1f7ae776": "Mandanten", "i18n:govoplan-admin.tenants.1f7ae776": "Mandanten",
"i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "Diese Einstellungen werden vom Backend erzwungen. Zentrale Gruppen und Mandantenrollen bleiben verfügbar, auch wenn lokale Erstellung deaktiviert ist.", "i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "Diese Einstellungen werden vom Backend erzwungen. Zentrale Gruppen und Mandantenrollen bleiben verfügbar, auch wenn lokale Erstellung deaktiviert ist.",
@@ -683,6 +749,8 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.unlocked.b3da7025": "Entsperrt", "i18n:govoplan-admin.unlocked.b3da7025": "Entsperrt",
"i18n:govoplan-admin.unsigned.e91344ea": "Unsigniert", "i18n:govoplan-admin.unsigned.e91344ea": "Unsigniert",
"i18n:govoplan-admin.untrusted.cdc7838a": "Nicht vertrauenswürdig", "i18n:govoplan-admin.untrusted.cdc7838a": "Nicht vertrauenswürdig",
"i18n:govoplan-admin.upgrade.12c5007d": "Upgrade",
"i18n:govoplan-admin.update.503a059f": "Aktualisieren",
"i18n:govoplan-admin.update_enabled_modules.9b7ae790": "Update enabled modules", "i18n:govoplan-admin.update_enabled_modules.9b7ae790": "Update enabled modules",
"i18n:govoplan-admin.updated.f2f8570d": "Aktualisiert", "i18n:govoplan-admin.updated.f2f8570d": "Aktualisiert",
"i18n:govoplan-admin.user_file_connector_policy_limits": "Dateiverbindungsrichtlinien fuer benutzereigene Bereiche.", "i18n:govoplan-admin.user_file_connector_policy_limits": "Dateiverbindungsrichtlinien fuer benutzereigene Bereiche.",

View File

@@ -54,7 +54,7 @@ const adminSections: AdminSectionsUiCapability = {
}, },
{ {
id: "system-configuration-packages", id: "system-configuration-packages",
label: "i18n:govoplan-admin.packages.0a999012", label: "i18n:govoplan-admin.configuration_packages.eb2f05f1",
group: "SYSTEM", group: "SYSTEM",
order: 30, order: 30,
allOf: ["system:settings:read"], allOf: ["system:settings:read"],