-
Notifications
You must be signed in to change notification settings - Fork 407
upcoming: [DI-27104] - Added GlobalFilter and WidgetFilter group by renderer components #12865
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
Merged
nikhagra-akamai
merged 51 commits into
linode:develop
from
nikhagra-akamai:feature/group-by
Sep 16, 2025
Merged
Changes from all commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
ccb32ce
upcoming: [DI-22916] - Added group by drawer component
nikhagra-akamai cc05634
upcoming: [DI-22916] - Added memo to group by drawer component
nikhagra-akamai ddb8997
upcoming: [DI-22916] - Added hook to fetch dimension for group by droβ¦
nikhagra-akamai 8cf75b1
upcoming: [DI-22916] - Updated test case
nikhagra-akamai c530be9
upcoming: [DI-22916] - Remove unused imports
nikhagra-akamai 0bc537a
upcoming: [DI-26666] - Added useWidgetDimension hook to generate widgβ¦
nikhagra-akamai 65922d8
upcoming: [DI-22916] - Updated interface documentation
nikhagra-akamai 844adc6
upcoming: [DI-26666] - Updated logic to no disable select all button
nikhagra-akamai 5463d9c
upcoming: [DI-26666] - Dynamically hiding maximum selection limit mesβ¦
nikhagra-akamai 274d010
upcoming: [DI-26666] - Show default options from dashboard api in gloβ¦
nikhagra-akamai 3a0064d
upcoming: [DI-26666] - Updated default value logic
nikhagra-akamai 9dcfb9f
upcoming: [DI-26666] - moved option rendering to a function
nikhagra-akamai 17bb024
upcoming: [DI-26666] - Added group by in dashboard interface
nikhagra-akamai 21f6e10
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai 7dc426f
Added changeset
nikhagra-akamai d54bd2e
upcoming: [DI-26666] - Added method documentation
nikhagra-akamai 27f0d5d
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai 88152b4
upcoming: [DI-26666] - Updated typos
nikhagra-akamai b1fc0a1
upcoming: [DI-26666] - Renamed file
nikhagra-akamai 4a16b7a
upcoming: [DI-26666] - Added test cases
nikhagra-akamai 536766b
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai fef65f3
upcoming: [DI-26666] - Updated subtitle and message component
nikhagra-akamai 9a780c8
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai 18206fe
upcoming: [DI-26666] - Removed typography styling
nikhagra-akamai 3c031d6
reverted hardcoded value
nikhagra-akamai 8e701b8
Merge branch 'develop' into feature/group-by
nikhagra-akamai 099393d
upcoming: [DI-22916] - Added group by svg file
nikhagra-akamai 07e1dfd
upcoming: [DI-22916] - Added Global Filter group by renderer
nikhagra-akamai 372651b
upcoming: [DI-26666] - Added widget filter group by renderer
nikhagra-akamai 3942ca6
upcoming: [DI-26666] - Added widget group by renderer test cases
nikhagra-akamai 0bc0e4b
upcoming: [DI-26666] - Added test cases for Global Group By Renderer
nikhagra-akamai f74409d
upcoming: [DI-26666] - Updated import statement
nikhagra-akamai 81003f5
Merge branch 'feature/group-by' of github.com:nikhagra-akamai/managerβ¦
nikhagra-akamai 6870759
Merge conflict resolved
nikhagra-akamai 68e2e45
upcoming: [DI-26666] - Code refactor
nikhagra-akamai b75c114
Hide dimension select placeholder when atleast 1 option is selected
nikhagra-akamai 2550baf
upcoming: [DI-26666] - Added qa id
nikhagra-akamai d3b01b8
upcoming: [DI-26666] - Updated file name
nikhagra-akamai f5d96d2
upcoming: [DI-26666] - Updated failing test cases
nikhagra-akamai 9a394f8
Added changeset
nikhagra-akamai b91fe19
Merge branch 'develop' into feature/group-by
nikhagra-akamai d4bb76d
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai 09632f6
Merge branch 'feature/group-by' of github.com:nikhagra-akamai/managerβ¦
nikhagra-akamai 3752bd1
upcoming: [DI-27104] - Updated interface documentation
nikhagra-akamai 330e239
upcoming: [DI-27104] - Updated dependency array
nikhagra-akamai fc53751
upcoming: [DI-27104] - Updated spacing function
nikhagra-akamai bb547d8
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai f22c5a6
upcoming: [DI-27104] - Updated tokens color
nikhagra-akamai 88e27e0
upcoming: [DI-27104] - Updated stack gap
nikhagra-akamai 64c64cb
Merge branch 'develop' of github.com:linode/manager into feature/grouβ¦
nikhagra-akamai dc3fbfa
Removed redundant file
nikhagra-akamai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
packages/manager/.changeset/pr-12865-upcoming-features-1757611405994.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@linode/manager": Upcoming Features | ||
| --- | ||
|
|
||
| ACLP: add `GlobalFilterGroupByRendererComponent` and `WidgetFilterGroupByRendererComponent` ([#12865](https://github.com/linode/manager/pull/12865)) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
packages/manager/src/features/CloudPulse/GroupBy/GlobalFilterGroupByRenderer.test.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import { screen } from '@testing-library/react'; | ||
| import React from 'react'; | ||
|
|
||
| import { dashboardFactory } from 'src/factories'; | ||
| import { renderWithTheme } from 'src/utilities/testHelpers'; | ||
|
|
||
| import { GlobalFilterGroupByRenderer } from './GlobalFilterGroupByRenderer'; | ||
|
|
||
| import type { GroupByOption } from './CloudPulseGroupByDrawer'; | ||
|
|
||
| const handleChange = vi.fn(); | ||
| const dashboard = dashboardFactory.build(); | ||
|
|
||
| const mocks = vi.hoisted(() => ({ | ||
| useGlobalDimensions: vi.fn(), | ||
| })); | ||
|
|
||
| const mockGroupByOptions: GroupByOption[] = [ | ||
| { value: 'option1', label: 'Option 1' }, | ||
| { value: 'option2', label: 'Option 2' }, | ||
| { value: 'option3', label: 'Option 3' }, | ||
| ]; | ||
|
|
||
| vi.mock('./utils', async () => { | ||
| const actual = await vi.importActual('./utils'); | ||
|
|
||
| return { | ||
| ...actual, | ||
| useGlobalDimensions: mocks.useGlobalDimensions, | ||
| }; | ||
| }); | ||
|
|
||
| describe('Global Group By Renderer Component', () => { | ||
| it('should render group by icon in disabled mode on undefined dashboard', () => { | ||
| mocks.useGlobalDimensions.mockReturnValue({ | ||
| isLoading: true, | ||
| options: [], | ||
| defaultValue: [], | ||
| }); | ||
| renderWithTheme( | ||
| <GlobalFilterGroupByRenderer | ||
| handleChange={handleChange} | ||
| selectedDashboard={undefined} | ||
| /> | ||
| ); | ||
|
|
||
| const groupByIcon = screen.getByTestId('group-by'); | ||
| expect(groupByIcon).toBeDisabled(); | ||
| }); | ||
|
|
||
| it('should render group by icon in disabled mode on data loading', () => { | ||
| mocks.useGlobalDimensions.mockReturnValue({ | ||
| isLoading: true, | ||
| options: [], | ||
| defaultValue: [], | ||
| }); | ||
| renderWithTheme( | ||
| <GlobalFilterGroupByRenderer | ||
| handleChange={handleChange} | ||
| selectedDashboard={dashboard} | ||
| /> | ||
| ); | ||
|
|
||
| const groupByIcon = screen.getByTestId('group-by'); | ||
| expect(groupByIcon).toBeDisabled(); | ||
| }); | ||
|
|
||
| it('Should render group by icon as enabled and open drawer on click', async () => { | ||
| mocks.useGlobalDimensions.mockReturnValue({ | ||
| isLoading: false, | ||
| options: mockGroupByOptions, | ||
| defaultValue: [], | ||
| }); | ||
| renderWithTheme( | ||
| <GlobalFilterGroupByRenderer | ||
| handleChange={handleChange} | ||
| selectedDashboard={dashboard} | ||
| /> | ||
| ); | ||
|
|
||
| const groupByIcon = screen.getByTestId('group-by'); | ||
| expect(groupByIcon).toBeEnabled(); | ||
|
|
||
| await groupByIcon.click(); | ||
|
|
||
| const drawer = screen.getByTestId('drawer'); | ||
| expect(drawer).toBeInTheDocument(); | ||
|
|
||
| expect(handleChange).toHaveBeenCalledWith([]); | ||
| }); | ||
|
|
||
| it('Should not open drawer but group by icon should be enabled', async () => { | ||
| mocks.useGlobalDimensions.mockReturnValue({ | ||
| isLoading: false, | ||
| options: mockGroupByOptions, | ||
| defaultValue: [], | ||
| }); | ||
| renderWithTheme( | ||
| <GlobalFilterGroupByRenderer | ||
| handleChange={handleChange} | ||
| selectedDashboard={dashboard} | ||
| /> | ||
| ); | ||
|
|
||
| const groupByIcon = screen.getByTestId('group-by'); | ||
| expect(groupByIcon).toBeEnabled(); | ||
|
|
||
| const drawer = screen.queryByTestId('drawer'); | ||
| expect(drawer).not.toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('Should open drawer on group by icon click and have default selected values', async () => { | ||
| const defaultValue = [mockGroupByOptions[0]]; | ||
|
|
||
| mocks.useGlobalDimensions.mockReturnValue({ | ||
| isLoading: false, | ||
| options: mockGroupByOptions, | ||
| defaultValue, | ||
| }); | ||
| renderWithTheme( | ||
| <GlobalFilterGroupByRenderer | ||
| handleChange={handleChange} | ||
| selectedDashboard={dashboard} | ||
| /> | ||
| ); | ||
|
|
||
| const groupByIcon = screen.getByTestId('group-by'); | ||
|
|
||
| await groupByIcon.click(); | ||
|
|
||
| const drawer = screen.getByTestId('drawer'); | ||
| expect(drawer).toBeInTheDocument(); | ||
|
|
||
| expect(handleChange).toHaveBeenCalledWith([defaultValue[0].value]); | ||
|
|
||
| defaultValue.forEach((value) => { | ||
| const option = screen.getByRole('button', { name: value.label }); | ||
| expect(option).toBeInTheDocument(); | ||
| }); | ||
| }); | ||
| }); |
90 changes: 90 additions & 0 deletions
90
packages/manager/src/features/CloudPulse/GroupBy/GlobalFilterGroupByRenderer.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import { IconButton } from '@linode/ui'; | ||
| import React from 'react'; | ||
|
|
||
| import GroupByIcon from 'src/assets/icons/group-by.svg'; | ||
|
|
||
| import { CloudPulseTooltip } from '../shared/CloudPulseTooltip'; | ||
| import { CloudPulseGroupByDrawer } from './CloudPulseGroupByDrawer'; | ||
| import { GLOBAL_GROUP_BY_MESSAGE } from './constants'; | ||
| import { useGlobalDimensions } from './utils'; | ||
|
|
||
| import type { GroupByOption } from './CloudPulseGroupByDrawer'; | ||
| import type { Dashboard } from '@linode/api-v4'; | ||
|
|
||
| interface GlobalFilterGroupByRendererProps { | ||
| /** | ||
| * Callback to handle the selected values | ||
| */ | ||
| handleChange: (selectedValue: string[]) => void; | ||
| /** | ||
| * Currently selected dashboard | ||
| */ | ||
| selectedDashboard?: Dashboard; | ||
| } | ||
|
|
||
| export const GlobalFilterGroupByRenderer = ( | ||
| props: GlobalFilterGroupByRendererProps | ||
| ) => { | ||
| const { selectedDashboard, handleChange } = props; | ||
| const [isSelected, setIsSelected] = React.useState(false); | ||
|
|
||
| const { options, defaultValue, isLoading } = useGlobalDimensions( | ||
| selectedDashboard?.id, | ||
| selectedDashboard?.service_type | ||
| ); | ||
|
|
||
| const [open, setOpen] = React.useState(false); | ||
|
|
||
| const onApply = React.useCallback( | ||
| (selectedValue: GroupByOption[]) => { | ||
| if (selectedValue.length === 0) { | ||
| setIsSelected(false); | ||
| } else { | ||
| setIsSelected(true); | ||
| } | ||
| handleChange(selectedValue.map(({ value }) => value)); | ||
| setOpen(false); | ||
| }, | ||
| [handleChange] | ||
| ); | ||
|
|
||
| const onCancel = React.useCallback(() => { | ||
| setOpen(false); | ||
| }, []); | ||
| return ( | ||
| <> | ||
| <CloudPulseTooltip placement="bottom-end" title="Group By"> | ||
| <IconButton | ||
| aria-label="Group By Dashboard Metrics" | ||
| color="inherit" | ||
| data-qa-selected={isSelected} | ||
| data-testid="group-by" | ||
| disabled={!selectedDashboard || isLoading} | ||
| onClick={() => setOpen(true)} | ||
| size="small" | ||
| sx={(theme) => ({ | ||
| marginBlockEnd: 'auto', | ||
| marginTop: { md: theme.spacingFunction(28) }, | ||
| color: isSelected ? theme.color.buttonPrimaryHover : 'inherit', | ||
| })} | ||
| > | ||
| <GroupByIcon height="24px" width="24px" /> | ||
| </IconButton> | ||
| </CloudPulseTooltip> | ||
|
|
||
| {!isLoading && selectedDashboard && ( | ||
| <CloudPulseGroupByDrawer | ||
| defaultValue={defaultValue} | ||
| message={GLOBAL_GROUP_BY_MESSAGE} | ||
| onApply={onApply} | ||
| onCancel={onCancel} | ||
| open={open} | ||
| options={options} | ||
| serviceType={selectedDashboard.service_type} | ||
| subtitle={selectedDashboard.label} | ||
| title="Global Group By" | ||
| /> | ||
| )} | ||
| </> | ||
| ); | ||
| }; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.