test: Adds tests to the filter scope components (#13887)

This commit is contained in:
Michael S. Molina 2021-04-07 01:31:35 -03:00 committed by GitHub
parent 3b11654c5a
commit 4602ead10c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 465 additions and 79 deletions

View File

@ -19,8 +19,8 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
import { mount } from 'enzyme';
import { ThemeProvider, supersetTheme } from '@superset-ui/core';
import CheckboxControl from 'src/explore/components/controls/CheckboxControl';
import ControlHeader from 'src/explore/components/ControlHeader';
import Checkbox from 'src/components/Checkbox';
@ -36,20 +36,21 @@ describe('CheckboxControl', () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<CheckboxControl {...defaultProps} />);
wrapper = mount(
<ThemeProvider theme={supersetTheme}>
<CheckboxControl {...defaultProps} />
</ThemeProvider>,
);
});
it('renders a Checkbox', () => {
const controlHeader = wrapper.find(ControlHeader);
const controlHeader = wrapper.childAt(0).find(ControlHeader);
expect(controlHeader).toHaveLength(1);
const headerWrapper = controlHeader.shallow();
expect(headerWrapper.find(Checkbox)).toHaveLength(1);
expect(controlHeader.find(Checkbox)).toHaveLength(1);
});
it('Checks the box when the label is clicked', () => {
const fullComponent = mount(<CheckboxControl {...defaultProps} />);
const fullComponent = wrapper.childAt(0);
const spy = sinon.spy(fullComponent.instance(), 'onChange');
fullComponent.instance().forceUpdate();

View File

@ -17,51 +17,64 @@
* under the License.
*/
import React from 'react';
import { useTheme } from '@superset-ui/core';
export const CheckboxChecked = () => (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.89 0 0 0.9 0 2V16C0 17.1 0.89 18 2 18H16C17.11 18 18 17.1 18 16V2C18 0.9 17.11 0 16 0Z"
fill="#20A7C9"
/>
<path d="M7 14L2 9L3.41 7.59L7 11.17L14.59 3.58L16 5L7 14Z" fill="white" />
</svg>
);
export const CheckboxChecked = () => {
const theme = useTheme();
return (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.89 0 0 0.9 0 2V16C0 17.1 0.89 18 2 18H16C17.11 18 18 17.1 18 16V2C18 0.9 17.11 0 16 0Z"
fill={theme.colors.primary.base}
/>
<path
d="M7 14L2 9L3.41 7.59L7 11.17L14.59 3.58L16 5L7 14Z"
fill="white"
/>
</svg>
);
};
export const CheckboxHalfChecked = () => (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
fill="#999999"
/>
<path d="M14 10H4V8H14V10Z" fill="white" />
</svg>
);
export const CheckboxHalfChecked = () => {
const theme = useTheme();
return (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
fill={theme.colors.grayscale.light1}
/>
<path d="M14 10H4V8H14V10Z" fill="white" />
</svg>
);
};
export const CheckboxUnchecked = () => (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
fill="#CCCCCC"
/>
<path d="M16 2V16H2V2H16V2Z" fill="white" />
</svg>
);
export const CheckboxUnchecked = () => {
const theme = useTheme();
return (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
fill={theme.colors.grayscale.light2}
/>
<path d="M16 2V16H2V2H16V2Z" fill="white" />
</svg>
);
};

View File

@ -19,7 +19,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import FormLabel from 'src/components/FormLabel';
const propTypes = {

View File

@ -19,10 +19,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import CheckboxTree from 'react-checkbox-tree';
import { filterScopeSelectorTreeNodePropShape } from 'src/dashboard/util/propShapes';
import treeIcons from './treeIcons';
import renderFilterFieldTreeNodes from './renderFilterFieldTreeNodes';
import { filterScopeSelectorTreeNodePropShape } from '../../util/propShapes';
const propTypes = {
activeKey: PropTypes.string,

View File

@ -0,0 +1,373 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { supersetTheme } from '@superset-ui/core';
import { render, screen } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import FilterScopeSelector from './FilterScopeSelector';
const ROOT_ID = 'ROOT_ID';
const GRID = 'GRID';
const TABS = 'TABS';
const TAB = 'TAB';
const FILTER_A = 'FILTER_A';
const FILTER_B = 'FILTER_B';
const FILTER_C = 'FILTER_C';
const TAB_A = 'TAB_A';
const TAB_B = 'TAB_B';
const CHART_A = 'CHART_A';
const CHART_B = 'CHART_B';
const CHART_C = 'CHART_C';
const CHART_D = 'CHART_D';
const EXPAND_ALL = 'Expand all';
const COLLAPSE_ALL = 'Collapse all';
const CHECKED = 'checked';
const UNCHECKED = 'unchecked';
const INDETERMINATE = 'indeterminate';
const ALL_FILTERS = 'All filters';
const ALL_CHARTS = 'All charts';
const createProps = () => ({
dashboardFilters: {
1: {
chartId: 1,
componentId: 'component-id',
datasourceId: 'datasource-id',
directPathToFilter: [],
isDateFilter: false,
isInstantFilter: false,
filterName: FILTER_A,
columns: { column_b: undefined, column_c: undefined },
labels: { column_b: FILTER_B, column_c: FILTER_C },
scopes: {
column_b: { immune: [], scope: [ROOT_ID] },
column_c: { immune: [], scope: [ROOT_ID] },
},
},
},
layout: {
ROOT_ID: { children: [GRID], id: ROOT_ID, type: 'ROOT' },
GRID: {
children: [TABS],
id: GRID,
type: GRID,
parents: [ROOT_ID],
},
TABS: {
children: [TAB_A, TAB_B],
id: TABS,
type: TABS,
parents: [ROOT_ID, GRID],
},
TAB_A: {
meta: { text: TAB_A },
children: [CHART_A, CHART_B],
id: TAB_A,
type: TAB,
parents: [ROOT_ID, GRID, TABS],
},
TAB_B: {
meta: { text: TAB_B },
children: [CHART_C, CHART_D],
id: TAB_B,
type: TAB,
parents: [ROOT_ID, GRID, TABS],
},
CHART_A: {
meta: {
chartId: 2,
sliceName: CHART_A,
},
children: [],
id: CHART_A,
type: 'CHART',
parents: [ROOT_ID, GRID, TABS, TAB_A],
},
CHART_B: {
meta: {
chartId: 3,
sliceName: CHART_B,
},
children: [],
id: CHART_B,
type: 'CHART',
parents: [ROOT_ID, GRID, TABS, TAB_A],
},
CHART_C: {
meta: {
chartId: 4,
sliceName: CHART_C,
},
children: [],
id: CHART_C,
type: 'CHART',
parents: [ROOT_ID, GRID, TABS, TAB_B],
},
CHART_D: {
meta: {
chartId: 5,
sliceName: CHART_D,
},
children: [],
id: CHART_D,
type: 'CHART',
parents: [ROOT_ID, GRID, TABS, TAB_B],
},
},
updateDashboardFiltersScope: jest.fn(),
setUnsavedChanges: jest.fn(),
onCloseModal: jest.fn(),
});
type CheckboxState = 'checked' | 'unchecked' | 'indeterminate';
/**
* Unfortunatelly react-checkbox-tree doesn't provide an easy way to
* access the checkbox icon. We need this function to find the element.
*/
function getCheckboxIcon(element: HTMLElement): Element {
const parent = element.parentElement!;
if (parent.classList.contains('rct-text')) {
return parent.children[1];
}
return getCheckboxIcon(parent);
}
/**
* Unfortunatelly when using react-checkbox-tree, the only perceived change of a
* checkbox state change is the fill color of the SVG icon.
*/
function getCheckboxState(name: string): CheckboxState {
const element = screen.getByRole('link', { name });
const svgPath = getCheckboxIcon(element).children[1].children[0].children[0];
const fill = svgPath.getAttribute('fill');
return fill === supersetTheme.colors.primary.base
? CHECKED
: fill === supersetTheme.colors.grayscale.light1
? INDETERMINATE
: UNCHECKED;
}
function clickCheckbox(name: string) {
const element = screen.getByRole('link', { name });
const checkboxLabel = getCheckboxIcon(element);
userEvent.click(checkboxLabel);
}
test('renders with empty filters', () => {
render(<FilterScopeSelector {...createProps()} dashboardFilters={{}} />, {
useRedux: true,
});
expect(screen.getByText('Configure filter scopes')).toBeInTheDocument();
expect(
screen.getByText('There are no filters in this dashboard.'),
).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument();
expect(
screen.queryByRole('button', { name: 'Save' }),
).not.toBeInTheDocument();
});
test('renders with filters values', () => {
render(<FilterScopeSelector {...createProps()} />, { useRedux: true });
expect(screen.getByRole('link', { name: FILTER_A })).toBeInTheDocument();
expect(screen.getByRole('link', { name: FILTER_B })).toBeInTheDocument();
expect(screen.getByRole('link', { name: FILTER_C })).toBeInTheDocument();
expect(screen.getByRole('link', { name: TAB_A })).toBeInTheDocument();
expect(screen.getByRole('link', { name: TAB_B })).toBeInTheDocument();
expect(screen.queryByText(CHART_A)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_B)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_C)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_D)).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument();
});
test('collapses/expands all filters', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.click(screen.getAllByRole('button', { name: COLLAPSE_ALL })[0]);
expect(screen.getByRole('link', { name: ALL_FILTERS })).toBeInTheDocument();
expect(
screen.queryByRole('link', { name: FILTER_A }),
).not.toBeInTheDocument();
expect(
screen.queryByRole('link', { name: FILTER_B }),
).not.toBeInTheDocument();
expect(
screen.queryByRole('link', { name: FILTER_C }),
).not.toBeInTheDocument();
userEvent.click(screen.getAllByRole('button', { name: EXPAND_ALL })[0]);
expect(screen.getByRole('link', { name: ALL_FILTERS })).toBeInTheDocument();
expect(screen.getByRole('link', { name: FILTER_A })).toBeInTheDocument();
expect(screen.getByRole('link', { name: FILTER_B })).toBeInTheDocument();
expect(screen.getByRole('link', { name: FILTER_C })).toBeInTheDocument();
});
test('collapses/expands all charts', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.click(screen.getAllByRole('button', { name: COLLAPSE_ALL })[1]);
expect(screen.getByText(ALL_CHARTS)).toBeInTheDocument();
expect(screen.queryByText(CHART_A)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_B)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_C)).not.toBeInTheDocument();
expect(screen.queryByText(CHART_D)).not.toBeInTheDocument();
userEvent.click(screen.getAllByRole('button', { name: EXPAND_ALL })[1]);
expect(screen.getByText(ALL_CHARTS)).toBeInTheDocument();
expect(screen.getByRole('link', { name: CHART_A })).toBeInTheDocument();
expect(screen.getByRole('link', { name: CHART_B })).toBeInTheDocument();
expect(screen.getByRole('link', { name: CHART_C })).toBeInTheDocument();
expect(screen.getByRole('link', { name: CHART_D })).toBeInTheDocument();
});
test('searches for a chart', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.type(screen.getByPlaceholderText('Search...'), CHART_C);
expect(screen.queryByRole('link', { name: CHART_A })).not.toBeInTheDocument();
expect(screen.queryByRole('link', { name: CHART_B })).not.toBeInTheDocument();
expect(screen.getByRole('link', { name: CHART_C })).toBeInTheDocument();
});
test('selects a leaf filter', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
expect(getCheckboxState(FILTER_C)).toBe(UNCHECKED);
clickCheckbox(FILTER_C);
expect(getCheckboxState(FILTER_C)).toBe(CHECKED);
});
test('selects a leaf chart', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.click(screen.getAllByRole('button', { name: EXPAND_ALL })[1]);
expect(getCheckboxState(CHART_D)).toBe(UNCHECKED);
clickCheckbox(CHART_D);
expect(getCheckboxState(CHART_D)).toBe(CHECKED);
});
test('selects a branch of filters', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
expect(getCheckboxState(FILTER_A)).toBe(UNCHECKED);
expect(getCheckboxState(FILTER_B)).toBe(UNCHECKED);
expect(getCheckboxState(FILTER_C)).toBe(UNCHECKED);
clickCheckbox(FILTER_A);
expect(getCheckboxState(FILTER_A)).toBe(CHECKED);
expect(getCheckboxState(FILTER_B)).toBe(CHECKED);
expect(getCheckboxState(FILTER_C)).toBe(CHECKED);
});
test('selects a branch of charts', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
const tabA = screen.getByText(TAB_A);
userEvent.click(tabA);
expect(getCheckboxState(TAB_A)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_A)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_B)).toBe(UNCHECKED);
clickCheckbox(TAB_A);
expect(getCheckboxState(TAB_A)).toBe(CHECKED);
expect(getCheckboxState(CHART_A)).toBe(CHECKED);
expect(getCheckboxState(CHART_B)).toBe(CHECKED);
});
test('selects all filters', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.click(screen.getAllByRole('button', { name: EXPAND_ALL })[0]);
expect(getCheckboxState(ALL_FILTERS)).toBe(UNCHECKED);
expect(getCheckboxState(FILTER_A)).toBe(UNCHECKED);
expect(getCheckboxState(FILTER_B)).toBe(UNCHECKED);
expect(getCheckboxState(FILTER_C)).toBe(UNCHECKED);
clickCheckbox(ALL_FILTERS);
expect(getCheckboxState(ALL_FILTERS)).toBe(CHECKED);
expect(getCheckboxState(FILTER_A)).toBe(CHECKED);
expect(getCheckboxState(FILTER_B)).toBe(CHECKED);
expect(getCheckboxState(FILTER_C)).toBe(CHECKED);
});
test('selects all charts', () => {
render(<FilterScopeSelector {...createProps()} />, {
useRedux: true,
});
userEvent.click(screen.getAllByRole('button', { name: EXPAND_ALL })[1]);
expect(getCheckboxState(TAB_A)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_A)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_B)).toBe(UNCHECKED);
expect(getCheckboxState(TAB_B)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_C)).toBe(UNCHECKED);
expect(getCheckboxState(CHART_D)).toBe(UNCHECKED);
clickCheckbox(ALL_CHARTS);
expect(getCheckboxState(TAB_A)).toBe(CHECKED);
expect(getCheckboxState(CHART_A)).toBe(CHECKED);
expect(getCheckboxState(CHART_B)).toBe(CHECKED);
expect(getCheckboxState(TAB_B)).toBe(CHECKED);
expect(getCheckboxState(CHART_C)).toBe(CHECKED);
expect(getCheckboxState(CHART_D)).toBe(CHECKED);
});
test('triggers onClose', () => {
const onCloseModal = jest.fn();
render(
<FilterScopeSelector {...createProps()} onCloseModal={onCloseModal} />,
{
useRedux: true,
},
);
expect(onCloseModal).toHaveBeenCalledTimes(0);
userEvent.click(screen.getByRole('button', { name: 'Close' }));
expect(onCloseModal).toHaveBeenCalledTimes(1);
});
test('triggers onSave', () => {
const updateDashboardFiltersScope = jest.fn();
const setUnsavedChanges = jest.fn();
const onCloseModal = jest.fn();
render(
<FilterScopeSelector
{...createProps()}
updateDashboardFiltersScope={updateDashboardFiltersScope}
setUnsavedChanges={setUnsavedChanges}
onCloseModal={onCloseModal}
/>,
{
useRedux: true,
},
);
expect(updateDashboardFiltersScope).toHaveBeenCalledTimes(0);
expect(setUnsavedChanges).toHaveBeenCalledTimes(0);
expect(onCloseModal).toHaveBeenCalledTimes(0);
userEvent.click(screen.getByRole('button', { name: 'Save' }));
expect(updateDashboardFiltersScope).toHaveBeenCalledTimes(1);
expect(setUnsavedChanges).toHaveBeenCalledTimes(1);
expect(onCloseModal).toHaveBeenCalledTimes(1);
});

View File

@ -18,7 +18,6 @@
*/
import React, { RefObject } from 'react';
import { styled } from '@superset-ui/core';
import ModalTrigger from 'src/components/ModalTrigger';
import FilterScope from 'src/dashboard/containers/FilterScope';

View File

@ -22,23 +22,23 @@ import cx from 'classnames';
import Button from 'src/components/Button';
import { t, styled } from '@superset-ui/core';
import buildFilterScopeTreeEntry from '../../util/buildFilterScopeTreeEntry';
import getFilterScopeNodesTree from '../../util/getFilterScopeNodesTree';
import getFilterFieldNodesTree from '../../util/getFilterFieldNodesTree';
import getFilterScopeParentNodes from '../../util/getFilterScopeParentNodes';
import getKeyForFilterScopeTree from '../../util/getKeyForFilterScopeTree';
import getSelectedChartIdForFilterScopeTree from '../../util/getSelectedChartIdForFilterScopeTree';
import getFilterScopeFromNodesTree from '../../util/getFilterScopeFromNodesTree';
import getRevertedFilterScope from '../../util/getRevertedFilterScope';
import FilterScopeTree from './FilterScopeTree';
import FilterFieldTree from './FilterFieldTree';
import { getChartIdsInFilterScope } from '../../util/activeDashboardFilters';
import buildFilterScopeTreeEntry from 'src/dashboard/util/buildFilterScopeTreeEntry';
import getFilterScopeNodesTree from 'src/dashboard/util/getFilterScopeNodesTree';
import getFilterFieldNodesTree from 'src/dashboard/util/getFilterFieldNodesTree';
import getFilterScopeParentNodes from 'src/dashboard/util/getFilterScopeParentNodes';
import getKeyForFilterScopeTree from 'src/dashboard/util/getKeyForFilterScopeTree';
import getSelectedChartIdForFilterScopeTree from 'src/dashboard/util/getSelectedChartIdForFilterScopeTree';
import getFilterScopeFromNodesTree from 'src/dashboard/util/getFilterScopeFromNodesTree';
import getRevertedFilterScope from 'src/dashboard/util/getRevertedFilterScope';
import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters';
import {
getChartIdAndColumnFromFilterKey,
getDashboardFilterKey,
} from '../../util/getDashboardFilterKey';
import { ALL_FILTERS_ROOT } from '../../util/constants';
import { dashboardFilterPropShape } from '../../util/propShapes';
} from 'src/dashboard/util/getDashboardFilterKey';
import { ALL_FILTERS_ROOT } from 'src/dashboard/util/constants';
import { dashboardFilterPropShape } from 'src/dashboard/util/propShapes';
import FilterScopeTree from './FilterScopeTree';
import FilterFieldTree from './FilterFieldTree';
const propTypes = {
dashboardFilters: PropTypes.objectOf(dashboardFilterPropShape).isRequired,

View File

@ -19,10 +19,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import CheckboxTree from 'react-checkbox-tree';
import { filterScopeSelectorTreeNodePropShape } from 'src/dashboard/util/propShapes';
import renderFilterScopeTreeNodes from './renderFilterScopeTreeNodes';
import treeIcons from './treeIcons';
import { filterScopeSelectorTreeNodePropShape } from '../../util/propShapes';
const propTypes = {
nodes: PropTypes.arrayOf(filterScopeSelectorTreeNodePropShape).isRequired,

View File

@ -17,7 +17,6 @@
* under the License.
*/
import React from 'react';
import FilterFieldItem from './FilterFieldItem';
export default function renderFilterFieldTreeNodes({ nodes, activeKey }) {

View File

@ -19,8 +19,8 @@
import React from 'react';
import cx from 'classnames';
import ChartIcon from '../../../components/ChartIcon';
import { CHART_TYPE } from '../../util/componentTypes';
import ChartIcon from 'src/components/ChartIcon';
import { CHART_TYPE } from 'src/dashboard/util/componentTypes';
function traverse({ currentNode = {}, selectedChartId }) {
if (!currentNode) {

View File

@ -98,10 +98,14 @@ const Header: FC<HeaderProps> = ({
<span>{t('Filters')}</span>
{canEdit && (
<FilterConfigurationLink createNewOnOpen={filterValues.length === 0}>
<Icon name="edit" data-test="create-filter" />
<Icon name="edit" role="button" data-test="create-filter" />
</FilterConfigurationLink>
)}
<Icon name="expand" onClick={() => toggleFiltersBar(false)} />
<Icon
name="expand"
role="button"
onClick={() => toggleFiltersBar(false)}
/>
</TitleArea>
<ActionButtons>
<Button