import dayjs from 'dayjs' import { BookOpen, Check, ChevronDown, Copy, ExternalLink, X } from 'lucide-react' import Link from 'next/link' import { ReactNode, useState } from 'react' import { IS_PLATFORM } from 'common' import Table from 'components/to-be-cleaned/Table' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { DOCS_URL } from 'lib/constants' import { logConstants } from 'shared-data' import { Badge, Button, copyToClipboard, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, SidePanel, Tabs, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { EXPLORER_DATEPICKER_HELPERS, LOGS_SOURCE_DESCRIPTION, LogsTableName, } from './Logs.constants' import { DatePickerValue, LogsDatePicker } from './Logs.DatePickers' import { LogsWarning, LogTemplate } from './Logs.types' export interface LogsQueryPanelProps { templates?: LogTemplate[] defaultFrom: string defaultTo: string warnings: LogsWarning[] onSelectTemplate: (template: LogTemplate) => void onSelectSource: (source: string) => void onDateChange: (value: DatePickerValue) => void } function DropdownMenuItemContent({ name, desc }: { name: ReactNode; desc?: string }) { return (
{name}
{desc &&
{desc}
}
) } const LogsQueryPanel = ({ templates = [], defaultFrom, defaultTo, warnings, onSelectTemplate, onSelectSource, onDateChange, }: LogsQueryPanelProps) => { const [showReference, setShowReference] = useState(false) const { logsTemplates } = useIsFeatureEnabled(['logs:templates']) const { projectAuthAll: authEnabled, projectStorageAll: storageEnabled, projectEdgeFunctionAll: edgeFunctionsEnabled, } = useIsFeatureEnabled(['project_auth:all', 'project_storage:all', 'project_edge_function:all']) const logsTableNames = Object.entries(LogsTableName) .filter(([key]) => { if (key === 'AUTH') return authEnabled if (key === 'STORAGE') return storageEnabled if (key === 'FN_EDGE') return edgeFunctionsEnabled if (key === 'PG_CRON') return false return true }) .map(([, value]) => value) function getDefaultDatePickerValue() { if (defaultFrom && defaultTo) { return { to: defaultTo, from: defaultFrom, text: `${dayjs(defaultFrom).format('DD MMM, HH:mm')} - ${dayjs(defaultTo).format('DD MMM, HH:mm')}`, isHelper: false, } } return { to: EXPLORER_DATEPICKER_HELPERS[0].calcTo(), from: EXPLORER_DATEPICKER_HELPERS[0].calcFrom(), text: EXPLORER_DATEPICKER_HELPERS[0].text, isHelper: true, } } const [selectedDatePickerValue, setSelectedDatePickerValue] = useState( getDefaultDatePickerValue() ) return (
{logsTableNames .sort((a, b) => a.localeCompare(b)) .map((source) => ( onSelectSource(source)}> ))} {IS_PLATFORM && logsTemplates && ( {templates .sort((a, b) => a.label!.localeCompare(b.label!)) .map((template) => ( onSelectTemplate(template)} >

{template.label}

))}
)} { setSelectedDatePickerValue(value) onDateChange(value) }} helpers={EXPLORER_DATEPICKER_HELPERS} />
0 ? 'opacity-100' : 'invisible h-0 w-0 opacity-0' }`} > {warnings.length} {warnings.length > 1 ? 'warnings' : 'warning'} {warnings.map((warning, index) => (

{warning.text}{' '} {warning.link && ( {warning.linkText || 'View'} )}

))}

Field Reference

} visible={showReference} cancelText="Close" onCancel={() => setShowReference(false)} hideFooter triggerElement={ } >

The following table shows all the available paths that can be queried from each respective source. Do note that to access nested keys, you would need to perform the necessary{' '} unnesting joins

{logConstants.schemas.map((schema) => ( Path , Type , ]} body={schema.fields .sort((a: any, b: any) => a.path - b.path) .map((field) => ( ))} /> ))} ) } const Field = ({ field, }: { field: { path: string type: string } }) => { const [isCopied, setIsCopied] = useState(false) return ( copyToClipboard(field.path, () => { setIsCopied(true) setTimeout(() => setIsCopied(false), 3000) }) } > {field.path} {isCopied ? ( Copied ) : ( Copy value )} {field.type} ) } export default LogsQueryPanel