93 lines
2.7 KiB
JavaScript
93 lines
2.7 KiB
JavaScript
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
|
import { unit as unitApi } from '../api';
|
|
import authAutomat, {
|
|
AUTH_COMPANY_CHANGED,
|
|
AUTH_LOGGED_OUT,
|
|
AUTH_SESSION_ESTABLISHED,
|
|
} from '../automats/authAutomat';
|
|
import { requireArray, requireObject } from '../utils/apiShape';
|
|
|
|
function sortUnits(units) {
|
|
return [...units].sort((a, b) => {
|
|
const left = a.symbol ?? a.si ?? '';
|
|
const right = b.symbol ?? b.si ?? '';
|
|
return String(left).localeCompare(String(right), 'de');
|
|
});
|
|
}
|
|
|
|
export const loadUnits = createAsyncThunk('unit/load', async () => {
|
|
const res = await unitApi.list();
|
|
requireObject(res, 'GET /api/unit');
|
|
return requireArray(res.units, 'units');
|
|
});
|
|
|
|
export const upsertUnit = createAsyncThunk('unit/upsert', async (body) => {
|
|
const res = await unitApi.upsert(body);
|
|
requireObject(res, 'PUT /api/unit');
|
|
requireObject(res.unit, 'unit');
|
|
return res.unit;
|
|
});
|
|
|
|
export const deleteUnit = createAsyncThunk('unit/delete', async (si) => {
|
|
await unitApi.delete(si);
|
|
return si;
|
|
});
|
|
|
|
const initialState = {
|
|
units: [],
|
|
status: 'idle',
|
|
error: null,
|
|
};
|
|
|
|
const unitSlice = createSlice({
|
|
name: 'unit',
|
|
initialState,
|
|
reducers: {},
|
|
extraReducers: (builder) => {
|
|
builder
|
|
.addCase(loadUnits.pending, (state) => {
|
|
state.status = 'loading';
|
|
state.error = null;
|
|
})
|
|
.addCase(loadUnits.fulfilled, (state, action) => {
|
|
state.status = 'succeeded';
|
|
state.units = sortUnits(action.payload);
|
|
})
|
|
.addCase(loadUnits.rejected, (state, action) => {
|
|
state.status = 'failed';
|
|
state.error = action.error.message;
|
|
})
|
|
.addCase(upsertUnit.fulfilled, (state, action) => {
|
|
const row = action.payload;
|
|
state.units = sortUnits([
|
|
...state.units.filter((u) => u.si !== row.si),
|
|
row,
|
|
]);
|
|
})
|
|
.addCase(deleteUnit.fulfilled, (state, action) => {
|
|
state.units = state.units.filter((u) => u.si !== action.payload);
|
|
})
|
|
.addCase(AUTH_COMPANY_CHANGED, () => initialState)
|
|
.addCase(AUTH_LOGGED_OUT, () => initialState);
|
|
},
|
|
});
|
|
|
|
export const selectUnits = (state) => state.unit.units;
|
|
export const selectUnitsStatus = (state) => state.unit.status;
|
|
export const selectUnitsError = (state) => state.unit.error;
|
|
|
|
export function unitLoadListener(listenerMiddleware) {
|
|
listenerMiddleware.startListening({
|
|
matcher: (action) =>
|
|
action.type === AUTH_SESSION_ESTABLISHED || action.type === AUTH_COMPANY_CHANGED,
|
|
effect: async (_action, api) => {
|
|
const companyId = authAutomat.state.user?.selectedCompanyId;
|
|
if (companyId) {
|
|
api.dispatch(loadUnits());
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
export default unitSlice.reducer;
|