mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 06:07:17 +01:00
Filtering via FilterBar.
This commit is contained in:
parent
da173779e0
commit
0a43ef7b1b
9 changed files with 83 additions and 26 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, Key } from 'react';
|
||||
import { Grid, Row, Column, Label, List, ListItem, Button, Heading } from '@umami/react-zen';
|
||||
import { useFilters, useMessages } from '@/components/hooks';
|
||||
import { useDateRange, useFilters, useMessages } from '@/components/hooks';
|
||||
import { FilterRecord } from '@/components/common/FilterRecord';
|
||||
import { Empty } from '@/components/common/Empty';
|
||||
|
||||
|
|
@ -11,10 +11,13 @@ export interface FilterEditFormProps {
|
|||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export function FilterEditForm({ data = [], onChange, onClose }: FilterEditFormProps) {
|
||||
export function FilterEditForm({ websiteId, data = [], onChange, onClose }: FilterEditFormProps) {
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const [filters, setFilters] = useState(data);
|
||||
const { fields } = useFilters();
|
||||
const {
|
||||
dateRange: { startDate, endDate },
|
||||
} = useDateRange(websiteId);
|
||||
|
||||
const updateFilter = (name: string, props: { [key: string]: any }) => {
|
||||
setFilters(filters =>
|
||||
|
|
@ -66,6 +69,10 @@ export function FilterEditForm({ data = [], onChange, onClose }: FilterEditFormP
|
|||
return (
|
||||
<FilterRecord
|
||||
key={filter.name}
|
||||
websiteId={websiteId}
|
||||
type={filter.name}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
{...filter}
|
||||
onSelect={handleSelect}
|
||||
onRemove={handleRemove}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import { Grid, Column, TextField, Label, ListItem, Select, Icon, Button } from '@umami/react-zen';
|
||||
import { useFilters } from '@/components/hooks';
|
||||
import { useState } from 'react';
|
||||
import { Grid, Column, TextField, Label, Select, Icon, Button, ListItem } from '@umami/react-zen';
|
||||
import { useFilters, useFormat, useWebsiteValuesQuery } from '@/components/hooks';
|
||||
import { Close } from '@/components/icons';
|
||||
import { isSearchOperator } from '@/lib/params';
|
||||
|
||||
export interface FilterRecordProps {
|
||||
websiteId: string;
|
||||
type: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
name: string;
|
||||
operator: string;
|
||||
value: string;
|
||||
|
|
@ -12,6 +18,10 @@ export interface FilterRecordProps {
|
|||
}
|
||||
|
||||
export function FilterRecord({
|
||||
websiteId,
|
||||
type,
|
||||
startDate,
|
||||
endDate,
|
||||
name,
|
||||
operator,
|
||||
value,
|
||||
|
|
@ -20,16 +30,40 @@ export function FilterRecord({
|
|||
onChange,
|
||||
}: FilterRecordProps) {
|
||||
const { fields, operators } = useFilters();
|
||||
const [selected, setSelected] = useState(value);
|
||||
const [search, setSearch] = useState('');
|
||||
const { formatValue } = useFormat();
|
||||
const { data, isLoading } = useWebsiteValuesQuery({
|
||||
websiteId,
|
||||
type,
|
||||
search,
|
||||
startDate,
|
||||
endDate,
|
||||
});
|
||||
const isSearch = isSearchOperator(operator);
|
||||
|
||||
const handleSearch = value => {
|
||||
setSearch(value);
|
||||
};
|
||||
|
||||
const handleSelectOperator = value => {
|
||||
onSelect?.(name, value);
|
||||
};
|
||||
|
||||
const handleSelectValue = value => {
|
||||
setSelected(value);
|
||||
onChange?.(name, value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Column>
|
||||
<Label>{fields.find(f => f.name === name)?.label}</Label>
|
||||
<Grid columns="1fr auto" gap>
|
||||
<Grid columns="200px 1fr" gap>
|
||||
<Select
|
||||
items={operators.filter(({ type }) => type === 'string')}
|
||||
value={operator}
|
||||
onSelectionChange={value => onSelect?.(name, value)}
|
||||
onSelectionChange={handleSelectOperator}
|
||||
>
|
||||
{({ name, label }: any) => {
|
||||
return (
|
||||
|
|
@ -39,7 +73,28 @@ export function FilterRecord({
|
|||
);
|
||||
}}
|
||||
</Select>
|
||||
<TextField value={value} onChange={e => onChange?.(name, e.target.value)} />
|
||||
{isSearch && (
|
||||
<TextField value={selected} defaultValue={selected} onChange={handleSelectValue} />
|
||||
)}
|
||||
{!isSearch && (
|
||||
<Select
|
||||
items={data}
|
||||
value={selected}
|
||||
onChange={handleSelectValue}
|
||||
searchValue={search}
|
||||
onSearch={handleSearch}
|
||||
isLoading={isLoading}
|
||||
allowSearch
|
||||
>
|
||||
{data?.map(({ value }) => {
|
||||
return (
|
||||
<ListItem key={value} id={value}>
|
||||
{formatValue(value, type)}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</Grid>
|
||||
<Column justifyContent="flex-end">
|
||||
<Button variant="quiet" onPress={() => onRemove?.(name)}>
|
||||
|
|
@ -49,6 +104,6 @@ export function FilterRecord({
|
|||
</Button>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue