Files
dashfront/src/api/category.js
2026-10-10 18:17:14 +02:00

141 lines
4.2 KiB
JavaScript

import { http, httpBinary, httpGetBinary } from './http.js';
export const category = {
/** GET /api/category/tree → { languageId, tree, articles } (company from session) */
// #region GET /api/category/tree — getTree
getTree() {
return http('/api/category/tree');
},
// #endregion
/**
* GET /api/category/:id/articles → { articles: [...] }
* Article rows: sku, name, net, taxRate, fullHash, thumbW, thumbH, thumbHash, childCount, …
*/
// #region GET /api/category/:id/articles — getArticles
getArticles(categoryId) {
return http(`/api/category/${categoryId}/articles`);
},
// #endregion
/** POST /api/category → 201 { category } */
// #region POST /api/category — create
create({ parentId, name }) {
return http('/api/category', {
method: 'POST',
body: { parentId: Number(parentId), name },
});
},
// #endregion
/**
* DELETE /api/category/:id → 204
* Query: ?recursive=true (cascades deletion of subcategories and articles)
*/
// #region DELETE /api/category/:id — delete
delete(categoryId, { recursive = false } = {}) {
const qs = recursive ? '?recursive=true' : '';
return http(`/api/category/${categoryId}${qs}`, { method: 'DELETE' });
},
// #endregion
/**
* PATCH /api/category/:id
* Body: { name } — renames and re-slugifies in the company default language.
* Empty name → 400 name is required.
* → 200 { category: { id, name, slug } }
*/
// #region PATCH /api/category/:id — updateName
updateName(categoryId, name) {
return http(`/api/category/${categoryId}`, {
method: 'PATCH',
body: { name },
});
},
// #endregion
/**
* PUT /api/category/order
* Body: { parentId, categoryIds: number[] } — sibling order of the children
* under `parentId` (top-down). categoryIds must be exactly the current child
* set of parentId (same count, no foreign/duplicate ids) → 400 Invalid category order.
* → 200 { categoryIds: number[] }
*/
// #region PUT /api/category/order — reorder
reorder(parentId, categoryIds) {
return http('/api/category/order', {
method: 'PUT',
body: { parentId, categoryIds },
});
},
// #endregion
/**
* PATCH /api/category/:id
* Body: { parentId } — moves the category under a new parent.
* → 200 { category: { id, parentId, sort } } (kein name/slug im Response)
*/
// #region PATCH /api/category/:id — move
move(categoryId, parentId) {
return http(`/api/category/${categoryId}`, {
method: 'PATCH',
body: { parentId },
});
},
// #endregion
/**
* PATCH /api/category/:id
* Body: { pos: boolean } — toggles the POS (Point of Sale) flag.
* → 200 { category: { id, pos } }
*
* PROPOSED — backend needs to implement this field.
*/
// #region PATCH /api/category/:id — updatePos
updatePos(categoryId, pos) {
return http(`/api/category/${categoryId}`, {
method: 'PATCH',
body: { pos },
});
},
// #endregion
/**
* POST /api/category/:id/image
* Body: raw image bytes (Content-Type: image/webp)
* → 201 { category: { id, fullHash, thumbW, thumbH, thumbHash } }
*/
// #region POST /api/category/:id/image — uploadImage
uploadImage(categoryId, file) {
return httpBinary(`/api/category/${categoryId}/image`, {
method: 'POST',
contentType: file?.type || 'image/webp',
body: file,
});
},
// #endregion
/**
* DELETE /api/category/:id/image
* → 200 { category: { id, thumbW: null, thumbH: null, thumbHash: null } }
*/
// #region DELETE /api/category/:id/image — deleteImage
deleteImage(categoryId) {
return http(`/api/category/${categoryId}/image`, { method: 'DELETE' });
},
// #endregion
/**
* GET /api/category/export.zip → application/zip (binary download)
* `kategorien.zip` = kategorien.csv (semicolon-separated, Windows-1252,
* depth-first, `Ebene N` name column per depth) + one `<fullHash>.avif`
* entry per category image (content-addressed, deduplicated).
* Errors: 400 No company selected, 401, 403, 404 (JSON { error }).
*/
// #region GET /api/category/export.zip — exportZip
exportZip() {
return httpGetBinary('/api/category/export.zip');
},
// #endregion
};