Publish curated ITWorx_MCP_Hub source from 6c7434368ce2a594005983c5a6601a31a639e7f1

This commit is contained in:
Public Source Publisher committed 2026-10-01 18:03:00 +00:00
1 parent 77946d62c4
commit 6d40ab975c
86 files changed
+6784 -1478

No files matched your search

+81 -27
View File
@@ -1,10 +1,10 @@
import { useEffect, useMemo, useRef, useState } from "react";
import type { DashboardSnapshot, ManagementApiClient, ManagementRole, SessionStatus } from "./contracts";
import type { ClientOnboardingResult, DashboardSnapshot, ManagementApiClient, ManagementRole, SessionStatus } from "./contracts";
import { routeTitle } from "./contracts";
import { ApiError, createApiClient, safeApiMessage } from "./api";
import { RbacProvider } from "./rbac-context";
import { can } from "./rbac";
import { basePath, resourceKind, usePath } from "./routing";
import { basePath, connectorDetailId, resourceKind, usePath } from "./routing";
import { Brand } from "./components/Brand";
import { CommandMenu } from "./components/CommandMenu";
import { ErrorPanel } from "./components/ErrorPanel";
@@ -19,6 +19,8 @@ import { Operations } from "./pages/Operations";
import { ProjectDetail } from "./pages/ProjectDetail";
import { ResourcePage } from "./pages/ResourcePage";
import { SettingsPage } from "./pages/SettingsPage";
import { ConnectorDetail } from "./pages/ConnectorDetail";
import { focusableElements, isolateOutside, lockBodyScroll, trapTab } from "./components/modal-focus";
export function App({ api: apiProp }: { api?: ManagementApiClient }) {
const [api] = useState<ManagementApiClient>(() => apiProp ?? createApiClient());
@@ -31,19 +33,24 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
const [subject, setSubject] = useState<string | null>(null);
const [navOpen, setNavOpen] = useState(false);
const [commandOpen, setCommandOpen] = useState(false);
const [createdClient, setCreatedClient] = useState<ClientOnboardingResult["client"] | null>(null);
const identitySubject = useRef<string | null>(null);
identitySubject.current = session === "authenticated" ? subject : null;
const navTriggerRef = useRef<HTMLButtonElement>(null);
const title = useMemo(() => routeTitle(basePath(path)), [path]);
const navCloseRef = useRef<HTMLButtonElement>(null);
const navSidebarRef = useRef<HTMLElement>(null);
const navBackdropRef = useRef<HTMLButtonElement>(null);
const [compactNavigation, setCompactNavigation] = useState(() => window.matchMedia("(max-width: 840px)").matches);
const title = useMemo(() => connectorDetailId(path) ? "Connector detail" : routeTitle(basePath(path)), [path]);
const clearIdentity = () => {
setRoles([]);
setSnapshot(null);
setSubject(null);
setCreatedClient(null);
};
const closeNavigation = (restoreFocus = true) => {
setNavOpen(false);
if (restoreFocus) window.setTimeout(() => navTriggerRef.current?.focus(), 0);
};
const closeNavigation = () => setNavOpen(false);
const load = async () => {
setSession("checking");
@@ -90,13 +97,45 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
useEffect(() => { void load(); }, []);
useEffect(() => { setNavOpen(false); }, [path]);
useEffect(() => {
if (!navOpen) return;
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") closeNavigation();
const media = window.matchMedia("(max-width: 840px)");
const update = () => {
setCompactNavigation(media.matches);
if (!media.matches) setNavOpen(false);
};
media.addEventListener("change", update);
return () => media.removeEventListener("change", update);
}, []);
useEffect(() => {
const sidebar = navSidebarRef.current;
if (!navOpen || !compactNavigation || !sidebar) return;
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
const backdrop = navBackdropRef.current;
const restoreIsolation = isolateOutside(sidebar, backdrop ? [backdrop] : []);
const restoreScroll = lockBodyScroll();
const focusables = () => focusableElements(sidebar);
const onFocusIn = (event: FocusEvent) => {
if (event.target instanceof Node && sidebar.contains(event.target)) return;
(focusables()[0] ?? sidebar).focus();
};
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
event.preventDefault();
setNavOpen(false);
} else {
trapTab(event, sidebar);
}
};
navCloseRef.current?.focus();
document.addEventListener("focusin", onFocusIn, true);
document.addEventListener("keydown", onKeyDown);
return () => document.removeEventListener("keydown", onKeyDown);
}, [navOpen]);
return () => {
document.removeEventListener("focusin", onFocusIn, true);
document.removeEventListener("keydown", onKeyDown);
restoreIsolation();
restoreScroll();
if (previouslyFocused?.isConnected) previouslyFocused.focus();
};
}, [navOpen, compactNavigation]);
useEffect(() => {
if (session !== "authenticated") return;
const onKeyDown = (event: KeyboardEvent) => {
@@ -114,6 +153,9 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
const kind = resourceKind(path);
const detail = basePath(path).startsWith("/projects/");
const connectorId = connectorDetailId(path);
const scopeParams = new URLSearchParams(path.split("?")[1] ?? "");
const scopeKey = `${scopeParams.get("project") ?? ""}:${scopeParams.get("environment") ?? ""}`;
const canReadAudit = can(roles, "audit.read");
const active = (href: string) => basePath(path) === href || (href !== "/" && basePath(path).startsWith(`${href}/`));
const authenticated = session === "authenticated";
@@ -125,27 +167,38 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
: loadState === "error"
? <ErrorPanel message={error} expired={session === "expired"} retry={() => void load()} />
: detail
? <ProjectDetail path={path} navigate={navigate} api={api} />
: kind
? <ResourcePage path={path} kind={kind} api={api} navigate={navigate} />
: snapshot && basePath(path) === "/"
? <Dashboard snapshot={snapshot} reload={() => void load()} navigate={navigate} />
: basePath(path) === "/operations"
? <Operations path={path} navigate={navigate} snapshot={snapshot} />
: basePath(path) === "/settings"
? <SettingsPage path={path} navigate={navigate} />
: <ForbiddenPanel />;
? <ProjectDetail key={basePath(path)} path={path} navigate={navigate} api={api} />
: connectorId
? <ConnectorDetail key={`${connectorId}:${scopeKey}`} path={path} navigate={navigate} api={api} />
: kind
? <ResourcePage key={`${kind}:${scopeKey}`} path={path} kind={kind} api={api} navigate={navigate} onClientCreated={(client) => { if (subject !== null && identitySubject.current === subject) setCreatedClient(client); }} />
: snapshot && basePath(path) === "/"
? <Dashboard snapshot={snapshot} api={api} reload={() => void load()} navigate={navigate} />
: basePath(path) === "/operations"
? <Operations path={path} navigate={navigate} snapshot={snapshot} api={api} />
: basePath(path) === "/settings"
? <SettingsPage path={path} navigate={navigate} />
: <ForbiddenPanel />;
return (
<RbacProvider roles={roles}>
<a className="skip-link" href="#main-content">Skip to main content</a>
<div className={authenticated ? "app-shell" : "preauth-shell"}>
{authenticated ? <>
{navOpen ? <button type="button" className="nav-backdrop" onClick={() => closeNavigation()} aria-label="Dismiss navigation" /> : null}
<aside className={navOpen ? "sidebar sidebar-open" : "sidebar"} aria-label="Application sidebar">
{navOpen ? <button ref={navBackdropRef} type="button" className="nav-backdrop" onClick={closeNavigation} aria-label="Dismiss navigation" aria-hidden="true" tabIndex={-1} /> : null}
<aside
ref={navSidebarRef}
className={navOpen ? "sidebar sidebar-open" : "sidebar"}
id="primary-navigation-panel"
aria-label="Application navigation"
role={compactNavigation && navOpen ? "dialog" : undefined}
aria-modal={compactNavigation && navOpen ? true : undefined}
aria-hidden={compactNavigation && !navOpen ? true : undefined}
inert={compactNavigation && !navOpen}
>
<div className="sidebar-head">
<a href="/" onClick={(event) => { event.preventDefault(); navigate("/"); }}><Brand /></a>
<button type="button" className="nav-close" aria-label="Close navigation" onClick={() => closeNavigation()}>×</button>
<button ref={navCloseRef} type="button" className="nav-close" aria-label="Close navigation" onClick={closeNavigation}>×</button>
</div>
<nav aria-label="Primary navigation">
{navigation.map((group) => {
@@ -170,7 +223,7 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
</> : null}
<main className="main-content" id="main-content" tabIndex={-1}>
{authenticated ? <header className="topbar">
<button ref={navTriggerRef} type="button" className="nav-trigger" aria-label="Open navigation" aria-expanded={navOpen} onClick={() => setNavOpen(true)}><span aria-hidden="true" /><span aria-hidden="true" /><span aria-hidden="true" /></button>
<button ref={navTriggerRef} type="button" className="nav-trigger" aria-label="Open navigation" aria-expanded={navOpen} aria-controls="primary-navigation-panel" onClick={() => setNavOpen(true)}><span aria-hidden="true" /><span aria-hidden="true" /><span aria-hidden="true" /></button>
<div className="topbar-title"><p className="eyebrow">Governance control plane</p><h1>{title}</h1></div>
<div className="topbar-actions">
<button className="command-trigger" type="button" onClick={() => setCommandOpen(true)} aria-label="Open quick jump">
@@ -179,10 +232,11 @@ export function App({ api: apiProp }: { api?: ManagementApiClient }) {
<SessionMenu subject={subject} roles={roles} />
</div>
</header> : null}
{authenticated && createdClient ? <div className="notice notice-info client-created-notice" role="status"><span>Pending client {createdClient.name} created for {createdClient.project} / {createdClient.environment}.</span><a href={`/clients?onboard=${encodeURIComponent(createdClient.id)}`} onClick={(event) => { event.preventDefault(); navigate(`/clients?onboard=${encodeURIComponent(createdClient.id)}`); setCreatedClient(null); }}>Resume onboarding</a><button type="button" aria-label="Dismiss client creation notice" onClick={() => setCreatedClient(null)}>Dismiss</button></div> : null}
{content}
</main>
</div>
{authenticated ? <CommandMenu open={commandOpen} canReadAudit={canReadAudit} navigate={navigate} onClose={() => setCommandOpen(false)} /> : null}
{authenticated ? <CommandMenu open={commandOpen} api={api} canReadAudit={canReadAudit} navigate={navigate} onClose={() => setCommandOpen(false)} /> : null}
</RbacProvider>
);
}