From 8e8d2a9ca4e076f7f2a6d0faf645e83a9f73ff4c Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Tue, 28 Jul 2026 14:04:37 +0200 Subject: [PATCH] Move the user activity into the user panel. --- apps/studio/TANSTACK_MIGRATION.md | 1 - .../Users}/UserActivity.constants.ts | 0 .../Users}/UserActivity.utils.test.ts | 0 .../Users}/UserActivity.utils.ts | 0 .../Users}/UserActivityEventDetailSheet.tsx | 0 .../Users}/UserActivityEventItem.tsx | 0 .../interfaces/Auth/Users/UserActivityTab.tsx | 153 +++++++++++++ .../Users}/UserActivityTimeline.tsx | 0 .../interfaces/Auth/Users/UserPanel.test.tsx | 25 +++ .../interfaces/Auth/Users/UserPanel.tsx | 20 +- .../UserActivity/UserActivity.tsx | 175 --------------- .../UserActivity/UserActivitySelector.tsx | 203 ------------------ .../ObservabilityMenu.utils.tsx | 10 - .../[ref]/observability/user-activity.tsx | 19 -- apps/studio/routeTree.gen.ts | 23 -- .../$ref/observability/user-activity.tsx | 14 -- 16 files changed, 196 insertions(+), 447 deletions(-) rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivity.constants.ts (100%) rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivity.utils.test.ts (100%) rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivity.utils.ts (100%) rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivityEventDetailSheet.tsx (100%) rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivityEventItem.tsx (100%) create mode 100644 apps/studio/components/interfaces/Auth/Users/UserActivityTab.tsx rename apps/studio/components/interfaces/{Observability/UserActivity => Auth/Users}/UserActivityTimeline.tsx (100%) delete mode 100644 apps/studio/components/interfaces/Observability/UserActivity/UserActivity.tsx delete mode 100644 apps/studio/components/interfaces/Observability/UserActivity/UserActivitySelector.tsx delete mode 100644 apps/studio/pages/project/[ref]/observability/user-activity.tsx delete mode 100644 apps/studio/routes/project/$ref/observability/user-activity.tsx diff --git a/apps/studio/TANSTACK_MIGRATION.md b/apps/studio/TANSTACK_MIGRATION.md index e3fb88e33ce..387e808c2ce 100644 --- a/apps/studio/TANSTACK_MIGRATION.md +++ b/apps/studio/TANSTACK_MIGRATION.md @@ -276,7 +276,6 @@ These are the layout-only TanStack files. Most hold a single product layout comp - [x] A `routes/project/$ref/observability/query-performance.tsx` ← `pages/project/[ref]/observability/query-performance.tsx` - [x] A `routes/project/$ref/observability/realtime.tsx` ← `pages/project/[ref]/observability/realtime.tsx` - [x] A `routes/project/$ref/observability/storage.tsx` ← `pages/project/[ref]/observability/storage.tsx` -- [x] A `routes/project/$ref/observability/user-activity.tsx` ← `pages/project/[ref]/observability/user-activity.tsx` ### Project shell — `/advisors/*` diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivity.constants.ts b/apps/studio/components/interfaces/Auth/Users/UserActivity.constants.ts similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivity.constants.ts rename to apps/studio/components/interfaces/Auth/Users/UserActivity.constants.ts diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivity.utils.test.ts b/apps/studio/components/interfaces/Auth/Users/UserActivity.utils.test.ts similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivity.utils.test.ts rename to apps/studio/components/interfaces/Auth/Users/UserActivity.utils.test.ts diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivity.utils.ts b/apps/studio/components/interfaces/Auth/Users/UserActivity.utils.ts similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivity.utils.ts rename to apps/studio/components/interfaces/Auth/Users/UserActivity.utils.ts diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivityEventDetailSheet.tsx b/apps/studio/components/interfaces/Auth/Users/UserActivityEventDetailSheet.tsx similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivityEventDetailSheet.tsx rename to apps/studio/components/interfaces/Auth/Users/UserActivityEventDetailSheet.tsx diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivityEventItem.tsx b/apps/studio/components/interfaces/Auth/Users/UserActivityEventItem.tsx similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivityEventItem.tsx rename to apps/studio/components/interfaces/Auth/Users/UserActivityEventItem.tsx diff --git a/apps/studio/components/interfaces/Auth/Users/UserActivityTab.tsx b/apps/studio/components/interfaces/Auth/Users/UserActivityTab.tsx new file mode 100644 index 00000000000..e690dd3894d --- /dev/null +++ b/apps/studio/components/interfaces/Auth/Users/UserActivityTab.tsx @@ -0,0 +1,153 @@ +import { useParams } from 'common' +import { useMemo, useState } from 'react' +import { Button, cn } from 'ui' +import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' + +import { + buildUserActivitySearch, + isErrorLevel, + mapLogRowToActivityEvent, + type UserActivityEvent, +} from './UserActivity.constants' +import { UserActivityEventDetailSheet } from './UserActivityEventDetailSheet' +import { UserActivityTimeline } from './UserActivityTimeline' +import { PANEL_PADDING } from './Users.constants' +import { REPORT_DATERANGE_HELPER_LABELS } from '@/components/interfaces/Reports/Reports.constants' +import { LogsDatePicker } from '@/components/interfaces/Settings/Logs/Logs.DatePickers' +import UpgradePrompt from '@/components/interfaces/Settings/Logs/UpgradePrompt' +import { AlertError } from '@/components/ui/AlertError' +import { User } from '@/data/auth/users-infinite-query' +import { useUnifiedLogsInfiniteQuery } from '@/data/logs/unified-logs-infinite-query' +import { useReportDateRange } from '@/hooks/misc/useReportDateRange' +import { SHORTCUT_IDS } from '@/state/shortcuts/registry' + +type UserActivityFilter = 'all' | 'errors' + +interface UserActivityTabProps { + user: User +} + +export const UserActivityTab = ({ user }: UserActivityTabProps) => { + const { ref: projectRef } = useParams() + + const [filter, setFilter] = useState('all') + const [showDatePicker, setShowDatePicker] = useState(false) + const [payloadEvent, setPayloadEvent] = useState(null) + + const { + selectedDateRange, + datePickerValue, + datePickerHelpers, + showUpgradePrompt, + setShowUpgradePrompt, + handleDatePickerChange, + } = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES) + + const search = useMemo( + () => + buildUserActivitySearch({ + user: user.id, + date: [ + new Date(selectedDateRange.period_start.date), + new Date(selectedDateRange.period_end.date), + ], + }), + [user.id, selectedDateRange] + ) + + const { + data, + isLoading, + isPlaceholderData, + isError, + error, + hasNextPage, + fetchNextPage, + isFetchingNextPage, + } = useUnifiedLogsInfiniteQuery({ projectRef, search }) + + const events = useMemo(() => { + const rows = data?.pages?.flatMap((page) => page.data ?? []) ?? [] + const mapped = rows.map(mapLogRowToActivityEvent) + return filter === 'errors' ? mapped.filter((event) => isErrorLevel(event.level)) : mapped + }, [data?.pages, filter]) + + return ( +
+
+
+ +
+ +
+ + + +
+ + {isLoading || isPlaceholderData ? ( + + ) : isError ? ( + + ) : ( + <> + + {hasNextPage && ( + + )} + + )} + + setPayloadEvent(null)} /> +
+ ) +} diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivityTimeline.tsx b/apps/studio/components/interfaces/Auth/Users/UserActivityTimeline.tsx similarity index 100% rename from apps/studio/components/interfaces/Observability/UserActivity/UserActivityTimeline.tsx rename to apps/studio/components/interfaces/Auth/Users/UserActivityTimeline.tsx diff --git a/apps/studio/components/interfaces/Auth/Users/UserPanel.test.tsx b/apps/studio/components/interfaces/Auth/Users/UserPanel.test.tsx index 23b4caea738..6f532d96f09 100644 --- a/apps/studio/components/interfaces/Auth/Users/UserPanel.test.tsx +++ b/apps/studio/components/interfaces/Auth/Users/UserPanel.test.tsx @@ -1,4 +1,5 @@ import { screen } from '@testing-library/react' +import { useFlag } from 'common' import { http, HttpResponse } from 'msw' import { ResizablePanelGroup } from 'ui' import { beforeEach, describe, expect, it, vi } from 'vitest' @@ -27,6 +28,12 @@ vi.mock('@/hooks/misc/useSelectedProject', () => ({ .mockReturnValue({ data: { ref: 'project-ref', connectionString: 'postgres://' } }), })) +// Defaults the `UserActivity` ConfigCat flag to off; individual tests override this. +vi.mock('common', async (importOriginal) => ({ + ...(await importOriginal()), + useFlag: vi.fn().mockReturnValue(false), +})) + // Heavy tab bodies — the sanctioned use of vi.mock. This spec only asserts tab // visibility, not what the tabs render. vi.mock('./UserOverview', () => ({ @@ -35,6 +42,9 @@ vi.mock('./UserOverview', () => ({ vi.mock('./UserLogs', () => ({ UserLogs: () =>
, })) +vi.mock('./UserActivityTab', () => ({ + UserActivityTab: () =>
, +})) const renderPanel = (disabledFeatures: string[] = []) => { // The user query flows through pg-meta SQL; mock it at the network boundary. @@ -88,4 +98,19 @@ describe('UserPanel', () => { expect(screen.queryByRole('tab', { name: 'Logs' })).not.toBeInTheDocument() expect(screen.getByRole('tab', { name: 'Raw JSON' })).toBeInTheDocument() }) + + it('shows the Activity tab when the UserActivity flag is enabled', async () => { + vi.mocked(useFlag).mockReturnValue(true) + renderPanel([]) + + expect(await screen.findByRole('tab', { name: 'Overview' })).toBeInTheDocument() + expect(screen.getByRole('tab', { name: 'Activity' })).toBeInTheDocument() + }) + + it('hides the Activity tab when the UserActivity flag is disabled', async () => { + renderPanel([]) + + expect(await screen.findByRole('tab', { name: 'Overview' })).toBeInTheDocument() + expect(screen.queryByRole('tab', { name: 'Activity' })).not.toBeInTheDocument() + }) }) diff --git a/apps/studio/components/interfaces/Auth/Users/UserPanel.tsx b/apps/studio/components/interfaces/Auth/Users/UserPanel.tsx index f9d7342f6ed..2f35b78732b 100644 --- a/apps/studio/components/interfaces/Auth/Users/UserPanel.tsx +++ b/apps/studio/components/interfaces/Auth/Users/UserPanel.tsx @@ -1,3 +1,4 @@ +import { useFlag } from 'common' import { X } from 'lucide-react' import { parseAsString, useQueryState } from 'nuqs' import { useState } from 'react' @@ -15,6 +16,7 @@ import { import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { SimpleCodeBlock } from 'ui-patterns/SimpleCodeBlock' +import { UserActivityTab } from './UserActivityTab' import { UserLogs } from './UserLogs' import { UserOverview } from './UserOverview' import { PANEL_PADDING } from './Users.constants' @@ -26,13 +28,14 @@ import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' export const UserPanel = () => { const { data: project } = useSelectedProjectQuery() const showLogs = useIsFeatureEnabled('logs:all') + const showActivity = useFlag('UserActivity') const [selectedId, setSelectedId] = useQueryState( 'show', parseAsString.withOptions({ history: 'push', clearOnDefault: true }) ) - const [view, setView] = useState<'overview' | 'raw' | 'logs'>('overview') + const [view, setView] = useState<'overview' | 'raw' | 'logs' | 'activity'>('overview') const [searchQuery, setSearchQuery] = useState('') const { data: selectedUser, isPending } = useUserQuery({ @@ -69,7 +72,7 @@ export const UserPanel = () => { setView(value as 'overview' | 'raw' | 'logs')} + onValueChange={(value) => setView(value as 'overview' | 'raw' | 'logs' | 'activity')} > {isPending ? (
@@ -95,6 +98,14 @@ export const UserPanel = () => { Logs )} + {showActivity && ( + + Activity + + )} { {selectedUser && } )} + {showActivity && ( + + {selectedUser && } + + )} { - const { ref: projectRef } = useParams() - const { data: project } = useSelectedProjectQuery() - - const [selectedUserId, setSelectedUserId] = useQueryState('user', parseAsString) - const [filter, setFilter] = useState('all') - const [showDatePicker, setShowDatePicker] = useState(false) - const [payloadEvent, setPayloadEvent] = useState(null) - - const { - selectedDateRange, - datePickerValue, - datePickerHelpers, - showUpgradePrompt, - setShowUpgradePrompt, - handleDatePickerChange, - } = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES) - - const search = useMemo( - () => - buildUserActivitySearch({ - user: selectedUserId ?? '', - date: [ - new Date(selectedDateRange.period_start.date), - new Date(selectedDateRange.period_end.date), - ], - }), - [selectedUserId, selectedDateRange] - ) - - const { - data, - isLoading, - isPlaceholderData, - isError, - error, - hasNextPage, - fetchNextPage, - isFetchingNextPage, - } = useUnifiedLogsInfiniteQuery({ projectRef, search }, { enabled: !!selectedUserId }) - - const events = useMemo(() => { - const rows = data?.pages?.flatMap((page) => page.data ?? []) ?? [] - const mapped = rows.map(mapLogRowToActivityEvent) - return filter === 'errors' ? mapped.filter((event) => isErrorLevel(event.level)) : mapped - }, [data?.pages, filter]) - - return ( -
-
-
-
-

User Activity

- Beta -
-
- -
- -
- -
- -
- - - -
-
- - {!selectedUserId ? ( - - ) : isLoading || isPlaceholderData ? ( - - ) : isError ? ( - - ) : ( - <> - - {hasNextPage && ( - - )} - - )} - - setPayloadEvent(null)} /> -
- ) -} diff --git a/apps/studio/components/interfaces/Observability/UserActivity/UserActivitySelector.tsx b/apps/studio/components/interfaces/Observability/UserActivity/UserActivitySelector.tsx deleted file mode 100644 index 429b245f693..00000000000 --- a/apps/studio/components/interfaces/Observability/UserActivity/UserActivitySelector.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import { keepPreviousData } from '@tanstack/react-query' -import { useDebounce } from '@uidotdev/usehooks' -import { ChevronDown, User as IconUser, Loader2, Search, X } from 'lucide-react' -import { useMemo, useState } from 'react' -import { - Button, - InputGroup, - InputGroupAddon, - InputGroupButton, - InputGroupInput, - Popover, - PopoverContent, - PopoverTrigger, -} from 'ui' - -import { getAvatarUrl, getDisplayName } from '@/components/interfaces/Auth/Users/Users.utils' -import { AlertError } from '@/components/ui/AlertError' -import { useUserQuery } from '@/data/auth/user-query' -import { User, useUsersInfiniteQuery } from '@/data/auth/users-infinite-query' - -interface UserActivitySelectorProps { - projectRef: string | undefined - connectionString: string | null | undefined - value: string | null - onChange: (userId: string | null) => void -} - -export const UserActivitySelector = ({ - projectRef, - connectionString, - value, - onChange, -}: UserActivitySelectorProps) => { - const [open, setOpen] = useState(false) - const [searchText, setSearchText] = useState('') - const debouncedSearchText = useDebounce(searchText, 300) - - // The last user picked from the list, kept locally so the trigger can show a display - // name/avatar immediately without waiting on a lookup. - const [resolvedUser, setResolvedUser] = useState(null) - - // On a fresh page load with only `?user=` in the URL (no picked-user cache yet), - // look the user up by id so the trigger can show their name instead of the raw id. - const isResolved = resolvedUser?.id === value - const { data: fetchedUser, isLoading: isLoadingUser } = useUserQuery( - { projectRef, connectionString, userId: value }, - { enabled: !!value && !isResolved } - ) - const displayUser = isResolved ? resolvedUser : (fetchedUser ?? null) - const isResolvingUser = !!value && !displayUser && isLoadingUser - - const { - data, - isSuccess, - isPending: isLoading, - isError, - error, - isFetching, - isPlaceholderData, - } = useUsersInfiniteQuery( - { projectRef, connectionString, keywords: debouncedSearchText.trim().toLowerCase() }, - { placeholderData: keepPreviousData, enabled: open } - ) - const users = useMemo(() => data?.pages.flatMap((page) => page.result) ?? [], [data?.pages]) - const isSearching = isPlaceholderData && isFetching - - const handleSelect = (user: User) => { - if (!user.id) return - setResolvedUser(user) - onChange(user.id) - setOpen(false) - setSearchText('') - } - - const displayName = displayUser - ? getDisplayName(displayUser, displayUser.email ?? displayUser.phone ?? displayUser.id ?? '') - : null - - return ( - - - - - -
- - setSearchText(e.target.value)} - value={searchText} - autoFocus - /> - - {isSearching ? ( - - ) : ( - - )} - - {searchText && ( - - setSearchText('')}> - Clear search - - - - )} - - - {isLoading && ( -
- - Loading users... -
- )} - - {isError && } - - {isSuccess && - (users.length > 0 ? ( -
    - {users.map((user) => ( -
  • - -
  • - ))} -
- ) : ( -
-

- No users found -

-
- ))} -
-
-
- ) -} - -const UserAvatar = ({ user }: { user: User | null }) => { - const avatarUrl = user ? getAvatarUrl(user) : undefined - if (avatarUrl) { - return - } - return ( -
- -
- ) -} - -const UserActivitySelectorRow = ({ - user, - onClick, -}: { - user: User - onClick: (user: User) => void -}) => { - const emailOrPhone = user.email || user.phone - const displayName = getDisplayName(user, '') - const showDisplayName = displayName && displayName !== emailOrPhone - - return ( - - ) -} diff --git a/apps/studio/components/layouts/ObservabilityLayout/ObservabilityMenu.utils.tsx b/apps/studio/components/layouts/ObservabilityLayout/ObservabilityMenu.utils.tsx index 97e1814dbba..efd8b8c1b98 100644 --- a/apps/studio/components/layouts/ObservabilityLayout/ObservabilityMenu.utils.tsx +++ b/apps/studio/components/layouts/ObservabilityLayout/ObservabilityMenu.utils.tsx @@ -48,7 +48,6 @@ export const useGenerateObservabilityMenu = () => { const showOverview = useFlag('observabilityOverview') const topForPostgres = useFlag('topForPostgres') - const userActivity = useFlag('UserActivity') const { isSupamonitorEnabled } = useSupamonitorStatus() const storageSupported = useIsFeatureEnabled('project_storage:all') @@ -65,15 +64,6 @@ export const useGenerateObservabilityMenu = () => { }, ] : []), - ...(userActivity - ? [ - { - name: 'User Activity', - key: 'user-activity', - url: `${baseUrl}/user-activity${preservedQueryParams}`, - }, - ] - : []), ...(isSupamonitorEnabled ? [ { diff --git a/apps/studio/pages/project/[ref]/observability/user-activity.tsx b/apps/studio/pages/project/[ref]/observability/user-activity.tsx deleted file mode 100644 index 08cd3726ec7..00000000000 --- a/apps/studio/pages/project/[ref]/observability/user-activity.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { UserActivity } from '@/components/interfaces/Observability/UserActivity/UserActivity' -import { ReportPadding } from '@/components/interfaces/Reports/ReportPadding' -import { DefaultLayout } from '@/components/layouts/DefaultLayout' -import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout' -import type { NextPageWithLayout } from '@/types' - -const UserActivityPage: NextPageWithLayout = () => ( - - - -) - -UserActivityPage.getLayout = (page) => ( - - {page} - -) - -export default UserActivityPage diff --git a/apps/studio/routeTree.gen.ts b/apps/studio/routeTree.gen.ts index 0db3e9fd968..8f8e52c4d4d 100644 --- a/apps/studio/routeTree.gen.ts +++ b/apps/studio/routeTree.gen.ts @@ -111,7 +111,6 @@ import { Route as ProjectRefSettingsAddonsRouteImport } from './routes/project/$ import { Route as ProjectRefRealtimeSettingsRouteImport } from './routes/project/$ref/realtime/settings' import { Route as ProjectRefRealtimePoliciesRouteImport } from './routes/project/$ref/realtime/policies' import { Route as ProjectRefRealtimeInspectorRouteImport } from './routes/project/$ref/realtime/inspector' -import { Route as ProjectRefObservabilityUserActivityRouteImport } from './routes/project/$ref/observability/user-activity' import { Route as ProjectRefObservabilityStorageRouteImport } from './routes/project/$ref/observability/storage' import { Route as ProjectRefObservabilityRealtimeRouteImport } from './routes/project/$ref/observability/realtime' import { Route as ProjectRefObservabilityQueryPerformanceRouteImport } from './routes/project/$ref/observability/query-performance' @@ -850,12 +849,6 @@ const ProjectRefRealtimeInspectorRoute = path: '/inspector', getParentRoute: () => ProjectRefRealtimeRoute, } as any) -const ProjectRefObservabilityUserActivityRoute = - ProjectRefObservabilityUserActivityRouteImport.update({ - id: '/user-activity', - path: '/user-activity', - getParentRoute: () => ProjectRefObservabilityRoute, - } as any) const ProjectRefObservabilityStorageRoute = ProjectRefObservabilityStorageRouteImport.update({ id: '/storage', @@ -2200,7 +2193,6 @@ export interface FileRoutesByFullPath { '/project/$ref/observability/query-performance': typeof ProjectRefObservabilityQueryPerformanceRoute '/project/$ref/observability/realtime': typeof ProjectRefObservabilityRealtimeRoute '/project/$ref/observability/storage': typeof ProjectRefObservabilityStorageRoute - '/project/$ref/observability/user-activity': typeof ProjectRefObservabilityUserActivityRoute '/project/$ref/realtime/inspector': typeof ProjectRefRealtimeInspectorRoute '/project/$ref/realtime/policies': typeof ProjectRefRealtimePoliciesRoute '/project/$ref/realtime/settings': typeof ProjectRefRealtimeSettingsRoute @@ -2497,7 +2489,6 @@ export interface FileRoutesByTo { '/project/$ref/observability/query-performance': typeof ProjectRefObservabilityQueryPerformanceRoute '/project/$ref/observability/realtime': typeof ProjectRefObservabilityRealtimeRoute '/project/$ref/observability/storage': typeof ProjectRefObservabilityStorageRoute - '/project/$ref/observability/user-activity': typeof ProjectRefObservabilityUserActivityRoute '/project/$ref/realtime/inspector': typeof ProjectRefRealtimeInspectorRoute '/project/$ref/realtime/policies': typeof ProjectRefRealtimePoliciesRoute '/project/$ref/realtime/settings': typeof ProjectRefRealtimeSettingsRoute @@ -2807,7 +2798,6 @@ export interface FileRoutesById { '/project/$ref/observability/query-performance': typeof ProjectRefObservabilityQueryPerformanceRoute '/project/$ref/observability/realtime': typeof ProjectRefObservabilityRealtimeRoute '/project/$ref/observability/storage': typeof ProjectRefObservabilityStorageRoute - '/project/$ref/observability/user-activity': typeof ProjectRefObservabilityUserActivityRoute '/project/$ref/realtime/inspector': typeof ProjectRefRealtimeInspectorRoute '/project/$ref/realtime/policies': typeof ProjectRefRealtimePoliciesRoute '/project/$ref/realtime/settings': typeof ProjectRefRealtimeSettingsRoute @@ -3117,7 +3107,6 @@ export interface FileRouteTypes { | '/project/$ref/observability/query-performance' | '/project/$ref/observability/realtime' | '/project/$ref/observability/storage' - | '/project/$ref/observability/user-activity' | '/project/$ref/realtime/inspector' | '/project/$ref/realtime/policies' | '/project/$ref/realtime/settings' @@ -3414,7 +3403,6 @@ export interface FileRouteTypes { | '/project/$ref/observability/query-performance' | '/project/$ref/observability/realtime' | '/project/$ref/observability/storage' - | '/project/$ref/observability/user-activity' | '/project/$ref/realtime/inspector' | '/project/$ref/realtime/policies' | '/project/$ref/realtime/settings' @@ -3723,7 +3711,6 @@ export interface FileRouteTypes { | '/project/$ref/observability/query-performance' | '/project/$ref/observability/realtime' | '/project/$ref/observability/storage' - | '/project/$ref/observability/user-activity' | '/project/$ref/realtime/inspector' | '/project/$ref/realtime/policies' | '/project/$ref/realtime/settings' @@ -4712,13 +4699,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefRealtimeInspectorRouteImport parentRoute: typeof ProjectRefRealtimeRoute } - '/project/$ref/observability/user-activity': { - id: '/project/$ref/observability/user-activity' - path: '/user-activity' - fullPath: '/project/$ref/observability/user-activity' - preLoaderRoute: typeof ProjectRefObservabilityUserActivityRouteImport - parentRoute: typeof ProjectRefObservabilityRoute - } '/project/$ref/observability/storage': { id: '/project/$ref/observability/storage' path: '/storage' @@ -6605,7 +6585,6 @@ interface ProjectRefObservabilityRouteChildren { ProjectRefObservabilityQueryPerformanceRoute: typeof ProjectRefObservabilityQueryPerformanceRoute ProjectRefObservabilityRealtimeRoute: typeof ProjectRefObservabilityRealtimeRoute ProjectRefObservabilityStorageRoute: typeof ProjectRefObservabilityStorageRoute - ProjectRefObservabilityUserActivityRoute: typeof ProjectRefObservabilityUserActivityRoute ProjectRefObservabilityIndexRoute: typeof ProjectRefObservabilityIndexRoute } @@ -6628,8 +6607,6 @@ const ProjectRefObservabilityRouteChildren: ProjectRefObservabilityRouteChildren ProjectRefObservabilityQueryPerformanceRoute, ProjectRefObservabilityRealtimeRoute: ProjectRefObservabilityRealtimeRoute, ProjectRefObservabilityStorageRoute: ProjectRefObservabilityStorageRoute, - ProjectRefObservabilityUserActivityRoute: - ProjectRefObservabilityUserActivityRoute, ProjectRefObservabilityIndexRoute: ProjectRefObservabilityIndexRoute, } diff --git a/apps/studio/routes/project/$ref/observability/user-activity.tsx b/apps/studio/routes/project/$ref/observability/user-activity.tsx deleted file mode 100644 index d6ad031497a..00000000000 --- a/apps/studio/routes/project/$ref/observability/user-activity.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -import UserActivityPage from '@/pages/project/[ref]/observability/user-activity' - -export const Route = createFileRoute('/project/$ref/observability/user-activity')({ - component: ObservabilityUserActivityRoute, - staticData: { - observabilityLayoutTitle: 'User Activity', - }, -}) - -function ObservabilityUserActivityRoute() { - return -}