mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-16 02:05:04 +01:00
Refactored functionality for all time date range.
This commit is contained in:
parent
c3973f5fb5
commit
d06808985b
@ -10,11 +10,7 @@ export function RefreshButton({ websiteId, isLoading }) {
|
||||
|
||||
function handleClick() {
|
||||
if (!isLoading && dateRange) {
|
||||
if (/^\d+/.test(dateRange.value)) {
|
||||
setWebsiteDateRange(websiteId, dateRange.value);
|
||||
} else {
|
||||
setWebsiteDateRange(websiteId, dateRange);
|
||||
}
|
||||
setWebsiteDateRange(websiteId, dateRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import PageviewsChart from 'components/metrics/PageviewsChart';
|
||||
import { useApi, useDateRange, useTimezone, usePageQuery } from 'hooks';
|
||||
import { getDateArray, getDateLength } from 'lib/date';
|
||||
import { getDateArray } from 'lib/date';
|
||||
|
||||
export function WebsiteChart({ websiteId }) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
@ -43,7 +43,7 @@ export function WebsiteChart({ websiteId }) {
|
||||
};
|
||||
}
|
||||
return { pageviews: [], sessions: [] };
|
||||
}, [data, startDate, endDate, unit, modified]);
|
||||
}, [data, startDate, endDate, unit]);
|
||||
|
||||
return <PageviewsChart websiteId={websiteId} data={chartData} unit={unit} loading={isLoading} />;
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ export function WebsiteHeader({ websiteId, showLinks = true, children }) {
|
||||
<Column className={styles.title} variant="two">
|
||||
<Favicon domain={domain} />
|
||||
<Text>{name}</Text>
|
||||
<ActiveUsers websiteId={websiteId} />
|
||||
</Column>
|
||||
<Column className={styles.actions} variant="two">
|
||||
<ActiveUsers websiteId={websiteId} />
|
||||
{showLinks && (
|
||||
<Flexbox alignItems="center">
|
||||
{links.map(({ label, icon, path }) => {
|
||||
|
@ -1,20 +1,43 @@
|
||||
import { parseDateRange } from 'lib/date';
|
||||
import { getMinimumUnit, parseDateRange } from 'lib/date';
|
||||
import { setItem } from 'next-basics';
|
||||
import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants';
|
||||
import useLocale from './useLocale';
|
||||
import websiteStore, { setWebsiteDateRange } from 'store/websites';
|
||||
import appStore, { setDateRange } from 'store/app';
|
||||
import useApi from './useApi';
|
||||
|
||||
export function useDateRange(websiteId) {
|
||||
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 saveDateRange = value => {
|
||||
const saveDateRange = async value => {
|
||||
if (websiteId) {
|
||||
setWebsiteDateRange(websiteId, value);
|
||||
let dateRange = value;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
if (value === 'all') {
|
||||
const result = await get(`/websites/${websiteId}/daterange`);
|
||||
const { mindate, maxdate } = result;
|
||||
|
||||
const startDate = new Date(mindate);
|
||||
const endDate = new Date(maxdate);
|
||||
|
||||
dateRange = {
|
||||
startDate,
|
||||
endDate,
|
||||
unit: getMinimumUnit(startDate, endDate),
|
||||
value,
|
||||
};
|
||||
} else {
|
||||
dateRange = parseDateRange(value, locale);
|
||||
}
|
||||
}
|
||||
|
||||
setWebsiteDateRange(websiteId, dateRange);
|
||||
} else {
|
||||
setItem(DATE_RANGE_CONFIG, value);
|
||||
setDateRange(value);
|
||||
|
@ -122,7 +122,7 @@ async function findUnique(data) {
|
||||
throw `${data.length} records found when expecting 1.`;
|
||||
}
|
||||
|
||||
return data[0] ?? null;
|
||||
return findFirst(data);
|
||||
}
|
||||
|
||||
async function findFirst(data) {
|
||||
|
11
lib/query.ts
11
lib/query.ts
@ -7,12 +7,15 @@ export async function parseDateRangeQuery(req: NextApiRequest) {
|
||||
|
||||
// All-time
|
||||
if (+startAt === 0 && +endAt === 1) {
|
||||
const { min, max } = await getWebsiteDateRange(websiteId as string);
|
||||
const result = await getWebsiteDateRange(websiteId as string);
|
||||
const { min, max } = result[0];
|
||||
const startDate = new Date(min);
|
||||
const endDate = new Date(max);
|
||||
|
||||
return {
|
||||
startDate: min,
|
||||
endDate: max,
|
||||
unit: getMinimumUnit(min, max),
|
||||
startDate,
|
||||
endDate,
|
||||
unit: getMinimumUnit(startDate, endDate),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -137,3 +137,10 @@ export interface RealtimeUpdate {
|
||||
events: any[];
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface DateRange {
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
unit: string;
|
||||
value: string;
|
||||
}
|
||||
|
32
pages/api/websites/[id]/daterange.ts
Normal file
32
pages/api/websites/[id]/daterange.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { WebsiteActive, NextApiRequestQueryBody } from 'lib/types';
|
||||
import { canViewWebsite } from 'lib/auth';
|
||||
import { useAuth, useCors } from 'lib/middleware';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
|
||||
import { getWebsiteDateRange } from 'queries';
|
||||
|
||||
export interface WebsiteDateRangeRequestQuery {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export default async (
|
||||
req: NextApiRequestQueryBody<WebsiteDateRangeRequestQuery>,
|
||||
res: NextApiResponse<WebsiteActive>,
|
||||
) => {
|
||||
await useCors(req, res);
|
||||
await useAuth(req, res);
|
||||
|
||||
const { id: websiteId } = req.query;
|
||||
|
||||
if (req.method === 'GET') {
|
||||
if (!(await canViewWebsite(req.auth, websiteId))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const result = await getWebsiteDateRange(websiteId);
|
||||
|
||||
return ok(res, result);
|
||||
}
|
||||
|
||||
return methodNotAllowed(res);
|
||||
};
|
@ -73,6 +73,7 @@ export default async (
|
||||
city,
|
||||
},
|
||||
});
|
||||
|
||||
const prevPeriod = await getWebsiteStats(websiteId, {
|
||||
startDate: prevStartDate,
|
||||
endDate: prevEndDate,
|
||||
|
@ -16,32 +16,36 @@ async function relationalQuery(websiteId: string) {
|
||||
const { rawQuery } = prisma;
|
||||
const website = await loadWebsite(websiteId);
|
||||
|
||||
return rawQuery(
|
||||
const result = await rawQuery(
|
||||
`
|
||||
select
|
||||
min(created_at) as min,
|
||||
max(created_at) as max
|
||||
min(created_at) as mindate,
|
||||
max(created_at) as maxdate
|
||||
from website_event
|
||||
where website_id = {{websiteId::uuid}}
|
||||
and created_at >= {{startDate}}
|
||||
`,
|
||||
{ websiteId, startDate: maxDate(new Date(DEFAULT_RESET_DATE), new Date(website.resetAt)) },
|
||||
);
|
||||
|
||||
return result[0] ?? null;
|
||||
}
|
||||
|
||||
async function clickhouseQuery(websiteId: string) {
|
||||
const { rawQuery } = clickhouse;
|
||||
const website = await loadWebsite(websiteId);
|
||||
|
||||
return rawQuery(
|
||||
const result = await rawQuery(
|
||||
`
|
||||
select
|
||||
min(created_at) as min,
|
||||
max(created_at) as max
|
||||
min(created_at) as mindate,
|
||||
max(created_at) as maxdate
|
||||
from website_event
|
||||
where website_id = {websiteId:UUID}
|
||||
and created_at >= {startDate:DateTime}
|
||||
`,
|
||||
{ websiteId, startDate: maxDate(new Date(DEFAULT_RESET_DATE), new Date(website.resetAt)) },
|
||||
);
|
||||
|
||||
return result[0] ?? null;
|
||||
}
|
||||
|
@ -1,28 +1,20 @@
|
||||
import { create } from 'zustand';
|
||||
import produce from 'immer';
|
||||
import app from './app';
|
||||
import { parseDateRange } from 'lib/date';
|
||||
import { DateRange } from 'lib/types';
|
||||
|
||||
const store = create(() => ({}));
|
||||
|
||||
export function getWebsiteDateRange(websiteId) {
|
||||
export function getWebsiteDateRange(websiteId: string) {
|
||||
return store.getState()?.[websiteId];
|
||||
}
|
||||
|
||||
export function setWebsiteDateRange(websiteId, value) {
|
||||
export function setWebsiteDateRange(websiteId: string, dateRange: DateRange) {
|
||||
store.setState(
|
||||
produce(state => {
|
||||
if (!state[websiteId]) {
|
||||
state[websiteId] = {};
|
||||
}
|
||||
|
||||
let dateRange = value;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
const { locale } = app.getState();
|
||||
dateRange = parseDateRange(value, locale);
|
||||
}
|
||||
|
||||
state[websiteId].dateRange = { ...dateRange, modified: Date.now() };
|
||||
|
||||
return state;
|
Loading…
Reference in New Issue
Block a user