mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 23:59:08 +03:00
add panel to show selected log in logs explorer, and some ui fixes (#26925)
* add panel to show selected log in logs explorer, and some ui fixes * fix type error --------- Co-authored-by: Terry Sutton <saltcod@gmail.com>
This commit is contained in:
1 parent
b4b67d22f3
commit
7f95e2fff0
7 files changed
+89
-86
No files matched your search
@@ -128,7 +128,7 @@ export const WarehouseCollectionDetail = () => {
|
||||
data={results}
|
||||
params={params}
|
||||
maxHeight="calc(100vh - 139px)"
|
||||
hideHeader={true}
|
||||
showHeader={false}
|
||||
emptyState={
|
||||
<ProductEmptyState
|
||||
title="Send your first event"
|
||||
|
||||
@@ -224,8 +224,12 @@ const LogSelection = ({
|
||||
<TabsContent_Shadcn_ className="bg-surface-100 space-y-6" value="details">
|
||||
<Formatter />
|
||||
</TabsContent_Shadcn_>
|
||||
<TabsContent_Shadcn_ value="raw" className="px-4">
|
||||
<CodeBlock language="json" className="prose w-full max-w-full">
|
||||
<TabsContent_Shadcn_ value="raw">
|
||||
<CodeBlock
|
||||
hideLineNumbers
|
||||
language="json"
|
||||
className="prose w-full pt-0 max-w-full border-none"
|
||||
>
|
||||
{JSON.stringify(fullLog || partialLog, null, 2)}
|
||||
</CodeBlock>
|
||||
</TabsContent_Shadcn_>
|
||||
|
||||
+2
-5
@@ -12,7 +12,7 @@ const DefaultExplorerSelectionRenderer = ({ log }: any) => {
|
||||
code?: boolean
|
||||
}) => {
|
||||
return (
|
||||
<div className="grid grid-cols-12">
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<span className="text-foreground-lighter text-sm col-span-3">{label}</span>
|
||||
<span
|
||||
className={`text-foreground text-sm col-span-9 overflow-x-auto ${
|
||||
@@ -33,10 +33,7 @@ const DefaultExplorerSelectionRenderer = ({ log }: any) => {
|
||||
<div className="overflow-hidden overflow-x-auto space-y-6">
|
||||
{Object.entries(log).map(([key, value], index) => {
|
||||
return (
|
||||
<div
|
||||
key={`${key}-${index}`}
|
||||
className={`${LOGS_TAILWIND_CLASSES.log_selection_x_padding}`}
|
||||
>
|
||||
<div key={`${key}-${index}`} className="px-4 pb-4">
|
||||
{value && typeof value === 'object' ? (
|
||||
<DetailedJsonRow label={key} value={value} />
|
||||
) : (
|
||||
|
||||
@@ -17,6 +17,9 @@ import {
|
||||
IconDownload,
|
||||
IconEye,
|
||||
IconEyeOff,
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
cn,
|
||||
} from 'ui'
|
||||
|
||||
@@ -36,7 +39,6 @@ import LogSelection, { LogSelectionProps } from './LogSelection'
|
||||
import type { LogData, QueryType } from './Logs.types'
|
||||
import DefaultErrorRenderer from './LogsErrorRenderers/DefaultErrorRenderer'
|
||||
import ResourcesExceededErrorRenderer from './LogsErrorRenderers/ResourcesExceededErrorRenderer'
|
||||
import { motion } from 'framer-motion'
|
||||
|
||||
interface Props {
|
||||
data?: Array<LogData | Object>
|
||||
@@ -54,9 +56,10 @@ interface Props {
|
||||
hasEditorValue?: boolean
|
||||
maxHeight?: string
|
||||
className?: string
|
||||
hideHeader?: boolean
|
||||
collectionName?: string // Used for warehouse queries
|
||||
emptyState?: ReactNode
|
||||
showHeader?: boolean
|
||||
showHistogramToggle?: boolean
|
||||
}
|
||||
type LogMap = { [id: string]: LogData }
|
||||
|
||||
@@ -79,9 +82,10 @@ const LogTable = ({
|
||||
hasEditorValue,
|
||||
maxHeight,
|
||||
className,
|
||||
hideHeader = false,
|
||||
collectionName,
|
||||
emptyState,
|
||||
showHeader = true,
|
||||
showHistogramToggle = true,
|
||||
}: Props) => {
|
||||
const [focusedLog, setFocusedLog] = useState<LogData | null>(null)
|
||||
const firstRow: LogData | undefined = data?.[0] as LogData
|
||||
@@ -193,10 +197,6 @@ const LogTable = ({
|
||||
}
|
||||
}, [data, focusedLog, stringData])
|
||||
|
||||
// [Joshen] Hmm quite hacky now, but will do
|
||||
const _maxHeight =
|
||||
maxHeight || (!queryType ? 'calc(100vh - 42px - 10rem)' : 'calc(100vh - 42px - 3rem)')
|
||||
|
||||
const logDataRows = useMemo(() => {
|
||||
if (hasId && hasTimestamp) {
|
||||
return Object.values(logMap).sort((a, b) => b.timestamp - a.timestamp)
|
||||
@@ -228,7 +228,7 @@ const LogTable = ({
|
||||
className={cn(
|
||||
'flex w-full items-center justify-between border-t bg-surface-100 px-5 py-2',
|
||||
className,
|
||||
{ hidden: hideHeader }
|
||||
{ hidden: !showHeader }
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -258,15 +258,17 @@ const LogTable = ({
|
||||
</CSVButton>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
type="default"
|
||||
icon={isHistogramShowing ? <IconEye /> : <IconEyeOff />}
|
||||
onClick={onHistogramToggle}
|
||||
>
|
||||
Histogram
|
||||
</Button>
|
||||
</div>
|
||||
{showHistogramToggle && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
type="default"
|
||||
icon={isHistogramShowing ? <IconEye /> : <IconEyeOff />}
|
||||
onClick={onHistogramToggle}
|
||||
>
|
||||
Histogram
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-x-2">
|
||||
{IS_PLATFORM && (
|
||||
@@ -358,66 +360,65 @@ const LogTable = ({
|
||||
if (!data) return null
|
||||
|
||||
return (
|
||||
<section className={'flex flex-grow w-full max-h-screen flex-col h-full'} style={{ maxHeight }}>
|
||||
<section className={'flex w-full flex-col h-full'} style={{ maxHeight }}>
|
||||
{!queryType && <LogsExplorerTableHeader />}
|
||||
<div className={`flex h-full flex-row ${!queryType ? 'border-x' : ''}`}>
|
||||
<DataGrid
|
||||
role="table"
|
||||
style={{ height: '100%' }}
|
||||
className={`
|
||||
flex-1 flex-grow h-full
|
||||
${!queryType ? 'data-grid--logs-explorer' : ' data-grid--simple-logs'}
|
||||
`}
|
||||
rowHeight={40}
|
||||
headerRowHeight={queryType ? 0 : 28}
|
||||
onSelectedCellChange={({ rowIdx }) => {
|
||||
if (!hasId) return
|
||||
setFocusedLog(data[rowIdx] as LogData)
|
||||
}}
|
||||
selectedRows={new Set([])}
|
||||
columns={columns}
|
||||
rowClass={(row: LogData) =>
|
||||
[
|
||||
'font-mono tracking-tight',
|
||||
isEqual(row, focusedLog)
|
||||
? '!bg-border-stronger rdg-row--focused'
|
||||
: ' !bg-studio hover:!bg-surface-100 cursor-pointer',
|
||||
].join(' ')
|
||||
}
|
||||
rows={logDataRows}
|
||||
rowKeyGetter={(r) => {
|
||||
if (!hasId) return JSON.stringify(r)
|
||||
const row = r as LogData
|
||||
return row.id
|
||||
}}
|
||||
// [Next 18 refactor] need to fix
|
||||
// onRowClick={setFocusedLog}
|
||||
renderers={{
|
||||
renderRow: RowRenderer,
|
||||
noRowsFallback: !isLoading ? (
|
||||
<div className="mx-auto flex h-full w-full items-center justify-center space-y-12 py-4 transition-all delay-200 duration-500">
|
||||
{!error && renderNoResultAlert()}
|
||||
{error && renderErrorAlert()}
|
||||
</div>
|
||||
) : null,
|
||||
}}
|
||||
/>
|
||||
{logDataRows.length > 0 ? (
|
||||
<div
|
||||
className={
|
||||
queryType ? 'flex w-1/2 flex-col' : focusedLog ? 'flex w-1/2 flex-col' : 'hidden w-0'
|
||||
}
|
||||
>
|
||||
<LogSelection
|
||||
projectRef={projectRef}
|
||||
onClose={() => setFocusedLog(null)}
|
||||
log={focusedLog}
|
||||
queryType={queryType}
|
||||
params={params}
|
||||
collectionName={collectionName}
|
||||
<div className={`flex h-full flex-row overflow-x-auto`}>
|
||||
<ResizablePanelGroup direction="horizontal">
|
||||
<ResizablePanel defaultSize={focusedLog ? 60 : 100}>
|
||||
<DataGrid
|
||||
role="table"
|
||||
style={{ height: '100%' }}
|
||||
className={cn('flex-1 flex-grow h-full', {
|
||||
'data-grid--simple-logs': queryType,
|
||||
'data-grid--logs-explorer': !queryType,
|
||||
})}
|
||||
rowHeight={40}
|
||||
headerRowHeight={queryType ? 0 : 28}
|
||||
onSelectedCellChange={(row) => {
|
||||
console.log('row', row)
|
||||
setFocusedLog(row.row as LogData)
|
||||
}}
|
||||
selectedRows={new Set([])}
|
||||
columns={columns}
|
||||
rowClass={(row: LogData) =>
|
||||
[
|
||||
'font-mono tracking-tight',
|
||||
isEqual(row, focusedLog)
|
||||
? '!bg-surface-300 rdg-row--focused'
|
||||
: ' !bg-studio hover:!bg-surface-100 cursor-pointer',
|
||||
].join(' ')
|
||||
}
|
||||
rows={logDataRows}
|
||||
rowKeyGetter={(r) => {
|
||||
if (!hasId) return JSON.stringify(r)
|
||||
const row = r as LogData
|
||||
return row.id
|
||||
}}
|
||||
renderers={{
|
||||
renderRow: RowRenderer,
|
||||
noRowsFallback: !isLoading ? (
|
||||
<div className="mx-auto flex h-full w-full items-center justify-center space-y-12 py-4 transition-all delay-200 duration-500">
|
||||
{!error && renderNoResultAlert()}
|
||||
{error && renderErrorAlert()}
|
||||
</div>
|
||||
) : null,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</ResizablePanel>
|
||||
<ResizableHandle />
|
||||
{focusedLog && (
|
||||
<ResizablePanel defaultSize={40}>
|
||||
<LogSelection
|
||||
projectRef={projectRef}
|
||||
onClose={() => setFocusedLog(null)}
|
||||
log={focusedLog}
|
||||
queryType={queryType}
|
||||
params={params}
|
||||
collectionName={collectionName}
|
||||
/>
|
||||
</ResizablePanel>
|
||||
)}
|
||||
</ResizablePanelGroup>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -30,7 +30,7 @@ export const SelectionDetailedRow = ({
|
||||
valueRender?: React.ReactNode
|
||||
}) => {
|
||||
return (
|
||||
<div className="grid grid-cols-12 group items-center">
|
||||
<div className="group flex items-center gap-2 flex-wrap relative">
|
||||
<span className="text-foreground-lighter text-sm col-span-3 whitespace-pre-wrap">
|
||||
{label}
|
||||
</span>
|
||||
@@ -43,7 +43,7 @@ export const SelectionDetailedRow = ({
|
||||
<CopyButton
|
||||
iconOnly
|
||||
text={value}
|
||||
className="group-hover:opacity-100 opacity-0 p-0 h-6 w-6 col-span-1"
|
||||
className="group-hover:opacity-100 opacity-0 p-0 h-6 w-6 col-span-1 absolute top-1 right-1"
|
||||
type="text"
|
||||
title="Copy to clipboard"
|
||||
/>
|
||||
|
||||
@@ -222,6 +222,7 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
|
||||
<ResizablePanel collapsible minSize={5} className="flex flex-col flex-grow">
|
||||
<LoadingOpacity active={isLoading}>
|
||||
<LogTable
|
||||
showHistogramToggle={false}
|
||||
onRun={handleRun}
|
||||
onSave={handleOnSave}
|
||||
hasEditorValue={Boolean(editorValue)}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
.rdg-row {
|
||||
&.rdg-row--focused {
|
||||
@apply border-r border-brand bg-background-surface-300;
|
||||
@apply border-r border-brand;
|
||||
border-right-width: 4px;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user