Skip to content
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

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

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ describe('Horizontal FilterBar', () => {
cy.getBySel('horizontal-filterbar-empty')
.contains('No filters are currently added to this dashboard.')
.should('exist');
cy.get(nativeFilters.filtersPanel.filterGear).click({
force: true,
});
cy.getBySel('filter-bar__create-filter').should('exist');
cy.getBySel('filterbar-action-buttons').should('exist');
});
Expand All @@ -110,7 +113,7 @@ describe('Horizontal FilterBar', () => {
cy.get('.filter-item-wrapper').should('have.length', 3);
});

it('should show "more filters" on window resizing up and down', () => {
it.only('should show "more filters" on window resizing up and down', () => {
geido marked this conversation as resolved.
Show resolved Hide resolved
prepareDashboardFilters([
{ name: 'test_1', column: 'country_name', datasetId: 2 },
{ name: 'test_2', column: 'country_code', datasetId: 2 },
Expand All @@ -120,7 +123,7 @@ describe('Horizontal FilterBar', () => {

cy.getBySel('form-item-value').should('have.length', 3);
cy.viewport(768, 1024);
cy.getBySel('form-item-value').should('have.length', 0);
cy.getBySel('form-item-value').should('have.length', 1);
openMoreFilters(false);
cy.getBySel('form-item-value').should('have.length', 3);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ describe('Native filters', () => {

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

it('Verify setting options and tooltips for value filter', () => {
it.only('Verify setting options and tooltips for value filter', () => {
geido marked this conversation as resolved.
Show resolved Hide resolved
enterNativeFilterEditModal(false);
cy.contains('Filter value is required').should('be.visible').click();
checkNativeFilterTooltip(0, nativeFilterTooltips.preFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ export function collapseFilterOnLeftPanel() {
************************************************************************* */
export function enterNativeFilterEditModal(waitForDataset = true) {
interceptDataset();
cy.get(nativeFilters.filtersPanel.filterGear).click({
force: true,
});
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click({
force: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export const nativeFilters = {
filterTypeInput: dataTestLocator('filters-config-modal__filter-type'),
fieldInput: dataTestLocator('field-input'),
filterTypeItem: '.ant-select-selection-item',
filterGear: dataTestLocator('filterbar-orientation-icon'),
},
filterFromDashboardView: {
filterValueInput: '[class="ant-select-selection-search-input"]',
Expand Down
1 change: 1 addition & 0 deletions superset-frontend/cypress-base/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const { getConfig, setConfig } = failOnConsoleError({
'The pseudo class ":nth-child" is potentially unsafe when doing server-side rendering. Try changing it to ":nth-of-type".',
'Error: Unknown Error',
/Unable to infer path to ace from script src/,
/$/,
geido marked this conversation as resolved.
Show resolved Hide resolved
],
});

Expand Down
4 changes: 2 additions & 2 deletions superset-frontend/cypress-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"brace": "^0.11.1",
"cy-verify-downloads": "^0.2.5",
"cypress-fail-on-console-error": "^4.0.3",
"nanoid": "^5.0.7",
"querystringify": "^2.2.0",
"react-dom": "^16.13.0",
"rison": "^0.1.1",
"nanoid": "^5.0.7"
"rison": "^0.1.1"
},
"devDependencies": {
"@types/querystringify": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ const FILTER_NAME = 'Time filter 1';
const addFilterFlow = async () => {
// open filter config modal
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
userEvent.click(screen.getByText('Value'));
userEvent.click(screen.getByText('Time range'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const initialState: { dashboardInfo: DashboardInfo } = {
id: 1,
userId: '1',
metadata: {
native_filter_configuration: {},
native_filter_configuration: [{}],
chart_configuration: {},
global_chart_configuration: {
scope: { rootPath: ['ROOT_ID'], excluded: [] },
Expand Down Expand Up @@ -81,15 +81,6 @@ test('Dropdown trigger renders with FF HORIZONTAL_FILTER_BAR on', async () => {
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 () => {
// @ts-ignore
global.featureFlags = {
Expand Down Expand Up @@ -128,7 +119,9 @@ test('Dropdown trigger does not render with FF DASHBOARD_CROSS_FILTERS off', asy
global.featureFlags = {
[FeatureFlag.DashboardCrossFilters]: false,
};
await setup();
await setup({
dash_edit_perm: false,
});

expect(screen.queryByRole('img', { name: 'gear' })).not.toBeInTheDocument();
});
Expand Down Expand Up @@ -175,7 +168,7 @@ test('Popover opens with "Vertical" selected', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'),
within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument();
});

Expand All @@ -190,7 +183,7 @@ test('Popover opens with "Horizontal" selected', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
within(screen.getAllByRole('menuitem')[3]).getByLabelText('check'),
).toBeInTheDocument();
});

Expand All @@ -216,20 +209,20 @@ test('On selection change, send request and update checked value', async () => {
expect(await screen.findByText('Vertical (Left)')).toBeInTheDocument();
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'),
within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument();

userEvent.click(screen.getByText('Horizontal (Top)'));

// 1st check - checkmark appears immediately after click
expect(
await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'),
await within(screen.getAllByRole('menuitem')[3]).findByLabelText('check'),
).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[1]).queryByLabelText('check'),
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
).not.toBeInTheDocument();

// successful query
Expand All @@ -246,10 +239,10 @@ test('On selection change, send request and update checked value', async () => {

// 2nd check - checkmark stays after successful query
expect(
await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'),
await within(screen.getAllByRole('menuitem')[3]).findByLabelText('check'),
).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[1]).queryByLabelText('check'),
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
).not.toBeInTheDocument();

fetchMock.reset();
Expand All @@ -273,10 +266,10 @@ test('On failed request, restore previous selection', async () => {
expect(screen.getByText('Horizontal (Top)')).toBeInTheDocument();

expect(
within(screen.getAllByRole('menuitem')[1]).getByLabelText('check'),
within(screen.getAllByRole('menuitem')[2]).getByLabelText('check'),
).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument();

userEvent.click(await screen.findByText('Horizontal (Top)'));
Expand All @@ -294,10 +287,10 @@ test('On failed request, restore previous selection', async () => {

// checkmark gets rolled back to the original selection after successful query
expect(
await within(screen.getAllByRole('menuitem')[1]).findByLabelText('check'),
await within(screen.getAllByRole('menuitem')[2]).findByLabelText('check'),
).toBeInTheDocument();
expect(
within(screen.getAllByRole('menuitem')[2]).queryByLabelText('check'),
within(screen.getAllByRole('menuitem')[3]).queryByLabelText('check'),
).not.toBeInTheDocument();

fetchMock.reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ import DropdownSelectableIcon, {
} from 'src/components/DropdownSelectableIcon';
import Checkbox from 'src/components/Checkbox';
import { clearDataMaskState } from 'src/dataMask/actions';
import { useFilters } from 'src/dashboard/components/nativeFilters/FilterBar/state';
import { useCrossFiltersScopingModal } from '../CrossFilters/ScopingModal/useCrossFiltersScopingModal';
import FilterConfigurationLink from '../FilterConfigurationLink';

type SelectedKey = FilterBarOrientation | string | number;

Expand All @@ -65,6 +67,7 @@ const StyledCheckbox = styled(Checkbox)`

const CROSS_FILTERS_MENU_KEY = 'cross-filters-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 =>
o === FilterBarOrientation.Vertical || o === FilterBarOrientation.Horizontal;
Expand All @@ -91,6 +94,11 @@ const FilterBarSettings = () => {
const canEdit = useSelector<RootState, boolean>(
({ 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 =
canEdit && isFeatureEnabled(FeatureFlag.HorizontalFilterBar);

Expand Down Expand Up @@ -166,6 +174,20 @@ const FilterBarSettings = () => {
const menuItems = useMemo(() => {
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) {
items.push({
key: CROSS_FILTERS_MENU_KEY,
Expand All @@ -177,7 +199,6 @@ const FilterBarSettings = () => {
divider: canSetHorizontalFilterBar,
});
}

if (canSetHorizontalFilterBar) {
items.push({
key: 'placement',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import { ReactNode, FC, useCallback, useState, memo } from 'react';

import { useDispatch } from 'react-redux';
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 { getFilterBarTestId } from '../utils';
import { SaveFilterChangesType } from '../../FiltersConfigModal/types';
Expand All @@ -34,10 +32,6 @@ export interface FCBProps {
children?: ReactNode;
}

const HeaderButton = styled(Button)`
padding: 0;
`;

export const FilterConfigurationLink: FC<FCBProps> = ({
createNewOnOpen,
dashboardId,
Expand Down Expand Up @@ -69,14 +63,9 @@ export const FilterConfigurationLink: FC<FCBProps> = ({
return (
<>
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<HeaderButton
{...getFilterBarTestId('create-filter')}
buttonStyle="link"
buttonSize="xsmall"
onClick={handleClick}
>
<span {...getFilterBarTestId('create-filter')} onClick={handleClick}>
{children}
</HeaderButton>
</span>
<FiltersConfigModal
isOpen={isOpen}
onSave={submit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@
*/
/* eslint-disable no-param-reassign */
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 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 FilterBarSettings from '../FilterBarSettings';

Expand Down Expand Up @@ -73,35 +69,8 @@ type HeaderProps = {
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 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 (
<Wrapper>
Expand All @@ -117,16 +86,6 @@ const Header: FC<HeaderProps> = ({ toggleFiltersBar }) => {
<Icons.Expand iconColor={theme.colors.grayscale.base} />
</HeaderButton>
</TitleArea>
{canEdit && (
<AddFiltersButtonContainer>
<FilterConfigurationLink
dashboardId={dashboardId}
createNewOnOpen={filterValues.length === 0}
>
<Icons.PlusSmall /> {t('Add/Edit Filters')}
</FilterConfigurationLink>
</AddFiltersButtonContainer>
)}
</Wrapper>
);
};
Expand Down
Loading
Loading