mirror of
https://github.com/umami-software/umami.git
synced 2026-02-16 02:25:35 +01:00
Compare commits
11 commits
767b373484
...
bac3ab2c1a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bac3ab2c1a | ||
|
|
1b43aa8d37 | ||
|
|
d948e122ea | ||
|
|
36ae53654d | ||
|
|
d440a44d96 | ||
|
|
5a7c6a9816 | ||
|
|
d0aa266dce | ||
|
|
0d67f1fdaa | ||
|
|
cc3710880c | ||
|
|
5244d8608b | ||
|
|
895b41cb78 |
12 changed files with 76 additions and 26 deletions
|
|
@ -30,7 +30,7 @@ export function EventsTable({ data = [] }) {
|
|||
<Text>
|
||||
{formatMessage(row.eventName ? labels.triggeredEvent : labels.viewedPage)}
|
||||
</Text>
|
||||
<Text weight="bold" truncate>
|
||||
<Text weight="bold" style={{ maxWidth: '300px' }} truncate>
|
||||
{row.eventName || row.urlPath}
|
||||
</Text>
|
||||
</Row>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ export function SessionActivity({
|
|||
? formatMessage(labels.triggeredEvent)
|
||||
: formatMessage(labels.viewedPage)}
|
||||
</Text>
|
||||
<Text weight="bold">{eventName || urlPath}</Text>
|
||||
<Text weight="bold" style={{ maxWidth: '400px' }} truncate>
|
||||
{eventName || urlPath}
|
||||
</Text>
|
||||
{hasData > 0 && <PropertiesButton websiteId={websiteId} eventId={eventId} />}
|
||||
</Row>
|
||||
</Row>
|
||||
|
|
|
|||
|
|
@ -3,8 +3,27 @@ import { getRandomChars } from '@/lib/generate';
|
|||
import { unauthorized, json } from '@/lib/response';
|
||||
import { canCreateTeam } from '@/permissions';
|
||||
import { uuid } from '@/lib/crypto';
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { createTeam } from '@/queries/prisma';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { createTeam, getUserTeams } from '@/queries/prisma';
|
||||
import { pagingParams } from '@/lib/schema';
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const schema = z.object({
|
||||
...pagingParams,
|
||||
});
|
||||
|
||||
const { auth, query, error } = await parseRequest(request, schema);
|
||||
|
||||
if (error) {
|
||||
return error();
|
||||
}
|
||||
|
||||
const filters = await getQueryFilters(query);
|
||||
|
||||
const teams = await getUserTeams(auth.user.id, filters);
|
||||
|
||||
return json(teams);
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const schema = z.object({
|
||||
|
|
|
|||
|
|
@ -55,7 +55,12 @@ export function LoginForm() {
|
|||
<PasswordField />
|
||||
</FormField>
|
||||
<FormButtons>
|
||||
<FormSubmitButton data-test="button-submit" variant="primary" style={{ flex: 1 }}>
|
||||
<FormSubmitButton
|
||||
data-test="button-submit"
|
||||
variant="primary"
|
||||
style={{ flex: 1 }}
|
||||
isDisabled={false}
|
||||
>
|
||||
{formatMessage(labels.login)}
|
||||
</FormSubmitButton>
|
||||
</FormButtons>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ReactQueryOptions } from '@/lib/types';
|
||||
import { keepPreviousData } from '@tanstack/react-query';
|
||||
import { useApi } from '../useApi';
|
||||
import { useFilterParameters } from '../useFilterParameters';
|
||||
import { useDateParameters } from '../useDateParameters';
|
||||
import { ReactQueryOptions } from '@/lib/types';
|
||||
import { useFilterParameters } from '../useFilterParameters';
|
||||
|
||||
export type WebsiteMetricsData = {
|
||||
x: string;
|
||||
|
|
@ -15,7 +15,7 @@ export function useWebsiteMetricsQuery(
|
|||
options?: ReactQueryOptions<WebsiteMetricsData>,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const filters = useFilterParameters();
|
||||
|
||||
return useQuery<WebsiteMetricsData>({
|
||||
|
|
@ -23,14 +23,20 @@ export function useWebsiteMetricsQuery(
|
|||
'websites:metrics',
|
||||
{
|
||||
websiteId,
|
||||
...date,
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...filters,
|
||||
...params,
|
||||
},
|
||||
],
|
||||
queryFn: async () =>
|
||||
get(`/websites/${websiteId}/metrics`, {
|
||||
...date,
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...filters,
|
||||
...params,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -13,12 +13,23 @@ export function useWebsitePageviewsQuery(
|
|||
options?: ReactQueryOptions<WebsitePageviewsData>,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const queryParams = useFilterParameters();
|
||||
|
||||
return useQuery<WebsitePageviewsData>({
|
||||
queryKey: ['websites:pageviews', { websiteId, compare, ...date, ...queryParams }],
|
||||
queryFn: () => get(`/websites/${websiteId}/pageviews`, { compare, ...date, ...queryParams }),
|
||||
queryKey: [
|
||||
'websites:pageviews',
|
||||
{ websiteId, compare, startAt, endAt, unit, timezone, ...queryParams },
|
||||
],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/pageviews`, {
|
||||
compare,
|
||||
startAt,
|
||||
endAt,
|
||||
unit,
|
||||
timezone,
|
||||
...queryParams,
|
||||
}),
|
||||
enabled: !!websiteId,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,12 +23,13 @@ export function useWebsiteStatsQuery(
|
|||
options?: UseQueryOptions<WebsiteStatsData, Error, WebsiteStatsData>,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const date = useDateParameters();
|
||||
const { startAt, endAt, unit, timezone } = useDateParameters();
|
||||
const filters = useFilterParameters();
|
||||
|
||||
return useQuery<WebsiteStatsData>({
|
||||
queryKey: ['websites:stats', { websiteId, ...date, ...filters }],
|
||||
queryFn: () => get(`/websites/${websiteId}/stats`, { ...date, ...filters }),
|
||||
queryKey: ['websites:stats', { websiteId, startAt, endAt, unit, timezone, ...filters }],
|
||||
queryFn: () =>
|
||||
get(`/websites/${websiteId}/stats`, { startAt, endAt, unit, timezone, ...filters }),
|
||||
enabled: !!websiteId,
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -117,7 +117,9 @@ const AnimatedRow = ({
|
|||
gap
|
||||
>
|
||||
<Row alignItems="center">
|
||||
<Text>{label}</Text>
|
||||
<Text truncate={true} style={{ maxWidth: '400px' }}>
|
||||
{label}
|
||||
</Text>
|
||||
</Row>
|
||||
<Row alignItems="center" height="30px" justifyContent="flex-end">
|
||||
{change}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export function getRequestFilters(query: Record<string, any>) {
|
|||
export async function setWebsiteDate(websiteId: string, data: Record<string, any>) {
|
||||
const website = await fetchWebsite(websiteId);
|
||||
|
||||
if (website) {
|
||||
if (website?.resetAt) {
|
||||
data.startDate = maxDate(data.startDate, new Date(website?.resetAt));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Auth } from '@/lib/types';
|
||||
import { PERMISSIONS } from '@/lib/constants';
|
||||
import { hasPermission } from '@/lib/auth';
|
||||
import { getTeamUser, getWebsite } from '@/queries/prisma';
|
||||
import { getLink, getPixel, getTeamUser, getWebsite } from '@/queries/prisma';
|
||||
|
||||
export async function canViewWebsite({ user, shareToken }: Auth, websiteId: string) {
|
||||
if (user?.isAdmin) {
|
||||
|
|
@ -13,17 +13,21 @@ export async function canViewWebsite({ user, shareToken }: Auth, websiteId: stri
|
|||
}
|
||||
|
||||
const website = await getWebsite(websiteId);
|
||||
const link = await getLink(websiteId);
|
||||
const pixel = await getPixel(websiteId);
|
||||
|
||||
if (!website) {
|
||||
const entity = website || link || pixel;
|
||||
|
||||
if (!entity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (website.userId) {
|
||||
return user.id === website.userId;
|
||||
if (entity.userId) {
|
||||
return user.id === entity.userId;
|
||||
}
|
||||
|
||||
if (website.teamId) {
|
||||
const teamUser = await getTeamUser(website.teamId, user.id);
|
||||
if (entity.teamId) {
|
||||
const teamUser = await getTeamUser(entity.teamId, user.id);
|
||||
|
||||
return !!teamUser;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters) {
|
|||
page_title as pageTitle,
|
||||
event_type as eventType,
|
||||
event_name as eventName,
|
||||
event_id IN (SELECT event_id FROM event_data) as hasData
|
||||
event_id IN (SELECT event_id FROM event_data where website_id = {websiteId:UUID}) as hasData
|
||||
from website_event
|
||||
${cohortQuery}
|
||||
where website_id = {websiteId:UUID}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ async function clickhouseQuery(websiteId: string, sessionId: string, filters: Qu
|
|||
event_type as eventType,
|
||||
event_name as eventName,
|
||||
visit_id as visitId,
|
||||
event_id IN (SELECT event_id FROM event_data) AS hasData
|
||||
event_id IN (SELECT event_id FROM event_data where website_id = {websiteId:UUID} and session_id = {sessionId:UUID}) AS hasData
|
||||
from website_event e
|
||||
where e.website_id = {websiteId:UUID}
|
||||
and e.session_id = {sessionId:UUID}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue