Skip to content

Instantly share code, notes, and snippets.

@loraxx753
Last active March 20, 2023 17:12
Show Gist options
  • Save loraxx753/46661327b5c92408e64c4d8be7c2ba5b to your computer and use it in GitHub Desktop.
Save loraxx753/46661327b5c92408e64c4d8be7c2ba5b to your computer and use it in GitHub Desktop.
import { createAction, createSlice, PayloadAction } from '@reduxjs/toolkit';
interface Entity {
id: string;
type: string;
}
interface EntityState<T extends Entity> {
entities: T[];
}
interface AddEntityPayload<T extends Entity> {
entity: T;
}
interface UpdateEntityPayload<T extends Entity> {
id: string;
entity: Partial<T>;
}
interface DeleteEntityPayload {
id: string;
}
export const createEntitySlice = <T extends Entity>(name: string) => {
const initialState: EntityState<T> = {
entities: [],
};
const addEntity = createAction<AddEntityPayload<T>>(`${name}/add`);
const updateEntity = createAction<UpdateEntityPayload<T>>(`${name}/update`);
const deleteEntity = createAction<DeleteEntityPayload>(`${name}/delete`);
const entitySlice = createSlice({
name,
initialState,
reducers: {
[addEntity.type]: (state, action: PayloadAction<AddEntityPayload<T>>) => {
state.entities.push(action.payload.entity);
},
[updateEntity.type]: (state, action: PayloadAction<UpdateEntityPayload<T>>) => {
const { id, entity } = action.payload;
const index = state.entities.findIndex((e) => e.id === id);
if (index !== -1) {
state.entities[index] = { ...state.entities[index], ...entity };
}
},
[deleteEntity.type]: (state, action: PayloadAction<DeleteEntityPayload>) => {
const index = state.entities.findIndex((e) => e.id === action.payload.id);
if (index !== -1) {
state.entities.splice(index, 1);
}
},
},
});
const actions = { addEntity, updateEntity, deleteEntity };
const { reducer } = entitySlice;
return { actions, reducer };
};
import { createEntitySlice } from './createEntitySlice';
/* These will be created in the customer-maintance-app page when they're needed.
interface Address {
id: string;
type: string;
address: string;
preferred: boolean;
}
const addressSlice = createEntitySlice<Address>('address');
export const { addEntity: addAddress, updateEntity: updateAddress, deleteEntity: deleteAddress } = addressSlice.actions;
export const addressReducer = addressSlice.reducer;
interface Phone {
id: string;
type: string;
number: string;
mobile: boolean;
}
const phoneSlice = createEntitySlice<Phone>('phone');
export const { addEntity: addPhone, updateEntity: updatePhone, deleteEntity: deletePhone } = phoneSlice.actions;
export const phoneReducer = phoneSlice.reducer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment