Skip to content

Commit

Permalink
upcoming: [DI-20360] - Updated preferences logic to remove flickering…
Browse files Browse the repository at this point in the history
… issue (#10853)

* upcoming: [DI-20360] - Modified user preference logic

* upcoming: [DI-20360] - Modified user preference logic

* upcoming: [DI-20360] - Removed useEffect from widget component

* upcoming: [DI-20360] - Updated request.tsx file

* upcoming: [DI-20360] - remove sensitive information

* upcoming: [DI-20360] - Update preference logic to avoid extra re-renderings

* upcoming: [DI-20360] - Updated preference logic in custom select

* upcoming: [DI-20360] - Metrics api hardcoded url removed

* upcoming: [DI-20360] - Updated jsdocs & removed un-used variable

* upcoming: [DI-20360] - Test cases updated

* upcoming: [DI-20360] - added changeset

* upcoming: [DI-20360] - Removed unused variable

* upcoming: [DI-20360] - Optimized user preferences to avoid passing update function as props

* upcoming: [DI-20360] - Eslint errors resolve

* upcoming: [DI-20360] - Merge conflicts resolved

* upcoming: [DI-20360] - Changes based on review comments

* upcoming: [DI-20360] - Passing default values to components instead of full preference object

* upcoming: [DI-20360] - Upddated widget components to avoid infinite loop

* upcoming: [DI-20360] - Updated review comment suggestions & test cases

* upcoming: [DI-20360] - Updated review comments

* upcoming: [DI-20360] - Test cases updated

* upcoming: [DI-20360] - Modified user preference logic

* upcoming: [DI-20360] - Modified user preference logic

* upcoming: [DI-20360] - Updated request.tsx file

* upcoming: [DI-20360] - remove sensitive information

* upcoming: [DI-20360] - Update preference logic to avoid extra re-renderings

* upcoming: [DI-20360] - Updated preference logic in custom select

* upcoming: [DI-20360] - Optimized user preferences to avoid passing update function as props

* upcoming: [DI-20360] - Changes based on review comments

* upcoming: [DI-20360] - Upddated widget components to avoid infinite loop

* upcoming: [DI-20360] - Updated review comment suggestions & test cases

* upcoming: [DI-20360] - Updated useAclpPreference hook to use ref for preserving the changes without re-rendering

* upcoming: [DI-20360] - Updated compare props logic

* upcoming: [DI-20360] - Test cases updated

* upcoming: [DI-20360] - Updated ESLint issues

* upcoming: [DI-20360] - Updated review comments

* upcoming: [DI-20360] - Test cases updated

* upcoming: [DI-20360] - Updated logic to prevent widget preference to override

* upcoming: [DI-20360] - Separated components into different files

* upcoming: [DI-20360] - updated funcntions with useMemo

* upcoming: [DI-20360] - updated eslint issues

* upcoming: [DI-20360] - Updated widget preferences logic

* upcoming: [DI-20360] - Updated deep equal logic

* Updated aggregate function type

* upcoming: [DI-20360] - Updated global filter test cases

* upcoming: [DI-20360] - Updated eslint issue

* upcoming: [DI-20360] - Removed unnecessary compare functions

---------

Co-authored-by: vmangalr <[email protected]>
  • Loading branch information
nikhagra-akamai and vmangalr committed Sep 30, 2024
1 parent 4e5c69e commit 033099c
Show file tree
Hide file tree
Showing 28 changed files with 924 additions and 649 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Upcoming Features
---

Add export to FilterValue interface ([#10853](https://github.com/linode/manager/pull/10853))
5 changes: 2 additions & 3 deletions packages/api-v4/src/cloudpulse/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Dashboard {
export interface TimeGranularity {
unit: string;
value: number;
label?: string;
}

export interface TimeDuration {
Expand Down Expand Up @@ -44,8 +45,7 @@ export interface Filters {
value: string;
}

// Define the type for filter values
type FilterValue =
export type FilterValue =
| number
| string
| string[]
Expand All @@ -56,7 +56,6 @@ type FilterValue =
type WidgetFilterValue = { [key: string]: AclpWidget };

export interface AclpConfig {
// we maintain only the filters selected in the preferences for latest selected dashboard
[key: string]: FilterValue;
widgets?: WidgetFilterValue;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

add useAclpPreference hook in UserPreference.ts, update CloudPulseWidget.ts, CloudPulseDashboard & GlobalFilters to use useAclpPreference and pass preference values to child component ([#10853](https://github.com/linode/manager/pull/10853))
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
import { Grid, Paper } from '@mui/material';
import { Grid } from '@mui/material';
import React from 'react';

import CloudPulseIcon from 'src/assets/icons/entityIcons/monitor.svg';
import { CircleProgress } from 'src/components/CircleProgress';
import { ErrorState } from 'src/components/ErrorState/ErrorState';
import { Placeholder } from 'src/components/Placeholder/Placeholder';
import { useCloudPulseDashboardByIdQuery } from 'src/queries/cloudpulse/dashboards';
import { useResourcesQuery } from 'src/queries/cloudpulse/resources';
import {
useCloudPulseJWEtokenQuery,
useGetCloudPulseMetricDefinitionsByServiceType,
} from 'src/queries/cloudpulse/services';

import { getUserPreferenceObject } from '../Utils/UserPreference';
import { createObjectCopy } from '../Utils/utils';
import { CloudPulseWidget } from '../Widget/CloudPulseWidget';
import {
allIntervalOptions,
getInSeconds,
getIntervalIndex,
} from '../Widget/components/CloudPulseIntervalSelect';
import { useAclpPreference } from '../Utils/UserPreference';
import { RenderWidgets } from '../Widget/CloudPulseWidgetRenderer';

import type {
CloudPulseMetricsAdditionalFilters,
CloudPulseWidgetProperties,
} from '../Widget/CloudPulseWidget';
import type {
AvailableMetrics,
Dashboard,
JWETokenPayLoad,
TimeDuration,
Widgets,
} from '@linode/api-v4';
import type { CloudPulseMetricsAdditionalFilters } from '../Widget/CloudPulseWidget';
import type { JWETokenPayLoad, TimeDuration } from '@linode/api-v4';

export interface DashboardProperties {
/**
Expand All @@ -52,7 +35,7 @@ export interface DashboardProperties {
/**
* optional timestamp to pass as react query param to forcefully re-fetch data
*/
manualRefreshTimeStamp?: number | undefined;
manualRefreshTimeStamp?: number;

/**
* Selected region for the dashboard
Expand Down Expand Up @@ -80,53 +63,14 @@ export const CloudPulseDashboard = (props: DashboardProperties) => {
savePref,
} = props;

const { preferences } = useAclpPreference();

const getJweTokenPayload = (): JWETokenPayLoad => {
return {
resource_ids: resourceList?.map((resource) => Number(resource.id)) ?? [],
};
};

const getCloudPulseGraphProperties = (
widget: Widgets
): CloudPulseWidgetProperties => {
const graphProp: CloudPulseWidgetProperties = {
additionalFilters,
ariaLabel: widget.label,
authToken: '',
availableMetrics: undefined,
duration,
errorLabel: 'Error While Loading Data',
resourceIds: resources,
resources: [],
serviceType: dashboard?.service_type ?? '',
timeStamp: manualRefreshTimeStamp,
unit: widget.unit ?? '%',
widget: { ...widget },
};
if (savePref) {
setPreferredWidgetPlan(graphProp.widget);
}
return graphProp;
};

const setPreferredWidgetPlan = (widgetObj: Widgets) => {
const widgetPreferences = getUserPreferenceObject().widgets;
const pref = widgetPreferences?.[widgetObj.label];
if (pref) {
Object.assign(widgetObj, {
aggregate_function: pref.aggregateFunction,
size: pref.size,
time_granularity: { ...pref.timeGranularity },
});
}
};

const getTimeGranularity = (scrapeInterval: string) => {
const scrapeIntervalValue = getInSeconds(scrapeInterval);
const index = getIntervalIndex(scrapeIntervalValue);
return index < 0 ? allIntervalOptions[0] : allIntervalOptions[index];
};

const {
data: dashboard,
isLoading: isDashboardLoading,
Expand Down Expand Up @@ -182,76 +126,18 @@ export const CloudPulseDashboard = (props: DashboardProperties) => {
return <ErrorState errorText={'Error loading metric definitions'} />;
}

const RenderWidgets = () => {
if (!dashboard || !dashboard.widgets?.length) {
return renderPlaceHolder(
'No visualizations are available at this moment. Create Dashboards to list here.'
);
}

if (
!dashboard.service_type ||
!Boolean(resources.length > 0) ||
!jweToken?.token ||
!Boolean(resourceList?.length)
) {
return renderPlaceHolder(
'Select Dashboard, Region and Resource to visualize metrics'
);
}

// maintain a copy
const newDashboard: Dashboard = createObjectCopy(dashboard)!;
return (
<Grid columnSpacing={2} container item rowSpacing={2} xs={12}>
{{ ...newDashboard }.widgets.map((widget, index) => {
// check if widget metric definition is available or not
if (widget) {
// find the metric defintion of the widget label
const availMetrics = metricDefinitions?.data.find(
(availMetrics: AvailableMetrics) =>
widget.label === availMetrics.label
);
const cloudPulseWidgetProperties = getCloudPulseGraphProperties({
...widget,
});

// metric definition is available but time_granularity is not present
if (
availMetrics &&
!cloudPulseWidgetProperties.widget.time_granularity
) {
cloudPulseWidgetProperties.widget.time_granularity = getTimeGranularity(
availMetrics.scrape_interval
);
}
return (
<CloudPulseWidget
key={widget.label}
{...cloudPulseWidgetProperties}
authToken={jweToken?.token}
availableMetrics={availMetrics}
resources={resourceList!}
savePref={savePref}
/>
);
} else {
return <React.Fragment key={index}></React.Fragment>;
}
})}
</Grid>
);
};

const renderPlaceHolder = (title: string) => {
return (
<Grid item xs>
<Paper>
<Placeholder icon={CloudPulseIcon} isEntity title={title} />
</Paper>
</Grid>
);
};

return <RenderWidgets />;
return (
<RenderWidgets
additionalFilters={additionalFilters}
dashboard={dashboard}
duration={duration}
jweToken={jweToken}
manualRefreshTimeStamp={manualRefreshTimeStamp}
metricDefinitions={metricDefinitions}
preferences={preferences}
resourceList={resourceList}
resources={resources}
savePref={savePref}
/>
);
};
Loading

0 comments on commit 033099c

Please sign in to comment.