Refactored AdminInvitesPage, AdminUserDetailsPage, AdminRolesPage, and AdminAppsPage to use the new pure Hono SSR JSX stateless components. Fixed missing import definitions in AdminRolesPage. Moved task file to complete state. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
205 lines
7.2 KiB
Python
205 lines
7.2 KiB
Python
import re
|
|
|
|
with open('ui/components/AdminRolesPage.tsx', 'r') as f:
|
|
content = f.read()
|
|
|
|
role_form = """ <div
|
|
id="roleFormCard"
|
|
class="card"
|
|
style="display: none; border-left: 4px solid var(--primary); margin-bottom: 1.5rem;"
|
|
>
|
|
<h3
|
|
id="roleFormTitle"
|
|
style="margin: 0 0 0.5rem 0; color: var(--text-primary);"
|
|
>
|
|
Create New Role
|
|
</h3>
|
|
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0 0 1.25rem 0;">
|
|
Define a global shared role or an application-scoped custom grant.
|
|
</p>
|
|
|
|
<form id="roleForm" onsubmit="handleSaveRole(event)">
|
|
<input type="hidden" id="editRoleId" value="" />
|
|
|
|
<div
|
|
id="scopeSelectContainer"
|
|
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-bottom: 1rem;"
|
|
>
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Scope (Applicability) *
|
|
</label>
|
|
<select
|
|
id="roleScope"
|
|
onchange="handleScopeChange()"
|
|
style="width: 100%;"
|
|
>
|
|
<option value="global">
|
|
Global (Shared across ALL applications)
|
|
</option>
|
|
<option value="app_specific">
|
|
Application-Specific (Scoped to single app)
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="appSelectContainer" style="display: none;">
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Target Application *
|
|
</label>
|
|
<select
|
|
id="roleAppId"
|
|
style="width: 100%;"
|
|
>
|
|
{apps.map((app) => (
|
|
<option value={app.id}>
|
|
{app.name} ({app.spiffe_id})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-bottom: 1.25rem;">
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Role Identifier *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="roleName"
|
|
placeholder="e.g. navigator, copilot, auditor"
|
|
required
|
|
style="width: 100%;"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Description / Purpose
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="roleDescription"
|
|
placeholder="e.g. Flight routing and navigational telemetry access"
|
|
style="width: 100%;"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 0.75rem;">
|
|
<button type="submit" class="btn-primary" style="min-height: 42px;">
|
|
Save Role
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn-outline"
|
|
onclick="closeRoleDrawer()"
|
|
style="min-height: 42px;"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>"""
|
|
|
|
role_form_replacement = """ <AdminModal
|
|
id="roleFormModal"
|
|
title="Create New Role"
|
|
onClose="closeRoleDrawer()"
|
|
>
|
|
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0 0 1.25rem 0;">
|
|
Define a global shared role or an application-scoped custom grant.
|
|
</p>
|
|
|
|
<form id="roleForm" onsubmit="handleSaveRole(event)">
|
|
<input type="hidden" id="editRoleId" value="" />
|
|
|
|
<div
|
|
id="scopeSelectContainer"
|
|
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-bottom: 1rem;"
|
|
>
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Scope (Applicability) *
|
|
</label>
|
|
<select
|
|
id="roleScope"
|
|
onchange="handleScopeChange()"
|
|
style="width: 100%;"
|
|
>
|
|
<option value="global">
|
|
Global (Shared across ALL applications)
|
|
</option>
|
|
<option value="app_specific">
|
|
Application-Specific (Scoped to single app)
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="appSelectContainer" style="display: none;">
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Target Application *
|
|
</label>
|
|
<select
|
|
id="roleAppId"
|
|
style="width: 100%;"
|
|
>
|
|
{apps.map((app) => (
|
|
<option value={app.id}>
|
|
{app.name} ({app.spiffe_id})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-bottom: 1.25rem;">
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Role Identifier *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="roleName"
|
|
placeholder="e.g. navigator, copilot, auditor"
|
|
required
|
|
style="width: 100%;"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
|
|
Description / Purpose
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="roleDescription"
|
|
placeholder="e.g. Flight routing and navigational telemetry access"
|
|
style="width: 100%;"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 0.75rem;">
|
|
<button type="submit" class="btn-primary" style="min-height: 42px;">
|
|
Save Role
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn-outline"
|
|
onclick="closeRoleDrawer()"
|
|
style="min-height: 42px;"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</AdminModal>"""
|
|
|
|
content = content.replace(role_form, role_form_replacement)
|
|
|
|
with open('ui/components/AdminRolesPage.tsx', 'w') as f:
|
|
f.write(content)
|
|
print("Replaced Roles Form!")
|