This commit is contained in:
seb
2026-10-09 21:57:57 +02:00
parent d04a5f104f
commit 082771b9c3
3 changed files with 75 additions and 109 deletions

View File

@@ -7,7 +7,7 @@ description: >-
# Dash API Routes Overview (All) # Dash API Routes Overview (All)
Overview of all 205 API endpoints across all modules. Overview of all 206 API endpoints across all modules.
### Notation ### Notation
@@ -620,6 +620,9 @@ _none_
#### Create package for a shipping — `POST /shipping/{id}/package` #### Create package for a shipping — `POST /shipping/{id}/package`
- Params: `id: int, body: { entityaddressId: int, type: str, state: str, details?: str }` - Params: `id: int, body: { entityaddressId: int, type: str, state: str, details?: str }`
- Returns: `201 { package: { id: int, shippingId: int, entityaddressId: int, number: str, type: str, state: str, details?: str|null } }` - Returns: `201 { package: { id: int, shippingId: int, entityaddressId: int, number: str, type: str, state: str, details?: str|null } }`
#### Small thumb image by hash — `GET /smallthumb/{fullHash}`
- Params: `fullHash: str`
- Returns: `200 avif`
#### Adjust stock manually — `POST /stock/adjust` #### Adjust stock manually — `POST /stock/adjust`
- Params: `body: { sku?: str, warehouseId?: int, amount?: num, text?: str|null, lines?: { sku: str, amount: num, warehouseId?: int, text?: str }[] }` - Params: `body: { sku?: str, warehouseId?: int, amount?: num, text?: str|null, lines?: { sku: str, amount: num, warehouseId?: int, text?: str }[] }`
- Returns: `201 { manifest: { id: int, number: str, type: str, date: str, createdAt: str }, lines: { manifestarticle_id: int, sku: str, name: str, warehouse_id: int, amount: num, text: str }[], ledger: T15[] }` - Returns: `201 { manifest: { id: int, number: str, type: str, date: str, createdAt: str }, lines: { manifestarticle_id: int, sku: str, name: str, warehouse_id: int, amount: num, text: str }[], ledger: T15[] }`

View File

