import { createSlice } from '@reduxjs/toolkit'; import { fetchKnowledgeBases, searchKnowledgeBases, createKnowledgeBase, getKnowledgeBaseById, updateKnowledgeBase, deleteKnowledgeBase, } from './knowledgeBase.thunks'; const initialState = { // List state list: { data: { items: [], total: 0, page: 1, page_size: 10, }, status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed' error: null, }, // Search state search: { data: { items: [], total: 0, page: 1, page_size: 10, keyword: '', }, status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed' error: null, }, // Current knowledge base details current: { data: null, status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed' error: null, }, // Create/update/delete operations status operations: { status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed' error: null, operationType: null, // 'create' | 'update' | 'delete' }, }; const knowledgeBaseSlice = createSlice({ name: 'knowledgeBase', initialState, reducers: { resetOperationStatus: (state) => { state.operations = { status: 'idle', error: null, operationType: null, }; }, resetCurrentKnowledgeBase: (state) => { state.current = { data: null, status: 'idle', error: null, }; }, resetSearchState: (state) => { state.search = { data: { items: [], total: 0, page: 1, page_size: 10, keyword: '', }, status: 'idle', error: null, }; }, }, extraReducers: (builder) => { builder // Fetch knowledge bases .addCase(fetchKnowledgeBases.pending, (state) => { state.list.status = 'loading'; }) .addCase(fetchKnowledgeBases.fulfilled, (state, action) => { state.list.status = 'succeeded'; state.list.data = action.payload; state.list.error = null; }) .addCase(fetchKnowledgeBases.rejected, (state, action) => { state.list.status = 'failed'; state.list.error = action.payload; }) // Search knowledge bases .addCase(searchKnowledgeBases.pending, (state, action) => { state.search.status = 'loading'; // Store the keyword for reference if (action.meta.arg.keyword) { state.search.data.keyword = action.meta.arg.keyword; } }) .addCase(searchKnowledgeBases.fulfilled, (state, action) => { state.search.status = 'succeeded'; state.search.data = action.payload; state.search.error = null; }) .addCase(searchKnowledgeBases.rejected, (state, action) => { state.search.status = 'failed'; state.search.error = action.payload; }) // Get knowledge base by ID .addCase(getKnowledgeBaseById.pending, (state) => { state.current.status = 'loading'; }) .addCase(getKnowledgeBaseById.fulfilled, (state, action) => { state.current.status = 'succeeded'; state.current.data = action.payload; state.current.error = null; }) .addCase(getKnowledgeBaseById.rejected, (state, action) => { state.current.status = 'failed'; state.current.error = action.payload; }) // Create knowledge base .addCase(createKnowledgeBase.pending, (state) => { state.operations.status = 'loading'; state.operations.operationType = 'create'; }) .addCase(createKnowledgeBase.fulfilled, (state, action) => { state.operations.status = 'succeeded'; // Don't add to list here - better to refetch the list to ensure consistency state.operations.error = null; }) .addCase(createKnowledgeBase.rejected, (state, action) => { state.operations.status = 'failed'; state.operations.error = action.payload; }) // Update knowledge base .addCase(updateKnowledgeBase.pending, (state) => { state.operations.status = 'loading'; state.operations.operationType = 'update'; }) .addCase(updateKnowledgeBase.fulfilled, (state, action) => { state.operations.status = 'succeeded'; // Update in list if present const index = state.list.data.items.findIndex((item) => item.id === action.payload.id); if (index !== -1) { state.list.data.items[index] = action.payload; } // Update in search results if present const searchIndex = state.search.data.items.findIndex((item) => item.id === action.payload.id); if (searchIndex !== -1) { state.search.data.items[searchIndex] = action.payload; } // Update current if it's the same knowledge base if (state.current.data && state.current.data.id === action.payload.id) { state.current.data = action.payload; } state.operations.error = null; }) .addCase(updateKnowledgeBase.rejected, (state, action) => { state.operations.status = 'failed'; state.operations.error = action.payload; }) // Delete knowledge base .addCase(deleteKnowledgeBase.pending, (state) => { state.operations.status = 'loading'; state.operations.operationType = 'delete'; }) .addCase(deleteKnowledgeBase.fulfilled, (state, action) => { state.operations.status = 'succeeded'; // Remove from list if present state.list.data.items = state.list.data.items.filter((item) => item.id !== action.payload); // Remove from search results if present state.search.data.items = state.search.data.items.filter((item) => item.id !== action.payload); // Reset current if it's the same knowledge base if (state.current.data && state.current.data.id === action.payload) { state.current.data = null; } state.operations.error = null; }) .addCase(deleteKnowledgeBase.rejected, (state, action) => { state.operations.status = 'failed'; state.operations.error = action.payload; }); }, }); export const { resetOperationStatus, resetCurrentKnowledgeBase, resetSearchState } = knowledgeBaseSlice.actions; const knowledgeBaseReducer = knowledgeBaseSlice.reducer; export default knowledgeBaseReducer;