refactor(admin): compose the inventory filters from dimensions (#188)
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { useState } from 'react';
|
||||
import Button from 'antd/es/button';
|
||||
import { FilterOutlined } from '@ant-design/icons';
|
||||
import type { Category, Tag } from '../api';
|
||||
import { ItemFilters, activeFilterCount } from '../filters';
|
||||
import FilterDrawer from '../components/FilterDrawer';
|
||||
import ActiveFilterChips from '../components/ActiveFilterChips';
|
||||
import { ItemFilters } from '../filters';
|
||||
import FilterBar from '../components/filters/FilterBar';
|
||||
import {
|
||||
categoryDimension,
|
||||
priceDimension,
|
||||
statusDimension,
|
||||
tagDimension
|
||||
} from '../components/filters/standardDimensions';
|
||||
|
||||
type Props = Readonly<{
|
||||
categories: Category[];
|
||||
@@ -15,16 +17,11 @@ type Props = Readonly<{
|
||||
resultCount: number;
|
||||
}>;
|
||||
|
||||
// The same flyout the storefront uses, rather than the row of controls this
|
||||
// used to be (#169).
|
||||
//
|
||||
// That row was deliberate — it carried a comment arguing that hiding the
|
||||
// controls above a data table costs more than the space it saves, and that a
|
||||
// drawer overlays the very rows being filtered. Both are true, and both are
|
||||
// traded for the two screens asking the same questions through the same UI.
|
||||
// The chips are what makes the trade bearable: the active filter stays readable
|
||||
// beside the button without opening anything, which is what the always-visible
|
||||
// row was really protecting.
|
||||
// Status, and no favorites: pending is excluded from every public read, so
|
||||
// Published and Unpublished are distinctions only the admin can draw, and
|
||||
// favoriting is a customer's idea.
|
||||
const DIMENSIONS = [categoryDimension, tagDimension, priceDimension, statusDimension];
|
||||
|
||||
export default function InventoryFilters({
|
||||
categories,
|
||||
tags,
|
||||
@@ -33,45 +30,19 @@ export default function InventoryFilters({
|
||||
onClear,
|
||||
resultCount
|
||||
}: Props) {
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
|
||||
// Status lives in the drawer here, unlike on the storefront, so it belongs in
|
||||
// the button's tally — activeFilterCount leaves it out precisely because the
|
||||
// storefront filters status outside the drawer.
|
||||
const activeCount = activeFilterCount(filters) + (filters.status === null ? 0 : 1);
|
||||
|
||||
return (
|
||||
<div className="inventory-filters">
|
||||
<Button
|
||||
icon={<FilterOutlined />}
|
||||
onClick={() => setDrawerOpen(true)}
|
||||
type={activeCount ? 'primary' : 'default'}
|
||||
>
|
||||
Filters{activeCount ? ` (${activeCount})` : ''}
|
||||
</Button>
|
||||
|
||||
<ActiveFilterChips
|
||||
categories={categories}
|
||||
tags={tags}
|
||||
<FilterBar
|
||||
dimensions={DIMENSIONS}
|
||||
filters={filters}
|
||||
onChange={onChange}
|
||||
onClear={onClear}
|
||||
showStatus
|
||||
/>
|
||||
|
||||
<FilterDrawer
|
||||
open={drawerOpen}
|
||||
onClose={() => setDrawerOpen(false)}
|
||||
categories={categories}
|
||||
tags={tags}
|
||||
// No slider: the admin has no catalogue-wide price range to bound one
|
||||
// with, and inventing bounds would misreport where the prices are.
|
||||
priceRange={null}
|
||||
filters={filters}
|
||||
onChange={onChange}
|
||||
onClear={onClear}
|
||||
resultCount={resultCount}
|
||||
showStatus
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user