mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 06:07:17 +01:00
Progress check-in for date compare.
This commit is contained in:
parent
24af06f3aa
commit
8cf7985dac
25 changed files with 181 additions and 61 deletions
|
|
@ -26,7 +26,7 @@ export function BarChart(props: BarChartProps) {
|
|||
stacked = false,
|
||||
} = props;
|
||||
|
||||
const options = useMemo(() => {
|
||||
const options: any = useMemo(() => {
|
||||
return {
|
||||
scales: {
|
||||
x: {
|
||||
|
|
|
|||
|
|
@ -79,15 +79,19 @@ export function Chart({
|
|||
};
|
||||
|
||||
const updateChart = (data: any) => {
|
||||
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
|
||||
if (data?.datasets[index]) {
|
||||
dataset.data = data?.datasets[index]?.data;
|
||||
if (data.datasets.length === chart.current.data.datasets.length) {
|
||||
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
|
||||
if (data?.datasets[index]) {
|
||||
dataset.data = data?.datasets[index]?.data;
|
||||
|
||||
if (chart.current.legend.legendItems[index]) {
|
||||
chart.current.legend.legendItems[index].text = data?.datasets[index]?.label;
|
||||
if (chart.current.legend.legendItems[index]) {
|
||||
chart.current.legend.legendItems[index].text = data?.datasets[index]?.label;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
chart.current.data.datasets = data.datasets;
|
||||
}
|
||||
|
||||
chart.current.options = options;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@ import { useFilterParams } from '..//useFilterParams';
|
|||
|
||||
export function useWebsitePageviews(
|
||||
websiteId: string,
|
||||
compare?: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const params = useFilterParams(websiteId);
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['websites:pageviews', { websiteId, ...params }],
|
||||
queryFn: () => get(`/websites/${websiteId}/pageviews`, params),
|
||||
queryKey: ['websites:pageviews', { websiteId, ...params, compare }],
|
||||
queryFn: () => get(`/websites/${websiteId}/pageviews`, { ...params, compare }),
|
||||
enabled: !!websiteId,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,19 +1,25 @@
|
|||
import { getMinimumUnit, parseDateRange } from 'lib/date';
|
||||
import { setItem } from 'next-basics';
|
||||
import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants';
|
||||
import websiteStore, { setWebsiteDateRange } from 'store/websites';
|
||||
import { DATE_RANGE_CONFIG, DEFAULT_DATE_COMPARE, DEFAULT_DATE_RANGE } from 'lib/constants';
|
||||
import websiteStore, { setWebsiteDateRange, setWebsiteDateCompare } from 'store/websites';
|
||||
import appStore, { setDateRange } from 'store/app';
|
||||
import { DateRange } from 'lib/types';
|
||||
import { useLocale } from './useLocale';
|
||||
import { useApi } from './queries/useApi';
|
||||
|
||||
export function useDateRange(websiteId?: string): [DateRange, (value: string | DateRange) => void] {
|
||||
export function useDateRange(websiteId?: string): {
|
||||
dateRange: DateRange;
|
||||
saveDateRange: (value: string | DateRange) => void;
|
||||
dateCompare: string;
|
||||
saveDateCompare: (value: string) => void;
|
||||
} {
|
||||
const { get } = useApi();
|
||||
const { locale } = useLocale();
|
||||
const websiteConfig = websiteStore(state => state[websiteId]?.dateRange);
|
||||
const defaultConfig = DEFAULT_DATE_RANGE;
|
||||
const globalConfig = appStore(state => state.dateRange);
|
||||
const dateRange = parseDateRange(websiteConfig || globalConfig || defaultConfig, locale);
|
||||
const dateCompare = websiteStore(state => state[websiteId]?.dateCompare || DEFAULT_DATE_COMPARE);
|
||||
|
||||
const saveDateRange = async (value: DateRange | string) => {
|
||||
if (websiteId) {
|
||||
|
|
@ -45,7 +51,11 @@ export function useDateRange(websiteId?: string): [DateRange, (value: string | D
|
|||
}
|
||||
};
|
||||
|
||||
return [dateRange, saveDateRange];
|
||||
const saveDateCompare = (value: string) => {
|
||||
setWebsiteDateCompare(websiteId, value);
|
||||
};
|
||||
|
||||
return { dateRange, saveDateRange, dateCompare, saveDateCompare };
|
||||
}
|
||||
|
||||
export default useDateRange;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useTimezone } from './useTimezone';
|
|||
import { zonedTimeToUtc } from 'date-fns-tz';
|
||||
|
||||
export function useFilterParams(websiteId: string) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { dateRange } = useDateRange(websiteId);
|
||||
const { startDate, endDate, unit } = dateRange;
|
||||
const { timezone } = useTimezone();
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export function RefreshButton({
|
|||
isLoading?: boolean;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { dateRange } = useDateRange(websiteId);
|
||||
|
||||
function handleClick() {
|
||||
if (!isLoading && dateRange) {
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ import { DateRange } from 'lib/types';
|
|||
|
||||
export function WebsiteDateFilter({ websiteId }: { websiteId: string }) {
|
||||
const { dir } = useLocale();
|
||||
const [dateRange, setDateRange] = useDateRange(websiteId);
|
||||
const { dateRange, saveDateRange } = useDateRange(websiteId);
|
||||
const { value, startDate, endDate, offset } = dateRange;
|
||||
const disableForward =
|
||||
value === 'all' || isAfter(getOffsetDateRange(dateRange, 1).startDate, new Date());
|
||||
|
||||
const handleChange = (value: string | DateRange) => {
|
||||
setDateRange(value);
|
||||
saveDateRange(value);
|
||||
};
|
||||
|
||||
const handleIncrement = (increment: number) => {
|
||||
setDateRange(getOffsetDateRange(dateRange, increment));
|
||||
saveDateRange(getOffsetDateRange(dateRange, increment));
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ export interface EventsChartProps {
|
|||
}
|
||||
|
||||
export function EventsChart({ websiteId, className }: EventsChartProps) {
|
||||
const [{ startDate, endDate, unit }] = useDateRange(websiteId);
|
||||
const {
|
||||
dateRange: { startDate, endDate, unit },
|
||||
} = useDateRange(websiteId);
|
||||
const { locale } = useLocale();
|
||||
const { data, isLoading } = useWebsiteEvents(websiteId);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export function FilterTags({
|
|||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { formatValue } = useFormat();
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { dateRange } = useDateRange(websiteId);
|
||||
const {
|
||||
router,
|
||||
renderUrl,
|
||||
|
|
|
|||
|
|
@ -5,13 +5,9 @@
|
|||
min-width: 150px;
|
||||
}
|
||||
|
||||
.card.compare {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.card.compare .change {
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.card:first-child {
|
||||
|
|
@ -23,7 +19,7 @@
|
|||
}
|
||||
|
||||
.value {
|
||||
font-size: 40px;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
color: var(--base900);
|
||||
|
|
@ -46,7 +42,7 @@
|
|||
gap: 5px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
padding: 0 5px;
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 5px;
|
||||
color: var(--base500);
|
||||
align-self: flex-start;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export const MetricCard = ({
|
|||
[styles.hide]: ~~change === 0,
|
||||
})}
|
||||
>
|
||||
<Icon rotate={positive ? -45 : 45} size={showPrevious ? 'sm' : 'xs'}>
|
||||
<Icon rotate={positive || reverseColors ? -45 : 45} size={showPrevious ? 'md' : 'xs'}>
|
||||
<Icons.ArrowRight />
|
||||
</Icon>
|
||||
<animated.span title={changeProps?.x as any}>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@ import { renderDateLabels } from 'lib/charts';
|
|||
|
||||
export interface PageviewsChartProps extends BarChartProps {
|
||||
data: {
|
||||
sessions: any[];
|
||||
pageviews: any[];
|
||||
sessions: any[];
|
||||
compare?: {
|
||||
pageviews: any[];
|
||||
sessions: any[];
|
||||
};
|
||||
};
|
||||
unit: string;
|
||||
isLoading?: boolean;
|
||||
|
|
@ -36,7 +40,25 @@ export function PageviewsChart({ data, unit, isLoading, ...props }: PageviewsCha
|
|||
borderWidth: 1,
|
||||
...colors.chart.views,
|
||||
},
|
||||
],
|
||||
data.compare
|
||||
? {
|
||||
type: 'line',
|
||||
label: formatMessage(labels.visitors),
|
||||
data: data.compare.pageviews,
|
||||
borderWidth: 2,
|
||||
borderColor: '#f15bb5',
|
||||
}
|
||||
: null,
|
||||
data.compare
|
||||
? {
|
||||
type: 'line',
|
||||
label: formatMessage(labels.visits),
|
||||
data: data.compare.sessions,
|
||||
borderWidth: 2,
|
||||
borderColor: '#9b5de5',
|
||||
}
|
||||
: null,
|
||||
].filter(n => n),
|
||||
};
|
||||
}, [data, locale]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue