chore(FilterBar): move the "Add/edit filters" button in the FilterBar to the settings menu (#31290)

Co-authored-by: Geido <60598000+geido@users.noreply.github.com>
Co-authored-by: Diego Pucci <diegopucci.me@gmail.com>
This commit is contained in:
alexandrusoare 2024-12-06 20:52:55 +02:00 committed by GitHub
parent 48864ce8c7
commit 079e7327a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 68 additions and 140 deletions

View File

@ -88,6 +88,9 @@ describe('Horizontal FilterBar', () => {
cy.getBySel('horizontal-filterbar-empty') cy.getBySel('horizontal-filterbar-empty')
.contains('No filters are currently added to this dashboard.') .contains('No filters are currently added to this dashboard.')
.should('exist'); .should('exist');
cy.get(nativeFilters.filtersPanel.filterGear).click({
force: true,
});
cy.getBySel('filter-bar__create-filter').should('exist'); cy.getBySel('filter-bar__create-filter').should('exist');
cy.getBySel('filterbar-action-buttons').should('exist'); cy.getBySel('filterbar-action-buttons').should('exist');
}); });
@ -120,7 +123,7 @@ describe('Horizontal FilterBar', () => {
cy.getBySel('form-item-value').should('have.length', 3); cy.getBySel('form-item-value').should('have.length', 3);
cy.viewport(768, 1024); cy.viewport(768, 1024);
cy.getBySel('form-item-value').should('have.length', 0); cy.getBySel('form-item-value').should('have.length', 1);
openMoreFilters(false); openMoreFilters(false);
cy.getBySel('form-item-value').should('have.length', 3); cy.getBySel('form-item-value').should('have.length', 3);

View File

@ -264,6 +264,9 @@ describe('Native filters', () => {
it('User can expand / retract native filter sidebar on a dashboard', () => { it('User can expand / retract native filter sidebar on a dashboard', () => {
expandFilterOnLeftPanel(); expandFilterOnLeftPanel();
cy.get(nativeFilters.filtersPanel.filterGear).click({
force: true,
});
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).should( cy.get(nativeFilters.filterFromDashboardView.createFilterButton).should(
'be.visible', 'be.visible',
); );

View File

@ -228,6 +228,9 @@ export function collapseFilterOnLeftPanel() {
************************************************************************* */ ************************************************************************* */
export function enterNativeFilterEditModal(waitForDataset = true) { export function enterNativeFilterEditModal(waitForDataset = true) {
interceptDataset(); interceptDataset();
cy.get(nativeFilters.filtersPanel.filterGear).click({
force: true,
});
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click({ cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click({
force: true, force: true,
}); });

View File

@ -346,6 +346,7 @@ export const nativeFilters = {
filterTypeInput: dataTestLocator('filters-config-modal__filter-type'), filterTypeInput: dataTestLocator('filters-config-modal__filter-type'),
fieldInput: dataTestLocator('field-input'), fieldInput: dataTestLocator('field-input'),
filterTypeItem: '.ant-select-selection-item', filterTypeItem: '.ant-select-selection-item',
filterGear: dataTestLocator('filterbar-orientation-icon'),
}, },
filterFromDashboardView: { filterFromDashboardView: {
filterValueInput: '[class="ant-select-selection-search-input"]', filterValueInput: '[class="ant-select-selection-search-input"]',

View File

@ -75,7 +75,8 @@ const FILTER_NAME = 'Time filter 1';
const addFilterFlow = async () => { const addFilterFlow = async () => {
// open filter config modal // open filter config modal
userEvent.click(screen.getByTestId(getTestId('collapsable'))); userEvent.click(screen.getByTestId(getTestId('collapsable')));
userEvent.click(screen.getByTestId(getTestId('create-filter'))); userEvent.click(screen.getByLabelText('gear'));
userEvent.click(screen.getByText('Add or edit filters'));
// select filter // select filter
userEvent.click(screen.getByText('Value')); userEvent.click(screen.getByText('Value'));
userEvent.click(screen.getByText('Time range')); userEvent.click(screen.getByText('Time range'));

View File

@ -31,7 +31,7 @@ const initialState: { dashboardInfo: DashboardInfo } = {
id: 1, id: 1,
userId: '1', userId: '1',
metadata: { metadata: {
native_filter_configuration: {}, native_filter_configuration: [{}],
chart_configuration: {}, chart_configuration: {},
global_chart_configuration: { global_chart_configuration: {
scope: { rootPath: ['ROOT_ID'], excluded: [] }, scope: { rootPath: ['ROOT_ID'], excluded: [] },
@ -81,15 +81,6 @@ test('Dropdown trigger renders with FF HORIZONTAL_FILTER_BAR on', async () => {
expect(screen.getByLabelText('gear')).toBeVisible(); expect(screen.getByLabelText('gear')).toBeVisible();
}); });
test('Dropdown trigger does not render with FF HORIZONTAL_FILTER_BAR off', async () => {
// @ts-ignore
global.featureFlags = {
[FeatureFlag.HorizontalFilterBar]: false,
};
await setup();
expect(screen.queryByLabelText('gear')).not.toBeInTheDocument();
});
test('Dropdown trigger renders with dashboard edit permissions', async () => { test('Dropdown trigger renders with dashboard edit permissions', async () => {
// @ts-ignore // @ts-ignore
global.featureFlags = { global.featureFlags = {
@ -128,7 +119,9 @@ test('Dropdown trigger does not render with FF DASHBOARD_CROSS_FILTERS off', asy
global.featureFlags = { global.featureFlags = {
[FeatureFlag.DashboardCrossFilters]: false, [FeatureFlag.DashboardCrossFilters]: false,
}; };
await setup(); await setup({
dash_edit_perm: false,
});
expect(screen.queryByRole('img', { name: 'gear' })).not.toBeInTheDocument(); expect(screen.queryByRole('img', { name: 'gear' })).not.toBeInTheDocument();
}); });
@ -175,7 +168,7 @@ test('Popover opens with "Vertical" selected', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument(); expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument(); expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'), within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
@ -190,7 +183,7 @@ test('Popover opens with "Horizontal" selected', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument(); expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument(); expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'), within(screen.getAllByRole('menuitem')[3]).getByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
@ -216,20 +209,20 @@ test('On selection change, send request and update checked value', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument(); expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument(); expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'), within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'), within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
userEvent.click(screen.getByText('Horizontal (Top)')); userEvent.click(screen.getByText('Horizontal (Top)'));
// 1st check - checkmark appears immediately after click // 1st check - checkmark appears immediately after click
expect( expect(
await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'), await within(screen.getAllByRole('menuitem')[3]).findByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[1]).queryByLabelText('check'), within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
// successful query // successful query
@ -246,10 +239,10 @@ test('On selection change, send request and update checked value', async () => {
// 2nd check - checkmark stays after successful query // 2nd check - checkmark stays after successful query
expect( expect(
await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'), await within(screen.getAllByRole('menuitem')[3]).findByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[1]).queryByLabelText('check'), within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
fetchMock.reset(); fetchMock.reset();
@ -273,10 +266,10 @@ test('On failed request, restore previous selection', async () => {
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument(); expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'), within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'), within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
userEvent.click(await screen.findByText('Horizontal (Top)')); userEvent.click(await screen.findByText('Horizontal (Top)'));
@ -294,10 +287,10 @@ test('On failed request, restore previous selection', async () => {
// checkmark gets rolled back to the original selection after successful query // checkmark gets rolled back to the original selection after successful query
expect( expect(
await within(screen.getAllByRole('menuitem')[1]).findByLabelText('check'), await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'),
).toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'), within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
fetchMock.reset(); fetchMock.reset();

View File

@ -38,7 +38,9 @@ import DropdownSelectableIcon, {
} from 'src/components/DropdownSelectableIcon'; } from 'src/components/DropdownSelectableIcon';
import Checkbox from 'src/components/Checkbox'; import Checkbox from 'src/components/Checkbox';
import { clearDataMaskState } from 'src/dataMask/actions'; import { clearDataMaskState } from 'src/dataMask/actions';
import { useFilters } from 'src/dashboard/components/nativeFilters/FilterBar/state';
import { useCrossFiltersScopingModal } from '../CrossFilters/ScopingModal/useCrossFiltersScopingModal'; import { useCrossFiltersScopingModal } from '../CrossFilters/ScopingModal/useCrossFiltersScopingModal';
import FilterConfigurationLink from '../FilterConfigurationLink';
type SelectedKey = FilterBarOrientation | string | number; type SelectedKey = FilterBarOrientation | string | number;
@ -65,6 +67,7 @@ const StyledCheckbox = styled(Checkbox)`
const CROSS_FILTERS_MENU_KEY = 'cross-filters-menu-key'; const CROSS_FILTERS_MENU_KEY = 'cross-filters-menu-key';
const CROSS_FILTERS_SCOPING_MENU_KEY = 'cross-filters-scoping-menu-key'; const CROSS_FILTERS_SCOPING_MENU_KEY = 'cross-filters-scoping-menu-key';
const ADD_EDIT_FILTERS_MENU_KEY = 'add-edit-filters-menu-key';
const isOrientation = (o: SelectedKey): o is FilterBarOrientation => const isOrientation = (o: SelectedKey): o is FilterBarOrientation =>
o === FilterBarOrientation.Vertical || o === FilterBarOrientation.Horizontal; o === FilterBarOrientation.Vertical || o === FilterBarOrientation.Horizontal;
@ -91,6 +94,11 @@ const FilterBarSettings = () => {
const canEdit = useSelector<RootState, boolean>( const canEdit = useSelector<RootState, boolean>(
({ dashboardInfo }) => dashboardInfo.dash_edit_perm, ({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
); );
const filters = useFilters();
const filterValues = useMemo(() => Object.values(filters), [filters]);
const dashboardId = useSelector<RootState, number>(
({ dashboardInfo }) => dashboardInfo.id,
);
const canSetHorizontalFilterBar = const canSetHorizontalFilterBar =
canEdit && isFeatureEnabled(FeatureFlag.HorizontalFilterBar); canEdit && isFeatureEnabled(FeatureFlag.HorizontalFilterBar);
@ -166,6 +174,20 @@ const FilterBarSettings = () => {
const menuItems = useMemo(() => { const menuItems = useMemo(() => {
const items: DropDownSelectableProps['menuItems'] = []; const items: DropDownSelectableProps['menuItems'] = [];
if (canEdit) {
items.push({
key: ADD_EDIT_FILTERS_MENU_KEY,
label: (
<FilterConfigurationLink
dashboardId={dashboardId}
createNewOnOpen={filterValues.length === 0}
>
{t('Add or edit filters')}
</FilterConfigurationLink>
),
divider: canSetHorizontalFilterBar,
});
}
if (isCrossFiltersFeatureEnabled && canEdit) { if (isCrossFiltersFeatureEnabled && canEdit) {
items.push({ items.push({
key: CROSS_FILTERS_MENU_KEY, key: CROSS_FILTERS_MENU_KEY,
@ -177,7 +199,6 @@ const FilterBarSettings = () => {
divider: canSetHorizontalFilterBar, divider: canSetHorizontalFilterBar,
}); });
} }
if (canSetHorizontalFilterBar) { if (canSetHorizontalFilterBar) {
items.push({ items.push({
key: 'placement', key: 'placement',
@ -199,6 +220,8 @@ const FilterBarSettings = () => {
canEdit, canEdit,
canSetHorizontalFilterBar, canSetHorizontalFilterBar,
crossFiltersMenuItem, crossFiltersMenuItem,
dashboardId,
filterValues,
isCrossFiltersFeatureEnabled, isCrossFiltersFeatureEnabled,
]); ]);

View File

@ -20,8 +20,6 @@ import { ReactNode, FC, useCallback, useState, memo } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { setFilterConfiguration } from 'src/dashboard/actions/nativeFilters'; import { setFilterConfiguration } from 'src/dashboard/actions/nativeFilters';
import Button from 'src/components/Button';
import { styled } from '@superset-ui/core';
import FiltersConfigModal from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal'; import FiltersConfigModal from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal';
import { getFilterBarTestId } from '../utils'; import { getFilterBarTestId } from '../utils';
import { SaveFilterChangesType } from '../../FiltersConfigModal/types'; import { SaveFilterChangesType } from '../../FiltersConfigModal/types';
@ -34,10 +32,6 @@ export interface FCBProps {
children?: ReactNode; children?: ReactNode;
} }
const HeaderButton = styled(Button)`
padding: 0;
`;
export const FilterConfigurationLink: FC<FCBProps> = ({ export const FilterConfigurationLink: FC<FCBProps> = ({
createNewOnOpen, createNewOnOpen,
dashboardId, dashboardId,
@ -69,14 +63,9 @@ export const FilterConfigurationLink: FC<FCBProps> = ({
return ( return (
<> <>
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */} {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<HeaderButton <span {...getFilterBarTestId('create-filter')} onClick={handleClick}>
{...getFilterBarTestId('create-filter')}
buttonStyle="link"
buttonSize="xsmall"
onClick={handleClick}
>
{children} {children}
</HeaderButton> </span>
<FiltersConfigModal <FiltersConfigModal
isOpen={isOpen} isOpen={isOpen}
onSave={submit} onSave={submit}

View File

@ -18,13 +18,9 @@
*/ */
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import { css, styled, t, useTheme } from '@superset-ui/core'; import { css, styled, t, useTheme } from '@superset-ui/core';
import { memo, FC, useMemo } from 'react'; import { memo, FC } from 'react';
import Icons from 'src/components/Icons'; import Icons from 'src/components/Icons';
import Button from 'src/components/Button'; import Button from 'src/components/Button';
import { useSelector } from 'react-redux';
import FilterConfigurationLink from 'src/dashboard/components/nativeFilters/FilterBar/FilterConfigurationLink';
import { useFilters } from 'src/dashboard/components/nativeFilters/FilterBar/state';
import { RootState } from 'src/dashboard/types';
import { getFilterBarTestId } from '../utils'; import { getFilterBarTestId } from '../utils';
import FilterBarSettings from '../FilterBarSettings'; import FilterBarSettings from '../FilterBarSettings';
@ -62,7 +58,6 @@ const Wrapper = styled.div`
padding: ${theme.gridUnit * 3}px ${theme.gridUnit * 2}px ${ padding: ${theme.gridUnit * 3}px ${theme.gridUnit * 2}px ${
theme.gridUnit theme.gridUnit
}px; }px;
.ant-dropdown-trigger span { .ant-dropdown-trigger span {
padding-right: ${theme.gridUnit * 2}px; padding-right: ${theme.gridUnit * 2}px;
} }
@ -73,35 +68,8 @@ type HeaderProps = {
toggleFiltersBar: (arg0: boolean) => void; toggleFiltersBar: (arg0: boolean) => void;
}; };
const AddFiltersButtonContainer = styled.div`
${({ theme }) => css`
margin-top: ${theme.gridUnit * 2}px;
& button > [role='img']:first-of-type {
margin-right: ${theme.gridUnit}px;
line-height: 0;
}
span[role='img'] {
padding-bottom: 1px;
}
.ant-btn > .anticon + span {
margin-left: 0;
}
`}
`;
const Header: FC<HeaderProps> = ({ toggleFiltersBar }) => { const Header: FC<HeaderProps> = ({ toggleFiltersBar }) => {
const theme = useTheme(); const theme = useTheme();
const filters = useFilters();
const filterValues = useMemo(() => Object.values(filters), [filters]);
const canEdit = useSelector<RootState, boolean>(
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
);
const dashboardId = useSelector<RootState, number>(
({ dashboardInfo }) => dashboardInfo.id,
);
return ( return (
<Wrapper> <Wrapper>
@ -117,16 +85,6 @@ const Header: FC<HeaderProps> = ({ toggleFiltersBar }) => {
<Icons.Expand iconColor={theme.colors.grayscale.base} /> <Icons.Expand iconColor={theme.colors.grayscale.base} />
</HeaderButton> </HeaderButton>
</TitleArea> </TitleArea>
{canEdit && (
<AddFiltersButtonContainer>
<FilterConfigurationLink
dashboardId={dashboardId}
createNewOnOpen={filterValues.length === 0}
>
<Icons.PlusSmall /> {t('Add/Edit Filters')}
</FilterConfigurationLink>
</AddFiltersButtonContainer>
)}
</Wrapper> </Wrapper>
); );
}; };

View File

@ -25,7 +25,6 @@ import {
styled, styled,
t, t,
} from '@superset-ui/core'; } from '@superset-ui/core';
import Icons from 'src/components/Icons';
import Loading from 'src/components/Loading'; import Loading from 'src/components/Loading';
import { RootState } from 'src/dashboard/types'; import { RootState } from 'src/dashboard/types';
import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems'; import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems';
@ -35,7 +34,6 @@ import FilterControls from './FilterControls/FilterControls';
import { useChartsVerboseMaps, getFilterBarTestId } from './utils'; import { useChartsVerboseMaps, getFilterBarTestId } from './utils';
import { HorizontalBarProps } from './types'; import { HorizontalBarProps } from './types';
import FilterBarSettings from './FilterBarSettings'; import FilterBarSettings from './FilterBarSettings';
import FilterConfigurationLink from './FilterConfigurationLink';
import crossFiltersSelector from './CrossFilters/selectors'; import crossFiltersSelector from './CrossFilters/selectors';
import { CrossFilterIndicator } from '../selectors'; import { CrossFilterIndicator } from '../selectors';
@ -70,39 +68,13 @@ const FilterBarEmptyStateContainer = styled.div`
font-weight: ${theme.typography.weights.bold}; font-weight: ${theme.typography.weights.bold};
color: ${theme.colors.grayscale.base}; color: ${theme.colors.grayscale.base};
font-size: ${theme.typography.sizes.s}px; font-size: ${theme.typography.sizes.s}px;
`} padding-left: ${theme.gridUnit * 2}px;
`;
const FiltersLinkContainer = styled.div<{ hasFilters: boolean }>`
${({ theme, hasFilters }) => `
height: 24px;
display: flex;
align-items: center;
padding: 0 ${theme.gridUnit * 4}px 0 ${theme.gridUnit * 4}px;
border-right: ${
hasFilters ? `1px solid ${theme.colors.grayscale.light2}` : 0
};
button {
display: flex;
align-items: center;
> .anticon {
height: 24px;
padding-right: ${theme.gridUnit}px;
}
> .anticon + span, > .anticon {
margin-right: 0;
margin-left: 0;
}
}
`} `}
`; `;
const EMPTY_ARRAY: CrossFilterIndicator[] = []; const EMPTY_ARRAY: CrossFilterIndicator[] = [];
const HorizontalFilterBar: FC<HorizontalBarProps> = ({ const HorizontalFilterBar: FC<HorizontalBarProps> = ({
actions, actions,
canEdit,
dashboardId,
dataMaskSelected, dataMaskSelected,
filterValues, filterValues,
isInitialized, isInitialized,
@ -141,16 +113,6 @@ const HorizontalFilterBar: FC<HorizontalBarProps> = ({
) : ( ) : (
<> <>
<FilterBarSettings /> <FilterBarSettings />
{canEdit && (
<FiltersLinkContainer hasFilters={hasFilters}>
<FilterConfigurationLink
dashboardId={dashboardId}
createNewOnOpen={filterValues.length === 0}
>
<Icons.PlusSmall /> {t('Add/Edit Filters')}
</FilterConfigurationLink>
</FiltersLinkContainer>
)}
{!hasFilters && ( {!hasFilters && (
<FilterBarEmptyStateContainer data-test="horizontal-filterbar-empty"> <FilterBarEmptyStateContainer data-test="horizontal-filterbar-empty">
{t('No filters are currently added to this dashboard.')} {t('No filters are currently added to this dashboard.')}

View File

@ -81,15 +81,3 @@ test('should render the loading icon', async () => {
}); });
expect(screen.getByRole('status', { name: 'Loading' })).toBeInTheDocument(); expect(screen.getByRole('status', { name: 'Loading' })).toBeInTheDocument();
}); });
test('should render Add/Edit Filters', async () => {
await renderWrapper();
expect(screen.getByText('Add/Edit Filters')).toBeInTheDocument();
});
test('should not render Add/Edit Filters', async () => {
await renderWrapper({
canEdit: false,
});
expect(screen.queryByText('Add/Edit Filters')).not.toBeInTheDocument();
});

View File

@ -174,7 +174,7 @@ const VerticalFilterBar: FC<VerticalBarProps> = ({
description={ description={
canEdit && canEdit &&
t( t(
'Click on "+Add/Edit Filters" button to create new dashboard filters', 'Click on "Add or Edit Filters" option in Settings to create new dashboard filters',
) )
} }
/> />

View File

@ -306,9 +306,7 @@ test('focus filter on filter card dependency click', () => {
test('edit filter button for dashboard viewer', () => { test('edit filter button for dashboard viewer', () => {
renderContent(); renderContent();
expect( expect(screen.queryByRole('img', { name: /edit/i })).not.toBeInTheDocument();
screen.queryByRole('button', { name: /edit/i }),
).not.toBeInTheDocument();
}); });
test('edit filter button for dashboard editor', () => { test('edit filter button for dashboard editor', () => {
@ -317,7 +315,7 @@ test('edit filter button for dashboard editor', () => {
dashboardInfo: { dash_edit_perm: true }, dashboardInfo: { dash_edit_perm: true },
}); });
expect(screen.getByRole('button', { name: /edit/i })).toBeVisible(); expect(screen.getByRole('img', { name: /edit/i })).toBeVisible();
}); });
test('open modal on edit filter button click', async () => { test('open modal on edit filter button click', async () => {
@ -326,7 +324,7 @@ test('open modal on edit filter button click', async () => {
dashboardInfo: { dash_edit_perm: true }, dashboardInfo: { dash_edit_perm: true },
}); });
const editButton = screen.getByRole('button', { name: /edit/i }); const editButton = screen.getByRole('img', { name: /edit/i });
userEvent.click(editButton); userEvent.click(editButton);
expect( expect(
await screen.findByRole('dialog', { name: /add and edit filters/i }), await screen.findByRole('dialog', { name: /add and edit filters/i }),

View File

@ -62,7 +62,13 @@ export const NameRow = ({
onClick={hidePopover} onClick={hidePopover}
initialFilterId={filter.id} initialFilterId={filter.id}
> >
<Icons.Edit iconSize="l" iconColor={theme.colors.grayscale.light1} /> <Icons.Edit
iconSize="l"
iconColor={theme.colors.grayscale.light1}
css={() => css`
cursor: pointer;
`}
/>
</FilterConfigurationLink> </FilterConfigurationLink>
)} )}
</Row> </Row>