Skip to content

Commit 3a78738

Browse files
authored
chore/unified-logs-fixes-04b (supabase#37150)
* Shift fixes from supabase#36762 * Add comment
1 parent 6918c78 commit 3a78738

File tree

12 files changed

+167
-131
lines changed

12 files changed

+167
-131
lines changed

apps/studio/components/interfaces/Settings/Logs/LogsPreviewer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { useSelectedLog } from 'hooks/analytics/useSelectedLog'
1414
import useSingleLog from 'hooks/analytics/useSingleLog'
1515
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
1616
import { useUpgradePrompt } from 'hooks/misc/useUpgradePrompt'
17+
import { useFlag } from 'hooks/ui/useFlag'
1718
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
1819
import { Button } from 'ui'
1920
import { LogsBarChart } from 'ui-patterns/LogsBarChart'
@@ -27,9 +28,8 @@ import {
2728
} from './Logs.constants'
2829
import type { Filters, LogSearchCallback, LogTemplate, QueryType } from './Logs.types'
2930
import { maybeShowUpgradePrompt } from './Logs.utils'
30-
import UpgradePrompt from './UpgradePrompt'
31-
import { useFlag } from 'hooks/ui/useFlag'
3231
import { PreviewFilterPanelWithUniversal } from './PreviewFilterPanelWithUniversal'
32+
import UpgradePrompt from './UpgradePrompt'
3333

3434
/**
3535
* Acts as a container component for the entire log display

apps/studio/components/interfaces/Settings/Logs/PreviewFilterPanelWithUniversal.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useRouter } from 'next/router'
55
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
66

77
import { useParams } from 'common'
8-
// import CSVButton from 'components/ui/CSVButton'
98
import DatabaseSelector from 'components/ui/DatabaseSelector'
109
import { useLoadBalancersQuery } from 'data/read-replicas/load-balancers-query'
1110
import { IS_PLATFORM } from 'lib/constants'
@@ -21,11 +20,6 @@ import { DatePickerValue } from './Logs.DatePickers'
2120
import { FILTER_OPTIONS, LOG_ROUTES_WITH_REPLICA_SUPPORT, LogsTableName } from './Logs.constants'
2221
import type { Filters, LogSearchCallback, LogTemplate } from './Logs.types'
2322

24-
interface CustomDateRangePickerProps {
25-
value?: { from: Date; to?: Date }
26-
onChange: (range: { from: Date; to?: Date } | undefined) => void
27-
}
28-
2923
function CustomDateRangePicker({ onChange, onCancel }: CustomOptionProps) {
3024
const [dateRange, setDateRange] = useState<any | undefined>()
3125

apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ export const UnifiedLogs = () => {
297297
>
298298
<DataTableSideBarLayout topBarHeight={topBarHeight}>
299299
<ResizablePanelGroup direction="horizontal" autoSaveId="logs-layout">
300-
<FilterSideBar />
300+
<FilterSideBar dateRangeDisabled={{ after: new Date() }} />
301301
<ResizableHandle
302302
withHandle
303303
// disabled={resizableSidebar ? false : true}

apps/studio/components/ui/DataTable/DataTable.types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ export type Slider = {
3030
options?: Option[]
3131
}
3232

33+
export type DateRangeDisabled = { before?: Date; after?: Date }
34+
3335
export type Timerange = {
3436
type: 'timerange'
3537
options?: Option[] // required for TS
3638
presets?: DatePreset[]
39+
dateRangeDisabled?: DateRangeDisabled
3740
}
3841

3942
export type Base<TData> = {

apps/studio/components/ui/DataTable/DataTableFilters/DataTableFilterCommand.tsx

Lines changed: 101 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export function DataTableFilterCommand({
6262

6363
const trimmedInputValue = inputValue.trim()
6464

65+
const queryFields = filterFields.filter(
66+
(x) => typeof x.value === 'string' && currentWord.includes(`${x.value}:`)
67+
)
68+
6569
// [Joshen] Temporarily disabling as this conflicts with our current CMD K behaviour
6670
// useHotKey(() => setOpen((open) => !open), 'k')
6771

@@ -80,18 +84,6 @@ export function DataTableFilterCommand({
8084
const field = _filterFields?.find((field) => field.value === filter.id)
8185
return !field?.commandDisabled
8286
})
83-
const currentDisabledFilters = currentFilters.filter((filter) => {
84-
const field = _filterFields?.find((field) => field.value === filter.id)
85-
return field?.commandDisabled
86-
})
87-
88-
const commandDisabledFilterKeys = currentDisabledFilters.reduce(
89-
(prev, curr) => {
90-
prev[curr.id] = curr.value
91-
return prev
92-
},
93-
{} as Record<string, unknown>
94-
)
9587

9688
for (const key of Object.keys(searchParams)) {
9789
const value = searchParams[key as keyof typeof searchParams]
@@ -198,6 +190,7 @@ export function DataTableFilterCommand({
198190
<div className="absolute top-2 z-50 w-full overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md outline-none animate-in">
199191
{/* default height is 300px but in case of more, we'd like to tease the user */}
200192
<CommandList className="max-h-[310px] bg-surface-100">
193+
<CommandEmpty>No results found.</CommandEmpty>
201194
<CommandGroup heading="Filter">
202195
{filterFields.map((field) => {
203196
if (typeof field.value !== 'string') return null
@@ -227,106 +220,113 @@ export function DataTableFilterCommand({
227220
}}
228221
className="group"
229222
>
230-
{field.value}
223+
{field.label}
231224
<CommandItemSuggestions field={field} />
232225
</CommandItem>
233226
)
234227
})}
235228
</CommandGroup>
229+
236230
<CommandSeparator />
237-
<CommandGroup heading="Query">
238-
{filterFields?.map((field) => {
239-
if (typeof field.value !== 'string') return null
240-
if (!currentWord.includes(`${field.value}:`)) return null
241231

242-
const column = table.getColumn(field.value)
243-
const facetedValue =
244-
getFacetedUniqueValues?.(table, field.value) || column?.getFacetedUniqueValues()
232+
{queryFields.length > 0 && (
233+
<>
234+
<CommandGroup heading="Query">
235+
{queryFields.map((field) => {
236+
const column = table.getColumn(field.value)
237+
const facetedValue =
238+
getFacetedUniqueValues?.(table, field.value) ||
239+
column?.getFacetedUniqueValues()
245240

246-
const options = getFieldOptions({ field })
241+
const options = getFieldOptions({ field })
247242

248-
return options.map((optionValue) => {
249-
return (
250-
<CommandItem
251-
key={`${String(field.value)}:${optionValue}`}
252-
value={`${String(field.value)}:${optionValue}`}
253-
onMouseDown={(e) => {
254-
e.preventDefault()
255-
e.stopPropagation()
256-
}}
257-
onSelect={(value) => {
258-
setInputValue((prev) =>
259-
replaceInputByFieldType({
260-
prev,
261-
currentWord,
262-
optionValue,
263-
value,
264-
field,
265-
})
266-
)
267-
setCurrentWord('')
268-
}}
269-
>
270-
{`${optionValue}`}
271-
{facetedValue?.has(optionValue) ? (
272-
<span className="ml-auto font-mono text-muted-foreground">
273-
{formatCompactNumber(facetedValue.get(optionValue) || 0)}
274-
</span>
275-
) : null}
276-
</CommandItem>
277-
)
278-
})
279-
})}
280-
</CommandGroup>
281-
<CommandSeparator />
282-
<CommandGroup heading="Suggestions">
283-
{lastSearches
284-
?.sort((a, b) => b.timestamp - a.timestamp)
285-
.slice(0, 5)
286-
.map((item) => {
287-
return (
288-
<CommandItem
289-
key={`suggestion:${item.search}`}
290-
value={`suggestion:${item.search}`}
291-
onMouseDown={(e) => {
292-
e.preventDefault()
293-
e.stopPropagation()
294-
}}
295-
onSelect={(value) => {
296-
const search = value.replace('suggestion:', '')
297-
setInputValue(`${search} `)
298-
setCurrentWord('')
299-
}}
300-
className="group"
301-
>
302-
{item.search}
303-
<span className="ml-auto truncate text-muted-foreground/80 group-aria-[selected=true]:block">
304-
{formatDistanceToNow(item.timestamp, {
305-
addSuffix: true,
306-
})}
307-
</span>
308-
<button
309-
type="button"
243+
return options.map((optionValue) => {
244+
return (
245+
<CommandItem
246+
key={`${String(field.value)}:${optionValue}`}
247+
value={`${String(field.value)}:${optionValue}`}
248+
onMouseDown={(e) => {
249+
e.preventDefault()
250+
e.stopPropagation()
251+
}}
252+
onSelect={(value) => {
253+
setInputValue((prev) =>
254+
replaceInputByFieldType({
255+
prev,
256+
currentWord,
257+
optionValue,
258+
value,
259+
field,
260+
})
261+
)
262+
setCurrentWord('')
263+
}}
264+
>
265+
{`${optionValue}`}
266+
{facetedValue?.has(optionValue) ? (
267+
<span className="ml-auto font-mono text-muted-foreground">
268+
{formatCompactNumber(facetedValue.get(optionValue) || 0)}
269+
</span>
270+
) : null}
271+
</CommandItem>
272+
)
273+
})
274+
})}
275+
</CommandGroup>
276+
<CommandSeparator />
277+
</>
278+
)}
279+
280+
{lastSearches.length > 0 && (
281+
<CommandGroup heading="Suggestions">
282+
{lastSearches
283+
.sort((a, b) => b.timestamp - a.timestamp)
284+
.slice(0, 5)
285+
.map((item) => {
286+
return (
287+
<CommandItem
288+
key={`suggestion:${item.search}`}
289+
value={`suggestion:${item.search}`}
310290
onMouseDown={(e) => {
311291
e.preventDefault()
312292
e.stopPropagation()
313293
}}
314-
onClick={(e) => {
315-
e.preventDefault()
316-
e.stopPropagation()
317-
// TODO: extract into function
318-
setLastSearches(lastSearches.filter((i) => i.search !== item.search))
294+
onSelect={(value) => {
295+
const search = value.replace('suggestion:', '')
296+
setInputValue(`${search} `)
297+
setCurrentWord('')
319298
}}
320-
className="ml-1 hidden rounded-md p-0.5 hover:bg-background group-aria-[selected=true]:block"
299+
className="group"
321300
>
322-
<X className="h-4 w-4" />
323-
</button>
324-
</CommandItem>
325-
)
326-
})}
327-
</CommandGroup>
328-
<CommandEmpty>No results found.</CommandEmpty>
301+
{item.search}
302+
<span className="ml-auto truncate text-muted-foreground/80 group-aria-[selected=true]:block">
303+
{formatDistanceToNow(item.timestamp, {
304+
addSuffix: true,
305+
})}
306+
</span>
307+
<button
308+
type="button"
309+
onMouseDown={(e) => {
310+
e.preventDefault()
311+
e.stopPropagation()
312+
}}
313+
onClick={(e) => {
314+
e.preventDefault()
315+
e.stopPropagation()
316+
// TODO: extract into function
317+
setLastSearches(lastSearches.filter((i) => i.search !== item.search))
318+
}}
319+
className="ml-1 hidden rounded-md p-0.5 hover:bg-background group-aria-[selected=true]:block"
320+
>
321+
<X className="h-4 w-4" />
322+
</button>
323+
</CommandItem>
324+
)
325+
})}
326+
</CommandGroup>
327+
)}
329328
</CommandList>
329+
330330
<div className="bg-surface-100 flex flex-wrap justify-between gap-3 border-t bg-accent/50 px-2 py-1.5 text-sm text-accent-foreground">
331331
<div className="flex flex-wrap gap-3">
332332
<span>
@@ -370,10 +370,12 @@ export function DataTableFilterCommand({
370370
function CommandItemSuggestions<TData>({ field }: { field: DataTableFilterField<TData> }) {
371371
const { table, getFacetedMinMaxValues, getFacetedUniqueValues } = useDataTable()
372372
const value = field.value as string
373+
const className = 'ml-2 hidden truncate text-foreground-lighter group-aria-[selected=true]:block'
374+
373375
switch (field.type) {
374376
case 'checkbox': {
375377
return (
376-
<span className="ml-1 hidden truncate text-muted-foreground/80 group-aria-[selected=true]:block">
378+
<span className={cn(className)}>
377379
{getFacetedUniqueValues
378380
? Array.from(getFacetedUniqueValues(table, value)?.keys() || [])
379381
.map((value) => `[${value}]`)
@@ -385,17 +387,13 @@ function CommandItemSuggestions<TData>({ field }: { field: DataTableFilterField<
385387
case 'slider': {
386388
const [min, max] = getFacetedMinMaxValues?.(table, value) || [field.min, field.max]
387389
return (
388-
<span className="ml-1 hidden truncate text-muted-foreground/80 group-aria-[selected=true]:block">
390+
<span className={cn(className)}>
389391
[{min} - {max}]
390392
</span>
391393
)
392394
}
393395
case 'input': {
394-
return (
395-
<span className="ml-1 hidden truncate text-muted-foreground/80 group-aria-[selected=true]:block">
396-
[{`${String(field.value)}`} input]
397-
</span>
398-
)
396+
return <span className={cn(className)}>[{`${String(field.value)}`} input]</span>
399397
}
400398
default: {
401399
return null

apps/studio/components/ui/DataTable/DataTableFilters/DataTableFilterControls.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@ import { DataTableFilterResetButton } from './DataTableFilterResetButton'
1111
import { DataTableFilterSlider } from './DataTableFilterSlider'
1212
import { DataTableFilterTimerange } from './DataTableFilterTimerange'
1313

14+
import { DateRangeDisabled } from '../DataTable.types'
1415
import { useDataTable } from '../providers/DataTableProvider'
1516

1617
// FIXME: use @container (especially for the slider element) to restructure elements
1718

1819
// TODO: only pass the columns to generate the filters!
1920
// https://tanstack.com/table/v8/docs/framework/react/examples/filters
2021

21-
export function DataTableFilterControls() {
22+
interface DataTableFilterControls {
23+
dateRangeDisabled?: DateRangeDisabled
24+
}
25+
26+
export function DataTableFilterControls({ dateRangeDisabled }: DataTableFilterControls) {
2227
const { filterFields } = useDataTable()
2328
return (
2429
<Accordion
@@ -55,7 +60,12 @@ export function DataTableFilterControls() {
5560
return <DataTableFilterInput {...field} />
5661
}
5762
case 'timerange': {
58-
return <DataTableFilterTimerange {...field} />
63+
return (
64+
<DataTableFilterTimerange
65+
dateRangeDisabled={dateRangeDisabled}
66+
{...field}
67+
/>
68+
)
5969
}
6070
}
6171
})()}

apps/studio/components/ui/DataTable/DataTableFilters/DataTableFilterTimerange.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useDataTable } from '../providers/DataTableProvider'
99
export function DataTableFilterTimerange<TData>({
1010
value: _value,
1111
presets,
12+
dateRangeDisabled,
1213
}: DataTableTimerangeFilterField<TData>) {
1314
const value = _value as string
1415
const { table, columnFilters } = useDataTable()
@@ -35,5 +36,7 @@ export function DataTableFilterTimerange<TData>({
3536
}
3637
}
3738

38-
return <DatePickerWithRange {...{ date, setDate, presets }} />
39+
return (
40+
<DatePickerWithRange dateRangeDisabled={dateRangeDisabled} {...{ date, setDate, presets }} />
41+
)
3942
}

apps/studio/components/ui/DataTable/DataTableFilters/DataTableFilters.utils.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,10 @@ export function columnFiltersParser<TData>({
218218
const regex = /(\w+):([^]*?)(?=\s+\w+:|$)/g
219219
let match
220220

221-
console.log('DataTableFilterCommand parsing input:', inputValue)
222-
223221
while ((match = regex.exec(inputValue)) !== null) {
224222
const [_, fieldName, fieldValue] = match
225223
if (fieldName && fieldValue) {
226224
filterPairs[fieldName] = fieldValue.trim()
227-
console.log(`Parsed filter pair: ${fieldName} = ${fieldValue.trim()}`)
228225
}
229226
}
230227

0 commit comments

Comments
 (0)