sotre
This commit is contained in:
@@ -1,28 +1,31 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Component } from 'react';
|
||||
import Autocomplete from '@mui/material/Autocomplete';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Box from '@mui/material/Box';
|
||||
import { EditablePanelTile } from '../../panels';
|
||||
import { useStorageManager } from '../../../api/storageManagerContext';
|
||||
import { StorageManagerContext } from '../../../api/storageManagerContext';
|
||||
import { requireDefined, requireObject } from '../../../utils/apiShape';
|
||||
import { notifyError } from '../../../utils/notify';
|
||||
import { PANEL_TILE_KEYS } from '../../../theme';
|
||||
|
||||
function PanelValue({ label, children }) {
|
||||
if (children == null || children === '') return null;
|
||||
return (
|
||||
<Box sx={{ mb: 1 }}>
|
||||
{label ? (
|
||||
<Typography variant="caption" color="text.secondary" display="block">
|
||||
{label}
|
||||
class PanelValue extends Component {
|
||||
render() {
|
||||
const { label, children } = this.props;
|
||||
if (children == null || children === '') return null;
|
||||
return (
|
||||
<Box sx={{ mb: 1 }}>
|
||||
{label ? (
|
||||
<Typography variant="caption" color="text.secondary" display="block">
|
||||
{label}
|
||||
</Typography>
|
||||
) : null}
|
||||
<Typography variant="body2" component="div">
|
||||
{children}
|
||||
</Typography>
|
||||
) : null}
|
||||
<Typography variant="body2" component="div">
|
||||
{children}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function brandDraftValue(article) {
|
||||
@@ -39,25 +42,70 @@ function brandDraftValid(draft) {
|
||||
|
||||
const SECOND_ROW_MIN_HEIGHT = 220;
|
||||
|
||||
export default function ArticleViewBrand({ article: articleData, onArticleUpdated }) {
|
||||
const store = useStorageManager();
|
||||
const [brands, setBrands] = useState([]);
|
||||
class BrandEdit extends Component {
|
||||
render() {
|
||||
const { draft, onChange, inputRef, brands } = this.props;
|
||||
return (
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
freeSolo
|
||||
options={brands}
|
||||
value={draft.name ?? ''}
|
||||
inputValue={draft.name ?? ''}
|
||||
getOptionLabel={(option) =>
|
||||
typeof option === 'string' ? option : String(option.name ?? '')
|
||||
}
|
||||
onInputChange={(_event, value) => onChange({ name: value })}
|
||||
onChange={(_event, option) => {
|
||||
onChange({ name: option ? String(option.name ?? '') : '' });
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
inputRef={inputRef}
|
||||
label="Marke"
|
||||
size="small"
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
store.brandPromise
|
||||
export default class ArticleViewBrand extends Component {
|
||||
static contextType = StorageManagerContext;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const brands = this.context?.brands;
|
||||
this.state = {
|
||||
brands: brands ?? [],
|
||||
};
|
||||
this._cancelled = false;
|
||||
this._brandsReady = brands != null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._cancelled = false;
|
||||
if (this._brandsReady) return;
|
||||
this.context.brandPromise
|
||||
.then((list) => {
|
||||
if (!cancelled) setBrands(list);
|
||||
if (!this._cancelled) this.setState({ brands: list });
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!cancelled) notifyError(err);
|
||||
if (!this._cancelled) notifyError(err);
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [store]);
|
||||
}
|
||||
|
||||
const handleSave = async (draft) => {
|
||||
componentWillUnmount() {
|
||||
this._cancelled = true;
|
||||
}
|
||||
|
||||
handleSave = async (draft) => {
|
||||
const { article: articleData, onArticleUpdated } = this.props;
|
||||
const store = this.context;
|
||||
const { brands } = this.state;
|
||||
const name = String(draft.name ?? '').trim();
|
||||
if (!name) {
|
||||
throw new Error('Bitte eine Marke angeben.');
|
||||
@@ -77,7 +125,7 @@ export default function ArticleViewBrand({ article: articleData, onArticleUpdate
|
||||
requireDefined(createdRes.brand.id, 'brand.id');
|
||||
brandId = createdRes.brand.id;
|
||||
const nextBrands = await store.updateBrand();
|
||||
setBrands(nextBrands);
|
||||
this.setState({ brands: nextBrands });
|
||||
}
|
||||
|
||||
const res = await store.article.setBrand(articleData.sku, { brandId });
|
||||
@@ -86,44 +134,24 @@ export default function ArticleViewBrand({ article: articleData, onArticleUpdate
|
||||
onArticleUpdated?.(res.article);
|
||||
};
|
||||
|
||||
return (
|
||||
<EditablePanelTile
|
||||
wide={1}
|
||||
tileKey={PANEL_TILE_KEYS.brand}
|
||||
title="Marke"
|
||||
minHeight={SECOND_ROW_MIN_HEIGHT}
|
||||
value={brandDraftValue(articleData)}
|
||||
onSave={handleSave}
|
||||
isDirty={brandDraftDirty}
|
||||
canSave={brandDraftValid}
|
||||
renderDisplay={(saved) => (
|
||||
<PanelValue>{saved.name || null}</PanelValue>
|
||||
)}
|
||||
renderEdit={(draft, onChange, inputRef) => (
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
freeSolo
|
||||
options={brands}
|
||||
value={draft.name ?? ''}
|
||||
inputValue={draft.name ?? ''}
|
||||
getOptionLabel={(option) =>
|
||||
typeof option === 'string' ? option : String(option.name ?? '')
|
||||
}
|
||||
onInputChange={(_event, value) => onChange({ name: value })}
|
||||
onChange={(_event, option) => {
|
||||
onChange({ name: option ? String(option.name ?? '') : '' });
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
inputRef={inputRef}
|
||||
label="Marke"
|
||||
size="small"
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
render() {
|
||||
const { article: articleData } = this.props;
|
||||
const { brands } = this.state;
|
||||
const value = brandDraftValue(articleData);
|
||||
|
||||
return (
|
||||
<EditablePanelTile
|
||||
wide={1}
|
||||
tileKey={PANEL_TILE_KEYS.brand}
|
||||
title="Marke"
|
||||
minHeight={SECOND_ROW_MIN_HEIGHT}
|
||||
value={value}
|
||||
onSave={this.handleSave}
|
||||
isDirty={brandDraftDirty}
|
||||
canSave={brandDraftValid}
|
||||
display={<PanelValue>{value.name || null}</PanelValue>}
|
||||
edit={<BrandEdit brands={brands} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user