161 lines
4.4 KiB
JavaScript
161 lines
4.4 KiB
JavaScript
import { PureComponent, createRef } from 'react';
|
|
import Box from '@mui/material/Box';
|
|
import TextField from '@mui/material/TextField';
|
|
import InputAdornment from '@mui/material/InputAdornment';
|
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
import BackendError from '../../components/BackendError';
|
|
import SearchIcon from '@mui/icons-material/Search';
|
|
import IconButton from '@mui/material/IconButton';
|
|
import ClearIcon from '@mui/icons-material/Clear';
|
|
import FillSpace from 'dashgui/FillSpace';
|
|
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
|
|
import { backendErrorFrom } from '../../utils/backendError';
|
|
import { notifyError } from '../../utils/notify';
|
|
import { setLastArticleSku } from '../../automats';
|
|
import brandAutomat from '../../automats/brandAutomat';
|
|
import {
|
|
ArtikelMarke,
|
|
ArtikelMarkeNew,
|
|
} from '../../components/brand';
|
|
import {
|
|
PURPLE_PANEL,
|
|
} from '../../colors';
|
|
|
|
class ArtikelMarkenSearchField extends PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = { input: '' };
|
|
}
|
|
|
|
onInputChange(input) {
|
|
this.setState({ input });
|
|
}
|
|
|
|
clearInput() {
|
|
this.setState({ input: '' });
|
|
}
|
|
render() {
|
|
const { inputRef } = this.props;
|
|
|
|
return (
|
|
<Box
|
|
ref={inputRef}
|
|
sx={{
|
|
mb: 2,
|
|
display: 'flex',
|
|
gap: 1.5,
|
|
alignItems: 'center',
|
|
minHeight: 40,
|
|
}}
|
|
>
|
|
<TextField
|
|
sx={{ maxWidth: 520, flexGrow: 1 }}
|
|
autoFocus
|
|
autoComplete="off"
|
|
value={this.state.input}
|
|
onChange={(e) => this.onInputChange(e.target.value)}
|
|
slotProps={{
|
|
htmlInput: {
|
|
autoCapitalize: 'off',
|
|
autoCorrect: 'off',
|
|
},
|
|
input: {
|
|
sx: { height: 40 },
|
|
startAdornment: (
|
|
<InputAdornment position="start">
|
|
<SearchIcon color="action" />
|
|
</InputAdornment>
|
|
),
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<IconButton
|
|
size="small"
|
|
onClick={() => this.clearInput()}
|
|
onMouseDown={(e) => e.preventDefault()}
|
|
aria-label="Suche löschen"
|
|
>
|
|
<ClearIcon fontSize="small" />
|
|
</IconButton>
|
|
</InputAdornment>
|
|
),
|
|
},
|
|
}}
|
|
/>
|
|
</Box>
|
|
);
|
|
}
|
|
}
|
|
|
|
class ArtikelMarkenPage extends PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
status: brandAutomat.state.status,
|
|
error: brandAutomat.state.error ? backendErrorFrom({ message: brandAutomat.state.error }) : null,
|
|
brands: brandAutomat.state.brands,
|
|
};
|
|
this.searchRef = createRef();
|
|
this.createRowRef = createRef();
|
|
this.handleRetry = this.handleRetry.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
setLastArticleSku(null);
|
|
|
|
this.unsub = brandAutomat.subscribe(this, (state) => ({
|
|
brands: state.brands,
|
|
status: state.status,
|
|
error: state.error ? backendErrorFrom({ message: state.error }) : null,
|
|
}));
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.unsub?.();
|
|
}
|
|
|
|
handleRetry() {
|
|
// The automat owns fetching; just ask it to load again.
|
|
void brandAutomat.actions.load().catch((err) => notifyError(err));
|
|
}
|
|
|
|
render() {
|
|
const { status, error, brands } = this.state;
|
|
|
|
if (status === 'loading' || status === 'idle') {
|
|
return (
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', py: 6 }}>
|
|
<CircularProgress />
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
if (status === 'failed') {
|
|
return <BackendError error={error} onRetry={this.handleRetry} />;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<ArtikelMarkenSearchField inputRef={this.searchRef} />
|
|
<PanelTileGrid>
|
|
<PanelTile wide={2} minHeight={0} color={PURPLE_PANEL} sx={{ pb: 0 }}>
|
|
<FillSpace
|
|
aboveRef={[this.searchRef]}
|
|
belowRef={this.createRowRef}
|
|
reserveBottom={32}
|
|
minPageSize={8}
|
|
minHeight={0}
|
|
items={brands}
|
|
renderItem={ArtikelMarke}
|
|
/>
|
|
|
|
<ArtikelMarkeNew rowRef={this.createRowRef} />
|
|
</PanelTile>
|
|
</PanelTileGrid>
|
|
</>
|
|
);
|
|
}
|
|
}
|
|
|
|
export { ArtikelMarke, ArtikelMarkeNew, ArtikelMarkenSearchField };
|
|
export default ArtikelMarkenPage;
|