feat(client): storage tab on the admin page

This commit is contained in:
jubnl
2026-08-20 14:19:37 +02:00
parent 462c5973ef
commit 584fe5a822
2 changed files with 26 additions and 1 deletions
+19
View File
@@ -69,6 +69,10 @@ vi.mock('../components/Admin/DefaultUserSettingsTab', () => ({
default: () => <div data-testid="default-user-settings" />,
}));
vi.mock('../components/Admin/storage/AdminStoragePanel', () => ({
default: () => <div data-testid="admin-storage-panel" />,
}));
beforeEach(() => {
resetAllStores();
});
@@ -1631,4 +1635,19 @@ describe('AdminPage', () => {
expect(screen.queryByText('Files')).not.toBeInTheDocument();
});
});
it('FE-PAGE-ADMIN-STOR-001: the Storage tab renders the storage panel', async () => {
seedStore(useAuthStore, { isAuthenticated: true, user: buildAdmin() });
render(<AdminPage />);
const tab = await screen.findByRole('button', { name: /^storage$/i });
fireEvent.click(tab);
expect(screen.getByTestId('admin-storage-panel')).toBeInTheDocument();
});
it('FE-PAGE-ADMIN-STOR-002: managed mode hides the Storage tab (hoster-level config)', async () => {
seedStore(useAuthStore, { isAuthenticated: true, user: buildAdmin(), managed: true });
render(<AdminPage />);
await screen.findByRole('button', { name: /^users$/i });
expect(screen.queryByRole('button', { name: /^storage$/i })).not.toBeInTheDocument();
});
});
+7 -1
View File
@@ -12,7 +12,8 @@ import PackingTemplateManager from '../components/Admin/PackingTemplateManager'
import AuditLogPanel from '../components/Admin/AuditLogPanel'
import AdminMcpTokensPanel from '../components/Admin/AdminMcpTokensPanel'
import AdminPluginsPanel from '../components/Admin/AdminPluginsPanel'
import { Users, Map, Briefcase, Shield, FileText, SlidersHorizontal, UserCog, Puzzle, Blocks, Settings as SettingsIcon, Bell, Database, ScrollText, KeyRound, GitBranch, Bug } from 'lucide-react'
import AdminStoragePanel from '../components/Admin/storage/AdminStoragePanel'
import { Users, Map, Briefcase, Shield, FileText, SlidersHorizontal, UserCog, Puzzle, Blocks, Settings as SettingsIcon, Bell, Database, ScrollText, KeyRound, GitBranch, Bug, HardDrive } from 'lucide-react'
import PageSidebar, { type PageSidebarTab } from '../components/Layout/PageSidebar'
import { useAdmin } from './admin/useAdmin'
import AdminUpdateBanner from './admin/AdminUpdateBanner'
@@ -55,6 +56,9 @@ function AdminPageDesktop(): React.ReactElement {
{ id: 'settings', label: t('admin.tabs.settings'), icon: SettingsIcon, group: gConfig },
{ id: 'addons', label: t('admin.tabs.addons'), icon: Puzzle, group: gConfig },
{ id: 'plugins', label: t('admin.tabs.plugins'), icon: Blocks, group: gConfig },
// Storage backends and their credentials are hoster-level configuration —
// the server refuses the whole surface in managed mode (MANAGED_FORBIDDEN).
...(managed ? [] : [{ id: 'storage', label: t('admin.tabs.storage'), icon: HardDrive, group: gConfig }]),
{ id: 'notifications', label: t('admin.tabs.notifications'), icon: Bell, group: gIntegration },
...(mcpEnabled ? [{ id: 'mcp-tokens', label: t('admin.tabs.mcpTokens'), icon: KeyRound, group: gIntegration }] : []),
// Releases and update cadence belong to whoever operates the install.
@@ -180,6 +184,8 @@ function AdminPageDesktop(): React.ReactElement {
{activeTab === 'plugins' && <AdminPluginsPanel />}
{activeTab === 'storage' && <AdminStoragePanel />}
{activeTab === 'github' && <GitHubPanel isPrerelease={updateInfo?.is_prerelease ?? false} />}
{activeTab === 'defaults' && <DefaultUserSettingsTab />}