refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics

- Add Workspace domain (entity, repository, service, handler, DTO)
- Add multi-tenant K8s client with tenant binding and quota management
- Add K8s diagnostics client (instance diagnostics)
- Add authorization middleware (authz package)
- Restructure frontend to feature-based architecture (features/)
- Add User Management page in configuration
- Add AccessDenied page and route guards
- Refactor shared components (form inputs, layout, UI)
- Update Tailwind config for new design system
- Add comprehensive documentation (docs/, tasks/, plans)
- Improve cluster service with better kubeconfig handling
- Add tests for crypto, config, helm client, tenant binding
This commit is contained in:
Ivan087
2026-05-12 16:15:14 +08:00
parent c5e51ed069
commit 7f238a3168
172 changed files with 15703 additions and 3162 deletions

View File

@ -17,7 +17,7 @@ interface SidebarNavProps {
}
export default function SidebarNav({ items = [] as NavItem[], isOpen = true, onClose }: SidebarNavProps) {
const [expandedKeys, setExpandedKeys] = useState<Set<string>>(new Set(["configuration", "monitoring", "artifact", "cluster"]));
const [expandedKeys, setExpandedKeys] = useState<Set<string>>(new Set(["setup"]));
const toggleExpand = (key: string) => {
setExpandedKeys((prev) => {
@ -55,8 +55,8 @@ export default function SidebarNav({ items = [] as NavItem[], isOpen = true, onC
onClick={() => handleItemClick(item, hasChildren)}
className={`w-full text-left flex items-center gap-2 px-3 py-2 rounded-xl text-sm font-medium transition-colors duration-200 ${
item.active
? "bg-brand-accent/15 text-primary border border-brand-accent/40 shadow-glow"
: "text-secondary hover:text-primary hover:bg-dark-elevated/70"
? "bg-blue-50 text-blue-700 border border-blue-200 shadow-sm"
: "text-slate-600 hover:text-slate-950 hover:bg-slate-100"
}`}
style={{ paddingLeft: `${12 + level * 16}px` }}
>
@ -93,22 +93,22 @@ export default function SidebarNav({ items = [] as NavItem[], isOpen = true, onC
<aside
className={`
fixed md:static inset-y-0 left-0 z-50 md:z-0
flex flex-col w-64 sm:w-72 md:w-60 xl:w-64 bg-dark-lighter/85 backdrop-blur-xl border-r border-dark-border/80 shadow-soft
flex flex-col w-64 sm:w-72 md:w-60 xl:w-64 bg-white/95 backdrop-blur-xl border-r border-slate-200 shadow-soft
transform transition-transform duration-300 ease-in-out
${isOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"}
`}
>
{/* Header */}
<div className="flex items-center justify-between px-4 py-4 border-b border-dark-border/70">
<div className="flex items-center justify-between px-4 py-4 border-b border-slate-200">
<div className="flex items-center gap-2">
<LayoutDashboard className="w-5 h-5 text-brand-accent" />
<span className="text-sm font-semibold text-secondary tracking-wide">Console</span>
<LayoutDashboard className="w-5 h-5 text-blue-600" />
<span className="text-sm font-semibold text-slate-700 tracking-wide">Operations</span>
</div>
{/* 移动端关闭按钮 */}
{onClose && (
<button
onClick={onClose}
className="md:hidden p-1.5 rounded-lg hover:bg-dark-elevated/70 text-secondary hover:text-primary transition"
className="md:hidden p-1.5 rounded-lg hover:bg-slate-100 text-slate-500 hover:text-slate-900 transition"
aria-label="关闭菜单"
>
<X className="w-5 h-5" />
@ -122,8 +122,8 @@ export default function SidebarNav({ items = [] as NavItem[], isOpen = true, onC
</nav>
{/* Footer */}
<div className="p-3 text-xs text-muted border-t border-dark-border/70">
© {new Date().getFullYear()} OCDP
<div className="p-3 text-xs text-muted border-t border-slate-200">
OCDP · {new Date().getFullYear()}
</div>
</aside>
</>