diff --git a/package.components.json b/package.components.json index 09c0cf52c..e0f8a105b 100644 --- a/package.components.json +++ b/package.components.json @@ -1,10 +1,24 @@ { "name": "@umami/components", - "version": "0.121.0", + "version": "0.116.0", "description": "Umami React components.", "author": "Mike Cao ", "license": "MIT", "type": "module", "main": "./index.js", - "types": "./index.d.ts" + "types": "./index.d.ts", + "dependencies": { + "chart.js": "^4.5.0", + "chartjs-adapter-date-fns": "^3.0.0", + "colord": "^2.9.2", + "jsonwebtoken": "^9.0.2", + "lucide-react": "^0.542.0", + "pure-rand": "^7.0.1", + "react-simple-maps": "^2.3.0", + "react-use-measure": "^2.0.4", + "react-window": "^1.8.6", + "serialize-error": "^12.0.0", + "thenby": "^1.3.4", + "uuid": "^11.1.0" + } } diff --git a/src/app/(main)/dashboard/DashboardPage.tsx b/src/app/(main)/dashboard/DashboardPage.tsx deleted file mode 100644 index c05e411d6..000000000 --- a/src/app/(main)/dashboard/DashboardPage.tsx +++ /dev/null @@ -1,17 +0,0 @@ -'use client'; -import { Column } from '@umami/react-zen'; -import { PageHeader } from '@/components/common/PageHeader'; -import { useMessages } from '@/components/hooks'; -import { PageBody } from '@/components/common/PageBody'; - -export function DashboardPage() { - const { formatMessage, labels } = useMessages(); - - return ( - - - - - - ); -} diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx deleted file mode 100644 index e934e6ada..000000000 --- a/src/app/(main)/dashboard/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Metadata } from 'next'; -import { DashboardPage } from './DashboardPage'; - -export default async function () { - return ; -} - -export const metadata: Metadata = { - title: 'Dashboard', -}; diff --git a/src/app/(main)/websites/WebsitesDataTable.tsx b/src/app/(main)/websites/WebsitesDataTable.tsx index 93b1a7c79..612dc502b 100644 --- a/src/app/(main)/websites/WebsitesDataTable.tsx +++ b/src/app/(main)/websites/WebsitesDataTable.tsx @@ -1,23 +1,20 @@ import Link from 'next/link'; import { WebsitesTable } from './WebsitesTable'; import { DataGrid } from '@/components/common/DataGrid'; -import { useLoginQuery, useNavigation, useUserWebsitesQuery } from '@/components/hooks'; +import { useNavigation, useUserWebsitesQuery } from '@/components/hooks'; export function WebsitesDataTable({ - userId, teamId, allowEdit = true, allowView = true, showActions = true, }: { - userId?: string; teamId?: string; allowEdit?: boolean; allowView?: boolean; showActions?: boolean; }) { - const { user } = useLoginQuery(); - const queryResult = useUserWebsitesQuery({ userId: userId || user?.id, teamId }); + const queryResult = useUserWebsitesQuery({ teamId }); const { renderUrl } = useNavigation(); const renderLink = (row: any) => ( diff --git a/src/app/(main)/websites/WebsitesTable.tsx b/src/app/(main)/websites/WebsitesTable.tsx index 3f781cb7c..3fc22a988 100644 --- a/src/app/(main)/websites/WebsitesTable.tsx +++ b/src/app/(main)/websites/WebsitesTable.tsx @@ -3,7 +3,6 @@ import { Row, Text, Icon, DataTable, DataColumn, MenuItem } from '@umami/react-z import { useMessages, useNavigation } from '@/components/hooks'; import { MenuButton } from '@/components/input/MenuButton'; import { Eye, SquarePen } from '@/components/icons'; -import { Empty } from '@/components/common/Empty'; export function WebsitesTable({ data = [], @@ -11,18 +10,20 @@ export function WebsitesTable({ allowEdit, allowView, renderLink, + children, }: { data: Record[]; showActions?: boolean; allowEdit?: boolean; allowView?: boolean; renderLink?: (row: any) => ReactNode; + children?: ReactNode; }) { const { formatMessage, labels } = useMessages(); const { renderUrl } = useNavigation(); - if (data.length === 0) { - return ; + if (!data?.length) { + return children; } return ( diff --git a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx index 8db82a585..e0d5ffb00 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx @@ -18,11 +18,10 @@ import { import { useMessages, useNavigation } from '@/components/hooks'; import { SideMenu } from '@/components/common/SideMenu'; import { WebsiteSelect } from '@/components/input/WebsiteSelect'; -import { Text } from '@umami/react-zen'; export function WebsiteNav({ websiteId }: { websiteId: string }) { const { formatMessage, labels } = useMessages(); - const { pathname, renderUrl, teamId, router } = useNavigation(); + const { pathname, renderUrl, teamId } = useNavigation(); const renderPath = (path: string) => renderUrl(`/websites/${websiteId}${path}`, { @@ -144,31 +143,13 @@ export function WebsiteNav({ websiteId }: { websiteId: string }) { }, ]; - const handleChange = (value: string) => { - router.push(renderUrl(`/websites/${value}`)); - }; - - const renderValue = (value: any) => { - return ( - - {value?.selectedItem?.name} - - ); - }; - const selectedKey = items .flatMap(e => e.items) .find(({ path }) => path && pathname.endsWith(path.split('?')[0]))?.id; return ( - + ); } diff --git a/src/app/api/me/websites/route.ts b/src/app/api/me/websites/route.ts index 2851dab46..41a8756d2 100644 --- a/src/app/api/me/websites/route.ts +++ b/src/app/api/me/websites/route.ts @@ -1,13 +1,12 @@ import { z } from 'zod'; import { pagingParams } from '@/lib/schema'; -import { getAllUserWebsitesIncludingTeamOwner, getUserWebsites } from '@/queries'; +import { getUserWebsites } from '@/queries'; import { json } from '@/lib/response'; import { parseRequest, getQueryFilters } from '@/lib/request'; export async function GET(request: Request) { const schema = z.object({ ...pagingParams, - includeTeams: z.string().optional(), }); const { auth, query, error } = await parseRequest(request, schema); @@ -18,9 +17,7 @@ export async function GET(request: Request) { const filters = await getQueryFilters(query); - if (query.includeTeams) { - return json(await getAllUserWebsitesIncludingTeamOwner(auth.user.id, filters)); - } + const websites = await getUserWebsites(auth.user.id, filters); - return json(await getUserWebsites(auth.user.id, filters)); + return json(websites); } diff --git a/src/app/api/users/[userId]/websites/route.ts b/src/app/api/users/[userId]/websites/route.ts index 3e81f4f4c..0c10682d8 100644 --- a/src/app/api/users/[userId]/websites/route.ts +++ b/src/app/api/users/[userId]/websites/route.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; import { unauthorized, json } from '@/lib/response'; -import { getAllUserWebsitesIncludingTeamOwner, getUserWebsites } from '@/queries/prisma/website'; +import { getUserWebsites } from '@/queries/prisma/website'; import { pagingParams, searchParams } from '@/lib/schema'; import { getQueryFilters, parseRequest } from '@/lib/request'; @@ -8,7 +8,6 @@ export async function GET(request: Request, { params }: { params: Promise<{ user const schema = z.object({ ...pagingParams, ...searchParams, - includeTeams: z.string().optional(), }); const { auth, query, error } = await parseRequest(request, schema); @@ -25,9 +24,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ user const filters = await getQueryFilters(query); - if (query.includeTeams) { - return json(await getAllUserWebsitesIncludingTeamOwner(auth.user.id, filters)); - } + const websites = await getUserWebsites(userId, filters); - return json(await getUserWebsites(userId, filters)); + return json(websites); } diff --git a/src/app/api/websites/[websiteId]/stats/route.ts b/src/app/api/websites/[websiteId]/stats/route.ts index f3b1a7081..7041f484c 100644 --- a/src/app/api/websites/[websiteId]/stats/route.ts +++ b/src/app/api/websites/[websiteId]/stats/route.ts @@ -40,5 +40,5 @@ export async function GET( endDate, }); - return json({ ...data, comparison }); + return json({ ...data[0], comparison }); } diff --git a/src/components/input/WebsiteSelect.tsx b/src/components/input/WebsiteSelect.tsx index 103e5c592..0df4c1af8 100644 --- a/src/components/input/WebsiteSelect.tsx +++ b/src/components/input/WebsiteSelect.tsx @@ -1,26 +1,30 @@ import { useState } from 'react'; -import { Select, SelectProps, ListItem } from '@umami/react-zen'; -import { useUserWebsitesQuery, useMessages, useLoginQuery } from '@/components/hooks'; +import { Select, SelectProps, ListItem, Text } from '@umami/react-zen'; +import { + useUserWebsitesQuery, + useWebsiteQuery, + useNavigation, + useMessages, +} from '@/components/hooks'; import { Empty } from '@/components/common/Empty'; export function WebsiteSelect({ websiteId, teamId, - onChange, - includeTeams, ...props }: { websiteId?: string; teamId?: string; - includeTeams?: boolean; } & SelectProps) { const { formatMessage, messages } = useMessages(); + const { router, renderUrl } = useNavigation(); const [search, setSearch] = useState(''); - const { user } = useLoginQuery(); - const { data, isLoading } = useUserWebsitesQuery( - { userId: user?.id, teamId }, - { search, pageSize: 5, includeTeams }, - ); + const { data: website } = useWebsiteQuery(websiteId); + const { data, isLoading } = useUserWebsitesQuery({ teamId }, { search, pageSize: 5 }); + + const handleSelect = (value: any) => { + router.push(renderUrl(`/websites/${value}`)); + }; const handleSearch = (value: string) => { setSearch(value); @@ -33,17 +37,24 @@ export function WebsiteSelect({ return ( diff --git a/src/index.ts b/src/index.ts index ab6f0946c..f72bece02 100644 --- a/src/index.ts +++ b/src/index.ts @@ -64,10 +64,6 @@ export * from '@/components/common/SectionHeader'; export * from '@/components/common/SideMenu'; export * from '@/components/common/TypeConfirmationForm'; -export * from '@/components/input/ActionButton'; -export * from '@/components/input/DateFilter'; -export * from '@/components/input/DownloadButton'; -export * from '@/components/input/ExportButton'; export * from '@/components/input/FilterButtons'; export * from '@/components/input/TeamsButton'; export * from '@/components/input/ProfileButton'; diff --git a/src/queries/prisma/website.ts b/src/queries/prisma/website.ts index 6a0c0913c..fc10bcfd8 100644 --- a/src/queries/prisma/website.ts +++ b/src/queries/prisma/website.ts @@ -46,34 +46,46 @@ export async function getWebsites( return pagedQuery('website', { ...criteria, where }, filters); } -export async function getAllUserWebsitesIncludingTeamOwner( - userId: string, - filters?: QueryFilters, -): Promise> { - return getWebsites( - { - where: { - OR: [ - { userId }, - { - team: { - deletedAt: null, - members: { - some: { - role: ROLES.teamOwner, - userId, - }, +export async function getAllWebsites(userId: string) { + return prisma.client.website.findMany({ + where: { + OR: [ + { userId }, + { + team: { + deletedAt: null, + teamUser: { + some: { + userId, }, }, }, - ], - }, + }, + ], + deletedAt: null, }, - { - orderBy: 'name', - ...filters, + }); +} + +export async function getAllUserWebsitesIncludingTeamOwner(userId: string) { + return prisma.client.website.findMany({ + where: { + OR: [ + { userId }, + { + team: { + deletedAt: null, + teamUser: { + some: { + role: ROLES.teamOwner, + userId, + }, + }, + }, + }, + ], }, - ); + }); } export async function getUserWebsites( diff --git a/src/queries/sql/getWebsiteStats.ts b/src/queries/sql/getWebsiteStats.ts index 79fb8bbe9..925c40818 100644 --- a/src/queries/sql/getWebsiteStats.ts +++ b/src/queries/sql/getWebsiteStats.ts @@ -58,7 +58,7 @@ async function relationalQuery( ) as t `, queryParams, - ).then(result => result?.[0]); + ); } async function clickhouseQuery(