New filter bar and filter edit form.

This commit is contained in:
Mike Cao 2025-04-09 21:15:12 -07:00
parent 47e89afcb4
commit bfdd3f9525
19 changed files with 300 additions and 150 deletions

View file

@ -1,52 +1,14 @@
import { MouseEvent } from 'react';
import {
Button,
Icon,
Icons,
Popover,
MenuTrigger,
Text,
Row,
TooltipTrigger,
Tooltip,
} from '@umami/react-zen';
import {
useDateRange,
useFields,
useNavigation,
useMessages,
useFormat,
useFilters,
} from '@/components/hooks';
import { FieldFilterEditForm } from '@/app/(main)/reports/[reportId]/FieldFilterEditForm';
import { FILTER_COLUMNS, OPERATOR_PREFIXES } from '@/lib/constants';
import { isSearchOperator, parseParameterValue } from '@/lib/params';
import { Button, Icon, Icons, Text, Row, TooltipTrigger, Tooltip } from '@umami/react-zen';
import { useNavigation, useMessages, useFormat, useFilters } from '@/components/hooks';
import { isSearchOperator } from '@/lib/params';
import { WebsiteFilterButton } from '@/app/(main)/websites/[websiteId]/WebsiteFilterButton';
export function FilterBar({ websiteId }: { websiteId: string }) {
const { formatMessage, labels } = useMessages();
const { formatValue } = useFormat();
const { dateRange } = useDateRange(websiteId);
const {
router,
renderUrl,
query: { view },
} = useNavigation();
const { fields } = useFields();
const { operatorLabels } = useFilters();
const { startDate, endDate } = dateRange;
const { query } = useNavigation();
const params = Object.keys(query).reduce((obj, key) => {
if (FILTER_COLUMNS[key]) {
obj[key] = query[key];
}
return obj;
}, {});
if (Object.keys(params).filter(key => params[key]).length === 0) {
return null;
}
const { router, renderUrl } = useNavigation();
const { filters, operatorLabels } = useFilters();
const handleCloseFilter = (param: string, e: MouseEvent) => {
e.stopPropagation();
@ -54,25 +16,17 @@ export function FilterBar({ websiteId }: { websiteId: string }) {
};
const handleResetFilter = () => {
router.push(renderUrl({ view }, true));
router.push(renderUrl(false));
};
const handleChangeFilter = (
values: { name: string; operator: string; value: string },
close: () => void,
) => {
const { name, operator, value } = values;
const prefix = OPERATOR_PREFIXES[operator];
router.push(renderUrl({ [name]: prefix + value }));
close();
};
if (!filters.length) {
return null;
}
return (
<Row
className="dark-theme"
gap="3"
backgroundColor="3"
backgroundColor="2"
alignItems="center"
justifyContent="space-between"
paddingY="3"
@ -85,46 +39,26 @@ export function FilterBar({ websiteId }: { websiteId: string }) {
<Text color="11" weight="bold">
{formatMessage(labels.filters)}
</Text>
{Object.keys(params).map(key => {
if (!params[key]) {
return null;
}
const label = fields.find(f => f.name === key)?.label;
const { operator, value } = parseParameterValue(params[key]);
{Object.keys(filters).map(key => {
const filter = filters[key];
const { name, label, operator, value } = filter;
const paramValue = isSearchOperator(operator) ? value : formatValue(value, key);
return (
<MenuTrigger key={key}>
<Button variant="outline">
<Button key={name} variant="outline">
<Row alignItems="center" gap="6">
<Row alignItems="center" gap="2">
<Text weight="bold">{label}</Text>
<Text transform="uppercase" color="muted">
<Text transform="uppercase" color="11" size="1">
{operatorLabels[operator]}
</Text>
<Text weight="bold">{paramValue}</Text>
<Icon onClick={e => handleCloseFilter(key, e)}>
<Icons.Close />
</Icon>
</Row>
</Button>
<Popover placement="start">
{({ close }: any) => {
return (
<FieldFilterEditForm
label={label}
type="string"
websiteId={websiteId}
name={key}
operator={operator}
defaultValue={value}
startDate={startDate}
endDate={endDate}
onChange={values => handleChangeFilter(values, close)}
/>
);
}}
</Popover>
</MenuTrigger>
<Icon onClick={e => handleCloseFilter(name, e)}>
<Icons.Close />
</Icon>
</Row>
</Button>
);
})}
<WebsiteFilterButton websiteId={websiteId} alignment="center" showText={false} />

View file

@ -20,7 +20,7 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
const { domain } = useContext(WebsiteContext);
const handleSelect = (key: any) => {
router.push(renderUrl({ view: key }), { scroll: false });
router.push(renderUrl({ view: key }));
};
const buttons = [

View file

@ -20,7 +20,7 @@ export function ReferrersTable({ allowFilter, ...props }: ReferrersTableProps) {
const { formatMessage, labels } = useMessages();
const handleSelect = (key: any) => {
router.push(renderUrl({ view: key }), { scroll: false });
router.push(renderUrl({ view: key }));
};
const buttons = [