From f4151f9d367e317e009e13daadc3fe4fe6f988cf Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Thu, 27 Feb 2025 22:19:11 -0500 Subject: [PATCH] log filters QA --- .../components/cd/logs/DateTimeFormInput.tsx | 23 ++++++++++++++----- assets/src/components/cd/logs/LogsFilters.tsx | 12 ++++++++++ assets/src/utils/datetime.ts | 13 +++++++---- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/assets/src/components/cd/logs/DateTimeFormInput.tsx b/assets/src/components/cd/logs/DateTimeFormInput.tsx index 96459de7f..daea06135 100644 --- a/assets/src/components/cd/logs/DateTimeFormInput.tsx +++ b/assets/src/components/cd/logs/DateTimeFormInput.tsx @@ -7,6 +7,7 @@ import { SegmentedInputHandle, SemanticColorKey, Toast, + useIsFocused, } from '@pluralsh/design-system' import { Body2P } from 'components/utils/typography/Text' @@ -43,6 +44,7 @@ export function DateTimeFormInput({ const [isEnteringTimestamp, setIsEnteringTimestamp] = useState(false) const [customTimestamp, setCustomTimestamp] = useState('') const [timestampError, setTimestampError] = useState(false) + const [isFocused, focusCallbacks] = useIsFocused({}) const initDateStr = formatDateTime(initialDate, DATE_FORMAT) || EMPTY_DATE_STR const initTimeStr = formatDateTime(initialDate, TIME_FORMAT) || EMPTY_TIME_STR @@ -86,15 +88,15 @@ export function DateTimeFormInput({ else setDate?.(initialDate) }, [dateStr, dateValid, initialDate, isSetToNow, setDate, timeStr, timeValid]) - const setValsFromTimestamp = (val?: DateParam) => { - const timestamp = val ?? customTimestamp + const setValsFromTimestamp = (val?: string) => { + const timestamp = handleUnixTS(val ?? customTimestamp) if (!isValidDateTime(timestamp)) { setTimestampError(true) return } setIsEnteringTimestamp(false) - const date = formatDateTime(timestamp, DATE_FORMAT) - const time = formatDateTime(timestamp, TIME_FORMAT) + const date = formatDateTime(timestamp, DATE_FORMAT, true) + const time = formatDateTime(timestamp, TIME_FORMAT, true) runAfterLayout(() => { dateInputRef.current?.setValue(date) timeInputRef.current?.setValue(time) @@ -130,6 +132,7 @@ export function DateTimeFormInput({ ) } {...props} + {...focusCallbacks} > {isEnteringTimestamp ? ( MM/DD/YYYY} @@ -173,7 +176,7 @@ export function DateTimeFormInput({ /> UTC} @@ -220,3 +223,11 @@ const CaptionTextBtnSC = styled.span<{ opacity: $disabled ? 0.4 : 1, '&:hover': { textDecoration: $disabled ? 'none' : 'underline' }, })) + +const handleUnixTS = (val: string) => { + // parse as a unix timestamp if it's a valid number + // otherwise keep it as is + const valNum = Number(val) + if (!isNaN(valNum)) return val.length === 10 ? valNum * 1000 : valNum + return val +} diff --git a/assets/src/components/cd/logs/LogsFilters.tsx b/assets/src/components/cd/logs/LogsFilters.tsx index b8556e767..44f928119 100644 --- a/assets/src/components/cd/logs/LogsFilters.tsx +++ b/assets/src/components/cd/logs/LogsFilters.tsx @@ -9,6 +9,7 @@ import { ListBoxItem, SearchIcon, Select, + Toast, } from '@pluralsh/design-system' import { useUpdateState } from 'components/hooks/useUpdateState' import { LogFacetInput } from 'generated/graphql' @@ -114,8 +115,10 @@ function FiltersForm({ onSubmit: (form: LogsFlyoverFiltersT) => void setLive: (live: boolean) => void }) { + const { spacing } = useTheme() const [hasDTErrors, setHasDTErrors] = useState(false) const clearDTFormRef = useRef<() => void>(null) + const [showSuccessToast, setShowSuccessToast] = useState(false) const { state, update, initialState, hasUpdates } = useUpdateState(initialForm) @@ -125,6 +128,7 @@ function FiltersForm({ onSubmit(state) // by default, logs should be live if no specific date is set, and vice versa setLive(!state.date) + setShowSuccessToast(true) } const resetToDefault = () => { @@ -202,6 +206,14 @@ function FiltersForm({ + setShowSuccessToast(false)} + margin={spacing.xlarge} + > + Filters applied + ) } diff --git a/assets/src/utils/datetime.ts b/assets/src/utils/datetime.ts index 0f959aa3a..8682f2395 100644 --- a/assets/src/utils/datetime.ts +++ b/assets/src/utils/datetime.ts @@ -79,13 +79,18 @@ dayjs.extend(localizedFormat) export { dayjs as dayjsExtended } -export const formatDateTime = (date: DateParam, pattern?: string) => { +export const formatDateTime = ( + date: DateParam, + pattern?: string, + isUtc: boolean = false +) => { if (!date) return '' - if (pattern) return dayjs(date).format(pattern) + const dateObj = isUtc ? dayjs(date).utc(true) : dayjs(date) + if (pattern) return dateObj.format(pattern) - if (isSameDay(date)) return dayjs(date).format('h:mm a') + if (isSameDay(date)) return dateObj.format('h:mm a') - return dayjs(date).format('MMM D, YYYY h:mm a') + return dateObj.format('MMM D, YYYY h:mm a') } export const toISOStringOrUndef = (date: DateParam, isUtc: boolean = false) => {