diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/charts/events-per-day-chart.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/charts/events-per-day-chart.tsx index 763cfff8..86be57f7 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/charts/events-per-day-chart.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/charts/events-per-day-chart.tsx @@ -1,4 +1,5 @@ import { ChartSwitchShortcut } from '@/components/report/chart'; +import { Widget, WidgetBody, WidgetHead } from '@/components/widget'; import type { IChartEvent } from '@openpanel/validation'; @@ -20,23 +21,28 @@ export function EventsPerDayChart({ projectId, filters, events }: Props) { ]; return ( -
- 0 - ? events.map((name) => ({ - id: name, - name, - displayName: name, - segment: 'event', - filters: filters ?? [], - })) - : fallback - } - /> -
+ + + Events per day + + + 0 + ? events.map((name) => ({ + id: name, + name, + displayName: name, + segment: 'event', + filters: filters ?? [], + })) + : fallback + } + /> + + ); } diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/event-conversions-list.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/event-conversions-list.tsx index f4218bc9..161fa5fa 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/event-conversions-list.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/event-conversions-list.tsx @@ -6,7 +6,7 @@ import { isSameDay } from 'date-fns'; import type { IServiceCreateEventPayload } from '@openpanel/db'; -import { EventListItem } from '../event-list-item'; +import { EventListItem } from '../event-list/event-list-item'; function showDateHeader(a: Date, b?: Date) { if (!b) return true; @@ -18,7 +18,7 @@ interface EventListProps { } export function EventConversionsList({ data }: EventListProps) { return ( - +
Conversions
diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/index.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/index.tsx index 57bcee32..338ae0ac 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/index.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-conversions-list/index.tsx @@ -1,3 +1,4 @@ +import withLoadingWidget from '@/hocs/with-loading-widget'; import { escape } from 'sqlstring'; import { db, getEvents } from '@openpanel/db'; @@ -8,7 +9,7 @@ interface Props { projectId: string; } -export default async function EventConversionsListServer({ projectId }: Props) { +async function EventConversionsListServer({ projectId }: Props) { const conversions = await db.eventMeta.findMany({ where: { projectId, @@ -30,3 +31,5 @@ export default async function EventConversionsListServer({ projectId }: Props) { return ; } + +export default withLoadingWidget(EventConversionsListServer); diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-details.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-details.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-details.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-details.tsx index 76e03835..7d753fc9 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-details.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-details.tsx @@ -1,5 +1,3 @@ -'use client'; - import { useState } from 'react'; import type { Dispatch, SetStateAction } from 'react'; import { ChartSwitchShortcut } from '@/components/report/chart'; @@ -27,6 +25,7 @@ interface Props { open: boolean; setOpen: Dispatch>; } + export function EventDetails({ event, open, setOpen }: Props) { const { name } = event; const [isEditOpen, setIsEditOpen] = useState(false); diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-edit.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-edit.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-edit.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-edit.tsx diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-icon.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-icon.tsx similarity index 85% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-icon.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-icon.tsx index 03004579..0bfa9cda 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-icon.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-icon.tsx @@ -1,25 +1,8 @@ -import { useEffect, useState } from 'react'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { Label } from '@/components/ui/label'; -import { - Sheet, - SheetContent, - SheetFooter, - SheetHeader, - SheetTitle, - SheetTrigger, -} from '@/components/ui/sheet'; -import { Tooltip, TooltipContent } from '@/components/ui/tooltip'; -import { api } from '@/trpc/client'; import { cn } from '@/utils/cn'; -import { TooltipTrigger } from '@radix-ui/react-tooltip'; import type { VariantProps } from 'class-variance-authority'; import { cva } from 'class-variance-authority'; import type { LucideIcon } from 'lucide-react'; import * as Icons from 'lucide-react'; -import { useRouter } from 'next/navigation'; -import { toast } from 'sonner'; import type { EventMeta } from '@openpanel/db'; diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list-item.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list-item.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list-item.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list-item.tsx diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list.tsx similarity index 90% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list.tsx index 8c86e380..dd50adff 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list.tsx @@ -1,19 +1,13 @@ 'use client'; -import { Fragment, Suspense } from 'react'; +import { Fragment } from 'react'; import { FullPageEmptyState } from '@/components/full-page-empty-state'; import { Pagination } from '@/components/pagination'; -import { ChartSwitch, ChartSwitchShortcut } from '@/components/report/chart'; import { Button } from '@/components/ui/button'; -import { useAppParams } from '@/hooks/useAppParams'; import { useCursor } from '@/hooks/useCursor'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; import { isSameDay } from 'date-fns'; -import { - ChevronLeftIcon, - ChevronRightIcon, - GanttChartIcon, -} from 'lucide-react'; +import { GanttChartIcon } from 'lucide-react'; import type { IServiceCreateEventPayload } from '@openpanel/db'; @@ -29,9 +23,11 @@ interface EventListProps { data: IServiceCreateEventPayload[]; count: number; } -export function EventList({ data, count }: EventListProps) { + +function EventList({ data, count }: EventListProps) { const { cursor, setCursor, loading } = useCursor(); const [filters] = useEventQueryFilters(); + return ( <> {data.length === 0 ? ( @@ -100,3 +96,5 @@ export function EventList({ data, count }: EventListProps) { ); } + +export default EventList; diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-listener.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-listener.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-listener.tsx rename to apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-listener.tsx diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/index.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/index.tsx new file mode 100644 index 00000000..79c09359 --- /dev/null +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/event-list/index.tsx @@ -0,0 +1,47 @@ +import withSuspense from '@/hocs/with-suspense'; + +import { getEventList, getEventsCount } from '@openpanel/db'; +import type { IChartEventFilter } from '@openpanel/validation'; + +import EventList from './event-list'; + +type Props = { + cursor?: number; + projectId: string; + filters?: IChartEventFilter[]; + eventNames?: string[]; +}; + +const EventListServer = async ({ + cursor, + projectId, + eventNames, + filters, +}: Props) => { + const [events, count] = await Promise.all([ + getEventList({ + cursor, + projectId, + take: 50, + events: eventNames, + filters, + }), + getEventsCount({ + projectId, + events: eventNames, + filters, + }), + ]); + + return ; +}; + +export default withSuspense(EventListServer, () => ( +
+
+
+
+
+
+
+)); diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/loading.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/loading.tsx deleted file mode 100644 index 9cf2cf50..00000000 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/loading.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import FullPageLoadingState from '@/components/full-page-loading-state'; - -export default FullPageLoadingState; diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/page.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/page.tsx index b251a43e..553103a4 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/page.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/events/page.tsx @@ -7,12 +7,10 @@ import { } from '@/hooks/useEventQueryFilters'; import { parseAsInteger } from 'nuqs'; -import { getEventList, getEventsCount } from '@openpanel/db'; - import { StickyBelowHeader } from '../layout-sticky-below-header'; import { EventsPerDayChart } from './charts/events-per-day-chart'; import EventConversionsListServer from './event-conversions-list'; -import { EventList } from './event-list'; +import EventListServer from './event-list'; interface PageProps { params: { @@ -30,30 +28,16 @@ const nuqsOptions = { shallow: false, }; -export default async function Page({ +export default function Page({ params: { projectId, organizationSlug }, searchParams, }: PageProps) { + const cursor = + parseAsInteger.parseServerSide(searchParams.cursor ?? '') ?? undefined; const filters = eventQueryFiltersParser.parseServerSide(searchParams.f ?? '') ?? undefined; - const eventsFilter = eventQueryNamesFilter.parseServerSide( - searchParams.events ?? '' - ); - const [events, count] = await Promise.all([ - getEventList({ - cursor: - parseAsInteger.parseServerSide(searchParams.cursor ?? '') ?? undefined, - projectId, - take: 50, - events: eventsFilter, - filters, - }), - getEventsCount({ - projectId, - events: eventsFilter, - filters, - }), - ]); + const eventNames = + eventQueryNamesFilter.parseServerSide(searchParams.events) ?? undefined; return ( <> @@ -72,12 +56,17 @@ export default async function Page({
- +
-
+
diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/profile-top/index.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/profile-top/index.tsx index 9a04cf0a..570122fc 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/profile-top/index.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/profile-top/index.tsx @@ -20,7 +20,7 @@ async function ProfileTopServer({ organizationSlug, projectId }: Props) { const res = await chQuery<{ profile_id: string; count: number }>( `SELECT profile_id, count(*) as count from events where profile_id != '' and project_id = ${escape(projectId)} group by profile_id order by count() DESC LIMIT 50` ); - const profiles = await getProfiles({ ids: res.map((r) => r.profile_id) }); + const profiles = await getProfiles(res.map((r) => r.profile_id)); const list = res.map((item) => { return { count: item.count, diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/realtime/realtime-live-events/live-events.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/realtime/realtime-live-events/live-events.tsx index 6fd86cd6..6f9b464d 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/realtime/realtime-live-events/live-events.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/realtime/realtime-live-events/live-events.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import { EventListItem } from '@/app/(app)/[organizationSlug]/[projectId]/events/event-list-item'; +import { EventListItem } from '@/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list-item'; import useWS from '@/hooks/useWS'; import { AnimatePresence, motion } from 'framer-motion'; diff --git a/apps/dashboard/src/app/(auth)/live-events/live-events.tsx b/apps/dashboard/src/app/(auth)/live-events/live-events.tsx index 6842b741..fb01dca7 100644 --- a/apps/dashboard/src/app/(auth)/live-events/live-events.tsx +++ b/apps/dashboard/src/app/(auth)/live-events/live-events.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import { EventListItem } from '@/app/(app)/[organizationSlug]/[projectId]/events/event-list-item'; +import { EventListItem } from '@/app/(app)/[organizationSlug]/[projectId]/events/event-list/event-list-item'; import useWS from '@/hooks/useWS'; import { AnimatePresence, motion } from 'framer-motion'; diff --git a/apps/dashboard/src/components/pagination.tsx b/apps/dashboard/src/components/pagination.tsx index 4c8cbe87..ffaec39d 100644 --- a/apps/dashboard/src/components/pagination.tsx +++ b/apps/dashboard/src/components/pagination.tsx @@ -44,21 +44,12 @@ export function Pagination({ return (
- {size === 'base' && ( - <> -
Page: {cursor + 1}
- {typeof count === 'number' && ( -
Total rows: {count}
- )} - - )} {size === 'base' && ( +