From 0e31ff664a099380c91f8e026339e9fc82ec88ad Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 27 Dec 2024 18:43:50 +0530 Subject: [PATCH 01/37] upcoming: [DI-20931] - Replaced CloudPulseTimeRange with date time range picker --- packages/api-v4/src/cloudpulse/types.ts | 8 +++- .../Dashboard/CloudPulseDashboard.tsx | 8 +++- .../Dashboard/CloudPulseDashboardLanding.tsx | 8 ++-- .../CloudPulse/Overview/GlobalFilters.tsx | 41 ++++++++++++------- .../CloudPulse/Utils/CloudPulseWidgetUtils.ts | 4 +- .../CloudPulse/Utils/FilterBuilder.ts | 3 +- .../CloudPulse/Widget/CloudPulseWidget.tsx | 4 +- .../Widget/CloudPulseWidgetRenderer.tsx | 5 ++- .../shared/CloudPulseDateTimeRangePicker.tsx | 35 ++++++++++++++++ 9 files changed, 89 insertions(+), 27 deletions(-) create mode 100644 packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx diff --git a/packages/api-v4/src/cloudpulse/types.ts b/packages/api-v4/src/cloudpulse/types.ts index 1fa7b63d280..3cb1affb14e 100644 --- a/packages/api-v4/src/cloudpulse/types.ts +++ b/packages/api-v4/src/cloudpulse/types.ts @@ -48,6 +48,11 @@ export interface TimeDuration { value: number; } +export interface TimeDurationDate { + end: string; + start: string; +} + export interface Widgets { label: string; metric: string; @@ -125,7 +130,8 @@ export interface CloudPulseMetricsRequest { filters?: Filters[]; aggregate_function: string; group_by: string; - relative_time_duration: TimeDuration; + relative_time_duration: TimeDuration | undefined; + absolute_time_duration: TimeDurationDate | undefined; time_granularity: TimeGranularity | undefined; entity_ids: number[]; } diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx index 4aa133e65cd..392bfbeff05 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx @@ -14,7 +14,11 @@ import { useAclpPreference } from '../Utils/UserPreference'; import { RenderWidgets } from '../Widget/CloudPulseWidgetRenderer'; import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget'; -import type { JWETokenPayLoad, TimeDuration } from '@linode/api-v4'; +import type { + JWETokenPayLoad, + TimeDuration, + TimeDurationDate, +} from '@linode/api-v4'; export interface DashboardProperties { /** @@ -30,7 +34,7 @@ export interface DashboardProperties { /** * time duration to fetch the metrics data in this widget */ - duration: TimeDuration; + duration: TimeDurationDate; /** * optional timestamp to pass as react query param to forcefully re-fetch data diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx index 238f81c6189..71290fe83de 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx @@ -6,7 +6,7 @@ import { GlobalFilters } from '../Overview/GlobalFilters'; import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; import { CloudPulseDashboardRenderer } from './CloudPulseDashboardRenderer'; -import type { Dashboard, TimeDuration } from '@linode/api-v4'; +import type { Dashboard, TimeDuration, TimeDurationDate } from '@linode/api-v4'; export type FilterValueType = number | number[] | string | string[] | undefined; @@ -19,7 +19,7 @@ export interface DashboardProp { filterValue: { [key: string]: FilterValueType; }; - timeDuration?: TimeDuration; + timeDuration?: TimeDurationDate; } export const CloudPulseDashboardLanding = () => { @@ -28,7 +28,7 @@ export const CloudPulseDashboardLanding = () => { label: {}, }); - const [timeDuration, setTimeDuration] = React.useState(); + const [timeDuration, setTimeDuration] = React.useState(); const [dashboard, setDashboard] = React.useState(); @@ -66,7 +66,7 @@ export const CloudPulseDashboardLanding = () => { }); // clear the filter values on dashboard change }, []); const onTimeDurationChange = React.useCallback( - (timeDurationObj: TimeDuration) => { + (timeDurationObj: TimeDurationDate) => { setTimeDuration(timeDurationObj); }, [] diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index 6cb3a67f1ad..84dc8627a33 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -1,6 +1,6 @@ import { Divider } from '@linode/ui'; -import { IconButton, useTheme } from '@mui/material'; import { Grid } from '@mui/material'; +import { IconButton, useTheme } from '@mui/material'; import { styled } from '@mui/material/styles'; import * as React from 'react'; @@ -8,13 +8,19 @@ import Reload from 'src/assets/icons/refresh.svg'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; +import { CloudPulseDateTimeRangePicker } from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseTimeRangeSelect } from '../shared/CloudPulseTimeRangeSelect'; import { CloudPulseTooltip } from '../shared/CloudPulseTooltip'; import { DASHBOARD_ID, REFRESH, TIME_DURATION } from '../Utils/constants'; import { useAclpPreference } from '../Utils/UserPreference'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; -import type { AclpConfig, Dashboard, TimeDuration } from '@linode/api-v4'; +import type { + AclpConfig, + Dashboard, + TimeDuration, + TimeDurationDate, +} from '@linode/api-v4'; export interface GlobalFilterProperties { handleAnyFilterChange( @@ -23,7 +29,7 @@ export interface GlobalFilterProperties { labels: string[] ): void; handleDashboardChange(dashboard: Dashboard | undefined): void; - handleTimeDurationChange(timeDuration: TimeDuration): void; + handleTimeDurationChange(timeDuration: TimeDurationDate): void; handleToggleAppliedFilter(isVisible: boolean): void; } @@ -44,15 +50,11 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { >(); const handleTimeRangeChange = React.useCallback( - ( - timerDuration: TimeDuration, - timeDurationValue: string = 'Auto', - savePref: boolean = false - ) => { - if (savePref) { - updatePreferences({ [TIME_DURATION]: timeDurationValue }); - } - handleTimeDurationChange(timerDuration); + (timeDuration: TimeDurationDate, savePref: boolean = false) => { + // if (savePref) { + // updatePreferences({ [TIME_DURATION]: timeDurationValue }); + // } + handleTimeDurationChange(timeDuration); }, [] ); @@ -109,12 +111,23 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { savePreferences /> - - + {/* */} + { const { duration, entityIds, resources, widget } = props; return { + absolute_time_duration: widget.time_duration ? undefined : duration, aggregate_function: widget.aggregate_function, entity_ids: resources ? entityIds.map((id) => parseInt(id, 10)) diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts index f3460a97b88..2d164ee59d7 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts @@ -28,6 +28,7 @@ import type { Filter, Filters, TimeDuration, + TimeDurationDate, } from '@linode/api-v4'; interface CloudPulseFilterProperties { @@ -45,7 +46,7 @@ interface CloudPulseMandatoryFilterCheckProps { filterValue: { [key: string]: FilterValueType; }; - timeDuration: TimeDuration | undefined; + timeDuration: TimeDurationDate | undefined; } /** * This function helps in building the properties needed for tags selection component diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx index e71e19e68f1..a1c7a5ea9d4 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx @@ -23,7 +23,7 @@ import { ZoomIcon } from './components/Zoomer'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; import type { CloudPulseResources } from '../shared/CloudPulseResourcesSelect'; -import type { Widgets } from '@linode/api-v4'; +import type { TimeDurationDate, Widgets } from '@linode/api-v4'; import type { MetricDefinition, TimeDuration, @@ -61,7 +61,7 @@ export interface CloudPulseWidgetProperties { /** * time duration to fetch the metrics data in this widget */ - duration: TimeDuration; + duration: TimeDurationDate; /** * entity ids selected by user to show metrics for diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx index 167d6aa80b8..b839fb9a819 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx @@ -23,13 +23,14 @@ import type { MetricDefinition, ResourcePage, TimeDuration, + TimeDurationDate, Widgets, } from '@linode/api-v4'; interface WidgetProps { additionalFilters?: CloudPulseMetricsAdditionalFilters[]; dashboard?: Dashboard | undefined; - duration: TimeDuration; + duration: TimeDurationDate; isJweTokenFetching: boolean; jweToken?: JWEToken | undefined; manualRefreshTimeStamp?: number; @@ -171,7 +172,7 @@ export const RenderWidgets = React.memo( /> ); } else { - return ; + return ; } })} diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx new file mode 100644 index 00000000000..00687ce8869 --- /dev/null +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +import { DateTimeRangePicker } from 'src/components/DatePicker/DateTimeRangePicker'; + +import type { TimeDurationDate } from '@linode/api-v4'; + +interface CloudPulseDateTimeRangePickerProps { + handleStatsChange: ( + timeDuration: TimeDurationDate, + savePref?: boolean + ) => void; +} +export const CloudPulseDateTimeRangePicker = ( + props: CloudPulseDateTimeRangePickerProps +) => { + const { handleStatsChange } = props; + return ( + { + if (!end || !start) { + return; + } + + handleStatsChange({ + end: end.split('.')[0] + 'Z', + start: start.split('.')[0] + 'Z', + }); + }} + sx={{ + minWidth: '226px', + }} + enablePresets + /> + ); +}; From 0ef704c88949d9ab36377f49f4c122ff9c9c8b11 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 31 Dec 2024 16:25:06 +0530 Subject: [PATCH 02/37] upcoming: [DI-20931] - Added preference capability to date time range picker --- packages/api-v4/src/cloudpulse/types.ts | 2 + .../CloudPulse/Overview/GlobalFilters.tsx | 17 ++++--- .../shared/CloudPulseDateTimeRangePicker.tsx | 44 +++++++++++++++---- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/api-v4/src/cloudpulse/types.ts b/packages/api-v4/src/cloudpulse/types.ts index 3cb1affb14e..08a2670071e 100644 --- a/packages/api-v4/src/cloudpulse/types.ts +++ b/packages/api-v4/src/cloudpulse/types.ts @@ -51,6 +51,7 @@ export interface TimeDuration { export interface TimeDurationDate { end: string; start: string; + preset?: string; } export interface Widgets { @@ -85,6 +86,7 @@ export type FilterValue = | string[] | number[] | WidgetFilterValue + | TimeDurationDate | undefined; type WidgetFilterValue = { [key: string]: AclpWidget }; diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index 84dc8627a33..c4731f42834 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -51,10 +51,13 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { const handleTimeRangeChange = React.useCallback( (timeDuration: TimeDurationDate, savePref: boolean = false) => { - // if (savePref) { - // updatePreferences({ [TIME_DURATION]: timeDurationValue }); - // } - handleTimeDurationChange(timeDuration); + if (savePref) { + updatePreferences({ [TIME_DURATION]: timeDuration }); + } + handleTimeDurationChange({ + end: timeDuration.end, + start: timeDuration.start, + }); }, [] ); @@ -120,14 +123,10 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { sm={5} xs={12} > - {/* */} - ; + handleStatsChange: ( timeDuration: TimeDurationDate, savePref?: boolean ) => void; + savePreferences?: boolean; } export const CloudPulseDateTimeRangePicker = ( props: CloudPulseDateTimeRangePickerProps ) => { - const { handleStatsChange } = props; + const { defaultValue, handleStatsChange, savePreferences } = props; + const defaultSelected: TimeDurationDate = defaultValue as TimeDurationDate; + + React.useEffect(() => { + if (defaultSelected) { + handleStatsChange(defaultSelected); + } + }, []); + + const end = DateTime.fromISO(defaultSelected.end, { zone: 'GMT' }); + const start = DateTime.fromISO(defaultSelected.start, { zone: 'GMT' }); + return ( { - if (!end || !start) { + endDateProps={{ + value: end, + }} + onChange={({ end, preset, start }) => { + if (!end || !start || !preset) { return; } - handleStatsChange({ - end: end.split('.')[0] + 'Z', - start: start.split('.')[0] + 'Z', - }); + handleStatsChange( + { + end: end.split('.')[0] + 'Z', + preset, + start: start.split('.')[0] + 'Z', + }, + savePreferences + ); + }} + presetsProps={{ + defaultValue: defaultSelected.preset, + }} + startDateProps={{ + value: start, }} sx={{ minWidth: '226px', From cb4526de12ecbd2787b92b8619edbbce3453a324 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 8 Jan 2025 15:18:55 +0530 Subject: [PATCH 03/37] upcoming: [DI-20931] - Added date range picker support in contextual view --- .../Dashboard/CloudPulseDashboardLanding.tsx | 7 +- .../CloudPulseDashboardWithFilters.tsx | 79 ++++++------ .../CloudPulse/Overview/GlobalFilters.tsx | 8 +- .../Utils/ReusableDashboardFilterUtils.ts | 7 +- .../CloudPulse/Widget/CloudPulseWidget.tsx | 7 +- .../shared/CloudPulseDateTimeRangePicker.tsx | 113 +++++++++++------- 6 files changed, 122 insertions(+), 99 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx index 71290fe83de..8d880831c0e 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx @@ -4,9 +4,10 @@ import * as React from 'react'; import { GlobalFilters } from '../Overview/GlobalFilters'; import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; +import { defaultTimeDuration } from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseDashboardRenderer } from './CloudPulseDashboardRenderer'; -import type { Dashboard, TimeDuration, TimeDurationDate } from '@linode/api-v4'; +import type { Dashboard, TimeDurationDate } from '@linode/api-v4'; export type FilterValueType = number | number[] | string | string[] | undefined; @@ -28,7 +29,9 @@ export const CloudPulseDashboardLanding = () => { label: {}, }); - const [timeDuration, setTimeDuration] = React.useState(); + const [timeDuration, setTimeDuration] = React.useState( + defaultTimeDuration() + ); const [dashboard, setDashboard] = React.useState(); diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index d91391163e7..2bde994c9e3 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -8,8 +8,11 @@ import { useCloudPulseDashboardByIdQuery } from 'src/queries/cloudpulse/dashboar import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; +import { + CloudPulseDateTimeRangePicker, + defaultTimeDuration, +} from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseErrorPlaceholder } from '../shared/CloudPulseErrorPlaceholder'; -import { CloudPulseTimeRangeSelect } from '../shared/CloudPulseTimeRangeSelect'; import { FILTER_CONFIG } from '../Utils/FilterConfig'; import { checkIfFilterBuilderNeeded, @@ -19,7 +22,7 @@ import { import { CloudPulseDashboard } from './CloudPulseDashboard'; import type { FilterData, FilterValueType } from './CloudPulseDashboardLanding'; -import type { TimeDuration } from '@linode/api-v4'; +import type { TimeDurationDate } from '@linode/api-v4'; export interface CloudPulseDashboardWithFiltersProp { /** @@ -44,10 +47,9 @@ export const CloudPulseDashboardWithFilters = React.memo( label: {}, }); - const [timeDuration, setTimeDuration] = React.useState({ - unit: 'min', - value: 30, - }); + const [timeDuration, setTimeDuration] = React.useState( + defaultTimeDuration() + ); const [showAppliedFilters, setShowAppliedFilters] = React.useState( false @@ -76,8 +78,11 @@ export const CloudPulseDashboardWithFilters = React.memo( ); const handleTimeRangeChange = React.useCallback( - (timeDuration: TimeDuration) => { - setTimeDuration(timeDuration); + (timeDuration: TimeDurationDate) => { + setTimeDuration({ + end: timeDuration.end, + start: timeDuration.start, + }); }, [] ); @@ -125,36 +130,34 @@ export const CloudPulseDashboardWithFilters = React.memo( padding: 0, }} > - - - - - - - - - - - - - - ({ - borderColor: theme.color.grey5, - margin: 0, - })} + + + diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index c4731f42834..f177cc7d12d 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -9,18 +9,12 @@ import Reload from 'src/assets/icons/refresh.svg'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; import { CloudPulseDateTimeRangePicker } from '../shared/CloudPulseDateTimeRangePicker'; -import { CloudPulseTimeRangeSelect } from '../shared/CloudPulseTimeRangeSelect'; import { CloudPulseTooltip } from '../shared/CloudPulseTooltip'; import { DASHBOARD_ID, REFRESH, TIME_DURATION } from '../Utils/constants'; import { useAclpPreference } from '../Utils/UserPreference'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; -import type { - AclpConfig, - Dashboard, - TimeDuration, - TimeDurationDate, -} from '@linode/api-v4'; +import type { AclpConfig, Dashboard, TimeDurationDate } from '@linode/api-v4'; export interface GlobalFilterProperties { handleAnyFilterChange( diff --git a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts index e6f28fc5341..4581bb93291 100644 --- a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts @@ -1,9 +1,10 @@ +import { defaultTimeDuration } from '../shared/CloudPulseDateTimeRangePicker'; import { FILTER_CONFIG } from './FilterConfig'; import type { DashboardProperties } from '../Dashboard/CloudPulseDashboard'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget'; -import type { Dashboard, TimeDuration } from '@linode/api-v4'; +import type { Dashboard, TimeDurationDate } from '@linode/api-v4'; /** * This interface is used to get method parameters for this utility @@ -24,7 +25,7 @@ interface ReusableDashboardFilterUtilProps { /** * The selected time duration */ - timeDuration?: TimeDuration; + timeDuration?: TimeDurationDate; } /** @@ -42,7 +43,7 @@ export const getDashboardProperties = ( resource, }), dashboardId: dashboardObj.id, - duration: timeDuration ?? { unit: 'min', value: 30 }, + duration: timeDuration ?? defaultTimeDuration(), resources: [String(resource)], savePref: false, }; diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx index a1c7a5ea9d4..33c9ed444f3 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx @@ -269,9 +269,10 @@ export const CloudPulseWidget = (props: CloudPulseWidgetProperties) => { } const metricsApiCallError = error?.[0]?.reason; - - const tickFormat = - duration.unit === 'min' || duration.unit === 'hr' ? 'hh:mm a' : 'LLL dd'; + const start = DateTime.fromISO(duration.start, { zone: 'GMT' }); + const end = DateTime.fromISO(duration.end, { zone: 'GMT' }); + const hours = end.diff(start, 'hours').hours; + const tickFormat = hours <= 24 ? 'hh:mm a' : 'LLL dd'; return ( diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 0dd7c1acd69..379da8ebda2 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -14,50 +14,71 @@ interface CloudPulseDateTimeRangePickerProps { ) => void; savePreferences?: boolean; } -export const CloudPulseDateTimeRangePicker = ( - props: CloudPulseDateTimeRangePickerProps -) => { - const { defaultValue, handleStatsChange, savePreferences } = props; - const defaultSelected: TimeDurationDate = defaultValue as TimeDurationDate; - - React.useEffect(() => { - if (defaultSelected) { - handleStatsChange(defaultSelected); - } - }, []); - - const end = DateTime.fromISO(defaultSelected.end, { zone: 'GMT' }); - const start = DateTime.fromISO(defaultSelected.start, { zone: 'GMT' }); - - return ( - { - if (!end || !start || !preset) { - return; - } - - handleStatsChange( - { - end: end.split('.')[0] + 'Z', - preset, - start: start.split('.')[0] + 'Z', - }, - savePreferences - ); - }} - presetsProps={{ - defaultValue: defaultSelected.preset, - }} - startDateProps={{ - value: start, - }} - sx={{ - minWidth: '226px', - }} - enablePresets - /> - ); + +export const CloudPulseDateTimeRangePicker = React.memo( + (props: CloudPulseDateTimeRangePickerProps) => { + const { defaultValue, handleStatsChange, savePreferences } = props; + const defaultSelected: TimeDurationDate = defaultValue as TimeDurationDate; + React.useEffect(() => { + if (defaultSelected) { + handleStatsChange(defaultSelected); + } + }, []); + + const end = DateTime.fromISO(defaultSelected?.end, { zone: 'GMT' }); + const start = DateTime.fromISO(defaultSelected?.start, { zone: 'GMT' }); + + return ( + { + if (!end || !start || !preset) { + return; + } + handleStatsChange( + { + end: convertToGmt(end), + preset, + start: convertToGmt(start), + }, + savePreferences + ); + }} + presetsProps={{ + defaultValue: defaultSelected?.preset, + }} + startDateProps={{ + label: 'Start Date', + placeholder: 'Select Start Date', + value: start, + }} + sx={{ + minWidth: '226px', + }} + enablePresets + /> + ); + } +); + +export const defaultTimeDuration = (): TimeDurationDate => { + const date = DateTime.now().setZone('GMT'); + + const start = convertToGmt(date.minus({ minutes: 30 }).toISO() ?? ''); + const end = convertToGmt(date.toISO() ?? ''); + + return { + end, + start, + }; +}; + +const convertToGmt = (date: string): string => { + const dateObject = DateTime.fromISO(date); + const updatedDate = dateObject.setZone('GMT'); + return updatedDate.toISO()?.split('.')[0] + 'Z'; }; From ee9f80fcff7b7f29a67b8671d28581f9bb662b55 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 9 Jan 2025 17:54:54 +0530 Subject: [PATCH 04/37] upcoming: [DI-20931] - Updated test cases --- .../manager/src/components/DatePicker/DateTimeRangePicker.tsx | 2 +- .../src/features/CloudPulse/Overview/GlobalFilters.test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index a83aab1206e..8e42dbcd5fd 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -257,8 +257,8 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { handlePresetSelection(selection.value as DatePresetType); } }} - data-qa-preset="preset-select" data-testid="preset-select" + data-qa-preset="preset-select" disableClearable fullWidth label={presetsLabel} diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.test.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.test.tsx index d1591390f97..9625cf0e3bb 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.test.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.test.tsx @@ -8,7 +8,7 @@ const mockHandleAnyFilterChange = vi.fn(); const mockHandleDashboardChange = vi.fn(); const mockHandleTimeDurationChange = vi.fn(); const mockHandleToggleAppliedFilter = vi.fn(); -const timeRangeSelectId = 'cloudpulse-time-duration'; +const timeRangeSelectId = 'preset-select'; const setup = () => { return renderWithTheme( Date: Fri, 10 Jan 2025 13:55:52 +0530 Subject: [PATCH 05/37] upcoming: [DI-20933] - Added default timezone value --- .../CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 379da8ebda2..08b0febb1c5 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -2,6 +2,7 @@ import { DateTime } from 'luxon'; import React from 'react'; import { DateTimeRangePicker } from 'src/components/DatePicker/DateTimeRangePicker'; +import { useProfile } from 'src/queries/profile/profile'; import type { FilterValue, TimeDurationDate } from '@linode/api-v4'; @@ -18,6 +19,8 @@ interface CloudPulseDateTimeRangePickerProps { export const CloudPulseDateTimeRangePicker = React.memo( (props: CloudPulseDateTimeRangePickerProps) => { const { defaultValue, handleStatsChange, savePreferences } = props; + const { data: profile } = useProfile(); + const timezone = profile?.timezone ?? DateTime.local().zoneName; const defaultSelected: TimeDurationDate = defaultValue as TimeDurationDate; React.useEffect(() => { if (defaultSelected) { @@ -33,6 +36,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( endDateProps={{ label: 'End Date', placeholder: 'Select End Date', + showTimeZone: true, value: end, }} onChange={({ end, preset, start }) => { @@ -54,12 +58,15 @@ export const CloudPulseDateTimeRangePicker = React.memo( startDateProps={{ label: 'Start Date', placeholder: 'Select Start Date', + showTimeZone: true, + timeZoneValue: timezone, value: start, }} sx={{ minWidth: '226px', }} enablePresets + readOnlyTimezone /> ); } From da2444d88855c8ac617fe51a89cc0293d9e4c959 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 10 Jan 2025 17:34:15 +0530 Subject: [PATCH 06/37] upcoming: [DI-20933] - Added disabled state for timezone --- .../CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 08b0febb1c5..5787a36cf32 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -65,8 +65,8 @@ export const CloudPulseDateTimeRangePicker = React.memo( sx={{ minWidth: '226px', }} + disabledTimeZone enablePresets - readOnlyTimezone /> ); } From b8d5c472a6e6c47c8fc73a8e88915e4d32cd6941 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 13 Jan 2025 17:44:55 +0530 Subject: [PATCH 07/37] upcoming: [DI-20933] - Added relative time duration in metric request for preset value --- .../CloudPulseDashboardWithFilters.tsx | 5 +-- .../CloudPulse/Overview/GlobalFilters.tsx | 5 +-- .../CloudPulse/Utils/CloudPulseWidgetUtils.ts | 42 ++++++++++++++++++- .../shared/CloudPulseDateTimeRangePicker.tsx | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index 2bde994c9e3..bb72ac009c3 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -79,10 +79,7 @@ export const CloudPulseDashboardWithFilters = React.memo( const handleTimeRangeChange = React.useCallback( (timeDuration: TimeDurationDate) => { - setTimeDuration({ - end: timeDuration.end, - start: timeDuration.start, - }); + setTimeDuration(timeDuration); }, [] ); diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index f177cc7d12d..e9b5b207dfd 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -48,10 +48,7 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { if (savePref) { updatePreferences({ [TIME_DURATION]: timeDuration }); } - handleTimeDurationChange({ - end: timeDuration.end, - start: timeDuration.start, - }); + handleTimeDurationChange(timeDuration); }, [] ); diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 58faed98d7d..254b577ab91 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -288,8 +288,13 @@ export const getCloudPulseMetricRequest = ( props: MetricRequestProps ): CloudPulseMetricsRequest => { const { duration, entityIds, resources, widget } = props; + const preset = duration.preset; + return { - absolute_time_duration: widget.time_duration ? undefined : duration, + absolute_time_duration: + widget.time_duration || preset !== 'custom_range' + ? undefined + : { end: duration.end, start: duration.start }, aggregate_function: widget.aggregate_function, entity_ids: resources ? entityIds.map((id) => parseInt(id, 10)) @@ -297,7 +302,9 @@ export const getCloudPulseMetricRequest = ( filters: undefined, group_by: widget.group_by, metric: widget.metric, - relative_time_duration: duration ?? widget.time_duration, + relative_time_duration: duration ?? widget.time_duration + ? widget.time_duration + : getTimeDurationFromPreset(preset), time_granularity: widget.time_granularity.unit === 'Auto' ? undefined @@ -375,3 +382,34 @@ export const getAutocompleteWidgetStyles = (theme: Theme) => ({ width: '90px', }, }); + +/** + * + * @param preset preset for time duration to get the corresponding time duration object + * @returns time duration object for the label + */ +export const getTimeDurationFromPreset = ( + preset?: string +): TimeDuration | undefined => { + if (preset === '30minutes') { + return { unit: 'min', value: 30 }; + } + + if (preset === '24hours') { + return { unit: 'hr', value: 24 }; + } + + if (preset === '12hours') { + return { unit: 'hr', value: 12 }; + } + + if (preset === '7days') { + return { unit: 'days', value: 7 }; + } + + if (preset === '30days') { + return { unit: 'days', value: 30 }; + } + + return undefined; +}; diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 5787a36cf32..51a252c87f6 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -21,7 +21,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( const { defaultValue, handleStatsChange, savePreferences } = props; const { data: profile } = useProfile(); const timezone = profile?.timezone ?? DateTime.local().zoneName; - const defaultSelected: TimeDurationDate = defaultValue as TimeDurationDate; + const defaultSelected = defaultValue as TimeDurationDate; React.useEffect(() => { if (defaultSelected) { handleStatsChange(defaultSelected); From 6ba5ea54982116d54a28df035cd7e193f782afa9 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 15 Jan 2025 11:19:11 +0530 Subject: [PATCH 08/37] upcoming: [DI-20933] - Removed widget time duration from metric request --- .../src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 254b577ab91..b10b07882d1 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -292,7 +292,7 @@ export const getCloudPulseMetricRequest = ( return { absolute_time_duration: - widget.time_duration || preset !== 'custom_range' + preset !== 'custom_range' ? undefined : { end: duration.end, start: duration.start }, aggregate_function: widget.aggregate_function, @@ -302,9 +302,7 @@ export const getCloudPulseMetricRequest = ( filters: undefined, group_by: widget.group_by, metric: widget.metric, - relative_time_duration: duration ?? widget.time_duration - ? widget.time_duration - : getTimeDurationFromPreset(preset), + relative_time_duration: getTimeDurationFromPreset(preset), time_granularity: widget.time_granularity.unit === 'Auto' ? undefined From eb55e1747bf9b4393d787746a34f0d36063ad5ee Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 17:59:04 +0530 Subject: [PATCH 09/37] upcoming: [DI-20933] - Updated value to be saved in preferences --- .../Dashboard/CloudPulseDashboardWithFilters.tsx | 7 ++++++- .../features/CloudPulse/Overview/GlobalFilters.tsx | 11 +++++++++-- .../shared/CloudPulseDateTimeRangePicker.tsx | 8 ++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index bb72ac009c3..c51ae233de6 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -10,6 +10,7 @@ import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardF import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; import { CloudPulseDateTimeRangePicker, + convertToGmt, defaultTimeDuration, } from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseErrorPlaceholder } from '../shared/CloudPulseErrorPlaceholder'; @@ -79,7 +80,11 @@ export const CloudPulseDashboardWithFilters = React.memo( const handleTimeRangeChange = React.useCallback( (timeDuration: TimeDurationDate) => { - setTimeDuration(timeDuration); + setTimeDuration({ + ...timeDuration, + end: convertToGmt(timeDuration.end), + start: convertToGmt(timeDuration.start), + }); }, [] ); diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index e9b5b207dfd..0c3ee30325e 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -8,7 +8,10 @@ import Reload from 'src/assets/icons/refresh.svg'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; -import { CloudPulseDateTimeRangePicker } from '../shared/CloudPulseDateTimeRangePicker'; +import { + CloudPulseDateTimeRangePicker, + convertToGmt, +} from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseTooltip } from '../shared/CloudPulseTooltip'; import { DASHBOARD_ID, REFRESH, TIME_DURATION } from '../Utils/constants'; import { useAclpPreference } from '../Utils/UserPreference'; @@ -48,7 +51,11 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { if (savePref) { updatePreferences({ [TIME_DURATION]: timeDuration }); } - handleTimeDurationChange(timeDuration); + handleTimeDurationChange({ + ...timeDuration, + end: convertToGmt(timeDuration.end), + start: convertToGmt(timeDuration.start), + }); }, [] ); diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 51a252c87f6..64ea7ffd524 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -21,6 +21,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( const { defaultValue, handleStatsChange, savePreferences } = props; const { data: profile } = useProfile(); const timezone = profile?.timezone ?? DateTime.local().zoneName; + const defaultSelected = defaultValue as TimeDurationDate; React.useEffect(() => { if (defaultSelected) { @@ -28,9 +29,8 @@ export const CloudPulseDateTimeRangePicker = React.memo( } }, []); - const end = DateTime.fromISO(defaultSelected?.end, { zone: 'GMT' }); - const start = DateTime.fromISO(defaultSelected?.start, { zone: 'GMT' }); - + const end = DateTime.fromISO(defaultSelected?.end, { zone: timezone }); + const start = DateTime.fromISO(defaultSelected?.start, { zone: timezone }); return ( { }; }; -const convertToGmt = (date: string): string => { +export const convertToGmt = (date: string): string => { const dateObject = DateTime.fromISO(date); const updatedDate = dateObject.setZone('GMT'); return updatedDate.toISO()?.split('.')[0] + 'Z'; From 6477dfd9845af564c1f8a22caba3bbf31ed71fb8 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 18:05:09 +0530 Subject: [PATCH 10/37] upcoming: [DI-20933] - Updated ifelse ladder to switch statement --- .../CloudPulse/Utils/CloudPulseWidgetUtils.ts | 33 ++++++++----------- .../shared/CloudPulseDateTimeRangePicker.tsx | 1 - 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index b10b07882d1..e66fdb94825 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -389,25 +389,18 @@ export const getAutocompleteWidgetStyles = (theme: Theme) => ({ export const getTimeDurationFromPreset = ( preset?: string ): TimeDuration | undefined => { - if (preset === '30minutes') { - return { unit: 'min', value: 30 }; + switch (preset) { + case '30minutes': + return { unit: 'min', value: 30 }; + case '24hours': + return { unit: 'hr', value: 24 }; + case '12hours': + return { unit: 'hr', value: 12 }; + case '7days': + return { unit: 'days', value: 7 }; + case '30days': + return { unit: 'days', value: 30 }; + default: + return undefined; } - - if (preset === '24hours') { - return { unit: 'hr', value: 24 }; - } - - if (preset === '12hours') { - return { unit: 'hr', value: 12 }; - } - - if (preset === '7days') { - return { unit: 'days', value: 7 }; - } - - if (preset === '30days') { - return { unit: 'days', value: 30 }; - } - - return undefined; }; diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 64ea7ffd524..0bcb6d82d8f 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -21,7 +21,6 @@ export const CloudPulseDateTimeRangePicker = React.memo( const { defaultValue, handleStatsChange, savePreferences } = props; const { data: profile } = useProfile(); const timezone = profile?.timezone ?? DateTime.local().zoneName; - const defaultSelected = defaultValue as TimeDurationDate; React.useEffect(() => { if (defaultSelected) { From 6cd17898af01c9988830350f44db8e5c399b5af9 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 18:43:18 +0530 Subject: [PATCH 11/37] upcoming: [DI-20933] - Updated contextual view --- .../CloudPulseDashboardWithFilters.tsx | 69 +++++++++++-------- .../shared/CloudPulseDateTimeRangePicker.tsx | 36 ++++++---- 2 files changed, 63 insertions(+), 42 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index c51ae233de6..d75accd5ca2 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -14,6 +14,7 @@ import { defaultTimeDuration, } from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseErrorPlaceholder } from '../shared/CloudPulseErrorPlaceholder'; +import { CloudPulseTimeRangeSelect } from '../shared/CloudPulseTimeRangeSelect'; import { FILTER_CONFIG } from '../Utils/FilterConfig'; import { checkIfFilterBuilderNeeded, @@ -23,7 +24,7 @@ import { import { CloudPulseDashboard } from './CloudPulseDashboard'; import type { FilterData, FilterValueType } from './CloudPulseDashboardLanding'; -import type { TimeDurationDate } from '@linode/api-v4'; +import type { TimeDuration, TimeDurationDate } from '@linode/api-v4'; export interface CloudPulseDashboardWithFiltersProp { /** @@ -132,34 +133,44 @@ export const CloudPulseDashboardWithFilters = React.memo( padding: 0, }} > - - - + + + + + + + + + + + + + ({ + borderColor: theme.color.grey5, + margin: 0, + })} /> diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 0bcb6d82d8f..f3a3a5dccca 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -28,8 +28,29 @@ export const CloudPulseDateTimeRangePicker = React.memo( } }, []); + const handleDateChange = (params: { + end: null | string; + preset?: string | undefined; + start: null | string; + timezone?: null | string | undefined; + }) => { + const { end, preset, start } = params; + if (!end || !start || !preset) { + return; + } + handleStatsChange( + { + end: convertToGmt(end), + preset, + start: convertToGmt(start), + }, + savePreferences + ); + }; + const end = DateTime.fromISO(defaultSelected?.end, { zone: timezone }); const start = DateTime.fromISO(defaultSelected?.start, { zone: timezone }); + return ( { - if (!end || !start || !preset) { - return; - } - handleStatsChange( - { - end: convertToGmt(end), - preset, - start: convertToGmt(start), - }, - savePreferences - ); - }} presetsProps={{ defaultValue: defaultSelected?.preset, }} @@ -66,6 +74,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( }} disabledTimeZone enablePresets + onChange={handleDateChange} /> ); } @@ -79,6 +88,7 @@ export const defaultTimeDuration = (): TimeDurationDate => { return { end, + preset: '30minutes', start, }; }; From ea5228ac37ceadaa1559286cd4667bba5bd95847 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 18:46:42 +0530 Subject: [PATCH 12/37] upcoming: [DI-20933] - Moved common methods to utils file --- .../CloudPulseDashboardWithFilters.tsx | 9 ++++---- .../CloudPulse/Overview/GlobalFilters.tsx | 8 +++---- .../Utils/CloudPulseDateTimePickerUtils.ts | 22 +++++++++++++++++++ .../shared/CloudPulseDateTimeRangePicker.tsx | 21 ++---------------- 4 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index d75accd5ca2..9c33e14318e 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -8,13 +8,12 @@ import { useCloudPulseDashboardByIdQuery } from 'src/queries/cloudpulse/dashboar import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; +import { CloudPulseDateTimeRangePicker } from '../shared/CloudPulseDateTimeRangePicker'; +import { CloudPulseErrorPlaceholder } from '../shared/CloudPulseErrorPlaceholder'; import { - CloudPulseDateTimeRangePicker, convertToGmt, defaultTimeDuration, -} from '../shared/CloudPulseDateTimeRangePicker'; -import { CloudPulseErrorPlaceholder } from '../shared/CloudPulseErrorPlaceholder'; -import { CloudPulseTimeRangeSelect } from '../shared/CloudPulseTimeRangeSelect'; +} from '../Utils/CloudPulseDateTimePickerUtils'; import { FILTER_CONFIG } from '../Utils/FilterConfig'; import { checkIfFilterBuilderNeeded, @@ -24,7 +23,7 @@ import { import { CloudPulseDashboard } from './CloudPulseDashboard'; import type { FilterData, FilterValueType } from './CloudPulseDashboardLanding'; -import type { TimeDuration, TimeDurationDate } from '@linode/api-v4'; +import type { TimeDurationDate } from '@linode/api-v4'; export interface CloudPulseDashboardWithFiltersProp { /** diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index 0c3ee30325e..a411fe84384 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -1,6 +1,6 @@ import { Divider } from '@linode/ui'; -import { Grid } from '@mui/material'; import { IconButton, useTheme } from '@mui/material'; +import { Grid } from '@mui/material'; import { styled } from '@mui/material/styles'; import * as React from 'react'; @@ -8,11 +8,9 @@ import Reload from 'src/assets/icons/refresh.svg'; import { CloudPulseDashboardFilterBuilder } from '../shared/CloudPulseDashboardFilterBuilder'; import { CloudPulseDashboardSelect } from '../shared/CloudPulseDashboardSelect'; -import { - CloudPulseDateTimeRangePicker, - convertToGmt, -} from '../shared/CloudPulseDateTimeRangePicker'; +import { CloudPulseDateTimeRangePicker } from '../shared/CloudPulseDateTimeRangePicker'; import { CloudPulseTooltip } from '../shared/CloudPulseTooltip'; +import { convertToGmt } from '../Utils/CloudPulseDateTimePickerUtils'; import { DASHBOARD_ID, REFRESH, TIME_DURATION } from '../Utils/constants'; import { useAclpPreference } from '../Utils/UserPreference'; diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts new file mode 100644 index 00000000000..2844e0e21f0 --- /dev/null +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts @@ -0,0 +1,22 @@ +import { DateTime } from 'luxon'; + +import type { TimeDurationDate } from '@linode/api-v4'; + +export const defaultTimeDuration = (): TimeDurationDate => { + const date = DateTime.now().setZone('GMT'); + + const start = convertToGmt(date.minus({ minutes: 30 }).toISO() ?? ''); + const end = convertToGmt(date.toISO() ?? ''); + + return { + end, + preset: '30minutes', + start, + }; +}; + +export const convertToGmt = (date: string): string => { + const dateObject = DateTime.fromISO(date); + const updatedDate = dateObject.setZone('GMT'); + return updatedDate.toISO()?.split('.')[0] + 'Z'; +}; diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index f3a3a5dccca..fccc7b5386f 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -4,6 +4,8 @@ import React from 'react'; import { DateTimeRangePicker } from 'src/components/DatePicker/DateTimeRangePicker'; import { useProfile } from 'src/queries/profile/profile'; +import { convertToGmt } from '../Utils/CloudPulseDateTimePickerUtils'; + import type { FilterValue, TimeDurationDate } from '@linode/api-v4'; interface CloudPulseDateTimeRangePickerProps { @@ -79,22 +81,3 @@ export const CloudPulseDateTimeRangePicker = React.memo( ); } ); - -export const defaultTimeDuration = (): TimeDurationDate => { - const date = DateTime.now().setZone('GMT'); - - const start = convertToGmt(date.minus({ minutes: 30 }).toISO() ?? ''); - const end = convertToGmt(date.toISO() ?? ''); - - return { - end, - preset: '30minutes', - start, - }; -}; - -export const convertToGmt = (date: string): string => { - const dateObject = DateTime.fromISO(date); - const updatedDate = dateObject.setZone('GMT'); - return updatedDate.toISO()?.split('.')[0] + 'Z'; -}; From 799e43b5217336b56825a807b789338d26fdeca1 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 19:58:25 +0530 Subject: [PATCH 13/37] upcoming: [DI-20933] - Renamed type name --- packages/api-v4/src/cloudpulse/types.ts | 6 +++--- .../CloudPulse/Dashboard/CloudPulseDashboard.tsx | 4 ++-- .../Dashboard/CloudPulseDashboardLanding.tsx | 10 +++++----- .../Dashboard/CloudPulseDashboardWithFilters.tsx | 6 +++--- .../src/features/CloudPulse/Overview/GlobalFilters.tsx | 8 ++++---- .../CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts | 4 ++-- .../features/CloudPulse/Utils/CloudPulseWidgetUtils.ts | 4 ++-- .../src/features/CloudPulse/Utils/FilterBuilder.ts | 4 ++-- .../CloudPulse/Utils/ReusableDashboardFilterUtils.ts | 6 +++--- .../features/CloudPulse/Widget/CloudPulseWidget.tsx | 4 ++-- .../CloudPulse/Widget/CloudPulseWidgetRenderer.tsx | 4 ++-- .../shared/CloudPulseDateTimeRangePicker.tsx | 6 +++--- 12 files changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/api-v4/src/cloudpulse/types.ts b/packages/api-v4/src/cloudpulse/types.ts index 08a2670071e..9b574c2efe9 100644 --- a/packages/api-v4/src/cloudpulse/types.ts +++ b/packages/api-v4/src/cloudpulse/types.ts @@ -48,7 +48,7 @@ export interface TimeDuration { value: number; } -export interface TimeDurationDate { +export interface DateTimeWithPreset { end: string; start: string; preset?: string; @@ -86,7 +86,7 @@ export type FilterValue = | string[] | number[] | WidgetFilterValue - | TimeDurationDate + | DateTimeWithPreset | undefined; type WidgetFilterValue = { [key: string]: AclpWidget }; @@ -133,7 +133,7 @@ export interface CloudPulseMetricsRequest { aggregate_function: string; group_by: string; relative_time_duration: TimeDuration | undefined; - absolute_time_duration: TimeDurationDate | undefined; + absolute_time_duration: DateTimeWithPreset | undefined; time_granularity: TimeGranularity | undefined; entity_ids: number[]; } diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx index 392bfbeff05..497d4d21393 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx @@ -15,9 +15,9 @@ import { RenderWidgets } from '../Widget/CloudPulseWidgetRenderer'; import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget'; import type { + DateTimeWithPreset, JWETokenPayLoad, TimeDuration, - TimeDurationDate, } from '@linode/api-v4'; export interface DashboardProperties { @@ -34,7 +34,7 @@ export interface DashboardProperties { /** * time duration to fetch the metrics data in this widget */ - duration: TimeDurationDate; + duration: DateTimeWithPreset; /** * optional timestamp to pass as react query param to forcefully re-fetch data diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx index 8d880831c0e..a2d4574955e 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.tsx @@ -4,10 +4,10 @@ import * as React from 'react'; import { GlobalFilters } from '../Overview/GlobalFilters'; import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; -import { defaultTimeDuration } from '../shared/CloudPulseDateTimeRangePicker'; +import { defaultTimeDuration } from '../Utils/CloudPulseDateTimePickerUtils'; import { CloudPulseDashboardRenderer } from './CloudPulseDashboardRenderer'; -import type { Dashboard, TimeDurationDate } from '@linode/api-v4'; +import type { Dashboard, DateTimeWithPreset } from '@linode/api-v4'; export type FilterValueType = number | number[] | string | string[] | undefined; @@ -20,7 +20,7 @@ export interface DashboardProp { filterValue: { [key: string]: FilterValueType; }; - timeDuration?: TimeDurationDate; + timeDuration?: DateTimeWithPreset; } export const CloudPulseDashboardLanding = () => { @@ -29,7 +29,7 @@ export const CloudPulseDashboardLanding = () => { label: {}, }); - const [timeDuration, setTimeDuration] = React.useState( + const [timeDuration, setTimeDuration] = React.useState( defaultTimeDuration() ); @@ -69,7 +69,7 @@ export const CloudPulseDashboardLanding = () => { }); // clear the filter values on dashboard change }, []); const onTimeDurationChange = React.useCallback( - (timeDurationObj: TimeDurationDate) => { + (timeDurationObj: DateTimeWithPreset) => { setTimeDuration(timeDurationObj); }, [] diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index 9c33e14318e..7d956e530b6 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -23,7 +23,7 @@ import { import { CloudPulseDashboard } from './CloudPulseDashboard'; import type { FilterData, FilterValueType } from './CloudPulseDashboardLanding'; -import type { TimeDurationDate } from '@linode/api-v4'; +import type { DateTimeWithPreset } from '@linode/api-v4'; export interface CloudPulseDashboardWithFiltersProp { /** @@ -48,7 +48,7 @@ export const CloudPulseDashboardWithFilters = React.memo( label: {}, }); - const [timeDuration, setTimeDuration] = React.useState( + const [timeDuration, setTimeDuration] = React.useState( defaultTimeDuration() ); @@ -79,7 +79,7 @@ export const CloudPulseDashboardWithFilters = React.memo( ); const handleTimeRangeChange = React.useCallback( - (timeDuration: TimeDurationDate) => { + (timeDuration: DateTimeWithPreset) => { setTimeDuration({ ...timeDuration, end: convertToGmt(timeDuration.end), diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index a411fe84384..843ca9c4939 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -15,7 +15,7 @@ import { DASHBOARD_ID, REFRESH, TIME_DURATION } from '../Utils/constants'; import { useAclpPreference } from '../Utils/UserPreference'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; -import type { AclpConfig, Dashboard, TimeDurationDate } from '@linode/api-v4'; +import type { AclpConfig, Dashboard, DateTimeWithPreset } from '@linode/api-v4'; export interface GlobalFilterProperties { handleAnyFilterChange( @@ -24,7 +24,7 @@ export interface GlobalFilterProperties { labels: string[] ): void; handleDashboardChange(dashboard: Dashboard | undefined): void; - handleTimeDurationChange(timeDuration: TimeDurationDate): void; + handleTimeDurationChange(timeDuration: DateTimeWithPreset): void; handleToggleAppliedFilter(isVisible: boolean): void; } @@ -45,7 +45,7 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { >(); const handleTimeRangeChange = React.useCallback( - (timeDuration: TimeDurationDate, savePref: boolean = false) => { + (timeDuration: DateTimeWithPreset, savePref: boolean = false) => { if (savePref) { updatePreferences({ [TIME_DURATION]: timeDuration }); } @@ -114,7 +114,7 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { display="flex" gap={1} item - justifyContent={'end'} + justifyContent="end" md={8} sm={5} xs={12} diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts index 2844e0e21f0..c78d9ba9963 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts @@ -1,8 +1,8 @@ import { DateTime } from 'luxon'; -import type { TimeDurationDate } from '@linode/api-v4'; +import type { DateTimeWithPreset } from '@linode/api-v4'; -export const defaultTimeDuration = (): TimeDurationDate => { +export const defaultTimeDuration = (): DateTimeWithPreset => { const date = DateTime.now().setZone('GMT'); const start = convertToGmt(date.minus({ minutes: 30 }).toISO() ?? ''); diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index e66fdb94825..16d727fff6b 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -19,7 +19,7 @@ import type { CloudPulseMetricsRequest, CloudPulseMetricsResponse, TimeDuration, - TimeDurationDate, + DateTimeWithPreset, Widgets, } from '@linode/api-v4'; import type { Theme } from '@mui/material'; @@ -101,7 +101,7 @@ interface MetricRequestProps { /** * time duration for the metrics data */ - duration: TimeDurationDate; + duration: DateTimeWithPreset; /** * entity ids selected by user diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts index 2d164ee59d7..23c43df7f55 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts @@ -28,7 +28,7 @@ import type { Filter, Filters, TimeDuration, - TimeDurationDate, + DateTimeWithPreset, } from '@linode/api-v4'; interface CloudPulseFilterProperties { @@ -46,7 +46,7 @@ interface CloudPulseMandatoryFilterCheckProps { filterValue: { [key: string]: FilterValueType; }; - timeDuration: TimeDurationDate | undefined; + timeDuration: DateTimeWithPreset | undefined; } /** * This function helps in building the properties needed for tags selection component diff --git a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts index 4581bb93291..790d1083050 100644 --- a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.ts @@ -1,10 +1,10 @@ -import { defaultTimeDuration } from '../shared/CloudPulseDateTimeRangePicker'; +import { defaultTimeDuration } from './CloudPulseDateTimePickerUtils'; import { FILTER_CONFIG } from './FilterConfig'; import type { DashboardProperties } from '../Dashboard/CloudPulseDashboard'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget'; -import type { Dashboard, TimeDurationDate } from '@linode/api-v4'; +import type { Dashboard, DateTimeWithPreset } from '@linode/api-v4'; /** * This interface is used to get method parameters for this utility @@ -25,7 +25,7 @@ interface ReusableDashboardFilterUtilProps { /** * The selected time duration */ - timeDuration?: TimeDurationDate; + timeDuration?: DateTimeWithPreset; } /** diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx index 33c9ed444f3..0325ac78412 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx @@ -23,7 +23,7 @@ import { ZoomIcon } from './components/Zoomer'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; import type { CloudPulseResources } from '../shared/CloudPulseResourcesSelect'; -import type { TimeDurationDate, Widgets } from '@linode/api-v4'; +import type { DateTimeWithPreset, Widgets } from '@linode/api-v4'; import type { MetricDefinition, TimeDuration, @@ -61,7 +61,7 @@ export interface CloudPulseWidgetProperties { /** * time duration to fetch the metrics data in this widget */ - duration: TimeDurationDate; + duration: DateTimeWithPreset; /** * entity ids selected by user to show metrics for diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx index b839fb9a819..9ac52602ed4 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx @@ -23,14 +23,14 @@ import type { MetricDefinition, ResourcePage, TimeDuration, - TimeDurationDate, + DateTimeWithPreset, Widgets, } from '@linode/api-v4'; interface WidgetProps { additionalFilters?: CloudPulseMetricsAdditionalFilters[]; dashboard?: Dashboard | undefined; - duration: TimeDurationDate; + duration: DateTimeWithPreset; isJweTokenFetching: boolean; jweToken?: JWEToken | undefined; manualRefreshTimeStamp?: number; diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index fccc7b5386f..5de166cd959 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -6,13 +6,13 @@ import { useProfile } from 'src/queries/profile/profile'; import { convertToGmt } from '../Utils/CloudPulseDateTimePickerUtils'; -import type { FilterValue, TimeDurationDate } from '@linode/api-v4'; +import type { DateTimeWithPreset, FilterValue } from '@linode/api-v4'; interface CloudPulseDateTimeRangePickerProps { defaultValue?: Partial; handleStatsChange: ( - timeDuration: TimeDurationDate, + timeDuration: DateTimeWithPreset, savePref?: boolean ) => void; savePreferences?: boolean; @@ -23,7 +23,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( const { defaultValue, handleStatsChange, savePreferences } = props; const { data: profile } = useProfile(); const timezone = profile?.timezone ?? DateTime.local().zoneName; - const defaultSelected = defaultValue as TimeDurationDate; + const defaultSelected = defaultValue as DateTimeWithPreset; React.useEffect(() => { if (defaultSelected) { handleStatsChange(defaultSelected); From e49cc123603e47276e2e1afcc11f9343395f32c5 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 16 Jan 2025 20:12:25 +0530 Subject: [PATCH 14/37] upcoming: [DI-20933] - Renamed disabledTimeZone to disableTimeZone --- .../components/DatePicker/DateTimePicker.tsx | 9 ++++---- .../DatePicker/DateTimeRangePicker.tsx | 21 +++++++++---------- .../components/DatePicker/TimeZoneSelect.tsx | 4 ++-- .../shared/CloudPulseDateTimeRangePicker.tsx | 2 +- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimePicker.tsx b/packages/manager/src/components/DatePicker/DateTimePicker.tsx index 1cee4f53b99..9e73fe2ef32 100644 --- a/packages/manager/src/components/DatePicker/DateTimePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimePicker.tsx @@ -21,7 +21,7 @@ import type { DateTime } from 'luxon'; export interface DateTimePickerProps { /** Additional props for the DateCalendar */ dateCalendarProps?: Partial>; - disabledTimeZone?: boolean; + disableTimeZone?: boolean; /** Error text for the date picker field */ errorText?: string; /** Format for displaying the date-time */ @@ -64,7 +64,7 @@ export interface DateTimePickerProps { export const DateTimePicker = ({ dateCalendarProps = {}, - disabledTimeZone = false, + disableTimeZone = false, errorText = '', format = 'yyyy-MM-dd HH:mm', label = 'Select Date and Time', @@ -235,8 +235,7 @@ export const DateTimePicker = ({ { const { - disabledTimeZone = false, + disableTimeZone = false, enablePresets = false, @@ -128,13 +133,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { const [endDateTime, setEndDateTime] = useState( endDateTimeValue ); - const [presetValue, setPresetValue] = useState< - | { - label: string; - value: string; - } - | undefined - >( + const [presetValue, setPresetValue] = useState( presetsOptions.find((option) => option.value === presetsDefaultValue) ?? presetsOptions[0] ); @@ -279,7 +278,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { onChange: (value) => setStartTimeZone(value), value: startTimeZone, }} - disabledTimeZone={disabledTimeZone} + disableTimeZone={disableTimeZone} errorText={startDateError ?? undefined} format={format} label={startLabel} @@ -293,7 +292,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { timeZoneSelectProps={{ value: startTimeZone, }} - disabledTimeZone={disabledTimeZone} + disableTimeZone={disableTimeZone} format={format} label={endLabel} minDate={startDateTime || undefined} diff --git a/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx b/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx index f4bd68c97a3..6e8f5e5b658 100644 --- a/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx +++ b/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx @@ -7,7 +7,7 @@ import { timezones } from 'src/assets/timezones/timezones'; type Timezone = typeof timezones[number]; interface TimeZoneSelectProps { - disabled?: boolean; + disable?: boolean; errorText?: string; label?: string; noMarginTop?: boolean; @@ -39,7 +39,7 @@ const getTimezoneOptions = () => { const timezoneOptions = getTimezoneOptions(); export const TimeZoneSelect = ({ - disabled = false, + disable: disabled = false, errorText, label = 'Timezone', noMarginTop = false, diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 5de166cd959..590e55a7bb9 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -74,7 +74,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( sx={{ minWidth: '226px', }} - disabledTimeZone + disableTimeZone enablePresets onChange={handleDateChange} /> From 83569d452abd6700120d5d7218475e98c5c0e803 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:01:36 +0530 Subject: [PATCH 15/37] upcoming: [DI-20933] - Code refactoring --- .../components/DatePicker/DateTimePicker.tsx | 6 +++--- .../DatePicker/DateTimeRangePicker.tsx | 21 ++++++++++--------- .../components/DatePicker/TimeZoneSelect.tsx | 4 ++-- .../shared/CloudPulseDateTimeRangePicker.tsx | 2 +- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimePicker.tsx b/packages/manager/src/components/DatePicker/DateTimePicker.tsx index 9e73fe2ef32..ab8f093908e 100644 --- a/packages/manager/src/components/DatePicker/DateTimePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimePicker.tsx @@ -21,7 +21,7 @@ import type { DateTime } from 'luxon'; export interface DateTimePickerProps { /** Additional props for the DateCalendar */ dateCalendarProps?: Partial>; - disableTimeZone?: boolean; + disabledTimeZone?: boolean; /** Error text for the date picker field */ errorText?: string; /** Format for displaying the date-time */ @@ -64,7 +64,7 @@ export interface DateTimePickerProps { export const DateTimePicker = ({ dateCalendarProps = {}, - disableTimeZone = false, + disabledTimeZone = false, errorText = '', format = 'yyyy-MM-dd HH:mm', label = 'Select Date and Time', @@ -277,7 +277,7 @@ export const DateTimePicker = ({ {showTimeZone && ( { const { - disableTimeZone = false, + disabledTimeZone = false, enablePresets = false, @@ -133,7 +128,13 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { const [endDateTime, setEndDateTime] = useState( endDateTimeValue ); - const [presetValue, setPresetValue] = useState( + const [presetValue, setPresetValue] = useState< + | { + label: string; + value: string; + } + | undefined + >( presetsOptions.find((option) => option.value === presetsDefaultValue) ?? presetsOptions[0] ); @@ -278,7 +279,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { onChange: (value) => setStartTimeZone(value), value: startTimeZone, }} - disableTimeZone={disableTimeZone} + disabledTimeZone={disabledTimeZone} errorText={startDateError ?? undefined} format={format} label={startLabel} @@ -292,7 +293,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { timeZoneSelectProps={{ value: startTimeZone, }} - disableTimeZone={disableTimeZone} + disabledTimeZone={disabledTimeZone} format={format} label={endLabel} minDate={startDateTime || undefined} diff --git a/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx b/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx index 6e8f5e5b658..f4bd68c97a3 100644 --- a/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx +++ b/packages/manager/src/components/DatePicker/TimeZoneSelect.tsx @@ -7,7 +7,7 @@ import { timezones } from 'src/assets/timezones/timezones'; type Timezone = typeof timezones[number]; interface TimeZoneSelectProps { - disable?: boolean; + disabled?: boolean; errorText?: string; label?: string; noMarginTop?: boolean; @@ -39,7 +39,7 @@ const getTimezoneOptions = () => { const timezoneOptions = getTimezoneOptions(); export const TimeZoneSelect = ({ - disable: disabled = false, + disabled = false, errorText, label = 'Timezone', noMarginTop = false, diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 590e55a7bb9..5de166cd959 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -74,7 +74,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( sx={{ minWidth: '226px', }} - disableTimeZone + disabledTimeZone enablePresets onChange={handleDateChange} /> From e3d039d6aa9838d00dd9720125ba569e72b9bfec Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:06:21 +0530 Subject: [PATCH 16/37] upcoming: [DI-20933] - Removed unused variabled --- .../features/CloudPulse/Dashboard/CloudPulseDashboard.tsx | 6 +----- .../src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts | 2 +- .../manager/src/features/CloudPulse/Utils/FilterBuilder.ts | 4 ++-- .../src/features/CloudPulse/Widget/CloudPulseWidget.tsx | 6 +----- .../features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx | 3 +-- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx index 497d4d21393..9a77d27fb44 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboard.tsx @@ -14,11 +14,7 @@ import { useAclpPreference } from '../Utils/UserPreference'; import { RenderWidgets } from '../Widget/CloudPulseWidgetRenderer'; import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget'; -import type { - DateTimeWithPreset, - JWETokenPayLoad, - TimeDuration, -} from '@linode/api-v4'; +import type { DateTimeWithPreset, JWETokenPayLoad } from '@linode/api-v4'; export interface DashboardProperties { /** diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 16d727fff6b..9a3f6c54e18 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -18,8 +18,8 @@ import type { CloudPulseMetricsList, CloudPulseMetricsRequest, CloudPulseMetricsResponse, - TimeDuration, DateTimeWithPreset, + TimeDuration, Widgets, } from '@linode/api-v4'; import type { Theme } from '@mui/material'; diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts index 23c43df7f55..122135e4102 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts @@ -25,10 +25,10 @@ import type { CloudPulseServiceTypeFilters } from './models'; import type { AclpConfig, Dashboard, + DateTimeWithPreset, Filter, Filters, TimeDuration, - DateTimeWithPreset, } from '@linode/api-v4'; interface CloudPulseFilterProperties { @@ -66,8 +66,8 @@ export const getTagsProperties = ( return { defaultValue: preferences?.[TAGS], handleTagsChange, - optional: props.config.configuration.isOptional, label, + optional: props.config.configuration.isOptional, placeholder, resourceType: dashboard.service_type, savePreferences: !isServiceAnalyticsIntegration, diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx index 0325ac78412..20631af0a1f 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.tsx @@ -24,11 +24,7 @@ import { ZoomIcon } from './components/Zoomer'; import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; import type { CloudPulseResources } from '../shared/CloudPulseResourcesSelect'; import type { DateTimeWithPreset, Widgets } from '@linode/api-v4'; -import type { - MetricDefinition, - TimeDuration, - TimeGranularity, -} from '@linode/api-v4'; +import type { MetricDefinition, TimeGranularity } from '@linode/api-v4'; import type { DataSet } from 'src/components/AreaChart/AreaChart'; import type { AreaProps, diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx index 9ac52602ed4..eb429ed4a0f 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidgetRenderer.tsx @@ -19,11 +19,10 @@ import type { import type { AclpConfig, Dashboard, + DateTimeWithPreset, JWEToken, MetricDefinition, ResourcePage, - TimeDuration, - DateTimeWithPreset, Widgets, } from '@linode/api-v4'; From 51110e332e5022e3bbb9c9be73551fe15727ea7a Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:42:53 +0530 Subject: [PATCH 17/37] upcoming: [DI-20933] - Updatef failing test cases --- .../CloudPulse/Utils/FilterBuilder.test.ts | 18 +++++++++++++---- .../ReusableDashboardFilterUtils.test.ts | 20 +++++++++++++------ .../Widget/CloudPulseWidget.test.tsx | 7 ++++++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts index 2152fa05488..37940ce169e 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts @@ -1,8 +1,9 @@ +import { DateTime } from 'luxon'; + import { dashboardFactory } from 'src/factories'; import { databaseQueries } from 'src/queries/databases/databases'; import { RESOURCES } from './constants'; -import { deepEqual, getFilters } from './FilterBuilder'; import { buildXFilter, checkIfAllMandatoryFiltersAreSelected, @@ -14,6 +15,7 @@ import { getResourcesProperties, getTimeDurationProperties, } from './FilterBuilder'; +import { deepEqual, getFilters } from './FilterBuilder'; import { FILTER_CONFIG } from './FilterConfig'; import { CloudPulseSelectTypes } from './models'; @@ -198,11 +200,15 @@ it('test checkIfAllMandatoryFiltersAreSelected method', () => { ); expect(resourceSelectionConfig).toBeDefined(); - + const now = DateTime.now(); let result = checkIfAllMandatoryFiltersAreSelected({ dashboard: mockDashboard, filterValue: { region: 'us-east', resource_id: ['1', '2'] }, - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { + end: now.toISO(), + preset: '30minutes', + start: now.minus({ minutes: 30 }).toISO(), + }, }); expect(result).toEqual(true); @@ -210,7 +216,11 @@ it('test checkIfAllMandatoryFiltersAreSelected method', () => { result = checkIfAllMandatoryFiltersAreSelected({ dashboard: mockDashboard, filterValue: { region: 'us-east' }, - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { + end: now.toISO(), + preset: '30minutes', + start: now.minus({ minutes: 30 }).toISO(), + }, }); expect(result).toEqual(false); diff --git a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts index 56b4e1e060f..fc631769c47 100644 --- a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts @@ -1,3 +1,5 @@ +import { DateTime } from 'luxon'; + import { dashboardFactory } from 'src/factories'; import { @@ -9,7 +11,9 @@ import { } from './ReusableDashboardFilterUtils'; const mockDashboard = dashboardFactory.build(); - +const end = DateTime.now(); +const start = end.minus({ minutes: 30 }); +const preset = '30minutes'; it('test getDashboardProperties method', () => { const result = getDashboardProperties({ dashboardObj: mockDashboard, @@ -29,12 +33,16 @@ it('test checkMandatoryFiltersSelected method for time duration and resource', ( resource: 0, }); expect(result).toBe(false); - + const now = DateTime.now(); result = checkMandatoryFiltersSelected({ dashboardObj: mockDashboard, filterValue: { region: 'us-east' }, resource: 1, - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { + end: end.toISO(), + preset, + start: start.toISO(), + }, }); expect(result).toBe(true); @@ -52,7 +60,7 @@ it('test checkMandatoryFiltersSelected method for time duration and resource', ( dashboardObj: mockDashboard, filterValue: { region: 'us-east' }, resource: 0, // here resource is 0, so it should return false - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { end: end.toISO(), preset, start: start.toISO() }, }); expect(result).toBe(false); @@ -64,7 +72,7 @@ it('test checkMandatoryFiltersSelected method for role', () => { dashboardObj: { ...mockDashboard, service_type: 'dbaas' }, filterValue: { region: 'us-east' }, // here role is missing resource: 1, - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { end: end.toISO(), preset, start: start.toISO() }, }); expect(result).toBe(false); @@ -73,7 +81,7 @@ it('test checkMandatoryFiltersSelected method for role', () => { dashboardObj: { ...mockDashboard, service_type: 'dbaas' }, filterValue: { node_type: 'primary', region: 'us-east' }, resource: 1, - timeDuration: { unit: 'min', value: 30 }, + timeDuration: { end: end.toISO(), preset, start: start.toISO() }, }); expect(result).toBe(true); diff --git a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.test.tsx b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.test.tsx index 476ad9997ac..faac2e496ae 100644 --- a/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.test.tsx +++ b/packages/manager/src/features/CloudPulse/Widget/CloudPulseWidget.test.tsx @@ -1,4 +1,5 @@ import userEvent from '@testing-library/user-event'; +import { DateTime } from 'luxon'; import React from 'react'; import { @@ -25,7 +26,11 @@ const props: CloudPulseWidgetProperties = { scrape_interval: '2m', unit: 'percent', }, - duration: { unit: 'min', value: 30 }, + duration: { + end: DateTime.now().toISO(), + preset: '30minutes', + start: DateTime.now().minus({ minutes: 30 }).toISO(), + }, entityIds: ['1', '2'], isJweTokenFetching: false, resources: [ From 38bff82d834637b0a3480a8618bcc87e548b97bc Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:46:48 +0530 Subject: [PATCH 18/37] upcoming: [DI-20931] - Updated logic to retain date time value for previous preset selected --- .../manager/src/components/DatePicker/DateTimeRangePicker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 8e42dbcd5fd..8cc40e5a494 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -194,8 +194,8 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { newEndDateTime = lastMonth.endOf('month'); break; case 'custom_range': - newStartDateTime = null; - newEndDateTime = null; + newStartDateTime = startDateTime; + newEndDateTime = endDateTime; break; default: return; From ef53c8c4fa1c76eeb0aad2215ab309596bfc3a7e Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:50:31 +0530 Subject: [PATCH 19/37] upcoming: [DI-20931] - Updated metrics call logic --- .../src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 9a3f6c54e18..afe5b238137 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -292,7 +292,9 @@ export const getCloudPulseMetricRequest = ( return { absolute_time_duration: - preset !== 'custom_range' + preset !== 'custom_range' && + preset !== 'this_month' && + preset !== 'last_month' ? undefined : { end: duration.end, start: duration.start }, aggregate_function: widget.aggregate_function, From e93ac515253434b4cf8c7b8082e26a96dd63bedf Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 18:55:09 +0530 Subject: [PATCH 20/37] upcoming: [DI-20933] - Removed unused variable --- .../CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts index fc631769c47..cc933eae00c 100644 --- a/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/ReusableDashboardFilterUtils.test.ts @@ -33,7 +33,6 @@ it('test checkMandatoryFiltersSelected method for time duration and resource', ( resource: 0, }); expect(result).toBe(false); - const now = DateTime.now(); result = checkMandatoryFiltersSelected({ dashboardObj: mockDashboard, filterValue: { region: 'us-east' }, From 4f17486427969191e41b08514699b3283cf75593 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 21 Jan 2025 19:02:54 +0530 Subject: [PATCH 21/37] upcoming: [DI-20933] - Added 1 hour in preset --- .../src/components/DatePicker/DateTimeRangePicker.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 8cc40e5a494..06d2cf1a103 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -72,6 +72,7 @@ export interface DateTimeRangePickerProps { } type DatePresetType = + | '1hour' | '7days' | '12hours' | '24hours' @@ -83,6 +84,7 @@ type DatePresetType = const presetsOptions: { label: string; value: DatePresetType }[] = [ { label: 'Last 30 Minutes', value: '30minutes' }, + { label: 'Last 1 Hour', value: '1hour' }, { label: 'Last 12 Hours', value: '12hours' }, { label: 'Last 24 Hours', value: '24hours' }, { label: 'Last 7 Days', value: '7days' }, @@ -172,6 +174,8 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { case '30minutes': newStartDateTime = now.minus({ minutes: 30 }); break; + case '1hour': + newStartDateTime = now.minus({ hours: 1 }); case '12hours': newStartDateTime = now.minus({ hours: 12 }); break; @@ -193,6 +197,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { newStartDateTime = lastMonth.startOf('month'); newEndDateTime = lastMonth.endOf('month'); break; + case 'custom_range': newStartDateTime = startDateTime; newEndDateTime = endDateTime; From 7556662aa31fe8fbd9ed59c8ada745d7d98c8d1d Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 22 Jan 2025 10:57:29 +0530 Subject: [PATCH 22/37] upcoming: [DI-20933] - bug fix for 1 hour preset --- .../manager/src/components/DatePicker/DateTimeRangePicker.tsx | 1 + .../src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 06d2cf1a103..f680c6e79e0 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -176,6 +176,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { break; case '1hour': newStartDateTime = now.minus({ hours: 1 }); + break; case '12hours': newStartDateTime = now.minus({ hours: 12 }); break; diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index afe5b238137..a53c42e4c9a 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -394,6 +394,8 @@ export const getTimeDurationFromPreset = ( switch (preset) { case '30minutes': return { unit: 'min', value: 30 }; + case '1hour': + return { unit: 'hr', value: 1 }; case '24hours': return { unit: 'hr', value: 24 }; case '12hours': From ed19fe9f19b258b1b72b4daae74cf9377575c9e7 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 22 Jan 2025 10:59:11 +0530 Subject: [PATCH 23/37] upcoming: [DI-20933] - Updated failing test cases --- .../DatabaseDetail/DatabaseMonitor/DatabaseMonitor.test.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseMonitor/DatabaseMonitor.test.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseMonitor/DatabaseMonitor.test.tsx index ec6c413ebb5..33e546b35cc 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseMonitor/DatabaseMonitor.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseMonitor/DatabaseMonitor.test.tsx @@ -1,7 +1,9 @@ import { waitForElementToBeRemoved } from '@testing-library/react'; import * as React from 'react'; + import { databaseFactory } from 'src/factories'; import { mockMatchMedia, renderWithTheme } from 'src/utilities/testHelpers'; + import { DatabaseMonitor } from './DatabaseMonitor'; const loadingTestId = 'circle-progress'; @@ -24,6 +26,6 @@ describe('database monitor', () => { ); expect(getByTestId(loadingTestId)).toBeInTheDocument(); await waitForElementToBeRemoved(getByTestId(loadingTestId)); - expect(getByTestId('cloudpulse-time-duration')).toBeInTheDocument(); + expect(getByTestId('preset-select')).toBeInTheDocument(); }); }); From 8202028d3d77f3ea78d12d34d8567080f01393be Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 22 Jan 2025 16:00:41 +0530 Subject: [PATCH 24/37] upcoming: [DI-20932] - Made input readonly for time range picker --- packages/manager/src/components/DatePicker/DateTimePicker.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/manager/src/components/DatePicker/DateTimePicker.tsx b/packages/manager/src/components/DatePicker/DateTimePicker.tsx index ab8f093908e..71a7b005a6e 100644 --- a/packages/manager/src/components/DatePicker/DateTimePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimePicker.tsx @@ -248,6 +248,9 @@ export const DateTimePicker = ({ padding: 0, }), }, + field: { + readOnly: true, + }, layout: { sx: (theme: Theme) => ({ '& .MuiPickersLayout-contentWrapper': { From b7525a69f52adb24edb32efaa5c22f0f3fb86872 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 22 Jan 2025 16:30:31 +0530 Subject: [PATCH 25/37] upcoming: [DI-20932] - Added qa id --- packages/manager/src/components/DatePicker/DateTimePicker.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/manager/src/components/DatePicker/DateTimePicker.tsx b/packages/manager/src/components/DatePicker/DateTimePicker.tsx index 71a7b005a6e..1ef8119aa69 100644 --- a/packages/manager/src/components/DatePicker/DateTimePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimePicker.tsx @@ -271,6 +271,7 @@ export const DateTimePicker = ({ }, textField: TimePickerFieldProps, }} + data-qa-time="time-picker" onChange={handleTimeChange} slots={{ textField: TextField }} value={selectedDateTime || null} From fa27b71d463773eb59b3de8f3534e60df5132cd3 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Wed, 22 Jan 2025 18:19:21 +0530 Subject: [PATCH 26/37] upcoiming: [DI-20931] - Added default start & end date for undefined default value --- .../src/components/DatePicker/DateTimeRangePicker.tsx | 6 ++---- .../CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx | 8 ++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index f680c6e79e0..207f746b294 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -123,12 +123,11 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { } = {}, sx, } = props; - const [startDateTime, setStartDateTime] = useState( - startDateTimeValue + startDateTimeValue ?? DateTime.now().minus({ minutes: 30 }) ); const [endDateTime, setEndDateTime] = useState( - endDateTimeValue + endDateTimeValue ?? DateTime.now() ); const [presetValue, setPresetValue] = useState< | { @@ -253,7 +252,6 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { }); } }; - return ( {showPresets ? ( diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 5de166cd959..1226587b939 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -50,8 +50,12 @@ export const CloudPulseDateTimeRangePicker = React.memo( ); }; - const end = DateTime.fromISO(defaultSelected?.end, { zone: timezone }); - const start = DateTime.fromISO(defaultSelected?.start, { zone: timezone }); + const end = defaultSelected?.start + ? DateTime.fromISO(defaultSelected?.end, { zone: timezone }) + : undefined; + const start = defaultSelected?.end + ? DateTime.fromISO(defaultSelected?.start, { zone: timezone }) + : end; return ( Date: Fri, 24 Jan 2025 17:16:44 +0530 Subject: [PATCH 27/37] upcoming: [DI-23187] - Changed end date for this month preset option --- .../DatePicker/DateTimeRangePicker.test.tsx | 58 +++++++++++++------ .../DatePicker/DateTimeRangePicker.tsx | 1 - 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx index 1011c755345..2404349c0a2 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx @@ -52,22 +52,24 @@ describe('DateTimeRangePicker Component', () => { vi.setSystemTime(vi.getRealSystemTime()); renderWithTheme(); - + const now = DateTime.now(); // Open start date picker await userEvent.click(screen.getByLabelText('Start Date and Time')); await userEvent.click(screen.getByRole('gridcell', { name: '10' })); await userEvent.click(screen.getByRole('button', { name: 'Apply' })); - - const expectedStartTime = DateTime.fromObject({ - day: 10, - month: DateTime.now().month, - year: DateTime.now().year, - }).toISO(); + const expectedStartTime = DateTime.now() + .set({ + day: 10, + month: DateTime.now().month, + year: DateTime.now().year, + }) + .minus({ minutes: 30 }) + .toISO(); // Check if the onChange function is called with the expected value expect(onChangeMock).toHaveBeenCalledWith({ - end: null, + end: now.toISO(), preset: 'custom_range', start: expectedStartTime, timeZone: null, @@ -97,17 +99,21 @@ describe('DateTimeRangePicker Component', () => { presetsProps: { ...Props.presetsProps }, }; renderWithTheme(); - + const now = DateTime.now(); // Set the end date-time to the 15th const endDateField = screen.getByLabelText('End Date and Time'); await userEvent.click(endDateField); - await userEvent.click(screen.getByRole('gridcell', { name: '15' })); + await userEvent.click( + screen.getByRole('gridcell', { name: now.day.toString() }) + ); await userEvent.click(screen.getByRole('button', { name: 'Apply' })); // Set the start date-time to the 10th (which is earlier than the end date-time) const startDateField = screen.getByLabelText('Start Date and Time'); await userEvent.click(startDateField); - await userEvent.click(screen.getByRole('gridcell', { name: '20' })); // Invalid date + await userEvent.click( + screen.getByRole('gridcell', { name: (now.day + 1).toString() }) + ); // Invalid date await userEvent.click(screen.getByRole('button', { name: 'Apply' })); // Confirm the error message is displayed @@ -133,17 +139,21 @@ describe('DateTimeRangePicker Component', () => { }, }; renderWithTheme(); - + const now = DateTime.now(); // Set the end date-time to the 15th const endDateField = screen.getByLabelText('End Date and Time'); await userEvent.click(endDateField); - await userEvent.click(screen.getByRole('gridcell', { name: '15' })); + await userEvent.click( + screen.getByRole('gridcell', { name: now.day.toString() }) + ); await userEvent.click(screen.getByRole('button', { name: 'Apply' })); // Set the start date-time to the 20th (which is earlier than the end date-time) const startDateField = screen.getByLabelText('Start Date and Time'); await userEvent.click(startDateField); - await userEvent.click(screen.getByRole('gridcell', { name: '20' })); // Invalid date + await userEvent.click( + screen.getByRole('gridcell', { name: (now.day + 1).toString() }) + ); // Invalid date await userEvent.click(screen.getByRole('button', { name: 'Apply' })); // Confirm the custom error message is displayed for the start date @@ -244,7 +254,7 @@ describe('DateTimeRangePicker Component', () => { // Expected start and end dates in ISO format const expectedStartDateISO = DateTime.now().startOf('month').toISO(); - const expectedEndDateISO = DateTime.now().endOf('month').toISO(); + const expectedEndDateISO = DateTime.now().toISO(); // Verify that onChange is called with the correct date range expect(onChangeMock).toHaveBeenCalledWith({ @@ -287,8 +297,14 @@ describe('DateTimeRangePicker Component', () => { ).not.toBeInTheDocument(); }); - it('should display the date range fields with empty values when the "Custom Range" preset is selected', async () => { - renderWithTheme(); + it('should display the date range fields with 30 min difference values when the "Custom Range" preset is selected', async () => { + const timezone = 'Asia/Kolkata'; + renderWithTheme( + + ); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); @@ -297,14 +313,18 @@ describe('DateTimeRangePicker Component', () => { // Select the "Custom Range" option const customRange = screen.getByText('Custom'); await userEvent.click(customRange); + const format = 'yyyy-MM-dd HH:mm'; + const now = DateTime.now(); + const start = now.minus({ minutes: 30 }); // Verify the input fields display the correct values expect( screen.getByRole('textbox', { name: 'Start Date and Time' }) - ).toHaveValue(''); + ).toHaveValue(`${start.toFormat(format)} (${timezone})`); + expect( screen.getByRole('textbox', { name: 'End Date and Time' }) - ).toHaveValue(''); + ).toHaveValue(`${now.toFormat(format)} (${timezone})`); expect(screen.getByRole('button', { name: 'Presets' })).toBeInTheDocument(); // Set start date-time to the 15th diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 207f746b294..17b20e9250c 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -190,7 +190,6 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { break; case 'this_month': newStartDateTime = now.startOf('month'); - newEndDateTime = now.endOf('month'); break; case 'last_month': const lastMonth = now.minus({ months: 1 }); From 1010f5892f866596339e21878e44ba32760fe00c Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 24 Jan 2025 18:25:34 +0530 Subject: [PATCH 28/37] upcoming: [DI-23186] - Changed format of date in date picker --- .../CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx index 1226587b939..5244c8206cf 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDateTimeRangePicker.tsx @@ -4,8 +4,6 @@ import React from 'react'; import { DateTimeRangePicker } from 'src/components/DatePicker/DateTimeRangePicker'; import { useProfile } from 'src/queries/profile/profile'; -import { convertToGmt } from '../Utils/CloudPulseDateTimePickerUtils'; - import type { DateTimeWithPreset, FilterValue } from '@linode/api-v4'; interface CloudPulseDateTimeRangePickerProps { @@ -42,9 +40,9 @@ export const CloudPulseDateTimeRangePicker = React.memo( } handleStatsChange( { - end: convertToGmt(end), + end, preset, - start: convertToGmt(start), + start, }, savePreferences ); @@ -80,6 +78,7 @@ export const CloudPulseDateTimeRangePicker = React.memo( }} disabledTimeZone enablePresets + format="yyyy-MM-dd hh:mm a" onChange={handleDateChange} /> ); From 53c0d7620e916b4d0dcb70b1ae672fafb79c0e84 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 27 Jan 2025 13:33:37 +0530 Subject: [PATCH 29/37] upcoming: [DI-20931] - Set 0 seconds to selected date --- .../manager/src/components/DatePicker/DateTimeRangePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 17b20e9250c..222bfd34358 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -165,7 +165,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { }; const handlePresetSelection = (value: DatePresetType) => { - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); let newStartDateTime: DateTime | null = null; let newEndDateTime: DateTime | null = now; From b7e5f5d57c28ed5e24a6853da09987603d6109e2 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 27 Jan 2025 14:47:46 +0530 Subject: [PATCH 30/37] upcoming: [DI-20931] - Set seconds value to 0 in default value --- .../features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts index c78d9ba9963..033d602d9af 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseDateTimePickerUtils.ts @@ -3,7 +3,7 @@ import { DateTime } from 'luxon'; import type { DateTimeWithPreset } from '@linode/api-v4'; export const defaultTimeDuration = (): DateTimeWithPreset => { - const date = DateTime.now().setZone('GMT'); + const date = DateTime.now().set({ second: 0 }).setZone('GMT'); const start = convertToGmt(date.minus({ minutes: 30 }).toISO() ?? ''); const end = convertToGmt(date.toISO() ?? ''); From b731e141b654cf731a493a7601b875ec04ca26e6 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 27 Jan 2025 14:49:55 +0530 Subject: [PATCH 31/37] upcoming: [DI-20931] - Set seconds value to 0 in default value --- .../src/components/DatePicker/DateTimeRangePicker.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 222bfd34358..b0f72b82966 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -124,10 +124,11 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { sx, } = props; const [startDateTime, setStartDateTime] = useState( - startDateTimeValue ?? DateTime.now().minus({ minutes: 30 }) + startDateTimeValue ?? + DateTime.now().set({ second: 0 }).minus({ minutes: 30 }) ); const [endDateTime, setEndDateTime] = useState( - endDateTimeValue ?? DateTime.now() + endDateTimeValue ?? DateTime.now().set({ second: 0 }) ); const [presetValue, setPresetValue] = useState< | { From eff2b6199df8c177d91649e1a480d270c30fa3ba Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 27 Jan 2025 15:43:19 +0530 Subject: [PATCH 32/37] upcoming: [DI-20931] - Updated test cases --- .../DatePicker/DateTimeRangePicker.test.tsx | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx index 2404349c0a2..dacd26cb67b 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx @@ -52,17 +52,17 @@ describe('DateTimeRangePicker Component', () => { vi.setSystemTime(vi.getRealSystemTime()); renderWithTheme(); - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); // Open start date picker await userEvent.click(screen.getByLabelText('Start Date and Time')); await userEvent.click(screen.getByRole('gridcell', { name: '10' })); await userEvent.click(screen.getByRole('button', { name: 'Apply' })); - const expectedStartTime = DateTime.now() + const expectedStartTime = now .set({ day: 10, - month: DateTime.now().month, - year: DateTime.now().year, + month: now.month, + year: now.year, }) .minus({ minutes: 30 }) .toISO(); @@ -99,7 +99,7 @@ describe('DateTimeRangePicker Component', () => { presetsProps: { ...Props.presetsProps }, }; renderWithTheme(); - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); // Set the end date-time to the 15th const endDateField = screen.getByLabelText('End Date and Time'); await userEvent.click(endDateField); @@ -139,7 +139,7 @@ describe('DateTimeRangePicker Component', () => { }, }; renderWithTheme(); - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); // Set the end date-time to the 15th const endDateField = screen.getByLabelText('End Date and Time'); await userEvent.click(endDateField); @@ -162,7 +162,7 @@ describe('DateTimeRangePicker Component', () => { it('should set the date range for the last 24 hours when the "Last 24 Hours" preset is selected', async () => { renderWithTheme(); - + const now = DateTime.now().set({ second: 0 }); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); await userEvent.click(presetsDropdown); @@ -172,8 +172,8 @@ describe('DateTimeRangePicker Component', () => { await userEvent.click(last24HoursOption); // Expected start and end dates in ISO format - const expectedStartDateISO = DateTime.now().minus({ hours: 24 }).toISO(); // 2024-12-17T00:28:27.071-06:00 - const expectedEndDateISO = DateTime.now().toISO(); // 2024-12-18T00:28:27.071-06:00 + const expectedStartDateISO = now.minus({ hours: 24 }).toISO(); // 2024-12-17T00:28:27.071-06:00 + const expectedEndDateISO = now.toISO(); // 2024-12-18T00:28:27.071-06:00 // Verify onChangeMock was called with correct ISO strings expect(onChangeMock).toHaveBeenCalledWith({ @@ -189,7 +189,7 @@ describe('DateTimeRangePicker Component', () => { it('should set the date range for the last 7 days when the "Last 7 Days" preset is selected', async () => { renderWithTheme(); - + const now = DateTime.now().set({ second: 0 }); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); await userEvent.click(presetsDropdown); @@ -199,8 +199,8 @@ describe('DateTimeRangePicker Component', () => { await userEvent.click(last7DaysOption); // Expected start and end dates in ISO format - const expectedStartDateISO = DateTime.now().minus({ days: 7 }).toISO(); - const expectedEndDateISO = DateTime.now().toISO(); + const expectedStartDateISO = now.minus({ days: 7 }).toISO(); + const expectedEndDateISO = now.toISO(); // Verify that onChange is called with the correct date range expect(onChangeMock).toHaveBeenCalledWith({ @@ -216,7 +216,7 @@ describe('DateTimeRangePicker Component', () => { it('should set the date range for the last 30 days when the "Last 30 Days" preset is selected', async () => { renderWithTheme(); - + const now = DateTime.now().set({ second: 0 }); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); await userEvent.click(presetsDropdown); @@ -226,8 +226,8 @@ describe('DateTimeRangePicker Component', () => { await userEvent.click(last30DaysOption); // Expected start and end dates in ISO format - const expectedStartDateISO = DateTime.now().minus({ days: 30 }).toISO(); - const expectedEndDateISO = DateTime.now().toISO(); + const expectedStartDateISO = now.minus({ days: 30 }).toISO(); + const expectedEndDateISO = now.toISO(); // Verify that onChange is called with the correct date range expect(onChangeMock).toHaveBeenCalledWith({ @@ -243,7 +243,7 @@ describe('DateTimeRangePicker Component', () => { it('should set the date range for this month when the "This Month" preset is selected', async () => { renderWithTheme(); - + const now = DateTime.now().set({ second: 0 }); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); await userEvent.click(presetsDropdown); @@ -253,8 +253,8 @@ describe('DateTimeRangePicker Component', () => { await userEvent.click(thisMonthOption); // Expected start and end dates in ISO format - const expectedStartDateISO = DateTime.now().startOf('month').toISO(); - const expectedEndDateISO = DateTime.now().toISO(); + const expectedStartDateISO = now.startOf('month').toISO(); + const expectedEndDateISO = now.toISO(); // Verify that onChange is called with the correct date range expect(onChangeMock).toHaveBeenCalledWith({ @@ -279,7 +279,7 @@ describe('DateTimeRangePicker Component', () => { const lastMonthOption = screen.getByText('Last Month'); await userEvent.click(lastMonthOption); - const lastMonth = DateTime.now().minus({ months: 1 }); + const lastMonth = DateTime.now().set({ second: 0 }).minus({ months: 1 }); // Expected start and end dates in ISO format const expectedStartDateISO = lastMonth.startOf('month').toISO(); @@ -314,7 +314,7 @@ describe('DateTimeRangePicker Component', () => { const customRange = screen.getByText('Custom'); await userEvent.click(customRange); const format = 'yyyy-MM-dd HH:mm'; - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); const start = now.minus({ minutes: 30 }); // Verify the input fields display the correct values From f3fa4d3cf30d7a748cedcf5843f949fefb7b86b7 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 27 Jan 2025 18:44:42 +0530 Subject: [PATCH 33/37] upcoming: [DI-20931] - Updated logic to set 0 seconds --- .../src/components/DatePicker/DateTimeRangePicker.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index b0f72b82966..2970fb2ae8f 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -166,30 +166,37 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { }; const handlePresetSelection = (value: DatePresetType) => { - const now = DateTime.now().set({ second: 0 }); + const now = DateTime.now(); let newStartDateTime: DateTime | null = null; - let newEndDateTime: DateTime | null = now; + let newEndDateTime: DateTime | null = null; switch (value) { case '30minutes': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ minutes: 30 }); break; case '1hour': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 1 }); break; case '12hours': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 12 }); break; case '24hours': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 24 }); break; case '7days': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ days: 7 }); break; case '30days': + newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ days: 30 }); break; case 'this_month': + newEndDateTime = now; newStartDateTime = now.startOf('month'); break; case 'last_month': From 91e8be1c88e3189fc811555a8fa3d224e63db030 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 28 Jan 2025 11:17:09 +0530 Subject: [PATCH 34/37] upcoming: [DI-20931] - updated logic to set 0 for seconds --- .../DatePicker/DateTimeRangePicker.test.tsx | 2 +- .../DatePicker/DateTimeRangePicker.tsx | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx index dacd26cb67b..0cf4f5a021f 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.test.tsx @@ -243,7 +243,7 @@ describe('DateTimeRangePicker Component', () => { it('should set the date range for this month when the "This Month" preset is selected', async () => { renderWithTheme(); - const now = DateTime.now().set({ second: 0 }); + const now = DateTime.now(); // Open the presets dropdown const presetsDropdown = screen.getByLabelText('Date Presets'); await userEvent.click(presetsDropdown); diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index 2970fb2ae8f..d09c0cedaa5 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -166,41 +166,35 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { }; const handlePresetSelection = (value: DatePresetType) => { - const now = DateTime.now(); + const now = DateTime.now().set({ second: 0 }); let newStartDateTime: DateTime | null = null; - let newEndDateTime: DateTime | null = null; + let newEndDateTime: DateTime | null = now; switch (value) { case '30minutes': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ minutes: 30 }); break; case '1hour': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 1 }); break; case '12hours': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 12 }); break; case '24hours': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ hours: 24 }); break; case '7days': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ days: 7 }); break; case '30days': - newEndDateTime = now.set({ second: 0 }); newStartDateTime = now.minus({ days: 30 }); break; case 'this_month': - newEndDateTime = now; - newStartDateTime = now.startOf('month'); + newEndDateTime = DateTime.now(); + newStartDateTime = newEndDateTime.startOf('month'); break; case 'last_month': - const lastMonth = now.minus({ months: 1 }); + const lastMonth = DateTime.now().minus({ months: 1 }); newStartDateTime = lastMonth.startOf('month'); newEndDateTime = lastMonth.endOf('month'); break; From 594ddff14bff32592514b99d6b4bcc55a50f3cad Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 28 Jan 2025 14:55:37 +0530 Subject: [PATCH 35/37] upcoming: [DI-20931] - Added support for multiple screen resolution --- .../DatePicker/DateTimeRangePicker.tsx | 2 +- .../CloudPulseDashboardWithFilters.tsx | 48 +++++----- .../CloudPulse/Overview/GlobalFilters.tsx | 90 +++++++++---------- 3 files changed, 65 insertions(+), 75 deletions(-) diff --git a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx index d09c0cedaa5..3baadbce7bb 100644 --- a/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx +++ b/packages/manager/src/components/DatePicker/DateTimeRangePicker.tsx @@ -208,7 +208,7 @@ export const DateTimeRangePicker = (props: DateTimeRangePickerProps) => { } setStartDateTime(newStartDateTime); - setEndDateTime(newEndDateTime); + setEndDateTime(newEndDateTime?.set({ second: 0 }) ?? null); setPresetValue( presetsOptions.find((option) => option.value === value) ?? presetsOptions[0] diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx index 7d956e530b6..92aed1b6c40 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardWithFilters.tsx @@ -133,35 +133,27 @@ export const CloudPulseDashboardWithFilters = React.memo( }} > - - - - - - - - + + + + + diff --git a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx index 843ca9c4939..64ead31acc4 100644 --- a/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx +++ b/packages/manager/src/features/CloudPulse/Overview/GlobalFilters.tsx @@ -1,4 +1,4 @@ -import { Divider } from '@linode/ui'; +import { Box, Divider } from '@linode/ui'; import { IconButton, useTheme } from '@mui/material'; import { Grid } from '@mui/material'; import { styled } from '@mui/material/styles'; @@ -95,52 +95,50 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { return ( - - - - - - - - - - - - - + + + + + + + + + + + {selectedDashboard && ( From fb3fcb5729f443e33e2b0af99c5d1c70bf9ed877 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 28 Jan 2025 17:51:38 +0530 Subject: [PATCH 36/37] upcoming: [DI-23083] - Added changeset --- .../.changeset/pr-11573-upcoming-features-1738066060175.md | 5 +++++ .../.changeset/pr-11573-upcoming-features-1738066869988.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 packages/api-v4/.changeset/pr-11573-upcoming-features-1738066060175.md create mode 100644 packages/manager/.changeset/pr-11573-upcoming-features-1738066869988.md diff --git a/packages/api-v4/.changeset/pr-11573-upcoming-features-1738066060175.md b/packages/api-v4/.changeset/pr-11573-upcoming-features-1738066060175.md new file mode 100644 index 00000000000..24df680cbb9 --- /dev/null +++ b/packages/api-v4/.changeset/pr-11573-upcoming-features-1738066060175.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Upcoming Features +--- + +Add `DateTimeWithPreset` type in cloudpulse types ([#11573](https://github.com/linode/manager/pull/11573)) diff --git a/packages/manager/.changeset/pr-11573-upcoming-features-1738066869988.md b/packages/manager/.changeset/pr-11573-upcoming-features-1738066869988.md new file mode 100644 index 00000000000..850bd5ca780 --- /dev/null +++ b/packages/manager/.changeset/pr-11573-upcoming-features-1738066869988.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Replace `CloudPulseTimeRangeSelect` with `CloudPulseDateTimeRangePicker`, Change metric request body to use `absolute_time_duration` for custom date and `relative_time_duration` for presets, add `1hr` preset option in `DateTimeRangePicker`, Change time select input field to `read-only` in `DateTimePicker ([#11573](https://github.com/linode/manager/pull/11573)) From d034eb672a5d9ba5e6817fddc888bd0c5a6f5824 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 28 Jan 2025 18:12:18 +0530 Subject: [PATCH 37/37] upcoming: [DI-20931] - Added test cases --- .../Utils/CloudPulseWidgetUtils.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.test.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.test.ts index 0d1985230b3..c9a40edf80f 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.test.ts @@ -5,6 +5,7 @@ import { generateMaxUnit, getDimensionName, getLabelName, + getTimeDurationFromPreset, mapResourceIdToName, } from './CloudPulseWidgetUtils'; @@ -235,3 +236,18 @@ it('test mapResourceIdToName method', () => { expect(mapResourceIdToName('999', resources)).toBe('999'); expect(mapResourceIdToName(undefined, resources)).toBe(''); }); + +describe('getTimeDurationFromPreset method', () => { + it('should return correct time duration for 24hours preset', () => { + const result = getTimeDurationFromPreset('24hours'); + expect(result).toStrictEqual({ + unit: 'hr', + value: 24, + }); + }); + + it('shoult return undefined of invalid preset', () => { + const result = getTimeDurationFromPreset('15min'); + expect(result).toBe(undefined); + }); +});