import { useKeyboardShortcuts } from 'components/grid/components/common/Hooks' import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState' import AlertError from 'components/ui/AlertError' import LoadingOpacity from 'components/ui/LoadingOpacity' import ShimmerLine from 'components/ui/ShimmerLine' import { useWarehouseAccessTokensQuery } from 'data/analytics/warehouse-access-tokens-query' import { useWarehouseLogDetailQuery } from 'data/analytics/warehouse-collection-log-detail-query' import { useWarehouseCollectionsQuery } from 'data/analytics/warehouse-collections-query' import { useWarehouseQueryQuery } from 'data/analytics/warehouse-query' import dayjs from 'dayjs' import { useSelectedLog } from 'hooks/analytics/useSelectedLog' import { useFlag } from 'hooks/ui/useFlag' import { RefreshCcw, Rewind, Terminal } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui' import { LogsDatePicker } from '../Settings/Logs/Logs.DatePickers' import { DatetimeHelper } from '../Settings/Logs/Logs.types' import LogTable from '../Settings/Logs/LogTable' import { TestCollectionDialog } from './TestCollectionDialog' const INTERVALS: DatetimeHelper[] = [ { text: 'Last hour', calcFrom: () => dayjs().subtract(1, 'hour').toISOString(), calcTo: () => dayjs().toISOString(), default: true, }, { text: 'Last 12 hours', calcFrom: () => dayjs().subtract(12, 'hour').toISOString(), calcTo: () => dayjs().toISOString(), }, { text: 'Last day', calcFrom: () => dayjs().subtract(1, 'day').toISOString(), calcTo: () => dayjs().toISOString(), }, { text: 'Last 7 days', calcFrom: () => dayjs().subtract(7, 'day').toISOString(), calcTo: () => dayjs().toISOString(), }, ] export const WarehouseCollectionDetail = () => { const router = useRouter() const collectionToken = router.query.collectionToken as string const projectRef = router.query.ref as string const accessTokens = useWarehouseAccessTokensQuery({ projectRef }) const [testDialogOpen, setTestDialogOpen] = useState(false) const hasWarehouse = useFlag('warehouse') const { data: collections, isLoading: collectionsLoading } = useWarehouseCollectionsQuery( { projectRef }, { enabled: hasWarehouse } ) const collection = collections?.find((c) => c.token === collectionToken) const [search, setSearch] = useState('') const [filters, setFilters] = useState({ limit: 100, offset: 0, search: '', interval: { to: INTERVALS[0].calcTo, from: INTERVALS[0].calcFrom, }, }) const [sql, setSQL] = useState('') useEffect(() => { if (collection) { const from = filters.interval.from() const to = filters.interval.to() const sql = `select id, timestamp from \`${collection.name}\` where timestamp >= TIMESTAMP('${from}') and timestamp <= TIMESTAMP('${to}') order by timestamp desc limit ${filters.limit} offset ${filters.offset} ` setSQL(sql) } }, [filters.interval, filters.limit, filters.offset, collection]) const { isLoading: queryLoading, data: queryData, isError, isRefetching, } = useWarehouseQueryQuery( { ref: projectRef, sql }, { enabled: !!sql && hasWarehouse, } ) const formatResults = (results: any) => { if (!results || !results.length) { return [] } const r = results.map(({ timestamp, ...r }: any) => { return { timestamp: new Date(timestamp / 1000).toLocaleString(), ...r, } }) return r } const results = formatResults(queryData?.result) function loadMore() { setFilters({ ...filters, offset: filters.offset + filters.limit }) } const isLoading = queryLoading || collectionsLoading || isRefetching function refreshResults(e?: React.FormEvent) { e?.preventDefault() setFilters({ ...filters, search, interval: { to: () => dayjs().toISOString(), from: () => filters.interval.from() || dayjs().subtract(1, 'hour').toISOString(), }, }) } const queryUrl = `/project/${projectRef}/logs/explorer?q=${encodeURIComponent( sql || '' )}&source=warehouse` useKeyboardShortcuts( { r: () => { document.getElementById('refresh-button')?.focus() }, s: () => { document.getElementById('search-input')?.focus() }, }, ['INPUT', 'BUTTON', 'TEXTAREA'] ) function KeyboardShortcut({ children }: { children: React.ReactNode }) { return ( {children} ) } // Selected Log Detail const [selectedLogId, setSelectedLogId] = useSelectedLog() const { data: selectedLogDetail, isLoading: selectedLogDetailLoading, error: selectedLogDetailError, } = useWarehouseLogDetailQuery({ ref: projectRef, collectionName: collection?.name, logId: selectedLogId ?? undefined, }) return (

{collection?.name}

Open query in Collections Explorer
{ refreshResults() setTestDialogOpen(false) }} />
{isError && (
)} {!isError && ( setSelectedLogId(log?.id ?? null)} selectedLog={selectedLogDetail?.result[0] ?? undefined} selectedLogError={selectedLogDetailError ?? undefined} isSelectedLogLoading={!!selectedLogId && selectedLogDetailLoading} data={results} showHeader={false} EmptyState={

Try adjusting your filters, send a test event or refresh the results.

} /> )}
{!isError && (
{results.length > 0 && ( )} {filters.offset !== 0 && ( <> )}
)} ) }