143 lines
4.1 KiB
TypeScript
143 lines
4.1 KiB
TypeScript
import { create } from 'zustand';
|
|
|
|
import type {
|
|
ReviewGptConfig,
|
|
ReviewRow,
|
|
ReviewSessionPayload,
|
|
} from '@/services/reviewEditorService';
|
|
|
|
export type ReviewBookState = {
|
|
enabled: boolean;
|
|
loading: boolean;
|
|
error: string;
|
|
baseUrl: string;
|
|
sessionId: string | null;
|
|
reviewRoot?: string;
|
|
version?: string;
|
|
rows: ReviewRow[];
|
|
session: ReviewSessionPayload | null;
|
|
gptConfig: ReviewGptConfig | null;
|
|
selectedRowId: string;
|
|
};
|
|
|
|
type ReviewModeStore = {
|
|
activeBookKey: string | null;
|
|
isPanelVisible: boolean;
|
|
isPanelPinned: boolean;
|
|
panelWidth: string;
|
|
panelHeight: string;
|
|
books: Record<string, ReviewBookState>;
|
|
getBookState: (bookKey: string | null) => ReviewBookState | null;
|
|
setActiveBookKey: (bookKey: string | null) => void;
|
|
setPanelVisible: (visible: boolean) => void;
|
|
togglePanelPin: () => void;
|
|
setPanelWidth: (width: string) => void;
|
|
setPanelHeight: (height: string) => void;
|
|
setBookLoading: (bookKey: string, loading: boolean) => void;
|
|
setBookError: (bookKey: string, error: string) => void;
|
|
setBookEnabled: (bookKey: string, enabled: boolean) => void;
|
|
setBookData: (
|
|
bookKey: string,
|
|
data: Partial<Omit<ReviewBookState, 'enabled' | 'loading' | 'error'>>,
|
|
) => void;
|
|
selectRow: (bookKey: string, rowId: string) => void;
|
|
updateRow: (bookKey: string, row: ReviewRow) => void;
|
|
clearBook: (bookKey: string) => void;
|
|
};
|
|
|
|
const emptyBookState = (): ReviewBookState => ({
|
|
enabled: false,
|
|
loading: false,
|
|
error: '',
|
|
baseUrl: '',
|
|
sessionId: null,
|
|
rows: [],
|
|
session: null,
|
|
gptConfig: null,
|
|
selectedRowId: '',
|
|
});
|
|
|
|
const withBookState = (
|
|
books: Record<string, ReviewBookState>,
|
|
bookKey: string,
|
|
patch: Partial<ReviewBookState>,
|
|
) => ({
|
|
...books,
|
|
[bookKey]: {
|
|
...(books[bookKey] || emptyBookState()),
|
|
...patch,
|
|
},
|
|
});
|
|
|
|
export const useReviewModeStore = create<ReviewModeStore>((set, get) => ({
|
|
activeBookKey: null,
|
|
isPanelVisible: false,
|
|
isPanelPinned: false,
|
|
panelWidth: '32%',
|
|
panelHeight: '68vh',
|
|
books: {},
|
|
getBookState: (bookKey) => (bookKey ? get().books[bookKey] || null : null),
|
|
setActiveBookKey: (bookKey) => set({ activeBookKey: bookKey }),
|
|
setPanelVisible: (visible) => set({ isPanelVisible: visible }),
|
|
togglePanelPin: () => set((state) => ({ isPanelPinned: !state.isPanelPinned })),
|
|
setPanelWidth: (width) => set({ panelWidth: width }),
|
|
setPanelHeight: (height) => set({ panelHeight: height }),
|
|
setBookLoading: (bookKey, loading) =>
|
|
set((state) => ({
|
|
books: withBookState(state.books, bookKey, loading ? { loading, error: '' } : { loading }),
|
|
})),
|
|
setBookError: (bookKey, error) =>
|
|
set((state) => ({
|
|
books: withBookState(state.books, bookKey, { error, loading: false }),
|
|
})),
|
|
setBookEnabled: (bookKey, enabled) =>
|
|
set((state) => ({
|
|
activeBookKey: enabled
|
|
? bookKey
|
|
: state.activeBookKey === bookKey
|
|
? null
|
|
: state.activeBookKey,
|
|
isPanelVisible: enabled
|
|
? true
|
|
: state.activeBookKey === bookKey
|
|
? false
|
|
: state.isPanelVisible,
|
|
books: withBookState(state.books, bookKey, { enabled }),
|
|
})),
|
|
setBookData: (bookKey, data) =>
|
|
set((state) => ({
|
|
books: withBookState(state.books, bookKey, {
|
|
...data,
|
|
loading: false,
|
|
error: '',
|
|
}),
|
|
})),
|
|
selectRow: (bookKey, rowId) =>
|
|
set((state) => ({
|
|
activeBookKey: bookKey,
|
|
isPanelVisible: true,
|
|
books: withBookState(state.books, bookKey, {
|
|
selectedRowId: rowId,
|
|
}),
|
|
})),
|
|
updateRow: (bookKey, row) =>
|
|
set((state) => {
|
|
const current = state.books[bookKey] || emptyBookState();
|
|
return {
|
|
books: withBookState(state.books, bookKey, {
|
|
rows: current.rows.map((item) => (item.id === row.id ? row : item)),
|
|
}),
|
|
};
|
|
}),
|
|
clearBook: (bookKey) =>
|
|
set((state) => {
|
|
const books = { ...state.books };
|
|
delete books[bookKey];
|
|
return {
|
|
books,
|
|
activeBookKey: state.activeBookKey === bookKey ? null : state.activeBookKey,
|
|
isPanelVisible: state.activeBookKey === bookKey ? false : state.isPanelVisible,
|
|
};
|
|
}),
|
|
}));
|