This commit is contained in:
seb
2026-09-29 18:26:30 +02:00
parent 43e1ab98b7
commit 1b9c39e975
11 changed files with 2150 additions and 6 deletions

View File

@@ -71,6 +71,48 @@ export class ApiClient {
delete: (id) => this.#empty('DELETE', `/api/brand/${enc(id)}`),
};
this.attributename = {
/** GET /api/attributename */
list: () => this.#json('GET', '/api/attributename'),
/** POST /api/attributename */
create: (body) => this.#json('POST', '/api/attributename', { body }),
/** PATCH /api/attributename/{id} */
update: (id, body) => this.#json('PATCH', `/api/attributename/${enc(id)}`, { body }),
/** DELETE /api/attributename/{id} */
delete: (id) => this.#json('DELETE', `/api/attributename/${enc(id)}`),
/** PUT /api/attributename/order */
order: (body) => this.#json('PUT', '/api/attributename/order', { body }),
};
this.attributevalue = {
/** GET /api/attributename/{attributeId}/value */
listByAttributeId: (attributeId) =>
this.#json('GET', `/api/attributename/${enc(attributeId)}/value`),
/** POST /api/attributename/{attributeId}/value */
create: (attributeId, body) =>
this.#json('POST', `/api/attributename/${enc(attributeId)}/value`, { body }),
/** PATCH /api/attributevalue/{id} */
update: (id, body) => this.#json('PATCH', `/api/attributevalue/${enc(id)}`, { body }),
/** DELETE /api/attributevalue/{id} */
delete: (id) => this.#json('DELETE', `/api/attributevalue/${enc(id)}`),
/** PUT /api/attributename/{attributeId}/value/order */
order: (attributeId, body) =>
this.#json('PUT', `/api/attributename/${enc(attributeId)}/value/order`, { body }),
};
this.propertyname = {
/** GET /api/propertyname */
list: () => this.#json('GET', '/api/propertyname'),
/** POST /api/propertyname */
create: (body) => this.#json('POST', '/api/propertyname', { body }),
/** PATCH /api/propertyname/{id} */
update: (id, body) => this.#json('PATCH', `/api/propertyname/${enc(id)}`, { body }),
/** DELETE /api/propertyname/{id} */
delete: (id) => this.#json('DELETE', `/api/propertyname/${enc(id)}`),
/** PUT /api/propertyname/order */
order: (body) => this.#json('PUT', '/api/propertyname/order', { body }),
};
this.supplier = {
/** GET /api/supplier → { suppliers: Supplier[] } */
list: () => this.#json('GET', '/api/supplier'),
@@ -425,6 +467,21 @@ export class ApiClient {
/** DELETE /api/article/{sku}/supplier/{id} */
deleteSupplier: (sku, id) =>
this.#empty('DELETE', `/api/article/${enc(sku)}/supplier/${enc(id)}`),
/** GET /api/article/{sku}/attributevalue */
getAttributeValues: (sku) =>
this.#json('GET', `/api/article/${enc(sku)}/attributevalue`),
/** PUT /api/article/{sku}/attributevalue */
setAttributeValues: (sku, body) =>
this.#json('PUT', `/api/article/${enc(sku)}/attributevalue`, { body }),
/** GET /api/article/{sku}/property */
getProperties: (sku) =>
this.#json('GET', `/api/article/${enc(sku)}/property`),
/** PUT /api/article/{sku}/property */
setProperties: (sku, body) =>
this.#json('PUT', `/api/article/${enc(sku)}/property`, { body }),
/** DELETE /api/article/{sku}/property/{propertyId} */
deleteProperty: (sku, propertyId) =>
this.#json('DELETE', `/api/article/${enc(sku)}/property/${enc(propertyId)}`),
};
this.posterminal = {

View File

@@ -9,6 +9,8 @@ import authAutomat from '../automats/authAutomat';
import categoryAutomat, { invalidateAllCategoryViews } from '../automats/categoryAutomat';
import posterminalAutomat from '../automats/posterminalAutomat';
import warehouseAutomat from '../automats/warehouseAutomat';
import attributeAutomat from '../automats/attributeAutomat';
import propertyAutomat from '../automats/propertyAutomat';
/**
@@ -683,6 +685,16 @@ export class StorageManager extends ApiClient {
console.error('[storageMgr] warehouse SSE refresh failed', err);
});
});
es.addEventListener('attributename', () => {
void attributeAutomat.actions.load().catch((err) => {
console.error('[storageMgr] attributename SSE refresh failed', err);
});
});
es.addEventListener('propertyname', () => {
void propertyAutomat.actions.load().catch((err) => {
console.error('[storageMgr] propertyname SSE refresh failed', err);
});
});
for (const sku of new Set([
...this.#articleWatchers.keys(),
...this.#historyWatchers.keys(),

View File

@@ -432,6 +432,53 @@ export const article = {
body,
});
},
/**
* GET /api/article/:sku/attributevalue → { attributevalues: ArticleAttributeValue[] }
*/
getAttributeValues(sku) {
return http(`/api/article/${encodeURIComponent(sku)}/attributevalue`);
},
/**
* PUT /api/article/:sku/attributevalue
* Body: { attributevalues: number[] | { attributeValueId: number, sort?: number }[] }
* → 200 { attributevalues: ArticleAttributeValue[] }
*/
setAttributeValues(sku, attributevalues) {
return http(`/api/article/${encodeURIComponent(sku)}/attributevalue`, {
method: 'PUT',
body: { attributevalues },
});
},
/**
* GET /api/article/:sku/property → { properties: ArticleProperty[] }
*/
getProperties(sku) {
return http(`/api/article/${encodeURIComponent(sku)}/property`);
},
/**
* PUT /api/article/:sku/property
* Body: { properties: { propertyId: number, value: string, sort?: number }[] }
* → 200 { properties: ArticleProperty[] }
*/
setProperties(sku, properties) {
return http(`/api/article/${encodeURIComponent(sku)}/property`, {
method: 'PUT',
body: { properties },
});
},
/**
* DELETE /api/article/:sku/property/:propertyId → 200 { ok: true }
*/
deleteProperty(sku, propertyId) {
return http(
`/api/article/${encodeURIComponent(sku)}/property/${encodeURIComponent(propertyId)}`,
{ method: 'DELETE' }
);
},
};
/**
@@ -679,6 +726,93 @@ export const brand = {
},
};
export const attributename = {
/** GET /api/attributename → { attributenames: Attributename[] } */
list() {
return http('/api/attributename');
},
/** POST /api/attributename → 201 { attributename } */
create(body) {
return http('/api/attributename', { method: 'POST', body });
},
/** PATCH /api/attributename/:id → 200 { attributename } */
update(id, body) {
return http(`/api/attributename/${encodeURIComponent(id)}`, { method: 'PATCH', body });
},
/** DELETE /api/attributename/:id → 200 */
delete(id) {
return http(`/api/attributename/${encodeURIComponent(id)}`, { method: 'DELETE' });
},
/** PUT /api/attributename/order → 200 */
order(attributenameIds) {
return http('/api/attributename/order', { method: 'PUT', body: { attributenameIds } });
},
};
export const attributevalue = {
/** GET /api/attributename/:attributeId/value → { values: AttributeValue[] } */
listByAttributeId(attributeId) {
return http(`/api/attributename/${encodeURIComponent(attributeId)}/value`);
},
/** POST /api/attributename/:attributeId/value → 201 { attributevalue } */
create(attributeId, body) {
return http(`/api/attributename/${encodeURIComponent(attributeId)}/value`, {
method: 'POST',
body,
});
},
/** PATCH /api/attributevalue/:id → 200 { attributevalue } */
update(id, body) {
return http(`/api/attributevalue/${encodeURIComponent(id)}`, { method: 'PATCH', body });
},
/** DELETE /api/attributevalue/:id → 200 */
delete(id) {
return http(`/api/attributevalue/${encodeURIComponent(id)}`, { method: 'DELETE' });
},
/** PUT /api/attributename/:attributeId/value/order → 200 */
order(attributeId, attributevalueIds) {
return http(`/api/attributename/${encodeURIComponent(attributeId)}/value/order`, {
method: 'PUT',
body: { attributevalueIds },
});
},
};
export const propertyname = {
/** GET /api/propertyname → { propertynames: Propertyname[] } */
list() {
return http('/api/propertyname');
},
/** POST /api/propertyname → 201 { propertyname } */
create(body) {
return http('/api/propertyname', { method: 'POST', body });
},
/** PATCH /api/propertyname/:id → 200 { propertyname } */
update(id, body) {
return http(`/api/propertyname/${encodeURIComponent(id)}`, { method: 'PATCH', body });
},
/** DELETE /api/propertyname/:id → 200 */
delete(id) {
return http(`/api/propertyname/${encodeURIComponent(id)}`, { method: 'DELETE' });
},
/** PUT /api/propertyname/order → 200 */
order(propertynameIds) {
return http('/api/propertyname/order', { method: 'PUT', body: { propertynameIds } });
},
};
/**
* Company-scoped suppliers / Lieferanten (selectedCompanyId from session).
* Shape: Supplier = { id, name, createdAt, updatedAt }
@@ -1587,6 +1721,8 @@ export default {
auth,
article,
articleIndex,
attributename,
attributevalue,
brand,
category,
company,
@@ -1599,6 +1735,7 @@ export default {
order,
posterminal,
printer,
propertyname,
quote,
supplier,
thumb,