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

Collapse source and systems filter into button #153

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/three-taxis-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@envyjs/webui': patch
---

Collapse source and systems filter into button
13 changes: 0 additions & 13 deletions packages/webui/src/components/ui/FiltersAndActions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import { setUseApplicationData } from '@/testing/mockUseApplication';
import FiltersAndActions from './FiltersAndActions';

jest.mock('@/components', () => ({
SourceAndSystemFilter: function (props: any) {
return <div {...props}>Mock SourceAndSystemFilter component</div>;
},
SearchInput: function ({ onChange }: any) {
return <input data-test-id="mock-search-input" onChange={e => onChange(e.target.value)} />;
},
Expand Down Expand Up @@ -55,16 +52,6 @@ describe('FiltersAndActions', () => {
render(<FiltersAndActions />);
});

describe('sources and systems', () => {
it('should render SourceAndSystemFilter component', () => {
const { getByTestId } = render(<FiltersAndActions />);

const sourcesAndSystems = getByTestId('sources-and-systems');
expect(sourcesAndSystems).toBeVisible();
expect(sourcesAndSystems).toHaveTextContent('Mock SourceAndSystemFilter component');
});
});

describe('search term', () => {
it('should render SearchInput component', () => {
const { getByTestId } = render(<FiltersAndActions />);
Expand Down
9 changes: 1 addition & 8 deletions packages/webui/src/components/ui/FiltersAndActions.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { SearchInput } from '@/components';
import useApplication from '@/hooks/useApplication';

import SourceAndSystemFilter from './SourceAndSystemFilter';

export default function FiltersAndActions() {
const { setFilters } = useApplication();

Expand All @@ -13,10 +11,5 @@ export default function FiltersAndActions() {
}));
}

return (
<span className="flex flex-row items-center gap-2">
<SourceAndSystemFilter className="w-52" data-test-id="sources-and-systems" />
<SearchInput className="w-48 lg:w-72" onChange={handleSearchTermChange} />
</span>
);
return <SearchInput className="w-72" onChange={handleSearchTermChange} />;
}
7 changes: 7 additions & 0 deletions packages/webui/src/components/ui/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ jest.mock(
return <div data-test-id="mock-filters-and-actions">Mock FiltersAndActions component</div>;
},
);
jest.mock(
'@/components/ui/SourceAndSystemFilter',
() =>
function SourceAndSystemFilter() {
return <div data-test-id="mock-source-and-systems">Mock Source and Systems component</div>;
},
);

describe('Header', () => {
const originalProcessEnv = process.env;
Expand Down
2 changes: 2 additions & 0 deletions packages/webui/src/components/ui/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import DarkModeToggle from '../DarkModeToggle';
import DebugToolbar from './DebugToolbar';
import FiltersAndActions from './FiltersAndActions';
import Logo from './Logo';
import SourceAndSystemFilter from './SourceAndSystemFilter';

export default function Header() {
const { enableThemeSwitcher } = useFeatureFlags();
Expand All @@ -21,6 +22,7 @@ export default function Header() {
</div>
<div className="flex items-center gap-2">
<FiltersAndActions />
<SourceAndSystemFilter />
{enableThemeSwitcher && <DarkModeToggle />}
{isDebugMode && <DebugToolbar />}
</div>
Expand Down
205 changes: 4 additions & 201 deletions packages/webui/src/components/ui/SourceAndSystemFilter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,112 +79,6 @@ describe('SourceAndSystemFilter', () => {
expect(component).toBeVisible();
});

describe('placeholder', () => {
it('should display expected placeholder in the listbox when there are no registered systems', () => {
// mock that there are no registered systems
setupMockSystems([]);

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('Sources...');
});

it('should display expected placeholder in the listbox when there is one or more registered systems', () => {
setupMockSystems(mockSystems);
const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('Sources & Systems');
});
});

describe('selection summary', () => {
it('should display expected selection summary when one source is selected', () => {
const filters: Filters = {
sources: ['source1'],
systems: [],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('1 source');
});

it('should display expected selection summary when two sources are selected', () => {
const filters: Filters = {
sources: ['source1', 'source2'],
systems: [],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('2 sources');
});

it('should display expected selection summary when one system is selected', () => {
const filters: Filters = {
sources: [],
systems: [mockSystems[0].name],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('1 system');
});

it('should display expected selection summary when two systems are selected', () => {
const filters: Filters = {
sources: [],
systems: [mockSystems[0].name, mockSystems[1].name],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('2 systems');
});

it('should display expected selection summary when a combination of sources and systems are selected', () => {
const filters: Filters = {
sources: ['source1'],
systems: [mockSystems[0].name, mockSystems[1].name],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('1 source, 2 systems');
});

it('should display the placeholder when no sources or systems are selected', () => {
const filters: Filters = {
sources: [],
systems: [],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByRole } = render(<SourceAndSystemFilter />);

const component = getByRole('listbox');
expect(component).toHaveTextContent('Sources & Systems');
});
});

describe('selection options', () => {
describe('with no registered systems', () => {
beforeEach(() => {
Expand Down Expand Up @@ -220,7 +114,6 @@ describe('SourceAndSystemFilter', () => {
const noSourcesMessage = getByTestId('no-sources');

expect(noSourcesMessage).toBeVisible();
expect(noSourcesMessage).toHaveTextContent('No sources connected...');
});

it('should display source options', async () => {
Expand All @@ -239,22 +132,6 @@ describe('SourceAndSystemFilter', () => {
expect(systemItems).not.toBeInTheDocument();
});

it('should not display source options heading', async () => {
const { queryByTestId } = await openDropDown();

const sourceItemsHeading = queryByTestId('source-items-heading');

expect(sourceItemsHeading).not.toBeInTheDocument();
});

it('should not display source / system divider', async () => {
const { queryByTestId } = await openDropDown();

const itemsDivider = queryByTestId('items-divider');

expect(itemsDivider).not.toBeInTheDocument();
});

it('should display each source as an option', async () => {
const { getAllByTestId } = await openDropDown();

Expand All @@ -271,8 +148,8 @@ describe('SourceAndSystemFilter', () => {

const sourceItems = getAllByTestId('source-item');

expect(within(sourceItems.at(0)!).getByTestId('status')).toHaveClass('bg-green-300');
expect(within(sourceItems.at(1)!).getByTestId('status')).toHaveClass('bg-green-300');
expect(within(sourceItems.at(0)!).getByTestId('status')).toHaveClass('bg-green-400');
expect(within(sourceItems.at(1)!).getByTestId('status')).toHaveClass('bg-green-400');
expect(within(sourceItems.at(2)!).getByTestId('status')).toHaveClass('bg-red-300');
});
});
Expand Down Expand Up @@ -337,8 +214,8 @@ describe('SourceAndSystemFilter', () => {

const sourceItems = getAllByTestId('source-item');

expect(within(sourceItems.at(0)!).getByTestId('status')).toHaveClass('bg-green-300');
expect(within(sourceItems.at(1)!).getByTestId('status')).toHaveClass('bg-green-300');
expect(within(sourceItems.at(0)!).getByTestId('status')).toHaveClass('bg-green-400');
expect(within(sourceItems.at(1)!).getByTestId('status')).toHaveClass('bg-green-400');
expect(within(sourceItems.at(2)!).getByTestId('status')).toHaveClass('bg-red-300');
});

Expand Down Expand Up @@ -553,80 +430,6 @@ describe('SourceAndSystemFilter', () => {
});
});

describe('clearing selections', () => {
it('should not display clear button when no selection is made', () => {
const filters: Filters = {
sources: [],
systems: [],
searchTerm: '',
};
setUseApplicationData({ filters });

const { queryByTestId } = render(<SourceAndSystemFilter />);

const clearButton = queryByTestId('input-clear');
expect(clearButton).not.toBeInTheDocument();
});

it('should display clear button when a selection is made', async () => {
const filters: Filters = {
sources: ['source1'],
systems: [mockSystems[0].name],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByTestId } = render(<SourceAndSystemFilter />);

const clearButton = getByTestId('input-clear');
expect(clearButton).toHaveTextContent('Mock X component');
});

it('should call `setFilters` with empty source and systems when clicking the clear button', async () => {
const filters: Filters = {
sources: ['source1'],
systems: [mockSystems[0].name],
searchTerm: '',
};
setUseApplicationData({ filters });

const { getByTestId } = render(<SourceAndSystemFilter />);

await act(async () => {
const clearButton = getByTestId('input-clear');
await userEvent.click(clearButton);
});

assertSetFilterUpdate(filters, {
sources: [],
systems: [],
searchTerm: '',
});
});

it('should not affect search term when clicking the clear button', async () => {
const filters: Filters = {
sources: ['source1'],
systems: [mockSystems[0].name],
searchTerm: 'search term',
};
setUseApplicationData({ filters });

const { getByTestId } = render(<SourceAndSystemFilter />);

await act(async () => {
const clearButton = getByTestId('input-clear');
await userEvent.click(clearButton);
});

assertSetFilterUpdate(filters, {
sources: [],
systems: [],
searchTerm: 'search term',
});
});
});

describe('clicking away', () => {
it('should hide options when clicking away somewhere else in the document', async () => {
const { container, getByRole, queryByTestId } = render(<SourceAndSystemFilter />);
Expand Down
Loading