Files
rack-planner/client/src/store/useRackStore.ts
T

91 lines
2.6 KiB
TypeScript
Raw Normal View History

import { create } from 'zustand';
import type { Rack, Module } from '../types';
import { apiClient } from '../api/client';
interface RackState {
racks: Rack[];
loading: boolean;
selectedModuleId: string | null;
// Fetch
fetchRacks: () => Promise<void>;
// Rack CRUD
addRack: (name: string, totalU?: number, location?: string) => Promise<Rack>;
updateRack: (id: string, data: Partial<{ name: string; totalU: number; location: string; displayOrder: number }>) => Promise<void>;
deleteRack: (id: string) => Promise<void>;
// Module CRUD (optimistic update helpers)
addModule: (rackId: string, data: Parameters<typeof apiClient.racks.addModule>[1]) => Promise<Module>;
updateModuleLocal: (moduleId: string, data: Partial<Module>) => void;
removeModuleLocal: (moduleId: string) => void;
// Selection
setSelectedModule: (id: string | null) => void;
}
export const useRackStore = create<RackState>((set, get) => ({
racks: [],
loading: false,
selectedModuleId: null,
fetchRacks: async () => {
set({ loading: true });
try {
const racks = await apiClient.racks.list();
set({ racks, loading: false });
} catch {
set({ loading: false });
throw new Error('Failed to load racks');
}
},
addRack: async (name, totalU = 42, location) => {
const rack = await apiClient.racks.create({ name, totalU, location });
set((s) => ({ racks: [...s.racks, rack].sort((a, b) => a.displayOrder - b.displayOrder) }));
return rack;
},
updateRack: async (id, data) => {
const updated = await apiClient.racks.update(id, data);
set((s) => ({
racks: s.racks
.map((r) => (r.id === id ? updated : r))
.sort((a, b) => a.displayOrder - b.displayOrder),
}));
},
deleteRack: async (id) => {
await apiClient.racks.delete(id);
set((s) => ({ racks: s.racks.filter((r) => r.id !== id) }));
},
addModule: async (rackId, data) => {
const module = await apiClient.racks.addModule(rackId, data);
set((s) => ({
racks: s.racks.map((r) =>
r.id === rackId
? { ...r, modules: [...r.modules, module].sort((a, b) => a.uPosition - b.uPosition) }
: r
),
}));
return module;
},
updateModuleLocal: (moduleId, data) => {
set((s) => ({
racks: s.racks.map((r) => ({
...r,
modules: r.modules.map((m) => (m.id === moduleId ? { ...m, ...data } : m)),
})),
}));
},
removeModuleLocal: (moduleId) => {
set((s) => ({
racks: s.racks.map((r) => ({
...r,
modules: r.modules.filter((m) => m.id !== moduleId),
})),
}));
},
setSelectedModule: (id) => set({ selectedModuleId: id }),
}));