mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Session properties.
This commit is contained in:
parent
deb9dd60df
commit
fc1fc5807e
@ -7,12 +7,16 @@ import styles from './SessionActivity.module.css';
|
||||
export function SessionActivity({
|
||||
websiteId,
|
||||
sessionId,
|
||||
startDate,
|
||||
endDate,
|
||||
}: {
|
||||
websiteId: string;
|
||||
sessionId: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
}) {
|
||||
const { formatDate } = useTimezone();
|
||||
const { data, isLoading } = useSessionActivity(websiteId, sessionId);
|
||||
const { data, isLoading } = useSessionActivity(websiteId, sessionId, startDate, endDate);
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading position="page" />;
|
||||
|
@ -28,7 +28,12 @@ export default function SessionDetailsPage({
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<SessionStats data={data} />
|
||||
<SessionActivity websiteId={websiteId} sessionId={sessionId} />
|
||||
<SessionActivity
|
||||
websiteId={websiteId}
|
||||
sessionId={sessionId}
|
||||
startDate={data?.firstAt}
|
||||
endDate={data?.lastAt}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.data}>
|
||||
<SessionData websiteId={websiteId} sessionId={sessionId} />
|
||||
|
@ -1,12 +1,21 @@
|
||||
import { useApi } from './useApi';
|
||||
|
||||
export function useSessionActivity(websiteId: string, sessionId: string) {
|
||||
export function useSessionActivity(
|
||||
websiteId: string,
|
||||
sessionId: string,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['session:activity', { websiteId, sessionId }],
|
||||
queryKey: ['session:activity', { websiteId, sessionId, startDate, endDate }],
|
||||
queryFn: () => {
|
||||
return get(`/websites/${websiteId}/sessions/${sessionId}/activity`);
|
||||
return get(`/websites/${websiteId}/sessions/${sessionId}/activity`, {
|
||||
startAt: +new Date(startDate),
|
||||
endAt: +new Date(endDate),
|
||||
});
|
||||
},
|
||||
enabled: Boolean(websiteId && sessionId && startDate && endDate),
|
||||
});
|
||||
}
|
||||
|
1
src/declaration.d.ts
vendored
1
src/declaration.d.ts
vendored
@ -1,5 +1,4 @@
|
||||
declare module 'cors';
|
||||
declare module 'dateformat';
|
||||
declare module 'debug';
|
||||
declare module 'chartjs-adapter-date-fns';
|
||||
declare module 'md5';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ClickHouseClient, createClient } from '@clickhouse/client';
|
||||
import { formatInTimeZone } from 'date-fns-tz';
|
||||
import debug from 'debug';
|
||||
import { CLICKHOUSE } from 'lib/db';
|
||||
import { DEFAULT_PAGE_SIZE, OPERATORS } from './constants';
|
||||
@ -48,6 +49,10 @@ function getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
function getUTCString(date?: Date) {
|
||||
return formatInTimeZone(date || new Date(), 'UTC', 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
|
||||
function getDateStringSQL(data: any, unit: string = 'utc', timezone?: string) {
|
||||
if (timezone) {
|
||||
return `formatDateTime(${data}, '${CLICKHOUSE_DATE_FORMATS[unit]}', '${timezone}')`;
|
||||
@ -221,6 +226,7 @@ export default {
|
||||
getDateStringSQL,
|
||||
getDateSQL,
|
||||
getFilterQuery,
|
||||
getUTCString,
|
||||
parseFilters,
|
||||
pagedQuery,
|
||||
findUnique,
|
||||
|
@ -6,7 +6,7 @@ import { methodNotAllowed, ok, unauthorized } from 'next-basics';
|
||||
import { getSessionDataProperties } from 'queries';
|
||||
import * as yup from 'yup';
|
||||
|
||||
export interface EventDataFieldsRequestQuery {
|
||||
export interface SessionDataFieldsRequestQuery {
|
||||
websiteId: string;
|
||||
startAt: string;
|
||||
endAt: string;
|
||||
@ -23,7 +23,7 @@ const schema = {
|
||||
};
|
||||
|
||||
export default async (
|
||||
req: NextApiRequestQueryBody<EventDataFieldsRequestQuery>,
|
||||
req: NextApiRequestQueryBody<SessionDataFieldsRequestQuery>,
|
||||
res: NextApiResponse<any>,
|
||||
) => {
|
||||
await useCors(req, res);
|
||||
|
@ -9,12 +9,16 @@ import { getSessionActivity } from 'queries';
|
||||
export interface SessionActivityRequestQuery extends PageParams {
|
||||
websiteId: string;
|
||||
sessionId: string;
|
||||
startAt: number;
|
||||
endAt: number;
|
||||
}
|
||||
|
||||
const schema = {
|
||||
GET: yup.object().shape({
|
||||
websiteId: yup.string().uuid().required(),
|
||||
sessionId: yup.string().uuid().required(),
|
||||
startAt: yup.number().integer(),
|
||||
endAt: yup.number().integer(),
|
||||
}),
|
||||
};
|
||||
|
||||
@ -26,14 +30,17 @@ export default async (
|
||||
await useAuth(req, res);
|
||||
await useValidate(schema, req, res);
|
||||
|
||||
const { websiteId, sessionId } = req.query;
|
||||
const { websiteId, sessionId, startAt, endAt } = req.query;
|
||||
|
||||
if (req.method === 'GET') {
|
||||
if (!(await canViewWebsite(req.auth, websiteId))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const data = await getSessionActivity(websiteId, sessionId);
|
||||
const startDate = new Date(+startAt);
|
||||
const endDate = new Date(+endAt);
|
||||
|
||||
const data = await getSessionActivity(websiteId, sessionId, startDate, endDate);
|
||||
|
||||
return ok(res, data);
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ async function clickhouseQuery(data: {
|
||||
city,
|
||||
...args
|
||||
} = data;
|
||||
const { insert } = clickhouse;
|
||||
const { insert, getUTCString } = clickhouse;
|
||||
const { sendMessage } = kafka;
|
||||
const eventId = uuid();
|
||||
const createdAt = new Date().toISOString();
|
||||
const createdAt = getUTCString();
|
||||
|
||||
const message = {
|
||||
...args,
|
||||
|
@ -2,32 +2,43 @@ import clickhouse from 'lib/clickhouse';
|
||||
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
|
||||
import prisma from 'lib/prisma';
|
||||
|
||||
export async function getSessionActivity(...args: [websiteId: string, sessionId: string]) {
|
||||
export async function getSessionActivity(
|
||||
...args: [websiteId: string, sessionId: string, startDate: Date, endDate: Date]
|
||||
) {
|
||||
return runQuery({
|
||||
[PRISMA]: () => relationalQuery(...args),
|
||||
[CLICKHOUSE]: () => clickhouseQuery(...args),
|
||||
});
|
||||
}
|
||||
|
||||
async function relationalQuery(websiteId: string, sessionId: string) {
|
||||
async function relationalQuery(
|
||||
websiteId: string,
|
||||
sessionId: string,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
) {
|
||||
return prisma.client.websiteEvent.findMany({
|
||||
where: {
|
||||
id: sessionId,
|
||||
websiteId,
|
||||
createdAt: { gte: startDate, lte: endDate },
|
||||
},
|
||||
take: 500,
|
||||
});
|
||||
}
|
||||
|
||||
async function clickhouseQuery(websiteId: string, sessionId: string) {
|
||||
const { rawQuery, getDateStringSQL } = clickhouse;
|
||||
async function clickhouseQuery(
|
||||
websiteId: string,
|
||||
sessionId: string,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
) {
|
||||
const { rawQuery } = clickhouse;
|
||||
|
||||
return rawQuery(
|
||||
`
|
||||
select
|
||||
session_id as id,
|
||||
website_id as websiteId,
|
||||
${getDateStringSQL('created_at')} as createdAt,
|
||||
created_at as createdAt,
|
||||
url_path as urlPath,
|
||||
url_query as urlQuery,
|
||||
referrer_domain as referrerDomain,
|
||||
@ -38,9 +49,10 @@ async function clickhouseQuery(websiteId: string, sessionId: string) {
|
||||
from website_event
|
||||
where website_id = {websiteId:UUID}
|
||||
and session_id = {sessionId:UUID}
|
||||
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
order by created_at desc
|
||||
limit 500
|
||||
`,
|
||||
{ websiteId, sessionId },
|
||||
{ websiteId, sessionId, startDate, endDate },
|
||||
);
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ async function clickhouseQuery(data: {
|
||||
}) {
|
||||
const { websiteId, sessionId, sessionData } = data;
|
||||
|
||||
const { insert } = clickhouse;
|
||||
const { insert, getUTCString } = clickhouse;
|
||||
const { sendMessages } = kafka;
|
||||
const createdAt = new Date().toISOString();
|
||||
const createdAt = getUTCString();
|
||||
|
||||
const jsonKeys = flattenJSON(sessionData);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user