107 lines
2.4 KiB
TypeScript
107 lines
2.4 KiB
TypeScript
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
|
|
|
// Filter value can be a simple string or an object with operator and value
|
|
export interface FilterValue {
|
|
operator: string;
|
|
value: string;
|
|
}
|
|
|
|
export type FilterField = string | FilterValue;
|
|
|
|
export interface AdvancedSearchFilters {
|
|
[field: string]: FilterField | undefined;
|
|
}
|
|
|
|
export type FetchStatus = "idle" | "loading" | "succeeded" | "failed";
|
|
|
|
export interface AdvancedSearchState {
|
|
filters: AdvancedSearchFilters;
|
|
pagination: {
|
|
page: number;
|
|
limit: number;
|
|
};
|
|
sort?: {
|
|
field: string;
|
|
order: "asc" | "desc";
|
|
};
|
|
status: FetchStatus;
|
|
error: string | null;
|
|
}
|
|
|
|
const initialState: AdvancedSearchState = {
|
|
filters: {},
|
|
pagination: {
|
|
page: 1,
|
|
limit: 10,
|
|
},
|
|
status: "idle",
|
|
error: null,
|
|
};
|
|
|
|
const advancedSearchSlice = createSlice({
|
|
name: "advancedSearch",
|
|
initialState,
|
|
reducers: {
|
|
setFilters: (state, action: PayloadAction<AdvancedSearchFilters>) => {
|
|
state.filters = action.payload;
|
|
// Reset to page 1 when filters change
|
|
state.pagination.page = 1;
|
|
},
|
|
updateFilter: (
|
|
state,
|
|
action: PayloadAction<{ field: string; value: FilterField | undefined }>
|
|
) => {
|
|
const { field, value } = action.payload;
|
|
if (value === undefined || value === "") {
|
|
delete state.filters[field];
|
|
} else {
|
|
state.filters[field] = value;
|
|
}
|
|
// Reset to page 1 when a filter changes
|
|
state.pagination.page = 1;
|
|
},
|
|
clearFilters: state => {
|
|
state.filters = {};
|
|
state.pagination.page = 1;
|
|
},
|
|
setPagination: (
|
|
state,
|
|
action: PayloadAction<{ page: number; limit: number }>
|
|
) => {
|
|
state.pagination = action.payload;
|
|
},
|
|
setSort: (
|
|
state,
|
|
action: PayloadAction<
|
|
{ field: string; order: "asc" | "desc" } | undefined
|
|
>
|
|
) => {
|
|
state.sort = action.payload;
|
|
},
|
|
setStatus: (state, action: PayloadAction<FetchStatus>) => {
|
|
state.status = action.payload;
|
|
if (action.payload === "loading") {
|
|
state.error = null;
|
|
}
|
|
},
|
|
setError: (state, action: PayloadAction<string | null>) => {
|
|
state.error = action.payload;
|
|
if (action.payload) {
|
|
state.status = "failed";
|
|
}
|
|
},
|
|
},
|
|
});
|
|
|
|
export const {
|
|
setFilters,
|
|
updateFilter,
|
|
clearFilters,
|
|
setPagination,
|
|
setSort,
|
|
setStatus,
|
|
setError,
|
|
} = advancedSearchSlice.actions;
|
|
|
|
export default advancedSearchSlice.reducer;
|