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;