mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
More work on reports. Added Funnel page.
This commit is contained in:
parent
5159dd470f
commit
3847e32f39
59 changed files with 1815 additions and 2370 deletions
|
|
@ -9,9 +9,8 @@ export function useGoalQuery(
|
|||
|
||||
return usePagedQuery({
|
||||
queryKey: ['goal', { websiteId, reportId, ...params }],
|
||||
queryFn: (data: any) => {
|
||||
queryFn: () => {
|
||||
return post(`/reports/goals`, {
|
||||
...data,
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@ export function useGoalsQuery(
|
|||
|
||||
return usePagedQuery({
|
||||
queryKey: ['goals', { websiteId, modified, ...params }],
|
||||
queryFn: (data: any) => {
|
||||
queryFn: () => {
|
||||
return get(`/websites/${websiteId}/goals`, {
|
||||
...data,
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ export function useReportQuery(reportId: string) {
|
|||
|
||||
return useQuery({
|
||||
queryKey: ['report', { reportId, modified }],
|
||||
queryFn: (data: any) => {
|
||||
return get(`/reports/${reportId}`, {
|
||||
...data,
|
||||
});
|
||||
queryFn: () => {
|
||||
return get(`/reports/${reportId}`);
|
||||
},
|
||||
enabled: !!reportId,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useReportsQuery({ websiteId, teamId }: { websiteId?: string; teamId?: string }) {
|
||||
const { modified } = useModified(`reports`);
|
||||
export function useReportsQuery({ websiteId, type }: { websiteId: string; type?: string }) {
|
||||
const { modified } = useModified(`reports:${type}`);
|
||||
const { get } = useApi();
|
||||
|
||||
return usePagedQuery({
|
||||
queryKey: ['reports', { websiteId, teamId, modified }],
|
||||
queryFn: (params: any) => {
|
||||
return get('/reports', { websiteId, teamId, ...params });
|
||||
},
|
||||
queryKey: ['reports', { websiteId, type, modified }],
|
||||
queryFn: async () => get('/reports', { websiteId, type }),
|
||||
enabled: !!websiteId && !!type,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export function useResultQuery<T>(
|
|||
|
||||
return useQuery<T>({
|
||||
queryKey: ['reports', type, params],
|
||||
queryFn: () => post(`/reports/${type}`, params),
|
||||
queryFn: () => post(`/reports/${type}`, { type, ...params }),
|
||||
enabled: !!type,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ export function useWebsiteSessionsQuery(
|
|||
|
||||
return usePagedQuery({
|
||||
queryKey: ['sessions', { websiteId, modified, ...params, ...filters }],
|
||||
queryFn: (data: any) => {
|
||||
queryFn: () => {
|
||||
return get(`/websites/${websiteId}/sessions`, {
|
||||
...data,
|
||||
...params,
|
||||
...filters,
|
||||
pageSize: 20,
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ export function useWebsites(
|
|||
|
||||
return usePagedQuery({
|
||||
queryKey: ['websites', { userId, teamId, modified, ...params }],
|
||||
queryFn: (data: any) => {
|
||||
queryFn: () => {
|
||||
return get(teamId ? `/teams/${teamId}/websites` : `/users/${userId || user.id}/websites`, {
|
||||
...data,
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
100
src/components/input/ReportEditButton.tsx
Normal file
100
src/components/input/ReportEditButton.tsx
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import { ReactNode, useState } from 'react';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { useDeleteQuery } from '@/components/hooks/queries/useDeleteQuery';
|
||||
import {
|
||||
AlertDialog,
|
||||
Button,
|
||||
Icon,
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuTrigger,
|
||||
Modal,
|
||||
Popover,
|
||||
Text,
|
||||
Row,
|
||||
} from '@umami/react-zen';
|
||||
import { Edit, More, Trash } from '@/components/icons';
|
||||
|
||||
export function ReportEditButton({
|
||||
id,
|
||||
name,
|
||||
type,
|
||||
children,
|
||||
onDelete,
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
onDelete?: () => void;
|
||||
children: ({ close }: { close: () => void }) => ReactNode;
|
||||
}) {
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const [showEdit, setShowEdit] = useState(false);
|
||||
const [showDelete, setShowDelete] = useState(false);
|
||||
const { mutate, touch } = useDeleteQuery(`/reports/${id}`);
|
||||
|
||||
const handleAction = (id: any) => {
|
||||
if (id === 'edit') {
|
||||
setShowEdit(true);
|
||||
} else if (id === 'delete') {
|
||||
setShowDelete(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setShowEdit(false);
|
||||
setShowDelete(false);
|
||||
};
|
||||
|
||||
const handleDelete = async () => {
|
||||
mutate(null, {
|
||||
onSuccess: async () => {
|
||||
touch(`reports:${type}`);
|
||||
setShowDelete(false);
|
||||
onDelete?.();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuTrigger>
|
||||
<Button variant="quiet">
|
||||
<Icon>
|
||||
<More />
|
||||
</Icon>
|
||||
</Button>
|
||||
<Popover placement="bottom">
|
||||
<Menu onAction={handleAction}>
|
||||
<MenuItem id="edit">
|
||||
<Icon>
|
||||
<Edit />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.edit)}</Text>
|
||||
</MenuItem>
|
||||
<MenuItem id="delete">
|
||||
<Icon>
|
||||
<Trash />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.delete)}</Text>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Popover>
|
||||
</MenuTrigger>
|
||||
<Modal isOpen={showEdit || showDelete} isDismissable={true}>
|
||||
{showEdit && children({ close: handleClose })}
|
||||
{showDelete && (
|
||||
<AlertDialog
|
||||
title={formatMessage(labels.delete)}
|
||||
onConfirm={handleDelete}
|
||||
onCancel={handleClose}
|
||||
>
|
||||
<Row gap="1">
|
||||
{formatMessage(messages.confirmDelete, { target: <b key={name}>{name}</b> })}
|
||||
</Row>
|
||||
</AlertDialog>
|
||||
)}
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -277,7 +277,6 @@ export const labels = defineMessages({
|
|||
addStep: { id: 'label.add-step', defaultMessage: 'Add step' },
|
||||
goal: { id: 'label.goal', defaultMessage: 'Goal' },
|
||||
goals: { id: 'label.goals', defaultMessage: 'Goals' },
|
||||
addGoal: { id: 'label.add-goal', defaultMessage: 'Add Goal' },
|
||||
goalsDescription: {
|
||||
id: 'label.goals-description',
|
||||
defaultMessage: 'Track your goals for pageviews and events.',
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@
|
|||
|
||||
.positive {
|
||||
color: var(--success-color);
|
||||
background: color-mix(in srgb, var(--success-color), var(--background-color) 85%);
|
||||
background: color-mix(in srgb, var(--success-color), var(--background-color) 95%);
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: var(--danger-color);
|
||||
background: color-mix(in srgb, var(--danger-color), var(--background-color) 85%);
|
||||
background: color-mix(in srgb, var(--danger-color), var(--background-color) 95%);
|
||||
}
|
||||
|
||||
.neutral {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import classNames from 'classnames';
|
||||
import { Icon, Text } from '@umami/react-zen';
|
||||
import { ReactNode } from 'react';
|
||||
import { HTMLAttributes, ReactNode } from 'react';
|
||||
import { Arrow } from '@/components/icons';
|
||||
import styles from './ChangeLabel.module.css';
|
||||
|
||||
export function ChangeLabel({
|
||||
value,
|
||||
size,
|
||||
title,
|
||||
reverseColors,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: {
|
||||
value: number;
|
||||
size?: 'xs' | 'sm' | 'md' | 'lg';
|
||||
|
|
@ -19,7 +19,7 @@ export function ChangeLabel({
|
|||
showPercentage?: boolean;
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
} & HTMLAttributes<HTMLDivElement>) {
|
||||
const positive = value >= 0;
|
||||
const negative = value < 0;
|
||||
const neutral = value === 0 || isNaN(value);
|
||||
|
|
@ -27,12 +27,12 @@ export function ChangeLabel({
|
|||
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={classNames(styles.label, className, {
|
||||
[styles.positive]: good,
|
||||
[styles.negative]: !good,
|
||||
[styles.neutral]: neutral,
|
||||
})}
|
||||
title={title}
|
||||
>
|
||||
{!neutral && (
|
||||
<Icon rotate={positive ? -90 : 90} size={size}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue