fix(ui): anchor help to headings and document grouped navigation

Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
This commit is contained in:
2026-09-09 02:03:13 +02:00
parent 7eb67b9fa7
commit f6cb72ccb0
10 changed files with 19 additions and 11 deletions
+8 -2
View File
@@ -1594,6 +1594,7 @@ ACCESS_DOCUMENTATION: tuple[DocumentationTopic, ...] = (
"Open Settings and use the workspace navigation editor to move or show available entries. Personal order and visibility take precedence over tenant and system preferences. Entries locked by a system or tenant administrator remain visible, and a user cannot create a lock. Choosing the inherited order removes the personal layer. Module entitlement, View policy, and permissions continue to decide which destinations are available, so changing navigation never grants access."
" The same editor is used for system, tenant, personal, and View layouts. Drag handles reorder modules and separators together; arrow buttons provide single-step moves. On a focused handle use Space to pick up, arrow keys to move, Enter to drop, or Escape to cancel. Add module restores a removed available entry; removing it only hides navigation and never uninstalls the module or deletes data. Add separator creates an optional group label, and separators remain horizontal rules when the rail is collapsed. Opening the editor leaves the draft clean; Save on the owning page persists changes, while inherited layout removes the override. View surface restrictions still apply, and an explicit personal layout takes precedence over the active View's presentation order."
" Expanded navigation shows group headings without divider lines; collapsing it replaces those headings with horizontal separators between groups."
" No setup is required for the standard groups: Work; Services and cases; Records and documents; Communication; Meetings and decisions; Data and assurance; People and responsibility. Only available, authorized groups appear. The editor identifies an inherited, custom grouped, or explicitly flat layout. The baseline is personal over tenant over system over these live standard groups. Use inherited layout and Save removes only the personal override, not tenant or system configuration. An intentionally flat layout is preserved until changed; locked entries still cannot be hidden."
" A temporarily failed module interface import is retried once after a short delay. If it still fails, the shell names the affected enabled modules and offers guarded Reload without changing entitlements, View restrictions, or configured data. Save or explicitly discard pending work before reloading; a missing interface is not evidence that the module was uninstalled."
),
layer="configured",
@@ -1623,6 +1624,7 @@ ACCESS_DOCUMENTATION: tuple[DocumentationTopic, ...] = (
"verfügbar sind. Eine Navigationsänderung gewährt daher niemals zusätzlichen Zugriff."
" Derselbe Editor wird für System-, Mandanten-, persönliche und View-Anordnungen verwendet. Ziehgriffe ordnen Module und Trennlinien gemeinsam an; Pfeilschaltflächen verschieben schrittweise. Am fokussierten Griff nimmt die Leertaste auf, Pfeiltasten verschieben, Eingabe legt ab und Escape bricht ab. Modul hinzufügen stellt einen entfernten verfügbaren Eintrag wieder her; Entfernen blendet nur die Navigation aus und deinstalliert weder ein Modul noch löscht es Daten. Trennlinie hinzufügen erlaubt eine optionale Gruppenbezeichnung; auch die eingeklappte Leiste zeigt horizontale Trennlinien. Das Öffnen erzeugt keine ungespeicherten Änderungen. Speichern auf der jeweiligen Seite übernimmt die Anordnung, die geerbte Anordnung entfernt die Ausnahme. View-Oberflächenbeschränkungen bleiben wirksam; eine ausdrückliche persönliche Anordnung hat Vorrang vor der Darstellungsreihenfolge der aktiven View."
" Die ausgeklappte Navigation zeigt Gruppenüberschriften ohne Trennlinien; beim Einklappen werden die Überschriften durch horizontale Linien zwischen den Gruppen ersetzt."
" Die Standardgruppen benötigen keine Einrichtung: Arbeit; Leistungen und Vorgänge; Akten und Dokumente; Kommunikation; Termine und Entscheidungen; Daten und Qualitätssicherung; Personen und Verantwortung. Nur verfügbare, berechtigte Gruppen erscheinen. Der Editor kennzeichnet geerbte, eigene gruppierte und ausdrücklich ungegliederte Anordnungen. Persönliche Vorgaben haben Vorrang vor Mandant, System und diesen aktuellen Standardgruppen. Geerbte Anordnung verwenden und Speichern entfernt nur die persönliche Anpassung, nicht die Mandanten- oder Systemkonfiguration. Eine bewusst ungegliederte Anordnung bleibt bis zu ihrer Änderung erhalten; gesperrte Einträge können weiterhin nicht ausgeblendet werden."
" Ein vorübergehend fehlgeschlagener Import einer Moduloberfläche wird nach kurzer Wartezeit einmal wiederholt. Bei erneutem Fehler nennt die Oberfläche die betroffenen aktivierten Module und bietet geschütztes Neuladen an; Modulberechtigungen, View-Beschränkungen und konfigurierte Daten bleiben unverändert. Speichern oder verwerfen Sie ausstehende Änderungen ausdrücklich vor dem Neuladen. Eine fehlende Oberfläche bedeutet nicht, dass das Modul deinstalliert wurde."
),
}
@@ -1637,7 +1639,9 @@ ACCESS_DOCUMENTATION: tuple[DocumentationTopic, ...] = (
id="access.reference.shared-interface-controls",
title="Use shared tables and dialogs",
summary="Resize table columns and use compact dialogs without losing action controls.",
body="Shared DataGrid action columns reserve room for their actual controls and wrap action groups in narrow containers. Wide data retains a local horizontal scrollbar; an oversized pinned column becomes scrollable rather than covering the entire table. Drag a column boundary, or focus it and use Left/Right for 10-pixel changes and Shift for 40 pixels. Enter or double-click resets that column; Escape cancels an active drag without closing its dialog. Widths are browser-local and do not change other users or stored data. The sizing-contract update resets incompatible legacy width preferences once while preserving filters and sort choices. Dialog form fields shrink within the available panel; only intentionally wide content such as a table scrolls horizontally inside its own region. Reload sits in the top-right action group immediately before New on collection pages; editable pages keep Save last and protect unsaved changes on Reload. Table-only cards have full-width bodies; explanatory sections remain padded. List-filter dropdowns use checkboxes with Select all and Deselect all; selecting several values matches any of them, while selecting none shows no matches. Filter and layout choices do not grant access or modify records.",
body="The documentation book sits immediately to the right of each Access administration heading; "
"field help remains beside its label. "
"Shared DataGrid action columns reserve room for their actual controls and wrap action groups in narrow containers. Wide data retains a local horizontal scrollbar; an oversized pinned column becomes scrollable rather than covering the entire table. Drag a column boundary, or focus it and use Left/Right for 10-pixel changes and Shift for 40 pixels. Enter or double-click resets that column; Escape cancels an active drag without closing its dialog. Widths are browser-local and do not change other users or stored data. The sizing-contract update resets incompatible legacy width preferences once while preserving filters and sort choices. Dialog form fields shrink within the available panel; only intentionally wide content such as a table scrolls horizontally inside its own region. Reload sits in the top-right action group immediately before New on collection pages; editable pages keep Save last and protect unsaved changes on Reload. Table-only cards have full-width bodies; explanatory sections remain padded. List-filter dropdowns use checkboxes with Select all and Deselect all; selecting several values matches any of them, while selecting none shows no matches. Filter and layout choices do not grant access or modify records.",
documentation_types=("user", "admin"),
audience=("user", "tenant_admin", "system_admin"),
related_modules=("admin", "templates"),
@@ -1645,7 +1649,9 @@ ACCESS_DOCUMENTATION: tuple[DocumentationTopic, ...] = (
translations={"de": {
"title": "Gemeinsame Tabellen und Dialoge bedienen",
"summary": "Tabellenspalten anpassen und kompakte Dialoge bedienen, ohne Aktionsschaltflächen zu verlieren.",
"body": "Aktionsspalten der zentralen DataGrid reservieren Platz für ihre tatsächlichen Bedienelemente; in schmalen Bereichen brechen Aktionsgruppen um. Breite Daten behalten eine lokale horizontale Bildlaufleiste. Eine übergroße angeheftete Spalte wird mitscrollbar, statt die gesamte Tabelle zu verdecken. Ziehen Sie eine Spaltengrenze oder fokussieren Sie sie und verwenden Links/Rechts für 10-Pixel-Schritte, mit Umschalt für 40 Pixel. Eingabe oder Doppelklick setzt diese Spalte zurück. Escape bricht einen laufenden Ziehvorgang ab, ohne den Dialog zu schließen. Breiten bleiben browserlokal und verändern weder andere Benutzer noch gespeicherte Daten. Die aktualisierte Größenberechnung setzt unvereinbare alte Breitenpräferenzen einmalig zurück; Filter und Sortierung bleiben erhalten. Formularfelder passen sich an den verfügbaren Dialog an. Nur bewusst breite Inhalte wie Tabellen scrollen horizontal in ihrem eigenen Bereich. Neu laden steht bei Sammlungsseiten oben rechts unmittelbar vor Neu. Bearbeitbare Seiten behalten Speichern als letzte Aktion und schützen ungespeicherte Änderungen beim Neuladen. Reine Tabellenkarten nutzen die volle Breite; erläuternde Abschnitte behalten Innenabstand. Listenfilter bieten Kontrollkästchen mit Alle auswählen und Alle abwählen: mehrere Werte schließen jeden davon ein, keine Auswahl zeigt keine Treffer. Filter und Layout erteilen weder Zugriff noch verändern sie Datensätze."
"body": "Das Dokumentationsbuch steht unmittelbar rechts neben der jeweiligen Überschrift der "
"Zugriffsverwaltung; Feldhilfe bleibt neben der Feldbezeichnung. "
"Aktionsspalten der zentralen DataGrid reservieren Platz für ihre tatsächlichen Bedienelemente; in schmalen Bereichen brechen Aktionsgruppen um. Breite Daten behalten eine lokale horizontale Bildlaufleiste. Eine übergroße angeheftete Spalte wird mitscrollbar, statt die gesamte Tabelle zu verdecken. Ziehen Sie eine Spaltengrenze oder fokussieren Sie sie und verwenden Links/Rechts für 10-Pixel-Schritte, mit Umschalt für 40 Pixel. Eingabe oder Doppelklick setzt diese Spalte zurück. Escape bricht einen laufenden Ziehvorgang ab, ohne den Dialog zu schließen. Breiten bleiben browserlokal und verändern weder andere Benutzer noch gespeicherte Daten. Die aktualisierte Größenberechnung setzt unvereinbare alte Breitenpräferenzen einmalig zurück; Filter und Sortierung bleiben erhalten. Formularfelder passen sich an den verfügbaren Dialog an. Nur bewusst breite Inhalte wie Tabellen scrollen horizontal in ihrem eigenen Bereich. Neu laden steht bei Sammlungsseiten oben rechts unmittelbar vor Neu. Bearbeitbare Seiten behalten Speichern als letzte Aktion und schützen ungespeicherte Änderungen beim Neuladen. Reine Tabellenkarten nutzen die volle Breite; erläuternde Abschnitte behalten Innenabstand. Listenfilter bieten Kontrollkästchen mit Alle auswählen und Alle abwählen: mehrere Werte schließen jeden davon ein, keine Auswahl zeigt keine Treffer. Filter und Layout erteilen weder Zugriff noch verändern sie Datensätze."
}},
),
DocumentationTopic(
+1 -1
View File
@@ -153,7 +153,7 @@ export default function ApiKeysPanel({ settings, auth, canCreate, canRevoke }: {
return (
<>
<AdminPageLayout title="i18n:govoplan-access.tenant_api_keys.4b1d81f8" description="i18n:govoplan-access.tenant_scoped_automation_credentials_are_capped_.9059dcae" loading={loading} error={error} success={success} helpContextId="access.admin.api-keys" helpModuleId="access" actions={<><DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} /><ToggleSwitch label="i18n:govoplan-access.show_revoked.b4265807" checked={showRevoked} helpContextId="access.api-keys.field.show-revoked" helpModuleId="access" onChange={setShowRevoked} /><Button helpContextId="access.api-keys.action.reload" helpModuleId="access" onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_api_key.725d9988" icon={<Plus />} variant="primary" helpContextId="access.api-keys.action.create" helpModuleId="access" onClick={openCreate} disabled={!canCreate || !users.length} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : !users.length ? ACCESS_INTERFACE_I18N.selectUserAndScopes : undefined} /></>}>
<AdminPageLayout title="i18n:govoplan-access.tenant_api_keys.4b1d81f8" titleHelp={<DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} />} description="i18n:govoplan-access.tenant_scoped_automation_credentials_are_capped_.9059dcae" loading={loading} error={error} success={success} helpContextId="access.admin.api-keys" helpModuleId="access" actions={<><ToggleSwitch label="i18n:govoplan-access.show_revoked.b4265807" checked={showRevoked} helpContextId="access.api-keys.field.show-revoked" helpModuleId="access" onChange={setShowRevoked} /><Button helpContextId="access.api-keys.action.reload" helpModuleId="access" onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_api_key.725d9988" icon={<Plus />} variant="primary" helpContextId="access.api-keys.action.create" helpModuleId="access" onClick={openCreate} disabled={!canCreate || !users.length} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : !users.length ? ACCESS_INTERFACE_I18N.selectUserAndScopes : undefined} /></>}>
<div className="admin-table-surface"><DataGrid id="admin-api-keys-v3" rows={keys} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-access.no_api_keys_found.1f377128" /></div>
</AdminPageLayout>
@@ -118,10 +118,10 @@ export default function CredentialEnvelopesPanel({
return (
<AdminPageLayout
title={scopeTitle(scopeType)}
titleHelp={<DocumentationHelpLink reference={CREDENTIAL_DOCUMENTATION} />}
description={scopeDescription(scopeType)}
loading={loadingTargets}
error={targetError}
actions={<DocumentationHelpLink reference={CREDENTIAL_DOCUMENTATION} />}
>
<CredentialEnvelopeManager
settings={settings}
@@ -271,13 +271,13 @@ export default function ExternalFunctionRoleMappingsPanel({
<>
<AdminPageLayout
title="i18n:govoplan-access.function_role_mappings.2b64e9c3"
titleHelp={<DocumentationHelpLink reference={FUNCTION_MAPPING_DOCUMENTATION} />}
description="i18n:govoplan-access.map_accepted_function_facts_to_tenant_roles_.7581e5cf"
loading={loading}
error={error}
success={success}
actions={
<>
<DocumentationHelpLink reference={FUNCTION_MAPPING_DOCUMENTATION} />
<Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button>
<AdminIconButton label="i18n:govoplan-access.add_function_role_mapping.1bc376ac" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canWrite || !assignableRoles.length} disabledReason={!canWrite ? ACCESS_INTERFACE_I18N.createPermissionRequired : !assignableRoles.length ? ACCESS_INTERFACE_I18N.selectAssignableRole : undefined} />
</>
+1 -1
View File
@@ -146,7 +146,7 @@ export default function GroupsPanel({ settings, auth, canDefine, canManageMember
return (
<>
<AdminPageLayout title="i18n:govoplan-access.tenant_groups.47e6cc05" description="i18n:govoplan-access.groups_provide_shared_file_spaces_and_inherited_.27f05309" loading={loading} error={error} success={success} actions={<><DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_group.2fca464f" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canDefine} disabledReason={!canDefine ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<AdminPageLayout title="i18n:govoplan-access.tenant_groups.47e6cc05" titleHelp={<DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} />} description="i18n:govoplan-access.groups_provide_shared_file_spaces_and_inherited_.27f05309" loading={loading} error={error} success={success} actions={<><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_group.2fca464f" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canDefine} disabledReason={!canDefine ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<div className="admin-table-surface"><DataGrid id="admin-groups-v3" rows={groups} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-access.no_groups_found.627ca913" /></div>
</AdminPageLayout>
+1 -1
View File
@@ -135,7 +135,7 @@ export default function RolesPanel({ settings, auth, canDefine, onAuthRefresh }:
return (
<>
<AdminPageLayout title="i18n:govoplan-access.tenant_roles.51aca82d" description="i18n:govoplan-access.roles_are_explicit_tenant_permission_bundles_bui.ce55fcaa" loading={loading} error={error} success={success} actions={<><DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_role.d8d5d55c" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canDefine} disabledReason={!canDefine ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<AdminPageLayout title="i18n:govoplan-access.tenant_roles.51aca82d" titleHelp={<DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} />} description="i18n:govoplan-access.roles_are_explicit_tenant_permission_bundles_bui.ce55fcaa" loading={loading} error={error} success={success} actions={<><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_role.d8d5d55c" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canDefine} disabledReason={!canDefine ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<div className="admin-table-surface"><DataGrid id="admin-roles-v3" rows={roles} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-access.no_roles_found.70f7c0c9" /></div>
</AdminPageLayout>
@@ -445,6 +445,7 @@ export default function ServiceAccountsPanel({
<>
<AdminPageLayout
title="Service accounts"
titleHelp={<DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} />}
description="Manage non-login automation principals and their independently rotatable, scope-bounded credentials."
loading={loading}
error={error}
@@ -452,7 +453,6 @@ export default function ServiceAccountsPanel({
helpContextId="access.admin.service-accounts"
helpModuleId="access"
actions={<>
<DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} />
<Button helpContextId="access.service-accounts.action.reload" helpModuleId="access" onClick={() => void load()} disabled={loading}>Reload</Button>
<AdminIconButton label="Add service account" icon={<Plus />} variant="primary" helpContextId="access.service-accounts.action.create" helpModuleId="access" onClick={openCreateAccount} disabled={!canWrite} disabledReason={!canWrite ? ACCESS_INTERFACE_I18N.writePermissionRequired : undefined} />
</>}
@@ -238,11 +238,12 @@ export default function SystemRolesPanel({
<>
<AdminPageLayout
title="i18n:govoplan-access.system_roles.a9461aa6"
titleHelp={<DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} />}
description="i18n:govoplan-access.instance_wide_role_definitions_system_owner_is_p.a888778d"
loading={loading}
error={error}
success={success}
actions={<><DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_system_role.f9ef262b" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canWrite} disabledReason={!canWrite ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
actions={<><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_system_role.f9ef262b" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canWrite} disabledReason={!canWrite ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<div className="admin-table-surface">
<DataGrid id="admin-system-role-definitions-v4" rows={roles} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-access.no_system_roles_found.051cf727" />
@@ -238,11 +238,12 @@ export default function SystemUsersPanel({
{recovering && canIssueRecovery && <PasswordRecoveryIssueDialog key={recovering.account_id} settings={settings} account={recovering} onClose={() => setRecovering(null)} />}
<AdminPageLayout
title="i18n:govoplan-access.central_users.91ac1b51"
titleHelp={<DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} />}
description="i18n:govoplan-access.global_login_identities_tenant_memberships_and_s.8f963b7f"
loading={loading}
error={error}
success={success}
actions={<><DocumentationHelpLink reference={ACCESS_REFERENCE_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_global_account.18e4df22" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
actions={<><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_global_account.18e4df22" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<div className="admin-table-surface"><DataGrid id="admin-system-users-v3" rows={accounts} columns={columns} initialFit="container" getRowKey={(row) => row.account_id} emptyText="i18n:govoplan-access.no_global_accounts_found.29d96a9e" /></div>
</AdminPageLayout>
+1 -1
View File
@@ -276,7 +276,7 @@ export default function UsersPanel({ settings, auth, canCreate, canUpdate, canSu
return (
<>
<AdminPageLayout title="i18n:govoplan-access.tenant_users.cb800b38" description="i18n:govoplan-access.manage_memberships_groups_and_direct_roles_in_th.25af86bb" loading={loading} error={error} success={success} actions={<><DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} /><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_tenant_user.36f37ce7" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<AdminPageLayout title="i18n:govoplan-access.tenant_users.cb800b38" titleHelp={<DocumentationHelpLink reference={ACCESS_WORKFLOW_DOCUMENTATION} />} description="i18n:govoplan-access.manage_memberships_groups_and_direct_roles_in_th.25af86bb" loading={loading} error={error} success={success} actions={<><Button onClick={() => void load()} disabled={loading} disabledReason={loading ? ACCESS_INTERFACE_I18N.loading : undefined}>i18n:govoplan-access.reload.cce71553</Button><AdminIconButton label="i18n:govoplan-access.add_tenant_user.36f37ce7" icon={<Plus />} variant="primary" onClick={openCreate} disabled={!canCreate} disabledReason={!canCreate ? ACCESS_INTERFACE_I18N.createPermissionRequired : undefined} /></>}>
<div className="admin-table-surface"><DataGrid id="admin-users-v3" rows={users} columns={columns} initialFit="container" getRowKey={(row) => row.id} emptyText="i18n:govoplan-access.no_tenant_users_found.74bb615f" /></div>
</AdminPageLayout>