This commit is contained in:
seb
2026-10-11 02:41:36 +02:00
parent 3379a63baf
commit c75521dc25

View File

@@ -7,10 +7,10 @@
* `'authed'` with a `selectedCompanyId`, and `actions.reset()` on `'anon'`.
* - `sseAutomat`: Subscribes to the single `'brand'` event carrying
* `{ sender, brandId }` — any create/rename/delete/picture change triggers
* `actions.reload()`, which silently re-fetches the list. Subscribed views
* `actions.load(true)`, which silently re-fetches the list. Subscribed views
* (e.g. `ArtikelMarkenPage` via `brandAutomat.subscribe(...)`) then
* re-render from the updated state. This is the reload pattern. Events sent
* by this tab (matching `sender`) are ignored.
* re-render from the updated state. Events sent by this tab (matching `sender`)
* are ignored.
* - UI / Settings: Mutating actions (`create`, `rename`, `remove`, `addImage`, `deleteImage`).
*/
@@ -78,43 +78,25 @@ const actions = {
brandAutomat.setState({ filter, filteredBrands: applyFilter(brandAutomat.state.brands, filter) });
},
/** Load all brands for the selected company (pages through the API). */
async load() {
if (inflightLoad) return inflightLoad;
brandAutomat.setState({ status: 'loading', error: null });
return (inflightLoad = fetchAllBrands()
.then(({ brands }) => updateStateWithBrands(brands, { status: 'succeeded' }))
.catch((err) => {
brandAutomat.setState({ status: 'failed', error: err?.message ?? String(err) });
throw err;
})
.finally(() => { inflightLoad = null; }));
},
/** Silently re-fetches all brands while keeping current state visible. */
async reload() {
/**
* Load all brands for the selected company (pages through the API).
* @param {boolean} [silent=false] If true, re-fetches without setting status to 'loading'.
*/
async load(silent = false) {
if (inflightLoad) return inflightLoad;
if (!silent) {
brandAutomat.setState({ status: 'loading', error: null });
}
return (inflightLoad = fetchAllBrands()
.then(({ brands }) => updateStateWithBrands(brands, { status: 'succeeded', error: null }))
.catch((err) => {
brandAutomat.setState({ error: err?.message ?? String(err) });
const error = err?.message ?? String(err);
brandAutomat.setState(silent ? { error } : { status: 'failed', error });
throw err;
})
.finally(() => { inflightLoad = null; }));
},
/**
* Returns the brand state, loading brands first if uninitialized.
*
* @returns {Promise<BrandState>} Current brand state.
*/
async getOrLoad() {
if (brandAutomat.state.status !== 'succeeded') {
await brandAutomat.actions.reload();
}
return brandAutomat.state;
},
/** Create a brand (insert). */
async create(body) {
const res = await brandApi.create(body);
@@ -140,14 +122,14 @@ const actions = {
/** Add / update brand image. */
async addImage(id, file) {
const res = await brandApi.addImage(id, file);
await brandAutomat.actions.reload();
await brandAutomat.actions.load(true);
return res.brand;
},
/** Delete brand image. */
async deleteImage(id) {
const res = await brandApi.deleteImage(id);
await brandAutomat.actions.reload();
await brandAutomat.actions.load(true);
return res.brand;
},
@@ -174,7 +156,7 @@ sseAutomat.actions.on('brand', (event) => {
const payload = JSON.parse(event?.data ?? '{}');
if (payload?.sender && payload.sender === getSseClientId()) return;
} catch { }
void brandAutomat.actions.reload().catch(() => { });
void brandAutomat.actions.load(true).catch(() => { });
});
export default brandAutomat;