/** * @file unitAutomat.js * @description Manages allowable units of measure (Stück, kg, Liter, etc.) * for the active company. * * Upstream Triggers: * - `authAutomat`: Subscribes to auth state changes — calls `actions.load()` on * `'authed'` with a `selectedCompanyId`, and `actions.reset()` on `'anon'`. * - UI / Settings: Mutating actions (`upsert`, `delete`). */ import { Automat } from 'react-automat'; import { unit as unitApi } from '../api'; import authAutomat from './authAutomat'; /** * @typedef {Object} UnitState * @property {Array} 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} */ 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;