168 lines
5.1 KiB
TypeScript
168 lines
5.1 KiB
TypeScript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
|
|
interface UIState {
|
|
sidebarOpen: boolean;
|
|
sidebarCollapsed: boolean;
|
|
searchOpen: boolean;
|
|
filterPanelOpen: boolean;
|
|
createTodoDialogOpen: boolean;
|
|
editTodoDialogOpen: boolean;
|
|
deleteTodoDialogOpen: boolean;
|
|
batchActionsOpen: boolean;
|
|
settingsDialogOpen: boolean;
|
|
aiChatOpen: boolean;
|
|
importDialogOpen: boolean;
|
|
currentEditingTodo: string | null;
|
|
currentDeletingTodos: string[];
|
|
notifications: Array<{
|
|
id: string;
|
|
message: string;
|
|
type: 'info' | 'success' | 'warning' | 'error';
|
|
timestamp: number;
|
|
read: boolean;
|
|
}>;
|
|
isOnline: boolean;
|
|
lastSync: string | null;
|
|
}
|
|
|
|
const initialState: UIState = {
|
|
sidebarOpen: true,
|
|
sidebarCollapsed: false,
|
|
searchOpen: false,
|
|
filterPanelOpen: false,
|
|
createTodoDialogOpen: false,
|
|
editTodoDialogOpen: false,
|
|
deleteTodoDialogOpen: false,
|
|
batchActionsOpen: false,
|
|
settingsDialogOpen: false,
|
|
aiChatOpen: false,
|
|
importDialogOpen: false,
|
|
currentEditingTodo: null,
|
|
currentDeletingTodos: [],
|
|
notifications: [],
|
|
isOnline: true,
|
|
lastSync: null,
|
|
};
|
|
|
|
const uiSlice = createSlice({
|
|
name: 'ui',
|
|
initialState,
|
|
reducers: {
|
|
toggleSidebar: (state) => {
|
|
state.sidebarOpen = !state.sidebarOpen;
|
|
},
|
|
setSidebarOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.sidebarOpen = action.payload;
|
|
},
|
|
toggleSidebarCollapsed: (state) => {
|
|
state.sidebarCollapsed = !state.sidebarCollapsed;
|
|
},
|
|
setSidebarCollapsed: (state, action: PayloadAction<boolean>) => {
|
|
state.sidebarCollapsed = action.payload;
|
|
},
|
|
setSearchOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.searchOpen = action.payload;
|
|
},
|
|
setFilterPanelOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.filterPanelOpen = action.payload;
|
|
},
|
|
setCreateTodoDialogOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.createTodoDialogOpen = action.payload;
|
|
},
|
|
setEditTodoDialogOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.editTodoDialogOpen = action.payload;
|
|
},
|
|
setDeleteTodoDialogOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.deleteTodoDialogOpen = action.payload;
|
|
},
|
|
setBatchActionsOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.batchActionsOpen = action.payload;
|
|
},
|
|
setSettingsDialogOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.settingsDialogOpen = action.payload;
|
|
},
|
|
setAiChatOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.aiChatOpen = action.payload;
|
|
},
|
|
setImportDialogOpen: (state, action: PayloadAction<boolean>) => {
|
|
state.importDialogOpen = action.payload;
|
|
},
|
|
setCurrentEditingTodo: (state, action: PayloadAction<string | null>) => {
|
|
state.currentEditingTodo = action.payload;
|
|
},
|
|
setCurrentDeletingTodos: (state, action: PayloadAction<string[]>) => {
|
|
state.currentDeletingTodos = action.payload;
|
|
},
|
|
addNotification: (state, action: PayloadAction<Omit<UIState['notifications'][0], 'id' | 'timestamp' | 'read'>>) => {
|
|
const notification = {
|
|
...action.payload,
|
|
id: Date.now().toString(),
|
|
timestamp: Date.now(),
|
|
read: false,
|
|
};
|
|
state.notifications.unshift(notification);
|
|
},
|
|
markNotificationAsRead: (state, action: PayloadAction<string>) => {
|
|
const notification = state.notifications.find(n => n.id === action.payload);
|
|
if (notification) {
|
|
notification.read = true;
|
|
}
|
|
},
|
|
markAllNotificationsAsRead: (state) => {
|
|
state.notifications.forEach(n => n.read = true);
|
|
},
|
|
removeNotification: (state, action: PayloadAction<string>) => {
|
|
state.notifications = state.notifications.filter(n => n.id !== action.payload);
|
|
},
|
|
clearNotifications: (state) => {
|
|
state.notifications = [];
|
|
},
|
|
setOnlineStatus: (state, action: PayloadAction<boolean>) => {
|
|
state.isOnline = action.payload;
|
|
},
|
|
setLastSync: (state, action: PayloadAction<string>) => {
|
|
state.lastSync = action.payload;
|
|
},
|
|
closeAllDialogs: (state) => {
|
|
state.createTodoDialogOpen = false;
|
|
state.editTodoDialogOpen = false;
|
|
state.deleteTodoDialogOpen = false;
|
|
state.settingsDialogOpen = false;
|
|
state.aiChatOpen = false;
|
|
state.importDialogOpen = false;
|
|
state.filterPanelOpen = false;
|
|
state.searchOpen = false;
|
|
state.batchActionsOpen = false;
|
|
state.currentEditingTodo = null;
|
|
state.currentDeletingTodos = [];
|
|
},
|
|
},
|
|
});
|
|
|
|
export const {
|
|
toggleSidebar,
|
|
setSidebarOpen,
|
|
toggleSidebarCollapsed,
|
|
setSidebarCollapsed,
|
|
setSearchOpen,
|
|
setFilterPanelOpen,
|
|
setCreateTodoDialogOpen,
|
|
setEditTodoDialogOpen,
|
|
setDeleteTodoDialogOpen,
|
|
setBatchActionsOpen,
|
|
setSettingsDialogOpen,
|
|
setAiChatOpen,
|
|
setImportDialogOpen,
|
|
setCurrentEditingTodo,
|
|
setCurrentDeletingTodos,
|
|
addNotification,
|
|
markNotificationAsRead,
|
|
markAllNotificationsAsRead,
|
|
removeNotification,
|
|
clearNotifications,
|
|
setOnlineStatus,
|
|
setLastSync,
|
|
closeAllDialogs,
|
|
} = uiSlice.actions;
|
|
|
|
export default uiSlice.reducer; |