@@ -1,119 +1,82 @@
import { PureComponent } from 'react';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import ThumbHashImage, { getThumbHashDimensions } from '../article/ThumbHashImage'; import ThumbHashImage from '../article/ThumbHashImage';
import brandAutomat from '../../automats/brandAutomat';
import { import {
SHADOW_THUMB_RING, SHADOW_THUMB_RING,
TINT_ROW_HOVER, TINT_ROW_HOVER,
} from '../../colors'; } from '../../colors';
/** export default class BrandThumb extends PureComponent {
* Extracts thumbHash from various brand representations: render() {
* - Direct thumbHash / thumbhash property const {
* - Brand with pics array (e.g. brand.pics[0].thumbHash) brand,
* - Brand by name or id looked up in brandAutomat.state.brands size = 20,
*/ fallback = null,
export function extractBrandThumbInfo(brand, thumbHashOverride) { sx,
if (thumbHashOverride) { } = this.props;
const dims = getThumbHashDimensions(thumbHashOverride); const pic = brand?.pics?.[0];
return {
thumbHash: thumbHashOverride,
thumbW: dims?.w ?? null,
thumbH: dims?.h ?? null,
};
}
if (!brand) return null; if (!pic?.thumbHash) {
return fallback;
}
// Direct thumbHash on brand object const { thumbHash, thumbW, thumbH } = pic;
let hash = brand.thumbHash ?? brand.thumbhash; const ratio = thumbW && thumbH ? thumbW / thumbH : 1;
let thumbW = brand.thumbW ?? brand.thumbw; // Contain-fit inside a square `size x size` box, preserving aspect ratio.
let thumbH = brand.thumbH ?? brand.thumbh; let innerW = size;
let innerH = size;
// Check pics array if (Number.isFinite(ratio) && ratio > 0) {
if (!hash && Array.isArray(brand.pics) && brand.pics.length > 0) { if (ratio >= 1) {
const firstPic = brand.pics[0]; innerW = size;
hash = firstPic?.thumbHash ?? firstPic?.thumbhash; innerH = Math.max(1, Math.round(size / ratio));
thumbW = firstPic?.thumbW ?? firstPic?.thumbw; } else {
thumbH = firstPic?.thumbH ?? firstPic?.thumbh; innerH = size;
} innerW = Math.max(1, Math.round(size * ratio));
// Fallback: look up in brandAutomat
if (!hash) {
const brands = brandAutomat.state?.brands;
if (Array.isArray(brands)) {
const id = typeof brand === 'object' ? brand.id : (typeof brand === 'number' ? brand : null);
const name = typeof brand === 'object' ? brand.name : (typeof brand === 'string' ? brand : null);
const found = brands.find(
(b) =>
(id != null && b.id === id) ||
(name && String(b.name || '').trim().toLowerCase() === String(name).trim().toLowerCase())
);
if (found) {
hash = found.thumbHash ?? found.thumbhash ?? found.pics?.[0]?.thumbHash ?? found.pics?.[0]?.thumbhash;
thumbW = found.thumbW ?? found.thumbw ?? found.pics?.[0]?.thumbW ?? found.pics?.[0]?.thumbw;
thumbH = found.thumbH ?? found.thumbh ?? found.pics?.[0]?.thumbH ?? found.pics?.[0]?.thumbh;
} }
} }
return (
<Box
component="span"
sx={{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: size,
width: size,
minWidth: size,
maxWidth: size,
flexShrink: 0,
verticalAlign: 'middle',
lineHeight: 0,
my: 0,
boxSizing: 'border-box',
...sx,
}}
>
<Box
component="span"
sx={{
display: 'block',
width: innerW,
height: innerH,
borderRadius: size >= 24 ? '4px' : '3px',
overflow: 'hidden',
flexShrink: 0,
lineHeight: 0,
boxSizing: 'border-box',
bgcolor: TINT_ROW_HOVER,
boxShadow: SHADOW_THUMB_RING,
}}
>
<ThumbHashImage
thumbHash={thumbHash}
width={innerW}
height={innerH}
sx={{ width: innerW, height: innerH, flexShrink: 0 }}
/>
</Box>
</Box>
);
} }
if (!hash) return null;
if (thumbW == null || thumbH == null) {
const dims = getThumbHashDimensions(hash);
if (dims) {
thumbW = dims.w;
thumbH = dims.h;
}
}
return { thumbHash: hash, thumbW, thumbH };
}
export default function BrandThumb({
brand,
thumbHash: thumbHashProp,
size = 20,
fallback = null,
sx,
}) {
const info = extractBrandThumbInfo(brand, thumbHashProp);
if (!info?.thumbHash) {
return fallback;
}
const { thumbHash, thumbW, thumbH } = info;
const ratio = (thumbW && thumbH) ? (thumbW / thumbH) : 1;
const calcWidth = Math.round(size * Math.max(0.6, Math.min(ratio, 2.5)));
return (
<Box
component="span"
sx={{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: size,
width: calcWidth,
minWidth: Math.round(size * 0.6),
maxWidth: Math.round(size * 2.5),
borderRadius: size >= 24 ? '4px' : '3px',
overflow: 'hidden',
flexShrink: 0,
verticalAlign: 'middle',
lineHeight: 0,
my: 0,
boxSizing: 'border-box',
bgcolor: TINT_ROW_HOVER,
boxShadow: SHADOW_THUMB_RING,
...sx,
}}
>
<ThumbHashImage
thumbHash={thumbHash}
width={calcWidth}
height={size}
/>
</Box>
);
} }

View File

@@ -1,4 +1,4 @@
export { default as BrandThumb, extractBrandThumbInfo } from './BrandThumb'; export { default as BrandThumb } from './BrandThumb';
export { default as BrandLabel } from './BrandLabel'; export { default as BrandLabel } from './BrandLabel';
export { default as BrandImageSearchDialog } from './BrandImageSearchDialog'; export { default as BrandImageSearchDialog } from './BrandImageSearchDialog';
export { default as ArtikelMarke } from './ArtikelMarke'; export { default as ArtikelMarke } from './ArtikelMarke';