diff --git a/packages/datagateway-common/src/api/index.test.tsx b/packages/datagateway-common/src/api/index.test.tsx
index 01d349039..dedceba84 100644
--- a/packages/datagateway-common/src/api/index.test.tsx
+++ b/packages/datagateway-common/src/api/index.test.tsx
@@ -347,6 +347,7 @@ describe('generic api functions', () => {
afterEach(() => {
jest.restoreAllMocks();
jest.resetModules();
+ window.history.pushState({}, 'Test', '/');
});
describe('useSort', () => {
@@ -398,6 +399,47 @@ describe('generic api functions', () => {
search: '?',
});
});
+
+ it('returns callback that, when called without shift modifier, replaces sort with the new one', () => {
+ window.history.pushState(
+ {},
+ 'Test',
+ '?sort=%7B%22name%22%3A%22asc%22%7D'
+ );
+ const { result } = renderHook(() => useSort(), {
+ wrapper,
+ });
+
+ act(() => {
+ result.current('title', 'asc', 'push', false);
+ });
+
+ expect(pushSpy).toHaveBeenCalledWith({
+ search: `?sort=${encodeURIComponent('{"title":"asc"}')}`,
+ });
+ });
+
+ it('returns callback that, when called with shift modifier, appends new sort to the existing one', () => {
+ window.history.pushState(
+ {},
+ 'Test',
+ '?sort=%7B%22name%22%3A%22asc%22%7D'
+ );
+
+ const { result } = renderHook(() => useSort(), {
+ wrapper,
+ });
+
+ act(() => {
+ result.current('title', 'asc', 'push', true);
+ });
+
+ console.log(history.location.search);
+
+ expect(pushSpy).toHaveBeenCalledWith({
+ search: `?sort=${encodeURIComponent('{"name":"asc","title":"asc"}')}`,
+ });
+ });
});
describe('usePushFilter', () => {
diff --git a/packages/datagateway-common/src/api/index.tsx b/packages/datagateway-common/src/api/index.tsx
index 8c61ee671..d0b2638e2 100644
--- a/packages/datagateway-common/src/api/index.tsx
+++ b/packages/datagateway-common/src/api/index.tsx
@@ -260,7 +260,8 @@ export const getApiParams = (
export const useSort = (): ((
sortKey: string,
order: Order | null,
- updateMethod: UpdateMethod
+ updateMethod: UpdateMethod,
+ shiftDown?: boolean
) => void) => {
const { push, replace } = useHistory();
@@ -268,17 +269,25 @@ export const useSort = (): ((
(
sortKey: string,
order: Order | null,
- updateMethod: UpdateMethod
+ updateMethod: UpdateMethod,
+ shiftDown?: boolean
): void => {
let query = parseSearchToQuery(window.location.search);
if (order !== null) {
- query = {
- ...query,
- sort: {
- ...query.sort,
- [sortKey]: order,
- },
- };
+ query = shiftDown
+ ? {
+ ...query,
+ sort: {
+ ...query.sort,
+ [sortKey]: order,
+ },
+ }
+ : {
+ ...query,
+ sort: {
+ [sortKey]: order,
+ },
+ };
} else {
// if order is null, user no longer wants to sort by that column so remove column from sort state
const { [sortKey]: order, ...rest } = query.sort;
diff --git a/packages/datagateway-common/src/card/cardView.component.test.tsx b/packages/datagateway-common/src/card/cardView.component.test.tsx
index 1a5674810..023aefe7b 100644
--- a/packages/datagateway-common/src/card/cardView.component.test.tsx
+++ b/packages/datagateway-common/src/card/cardView.component.test.tsx
@@ -227,7 +227,7 @@ describe('Card View', () => {
await user.click(
await screen.findByRole('button', { name: 'Sort by TITLE' })
);
- expect(onSort).toHaveBeenNthCalledWith(1, 'title', 'asc', 'push');
+ expect(onSort).toHaveBeenNthCalledWith(1, 'title', 'asc', 'push', false);
updatedProps = {
...updatedProps,
@@ -240,7 +240,7 @@ describe('Card View', () => {
name: 'Sort by TITLE, current direction ascending',
})
);
- expect(onSort).toHaveBeenNthCalledWith(2, 'title', 'desc', 'push');
+ expect(onSort).toHaveBeenNthCalledWith(2, 'title', 'desc', 'push', false);
updatedProps = {
...updatedProps,
@@ -253,7 +253,7 @@ describe('Card View', () => {
name: 'Sort by TITLE, current direction descending',
})
);
- expect(onSort).toHaveBeenNthCalledWith(3, 'title', null, 'push');
+ expect(onSort).toHaveBeenNthCalledWith(3, 'title', null, 'push', false);
});
it('default sort applied correctly', () => {
@@ -272,9 +272,9 @@ describe('Card View', () => {
};
render();
- expect(onSort).toHaveBeenCalledWith('title', 'asc', 'replace');
- expect(onSort).toHaveBeenCalledWith('name', 'desc', 'replace');
- expect(onSort).toHaveBeenCalledWith('test', 'asc', 'replace');
+ expect(onSort).toHaveBeenCalledWith('title', 'asc', 'replace', false);
+ expect(onSort).toHaveBeenCalledWith('name', 'desc', 'replace', false);
+ expect(onSort).toHaveBeenCalledWith('test', 'asc', 'replace', false);
});
it('can sort by description with label', async () => {
@@ -290,7 +290,7 @@ describe('Card View', () => {
await user.click(
await screen.findByRole('button', { name: 'Sort by NAME' })
);
- expect(onSort).toHaveBeenCalledWith('name', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('name', 'asc', 'push', false);
});
it('can sort by description without label', async () => {
@@ -306,7 +306,7 @@ describe('Card View', () => {
await user.click(
await screen.findByRole('button', { name: 'Sort by NAME' })
);
- expect(onSort).toHaveBeenCalledWith('name', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('name', 'asc', 'push', false);
});
it('page changed when sort applied', async () => {
@@ -318,7 +318,7 @@ describe('Card View', () => {
await screen.findByRole('button', { name: 'Sort by TITLE' })
);
- expect(onSort).toHaveBeenCalledWith('title', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('title', 'asc', 'push', false);
expect(onPageChange).toHaveBeenCalledWith(1);
});
@@ -377,7 +377,53 @@ describe('Card View', () => {
await user.click(
await screen.findByRole('button', { name: 'Sort by VISITID' })
);
- expect(onSort).toHaveBeenCalledWith('visitId', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('visitId', 'asc', 'push', false);
+ });
+
+ it('calls onSort with correct parameters when shift key is pressed', async () => {
+ const updatedProps = {
+ ...props,
+ title: { dataKey: 'title', disableSort: true },
+ description: { dataKey: 'name', disableSort: true },
+ information: [
+ { dataKey: 'visitId' },
+ {
+ dataKey: 'name',
+ label: 'Name',
+ content: (entity: Entity) => entity.name,
+ },
+ ],
+ page: 1,
+ };
+ render();
+
+ // Click with shift to sort ascending
+ await user.keyboard('{Shift>}');
+ await user.click(
+ await screen.findByRole('button', { name: 'Sort by VISITID' })
+ );
+ await user.keyboard('{/Shift}');
+
+ expect(onSort).toHaveBeenCalledWith('visitId', 'asc', 'push', true);
+
+ await user.click(
+ await screen.findByRole('button', { name: 'Sort by NAME' })
+ );
+
+ expect(onSort).toHaveBeenCalledWith('name', 'asc', 'push', false);
+ });
+
+ it('displays correct icon when no sort applied', async () => {
+ render();
+
+ const cards = await screen.findAllByRole('button', { name: /Sort by/ });
+ expect(
+ within(cards[0]).getByTestId(`ArrowDownwardIcon`)
+ ).toBeInTheDocument();
+
+ await user.keyboard('{Shift>}');
+ expect(within(cards[0]).getByTestId(`AddIcon`)).toBeInTheDocument();
+ await user.keyboard('{/Shift}');
});
it('information displays with content that has no tooltip', async () => {
diff --git a/packages/datagateway-common/src/card/cardView.component.tsx b/packages/datagateway-common/src/card/cardView.component.tsx
index fcbb48d44..e7dab298d 100644
--- a/packages/datagateway-common/src/card/cardView.component.tsx
+++ b/packages/datagateway-common/src/card/cardView.component.tsx
@@ -33,6 +33,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import AdvancedFilter from './advancedFilter.component';
import EntityCard, { EntityImageDetails } from './entityCard.component';
+import AddIcon from '@mui/icons-material/Add';
const SelectedChips = styled('ul')(({ theme }) => ({
display: 'inline-flex',
@@ -85,7 +86,8 @@ export interface CardViewProps {
onSort: (
sort: string,
order: Order | null,
- updateMethod: UpdateMethod
+ updateMethod: UpdateMethod,
+ shiftDown?: boolean
) => void;
// Props to get title, description of the card
@@ -189,6 +191,30 @@ const CardView = (props: CardViewProps): React.ReactElement => {
sort,
} = props;
+ const [shiftDown, setShiftDown] = React.useState(false);
+ // add event listener to listen for shift key being pressed
+ React.useEffect(() => {
+ const handleKeyDown = (event: KeyboardEvent): void => {
+ if (event.key === 'Shift') {
+ setShiftDown(true);
+ }
+ };
+
+ const handleKeyUp = (event: KeyboardEvent): void => {
+ if (event.key === 'Shift') {
+ setShiftDown(false);
+ }
+ };
+
+ document.addEventListener('keydown', handleKeyDown);
+ document.addEventListener('keyup', handleKeyUp);
+
+ return (): void => {
+ document.removeEventListener('keydown', handleKeyDown);
+ document.removeEventListener('keyup', handleKeyUp);
+ };
+ }, []);
+
// Results options (by default it is 10, 20 and 30).
const resOptions = React.useMemo(
() =>
@@ -233,20 +259,20 @@ const CardView = (props: CardViewProps): React.ReactElement => {
//defaultSort has been provided
React.useEffect(() => {
if (title.defaultSort !== undefined && sort[title.dataKey] === undefined)
- onSort(title.dataKey, title.defaultSort, 'replace');
+ onSort(title.dataKey, title.defaultSort, 'replace', false);
if (
description &&
description.defaultSort !== undefined &&
sort[description.dataKey] === undefined
)
- onSort(description.dataKey, description.defaultSort, 'replace');
+ onSort(description.dataKey, description.defaultSort, 'replace', false);
if (information) {
information.forEach((element: CardViewDetails) => {
if (
element.defaultSort !== undefined &&
sort[element.dataKey] === undefined
)
- onSort(element.dataKey, element.defaultSort, 'replace');
+ onSort(element.dataKey, element.defaultSort, 'replace', false);
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -593,11 +619,12 @@ const CardView = (props: CardViewProps): React.ReactElement => {
{
+ onClick={(event) => {
onSort(
s.dataKey,
nextSortDirection(s.dataKey),
- 'push'
+ 'push',
+ event.shiftKey
);
if (page !== 1) {
onPageChange(1);
@@ -615,14 +642,21 @@ const CardView = (props: CardViewProps): React.ReactElement => {
>
-
- {s.dataKey in sort && sort[s.dataKey]}
-
+ {
+
+ {s.dataKey in sort && sort[s.dataKey]}
+
+ }
))}
diff --git a/packages/datagateway-common/src/table/headerRenderers/__snapshots__/dataHeader.component.test.tsx.snap b/packages/datagateway-common/src/table/headerRenderers/__snapshots__/dataHeader.component.test.tsx.snap
index f463d63d1..fd5596d65 100644
--- a/packages/datagateway-common/src/table/headerRenderers/__snapshots__/dataHeader.component.test.tsx.snap
+++ b/packages/datagateway-common/src/table/headerRenderers/__snapshots__/dataHeader.component.test.tsx.snap
@@ -131,7 +131,9 @@ exports[`Data column header component renders correctly with sort and filter 1`]
class="MuiBox-root css-0"
>
@@ -142,13 +144,13 @@ exports[`Data column header component renders correctly with sort and filter 1`]
@@ -257,7 +259,9 @@ exports[`Data column header component renders correctly with sort but no filter
class="MuiBox-root css-0"
>
@@ -268,13 +272,13 @@ exports[`Data column header component renders correctly with sort but no filter
diff --git a/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.test.tsx b/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.test.tsx
index 96dfe5a5f..b357cc3eb 100644
--- a/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.test.tsx
+++ b/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.test.tsx
@@ -71,7 +71,7 @@ describe('Data column header component', () => {
it('sets asc order', async () => {
render();
await user.click(await screen.findByRole('button', { name: 'Test' }));
- expect(onSort).toHaveBeenCalledWith('test', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('test', 'asc', 'push', false);
});
it('sets desc order', async () => {
@@ -84,7 +84,7 @@ describe('Data column header component', () => {
/>
);
await user.click(await screen.findByRole('button', { name: 'Test' }));
- expect(onSort).toHaveBeenCalledWith('test', 'desc', 'push');
+ expect(onSort).toHaveBeenCalledWith('test', 'desc', 'push', false);
});
it('sets null order', async () => {
@@ -97,7 +97,7 @@ describe('Data column header component', () => {
/>
);
await user.click(await screen.findByRole('button', { name: 'Test' }));
- expect(onSort).toHaveBeenCalledWith('test', null, 'push');
+ expect(onSort).toHaveBeenCalledWith('test', null, 'push', false);
});
});
@@ -105,11 +105,28 @@ describe('Data column header component', () => {
it('sets asc order', () => {
render();
- expect(onSort).toHaveBeenCalledWith('test', 'asc', 'replace');
+ expect(onSort).toHaveBeenCalledWith('test', 'asc', 'replace', false);
});
it('sets desc order', () => {
render();
- expect(onSort).toHaveBeenCalledWith('test', 'desc', 'replace');
+ expect(onSort).toHaveBeenCalledWith('test', 'desc', 'replace', false);
+ });
+ });
+
+ describe('changes icons in the label', () => {
+ it('changes icon to Add when shift is pressed', async () => {
+ render();
+ expect(screen.getByTestId('AddIcon')).toBeInTheDocument();
+ });
+
+ it('changes icon to ArrowUpward when hovered', async () => {
+ render();
+ expect(screen.getByTestId('SortIcon')).toBeInTheDocument();
+ await user.hover(await screen.findByRole('button', { name: 'Test' }));
+ expect(screen.getByTestId('ArrowUpwardIcon')).toBeInTheDocument();
+
+ await user.unhover(await screen.findByRole('button', { name: 'Test' }));
+ expect(screen.getByTestId('SortIcon')).toBeInTheDocument();
});
});
diff --git a/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.tsx b/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.tsx
index 0fb8aa963..ccc62f224 100644
--- a/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.tsx
+++ b/packages/datagateway-common/src/table/headerRenderers/dataHeader.component.tsx
@@ -9,7 +9,11 @@ import {
Divider,
SxProps,
} from '@mui/material';
+import { StyledTooltip } from '../../arrowtooltip.component';
import Draggable from 'react-draggable';
+import SortIcon from '@mui/icons-material/Sort';
+import AddIcon from '@mui/icons-material/Add';
+import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
const DataHeader = (
props: TableHeaderProps & {
@@ -18,13 +22,15 @@ const DataHeader = (
onSort: (
column: string,
order: Order | null,
- defaultSort: UpdateMethod
+ defaultSort: UpdateMethod,
+ shiftDown?: boolean
) => void;
resizeColumn: (dataKey: string, deltaX: number) => void;
labelString: string;
icon?: React.ComponentType;
filterComponent?: (label: string, dataKey: string) => React.ReactElement;
defaultSort?: Order;
+ shiftDown?: boolean;
}
): React.ReactElement => {
const {
@@ -39,15 +45,18 @@ const DataHeader = (
resizeColumn,
icon: Icon,
filterComponent,
+ shiftDown,
} = props;
const currSortDirection = sort[dataKey];
+ const [hover, setHover] = React.useState(false);
+
//Apply default sort on page load (but only if not already defined in URL params)
//This will apply them in the order of the column definitions given to a table
React.useEffect(() => {
if (defaultSort !== undefined && currSortDirection === undefined)
- onSort(dataKey, defaultSort, 'replace');
+ onSort(dataKey, defaultSort, 'replace', false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -64,16 +73,39 @@ const DataHeader = (
}
const inner = !disableSort ? (
- onSort(dataKey, nextSortDirection, 'push')}
+
-
- {label}
-
-
+ {
+ onSort(dataKey, nextSortDirection, 'push', event.shiftKey);
+ if (!(dataKey in sort)) setHover(false);
+ }}
+ {...(!(dataKey in sort)
+ ? {
+ onMouseEnter: () => setHover(true),
+ onMouseLeave: () => setHover(false),
+ IconComponent: hover
+ ? ArrowUpwardIcon
+ : shiftDown
+ ? AddIcon
+ : SortIcon,
+ sx: {
+ transition: 'opacity 0.5s',
+ opacity: hover ? 0.7 : 1,
+ },
+ }
+ : {})}
+ >
+
+ {label}
+
+
+
) : (
{label}
diff --git a/packages/datagateway-common/src/table/table.component.test.tsx b/packages/datagateway-common/src/table/table.component.test.tsx
index 527561ffe..1e4030d8d 100644
--- a/packages/datagateway-common/src/table/table.component.test.tsx
+++ b/packages/datagateway-common/src/table/table.component.test.tsx
@@ -76,7 +76,7 @@ describe('Table component', () => {
it('calls onSort function when sort label clicked', async () => {
render();
await user.click(await screen.findByText('Test 1'));
- expect(onSort).toHaveBeenCalledWith('TEST1', 'asc', 'push');
+ expect(onSort).toHaveBeenCalledWith('TEST1', 'asc', 'push', false);
});
it('calls onSort function when defaultSort has been specified', () => {
@@ -89,8 +89,23 @@ describe('Table component', () => {
};
render();
- expect(onSort).toHaveBeenCalledWith('TEST1', 'asc', 'replace');
- expect(onSort).toHaveBeenCalledWith('TEST2', 'desc', 'replace');
+ expect(onSort).toHaveBeenCalledWith('TEST1', 'asc', 'replace', false);
+ expect(onSort).toHaveBeenCalledWith('TEST2', 'desc', 'replace', false);
+ });
+
+ it('calls onSort with correct parameters when shift key is pressed', async () => {
+ render();
+
+ // Click with shift to sort ascending
+ await user.keyboard('{Shift>}');
+ await user.click(await screen.findByRole('button', { name: 'Test 1' }));
+ await user.keyboard('{/Shift}');
+
+ expect(onSort).toHaveBeenCalledWith('TEST1', 'asc', 'push', true);
+
+ await user.click(await screen.findByRole('button', { name: 'Test 2' }));
+
+ expect(onSort).toHaveBeenCalledWith('TEST2', 'asc', 'push', false);
});
it('renders select column correctly', async () => {
diff --git a/packages/datagateway-common/src/table/table.component.tsx b/packages/datagateway-common/src/table/table.component.tsx
index 5c5d3d9da..aa07dd089 100644
--- a/packages/datagateway-common/src/table/table.component.tsx
+++ b/packages/datagateway-common/src/table/table.component.tsx
@@ -163,6 +163,30 @@ const VirtualizedTable = React.memo(
disableSelectAll,
} = props;
+ const [shiftDown, setShiftDown] = React.useState(false);
+ // add event listener to listen for shift key being pressed
+ React.useEffect(() => {
+ const handleKeyDown = (event: KeyboardEvent): void => {
+ if (event.key === 'Shift') {
+ setShiftDown(true);
+ }
+ };
+
+ const handleKeyUp = (event: KeyboardEvent): void => {
+ if (event.key === 'Shift') {
+ setShiftDown(false);
+ }
+ };
+
+ document.addEventListener('keydown', handleKeyDown);
+ document.addEventListener('keyup', handleKeyUp);
+
+ return (): void => {
+ document.removeEventListener('keydown', handleKeyDown);
+ document.removeEventListener('keyup', handleKeyUp);
+ };
+ }, []);
+
if (
(props.loadMoreRows && typeof totalRowCount === 'undefined') ||
(totalRowCount && typeof props.loadMoreRows === 'undefined')
@@ -452,6 +476,7 @@ const VirtualizedTable = React.memo(
filterComponent={filterComponent}
resizeColumn={resizeColumn}
defaultSort={defaultSort}
+ shiftDown={shiftDown}
/>
)}
className={className}
diff --git a/packages/datagateway-dataview/cypress/e2e/card/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/datasets.cy.ts
index 3296fe33b..44c985b40 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/datasets.cy.ts
@@ -50,13 +50,13 @@ describe('Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 1');
- // multiple fields
+ // multiple fields (shift click)
cy.contains('[role="button"]', 'Create Time').click();
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
@@ -65,6 +65,17 @@ describe('Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 1');
+
+ // should replace current sort if clicked without shift
+ cy.get('@nameSortButton').click();
+
+ cy.contains('[aria-label="Sort by NAME"]', 'desc').should('exist');
+ cy.contains('[role="button"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by CREATE TIME"]', 'asc').should(
+ 'not.exist'
+ );
+
+ cy.get('[data-testid="card"]').first().contains('DATASET 61');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/dls/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/dls/datasets.cy.ts
index fa7e2cdd9..b9455fa83 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/dls/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/dls/datasets.cy.ts
@@ -81,13 +81,13 @@ describe('DLS - Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 1');
- // multiple fields
+ // multiple fields (shift click)
cy.get('@timeSortButton').click();
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
@@ -96,6 +96,17 @@ describe('DLS - Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 1');
+
+ // should replace current sort if clicked without shift
+ cy.get('@nameSortButton').click();
+
+ cy.contains('[aria-label="Sort by NAME"]', 'desc').should('exist');
+ cy.contains('[role="button"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by CREATE TIME"]', 'asc').should(
+ 'not.exist'
+ );
+
+ cy.get('[data-testid="card"]').first().contains('DATASET 61');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/investigations.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/investigations.cy.ts
index 59aa31f72..2ba276b02 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/investigations.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/investigations.cy.ts
@@ -63,9 +63,9 @@ describe('Investigations Cards', () => {
.first()
.contains('Analysis reflect work or hour color maybe.');
- // multiple fields
+ // multiple fields (shift click)
cy.contains('[role="button"]', 'Start Date').click();
- cy.get('@titleSortButton').click();
+ cy.get('@titleSortButton').click({ shiftKey: true });
cy.wait('@getInvestigationsOrder', { timeout: 10000 });
cy.contains('[aria-label="Sort by TITLE"]', 'asc').should('exist');
@@ -74,6 +74,14 @@ describe('Investigations Cards', () => {
cy.get('[data-testid="card"]')
.first()
.contains('Analysis reflect work or hour color maybe.');
+
+ // should replace current sort if clicked without shift
+ cy.contains('[role="button"]', 'Start Date').click();
+ cy.wait('@getInvestigationsOrder', { timeout: 10000 });
+
+ cy.contains('[aria-label="Sort by START DATE"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by TITLE"]', 'asc').should('not.exist');
+ cy.get('[data-testid="card"]').first().contains('Put modern else answer.');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/isis/dataPublications.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/isis/dataPublications.cy.ts
index e38c1b435..918aa94dc 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/isis/dataPublications.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/isis/dataPublications.cy.ts
@@ -72,9 +72,9 @@ describe('ISIS - Data Publication Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('Article');
- // multiple fields
+ // multiple fields (shift click)
cy.contains('[role="button"]', 'Title').click();
- cy.get('@dateSortButton').click();
+ cy.get('@dateSortButton').click({ shiftKey: true });
cy.wait('@getDataPublicationsOrder', { timeout: 10000 });
cy.contains('[aria-label="Sort by TITLE"]', 'asc').should('exist');
@@ -83,6 +83,17 @@ describe('ISIS - Data Publication Cards', () => {
);
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('Article');
+
+ // should replace current sort if clicked without shift
+ cy.get('@dateSortButton').click();
+ cy.wait('@getDataPublicationsOrder', { timeout: 10000 });
+
+ cy.contains('[aria-label="Sort by PUBLICATION DATE"]', 'desc').should(
+ 'exist'
+ );
+ cy.contains('[aria-label="Sort by TITLE"]', 'asc').should('not.exist');
+
+ cy.get('[data-testid="card"]').first().contains('Church');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/isis/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/isis/datasets.cy.ts
index 0ae174db3..62407373b 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/isis/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/isis/datasets.cy.ts
@@ -84,13 +84,13 @@ describe('ISIS - Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 19');
- // multiple fields
+ // multiple fields (shift click)
cy.get('@timeSortButton').click();
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@getDatasetsOrder', {
timeout: 10000,
});
@@ -99,6 +99,16 @@ describe('ISIS - Datasets Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('DATASET 19');
+
+ // should replace current sort if clicked without shift
+ cy.get('@nameSortButton').click();
+
+ cy.contains('[aria-label="Sort by NAME"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by CREATE TIME"]', 'asc').should(
+ 'not.exist'
+ );
+
+ cy.get('[data-testid="card"]').first().contains('DATASET 79');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/isis/facilityCycles.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/isis/facilityCycles.cy.ts
index 88695d603..68533d878 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/isis/facilityCycles.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/isis/facilityCycles.cy.ts
@@ -53,15 +53,23 @@ describe('ISIS - FacilityCycles Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('2001 cycle 2');
- // multiple fields
+ // multiple fields (shift click)
cy.get('@dateSortButton').click();
- cy.contains('[role="button"]', 'End Date').click();
+ cy.contains('[role="button"]', 'End Date').click({ shiftKey: true });
cy.wait('@getFacilityCyclesOrder', { timeout: 10000 });
cy.contains('[aria-label="Sort by START DATE"]', 'asc').should('exist');
cy.contains('[aria-label="Sort by END DATE"]', 'asc').should('exist');
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('2001 cycle 2');
+
+ // should replace current sort if clicked without shift
+ cy.get('@dateSortButton').click();
+
+ cy.contains('[aria-label="Sort by START DATE"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by END DATE"]', 'asc').should('not.exist');
+ cy.contains('[role="button"]', 'asc').should('not.exist');
+ cy.get('[data-testid="card"]').first().contains('2004 cycle 3');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/card/isis/instruments.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/isis/instruments.cy.ts
index 2937c76f0..753505c16 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/isis/instruments.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/isis/instruments.cy.ts
@@ -47,11 +47,9 @@ describe('ISIS - Instruments Cards', () => {
//Revert the default sort
cy.contains('[role="button"]', 'Name').as('nameSortButton').click();
cy.get('@nameSortButton').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
// ascending
cy.get('@nameSortButton').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
cy.contains('[role="button"]', 'asc').should('exist');
cy.contains('[role="button"]', 'desc').should('not.exist');
@@ -61,7 +59,6 @@ describe('ISIS - Instruments Cards', () => {
// descending
cy.get('@nameSortButton').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
cy.contains('[role="button"]', 'asc').should('not.exist');
cy.contains('[role="button"]', 'desc').should('exist');
@@ -77,25 +74,35 @@ describe('ISIS - Instruments Cards', () => {
.first()
.contains('Stop prove field onto think suffer measure.');
+ // multiple fields (shift click)
cy.contains('[role="button"]', 'Description').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
cy.get('[data-testid="card"]')
.first()
.contains('Sound low certain challenge yet sport happy.');
- cy.contains('[role="button"]', 'Type').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
+ cy.contains('[role="button"]', 'Type').click({ shiftKey: true });
cy.contains('[aria-label="Sort by DESCRIPTION"]', 'asc').should('exist');
cy.contains('[aria-label="Sort by TYPE"]', 'asc').should('exist');
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('10');
+
+ // should replace current sort if clicked without shift
+ cy.contains('[role="button"]', 'Name').click();
+ cy.contains('[aria-label="Sort by NAME"]', 'asc').should('exist');
+ cy.contains('[aria-label="Sort by DESCRIPTION"]', 'asc').should(
+ 'not.exist'
+ );
+ cy.contains('[aria-label="Sort by TYPE"]', 'asc').should('not.exist');
+ cy.contains('[role="button"]', 'desc').should('not.exist');
+ cy.get('[data-testid="card"]')
+ .first()
+ .contains('Eight imagine picture tough.');
});
it('should be able to filter by multiple fields', () => {
//Revert the default sort
cy.contains('[role="button"]', 'Name').as('nameSortButton').click();
cy.get('@nameSortButton').click();
- cy.wait('@getInstrumentsOrder', { timeout: 10000 });
cy.get('[data-testid="advanced-filters-link"]').click();
cy.get('[aria-label="Filter by Name"]').first().type('oil');
diff --git a/packages/datagateway-dataview/cypress/e2e/card/isis/investigations.cy.ts b/packages/datagateway-dataview/cypress/e2e/card/isis/investigations.cy.ts
index 408b68aa1..0c6cd802c 100644
--- a/packages/datagateway-dataview/cypress/e2e/card/isis/investigations.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/card/isis/investigations.cy.ts
@@ -146,15 +146,24 @@ describe('ISIS - Investigations Cards', () => {
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('Stop system investment');
- // multiple fields
+ // multiple fields (shift click)
cy.get('@dateSortButton').click();
- cy.get('@titleSortButton').click();
+ cy.get('@titleSortButton').click({ shiftKey: true });
cy.wait('@getInvestigationsOrder', { timeout: 10000 });
cy.contains('[aria-label="Sort by TITLE"]', 'asc').should('exist');
cy.contains('[aria-label="Sort by START DATE"]', 'asc').should('exist');
cy.contains('[role="button"]', 'desc').should('not.exist');
cy.get('[data-testid="card"]').first().contains('Stop system investment');
+
+ // should replace current sort if clicked without shift
+ cy.get('@titleSortButton').click();
+ cy.wait('@getInvestigationsOrder', { timeout: 10000 });
+
+ cy.contains('[aria-label="Sort by TITLE"]', 'desc').should('exist');
+ cy.contains('[aria-label="Sort by START DATE"]', 'asc').should('not.exist');
+ cy.contains('[role="button"]', 'asc').should('not.exist');
+ cy.get('[data-testid="card"]').first().contains('Stop system investment');
});
it('should be able to filter by multiple fields', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/datafiles.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/datafiles.cy.ts
index 8c37e62fc..813e5d290 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/datafiles.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/datafiles.cy.ts
@@ -70,23 +70,65 @@ describe('Datafiles Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
'/five/with/question.bmp'
);
- // multiple columns
+ // multiple columns (shift click)
cy.contains('[role="button"]', 'Name').click();
cy.wait('@datafilesOrder', { timeout: 10000 });
- cy.contains('[role="button"]', 'Modified Time').click();
+ cy.contains('[role="button"]', 'Modified Time').click({ shiftKey: true });
cy.wait('@datafilesOrder', { timeout: 10000 });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('Datafile 1071');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
+ '/able/leg/policy.gif'
+ );
+ });
+
+ it('should change icons when sorting on a column', () => {
+ cy.wait(
+ [
+ '@investigations',
+ '@datafilesCount',
+ '@datasets',
+ '@datafilesOrder',
+ '@datafilesOrder',
+ ],
+ {
+ timeout: 10000,
+ }
+ );
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Name').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 2);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/datasets.cy.ts
index fa73864af..05af2e223 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/datasets.cy.ts
@@ -55,20 +55,49 @@ describe('Datasets Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 1');
+ // multiple columns (shift + click)
cy.contains('[role="button"]', 'Create Time').as('timeSortButton').click();
- cy.get('@timeSortButton').click();
- cy.get('@nameSortButton').click();
- cy.get('@nameSortButton').click();
+ cy.get('@timeSortButton').click({ shiftKey: true });
+ cy.get('@nameSortButton').click({ shiftKey: true });
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 61');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.get('[aria-sort="descending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 61');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Modified Time').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/dls/datafiles.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/dls/datafiles.cy.ts
index f8e316209..10cd0da45 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/dls/datafiles.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/dls/datafiles.cy.ts
@@ -71,25 +71,56 @@ describe('DLS - Datafiles Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
'/time/run/drug.jpeg'
);
- // multiple columns
+ // multiple columns (shift click)
cy.get('@timeSortButton').click();
cy.wait('@datafilesOrder', { timeout: 10000 });
- cy.contains('[role="button"]', 'Name').as('nameSortButton').click();
+ cy.contains('[role="button"]', 'Name')
+ .as('nameSortButton')
+ .click({ shiftKey: true });
cy.wait('@datafilesOrder', { timeout: 10000 });
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@datafilesOrder', { timeout: 10000 });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('Datafile 60');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
+ '/analysis/unit/bank.tiff'
+ );
+ });
+
+ it('should change icons when sorting on a column', () => {
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Name').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 2);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/dls/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/dls/datasets.cy.ts
index a5f9ce928..1614f8f56 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/dls/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/dls/datasets.cy.ts
@@ -1,7 +1,6 @@
describe('DLS - Datasets Table', () => {
beforeEach(() => {
cy.intercept('**/investigations/1').as('investigations');
- cy.intercept('**/investigations/findone?*').as('investigationsFindOne');
cy.intercept('**/datasets/count?*').as('datasetsCount');
cy.intercept('**/datasets?*').as('datasets');
cy.login();
@@ -9,7 +8,6 @@ describe('DLS - Datasets Table', () => {
[
'@investigations',
'@investigations',
- '@investigationsFindOne',
'@datasetsCount',
'@datasets',
'@datasets',
@@ -78,24 +76,55 @@ describe('DLS - Datasets Table', () => {
cy.get('@nameSortButton').click();
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 1');
- // multiple columns
+ // multiple columns (shift click)
cy.get('@timeSortButton').click();
cy.wait('@datasets', { timeout: 10000 });
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@datasets', { timeout: 10000 });
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@datasets', { timeout: 10000 });
cy.get('[aria-rowcount="2"]').should('exist');
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 1');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.get('[aria-sort="descending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 61');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear the default sort
+ cy.contains('[role="button"]', 'Create Time').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Modified Time').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/dls/myData.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/dls/myData.cy.ts
index 803ddc0fa..bbf38f5c9 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/dls/myData.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/dls/myData.cy.ts
@@ -68,23 +68,53 @@ describe('DLS - MyData Table', () => {
cy.get('@titleSortButton').click();
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 5);
+
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
cy.get('[aria-rowindex="1"] [aria-colindex="2"]').contains(
'Star enter wide nearly off.'
);
- // multiple columns
+ // multiple columns (shift + click)
cy.get('@titleSortButton').click();
- cy.contains('[role="button"]', 'Instrument').click();
+ cy.contains('[role="button"]', 'Instrument').click({ shiftKey: true });
cy.get('[aria-rowindex="1"] [aria-colindex="2"]').contains(
'Across prepare why go.'
);
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Visit').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('72');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Start Date').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 5);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Instrument').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Instrument').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Visit').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 3);
});
it('should be able to filter with role, text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/investigations.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/investigations.cy.ts
index 4a046e913..1153dea63 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/investigations.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/investigations.cy.ts
@@ -65,22 +65,49 @@ describe('Investigations Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 6);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains(
'Analysis reflect work or hour color maybe. Much team discussion message weight.'
);
- // multiple columns
+ // multiple columns (shift + click)
cy.contains('[role="button"]', 'Start Date').click();
- cy.get('@titleSortButton').click();
+ cy.get('@titleSortButton').click({ shiftKey: true });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains(
'Analysis reflect work or hour color maybe. Much team discussion message weight.'
);
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Visit').click();
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains('1');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ cy.get('[data-testid="SortIcon"]').should('have.length', 6);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Visit').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Visit').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Title').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 4);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/isis/dataPublications.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/isis/dataPublications.cy.ts
index e997bea4f..0b0fee3ec 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/isis/dataPublications.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/isis/dataPublications.cy.ts
@@ -80,24 +80,54 @@ describe('ISIS - Data Publication Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.be.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="1"]').contains(
'Article subject amount'
);
- // multiple columns
- cy.get('@dateSortButton').click();
+ // multiple columns (shift click)
cy.get('@dateSortButton').click();
- cy.get('@titleSortButton').click();
+ cy.get('@dateSortButton').click({ shiftKey: true });
+ cy.get('@titleSortButton').click({ shiftKey: true });
cy.get('[aria-rowindex="1"] [aria-colindex="1"]').contains(
'Church child time Congress'
);
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Publication Date').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('2010-02-24');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Publication Date').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'DOI').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'DOI').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Title').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/isis/datafiles.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/isis/datafiles.cy.ts
index 9a36b164d..51ae140a2 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/isis/datafiles.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/isis/datafiles.cy.ts
@@ -87,25 +87,60 @@ describe('ISIS - Datafiles Table', () => {
cy.get('@locationSortButton').click();
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
'/debate/form/growth.gif'
);
- // multiple columns
+ // multiple columns (shift click)
cy.get('@timeSortButton').click();
cy.wait('@datafilesOrder', { timeout: 10000 });
- cy.contains('[role="button"]', 'Name').as('nameSortButton').click();
+ cy.contains('[role="button"]', 'Name')
+ .as('nameSortButton')
+ .click({ shiftKey: true });
cy.wait('@datafilesOrder', { timeout: 10000 });
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@datafilesOrder', { timeout: 10000 });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('Datafile 78');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Location').click();
+ cy.wait('@datafilesOrder', { timeout: 10000 });
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="4"]').contains(
+ '/add/go/interview.png'
+ );
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Modified Time').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Location').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Name').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 2);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/isis/datasets.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/isis/datasets.cy.ts
index 702e7b5c1..985098ac6 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/isis/datasets.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/isis/datasets.cy.ts
@@ -78,21 +78,52 @@ describe('ISIS - Datasets Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 19');
- // multiple columns
+ // multiple columns (shift click)
cy.get('@timeSortButton').click();
cy.wait('@datasetsOrder', { timeout: 10000 });
- cy.get('@nameSortButton').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
cy.wait('@datasetsOrder', { timeout: 10000 });
cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 19');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.contains('[role="button"]', 'Modified Time').click();
+ cy.get('[aria-sort="descending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('DATASET 79');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Create Time').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Create Time').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Modified Time').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/isis/facilityCycles.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/isis/facilityCycles.cy.ts
index 9ec657116..da858de13 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/isis/facilityCycles.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/isis/facilityCycles.cy.ts
@@ -59,15 +59,51 @@ describe('ISIS - FacilityCycles Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="2"]').contains(
'2001-04-02 00:00:00'
);
+
+ // multiple columns (shift click)
+ cy.contains('[role="button"]', 'Start Date').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
+ cy.get('[aria-rowindex="1"] [aria-colindex="1"]').contains('2001 cycle 2');
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'End Date').click();
+ cy.contains('[role="button"]', 'End Date').click();
+ cy.get('[aria-sort="descending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="1"]').contains('2004 cycle 3');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Start Date').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 3);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Start Date').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Start Date').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'End Date').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-dataview/cypress/e2e/table/isis/instruments.cy.ts b/packages/datagateway-dataview/cypress/e2e/table/isis/instruments.cy.ts
index 7ea36932d..fea99b6b8 100644
--- a/packages/datagateway-dataview/cypress/e2e/table/isis/instruments.cy.ts
+++ b/packages/datagateway-dataview/cypress/e2e/table/isis/instruments.cy.ts
@@ -62,15 +62,52 @@ describe('ISIS - Instruments Table', () => {
cy.get('[aria-sort="ascending"]').should('not.exist');
cy.get('[aria-sort="descending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 2);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="2"]').contains(
'Stop prove field onto think suffer measure.'
);
+
+ // multiple columns (shift click)
+ cy.contains('[role="button"]', 'Type').click();
+ cy.get('@nameSortButton').click({ shiftKey: true });
+ cy.get('[aria-sort="ascending"]').should('have.length', 2);
+
+ // should replace the previous sort when clicked without shift
+ cy.get('@nameSortButton').click();
+ cy.get('[aria-sort="descending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('5');
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Name').click();
+ cy.contains('[role="button"]', 'Name').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 2);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Name').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Name').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Type').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.contains('[role="button"]', 'Type').trigger('mouseout');
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 1);
});
it('should be able to filter with text filter on multiple columns', () => {
diff --git a/packages/datagateway-download/cypress/e2e/adminDownloadStatus.cy.ts b/packages/datagateway-download/cypress/e2e/adminDownloadStatus.cy.ts
index 270dcad09..97a6b68f1 100644
--- a/packages/datagateway-download/cypress/e2e/adminDownloadStatus.cy.ts
+++ b/packages/datagateway-download/cypress/e2e/adminDownloadStatus.cy.ts
@@ -77,20 +77,21 @@ describe('Admin Download Status', () => {
cy.get('@accessMethodSortButton').click();
cy.get('[aria-sort="ascending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('[aria-sort="descending"]').should('not.exist');
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 8);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="5"]').should(
'have.text',
'https'
);
- // multiple columns
+ // multiple columns (shift + click)
cy.contains('[role="button"]', 'Deleted').click();
- cy.contains('[role="button"]', 'Availability').click();
+ cy.contains('[role="button"]', 'Availability').click({ shiftKey: true });
+ cy.get('[aria-sort="ascending"]').should('have.length', 2);
cy.get('[aria-rowindex="2"] [aria-colindex="6"]').should(
'have.text',
@@ -100,6 +101,36 @@ describe('Admin Download Status', () => {
'have.text',
'Expired'
);
+
+ // should replace previous sort when clicked without shift
+ cy.contains('[role="button"]', 'Prepared ID').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ });
+
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Requested Date').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 8);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'ID').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'ID').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Full Name').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 6);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-download/cypress/e2e/downloadCart.cy.ts b/packages/datagateway-download/cypress/e2e/downloadCart.cy.ts
index 2ca7ad9e9..2b4918234 100644
--- a/packages/datagateway-download/cypress/e2e/downloadCart.cy.ts
+++ b/packages/datagateway-download/cypress/e2e/downloadCart.cy.ts
@@ -68,11 +68,19 @@ describe('Download Cart', () => {
'investigation'
);
- cy.contains('[role="button"]', 'Name').click();
+ // multisort with shift key
+ cy.contains('[role="button"]', 'Name').click({ shiftKey: true });
cy.get('[aria-rowindex=1] [aria-colindex=1]').should(
'have.text',
'INVESTIGATION 10'
);
+
+ // replace previous sory by clicking without shift key
+ cy.contains('[role="button"]', 'Name').click();
+ cy.get('[aria-rowindex=1] [aria-colindex=1]').should(
+ 'have.text',
+ 'INVESTIGATION 8'
+ );
});
it('should be able to filter cart items by name and type', () => {
diff --git a/packages/datagateway-download/cypress/e2e/downloadStatus.cy.ts b/packages/datagateway-download/cypress/e2e/downloadStatus.cy.ts
index 117ab83d7..606c9331f 100644
--- a/packages/datagateway-download/cypress/e2e/downloadStatus.cy.ts
+++ b/packages/datagateway-download/cypress/e2e/downloadStatus.cy.ts
@@ -109,12 +109,12 @@ describe('Download Status', () => {
cy.get('@nameSortButton').click();
cy.get('[aria-sort="ascending"]').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionDesc').should('not.exist');
- cy.get('.MuiTableSortLabel-iconDirectionAsc').should(
- 'have.css',
- 'opacity',
- '0'
- );
+ cy.get('[aria-sort="descending"]').should('not.exist');
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('not.exist');
+
cy.get('[aria-rowindex="1"] [aria-colindex="1"]').should(
'have.text',
'test-file-1'
@@ -125,14 +125,43 @@ describe('Download Status', () => {
'Available'
);
- // multiple columns
+ // multiple columns (shift + click)
+ cy.contains('[role="button"]', 'Download Name').click();
+ cy.contains('[role="button"]', 'Availability').click({ shiftKey: true });
+ cy.get('[aria-sort="ascending"]').should('have.length', 2);
+
+ cy.get('[aria-rowindex="1"] [aria-colindex="3"]').contains('Available');
+
+ // should replace previous sort when clicked without shift
cy.contains('[role="button"]', 'Access Method').click();
- cy.contains('[role="button"]', 'Availability').click();
+ cy.get('[aria-sort="ascending"]').should('have.length', 1);
+ cy.get('[aria-rowindex="1"] [aria-colindex="1"]').contains('test-file-2');
+ });
- cy.get('[aria-rowindex="1"] [aria-colindex="1"]').should(
- 'have.text',
- 'test-file-4'
- );
+ it('should change icons when sorting on a column', () => {
+ // clear default sort
+ cy.contains('[role="button"]', 'Requested Date').click();
+
+ cy.get('[data-testid="SortIcon"]').should('have.length', 4);
+
+ // check icon when clicking on a column
+ cy.contains('[role="button"]', 'Download Name').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('exist');
+
+ // check icon when clicking on a column again
+ cy.contains('[role="button"]', 'Download Name').click();
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+ cy.get('.MuiTableSortLabel-iconDirectionAsc').should('not.exist');
+
+ // check icon when hovering over a column
+ cy.contains('[role="button"]', 'Access Method').trigger('mouseover');
+ cy.get('[data-testid="ArrowUpwardIcon"]').should('have.length', 1);
+ cy.get('[data-testid="ArrowDownwardIcon"]').should('have.length', 1);
+
+ // check icons when shift is held
+ cy.get('.App').trigger('keydown', { key: 'Shift' });
+ cy.get('[data-testid="AddIcon"]').should('have.length', 2);
});
it('should be able to filter with both text & date filters on multiple columns', () => {
diff --git a/packages/datagateway-download/src/downloadCart/downloadCartTable.component.test.tsx b/packages/datagateway-download/src/downloadCart/downloadCartTable.component.test.tsx
index fa22a6f42..84a46db79 100644
--- a/packages/datagateway-download/src/downloadCart/downloadCartTable.component.test.tsx
+++ b/packages/datagateway-download/src/downloadCart/downloadCartTable.component.test.tsx
@@ -242,6 +242,8 @@ describe('Download cart table component', () => {
});
it('should sort data when headers are clicked', async () => {
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ skipHover: true });
renderComponent();
const typeSortLabel = await screen.findByRole('button', {
@@ -272,7 +274,9 @@ describe('Download cart table component', () => {
name: 'downloadCart.name',
});
+ await user.keyboard('{Shift>}');
await user.click(nameSortLabel);
+ await user.keyboard('{/Shift}');
rows = await screen.findAllByText(/(DATAFILE|DATASET|INVESTIGATION) \d/);
// row should be sorted by type desc & name asc.
@@ -281,7 +285,9 @@ describe('Download cart table component', () => {
expect(rows[2]).toHaveTextContent('DATASET 1');
expect(rows[3]).toHaveTextContent('DATAFILE 1');
+ await user.keyboard('{Shift>}');
await user.click(nameSortLabel);
+ await user.keyboard('{/Shift}');
rows = await screen.findAllByText(/(DATAFILE|DATASET|INVESTIGATION) \d/);
// row should be sorted by type desc & name desc.
@@ -298,6 +304,15 @@ describe('Download cart table component', () => {
expect(rows[1]).toHaveTextContent('INVESTIGATION 2');
expect(rows[2]).toHaveTextContent('DATASET 1');
expect(rows[3]).toHaveTextContent('DATAFILE 1');
+
+ await user.click(nameSortLabel);
+
+ rows = await screen.findAllByText(/(DATAFILE|DATASET|INVESTIGATION) \d/);
+ // row should be sorted by name asc.
+ expect(rows[0]).toHaveTextContent('DATAFILE 1');
+ expect(rows[1]).toHaveTextContent('DATASET 1');
+ expect(rows[2]).toHaveTextContent('INVESTIGATION 1');
+ expect(rows[3]).toHaveTextContent('INVESTIGATION 2');
});
it('should filter data when text fields are typed into', async () => {
diff --git a/packages/datagateway-download/src/downloadCart/downloadCartTable.component.tsx b/packages/datagateway-download/src/downloadCart/downloadCartTable.component.tsx
index 4c389d298..17963293c 100644
--- a/packages/datagateway-download/src/downloadCart/downloadCartTable.component.tsx
+++ b/packages/datagateway-download/src/downloadCart/downloadCartTable.component.tsx
@@ -194,9 +194,11 @@ const DownloadCartTable: React.FC = (
[t, textFilter]
);
const onSort = React.useCallback(
- (column: string, order: 'desc' | 'asc' | null) => {
+ (column: string, order: 'desc' | 'asc' | null, _, shiftDown?: boolean) => {
if (order) {
- setSort({ ...sort, [column]: order });
+ shiftDown
+ ? setSort({ ...sort, [column]: order })
+ : setSort({ [column]: order });
} else {
const { [column]: order, ...restOfSort } = sort;
setSort(restOfSort);
diff --git a/packages/datagateway-download/src/downloadStatus/__snapshots__/adminDownloadStatusTable.component.test.tsx.snap b/packages/datagateway-download/src/downloadStatus/__snapshots__/adminDownloadStatusTable.component.test.tsx.snap
index 55c0f2651..f0915329e 100644
--- a/packages/datagateway-download/src/downloadStatus/__snapshots__/adminDownloadStatusTable.component.test.tsx.snap
+++ b/packages/datagateway-download/src/downloadStatus/__snapshots__/adminDownloadStatusTable.component.test.tsx.snap
@@ -101,7 +101,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -112,13 +114,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -224,7 +226,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -235,13 +239,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -347,7 +351,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -358,13 +364,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -470,7 +476,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -481,13 +489,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -593,7 +601,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -604,13 +614,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -716,7 +726,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -727,13 +739,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
@@ -878,7 +890,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -1023,7 +1037,9 @@ exports[`Admin Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -1034,13 +1050,13 @@ exports[`Admin Download Status Table should render correctly 1`] = `
diff --git a/packages/datagateway-download/src/downloadStatus/__snapshots__/downloadStatusTable.component.test.tsx.snap b/packages/datagateway-download/src/downloadStatus/__snapshots__/downloadStatusTable.component.test.tsx.snap
index 4fbc6d645..6801228c7 100644
--- a/packages/datagateway-download/src/downloadStatus/__snapshots__/downloadStatusTable.component.test.tsx.snap
+++ b/packages/datagateway-download/src/downloadStatus/__snapshots__/downloadStatusTable.component.test.tsx.snap
@@ -61,7 +61,9 @@ exports[`Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -72,13 +74,13 @@ exports[`Download Status Table should render correctly 1`] = `
@@ -184,7 +186,9 @@ exports[`Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -195,13 +199,13 @@ exports[`Download Status Table should render correctly 1`] = `
@@ -307,7 +311,9 @@ exports[`Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -318,13 +324,13 @@ exports[`Download Status Table should render correctly 1`] = `
@@ -431,7 +437,9 @@ exports[`Download Status Table should render correctly 1`] = `
class="MuiBox-root css-0"
>
diff --git a/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.test.tsx b/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.test.tsx
index 20d4870a4..68c297fdf 100644
--- a/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.test.tsx
+++ b/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.test.tsx
@@ -156,6 +156,8 @@ describe('Admin Download Status Table', () => {
});
it('should send sort request on sort', async () => {
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ delay: null, skipHover: true });
renderComponent();
// Table is sorted by createdAt desc by default
@@ -182,22 +184,39 @@ describe('Admin Download Status Table', () => {
'downloadStatus.transport'
);
+ // should replace the sort by username with sort by access method
await user.click(accessMethodSortLabel);
expect(fetchAdminDownloads).toHaveBeenCalledWith(
{
downloadApiUrl: mockedSettings.downloadApiUrl,
facilityName: mockedSettings.facilityName,
},
- `WHERE download.facilityName = '${mockedSettings.facilityName}' ORDER BY download.userName asc, download.transport asc, download.id ASC LIMIT 0, 50`
+ `WHERE download.facilityName = '${mockedSettings.facilityName}' ORDER BY download.transport asc, download.id ASC LIMIT 0, 50`
);
+ // should append sort if shift key is pressed
+ await user.keyboard('{Shift>}');
+ await user.click(usernameSortLabel);
+ await user.keyboard('{/Shift}');
+
+ expect(fetchAdminDownloads).toHaveBeenCalledWith(
+ {
+ downloadApiUrl: mockedSettings.downloadApiUrl,
+ facilityName: mockedSettings.facilityName,
+ },
+ `WHERE download.facilityName = '${mockedSettings.facilityName}' ORDER BY download.transport asc, download.userName asc, download.id ASC LIMIT 0, 50`
+ );
+
+ await user.keyboard('{Shift>}');
await user.click(accessMethodSortLabel);
+ await user.keyboard('{/Shift}');
+
expect(fetchAdminDownloads).toHaveBeenCalledWith(
{
downloadApiUrl: mockedSettings.downloadApiUrl,
facilityName: mockedSettings.facilityName,
},
- `WHERE download.facilityName = '${mockedSettings.facilityName}' ORDER BY download.userName asc, download.transport desc, download.id ASC LIMIT 0, 50`
+ `WHERE download.facilityName = '${mockedSettings.facilityName}' ORDER BY download.transport desc, download.userName asc, download.id ASC LIMIT 0, 50`
);
await user.click(accessMethodSortLabel);
@@ -212,6 +231,9 @@ describe('Admin Download Status Table', () => {
describe('text filters', () => {
it('should filter username properly', async () => {
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ delay: null, skipHover: true });
+
renderComponent();
await flushPromises();
@@ -248,6 +270,9 @@ describe('Admin Download Status Table', () => {
});
it('should filter download availability properly', async () => {
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ delay: null, skipHover: true });
+
renderComponent();
await flushPromises();
@@ -305,12 +330,16 @@ describe('Admin Download Status Table', () => {
it('sends filter request on date filter', async () => {
applyDatePickerWorkaround();
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ delay: null, skipHover: true });
+
renderComponent();
await flushPromises();
// Table is sorted by createdAt desc by default
// To keep working test, we will remove all sorts on the table beforehand
await user.click(await screen.findByText('downloadStatus.createdAt'));
+ await flushPromises();
// Get the Requested Data From filter input
const dateFromFilterInput = screen.getByRole('textbox', {
@@ -337,18 +366,15 @@ describe('Admin Download Status Table', () => {
await user.type(dateToFilterInput, '2020-01-02_23:59:00');
await flushPromises();
- // have to wrap the expect in a waitFor because for some reason
- // await user.type doesn't wait until the full thing is typed in before resolving
- // causing fetchAdminDownloads to be called with partial values
- await waitFor(() => {
- expect(fetchAdminDownloads).toHaveBeenCalledWith(
- {
- downloadApiUrl: mockedSettings.downloadApiUrl,
- facilityName: mockedSettings.facilityName,
- },
- `WHERE download.facilityName = '${mockedSettings.facilityName}' AND download.createdAt BETWEEN {ts '2020-01-01 00:00:00'} AND {ts '2020-01-02 23:59:00'} ORDER BY download.id ASC LIMIT 0, 50`
- );
- });
+ expect(fetchAdminDownloads).toHaveBeenCalledWith(
+ {
+ downloadApiUrl: mockedSettings.downloadApiUrl,
+ facilityName: mockedSettings.facilityName,
+ },
+ `WHERE download.facilityName = '${mockedSettings.facilityName}' AND download.createdAt BETWEEN {ts '2020-01-01 00:00:00'} AND {ts '2020-01-02 23:59:00'} ORDER BY download.id ASC LIMIT 0, 50`
+ );
+
+ (fetchAdminDownloads as jest.Mock).mockClear();
await user.clear(dateFromFilterInput);
await user.clear(dateToFilterInput);
diff --git a/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.tsx b/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.tsx
index f9125908e..6752b35b6 100644
--- a/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.tsx
+++ b/packages/datagateway-download/src/downloadStatus/adminDownloadStatusTable.component.tsx
@@ -370,9 +370,16 @@ const AdminDownloadStatusTable: React.FC = () => {
},
]}
sort={sort}
- onSort={(column: string, order: 'desc' | 'asc' | null) => {
+ onSort={(
+ column: string,
+ order: 'desc' | 'asc' | null,
+ _,
+ shiftDown?: boolean
+ ) => {
if (order) {
- setSort({ ...sort, [column]: order });
+ shiftDown
+ ? setSort({ ...sort, [column]: order })
+ : setSort({ [column]: order });
} else {
const { [column]: order, ...restOfSort } = sort;
setSort(restOfSort);
diff --git a/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.test.tsx b/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.test.tsx
index 19627c92e..775a4af2c 100644
--- a/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.test.tsx
+++ b/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.test.tsx
@@ -47,7 +47,7 @@ describe('Download Status Table', () => {
let user: ReturnType;
beforeEach(() => {
- user = userEvent.setup();
+ user = userEvent.setup({ delay: null });
(downloadDeleted as jest.Mock).mockImplementation(() => Promise.resolve());
(fetchDownloads as jest.Mock).mockImplementation(() =>
@@ -188,6 +188,8 @@ describe('Download Status Table', () => {
});
it('should sort data when headers are clicked', async () => {
+ // use skipHover to avoid triggering sort tooltips which slow the test down
+ user = userEvent.setup({ delay: null, skipHover: true });
renderComponent();
// Table is sorted by createdAt desc by default
@@ -220,7 +222,9 @@ describe('Download Status Table', () => {
// Get the download name sort header.
const nameSortLabel = screen.getByText('downloadStatus.filename');
+ await user.keyboard('{Shift>}');
await user.click(nameSortLabel);
+ await user.keyboard('{/Shift}');
// name should be in asc order
rows = await screen.findAllByText(/^test-file-\d$/);
@@ -230,7 +234,9 @@ describe('Download Status Table', () => {
expect(rows[3]).toHaveTextContent('test-file-4');
expect(rows[4]).toHaveTextContent('test-file-5');
+ await user.keyboard('{Shift>}');
await user.click(nameSortLabel);
+ await user.keyboard('{/Shift}');
// name should be in desc order
rows = await screen.findAllByText(/^test-file-\d$/);
@@ -239,6 +245,26 @@ describe('Download Status Table', () => {
expect(rows[2]).toHaveTextContent('test-file-5');
expect(rows[3]).toHaveTextContent('test-file-4');
expect(rows[4]).toHaveTextContent('test-file-2');
+
+ await user.click(accessMethodSortLabel);
+
+ // name should be in desc order
+ rows = await screen.findAllByText(/^test-file-\d$/);
+ expect(rows[0]).toHaveTextContent('test-file-5');
+ expect(rows[1]).toHaveTextContent('test-file-4');
+ expect(rows[2]).toHaveTextContent('test-file-3');
+ expect(rows[3]).toHaveTextContent('test-file-2');
+ expect(rows[4]).toHaveTextContent('test-file-1');
+
+ await user.click(accessMethodSortLabel);
+
+ // access methods should be in asc order, globus < https
+ rows = await screen.findAllByText(/^test-file-\d$/);
+ expect(rows[0]).toHaveTextContent('test-file-2');
+ expect(rows[1]).toHaveTextContent('test-file-4');
+ expect(rows[2]).toHaveTextContent('test-file-5');
+ expect(rows[3]).toHaveTextContent('test-file-1');
+ expect(rows[4]).toHaveTextContent('test-file-3');
});
it('should filter data when text fields are typed into', async () => {
diff --git a/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.tsx b/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.tsx
index 68cafe642..0c8f3c082 100644
--- a/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.tsx
+++ b/packages/datagateway-download/src/downloadStatus/downloadStatusTable.component.tsx
@@ -326,9 +326,16 @@ const DownloadStatusTable: React.FC = (
},
]}
sort={sort}
- onSort={(column: string, order: 'desc' | 'asc' | null) => {
+ onSort={(
+ column: string,
+ order: 'desc' | 'asc' | null,
+ _,
+ shiftDown?: boolean
+ ) => {
if (order) {
- setSort({ ...sort, [column]: order });
+ shiftDown
+ ? setSort({ ...sort, [column]: order })
+ : setSort({ [column]: order });
} else {
const { [column]: order, ...restOfSort } = sort;
setSort(restOfSort);
diff --git a/packages/datagateway-download/src/downloadTab/__snapshots__/downloadTab.component.test.tsx.snap b/packages/datagateway-download/src/downloadTab/__snapshots__/downloadTab.component.test.tsx.snap
index 049b6b42f..fd2d892c1 100644
--- a/packages/datagateway-download/src/downloadTab/__snapshots__/downloadTab.component.test.tsx.snap
+++ b/packages/datagateway-download/src/downloadTab/__snapshots__/downloadTab.component.test.tsx.snap
@@ -122,7 +122,9 @@ exports[`DownloadTab should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -133,13 +135,13 @@ exports[`DownloadTab should render correctly 1`] = `
@@ -245,7 +247,9 @@ exports[`DownloadTab should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -256,13 +260,13 @@ exports[`DownloadTab should render correctly 1`] = `
@@ -368,7 +372,9 @@ exports[`DownloadTab should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -379,13 +385,13 @@ exports[`DownloadTab should render correctly 1`] = `
@@ -423,7 +429,9 @@ exports[`DownloadTab should render correctly 1`] = `
class="MuiBox-root css-0"
>
@@ -434,13 +442,13 @@ exports[`DownloadTab should render correctly 1`] = `