feat(portal): implement two-tier AppShell header (fix top-left wrapping) and interactive Storybook workbench

Browse Source
This commit is contained in:
Yin Kou committed 2026-11-07 00:17:06 +08:00
1 parent 4ca86da55f
commit 6b589fa62a
11 files changed
+935 -178

No files matched your search

+13 -3
View File
@@ -5,12 +5,16 @@ import { ServiceCard } from './components/ServiceCard';
import { SshShelf } from './components/SshShelf'; import { SshShelf } from './components/SshShelf';
import { CommandPalette } from './components/CommandPalette'; import { CommandPalette } from './components/CommandPalette';
import { AgyTerminalModal } from './components/AgyTerminalModal'; import { AgyTerminalModal } from './components/AgyTerminalModal';
import { StorybookWorkbench } from './components/StorybookWorkbench';
import { LAYOUT_PRESETS } from './design-system/tokens';
import type { ServiceGroup } from './types/telemetry'; import type { ServiceGroup } from './types/telemetry';
export const App: React.FC = () => { export const App: React.FC = () => {
const { const {
telemetry, telemetry,
toast, toast,
viewMode,
layoutPreset,
fetchTelemetry, fetchTelemetry,
setShowCmdPalette, setShowCmdPalette,
getEffectiveMode, getEffectiveMode,
@@ -41,6 +45,8 @@ export const App: React.FC = () => {
return '443 免端口 HTTPS 直达 (*.961504.xyz)'; return '443 免端口 HTTPS 直达 (*.961504.xyz)';
}, [getEffectiveMode, routeMode]); }, [getEffectiveMode, routeMode]);
const gridClass = LAYOUT_PRESETS[layoutPreset]?.gridClass || LAYOUT_PRESETS['homepage-3col'].gridClass;
const serviceGroups = useMemo<ServiceGroup[]>(() => { const serviceGroups = useMemo<ServiceGroup[]>(() => {
const t = telemetry; const t = telemetry;
return [ return [
@@ -176,10 +182,13 @@ export const App: React.FC = () => {
</div> </div>
)} )}
{/* 1. Top Utility & System Resources Ribbon */} {/* 1. Standard Two-Tier AppShell Header & Telemetry Subheader */}
<TopRibbon /> <TopRibbon />
{/* 2. Main Categorized 3-Column Rows */} {/* 2. View Switch: Dashboard vs Storybook Workbench */}
{viewMode === 'storybook' ? (
<StorybookWorkbench />
) : (
<main className="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-7"> <main className="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-7">
{serviceGroups.map((group) => ( {serviceGroups.map((group) => (
<section key={group.title} className="space-y-3"> <section key={group.title} className="space-y-3">
@@ -208,7 +217,7 @@ export const App: React.FC = () => {
)} )}
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className={`grid ${gridClass}`}>
{group.items.map((card) => ( {group.items.map((card) => (
<ServiceCard key={card.id} card={card} /> <ServiceCard key={card.id} card={card} />
))} ))}
@@ -219,6 +228,7 @@ export const App: React.FC = () => {
{/* 3. Bottom SSH Quick Copy & Maintenance Shelf */} {/* 3. Bottom SSH Quick Copy & Maintenance Shelf */}
<SshShelf /> <SshShelf />
</main> </main>
)}
{/* 4. Global Cmd+K Command Palette */} {/* 4. Global Cmd+K Command Palette */}
<CommandPalette /> <CommandPalette />