From 6bb50526b38303e826951f29b11aa09e08c30374 Mon Sep 17 00:00:00 2001 From: balaji-jr Date: Tue, 15 Oct 2024 09:33:18 +0530 Subject: [PATCH 1/7] tz support --- src/pages/Dashboards/utils.ts | 4 +++- .../Stream/Views/Explore/StaticLogTable.tsx | 6 ++++-- .../Stream/components/EventTimeLineGraph.tsx | 8 ++++++-- src/pages/Stream/providers/LogsProvider.tsx | 16 +++++++--------- src/pages/Systems/EventCountSection.tsx | 6 +++++- src/pages/Systems/StorageSection.tsx | 6 ++++-- src/utils/timeRangeUtils.ts | 19 +++++++++++-------- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/pages/Dashboards/utils.ts b/src/pages/Dashboards/utils.ts index 1ffb3d53..fcfb8eb4 100644 --- a/src/pages/Dashboards/utils.ts +++ b/src/pages/Dashboards/utils.ts @@ -26,8 +26,10 @@ const formatTickValue = (value: any, unit: (typeof tickUnits)[number] | null) => } else if (unit === 'bytes' && _.isNumber(value)) { return formatBytes(value); } else if (unit === 'utc-timestamp') { - const date = new Date(value); + const sanitizedTs = _.includes(value, 'z') || _.includes(value, 'Z') ? value : `${value}Z`; + const date = new Date(sanitizedTs); const isValidDate = !isNaN(date.getTime()); + if (!isValidDate) return value; if (date.getHours() === 0) { diff --git a/src/pages/Stream/Views/Explore/StaticLogTable.tsx b/src/pages/Stream/Views/Explore/StaticLogTable.tsx index e05d5f27..24ad6796 100644 --- a/src/pages/Stream/Views/Explore/StaticLogTable.tsx +++ b/src/pages/Stream/Views/Explore/StaticLogTable.tsx @@ -19,9 +19,10 @@ import { MantineReactTable } from 'mantine-react-table'; import Column from '../../components/Column'; import { Log } from '@/@types/parseable/api/query'; import { CopyIcon } from './JSONView'; +import timeRangeUtils from '@/utils/timeRangeUtils'; const { setSelectedLog } = logsStoreReducers; - +const { formatDateWithTimezone } = timeRangeUtils; const TableContainer = (props: { children: ReactNode }) => { return {props.children}; }; @@ -38,9 +39,10 @@ const makeHeaderOpts = (headers: string[], isSecureHTTPContext: boolean) => { grow: true, Cell: ({ cell }: { cell: any }) => { const value = _.isFunction(cell.getValue) ? cell.getValue() : ''; + const isTimestamp = cell?.column?.id === 'p_timestamp'; return (
- {value} + {isTimestamp ? formatDateWithTimezone(`${value}Z`, 'hh:mm:ss.SSS A DD MMM YY z') : value}
{isSecureHTTPContext ? value && : null}
diff --git a/src/pages/Stream/components/EventTimeLineGraph.tsx b/src/pages/Stream/components/EventTimeLineGraph.tsx index 0d6ff2d1..47539c47 100644 --- a/src/pages/Stream/components/EventTimeLineGraph.tsx +++ b/src/pages/Stream/components/EventTimeLineGraph.tsx @@ -10,9 +10,11 @@ import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import { useFilterStore, filterStoreReducers } from '../providers/FilterProvider'; import { LogsResponseWithHeaders } from '@/@types/parseable/api/query'; import _ from 'lodash'; -const { setTimeRange } = logsStoreReducers; +import timeRangeUtils from '@/utils/timeRangeUtils'; +const { setTimeRange } = logsStoreReducers; const { parseQuery } = filterStoreReducers; +const { makeTimeRangeLabel } = timeRangeUtils; type CompactInterval = 'minute' | 'day' | 'hour' | 'quarter-hour' | 'half-hour' | 'month'; @@ -233,10 +235,12 @@ function ChartTooltip({ payload }: ChartTooltipProps) { const { aboveAvgPercent, events, startTime, endTime } = payload[0]?.payload as GraphTickItem; const isAboveAvg = aboveAvgPercent > 0; + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); + return ( - {`${startTime.format('DD MMM YY hh:mm A')} - ${endTime.format('DD MMM YY hh:mm A')}`} + {label} Events diff --git a/src/pages/Stream/providers/LogsProvider.tsx b/src/pages/Stream/providers/LogsProvider.tsx index 0a81054e..5b033d0c 100644 --- a/src/pages/Stream/providers/LogsProvider.tsx +++ b/src/pages/Stream/providers/LogsProvider.tsx @@ -7,6 +7,9 @@ import { addOrRemoveElement } from '@/utils'; import { getPageSlice } from '../utils'; import _ from 'lodash'; import { sanitizeCSVData } from '@/utils/exportHelpers'; +import timeRangeUtils from '@/utils/timeRangeUtils'; + +const { makeTimeRangeLabel } = timeRangeUtils; export const DEFAULT_FIXED_DURATIONS = FIXED_DURATIONS[0]; export const LOG_QUERY_LIMITS = [50, 100, 150, 200]; @@ -119,23 +122,18 @@ const getDefaultTimeRange = (duration: FixedDuration = DEFAULT_FIXED_DURATIONS) const startTime = now.subtract(milliseconds, 'milliseconds'); const endTime = now; - const startTimeLabel = dayjs(startTime).format('hh:mm A DD MMM YY'); - const endTimeLabel = dayjs(endTime).format('hh:mm A DD MMM YY'); + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); return { startTime: startTime.toDate(), endTime: now.toDate(), type: 'fixed' as 'fixed', - label: `${startTimeLabel} to ${endTimeLabel}`, + label, interval: milliseconds, shiftInterval: 1, }; }; -export const makeTimeRangeLabel = (startTime: Date | string, endTime: Date | string) => { - return `${dayjs(startTime).format('hh:mm A DD MMM YY')} to ${dayjs(endTime).format('hh:mm A DD MMM YY')}`; -}; - const defaultQuickFilters = { search: '', filters: {}, @@ -362,7 +360,7 @@ const setTimeRange = ( payload: { startTime: dayjs.Dayjs; endTime: Dayjs; type: 'fixed' | 'custom' }, ) => { const { startTime, endTime, type } = payload; - const label = `${startTime.format('hh:mm A DD MMM YY')} to ${endTime.format('hh:mm A DD MMM YY')}`; + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); const interval = endTime.diff(startTime, 'milliseconds'); const cleanStore = getCleanStoreForRefetch(store); return { @@ -711,7 +709,7 @@ const applyCustomQuery = ( } else { const startTime = dayjs(timeRangePayload.from); const endTime = dayjs(timeRangePayload.to); - const label = `${startTime.format('hh:mm A DD MMM YY')} to ${endTime.format('hh:mm A DD MMM YY')}`; + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); const interval = endTime.diff(startTime, 'milliseconds'); return { timeRange: { diff --git a/src/pages/Systems/EventCountSection.tsx b/src/pages/Systems/EventCountSection.tsx index fcdd0b5f..1ae9e55b 100644 --- a/src/pages/Systems/EventCountSection.tsx +++ b/src/pages/Systems/EventCountSection.tsx @@ -7,6 +7,9 @@ import { useMemo } from 'react'; import { useClusterStore } from './providers/ClusterProvider'; import { sanitizeEventsCount } from '@/utils/formatBytes'; import dayjs from 'dayjs'; +import timeRangeUtils from '@/utils/timeRangeUtils'; + +const { formatDateWithTimezone } = timeRangeUtils; function ChartTooltip({ payload }: ChartTooltipProps) { if (!payload || (Array.isArray(payload) && payload.length === 0)) return null; @@ -52,7 +55,8 @@ const EventsCountGraph = () => { (acc, record) => { const date = _.get(record, 'event_time', ''); const localDate = new Date(`${date}Z`); - const parsedDate = dayjs(localDate).format('HH:mm A'); + const parsedDate = formatDateWithTimezone(localDate, 'HH:mm A z'); + dayjs(localDate).format('HH:mm A'); const count = _.get(record, 'parseable_events_ingested', 0); return [...acc, { date: parsedDate, count }]; }, diff --git a/src/pages/Systems/StorageSection.tsx b/src/pages/Systems/StorageSection.tsx index e9160196..bdf6fb58 100644 --- a/src/pages/Systems/StorageSection.tsx +++ b/src/pages/Systems/StorageSection.tsx @@ -6,8 +6,10 @@ import _ from 'lodash'; import { useMemo } from 'react'; import { useClusterStore } from './providers/ClusterProvider'; import { calcCompressionRate, formatBytes } from '@/utils/formatBytes'; -import dayjs from 'dayjs'; import { IconArrowDown } from '@tabler/icons-react'; +import timeRangeUtils from '@/utils/timeRangeUtils'; + +const { formatDateWithTimezone } = timeRangeUtils; function ChartTooltip({ payload }: ChartTooltipProps) { if (!payload || (Array.isArray(payload) && payload.length === 0)) return null; @@ -53,7 +55,7 @@ const StorageSizeGraph = () => { (acc, record) => { const date = _.get(record, 'event_time', ''); const localDate = new Date(`${date}Z`); - const parsedDate = dayjs(localDate).format('HH:mm A'); + const parsedDate = formatDateWithTimezone(localDate, 'HH:mm A z'); const size = _.get(record, 'parseable_storage_size_data', 0); return [...acc, { date: parsedDate, size }]; }, diff --git a/src/utils/timeRangeUtils.ts b/src/utils/timeRangeUtils.ts index 546b821c..44d80a59 100644 --- a/src/utils/timeRangeUtils.ts +++ b/src/utils/timeRangeUtils.ts @@ -40,16 +40,19 @@ const makeTimeRangeOptions = ({ ]; }; -const formatTime = (date: Date | string) => { - return dayjs(date).format('hh:mm A DD MMM YY'); +const formatTime = (date: Date | string): string => { + return formatDateWithTimezone(date, 'hh:mm A DD MMM YY z'); }; -const formatDay = (date: Date | string) => { - return dayjs(date).format('DD MMMYY'); +const formatDay = (date: Date | string): string => { + return formatDateWithTimezone(date, 'DD MMMYY z'); }; const makeTimeRangeLabel = (startTime: Date | string, endTime: Date | string) => { - return `${formatTime(startTime)} to ${formatTime(endTime)}`; + const startTimeWithTz = formatDateWithTimezone(startTime, 'hh:mm A DD MMM YY z'); + const endTimeWithTz = formatDateWithTimezone(endTime, 'hh:mm A DD MMM YY z'); + + return `${startTimeWithTz} to ${endTimeWithTz}`; }; // to optimize performace, it has been decided to round off the time at the given level @@ -65,9 +68,9 @@ const getDefaultTimeRangeOption = ( return selectedTimeRange ? selectedTimeRange : defaultTimeRangeOption; }; -//accepts a date-time string and outputs a human readable string with timezone -//output format 31/12/1990 11:59 pm IST as default -const formatDateWithTimezone = (dateTime: string, format: string = 'DD/MM/YYYY h:mm a z'): string => { +// accepts a date-time string and outputs a human readable string with timezone +// output format 31/12/1990 11:59 pm IST +const formatDateWithTimezone = (dateTime: string | Date, format: string = 'DD/MM/YYYY h:mm a z'): string => { const localTimeZone = moment.tz.guess(); const convertedDate = moment.tz(dateTime, localTimeZone); return convertedDate.format(format); From 382f54eff4789e31e5b660f74345c1d60aa2acb0 Mon Sep 17 00:00:00 2001 From: balaji-jr Date: Thu, 17 Oct 2024 10:13:53 +0530 Subject: [PATCH 2/7] timerange selector - ui updates --- src/components/Header/TimeRange.tsx | 231 +++++++++++------- .../Header/styles/LogQuery.module.css | 230 ++++++++--------- src/constants/timeConstants.ts | 10 +- src/pages/Dashboards/Dashboard.tsx | 6 +- src/pages/Dashboards/Toolbar.tsx | 8 +- .../Stream/Views/Explore/StaticLogTable.tsx | 2 +- 6 files changed, 279 insertions(+), 208 deletions(-) diff --git a/src/components/Header/TimeRange.tsx b/src/components/Header/TimeRange.tsx index c94dac9f..6a904ca1 100644 --- a/src/components/Header/TimeRange.tsx +++ b/src/components/Header/TimeRange.tsx @@ -1,27 +1,41 @@ import useMountedState from '@/hooks/useMountedState'; -import { Box, Button, Divider, Menu, NumberInput, Stack, Text, Tooltip, UnstyledButton, px } from '@mantine/core'; -import { DateTimePicker } from '@mantine/dates'; -import { IconChevronLeft, IconChevronRight, IconClock } from '@tabler/icons-react'; +import { Box, Button, Divider, Menu, NumberInput, Stack, Text, Tooltip, px } from '@mantine/core'; +import { DatePicker, TimeInput } from '@mantine/dates'; +import { IconCalendarEvent, IconCheck, IconChevronLeft, IconChevronRight } from '@tabler/icons-react'; import dayjs from 'dayjs'; import type { FC } from 'react'; -import { Fragment, useCallback, useMemo } from 'react'; -import { FIXED_DURATIONS, FIXED_DURATIONS_LABEL } from '@/constants/timeConstants'; +import { Fragment, useCallback, useMemo, useRef, useState } from 'react'; +import { FIXED_DURATIONS } from '@/constants/timeConstants'; import classes from './styles/LogQuery.module.css'; import { useOuterClick } from '@/hooks/useOuterClick'; import { logsStoreReducers, useLogsStore } from '@/pages/Stream/providers/LogsProvider'; +import _ from 'lodash'; const { setTimeRange, setshiftInterval } = logsStoreReducers; type FixedDurations = (typeof FIXED_DURATIONS)[number]; -const { - timeRangeBTn, - timeRangeContainer, - fixedRangeContainer, - fixedRangeBtn, - fixedRangeBtnSelected, - customRangeContainer, - shiftIntervalContainer, -} = classes; +const { timeRangeContainer, fixedRangeBtn, fixedRangeBtnSelected, customRangeContainer, shiftIntervalContainer } = + classes; + +const RelativeTimeIntervals = (props: { + interval: number; + onDurationSelect: (fixedDuration: FixedDurations) => void; +}) => { + const { interval, onDurationSelect } = props; + return ( + + {_.map(FIXED_DURATIONS, (duration) => { + return ( + onDurationSelect(duration)}> + + {duration.label} + + + ); + })} + + ); +}; const TimeRange: FC = () => { const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); @@ -45,6 +59,8 @@ const TimeRange: FC = () => { const innerRef = useOuterClick(handleOuterClick); const [opened, setOpened] = useMountedState(false); + const [showTick, setShowTick] = useState(false); + const shiftIntervalRef = useRef(null); const toggleMenu = useCallback(() => { setOpened((prev) => !prev); @@ -58,9 +74,27 @@ const TimeRange: FC = () => { setOpened(false); }; + const resetToRelative = useCallback(() => { + const now = dayjs().startOf('minute'); + const startTime = now.subtract(FIXED_DURATIONS[0].milliseconds, 'milliseconds'); + const endTime = now; + setLogsStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); + setOpened(false); + }, []); + + const debouncedShowTick = useCallback( + _.debounce(() => { + setShowTick(true); + shiftIntervalRef.current?.blur(); // Remove focus after showing tick + }, 1000), // 1000ms = 1 second delay + [], + ); + const onSetShiftInterval = useCallback((val: number | string) => { if (typeof val === 'number') { setLogsStore((store) => setshiftInterval(store, val)); + setShowTick(false); // Hide the tick when editing starts again + debouncedShowTick(); // Show the tick after the user stops typing } }, []); @@ -92,15 +126,18 @@ const TimeRange: FC = () => { - - - + + {type === 'fixed' ? ( + + ) : ( + + {label} + + )} + + + + shiftTimeRange('right')}> @@ -111,33 +148,24 @@ const TimeRange: FC = () => {
- - {FIXED_DURATIONS.map((duration) => { - return ( - onDurationSelect(duration)}> - {duration.name} - - ); - })} - Shift Interval (In Mins) - + + + + - +
@@ -148,17 +176,35 @@ const TimeRange: FC = () => { type CustomTimeRangeProps = { setOpened: (opened: boolean) => void; + resetToRelative: () => void; }; -const CustomTimeRange: FC = ({ setOpened }) => { - const [{ startTime, endTime }, setLogsStore] = useLogsStore((store) => store.timeRange); +const CustomTimeRange: FC = ({ setOpened, resetToRelative }) => { + const [{ startTime: startTimeFromStore, endTime: endTimeFromStore, type }, setLogsStore] = useLogsStore( + (store) => store.timeRange, + ); - const [localSelectedRange, setLocalSelectedRange] = useMountedState({ - startTime, - endTime, + const [localSelectedRange, setLocalSelectedRange] = useState({ + startTime: _.clone(startTimeFromStore), + endTime: _.clone(endTimeFromStore), }); const onRangeSelect = (key: keyof typeof localSelectedRange, date: Date) => { setLocalSelectedRange((state) => { + const year = date.getFullYear(); + const month = date.getMonth(); + const day = date.getDate(); + const newDate = state[key]; + newDate.setFullYear(year, month, day); + state[key] = newDate; + return { ...state }; + }); + }; + + const onTimeSelect = (key: keyof typeof localSelectedRange, time: string) => { + setLocalSelectedRange((state) => { + const [hours, minutes] = time.split(':').map(Number); + const date = state[key]; + date.setHours(hours, minutes, 0, 0); state[key] = date; return { ...state }; }); @@ -179,52 +225,67 @@ const CustomTimeRange: FC = ({ setOpened }) => { const isApplicable = useMemo(() => { return ( - dayjs(localSelectedRange.startTime).isSame(startTime, 'seconds') && - dayjs(localSelectedRange.endTime).isSame(endTime, 'seconds') + dayjs(localSelectedRange.startTime).isSame(startTimeFromStore, 'seconds') && + dayjs(localSelectedRange.endTime).isSame(endTimeFromStore, 'seconds') ); }, [localSelectedRange]); const isStartTimeMoreThenEndTime = useMemo(() => { return dayjs(localSelectedRange.startTime).isAfter(localSelectedRange.endTime, 'seconds'); }, [localSelectedRange]); + const startingTime = (() => { + const hours = localSelectedRange.startTime.getHours().toString().padStart(2, '0'); + const minutes = localSelectedRange.startTime.getMinutes().toString().padStart(2, '0'); + return `${hours}:${minutes}`; + })(); + const endingTime = (() => { + const hours = localSelectedRange.endTime.getHours().toString().padStart(2, '0'); + const minutes = localSelectedRange.endTime.getMinutes().toString().padStart(2, '0'); + return `${hours}:${minutes}`; + })(); return ( - Custom Range - { - if (date) { - onRangeSelect('startTime', date); - } - }} - valueFormat="DD-MM-YY HH:mm" - label="From" - placeholder="Pick date and time" - /> - { - if (date) { - onRangeSelect('endTime', date); - } - }} - valueFormat="DD-MM-YY HH:mm" - label="To" - placeholder="Pick date and time" - /> - - - + Absolute Range + + + { + if (date) { + onRangeSelect('startTime', date); + } + }} + /> + onTimeSelect('startTime', e.currentTarget.value)} /> + + + { + if (date) { + onRangeSelect('endTime', date); + } + }} + /> + onTimeSelect('endTime', e.currentTarget.value)} /> + + + + + + + + + + ); }; diff --git a/src/components/Header/styles/LogQuery.module.css b/src/components/Header/styles/LogQuery.module.css index 446cdbd8..2efb1f01 100644 --- a/src/components/Header/styles/LogQuery.module.css +++ b/src/components/Header/styles/LogQuery.module.css @@ -4,61 +4,63 @@ align-items: center; padding: 0 1rem; } - - .innerContainer { + +.innerContainer { display: flex; height: 100%; align-items: center; width: 100%; - } - - .refreshNowBtn { +} + +.refreshNowBtn { background: #fff; padding: 0; width: 36px; color: #211F1F; border: 1px #e9ecef solid; - border-radius: rem(8px); + border-radius: rem(8px); + &:hover { color: black; } - } +} + +.refreshNowBtn:hover { + background-color: #E0E0E0; +} - .refreshNowBtn:hover { - background-color: #E0E0E0; - } - - .streamButton { +.streamButton { background: #fff; color: #211F1F; border: 1px #e9ecef solid; - border-radius: rem(8px); - } - - .intervalbtn { + border-radius: rem(8px); +} + +.intervalbtn { background-color: white; color: var(--mantine-color-gray-7); border: 1px #e9ecef solid; - border-radius: rem(8px); + border-radius: rem(8px); font-size: 0.65rem; + &:hover { color: black; } - } - - .intervalbtn:hover { - background-color: #E0E0E0; - } - - .homeIcon { +} + +.intervalbtn:hover { + background-color: #E0E0E0; +} + +.homeIcon { size: 24px; - } - - .timeRangeContainer { +} + +.timeRangeContainer { display: flex; - } - - .fixedRangeContainer { +} + +.fixedRangeContainer { display: flex; flex-direction: column; background: #f8f9fa; @@ -67,55 +69,59 @@ margin-top: 0.5rem; margin-bottom: 0.5rem; overflow: hidden; - } - - .fixedRangeBtn { +} + +.fixedRangeBtn { padding: 0.65rem; font-size: 0.675rem; background: #f8f9fa; text-transform: capitalize; + cursor: pointer; + border-radius: 0.65rem; + &:hover { - color: black !important; + /* color: black !important; */ + &:disabled { color: white !important; } } - } - - .fixedRangeBtn:hover { +} + +.fixedRangeBtn:hover { background: #ced4da; - } +} - .fixedRangeBtn:disabled { +.fixedRangeBtn:disabled { cursor: not-allowed; background: #424242; font-weight: 600; color: #fff; - } - - .customRangeContainer { +} + +.customRangeContainer { padding: 0.625rem 1rem; min-width: 20rem; flex: 1; display: flex; flex-direction: column; justify-content: stretch; - } - - .customTimeRangeFooter { +} + +.customTimeRangeFooter { display: flex; margin-top: auto; justify-content: flex-end; align-items: center; - } - - .searchContainer { +} + +.searchContainer { display: flex; padding-right: 0.75rem; - } - - .searchTypeBtn { +} + +.searchTypeBtn { border: 1px #f1f3f5 solid; border-top-right-radius: 0; border-bottom-right-radius: 0; @@ -124,43 +130,43 @@ border-right: none; font-weight: 700; padding-right: 0.75rem; - } - - .searchTypeActive { +} + +.searchTypeActive { background: #545beb; font-weight: 500; color: #fff; - } - - .searchTypeActive:hover { +} + +.searchTypeActive:hover { background: #fc466b; - } - - .searchInput { +} + +.searchInput { width: 100%; flex: 1; - } - - .searchInput input { +} + +.searchInput input { background: #fff; border: 1px #e9ecef solid; - border-radius: rem(8px); + border-radius: rem(8px); font-weight: 500; - } - - .toggleBtn { +} + +.toggleBtn { background-color: white; padding: 6px 12px; margin-right: 0.625rem; color: #211F1F; border: 1px #e9ecef solid; - } - - .toggleBtn:hover { +} + +.toggleBtn:hover { background: #f1f3f5; - } - - .timeRangeBTn { +} + +.timeRangeBTn { background-color: white; color: var(--mantine-color-gray-7); padding: 0 0.5rem; @@ -168,42 +174,45 @@ border-right: 1px solid var(--mantine-color-gray-2); border-left: 1px solid var(--mantine-color-gray-2); height: 100%; - } - - .timeRangeBTn:hover { - background-color: #E0E0E0; +} + +.timeRangeBTn:hover { + background-color: #E0E0E0; color: black; - } - - .dropdownBtn { +} + +.dropdownBtn { margin-right: 0.625rem; border-radius: rem(8px); - } +} - .dropdownOption { +.dropdownOption { color: #211F1F; font-size: var(--mantine-font-size-md); - } +} - .liveTailFilterContainer { +.liveTailFilterContainer { display: flex; gap: 12px; margin-right: 20px; - } - - .fixedRangeBtnSelected { +} + +.fixedRangeBtnSelected { background: #545beb !important; font-weight: 500; color: white; - } - - .fixedRangeBtnSelected:hover { +} + +.fixedRangeBtnSelected:hover { background: #f1f3f5; - } - - .customTimeRangeApplyBtn { + cursor: not-allowed; + color: white; +} + +.customTimeRangeApplyBtn { background: #545BEB; color: white; + &:hover { background: #FC466B; } @@ -224,22 +233,9 @@ } .streamInput { - /* border: none; */ - /* padding-left: 0; */ - /* padding-right: 30px; */ - /* height: 50px; */ - /* font-size: 24px; */ - /* font-weight: 600; */ - /* margin-top: -10px; */ - /* background-color: transparent; */ cursor: pointer; border: 1px var(--mantine-color-gray-2) solid; border-radius: rem(8px); - /* height: 50px; */ - /* height: 100%; */ - /* font-size: 1rem; */ - /* width: 200px; */ - } .chevronDown { @@ -247,15 +243,15 @@ } .iconBtn { - cursor: pointer; - align-items: center; + cursor: pointer; + align-items: center; /* padding: 0.25rem; */ border-radius: 0.25rem; /* padding: 0.25rem 0; */ } .iconBtnIcon { - color: var(--mantine-color-brandPrimary-6); + color: var(--mantine-color-brandPrimary-6); /* color: white; background-color: var(--mantine-color-brandPrimary-4); */ border-radius: 0.25rem; @@ -263,7 +259,7 @@ } .iconBtnLabel { - font-size: 0.8rem; + font-size: 0.8rem; white-space: nowrap; } @@ -304,16 +300,20 @@ border: 1px solid var(--mantine-color-gray-3); overflow: hidden; border-radius: rem(8px); + align-items: center; + height: 1.6rem } .timeRangeCtrlIcon { height: 100%; - align-items: center; - justify-content: center; + align-items: center; + justify-content: center; + &:hover { background-color: #E0E0E0; color: black; } + padding: 0 0.25rem; color: var(--mantine-color-gray-7); cursor: pointer; @@ -330,4 +330,10 @@ font-size: 0.7rem; font-weight: 500; text-align: center; +} + +.datePickerContainer { + border: 1px solid var(--mantine-color-gray-2); + border-radius: 0.2rem; + padding: 1rem; } \ No newline at end of file diff --git a/src/constants/timeConstants.ts b/src/constants/timeConstants.ts index 49d81cb8..56124051 100644 --- a/src/constants/timeConstants.ts +++ b/src/constants/timeConstants.ts @@ -12,27 +12,27 @@ export const FIXED_DURATIONS: ReadonlyArray = [ { name: 'last 10 minutes', milliseconds: dayjs.duration({ minutes: 10 }).asMilliseconds(), - label: '10M', + label: '10m', }, { name: 'last 1 hour', milliseconds: dayjs.duration({ hours: 1 }).asMilliseconds(), - label: '1H', + label: '1h', }, { name: 'last 5 hours', milliseconds: dayjs.duration({ hours: 5 }).asMilliseconds(), - label: '5H', + label: '5h', }, { name: 'last 24 hours', milliseconds: dayjs.duration({ days: 1 }).asMilliseconds(), - label: '1D', + label: '1d', }, { name: 'last 3 days', milliseconds: dayjs.duration({ days: 3 }).asMilliseconds(), - label: '3D', + label: '3d', }, ] as const; diff --git a/src/pages/Dashboards/Dashboard.tsx b/src/pages/Dashboards/Dashboard.tsx index f33b8882..0d5c56b5 100644 --- a/src/pages/Dashboards/Dashboard.tsx +++ b/src/pages/Dashboards/Dashboard.tsx @@ -196,7 +196,7 @@ const ImportDashboardModal = () => { }, []); const onImport = useCallback(() => { - if (activeDashboard === null || file === null) return; + if (file === null) return; if (file) { const reader = new FileReader(); @@ -209,7 +209,9 @@ const ImportDashboardModal = () => { if (_.isEmpty(newDashboard)) return; return makePostCall(newDashboard) - } catch (error) {} + } catch (error) { + console.log("error", error) + } }; reader.readAsText(file); } else { diff --git a/src/pages/Dashboards/Toolbar.tsx b/src/pages/Dashboards/Toolbar.tsx index 43336476..e0661747 100644 --- a/src/pages/Dashboards/Toolbar.tsx +++ b/src/pages/Dashboards/Toolbar.tsx @@ -155,7 +155,9 @@ const DeleteDashboardModal = () => {
- +