-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
upcoming: [DI-20929] - Added applied filters view in CloudPulse #11354
Changes from 7 commits
726bddc
fab859a
24af9e8
33e78a8
2ec9bd6
7177bc5
265cb62
2bf49af
755ad00
7cc5507
704296a
48c186b
af2f296
be56566
d67c01f
1f79afa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@linode/manager": Upcoming Features | ||
--- | ||
|
||
Add `CloudPulseAppliedFilter` and `CloudPulseAppliedFilterRenderer` components, update filter change handler function to add another parameter `label` ([#11354](https://github.com/linode/manager/pull/11354)) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,13 +1,18 @@ | ||||||
import { Grid, Paper } from '@mui/material'; | ||||||
import { Box, Grid, Paper } from '@mui/material'; | ||||||
import * as React from 'react'; | ||||||
|
||||||
import { GlobalFilters } from '../Overview/GlobalFilters'; | ||||||
import { CloudPulseAppliedFilterRenderer } from '../shared/CloudPulseAppliedFilterRenderer'; | ||||||
import { CloudPulseDashboardRenderer } from './CloudPulseDashboardRenderer'; | ||||||
|
||||||
import type { Dashboard, TimeDuration } from '@linode/api-v4'; | ||||||
|
||||||
export type FilterValueType = number | number[] | string | string[] | undefined; | ||||||
|
||||||
export interface FilterValue { | ||||||
id: { [key: string]: FilterValueType }; | ||||||
label: { [key: string]: string[] }; | ||||||
} | ||||||
export interface DashboardProp { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering if this interface should be named differently, like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated thanks for pointing out |
||||||
dashboard?: Dashboard; | ||||||
filterValue: { | ||||||
|
@@ -17,26 +22,47 @@ export interface DashboardProp { | |||||
} | ||||||
|
||||||
export const CloudPulseDashboardLanding = () => { | ||||||
const [filterValue, setFilterValue] = React.useState<{ | ||||||
[key: string]: FilterValueType; | ||||||
}>({}); | ||||||
const [filterValue, setFilterValue] = React.useState<FilterValue>({ | ||||||
id: {}, | ||||||
label: {}, | ||||||
}); | ||||||
|
||||||
const [timeDuration, setTimeDuration] = React.useState<TimeDuration>(); | ||||||
|
||||||
const [dashboard, setDashboard] = React.useState<Dashboard>(); | ||||||
|
||||||
const [showAppliedFilters, setShowAppliedFilters] = React.useState<boolean>( | ||||||
false | ||||||
); | ||||||
|
||||||
const toggleAppliedFilter = (isVisible: boolean) => { | ||||||
setShowAppliedFilters(isVisible); | ||||||
}; | ||||||
|
||||||
const onFilterChange = React.useCallback( | ||||||
(filterKey: string, filterValue: FilterValueType) => { | ||||||
setFilterValue((prev: { [key: string]: FilterValueType }) => ({ | ||||||
...prev, | ||||||
[filterKey]: filterValue, | ||||||
})); | ||||||
(filterKey: string, filterValue: FilterValueType, labels: string[]) => { | ||||||
setFilterValue((prev: FilterValue) => { | ||||||
return { | ||||||
id: { | ||||||
...prev.id, | ||||||
[filterKey]: filterValue, | ||||||
}, | ||||||
label: { | ||||||
...prev.label, | ||||||
[filterKey]: labels, | ||||||
}, | ||||||
}; | ||||||
}); | ||||||
}, | ||||||
[] | ||||||
); | ||||||
|
||||||
const onDashboardChange = React.useCallback((dashboardObj: Dashboard) => { | ||||||
setDashboard(dashboardObj); | ||||||
setFilterValue({}); // clear the filter values on dashboard change | ||||||
setFilterValue({ | ||||||
id: {}, | ||||||
label: {}, | ||||||
}); // clear the filter values on dashboard change | ||||||
}, []); | ||||||
const onTimeDurationChange = React.useCallback( | ||||||
(timeDurationObj: TimeDuration) => { | ||||||
|
@@ -48,16 +74,25 @@ export const CloudPulseDashboardLanding = () => { | |||||
<Grid container spacing={2}> | ||||||
<Grid item xs={12}> | ||||||
<Paper> | ||||||
<GlobalFilters | ||||||
handleAnyFilterChange={onFilterChange} | ||||||
handleDashboardChange={onDashboardChange} | ||||||
handleTimeDurationChange={onTimeDurationChange} | ||||||
/> | ||||||
<Box display={'flex'} flexDirection={'column'}> | ||||||
<GlobalFilters | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. heads up, since Paper is now from linode/ui, it has built in padding - you need to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for informing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit: we don't need object notation here |
||||||
handleAnyFilterChange={onFilterChange} | ||||||
handleDashboardChange={onDashboardChange} | ||||||
handleTimeDurationChange={onTimeDurationChange} | ||||||
handleToggleAppliedFilter={toggleAppliedFilter} | ||||||
/> | ||||||
{dashboard?.service_type && showAppliedFilters && ( | ||||||
<CloudPulseAppliedFilterRenderer | ||||||
filters={filterValue.label} | ||||||
serviceType={dashboard.service_type} | ||||||
/> | ||||||
)} | ||||||
</Box> | ||||||
</Paper> | ||||||
</Grid> | ||||||
<CloudPulseDashboardRenderer | ||||||
dashboard={dashboard} | ||||||
filterValue={filterValue} | ||||||
filterValue={filterValue.id} | ||||||
timeDuration={timeDuration} | ||||||
/> | ||||||
</Grid> | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,16 +17,22 @@ import type { FilterValueType } from '../Dashboard/CloudPulseDashboardLanding'; | |
import type { AclpConfig, Dashboard, TimeDuration } from '@linode/api-v4'; | ||
|
||
export interface GlobalFilterProperties { | ||
handleAnyFilterChange(filterKey: string, filterValue: FilterValueType): void; | ||
handleAnyFilterChange( | ||
filterKey: string, | ||
filterValue: FilterValueType, | ||
labels: string[] | ||
): void; | ||
handleDashboardChange(dashboard: Dashboard | undefined): void; | ||
handleTimeDurationChange(timeDuration: TimeDuration): void; | ||
handleToggleAppliedFilter(isVisible: boolean): void; | ||
} | ||
|
||
export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { | ||
const { | ||
handleAnyFilterChange, | ||
handleDashboardChange, | ||
handleTimeDurationChange, | ||
handleToggleAppliedFilter, | ||
} = props; | ||
|
||
const { | ||
|
@@ -68,19 +74,20 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { | |
( | ||
filterKey: string, | ||
value: FilterValueType, | ||
labels: string[], | ||
savePref: boolean = false, | ||
updatedPreferenceData: AclpConfig = {} | ||
) => { | ||
if (savePref) { | ||
updatePreferences(updatedPreferenceData); | ||
} | ||
handleAnyFilterChange(filterKey, value); | ||
handleAnyFilterChange(filterKey, value, labels); | ||
}, | ||
[] | ||
); | ||
|
||
const handleGlobalRefresh = React.useCallback(() => { | ||
handleAnyFilterChange(REFRESH, Date.now()); | ||
handleAnyFilterChange(REFRESH, Date.now(), []); | ||
}, []); | ||
|
||
const theme = useTheme(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional: I wonder if we could avoid importing this |
||
|
@@ -143,6 +150,7 @@ export const GlobalFilters = React.memo((props: GlobalFilterProperties) => { | |
<CloudPulseDashboardFilterBuilder | ||
dashboard={selectedDashboard} | ||
emitFilterChange={emitFilterChange} | ||
handleToggleAppliedFilter={handleToggleAppliedFilter} | ||
isServiceAnalyticsIntegration={false} | ||
preferences={preferences} | ||
/> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React from 'react'; | ||
|
||
import { renderWithTheme } from 'src/utilities/testHelpers'; | ||
|
||
import { CloudPulseAppliedFilter } from './CloudPulseAppliedFilter'; | ||
import { CloudPulseAppliedFilterRenderer } from './CloudPulseAppliedFilterRenderer'; | ||
|
||
const data = { | ||
region: ['us-east'], | ||
resource: ['res1', 'res2'], | ||
}; | ||
|
||
const testId = 'applied-filter'; | ||
|
||
describe('CloudPulse Applied Filter', () => { | ||
it('should render applied filter component', () => { | ||
const { getByTestId } = renderWithTheme( | ||
<CloudPulseAppliedFilter filters={data} /> | ||
); | ||
expect(getByTestId(testId)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render the applied filter key & values', () => { | ||
const { getByTestId } = renderWithTheme( | ||
<CloudPulseAppliedFilter filters={data} /> | ||
); | ||
expect(getByTestId(testId)).toHaveTextContent('region'); | ||
expect(getByTestId(testId)).toHaveTextContent('res1'); | ||
expect(getByTestId(testId)).not.toHaveTextContent('resources'); | ||
}); | ||
|
||
it('should not render the applied filter component', () => { | ||
const { queryByTestId } = renderWithTheme( | ||
<CloudPulseAppliedFilterRenderer filters={{}} serviceType="abc" /> | ||
); | ||
|
||
expect(queryByTestId(testId)).toBe(null); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we import Box and Paper from our linode/ui package?