filter
This commit is contained in:
@@ -21,7 +21,7 @@ export const NAV_ITEMS = [
|
|||||||
|
|
||||||
export const SUB_NAV = {
|
export const SUB_NAV = {
|
||||||
'/artikel': [
|
'/artikel': [
|
||||||
{ segment: '', label: 'Übersicht', icon: ViewListIcon },
|
{ segment: '', icon: ViewListIcon },
|
||||||
{ segment: 'kategorien', label: 'Kategorien', icon: CategoryIcon },
|
{ segment: 'kategorien', label: 'Kategorien', icon: CategoryIcon },
|
||||||
{ segment: 'lager', label: 'Lager', icon: WarehouseIcon },
|
{ segment: 'lager', label: 'Lager', icon: WarehouseIcon },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import Paper from '@mui/material/Paper';
|
|||||||
import TextField from '@mui/material/TextField';
|
import TextField from '@mui/material/TextField';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
import ClearIcon from '@mui/icons-material/Clear';
|
||||||
import { article } from '../../api';
|
import { article } from '../../api';
|
||||||
import { formatPrice } from '../../utils/price';
|
import { formatPrice } from '../../utils/price';
|
||||||
|
|
||||||
@@ -44,7 +45,8 @@ function formatCategoryList(catStr, facets) {
|
|||||||
if (!catStr) return '';
|
if (!catStr) return '';
|
||||||
return catStr
|
return catStr
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((id) => facets[id]?.name ?? id)
|
.map((id) => facets[id]?.name)
|
||||||
|
.filter(Boolean)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ function ResultsPagination({ offset, totalCount, pageCount, currentPage, onPageC
|
|||||||
onChange={onPageChange}
|
onChange={onPageChange}
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@@ -186,7 +189,8 @@ class ArtikelUebersichtPage extends Component {
|
|||||||
|
|
||||||
const facetEntries = categoryFacets
|
const facetEntries = categoryFacets
|
||||||
? Object.entries(categoryFacets)
|
? Object.entries(categoryFacets)
|
||||||
.map(([id, { count, name, parent }]) => ({
|
.filter(([, meta]) => meta?.name)
|
||||||
|
.map(([id, { count, name }]) => ({
|
||||||
id,
|
id,
|
||||||
count,
|
count,
|
||||||
name,
|
name,
|
||||||
@@ -198,6 +202,8 @@ class ArtikelUebersichtPage extends Component {
|
|||||||
const pageCount = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));
|
const pageCount = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));
|
||||||
const currentPage = Math.floor(offset / PAGE_SIZE) + 1;
|
const currentPage = Math.floor(offset / PAGE_SIZE) + 1;
|
||||||
const emptyRowCount = Math.max(0, PAGE_SIZE - recordset.length);
|
const emptyRowCount = Math.max(0, PAGE_SIZE - recordset.length);
|
||||||
|
const showResultsPanel =
|
||||||
|
facetEntries.length > 0 || recordset.length > 0 || (searchActive && !error && totalCount === 0);
|
||||||
|
|
||||||
const handlePageChange = (_e, page) => {
|
const handlePageChange = (_e, page) => {
|
||||||
this.updateParams(input, filterParam, (page - 1) * PAGE_SIZE);
|
this.updateParams(input, filterParam, (page - 1) * PAGE_SIZE);
|
||||||
@@ -211,15 +217,15 @@ class ArtikelUebersichtPage extends Component {
|
|||||||
autoFocus
|
autoFocus
|
||||||
type="search"
|
type="search"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
inputProps={{
|
|
||||||
autocapitalize: 'off',
|
|
||||||
autocorrect: 'off',
|
|
||||||
spellcheck: false,
|
|
||||||
}}
|
|
||||||
placeholder="Artikel suchen (EAN, Artikelnr., Name, Barcode)…"
|
placeholder="Artikel suchen (EAN, Artikelnr., Name, Barcode)…"
|
||||||
value={input}
|
value={input}
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
|
htmlInput: {
|
||||||
|
spellCheck: false,
|
||||||
|
autoCapitalize: 'off',
|
||||||
|
autoCorrect: 'off',
|
||||||
|
},
|
||||||
input: {
|
input: {
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
@@ -243,11 +249,7 @@ class ArtikelUebersichtPage extends Component {
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{searchActive && !error && totalCount === 0 && (
|
{showResultsPanel && (
|
||||||
<Typography color="text.secondary">Keine Artikel gefunden.</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(facetEntries.length > 0 || recordset.length > 0) && (
|
|
||||||
<Box sx={{ display: 'flex', gap: 3, alignItems: 'flex-start' }}>
|
<Box sx={{ display: 'flex', gap: 3, alignItems: 'flex-start' }}>
|
||||||
{facetEntries.length > 0 && (
|
{facetEntries.length > 0 && (
|
||||||
<Paper variant="outlined" sx={{ width: 220, flexShrink: 0, overflow: 'hidden' }}>
|
<Paper variant="outlined" sx={{ width: 220, flexShrink: 0, overflow: 'hidden' }}>
|
||||||
@@ -258,29 +260,40 @@ class ArtikelUebersichtPage extends Component {
|
|||||||
Kategorien
|
Kategorien
|
||||||
</Typography>
|
</Typography>
|
||||||
<List dense disablePadding>
|
<List dense disablePadding>
|
||||||
{facetEntries.map(({ id, count, name, depth }) => (
|
{facetEntries.map(({ id, count, name, depth }) => {
|
||||||
<ListItemButton
|
const selected = categories.includes(id);
|
||||||
key={id}
|
return (
|
||||||
selected={categories.includes(id)}
|
<ListItemButton
|
||||||
onClick={() => {
|
key={id}
|
||||||
const next = categories.includes(id)
|
selected={selected}
|
||||||
? categories.filter((c) => c !== id)
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
: [...categories, id];
|
onClick={() => {
|
||||||
this.updateParams(input, buildFilter(next), 0);
|
const next = selected
|
||||||
}}
|
? categories.filter((c) => c !== id)
|
||||||
sx={{ pl: 2 + depth * 1.5 }}
|
: [...categories, id];
|
||||||
>
|
this.updateParams(input, buildFilter(next), 0);
|
||||||
<ListItemText
|
}}
|
||||||
primary={`${name ?? id} (${count})`}
|
sx={{ pl: 2 + depth * 1.5 }}
|
||||||
slotProps={{ primary: { variant: 'body2' } }}
|
>
|
||||||
/>
|
<ListItemText
|
||||||
</ListItemButton>
|
primary={`${name} (${count})`}
|
||||||
))}
|
slotProps={{ primary: { variant: 'body2' } }}
|
||||||
|
/>
|
||||||
|
{selected && (
|
||||||
|
<ClearIcon fontSize="small" color="action" sx={{ ml: 1, flexShrink: 0 }} />
|
||||||
|
)}
|
||||||
|
</ListItemButton>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</List>
|
</List>
|
||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box sx={{ flexGrow: 1, minWidth: 0 }}>
|
<Box sx={{ flexGrow: 1, minWidth: 0 }}>
|
||||||
|
{searchActive && !error && totalCount === 0 && (
|
||||||
|
<Typography color="text.secondary">Keine Artikel gefunden.</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
{recordset.length > 0 && (
|
{recordset.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<ResultsPagination
|
<ResultsPagination
|
||||||
|
|||||||
Reference in New Issue
Block a user