google-labs-jules[bot] 65f59521c0 feat(ui): decompose Admin UI with separate Drawers and Scripts
Phase 2 Admin Drawers & Scripts execution:
- Extract `AppDrawer`, `InviteDrawer`, `RoleEditorDrawer`, and `GrantDrawer`.
- Extract `AdminAppsScript`, `AdminInvitesScript`, `AdminRolesScript`, and `AdminUserDetailsScript`.
- Hook extracted components into their respective pages.
- Format `AdminRolesPage.tsx` and all modified files using `deno fmt`.

Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
2026-08-26 18:37:15 +00:00

129 lines
4.5 KiB
XML

import { AdminModal } from "../AdminModal.tsx";
export const AppDrawer = () => {
return (
<AdminModal
id="appFormModal"
title="Register New Subsidiary Application"
onClose="closeAppDrawer()"
>
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0 0 1.25rem 0;">
Authenticate incoming ConnectRPC/ForwardAuth requests against the
application's SPIFFE ID and edge routing domains.
</p>
<form id="appForm" onsubmit="handleSaveApp(event)">
<input type="hidden" id="editAppId" value="" />
<div 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);">
Application Name *
</label>
<input
type="text"
id="appName"
name="name"
placeholder="e.g. Elite Dangerous Streaming Hub"
required
style="width: 100%;"
/>
</div>
<div id="spiffeIdContainer">
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
SPIFFE ID (Workload Identity) *
</label>
<input
type="text"
id="appSpiffeId"
name="spiffeId"
placeholder="e.g. spiffe://system.local/ed-droid-backend"
required
style="width: 100%;"
/>
</div>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
Description
</label>
<input
type="text"
id="appDescription"
name="description"
placeholder="e.g. Data telemetry streaming and UI module system"
style="width: 100%;"
/>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
Domain (Edge Ingress Hostname)
</label>
<input
type="text"
id="appDomain"
name="domain"
placeholder="e.g. ed-droid.atyg.org"
style="width: 100%;"
/>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: flex; align-items: center; gap: 0.5rem; font-weight: 600; font-size: 0.875rem; cursor: pointer; color: var(--text-primary);">
<input
type="checkbox"
id="appIsPublic"
name="is_public"
style="width: 18px; height: 18px;"
/>
Is Publicly Accessible (Bypass all auth checks)
</label>
</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);">
Bypass Paths (Comma-separated)
</label>
<input
type="text"
id="appBypassPaths"
name="bypass_paths"
placeholder="e.g. /api/public, /webhooks/github"
style="width: 100%;"
/>
</div>
<div>
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.85rem; color: var(--text-secondary);">
Allowed CIDRs (Comma-separated)
</label>
<input
type="text"
id="appAllowedCidrs"
name="allowed_cidrs"
placeholder="e.g. 192.168.1.0/24, 10.0.0.0/8"
style="width: 100%;"
/>
</div>
</div>
<div style="display: flex; gap: 0.75rem;">
<button type="submit" class="btn-primary" style="min-height: 42px;">
Save Registration
</button>
<button
type="button"
class="btn-outline"
onclick="closeAppDrawer()"
style="min-height: 42px;"
>
Cancel
</button>
</div>
</form>
</AdminModal>
);
};