createListSlices.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
  2. import {
  3. EntitiesState,
  4. FiltersState,
  5. PaginationState,
  6. SelectionState,
  7. UIState,
  8. } from './type.model';
  9. export function createEntityListSlices<T, F extends object>(
  10. namespace: string,
  11. fetchThunk,
  12. deleteThunk,
  13. extraReducersForFilter?: (builder) => void,
  14. initialFilter?: F
  15. ) {
  16. const entitiesSlice = createSlice({
  17. name: `${namespace}/entities`,
  18. initialState: { data: [], total: 0 } as EntitiesState<T>,
  19. reducers: {},
  20. extraReducers(builder) {
  21. builder.addCase(
  22. fetchThunk.fulfilled,
  23. (state, action: PayloadAction<{ data: T[]; total: number }>) => {
  24. state.data = action.payload.data as unknown as Draft<T>[];
  25. state.total = action.payload.total;
  26. // return {
  27. // ...state,
  28. // data: action.payload.data,
  29. // total: action.payload.total,
  30. // };
  31. }
  32. );
  33. builder.addCase(
  34. deleteThunk.fulfilled,
  35. (state, action: PayloadAction<string[]>) => {
  36. state.data = state.data.filter(
  37. (item) => !action.payload.includes((item as { id: string }).id)
  38. );
  39. }
  40. );
  41. },
  42. });
  43. const filtersSlice = createSlice({
  44. name: `${namespace}/filters`,
  45. initialState: initialFilter as FiltersState<F>,
  46. reducers: {
  47. setFilters(state, action: PayloadAction<Partial<FiltersState<F>>>) {
  48. return { ...state, ...action.payload };
  49. },
  50. resetFilters() {
  51. return {} as FiltersState<F>;
  52. },
  53. },
  54. extraReducers: extraReducersForFilter,
  55. });
  56. const paginationSlice = createSlice({
  57. name: `${namespace}/pagination`,
  58. initialState: { page: 1, pageSize: 10 } as PaginationState,
  59. reducers: {
  60. setPage(state, action: PayloadAction<number>) {
  61. state.page = action.payload;
  62. },
  63. setPageSize(state, action: PayloadAction<number>) {
  64. state.pageSize = action.payload;
  65. },
  66. },
  67. });
  68. const selectionSlice = createSlice({
  69. name: `${namespace}/selection`,
  70. initialState: { selectedIds: [] } as SelectionState,
  71. reducers: {
  72. setSelectedIds(state, action: PayloadAction<string[]>) {
  73. console.log('Setting selected IDs:', action.payload);
  74. state.selectedIds = action.payload;
  75. },
  76. clearSelection(state) {
  77. state.selectedIds = [];
  78. },
  79. },
  80. });
  81. const uiSlice = createSlice({
  82. name: `${namespace}/ui`,
  83. initialState: { loading: false, error: null } as UIState,
  84. reducers: {},
  85. extraReducers(builder) {
  86. builder.addCase(fetchThunk.pending, (state) => {
  87. state.loading = true;
  88. state.error = null;
  89. });
  90. builder.addCase(fetchThunk.fulfilled, (state) => {
  91. state.loading = false;
  92. });
  93. builder.addCase(fetchThunk.rejected, (state, action) => {
  94. state.loading = false;
  95. state.error = action.error.message ?? 'Unknown error';
  96. });
  97. },
  98. });
  99. return {
  100. entitiesSlice,
  101. filtersSlice,
  102. paginationSlice,
  103. selectionSlice,
  104. uiSlice,
  105. };
  106. }