mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
5c3a6ce8ce
12 changed files with 91 additions and 44 deletions
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
|
|
@ -364,8 +364,6 @@ importers:
|
|||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
|
||||
dist: {}
|
||||
|
||||
packages:
|
||||
|
||||
'@ampproject/remapping@2.3.0':
|
||||
|
|
|
|||
|
|
@ -24,22 +24,26 @@ export async function GET(request: Request) {
|
|||
const teams = await getTeams(
|
||||
{
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
members: true,
|
||||
websites: true,
|
||||
},
|
||||
},
|
||||
members: {
|
||||
select: {
|
||||
include: {
|
||||
user: {
|
||||
omit: {
|
||||
password: true,
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
role: 'team-owner',
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
websites: {
|
||||
where: { deletedAt: null },
|
||||
},
|
||||
members: {
|
||||
where: {
|
||||
user: { deletedAt: null },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from 'zod';
|
||||
import { uuid } from '@/lib/crypto';
|
||||
import { pagingParams, reportSchema } from '@/lib/schema';
|
||||
import { pagingParams, reportSchema, reportTypeParam } from '@/lib/schema';
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { canViewWebsite, canUpdateWebsite } from '@/permissions';
|
||||
import { unauthorized, json } from '@/lib/response';
|
||||
|
|
@ -9,7 +9,7 @@ import { getReports, createReport } from '@/queries/prisma';
|
|||
export async function GET(request: Request) {
|
||||
const schema = z.object({
|
||||
websiteId: z.uuid(),
|
||||
type: z.string().optional(),
|
||||
type: reportTypeParam.optional(),
|
||||
...pagingParams,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ export async function GET(request: Request, { params }: { params: Promise<{ user
|
|||
|
||||
export async function POST(request: Request, { params }: { params: Promise<{ userId: string }> }) {
|
||||
const schema = z.object({
|
||||
username: z.string().max(255),
|
||||
username: z.string().max(255).optional(),
|
||||
password: z.string().max(255).optional(),
|
||||
role: userRoleParam,
|
||||
role: userRoleParam.optional(),
|
||||
});
|
||||
|
||||
const { auth, body, error } = await parseRequest(request, schema);
|
||||
|
|
|
|||
|
|
@ -3,15 +3,16 @@ import { getQueryFilters, parseRequest } from '@/lib/request';
|
|||
import { unauthorized, json } from '@/lib/response';
|
||||
import { canViewWebsite } from '@/permissions';
|
||||
import { getEventDataProperties } from '@/queries/sql';
|
||||
import { dateRangeParams, filterParams } from '@/lib/schema';
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: Promise<{ websiteId: string }> },
|
||||
) {
|
||||
const schema = z.object({
|
||||
startAt: z.coerce.number().int(),
|
||||
endAt: z.coerce.number().int(),
|
||||
propertyName: z.string().optional(),
|
||||
...dateRangeParams,
|
||||
...filterParams,
|
||||
});
|
||||
|
||||
const { auth, query, error } = await parseRequest(request, schema);
|
||||
|
|
|
|||
|
|
@ -3,16 +3,17 @@ import { getQueryFilters, parseRequest } from '@/lib/request';
|
|||
import { unauthorized, json } from '@/lib/response';
|
||||
import { canViewWebsite } from '@/permissions';
|
||||
import { getEventDataValues } from '@/queries/sql';
|
||||
import { dateRangeParams, filterParams } from '@/lib/schema';
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: Promise<{ websiteId: string }> },
|
||||
) {
|
||||
const schema = z.object({
|
||||
startAt: z.coerce.number().int(),
|
||||
endAt: z.coerce.number().int(),
|
||||
eventName: z.string().optional(),
|
||||
propertyName: z.string().optional(),
|
||||
...dateRangeParams,
|
||||
...filterParams,
|
||||
});
|
||||
|
||||
const { auth, query, error } = await parseRequest(request, schema);
|
||||
|
|
|
|||
|
|
@ -5,12 +5,22 @@ import { ReactQueryOptions } from '@/lib/types';
|
|||
|
||||
export function useEventDataEventsQuery(websiteId: string, options?: ReactQueryOptions) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const filters = useFilterParameters();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['websites:event-data:events', { websiteId, ...date, ...filters }],
|
||||
queryFn: () => get(`/websites/${websiteId}/event-data/events`, { ...date, ...filters }),
|
||||
queryKey: [
|
||||
'websites:event-data:events',
|
||||
{ websiteId, startAt, endAt, unit, timezone, ...filters },
|
||||
],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/event-data/events`, {
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...filters,
|
||||
}),
|
||||
enabled: !!websiteId,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,12 +5,22 @@ import { ReactQueryOptions } from '@/lib/types';
|
|||
|
||||
export function useEventDataPropertiesQuery(websiteId: string, options?: ReactQueryOptions) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const filters = useFilterParameters();
|
||||
|
||||
return useQuery<any>({
|
||||
queryKey: ['websites:event-data:properties', { websiteId, ...date, ...filters }],
|
||||
queryFn: () => get(`/websites/${websiteId}/event-data/properties`, { ...date, ...filters }),
|
||||
queryKey: [
|
||||
'websites:event-data:properties',
|
||||
{ websiteId, startAt, endAt, unit, timezone, ...filters },
|
||||
],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/event-data/properties`, {
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...filters,
|
||||
}),
|
||||
enabled: !!websiteId,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,12 +5,22 @@ import { ReactQueryOptions } from '@/lib/types';
|
|||
|
||||
export function useEventDataQuery(websiteId: string, eventId: string, options?: ReactQueryOptions) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const params = useFilterParameters();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['websites:event-data', { websiteId, eventId, ...date, ...params }],
|
||||
queryFn: () => get(`/websites/${websiteId}/event-data/${eventId}`, { ...date, ...params }),
|
||||
queryKey: [
|
||||
'websites:event-data',
|
||||
{ websiteId, eventId, startAt, endAt, unit, timezone, ...params },
|
||||
],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/event-data/${eventId}`, {
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...params,
|
||||
}),
|
||||
enabled: !!(websiteId && eventId),
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParameters } from '../useFilterParameters';
|
||||
import { useDateParameters } from '../useDateParameters';
|
||||
import { ReactQueryOptions } from '@/lib/types';
|
||||
import { useApi } from '../useApi';
|
||||
import { useDateParameters } from '../useDateParameters';
|
||||
import { useFilterParameters } from '../useFilterParameters';
|
||||
|
||||
export function useEventDataValuesQuery(
|
||||
websiteId: string,
|
||||
|
|
@ -10,17 +10,20 @@ export function useEventDataValuesQuery(
|
|||
options?: ReactQueryOptions,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const filters = useFilterParameters();
|
||||
|
||||
return useQuery<any>({
|
||||
queryKey: [
|
||||
'websites:event-data:values',
|
||||
{ websiteId, eventName, propertyName, ...date, ...filters },
|
||||
{ websiteId, eventName, propertyName, startAt, endAt, unit, timezone, ...filters },
|
||||
],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/event-data/values`, {
|
||||
...date,
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...filters,
|
||||
eventName,
|
||||
propertyName,
|
||||
|
|
|
|||
|
|
@ -68,10 +68,15 @@ async function clickhouseQuery(
|
|||
event_name as eventName,
|
||||
data_key as propertyName,
|
||||
count(*) as total
|
||||
from event_data website_event
|
||||
from event_data
|
||||
join website_event
|
||||
on website_event.event_id = event_data.event_id
|
||||
and website_event.website_id = event_data.website_id
|
||||
and website_event.website_id = {websiteId:UUID}
|
||||
and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
${cohortQuery}
|
||||
where website_id = {websiteId:UUID}
|
||||
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
where event_data.website_id = {websiteId:UUID}
|
||||
and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
${filterQuery}
|
||||
group by event_name, data_key
|
||||
order by 1, 3 desc
|
||||
|
|
|
|||
|
|
@ -75,12 +75,17 @@ async function clickhouseQuery(
|
|||
data_type = 4, toString(date_trunc('hour', date_value)),
|
||||
string_value) as "value",
|
||||
count(*) as "total"
|
||||
from event_data website_event
|
||||
from event_data
|
||||
join website_event
|
||||
on website_event.event_id = event_data.event_id
|
||||
and website_event.website_id = event_data.website_id
|
||||
and website_event.website_id = {websiteId:UUID}
|
||||
and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
${cohortQuery}
|
||||
where website_id = {websiteId:UUID}
|
||||
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
and data_key = {propertyName:String}
|
||||
and event_name = {eventName:String}
|
||||
where event_data.website_id = {websiteId:UUID}
|
||||
and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
and event_data.data_key = {propertyName:String}
|
||||
and event_data.event_name = {eventName:String}
|
||||
${filterQuery}
|
||||
group by value
|
||||
order by 2 desc
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue