mirror of
https://github.com/umami-software/umami.git
synced 2026-02-16 02:25:35 +01:00
implement UTM filters and fields
This commit is contained in:
parent
7514af4236
commit
49adaa32d0
11 changed files with 336 additions and 55 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { Button, Column, Grid, List, ListItem } from '@umami/react-zen';
|
||||
import { Button, Column, Grid, List, ListItem, ListSection } from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useFields, useMessages } from '@/components/hooks';
|
||||
import { type FieldGroup, useFields, useMessages } from '@/components/hooks';
|
||||
|
||||
export function FieldSelectForm({
|
||||
selectedFields = [],
|
||||
|
|
@ -13,7 +13,7 @@ export function FieldSelectForm({
|
|||
}) {
|
||||
const [selected, setSelected] = useState(selectedFields);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { fields } = useFields();
|
||||
const { fields, groupLabels } = useFields();
|
||||
|
||||
const handleChange = (value: string[]) => {
|
||||
setSelected(value);
|
||||
|
|
@ -24,17 +24,38 @@ export function FieldSelectForm({
|
|||
onClose();
|
||||
};
|
||||
|
||||
const groupedFields = fields
|
||||
.filter(field => field.name !== 'event')
|
||||
.reduce(
|
||||
(acc, field) => {
|
||||
const group = field.group;
|
||||
if (!acc[group]) {
|
||||
acc[group] = [];
|
||||
}
|
||||
acc[group].push(field);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<FieldGroup, typeof fields>,
|
||||
);
|
||||
|
||||
return (
|
||||
<Column gap="6">
|
||||
<List value={selected} onChange={handleChange} selectionMode="multiple">
|
||||
{fields.map(({ name, label }) => {
|
||||
return (
|
||||
<ListItem key={name} id={name}>
|
||||
{label}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
<Column gap="3" overflowY="auto" maxHeight="400px">
|
||||
<List value={selected} onChange={handleChange} selectionMode="multiple">
|
||||
{groupLabels.map(({ key: groupKey, label }) => {
|
||||
const groupFields = groupedFields[groupKey];
|
||||
return (
|
||||
<ListSection key={groupKey} title={label}>
|
||||
{groupFields.map(field => (
|
||||
<ListItem key={field.name} id={field.name}>
|
||||
{field.filterLabel}
|
||||
</ListItem>
|
||||
))}
|
||||
</ListSection>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Column>
|
||||
<Grid columns="1fr 1fr" gap>
|
||||
<Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>
|
||||
<Button onPress={handleApply} variant="primary">
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@ import {
|
|||
AppWindow,
|
||||
Cpu,
|
||||
Earth,
|
||||
Fingerprint,
|
||||
Globe,
|
||||
KeyRound,
|
||||
Landmark,
|
||||
Languages,
|
||||
Laptop,
|
||||
Layers,
|
||||
Link2,
|
||||
LogIn,
|
||||
LogOut,
|
||||
MapPin,
|
||||
|
|
@ -15,9 +19,11 @@ import {
|
|||
Monitor,
|
||||
Network,
|
||||
Search,
|
||||
Send,
|
||||
Share2,
|
||||
SquareSlash,
|
||||
Tag,
|
||||
Target,
|
||||
Type,
|
||||
} from '@/components/icons';
|
||||
import { Lightning } from '@/components/svg';
|
||||
|
|
@ -154,6 +160,41 @@ export function WebsiteExpandedMenu({
|
|||
},
|
||||
].filter(filterExcluded),
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.utm),
|
||||
items: [
|
||||
{
|
||||
id: 'utmSource',
|
||||
label: formatMessage(labels.source),
|
||||
path: updateParams({ view: 'utmSource' }),
|
||||
icon: <Link2 />,
|
||||
},
|
||||
{
|
||||
id: 'utmMedium',
|
||||
label: formatMessage(labels.medium),
|
||||
path: updateParams({ view: 'utmMedium' }),
|
||||
icon: <Send />,
|
||||
},
|
||||
{
|
||||
id: 'utmCampaign',
|
||||
label: formatMessage(labels.campaign),
|
||||
path: updateParams({ view: 'utmCampaign' }),
|
||||
icon: <Target />,
|
||||
},
|
||||
{
|
||||
id: 'utmContent',
|
||||
label: formatMessage(labels.content),
|
||||
path: updateParams({ view: 'utmContent' }),
|
||||
icon: <Layers />,
|
||||
},
|
||||
{
|
||||
id: 'utmTerm',
|
||||
label: formatMessage(labels.term),
|
||||
path: updateParams({ view: 'utmTerm' }),
|
||||
icon: <KeyRound />,
|
||||
},
|
||||
].filter(filterExcluded),
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.other),
|
||||
items: [
|
||||
|
|
@ -173,7 +214,7 @@ export function WebsiteExpandedMenu({
|
|||
id: 'distinctId',
|
||||
label: formatMessage(labels.distinctId),
|
||||
path: updateParams({ view: 'distinctId' }),
|
||||
icon: <Tag />,
|
||||
icon: <Fingerprint />,
|
||||
},
|
||||
{
|
||||
id: 'tag',
|
||||
|
|
|
|||
|
|
@ -88,6 +88,31 @@ export function CompareTables({ websiteId }: { websiteId: string }) {
|
|||
label: formatMessage(labels.events),
|
||||
path: renderPath('event'),
|
||||
},
|
||||
{
|
||||
id: 'utmSource',
|
||||
label: formatMessage(labels.utmSource),
|
||||
path: renderPath('utmSource'),
|
||||
},
|
||||
{
|
||||
id: 'utmMedium',
|
||||
label: formatMessage(labels.utmMedium),
|
||||
path: renderPath('utmMedium'),
|
||||
},
|
||||
{
|
||||
id: 'utmCampaign',
|
||||
label: formatMessage(labels.utmCampaign),
|
||||
path: renderPath('utmCampaign'),
|
||||
},
|
||||
{
|
||||
id: 'utmContent',
|
||||
label: formatMessage(labels.utmContent),
|
||||
path: renderPath('utmContent'),
|
||||
},
|
||||
{
|
||||
id: 'utmTerm',
|
||||
label: formatMessage(labels.utmTerm),
|
||||
path: renderPath('utmTerm'),
|
||||
},
|
||||
{
|
||||
id: 'hostname',
|
||||
label: formatMessage(labels.hostname),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue