fix: improvements for frontend
This commit is contained in:
@@ -680,12 +680,10 @@ clix.toStartOf = (node: string, interval: IInterval, timezone?: string) => {
|
||||
return `toStartOfDay(${node})`;
|
||||
}
|
||||
case 'week': {
|
||||
// Does not respect timezone settings (session_timezone) so we need to pass it manually
|
||||
return `toStartOfWeek(${node}${timezone ? `, 1, '${timezone}'` : ''})`;
|
||||
return `toStartOfWeek(toDateTime(${node}))`;
|
||||
}
|
||||
case 'month': {
|
||||
// Does not respect timezone settings (session_timezone) so we need to pass it manually
|
||||
return `toStartOfMonth(${node}${timezone ? `, '${timezone}'` : ''})`;
|
||||
return `toStartOfMonth(toDateTime(${node}))`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { path, assocPath, last, mergeDeepRight } from 'ramda';
|
||||
import { path, assocPath, last, mergeDeepRight, uniq } from 'ramda';
|
||||
import sqlstring from 'sqlstring';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
@@ -561,6 +561,15 @@ export async function getEventList(options: GetEventListOptions) {
|
||||
...sb.where,
|
||||
...getEventFiltersWhereClause(filters),
|
||||
};
|
||||
|
||||
// Join profiles table if any filter uses profile fields
|
||||
const profileFilters = filters
|
||||
.filter((f) => f.name.startsWith('profile.'))
|
||||
.map((f) => f.name.replace('profile.', ''));
|
||||
|
||||
if (profileFilters.length > 0) {
|
||||
sb.joins.profiles = `LEFT ANY JOIN (SELECT id, ${uniq(profileFilters.map((f) => f.split('.')[0])).join(', ')} FROM ${TABLE_NAMES.profiles} FINAL WHERE project_id = ${sqlstring.escape(projectId)}) as profile on profile.id = profile_id`;
|
||||
}
|
||||
}
|
||||
|
||||
sb.orderBy.created_at =
|
||||
@@ -622,6 +631,15 @@ export async function getEventsCount({
|
||||
...sb.where,
|
||||
...getEventFiltersWhereClause(filters),
|
||||
};
|
||||
|
||||
// Join profiles table if any filter uses profile fields
|
||||
const profileFilters = filters
|
||||
.filter((f) => f.name.startsWith('profile.'))
|
||||
.map((f) => f.name.replace('profile.', ''));
|
||||
|
||||
if (profileFilters.length > 0) {
|
||||
sb.joins.profiles = `LEFT ANY JOIN (SELECT id, ${uniq(profileFilters.map((f) => f.split('.')[0])).join(', ')} FROM ${TABLE_NAMES.profiles} FINAL WHERE project_id = ${sqlstring.escape(projectId)}) as profile on profile.id = profile_id`;
|
||||
}
|
||||
}
|
||||
|
||||
const res = await chQuery<{ count: number }>(
|
||||
@@ -701,6 +719,7 @@ class EventService {
|
||||
select,
|
||||
limit,
|
||||
orderBy,
|
||||
filters,
|
||||
}: {
|
||||
projectId: string;
|
||||
profileId?: string;
|
||||
@@ -715,7 +734,14 @@ class EventService {
|
||||
};
|
||||
limit?: number;
|
||||
orderBy?: keyof IClickhouseEvent;
|
||||
filters?: IChartEventFilter[];
|
||||
}) {
|
||||
// Extract profile filters if any
|
||||
const profileFilters =
|
||||
filters
|
||||
?.filter((f) => f.name.startsWith('profile.'))
|
||||
.map((f) => f.name.replace('profile.', '')) ?? [];
|
||||
|
||||
const events = clix(this.client)
|
||||
.select<
|
||||
Partial<IClickhouseEvent> & {
|
||||
@@ -744,6 +770,12 @@ class EventService {
|
||||
])
|
||||
.from('events e')
|
||||
.where('project_id', '=', projectId)
|
||||
.when(profileFilters.length > 0, (q) => {
|
||||
q.leftJoin(
|
||||
`(SELECT id, ${uniq(profileFilters.map((f) => f.split('.')[0])).join(', ')} FROM ${TABLE_NAMES.profiles} FINAL WHERE project_id = ${sqlstring.escape(projectId)}) as profile`,
|
||||
'profile.id = e.profile_id',
|
||||
);
|
||||
})
|
||||
.when(!!where?.event, where?.event)
|
||||
// Do not limit if profileId, we will limit later since we need the "correct" profileId
|
||||
.when(!!limit && !profileId, (q) => q.limit(limit!))
|
||||
@@ -941,6 +973,7 @@ class EventService {
|
||||
profileId,
|
||||
limit,
|
||||
orderBy: 'created_at',
|
||||
filters,
|
||||
select: {
|
||||
event: {
|
||||
deviceId: true,
|
||||
|
||||
@@ -200,6 +200,12 @@ export class OverviewService {
|
||||
])
|
||||
.rawWhere(this.getRawWhereClause('events', filters));
|
||||
|
||||
// Use toDate for month/week intervals, toDateTime for others
|
||||
const rollupDate =
|
||||
interval === 'month' || interval === 'week'
|
||||
? clix.date('1970-01-01')
|
||||
: clix.datetime('1970-01-01 00:00:00');
|
||||
|
||||
return clix(this.client, timezone)
|
||||
.with('session_agg', sessionAggQuery)
|
||||
.with(
|
||||
@@ -207,14 +213,14 @@ export class OverviewService {
|
||||
clix(this.client, timezone)
|
||||
.select(['bounce_rate'])
|
||||
.from('session_agg')
|
||||
.where('date', '=', clix.datetime('1970-01-01 00:00:00')),
|
||||
.where('date', '=', rollupDate),
|
||||
)
|
||||
.with(
|
||||
'daily_stats',
|
||||
clix(this.client, timezone)
|
||||
.select(['date', 'bounce_rate'])
|
||||
.from('session_agg')
|
||||
.where('date', '!=', clix.datetime('1970-01-01 00:00:00')),
|
||||
.where('date', '!=', rollupDate),
|
||||
)
|
||||
.with('overall_unique_visitors', overallUniqueVisitorsQuery)
|
||||
.select<{
|
||||
|
||||
@@ -172,7 +172,7 @@ export const eventRouter = createTRPCRouter({
|
||||
data: items,
|
||||
meta: {
|
||||
next:
|
||||
items.length === 50 && lastItem
|
||||
items.length > 0 && lastItem
|
||||
? lastItem.createdAt.toISOString()
|
||||
: null,
|
||||
},
|
||||
@@ -190,12 +190,19 @@ export const eventRouter = createTRPCRouter({
|
||||
cursor: z.string().optional(),
|
||||
startDate: z.date().optional(),
|
||||
endDate: z.date().optional(),
|
||||
events: z.array(z.string()).optional(),
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
const conversions = await getConversionEventNames(input.projectId);
|
||||
const filteredConversions = conversions.filter((event) => {
|
||||
if (input.events && input.events.length > 0) {
|
||||
return input.events.includes(event.name);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (conversions.length === 0) {
|
||||
if (filteredConversions.length === 0) {
|
||||
return {
|
||||
data: [],
|
||||
meta: {
|
||||
@@ -220,7 +227,7 @@ export const eventRouter = createTRPCRouter({
|
||||
origin: true,
|
||||
},
|
||||
custom: (sb) => {
|
||||
sb.where.name = `name IN (${conversions.map((event) => sqlstring.escape(event.name)).join(',')})`;
|
||||
sb.where.name = `name IN (${filteredConversions.map((event) => sqlstring.escape(event.name)).join(',')})`;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -249,7 +256,7 @@ export const eventRouter = createTRPCRouter({
|
||||
data: items,
|
||||
meta: {
|
||||
next:
|
||||
items.length === 50 && lastItem
|
||||
items.length > 0 && lastItem
|
||||
? lastItem.createdAt.toISOString()
|
||||
: null,
|
||||
},
|
||||
@@ -354,15 +361,11 @@ export const eventRouter = createTRPCRouter({
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
const res = await chQuery<{ origin: string }>(
|
||||
`SELECT DISTINCT origin FROM ${TABLE_NAMES.events} WHERE project_id = ${sqlstring.escape(
|
||||
`SELECT DISTINCT origin, count(id) as count FROM ${TABLE_NAMES.events} WHERE project_id = ${sqlstring.escape(
|
||||
input.projectId,
|
||||
)} AND origin IS NOT NULL AND origin != '' AND toDate(created_at) > now() - INTERVAL 30 DAY ORDER BY origin ASC`,
|
||||
)} AND origin IS NOT NULL AND origin != '' AND toDate(created_at) > now() - INTERVAL 30 DAY GROUP BY origin ORDER BY count DESC LIMIT 3`,
|
||||
);
|
||||
|
||||
return res.sort((a, b) =>
|
||||
a.origin
|
||||
.replace(/https?:\/\//, '')
|
||||
.localeCompare(b.origin.replace(/https?:\/\//, '')),
|
||||
);
|
||||
return res;
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user