This commit is contained in:
seb
2026-09-22 07:20:31 +02:00
parent 536e7b1e2a
commit 5e13b8f9cd
32 changed files with 2485 additions and 1908 deletions

View File

@@ -0,0 +1,94 @@
import { Automat } from 'react-automat';
import { unit as unitApi } from '../api';
import authAutomat from './authAutomat';
/**
* @typedef {Object} UnitState
* @property {Array<object>} units
* @property {'idle'|'loading'|'succeeded'|'failed'} status
* @property {string|null} error
*/
/** @type {UnitState} */
const initialState = {
units: [],
status: 'idle',
error: null,
};
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');
});
}
let unitAutomat;
const actions = {
/** Load all units for the selected company. */
async load() {
unitAutomat.setState({ status: 'loading', error: null });
try {
const res = await unitApi.list();
const units = sortUnits(Array.isArray(res.units) ? res.units : []);
unitAutomat.setState({ units, status: 'succeeded' });
return units;
} catch (err) {
unitAutomat.setState({ status: 'failed', error: err?.message ?? String(err) });
throw err;
}
},
/**
* Upsert (create or update) a unit.
* @param {object} body
*/
async upsert(body) {
const res = await unitApi.upsert(body);
const row = res.unit;
const units = sortUnits([
...unitAutomat.state.units.filter((u) => u.si !== row.si),
row,
]);
unitAutomat.setState({ units });
return units;
},
/**
* Delete a unit by SI symbol.
* @param {string} si
*/
async delete(si) {
await unitApi.delete(si);
unitAutomat.setState({
units: unitAutomat.state.units.filter((u) => u.si !== si),
});
},
/** Reset to idle state (called on logout / company switch). */
reset() {
unitAutomat.setState(initialState);
},
};
/**
* Global unit state container.
* Loads automatically when authAutomat reaches 'authed' with a selectedCompanyId.
*
* @type {Automat<UnitState>}
*/
unitAutomat = new Automat(initialState, actions, { name: 'unit' });
// Subscribe to auth changes
authAutomat.subscribe((auth) => {
const companyId = auth.user?.selectedCompanyId;
if (auth.status === 'authed' && companyId) {
void unitAutomat.actions.load();
} else if (auth.status === 'anon') {
unitAutomat.actions.reset();
}
});
export default unitAutomat;