chore: explorer error message updated. time range buttons updated

This commit is contained in:
Jonathan Summers-Muir authored and TzeYiing committed 2022-03-30 14:43:33 +02:00
1 parent 0c2b5ea011
commit 2eeb1c8fce
6 files changed
+192 -84

No files matched your search

@@ -16,9 +16,10 @@ interface Props {
log: LogData | null
onClose: () => void
queryType?: QueryType
isLoading?: boolean
}
const LogSelection: FC<Props> = ({ log, onClose, queryType }) => {
const LogSelection: FC<Props> = ({ log, onClose, queryType, isLoading }) => {
const Formatter = () => {
switch (queryType) {
case 'api':
@@ -59,13 +60,13 @@ const LogSelection: FC<Props> = ({ log, onClose, queryType }) => {
className={[
'relative h-full flex flex-col flex-grow border border-l',
'border-panel-border-light dark:border-panel-border-dark',
'bg-gray-200',
'bg-gray-200 overflow-y-scroll',
].join(' ')}
>
<div
className={
`transition-all
bg-scale-200 absolute w-full h-full text-center flex-col gap-2 flex items-center justify-center ` +
`overflow-y-scroll transition-all
bg-scale-200 absolute w-full h-full text-center flex-col gap-2 flex items-center justify-center opacity-0 ` +
(log ? 'opacity-0 z-0' : 'opacity-100 z-10')
}
>
@@ -73,7 +74,7 @@ const LogSelection: FC<Props> = ({ log, onClose, queryType }) => {
className={
`transition-all
duration-500
delay-200
delay-300
w-full
flex
flex-col
@@ -81,7 +82,8 @@ const LogSelection: FC<Props> = ({ log, onClose, queryType }) => {
items-center
gap-6
max-w-sm
text-center ` + (log ? 'mt-0 opacity-0 scale-95' : 'mt-8 opacity-100 scale-100')
text-center scale-95 opacity-0 ` +
(log || isLoading ? 'mt-0 opacity-0 scale-95' : 'mt-8 opacity-100 scale-100')
}
>
<div className="relative border border-scale-600 dark:border-scale-400 w-32 h-4 rounded px-2 flex items-center">
@@ -112,23 +114,21 @@ const LogSelection: FC<Props> = ({ log, onClose, queryType }) => {
</div>
</div>
</div>
<div className="flex w-full grow">
<div
className="
relative
flex-grow
h-px
bg-scale-300
"
>
<div
className="
flex-grow overflow-y-auto
bg-scale-300
space-y-6
py-4
"
className="transition absolute cursor-pointer top-6 right-6 text-scale-900 hover:text-scale-1200"
onClick={onClose}
>
<div
className="transition absolute cursor-pointer top-5 right-5 text-scale-900 hover:text-scale-1200"
onClick={onClose}
>
<IconX size={14} strokeWidth={2} />
</div>
<div className="flex flex-col space-y-6">{log && <Formatter />}</div>
<IconX size={14} strokeWidth={2} />
</div>
<div className="bg-scale-300 py-8 flex flex-col space-y-6">{log && <Formatter />}</div>
</div>
</div>
)
@@ -1,6 +1,15 @@
import dayjs from 'dayjs'
import { useEffect, useState, useMemo } from 'react'
import { Button, IconDownloadCloud, IconEye, IconEyeOff, Typography } from '@supabase/ui'
import {
Alert,
Button,
IconDownloadCloud,
IconEye,
IconEyeOff,
IconLoader,
Input,
Typography,
} from '@supabase/ui'
import DataGrid from '@supabase/react-data-grid'
import LogSelection from './LogSelection'
@@ -16,6 +25,8 @@ interface Props {
queryType?: QueryType
onHistogramToggle?: () => void
isHistogramShowing?: boolean
isLoading?: boolean
error?: any
}
type LogMap = { [id: string]: LogData }
@@ -24,7 +35,14 @@ type LogMap = { [id: string]: LogData }
*
* When in custom data display mode, the side panel will not open when focusing on logs.
*/
const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing }: Props) => {
const LogTable = ({
data = [],
queryType,
onHistogramToggle,
isHistogramShowing,
isLoading,
error,
}: Props) => {
const [focusedLog, setFocusedLog] = useState<LogData | null>(null)
const columnNames = Object.keys(data[0] || {})
const hasId = columnNames.includes('id')
@@ -183,7 +201,7 @@ const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing
return (
<>
<section
className={'flex flex-1 flex-col ' + (!queryType ? 'shadow-lg' : '')}
className={'flex flex-1 flex-col ' + (!queryType ? 'shadow-lg' : '')}
style={{ maxHeight }}
>
{!queryType && (
@@ -197,6 +215,7 @@ const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing
border-l
border-r
flex items-center justify-between
px-5 py-2
"
@@ -228,7 +247,9 @@ const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing
</div>
</div>
)}
<div className={'flex flex-row h-full ' + (!queryType ? 'border-l border-r' : '')}>
<div
className={'flex flex-row flex-grow h-full ' + (!queryType ? 'border-l border-r' : '')}
>
<DataGrid
style={{ height: '100%' }}
className={`
@@ -242,11 +263,77 @@ const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing
setFocusedLog(data[rowIdx] as LogData)
}}
noRowsFallback={
<div className="p-4">
<Typography.Text type="secondary" small className="font-mono">
No data returned from query
</Typography.Text>
</div>
!isLoading ? (
<>
<div className="py-4 w-full h-full flex-col space-y-12">
<div
className={`transition-all
duration-500
delay-200
flex
flex-col
items-center
gap-6
text-center
mt-16
opacity-100
scale-100
justify-center
`}
>
<div className="flex flex-col gap-1">
<div className="relative border border-scale-600 border-dashed dark:border-scale-400 w-32 h-4 rounded px-2 flex items-center"></div>
<div className="relative border border-scale-600 border-dashed dark:border-scale-400 w-32 h-4 rounded px-2 flex items-center">
<div className="absolute right-1 -bottom-4">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
</div>
</div>
<div className="flex flex-col gap-1 px-5">
<h3 className="text-lg text-scale-1200">No results</h3>
<p className="text-sm text-scale-900">
Try another search, or adjusting the filters
</p>
</div>
</div>
{error && (
<div className="flex justify-center px-5">
<Alert
variant="danger"
title="Sorry! An error occured when fetching data."
withIcon
className="max-w-xl"
>
<Input.TextArea
size="small"
value={JSON.stringify(error, null, 2)}
borderless
className="font-mono w-full mt-4"
copy
rows={12}
/>
</Alert>
</div>
)}
</div>
</>
) : null
}
columns={columns as any}
rowClass={(r) => {
@@ -269,19 +356,24 @@ const LogTable = ({ data = [], queryType, onHistogramToggle, isHistogramShowing
}}
onRowClick={(r) => setFocusedLog(r)}
/>
{/* {focusedLog && ( */}
<div
className={
queryType ? 'w-1/2 flex flex-col' : focusedLog ? 'w-1/2 flex flex-col' : 'w-0 hidden'
}
>
<LogSelection
onClose={() => setFocusedLog(null)}
log={focusedLog}
queryType={queryType}
/>
</div>
{/* )} */}
{logDataRows.length > 0 ? (
<div
className={
queryType
? 'w-1/2 flex flex-col'
: focusedLog
? 'w-1/2 flex flex-col'
: 'w-0 hidden'
}
>
<LogSelection
isLoading={isLoading}
onClose={() => setFocusedLog(null)}
log={focusedLog}
queryType={queryType}
/>
</div>
) : null}
</div>
</section>
</>
@@ -166,7 +166,9 @@ export const LogsPreviewer: React.FC<Props> = ({ projectRef, queryType, override
<div
className={
'transition-all duration-500 ' +
(showChart && !isLoading ? 'opacity-100 h-48 pt-4 mb-4' : 'opacity-0 h-0')
(showChart && !isLoading && logData.length > 0
? 'opacity-100 h-48 pt-4 mb-4'
: 'opacity-0 h-0')
}
>
<div className={condensedLayout ? 'px-4' : ''}>
@@ -182,6 +184,7 @@ export const LogsPreviewer: React.FC<Props> = ({ projectRef, queryType, override
<ShimmerLine active={isLoading} />
<LoadingOpacity active={isLoading}>
<LogTable
isLoading={isLoading}
data={logData}
queryType={queryType}
isHistogramShowing={showChart}
@@ -102,6 +102,7 @@ const PreviewFilterPanel: FC<Props> = ({
</div>
}
loading={isLoading}
disabled={isLoading}
onClick={onRefresh}
>
Refresh
@@ -119,25 +119,32 @@ const PageLayout = () => {
return (
<FunctionLayout>
<div className="space-y-6">
<div className="space-y-6 py-2">
<div className="flex flex-row items-center gap-2">
<Dropdown
side="bottom"
align="start"
overlay={
<Dropdown.RadioGroup value={interval} onChange={setInterval}>
{CHART_INTERVALS.map((i) => (
<Dropdown.Radio key={i.key} value={i.key}>
{i.label}
</Dropdown.Radio>
))}
</Dropdown.RadioGroup>
}
>
<Button as="span" type="default" iconRight={<IconChevronDown />}>
{selectedInterval.label}
</Button>
</Dropdown>
<div className="flex items-center">
{CHART_INTERVALS.map((item, i) => {
const classes = []
if (i === 0) {
classes.push('rounded-tr-none rounded-br-none')
} else if (i === CHART_INTERVALS.length - 1) {
classes.push('rounded-tl-none rounded-bl-none')
} else {
classes.push('rounded-none')
}
return (
<Button
key={`function-filter-${i}`}
type={interval === item.key ? 'secondary' : 'default'}
onClick={() => setInterval(item.key)}
className={classes.join(' ')}
>
{item.label}
</Button>
)
})}
</div>
<span className="text-scale-1000 text-xs">
Statistics for past {selectedInterval.label}
@@ -170,7 +177,7 @@ const PageLayout = () => {
/>
</Panel.Content>
</Panel>
<Panel key="auth-chart">
<Panel key="invocation-chart">
<Panel.Content className="space-y-4">
<ChartHandler
label="Invocations"
@@ -191,6 +198,31 @@ const PageLayout = () => {
</Panel.Content>
</Panel>
</div>
<Panel key="error-chart">
<Panel.Content className="space-y-4">
<ChartHandler
defaultChartStyle="line"
label="Error count"
startDate={startDate}
endDate={endDate}
attribute={'min_execution_time'}
provider="log-stats"
// interval="1d"
hideChartType
customDateFormat={datetimeFormat}
data={charts}
isLoading={!charts.data && !error ? true : false}
highlightedValue={calculateHighlightedValue(
data?.result,
'min_execution_time',
{
sum: true,
}
)}
onBarClick={(v) => handleBarClick(v, '/auth')}
/>
</Panel.Content>
</Panel>
</>
)}
</div>
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { NextPage } from 'next'
import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { Typography, IconAlertCircle, Card, Input } from '@supabase/ui'
import { Typography, IconAlertCircle, Card, Input, Alert } from '@supabase/ui'
import { withAuth } from 'hooks'
import CodeEditor from 'components/ui/CodeEditor'
import {
@@ -88,32 +88,12 @@ export const LogsExplorerPage: NextPage = () => {
/>
</div>
</div>
<div className="flex flex-col flex-grow relative pb-8">
<LoadingOpacity active={isLoading}>
<div className="flex flex-grow h-full">
<LogTable data={logData} />
<LogTable data={logData} error={error} />
</div>
</LoadingOpacity>
{error && (
<div className="flex w-full h-full justify-center items-center mx-auto">
<Card className="flex flex-col gap-y-2 w-2/5 bg-scale-400">
<div className="flex flex-row gap-x-2 py-2">
<IconAlertCircle size={16} />
<Typography.Text type="secondary">
Sorry! An error occured when fetching data.
</Typography.Text>
</div>
<Input.TextArea
label="Error Messages"
value={JSON.stringify(error, null, 2)}
borderless
className=" border-t-2 border-scale-800 pt-2 font-mono"
/>
</Card>
</div>
)}
</div>
</div>
</LogsExplorerLayout>