Files
SRCmail/stores/admin-tab-store.ts
T
Bernd Rodler 13ec05da83 feat: P2.9 VNCtalk + P2.10 Collabora + P2.11 Calendar Enhancements + P2.13 VNCdirectory Admin
- P2.9: VNCtalk video meeting — create/update meeting from event modal,
  'Join Meeting' link in event detail. Admin config vnctalkServerUrl.
- P2.10: Collabora online editing — 'Edit with Collabora' for office files,
  WOPI discovery + edit URL. Admin config collaboraServerUrl.
- P2.11: Calendar enhancements — clickable links in descriptions,
  participant contact popover, Reply/Reply All from event, timezone picker,
  map links for locations.
- P2.13: VNCdirectory IDP admin panel — Connection, SAML/IDP, LDAP,
  Authentication, Federated Apps configuration. Secret masking on display.
2026-08-07 13:38:12 +02:00

44 lines
1.1 KiB
TypeScript

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
export const ADMIN_TABS = [
'dashboard',
'settings',
'branding',
'auth',
'vncdirectory',
'policy',
'ai-policy',
'plugins',
'themes',
'marketplace',
'version',
'telemetry',
'logs',
] as const;
export type AdminTabId = typeof ADMIN_TABS[number];
export function isAdminTab(value: string | null | undefined): value is AdminTabId {
return typeof value === 'string' && (ADMIN_TABS as readonly string[]).includes(value);
}
interface AdminTabState {
activeTab: AdminTabId;
setActiveTab: (tab: AdminTabId) => void;
}
// Tab state lives in client memory + localStorage. Sidebar clicks update
// state (no URL navigation) so React can commit the transition immediately,
// avoiding the dev-mode "Rendering…" hang we saw when each tab was its own
// route or distinguished by ?tab= search param.
export const useAdminTabStore = create<AdminTabState>()(
persist(
(set) => ({
activeTab: 'dashboard',
setActiveTab: (tab) => set({ activeTab: tab }),
}),
{ name: 'admin_active_tab' },
),
);