Files
Microsoft.SelfService.Porta…/src/layout/AppShell.tsx
Torsten Brendgen 7080d659ef feat: Enhance Domains, Environments, Services, and Templates management
- Implemented dialog-based forms for adding and editing Domains and Environments.
- Added delete functionality for Domains and Environments with confirmation prompts.
- Introduced EnvironmentDetailsPage to display details of selected environments and their linked domains.
- Created EnvironmentDomainsPage for linking domains to environments.
- Enhanced ServicesPage with dialog support for adding, editing, and viewing service details.
- Updated TemplatesPage to manage templates with comprehensive form fields and validation.
- Improved type definitions in portal.ts to support new features and ensure type safety.
2026-05-15 00:05:09 +02:00

123 lines
3.4 KiB
TypeScript

import { Outlet, NavLink } from "react-router-dom";
import {
Button,
makeStyles,
shorthands,
Text,
Title2,
tokens,
} from "@fluentui/react-components";
import {
AppsListDetail24Regular,
BoxMultiple24Regular,
CloudFlow24Regular,
DatabasePlugConnectedRegular,
LinkMultiple24Regular,
Globe24Regular,
Home24Regular,
PlayCircle24Regular,
ServerMultipleRegular,
} from "@fluentui/react-icons";
const useStyles = makeStyles({
root: {
minHeight: "100vh",
display: "grid",
gridTemplateColumns: "280px minmax(0, 1fr)",
backgroundColor: tokens.colorNeutralBackground2,
color: tokens.colorNeutralForeground1,
},
sidebar: {
display: "flex",
flexDirection: "column",
gap: "20px",
backgroundColor: tokens.colorNeutralBackground1,
...shorthands.borderRight("1px", "solid", tokens.colorNeutralStroke2),
...shorthands.padding("24px", "18px"),
},
brand: {
display: "grid",
gap: "4px",
...shorthands.padding("0", "6px"),
},
nav: {
display: "grid",
gap: "6px",
},
navLink: {
textDecorationLine: "none",
},
navButton: {
width: "100%",
justifyContent: "flex-start",
},
content: {
minWidth: 0,
display: "flex",
flexDirection: "column",
},
topbar: {
height: "64px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: tokens.colorNeutralBackground1,
...shorthands.borderBottom("1px", "solid", tokens.colorNeutralStroke2),
...shorthands.padding("0", "28px"),
},
main: {
...shorthands.padding("28px"),
},
});
const links = [
{ to: "/", label: "Dashboard", icon: <Home24Regular /> },
//{ to: "/deployments", label: "Deployments", icon: <CloudFlow24Regular /> },
//{ to: "/deployment-groups", label: "Deployment Groups", icon: <ServerMultipleRegular /> },
{ to: "/domains", label: "Domains", icon: <Globe24Regular /> },
{ to: "/environment-domains", label: "Environment Domains", icon: <LinkMultiple24Regular /> },
{ to: "/environments", label: "Environments", icon: <DatabasePlugConnectedRegular /> },
//{ to: "/runbooks", label: "Runbooks", icon: <PlayCircle24Regular /> },
{ to: "/templates", label: "Templates", icon: <BoxMultiple24Regular /> },
{ to: "/services", label: "Services", icon: <AppsListDetail24Regular /> },
];
export function AppShell() {
const styles = useStyles();
return (
<div className={styles.root}>
<aside className={styles.sidebar}>
<div className={styles.brand}>
<Title2>Self Service Portal</Title2>
<Text size={200}>Core API Frontend</Text>
</div>
<nav className={styles.nav}>
{links.map((link) => (
<NavLink className={styles.navLink} end={link.to === "/"} key={link.to} to={link.to}>
{({ isActive }) => (
<Button
appearance={isActive ? "primary" : "subtle"}
className={styles.navButton}
icon={link.icon}
>
{link.label}
</Button>
)}
</NavLink>
))}
</nav>
</aside>
<section className={styles.content}>
<header className={styles.topbar}>
<Text weight="semibold">Portal workspace</Text>
<Text size={200}>API: {import.meta.env.VITE_API_BASE_URL ?? "/api"}</Text>
</header>
<main className={styles.main}>
<Outlet />
</main>
</section>
</div>
);
}