diff --git a/webui/src/features/admin/ApiKeysPanel.tsx b/webui/src/features/admin/ApiKeysPanel.tsx
index d30ae43..2b70490 100644
--- a/webui/src/features/admin/ApiKeysPanel.tsx
+++ b/webui/src/features/admin/ApiKeysPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Plus, Search, Trash2 } from "lucide-react";
-import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings, AuthInfo } from "@govoplan/core-webui";
import { createApiKey, fetchApiKeysDelta, fetchPermissionCatalog, fetchUsersDelta, revokeApiKey, type ApiKeyAdminItem, type PermissionItem, type UserAdminItem } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
@@ -156,16 +156,16 @@ export default function ApiKeysPanel({ settings, auth, canCreate, canRevoke }: {
row.id} emptyText="i18n:govoplan-access.no_api_keys_found.1f377128" />
-
- setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing && <>
- i18n:govoplan-access.name.709a2322
- {viewing.name}
- i18n:govoplan-access.prefix.90eceb01
- {viewing.prefix}…
- i18n:govoplan-access.owner.89ff3122
- {viewing.user_email}
- i18n:govoplan-access.status.bae7d5be
- {viewing.revoked_at ? "i18n:govoplan-access.revoked.85f17ac0" : "i18n:govoplan-access.active.a733b809"}
@@ -174,7 +174,7 @@ export default function ApiKeysPanel({ settings, auth, canCreate, canRevoke }: {
i18n:govoplan-access.scopes.c23540e5
{viewing.scopes.map((scope) => {scope})}
>}
- setSecret(null)} className="admin-dialog" footer={}>
+ setSecret(null)} className="" footer={}>
{secret && <>i18n:govoplan-access.the_secret_for.c60737ef {secret.name} i18n:govoplan-access.is_shown_once.af2b1235
{secret.value}i18n:govoplan-access.store_it_in_a_secret_manager_only_its_prefix_and.796ac588
>}
diff --git a/webui/src/features/admin/ExternalFunctionRoleMappingsPanel.tsx b/webui/src/features/admin/ExternalFunctionRoleMappingsPanel.tsx
index d2f3d5d..8f515d8 100644
--- a/webui/src/features/admin/ExternalFunctionRoleMappingsPanel.tsx
+++ b/webui/src/features/admin/ExternalFunctionRoleMappingsPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Pencil, Plus, Trash2 } from "lucide-react";
-import type { ApiSettings, AuthInfo, OrganizationFunctionPickerUiCapability, OrganizationFunctionSelection } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings, AuthInfo, OrganizationFunctionPickerUiCapability, OrganizationFunctionSelection } from "@govoplan/core-webui";
import {
createExternalFunctionRoleMapping,
deleteExternalFunctionRoleMapping,
@@ -295,11 +295,11 @@ export default function ExternalFunctionRoleMappingsPanel({
- !busy && closeEditor()}
- className="admin-dialog"
+ className=""
footer={
<>
@@ -309,7 +309,7 @@ export default function ExternalFunctionRoleMappingsPanel({
>
}
>
-
+
{functionPicker.renderPicker({
settings,
@@ -327,7 +327,7 @@ export default function ExternalFunctionRoleMappingsPanel({
))}
-
+
i18n:govoplan-access.function_role_mapping_help.0cf9996a
diff --git a/webui/src/features/admin/GroupsPanel.tsx b/webui/src/features/admin/GroupsPanel.tsx
index d9c3841..34169d3 100644
--- a/webui/src/features/admin/GroupsPanel.tsx
+++ b/webui/src/features/admin/GroupsPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Pencil, Plus, Search, Trash2 } from "lucide-react";
-import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings, AuthInfo } from "@govoplan/core-webui";
import { createGroup, fetchGroupsDelta, fetchRolesDelta, fetchUsersDelta, updateGroup, type GroupSummary, type RoleSummary, type UserAdminItem } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
@@ -149,14 +149,14 @@ export default function GroupsPanel({ settings, auth, canDefine, canManageMember
row.id} emptyText="i18n:govoplan-access.no_groups_found.627ca913" />
- !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<>>}>
+ !busy && setEditing(null)} className="" footer={<>>}>
{editing !== "new" && editing?.system_template_id && i18n:govoplan-access.this_group_definition_is_managed_by_the_system_n.640b235e
}
-
+
setDraft({ ...draft, name: event.target.value })} />
setDraft({ ...draft, slug: event.target.value })} />
-
+
i18n:govoplan-access.members.1cb449c1 ({ id: user.id, label: user.display_name || user.email, description: user.email, disabled: !canManageMembers || !user.is_active || !user.account_is_active }))} selected={draft.memberIds} onChange={(memberIds) => setDraft({ ...draft, memberIds })} emptyText="i18n:govoplan-access.no_tenant_users_exist.96b4a88a" />
i18n:govoplan-access.inherited_roles.8def9f05 ({ id: role.id, label: role.name, description: role.description, disabled: !canAssignRoles }))} selected={draft.roleIds} onChange={(roleIds) => setDraft({ ...draft, roleIds })} emptyText="i18n:govoplan-access.no_assignable_roles_exist.a4c268c2" />
@@ -164,7 +164,7 @@ export default function GroupsPanel({ settings, auth, canDefine, canManageMember
i18n:govoplan-access.the_backend_evaluates_the_resulting_access_graph.f318a7dc
-
setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing &&
- i18n:govoplan-access.group.171a0606
- {viewing.name}
- i18n:govoplan-access.slug.094da9b9
- {viewing.slug}
- i18n:govoplan-access.status.bae7d5be
- {viewing.is_active ? "i18n:govoplan-access.active.a733b809" : "i18n:govoplan-access.inactive.09af574c"}
- i18n:govoplan-access.management.63cecca6
- {viewing.system_template_id ? i18nMessage("i18n:govoplan-access.system_managed_value.eb564eb1", { value0: viewing.system_required ? "i18n:govoplan-access.required.2e5396fd" : "i18n:govoplan-access.available.ce372771" }) : "i18n:govoplan-access.tenant_managed.843eed93"}
diff --git a/webui/src/features/admin/RolesPanel.tsx b/webui/src/features/admin/RolesPanel.tsx
index 98c9656..1e260a8 100644
--- a/webui/src/features/admin/RolesPanel.tsx
+++ b/webui/src/features/admin/RolesPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Pencil, Plus, Search, Trash2 } from "lucide-react";
-import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings, AuthInfo } from "@govoplan/core-webui";
import { createRole, deleteRole, fetchPermissionCatalog, fetchRolesDelta, updateRole, type PermissionItem, type RoleSummary } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
@@ -138,20 +138,20 @@ export default function RolesPanel({ settings, auth, canDefine, onAuthRefresh }:
row.id} emptyText="i18n:govoplan-access.no_roles_found.70f7c0c9" />
- !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<>>}>
-
+ !busy && setEditing(null)} className="" footer={<>>}>
+
setDraft({ ...draft, name: event.target.value })} />
setDraft({ ...draft, slug: event.target.value })} />
{editing !== "new" && }
-
+
{permissionGroups.map(([category, items]) => {
const scopes = items.map((permission) => permission.scope);
return
;
})}
- setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing && <>
- i18n:govoplan-access.role.c3f104d1
- {viewing.name}
- i18n:govoplan-access.slug.094da9b9
- {viewing.slug}
- i18n:govoplan-access.type.3deb7456
- {viewing.is_builtin ? "i18n:govoplan-access.built_in.20f409cc" : viewing.system_template_id ? i18nMessage("i18n:govoplan-access.system_managed_value.eb564eb1", { value0: viewing.system_required ? "i18n:govoplan-access.required.2e5396fd" : "i18n:govoplan-access.available.ce372771" }) : "i18n:govoplan-access.tenant_custom.4307081e"}
- i18n:govoplan-access.assignable.a88debc5
- {viewing.is_assignable ? "i18n:govoplan-access.yes.5397e058" : "i18n:govoplan-access.no.816c52fd"}
diff --git a/webui/src/features/admin/ServiceAccountsPanel.tsx b/webui/src/features/admin/ServiceAccountsPanel.tsx
index 3cf11c6..fc7962d 100644
--- a/webui/src/features/admin/ServiceAccountsPanel.tsx
+++ b/webui/src/features/admin/ServiceAccountsPanel.tsx
@@ -8,7 +8,7 @@ import {
ShieldOff,
Trash2
} from "lucide-react";
-import {
+import { FormGrid, ActionToolbar,
AdminIconButton,
AdminPageLayout,
AdminSelectionList,
@@ -455,28 +455,28 @@ export default function ServiceAccountsPanel({
- !busy && setAccountEditor(null)}
- className="admin-dialog admin-dialog-wide"
+ className=""
footer={<>>}
>
-
+
setAccountDraft({ ...accountDraft, name: event.target.value })} />
setAccountDraft({ ...accountDraft, description: event.target.value })} />
-
+
Scope ceiling
({ id: permission.scope, label: permission.label, description: `${permission.scope} - ${permission.description}` }))} selected={accountDraft.scopes} onChange={(scopes) => setAccountDraft({ ...accountDraft, scopes })} emptyText="No tenant scopes can be delegated by your current account." />
- !busy && setManaging(null)}
- className="admin-dialog admin-dialog-wide"
+ className=""
footer={}
>
{managing && <>
@@ -486,15 +486,15 @@ export default function ServiceAccountsPanel({
-
+
} variant="primary" onClick={() => openCredentialEditor("create")} disabled={!canWrite || !managing.is_active} disabledReason={!canWrite ? ACCESS_INTERFACE_I18N.writePermissionRequired : !managing.is_active ? "Activate the service account first." : undefined} />
-
-
+
row.id} emptyText="No credentials found." />
@@ -502,25 +502,25 @@ export default function ServiceAccountsPanel({
>}
- !busy && setCredentialEditor(null)}
- className="admin-dialog admin-dialog-wide"
+ className=""
footer={<>>}
>
{credentialEditor?.mode === "rotate" && Rotation creates a new secret and revokes the previous credential in the same transaction.
}
-
+
setCredentialDraft({ ...credentialDraft, name: event.target.value })} />
setCredentialDraft({ ...credentialDraft, expiresAt: value })} />
-
+
Credential scopes
({ id: permission.scope, label: permission.label, description: `${permission.scope} - ${permission.description}` }))} selected={credentialDraft.scopes} onChange={(scopes) => setCredentialDraft({ ...credentialDraft, scopes })} emptyText="The service account has no credential scopes available." />
- setSecret(null)} className="admin-dialog" footer={}>
+ setSecret(null)} className="" footer={}>
{secret && <>The secret for {secret.name} is shown once.
{secret.value}Store it in a secret manager. GovOPlaN retains only a one-way hash and the visible prefix.
>}
diff --git a/webui/src/features/admin/SystemRolesPanel.tsx b/webui/src/features/admin/SystemRolesPanel.tsx
index 7887c9b..f1886af 100644
--- a/webui/src/features/admin/SystemRolesPanel.tsx
+++ b/webui/src/features/admin/SystemRolesPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Pencil, Plus, Search, Trash2 } from "lucide-react";
-import type { ApiSettings } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings } from "@govoplan/core-webui";
import {
createSystemRole,
deleteSystemRole,
@@ -248,19 +248,19 @@ export default function SystemRolesPanel({
- !busy && setEditing(null)}
- className="admin-dialog admin-dialog-wide"
+ className=""
footer={<>>}>
-
+
setDraft({ ...draft, name: event.target.value })} />
setDraft({ ...draft, slug: event.target.value })} />
-
+
i18n:govoplan-access.system_permissions.53ff0ab2
- setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing && - i18n:govoplan-access.slug.094da9b9
- {viewing.slug}
- i18n:govoplan-access.protected.28531336
- {viewing.slug === "system_owner" ? "i18n:govoplan-access.yes.5397e058" : "i18n:govoplan-access.no.816c52fd"}
- i18n:govoplan-access.assignable.a88debc5
- {viewing.is_assignable ? "i18n:govoplan-access.yes.5397e058" : "i18n:govoplan-access.no.816c52fd"}
- i18n:govoplan-access.account_assignments.f5a91f2a
- {viewing.user_assignments}
- i18n:govoplan-access.description.55f8ebc8
- {viewing.description || "—"}
- i18n:govoplan-access.effective_permissions.17c0fe8a
- {viewing.effective_permission_count}
- i18n:govoplan-access.assigned_scopes.c7b09b12
- {viewing.permissions.length ? joinLabels(viewing.permissions.map((name) => ({ name }))) : "—"}
}
diff --git a/webui/src/features/admin/SystemUsersPanel.tsx b/webui/src/features/admin/SystemUsersPanel.tsx
index 4d6d5d1..32ccd9e 100644
--- a/webui/src/features/admin/SystemUsersPanel.tsx
+++ b/webui/src/features/admin/SystemUsersPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { Search, Pencil, Plus, Trash2 } from "lucide-react";
-import type { ApiSettings } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings } from "@govoplan/core-webui";
import { Button } from "@govoplan/core-webui";
import { ConfirmDialog } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
@@ -233,8 +233,8 @@ export default function SystemUsersPanel({
row.account_id} emptyText="i18n:govoplan-access.no_global_accounts_found.29d96a9e" />
- !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<>>}>
-
+ !busy && setEditing(null)} className="" footer={<>>}>
+
setDraft({ ...draft, email: event.target.value })} />
setDraft({ ...draft, displayName: event.target.value })} />
{editing === "new" &&
@@ -248,7 +248,7 @@ export default function SystemUsersPanel({
}
-
+
i18n:govoplan-access.system_roles.a9461aa6 ({ id: role.id, label: role.name, description: role.description, disabled: !canAssignRoles }))} selected={draft.roleIds} onChange={(roleIds) => setDraft({ ...draft, roleIds })} />
i18n:govoplan-access.tenant_memberships.451de736 ({ id: tenant.id, label: tenant.name, description: tenant.slug, disabled: !canManageMemberships || Boolean(draft.memberships.find((item) => item.tenant_id === tenant.id)?.is_last_active_owner) }))} selected={draft.memberships.map((item) => item.tenant_id)} onChange={setMembershipSelection} />
@@ -257,11 +257,11 @@ export default function SystemUsersPanel({
i18n:govoplan-access.removing_a_tenant_checkbox_suspends_that_members.7c6df77d
-
setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing && - i18n:govoplan-access.account.85dfa32c
- {viewing.email}
- i18n:govoplan-access.display_name.c7874aaa
- {viewing.display_name || "—"}
- i18n:govoplan-access.status.bae7d5be
- {viewing.is_active ? "i18n:govoplan-access.active.a733b809" : "i18n:govoplan-access.inactive.09af574c"}
- i18n:govoplan-access.last_login.43dab84f
- {formatDateTime(viewing.last_login_at)}
- i18n:govoplan-access.system_roles.a9461aa6
- {joinLabels(viewing.roles)}
- i18n:govoplan-access.tenants.1f7ae776
- {viewing.memberships.map((item) => item.tenant_name).join(", ") || "—"}
}
- setTemporaryPassword(null)} className="admin-dialog" footer={}>
+ setTemporaryPassword(null)} className="" footer={}>
{temporaryPassword && <>i18n:govoplan-access.this_is_shown_once_for.b0f0f526 {temporaryPassword.email}.
{temporaryPassword.value}>}
diff --git a/webui/src/features/admin/UsersPanel.tsx b/webui/src/features/admin/UsersPanel.tsx
index e8918ec..0a5038a 100644
--- a/webui/src/features/admin/UsersPanel.tsx
+++ b/webui/src/features/admin/UsersPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { KeyRound, Pencil, Plus, Search, Trash2 } from "lucide-react";
-import type { ApiSettings, AuthInfo } from "@govoplan/core-webui";
+import type { FormGrid, ApiSettings, AuthInfo } from "@govoplan/core-webui";
import { createUser, fetchGroupsDelta, fetchRolesDelta, fetchUserAccessExplanation, fetchUsersDelta, updateUser, type AccessRoleSourceItem, type FunctionFactExplanationItem, type GroupSummary, type RoleSummary, type UserAccessExplanationResponse, type UserAdminItem } from "../../api/admin";
import { Button } from "@govoplan/core-webui";
import { DataGrid, type DataGridColumn } from "@govoplan/core-webui";
@@ -206,8 +206,8 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
row.id} emptyText="i18n:govoplan-access.no_tenant_users_found.74bb615f" />
- !busy && setEditing(null)} className="admin-dialog admin-dialog-wide" footer={<>>}>
-
+ !busy && setEditing(null)} className="" footer={<>>}>
+
setDraft({ ...draft, email: event.target.value })} />
setDraft({ ...draft, displayName: event.target.value })} />
{editing === "new" &&
@@ -221,7 +221,7 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
}
-
+
{editing === "new" && setDraft({ ...draft, passwordResetRequired })} />}
{editing && editing !== "new" && editing.is_last_active_owner && i18n:govoplan-access.this_membership_is_the_tenant_s_last_active_oper.072b247f
}
@@ -231,7 +231,7 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
i18n:govoplan-access.group_roles_and_direct_roles_are_combined_the_ba.a43c2f16
-
setViewing(null)} className="admin-dialog admin-dialog-wide" footer={}>
+ setViewing(null)} className="" footer={}>
{viewing &&
- i18n:govoplan-access.user.9f8a2389
- {viewing.display_name || viewing.email}
- i18n:govoplan-access.email.84add5b2
- {viewing.email}
- i18n:govoplan-access.membership.53bc9670
- {viewing.is_active ? "i18n:govoplan-access.active.a733b809" : "i18n:govoplan-access.inactive.09af574c"}
- i18n:govoplan-access.global_account.e1b00cf5
- {viewing.account_is_active ? "i18n:govoplan-access.active.a733b809" : "i18n:govoplan-access.inactive.09af574c"}
@@ -240,7 +240,7 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
}
- { if (!accessExplanationLoading) { setExplaining(null); setAccessExplanation(null); } }} className="admin-dialog admin-dialog-wide" footer={}>
+ { if (!accessExplanationLoading) { setExplaining(null); setAccessExplanation(null); } }} className="" footer={}>
{accessExplanationLoading && i18n:govoplan-access.loading_access_explanation.04a7c934
}
{accessExplanation && <>
@@ -282,7 +282,7 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
>}
- setTemporaryPassword(null)} className="admin-dialog" footer={}>
+ setTemporaryPassword(null)} className="" footer={}>
{temporaryPassword && <>i18n:govoplan-access.this_is_shown_once_for.b0f0f526 {temporaryPassword.email}.
{temporaryPassword.password}i18n:govoplan-access.transmit_it_through_a_separate_secure_channel.ab892c7b
>}