chore: more work on the date picker in logs

• issues with date inputs in the date picker, commented out for now
• also need to add restrictions in place so restricted dates cannot be selected
This commit is contained in:
Jonathan Summers-Muir authored and Copple committed 2022-03-30 17:07:39 +02:00
1 parent f0ea00cf66
commit c2d14cf965
6 files changed
+333 -172

No files matched your search

@@ -46,28 +46,28 @@ const LogTable = ({ isCustomQuery, data = [], queryType }: Props) => {
(v) => ({
key: v,
name: v,
width: hasLogDataFormat && v === 'timestamp' ? 210 : undefined,
// width: hasLogDataFormat && v === 'timestamp' ? 210 : undefined,
resizable: true,
headerRenderer: () => {
return <div className="flex items-center text-xs font-mono h-full">{v}</div>
},
formatter: ({ row }: any) => {
let value = row[v]
if (hasLogDataFormat && v === 'timestamp') {
value = dayjs(Number(row['timestamp']) / 1000).toISOString()
}
return (
<p
className={[
'block whitespace-wrap font-mono',
`${hasLogDataFormat && row.id === focusedLog?.id ? 'font-bold' : ''}`,
`${hasLogDataFormat && v === 'timestamp' ? 'text-green-900' : ''}`,
].join(' ')}
>
{value}
</p>
)
},
// headerRenderer: () => {
// return <div className="flex items-center text-xs font-mono h-full">{v}</div>
// },
// formatter: ({ row }: any) => {
// let value = row[v]
// if (hasLogDataFormat && v === 'timestamp') {
// value = dayjs(Number(row['timestamp']) / 1000).toISOString()
// }
// return (
// <p
// className={[
// 'block whitespace-wrap font-mono',
// `${hasLogDataFormat && row.id === focusedLog?.id ? 'font-bold' : ''}`,
// `${hasLogDataFormat && v === 'timestamp' ? 'text-green-900' : ''}`,
// ].join(' ')}
// >
// {value}
// </p>
// )
// },
})
)
@@ -65,7 +65,9 @@ const PreviewFilterPanel: FC<Props> = ({
table,
}) => {
const [search, setSearch] = useState('')
const [to, setTo] = useState({ value: '', error: '' })
const [from, setFrom] = useState({ value: '', error: '' })
const [defaultTimestamp, setDefaultTimestamp] = useState(dayjs().utc().toISOString())
const [localSearchValue, setlocalSearchValue] = useState(search)
@@ -85,14 +87,6 @@ const PreviewFilterPanel: FC<Props> = ({
}
}, [defaultToValue])
const handleFromChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
if (value !== '' && isNaN(Date.parse(value))) {
setTo({ value, error: 'Invalid ISO 8601 timestamp' })
} else {
setTo({ value, error: '' })
}
}
const handleFromReset = async () => {
setTo({ value: '', error: '' })
const value = dayjs().utc().toISOString()
@@ -102,12 +96,12 @@ const PreviewFilterPanel: FC<Props> = ({
// const handleSearch = () => onSearch({ query: search, to: to.value })
const handleSearch = (value: string) =>
onSearch({
query: value,
to: to.value,
// , from: from.value
})
// const handleSearch = (value: string) =>
// onSearch({
// query: value,
// to: to.value,
// // , from: from.value
// })
const RefreshButton = () => {
return !isCustomQuery ? (
@@ -142,8 +136,38 @@ const PreviewFilterPanel: FC<Props> = ({
) : null
}
const handleToChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
if (value !== '' && isNaN(Date.parse(value))) {
setTo({ value, error: 'Invalid ISO 8601 timestamp' })
} else {
setTo({ value, error: '' })
}
}
const handleFromChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
if (value !== '' && isNaN(Date.parse(value))) {
setFrom({ value, error: 'Invalid ISO 8601 timestamp' })
} else {
setFrom({ value, error: '' })
}
}
const handleReset = async () => {
setTo({ value: '', error: '' })
setFrom({ value: '', error: '' })
const value = dayjs().utc().toISOString()
setDefaultTimestamp(value)
onSearch({ query: search, to: '', from: '' })
}
const showReset = to.value !== '' || from.value !== ''
const showFromReset = to.value !== ''
const handleSearch = () => onSearch({ query: search, to: to.value, from: from.value })
// console.log('this is what is going through', FILTER_OPTIONS[table])
return (
@@ -238,10 +262,69 @@ const PreviewFilterPanel: FC<Props> = ({
})}
</div>
<div className="flex flex-row">
<Popover
side="bottom"
align="end"
portalled
overlay={
<>
<Input
label="From"
labelOptional="UTC"
value={from.value === '' ? defaultTimestamp : from.value}
onChange={handleFromChange}
error={from.error}
className="w-72 p-3"
/>
<Input
label="To"
labelOptional="UTC"
value={to.value === '' ? defaultTimestamp : to.value}
onChange={handleToChange}
error={to.error}
className="w-72 p-3"
/>
<div className="flex flex-row justify-end pb-2 px-4">
<Button key="set" size="tiny" title="Set" type="secondary" onClick={handleSearch}>
Set
</Button>
</div>
</>
}
>
<Button
as="span"
size="tiny"
className={showReset ? '!rounded-r-none' : ''}
type={showReset ? 'outline' : 'text'}
icon={<IconClock size="tiny" />}
>
{to.value || from.value ? 'Custom' : 'Now'}
</Button>
</Popover>
{showReset && (
<Button
size="tiny"
className={showReset ? '!rounded-l-none' : ''}
icon={<IconX size="tiny" />}
type="outline"
title="Clear timestamp filter"
onClick={handleReset}
/>
)}
</div>
{/* {!isCustomQuery && (
<div className="flex items-center space-x-2">
<p className="text-xs">Show event chart</p>
<Toggle size="tiny" checked={isShowingEventChart} onChange={onToggleEventChart} />
</div>
)} */}
{!isCustomQuery && (
<>
<div className="flex flex-row gap-2">
<Popover
{/* <Popover
side="bottom"
align="end"
portalled
@@ -276,7 +359,7 @@ const PreviewFilterPanel: FC<Props> = ({
>
{to.value ? 'Custom' : 'Now'}
</Button>
</Popover>
</Popover> */}
{/* Clear the filters could be here */}
</div>
+64 -21
View File
@@ -20,6 +20,7 @@ import {
import { format } from 'date-fns'
import TimeSplitInput from './TimeSplitInput'
import DateSplitInput from './DateSplitInput'
import DividerSlash from './DividerSlash'
import dayjs from 'dayjs'
@@ -32,6 +33,10 @@ dayjs.extend(timezone)
interface RootProps {
handleChange?: ({}) => void
initialValues?: {
to: number
from: number
}
}
const START_DATE_DEFAULT = new Date()
@@ -44,7 +49,7 @@ const TIME_NOW = format(new Date(), 'HH:mm:ss').split(':')
const START_TIME_DEFAULT = { HH: TIME_NOW[0], mm: TIME_NOW[1], ss: TIME_NOW[2] }
const END_TIME_DEFAULT = { HH: TIME_NOW[0], mm: TIME_NOW[1], ss: TIME_NOW[2] }
function _DatePicker({ handleChange }: RootProps) {
function _DatePicker({ handleChange, initialValues }: RootProps) {
const [open, setOpen] = useState<boolean>(false)
const [showTime, setShowTime] = useState<boolean>(true)
@@ -58,21 +63,49 @@ function _DatePicker({ handleChange }: RootProps) {
const [startTime, setStartTime] = useState<any>(START_TIME_DEFAULT)
const [endTime, setEndTime] = useState<any>(END_TIME_DEFAULT)
if (initialValues) {
const from = dayjs(initialValues.from)
const to = dayjs(initialValues.to)
}
function handleDatePickerChange(dates: [from: string, to: string]) {
const [from, to] = dates
console.log('start', from)
console.log('end', to)
setStartDate(from)
setEndDate(to)
}
function handleSubmit() {
setOpen(false)
setAppliedStartDate(startDate)
setAppliedEndDate(endDate)
if (handleChange)
handleChange({
from: dayjs(
`${format(new Date(startDate), 'yyyy-MM-dd')} ${Object.values(startTime).join(':')}`
).toISOString(),
to: dayjs(
`${format(new Date(endDate), 'yyyy-MM-dd')} ${Object.values(endTime).join(':')}`
).toISOString(),
})
const from = `${format(new Date(startDate), 'yyyy-MM-dd')} ${Object.values(startTime).join(
':'
)}`
const to = `${format(new Date(endDate), 'yyyy-MM-dd')} ${Object.values(endTime).join(':')}`
function isoPayload() {
return {
from: dayjs(from).toISOString(),
to: dayjs(to).toISOString(),
}
}
function unixPayload() {
return {
from: dayjs(from).valueOf(),
to: dayjs(to).valueOf(),
}
}
// console.log('unixPayload', unixPayload())
// console.log('isoPayload', isoPayload())
if (handleChange) handleChange(unixPayload())
}
function handleClear() {
@@ -101,7 +134,7 @@ function _DatePicker({ handleChange }: RootProps) {
<>
<div className="flex justify-between items-stretch py-2">
<div className="grow flex flex-col gap-1">
<div
{/* <div
className="
flex items-center justify-center gap-0
text-xs text-scale-1100 bg-scale-100 dark:bg-scaleA-300 border border-scale-700 h-7 rounded"
@@ -135,7 +168,15 @@ function _DatePicker({ handleChange }: RootProps) {
className="w-8 bg-transparent text-scale-1200 text-center"
value={format(new Date(startDate), 'yyyy')}
/>
</div>
</div> */}
{/* <DateSplitInput
type="start"
date={startDate}
setDate={(e) => setStartDate(e)}
startDate={startDate}
endDate={endDate}
/> */}
{showTime && (
<TimeSplitInput
@@ -163,7 +204,7 @@ function _DatePicker({ handleChange }: RootProps) {
<IconArrowRight strokeWidth={1.5} size={14} />
</div>
<div className="grow flex flex-col gap-1">
<div
{/* <div
className="
flex items-center justify-center gap-0
text-xs text-scale-1100 bg-scale-100 dark:bg-scaleA-300 border border-scale-700 h-7 rounded"
@@ -182,7 +223,14 @@ function _DatePicker({ handleChange }: RootProps) {
className="appearance-none w-8 text-scale-1200 bg-transparent text-center"
value={format(new Date(endDate), 'yyyy')}
/>
</div>
</div> */}
{/* <DateSplitInput
type="end"
date={endDate}
setDate={(e) => setEndDate(e)}
startDate={startDate}
endDate={endDate}
/> */}
{showTime && (
<TimeSplitInput
type="end"
@@ -205,13 +253,8 @@ function _DatePicker({ handleChange }: RootProps) {
<div className="px-3 py-4">
<DatePicker
selected={startDate}
onChange={(date) => {
const [start, end] = date
console.log('start', start)
console.log('end', end)
setStartDate(start)
// setEndDate(!end ? start : end)
setEndDate(end)
onChange={(dates) => {
handleDatePickerChange(dates)
}}
dateFormat="MMMM d, yyyy h:mm aa"
startDate={startDate}
@@ -0,0 +1,27 @@
export type Time = {
HH: string
mm: string
ss: string
}
export type TimeType = 'HH' | 'mm' | 'ss'
export interface TimeSplitInputProps {
time: Time
setTime: (x: Time) => void
type: 'start' | 'end'
setStartTime: (x: Time) => void
setEndTime: (x: Time) => void
startTime: Time
endTime: Time
startDate: any
endDate: any
}
export type Date = {
YYYY: string
MM: string
DD: string
}
export type DateType = 'YYYY' | 'MM' | 'DD'
@@ -1,87 +1,112 @@
import React, { useState } from 'react'
import { IconClock } from '@supabase/ui'
import DividerSlash from './DividerSlash'
import { format } from 'date-fns'
import { DateType } from './DatePicker.types'
import dayjs from 'dayjs'
type TimeType = 'DD' | 'MM' | 'YYYY'
var advancedFormat = require('dayjs/plugin/advancedFormat')
var utc = require('dayjs/plugin/utc')
var timezone = require('dayjs/plugin/timezone') // dependent on utc plugin
type Time = {
HH: string
mm: string
ss: string
}
dayjs.extend(advancedFormat)
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.tz.guess()
// type TimeType = 'DD' | 'MM' | 'YYYY'
// type Time = {
// HH: string
// mm: string
// ss: string
// }
interface TimeSplitInputProps {
time: Time
setTime: (x: Time) => void
date: string
// setTime: (x: Time) => void
type: 'start' | 'end'
setStartTime: (x: Time) => void
setEndTime: (x: Time) => void
startTime: Time
endTime: Time
// setStartTime: (x: Time) => void
// setEndTime: (x: Time) => void
// startTime: Time
// endTime: Time
startDate: any
endDate: any
setDate: ({}) => void
}
const TimeSplitInput = ({
const DateSplitInput = ({
type,
time,
setTime,
setStartTime,
setEndTime,
startTime,
endTime,
date,
// setTime,
// setStartTime,
// setEndTime,
// startTime,
// endTime,
startDate,
endDate,
setDate,
}: TimeSplitInputProps) => {
const [focus, setFocus] = useState(false)
function handleOnChange(value: string, valueType: TimeType) {
const [splitDate, setSplitDate] = useState({
DD: format(new Date(date), 'dd'),
MM: format(new Date(date), 'MM'),
YYYY: format(new Date(date), 'yyyy'),
})
function handleOnChange() {
// console.log('handleOnChange')
const payload = {
HH: time.HH,
mm: time.mm,
ss: time.ss,
DD: splitDate.DD,
MM: splitDate.MM,
YYYY: splitDate.YYYY,
}
if (value.length > 2) return
switch (valueType) {
case 'DD':
if (value && Number(value) > 23) return
break
case 'MM':
if (value && Number(value) > 59) return
break
case 'YYYY':
if (value && Number(value) > 59) return
break
default:
break
}
// if (Number(payload.YYYY) > 2021) {
// payload.YYYY = 2021
// }
// if (value.length > 2) return
// switch (valueType) {
// case 'DD':
// if (value && Number(value) > 23) return
// break
// case 'MM':
// if (value && Number(value) > 59) return
// break
// case 'YYYY':
// if (value && Number(value) > 59) return
// break
// default:
// break
// }
// console.log('got here')
payload[valueType] = value
setTime({ ...payload })
// payload[valueType] = value
// if (endTimeChanges) {
// setEndTime(endTimePayload)
// }
const dns_format = new Date(Number(payload.YYYY), Number(payload.MM), Number(payload.DD))
// console.log('format:', dns_format)
setDate(dns_format)
}
function handleOnBlur(valueType: TimeType) {
function sanitize(valueType: DateType) {
// console.log('handle blur')
const _time = time
// console.log('_time.HH.length', _time.HH.length)
const _time = splitDate
// console.log('_time.MM.length', _time.MM.length)
if (_time.HH.length === 1) _time.HH = '0' + _time.HH
if (_time.mm.length === 1) _time.mm = '0' + _time.mm
if (_time.ss.length === 1) _time.ss = '0' + _time.ss
if (_time.DD.length === 1) _time.DD = '0' + _time.DD
if (_time.MM.length === 1) _time.MM = '0' + _time.MM
if (_time.YYYY.length === 1) _time.YYYY = '0' + _time.YYYY
if (!_time.HH) _time.HH = '00'
if (!_time.mm) _time.mm = '00'
if (!_time.ss) _time.ss = '00'
if (!_time.DD) _time.DD = '00'
if (!_time.MM) _time.MM = '00'
if (!_time.YYYY) _time.YYYY = '00'
// console.log('_time', _time)
@@ -101,35 +126,35 @@ const TimeSplitInput = ({
if (type === 'start') {
// console.log('HH in start switch')
if (_time.HH && Number(_time.HH) > Number(endTime.HH)) {
endTimePayload.HH = _time.HH
if (_time.MM && Number(_time.MM) > Number(endTime.HH)) {
endTimePayload.HH = _time.MM
endTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) >= Number(endTime.HH) &&
_time.MM &&
Number(_time.MM) >= Number(endTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) > Number(endTime.mm)
_time.MM &&
Number(_time.MM) > Number(endTime.mm)
) {
endTimePayload.mm = _time.mm
endTimePayload.mm = _time.MM
endTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) >= Number(endTime.HH) &&
_time.MM &&
Number(_time.MM) >= Number(endTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) >= Number(endTime.mm) &&
_time.MM &&
Number(_time.MM) >= Number(endTime.mm) &&
// check the seconds
_time.ss &&
Number(_time.ss) > Number(endTime.ss)
_time.YYYY &&
Number(_time.YYYY) > Number(endTime.ss)
) {
endTimePayload.ss = _time.ss
endTimePayload.ss = _time.YYYY
endTimeChanges = true
}
}
@@ -137,35 +162,35 @@ const TimeSplitInput = ({
if (type === 'end') {
// console.log('HH in start switch')
if (_time.HH && Number(_time.HH) < Number(startTime.HH)) {
startTimePayload.HH = _time.HH
if (_time.MM && Number(_time.MM) < Number(startTime.HH)) {
startTimePayload.HH = _time.MM
startTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) <= Number(startTime.HH) &&
_time.MM &&
Number(_time.MM) <= Number(startTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) < Number(startTime.mm)
_time.MM &&
Number(_time.MM) < Number(startTime.mm)
) {
startTimePayload.mm = _time.mm
startTimePayload.mm = _time.MM
startTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) <= Number(startTime.HH) &&
_time.MM &&
Number(_time.MM) <= Number(startTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) <= Number(startTime.mm) &&
_time.MM &&
Number(_time.MM) <= Number(startTime.mm) &&
// check the seconds
_time.ss &&
Number(_time.ss) < Number(startTime.ss)
_time.YYYY &&
Number(_time.YYYY) < Number(startTime.ss)
) {
startTimePayload.ss = _time.ss
startTimePayload.ss = _time.YYYY
startTimeChanges = true
}
}
@@ -196,43 +221,44 @@ const TimeSplitInput = ({
${focus && ' outline outline-2 outline-scale-500 border-scale-800'}
`}
>
<div className="text-scale-900 mr-1">
<IconClock size={14} strokeWidth={1.5} />
</div>
<input
onBlur={() => handleOnBlur('DD')}
onBlur={() => handleOnChange()}
onFocus={handleFocus}
pattern="[0-31]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'DD')}
maxLength={2}
onChange={(e) => setSplitDate({ ...splitDate, DD: e.target.value })}
aria-label="Days"
className="text-scale-1200 w-5 bg-transparent text-center outline-none"
value={time.HH}
value={splitDate.DD}
/>
<span className="text-scale-900">:</span>
<DividerSlash />
<input
onBlur={() => handleOnBlur('MM')}
onBlur={() => handleOnChange()}
onFocus={handleFocus}
pattern="[0-12]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'MM')}
maxLength={2}
onChange={(e) => setSplitDate({ ...splitDate, MM: e.target.value })}
aria-label="Months"
className="text-scale-1200 w-5 bg-transparent text-center outline-none"
value={time.mm}
value={splitDate.MM}
/>
<span className="text-scale-900">:</span>
<DividerSlash />
<input
onBlur={() => handleOnBlur('YYYY')}
onBlur={() => handleOnChange()}
onFocus={handleFocus}
pattern="[2021-2022]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'YYYY')}
maxLength={4}
minLength={4}
onChange={(e) => setSplitDate({ ...splitDate, YYYY: e.target.value })}
aria-label="Years"
className="text-scale-1200 w-5 bg-transparent text-center outline-none"
value={time.ss}
className="text-scale-1200 w-8 bg-transparent text-center outline-none"
value={splitDate.YYYY}
/>
</div>
)
}
export default TimeSplitInput
export default DateSplitInput
@@ -3,25 +3,7 @@ import { IconClock } from '@supabase/ui'
import { format } from 'date-fns'
type TimeType = 'HH' | 'mm' | 'ss'
type Time = {
HH: string
mm: string
ss: string
}
interface TimeSplitInputProps {
time: Time
setTime: (x: Time) => void
type: 'start' | 'end'
setStartTime: (x: Time) => void
setEndTime: (x: Time) => void
startTime: Time
endTime: Time
startDate: any
endDate: any
}
import { TimeType, Time, TimeSplitInputProps } from './DatePicker.types'
const TimeSplitInput = ({
type,