Skip to content
File

Blob: src/client/stores/workspace-directory.ts

typescript65 lines
1import { create } from "zustand";
2import type { MemberWorkspaceRow } from "./db/bland-db";
3 
4export interface WorkspaceDirectoryState {
5 workspaces: MemberWorkspaceRow[];
6}
7 
8const initialState: WorkspaceDirectoryState = {
9 workspaces: [],
10};
11 
12export const useWorkspaceDirectoryStore = create<WorkspaceDirectoryState>(() => initialState);
13 
14export function applyWorkspaceDirectoryProjection(workspaces: MemberWorkspaceRow[]): void {
15 useWorkspaceDirectoryStore.setState({ workspaces }, true);
16}
17 
18export function resetWorkspaceDirectoryProjection(): void {
19 useWorkspaceDirectoryStore.setState(initialState, true);
20}
21 
22export function selectMemberWorkspaces(state: WorkspaceDirectoryState): MemberWorkspaceRow[] {
23 return state.workspaces;
24}
25 
26export function selectMemberWorkspaceCount(state: WorkspaceDirectoryState): number {
27 return state.workspaces.length;
28}
29 
30export function selectWorkspaceBySlug(state: WorkspaceDirectoryState, slug: string): MemberWorkspaceRow | null {
31 return state.workspaces.find((w) => w.slug === slug) ?? null;
32}
33 
34export function selectWorkspaceById(state: WorkspaceDirectoryState, id: string): MemberWorkspaceRow | null {
35 return state.workspaces.find((w) => w.id === id) ?? null;
36}
37 
38/**
39 * Root-redirect / home-slug preference. Prefers the last-visited workspace
40 * when the caller still has membership; falls back to the first listed
41 * workspace. Returns null when the caller has no member workspaces.
42 */
43export function selectFirstMemberSlug(
44 state: WorkspaceDirectoryState,
45 lastVisitedWorkspaceId: string | null,
46): string | null {
47 if (lastVisitedWorkspaceId) {
48 const match = state.workspaces.find((w) => w.id === lastVisitedWorkspaceId);
49 if (match) return match.slug;
50 }
51 return state.workspaces[0]?.slug ?? null;
52}
53 
54export function useMemberWorkspaces(): MemberWorkspaceRow[] {
55 return useWorkspaceDirectoryStore(selectMemberWorkspaces);
56}
57 
58export function useMemberWorkspaceCount(): number {
59 return useWorkspaceDirectoryStore(selectMemberWorkspaceCount);
60}
61 
62export function useWorkspaceBySlug(slug: string | null | undefined): MemberWorkspaceRow | null {
63 return useWorkspaceDirectoryStore((s) => (slug ? selectWorkspaceBySlug(s, slug) : null));
64}