Skip to content

Commit

Permalink
518 extraction phase can we make the list of studies more spreadsheet…
Browse files Browse the repository at this point in the history
… like (#825)

* feat: added wireframes for extraction

* feat: added table

* feat: implemented table and table ordering during study edit

* feat: preserve table state in session storage and fix unit tests

* feat: finished integration tests

* fix: table pagination resets on data update

* feat: updated table with feedback

* fix: integration test

* fix: address feedback

* fix: extraction tests

* fix: tests
  • Loading branch information
nicoalee authored Sep 23, 2024
1 parent 83b42d9 commit 3ded631
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,26 +95,26 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').should('have.length', 1);
});

it('should filter the table by doi', () => {
cy.wait('@studysetFixture').then((studysetFixture) => {
const studyset = studysetFixture?.response?.body as StudysetReturn;
const studysetStudies = studyset.studies as StudyReturn[];
cy.get('input').eq(4).click();
cy.get(`input`)
.eq(4)
.type(studysetStudies[0].doi || '');
});

cy.get('tbody > tr').should('have.length', 1);
});
// it('should filter the table by doi', () => {
// cy.wait('@studysetFixture').then((studysetFixture) => {
// const studyset = studysetFixture?.response?.body as StudysetReturn;
// const studysetStudies = studyset.studies as StudyReturn[];
// cy.get('input').eq(4).click();
// cy.get(`input`)
// .eq(4)
// .type(studysetStudies[0].doi || '');
// });

// cy.get('tbody > tr').should('have.length', 1);
// });

it('should filter the table by pmid', () => {
cy.wait('@studysetFixture').then((studysetFixture) => {
const studyset = studysetFixture?.response?.body as StudysetReturn;
const studysetStudies = studyset.studies as StudyReturn[];
cy.get('input').eq(5).click();
cy.get('input').eq(4).click();
cy.get(`input`)
.eq(5)
.eq(4)
.type(studysetStudies[0].pmid || '');
});

Expand Down Expand Up @@ -181,7 +181,7 @@ describe('ExtractionTable', () => {

it('should change the study status', () => {
// ARRANGE
cy.get('tbody > tr').eq(0).get('td').eq(6).as('getFirstRowStudyStatusCol');
cy.get('tbody > tr').eq(0).get('td').eq(5).as('getFirstRowStudyStatusCol');
cy.get('@getFirstRowStudyStatusCol').within(() => {
cy.get('button').eq(0).should('have.class', 'MuiButton-contained');
});
Expand Down Expand Up @@ -370,49 +370,49 @@ describe('ExtractionTable', () => {
});
});

it('should sort by doi desc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
// it('should sort by doi desc', () => {
// cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();

cy.wait('@studysetFixture').then((studysetFixture) => {
const studyset = studysetFixture.response?.body as StudysetReturn;
const studies = [...(studyset.studies || [])] as StudyReturn[];
// cy.wait('@studysetFixture').then((studysetFixture) => {
// const studyset = studysetFixture.response?.body as StudysetReturn;
// const studies = [...(studyset.studies || [])] as StudyReturn[];

const sortedStudies = studies.sort((a, b) =>
(b.doi as string).localeCompare(a.doi as string)
);
// const sortedStudies = studies.sort((a, b) =>
// (b.doi as string).localeCompare(a.doi as string)
// );

console.log(sortedStudies);
// console.log(sortedStudies);

cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td').eq(4).should('have.text', sortedStudies[index].doi);
});
});
});
});
it('should sort by doi asc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
cy.get('[data-testid="ArrowUpwardIcon"]').should('exist');
// cy.get('tbody > tr').each((tr, index) => {
// cy.wrap(tr).within(() => {
// cy.get('td').eq(4).should('have.text', sortedStudies[index].doi);
// });
// });
// });
// });
// it('should sort by doi asc', () => {
// cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
// cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
// cy.get('[data-testid="ArrowUpwardIcon"]').should('exist');

cy.wait('@studysetFixture').then((studysetFixture) => {
const studyset = studysetFixture.response?.body as StudysetReturn;
const studies = [...(studyset.studies || [])] as StudyReturn[];
// cy.wait('@studysetFixture').then((studysetFixture) => {
// const studyset = studysetFixture.response?.body as StudysetReturn;
// const studies = [...(studyset.studies || [])] as StudyReturn[];

const sortedStudies = studies.sort((a, b) =>
(a.doi as string).localeCompare(b.doi as string)
);
// const sortedStudies = studies.sort((a, b) =>
// (a.doi as string).localeCompare(b.doi as string)
// );

cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td').eq(4).should('have.text', sortedStudies[index].doi);
});
});
});
});
// cy.get('tbody > tr').each((tr, index) => {
// cy.wrap(tr).within(() => {
// cy.get('td').eq(4).should('have.text', sortedStudies[index].doi);
// });
// });
// });
// });

it('should sort by pmid desc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();

cy.wait('@studysetFixture').then((studysetFixture) => {
const studyset = studysetFixture.response?.body as StudysetReturn;
Expand All @@ -424,21 +424,19 @@ describe('ExtractionTable', () => {
})
);

console.log(sortedStudies);

cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td')
.eq(5)
.eq(4)
.should('have.text', sortedStudies[index].pmid ?? '');
});
});
});
});

it('should sort by pmid asc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(4).click();
cy.get('[data-testid="ArrowUpwardIcon"]').should('exist');

cy.wait('@studysetFixture').then((studysetFixture) => {
Expand All @@ -454,15 +452,15 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td')
.eq(5)
.eq(4)
.should('have.text', sortedStudies[index].pmid ?? '');
});
});
});
});

it('should sort by status desc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(6).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();

cy.wait('@projectFixture').then((projectFixture) => {
const project = projectFixture?.response?.body as INeurosynthProjectReturn;
Expand All @@ -487,7 +485,7 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td')
.eq(6)
.eq(5)
.within(() => {
const studyStatus = sortedStudies[index].status;
const buttonIndex =
Expand Down Expand Up @@ -518,8 +516,8 @@ describe('ExtractionTable', () => {
});

it('should sort by status asc', () => {
cy.get('[data-testid="ArrowDownwardIcon"]').eq(6).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(6).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();
cy.get('[data-testid="ArrowDownwardIcon"]').eq(5).click();
cy.get('[data-testid="ArrowUpwardIcon"]').should('exist');

cy.wait('@projectFixture').then((projectFixture) => {
Expand All @@ -545,7 +543,7 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
cy.get('td')
.eq(6)
.eq(5)
.within(() => {
const studyStatus = sortedStudies[index].status;
const buttonIndex =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { useNavigate } from 'react-router-dom';
import { EExtractionStatus } from '../ExtractionPage';
import styles from './ExtractionTable.module.css';
import { ExtractionTableAuthorCell, ExtractionTableAuthorHeader } from './ExtractionTableAuthor';
import { ExtractionTableDOICell, ExtractionTableDOIHeader } from './ExtractionTableDOI';
import ExtractionTableFilterInput from './ExtractionTableFilterInput';
import { ExtractionTableJournalCell, ExtractionTableJournalHeader } from './ExtractionTableJournal';
import { ExtractionTableNameCell, ExtractionTableNameHeader } from './ExtractionTableName';
Expand Down Expand Up @@ -106,9 +105,9 @@ const ExtractionTable: React.FC = () => {
return [
columnHelper.accessor(({ year }) => (year ? String(year) : ''), {
id: 'year',
size: 5,
minSize: 5,
maxSize: 5,
size: 70,
minSize: 70,
maxSize: 70,
cell: ExtractionTableYearCell,
header: ExtractionTableYearHeader,
enableSorting: true,
Expand All @@ -121,9 +120,9 @@ const ExtractionTable: React.FC = () => {
columnHelper.accessor('name', {
id: 'name',
cell: ExtractionTableNameCell,
size: 25,
minSize: 25,
maxSize: 25,
size: 500,
minSize: 500,
maxSize: 500,
header: ExtractionTableNameHeader,
enableSorting: true,
sortingFn: 'text',
Expand All @@ -134,9 +133,9 @@ const ExtractionTable: React.FC = () => {
}),
columnHelper.accessor('authors', {
id: 'authors',
size: 20,
minSize: 20,
maxSize: 20,
size: 300,
minSize: 300,
maxSize: 300,
enableSorting: true,
enableColumnFilter: true,
sortingFn: 'text',
Expand All @@ -149,9 +148,9 @@ const ExtractionTable: React.FC = () => {
}),
columnHelper.accessor('publication', {
id: 'journal',
size: 15,
minSize: 15,
maxSize: 15,
size: 100,
minSize: 100,
maxSize: 100,
enableSorting: true,
enableColumnFilter: true,
cell: ExtractionTableJournalCell,
Expand All @@ -160,26 +159,26 @@ const ExtractionTable: React.FC = () => {
filterVariant: 'journal-autocomplete',
},
}),
columnHelper.accessor('doi', {
id: 'doi',
size: 15,
minSize: 15,
maxSize: 15,
sortingFn: 'alphanumeric',
enableSorting: true,
enableColumnFilter: true,
filterFn: 'includesString',
cell: ExtractionTableDOICell,
header: ExtractionTableDOIHeader,
meta: {
filterVariant: 'text',
},
}),
// columnHelper.accessor('doi', {
// id: 'doi',
// size: 10,
// minSize: 10,
// maxSize: 10,
// sortingFn: 'alphanumeric',
// enableSorting: true,
// enableColumnFilter: true,
// filterFn: 'includesString',
// cell: ExtractionTableDOICell,
// header: ExtractionTableDOIHeader,
// meta: {
// filterVariant: 'text',
// },
// }),
columnHelper.accessor('pmid', {
id: 'pmid',
size: 10,
minSize: 10,
maxSize: 10,
size: 100,
minSize: 100,
maxSize: 100,
enableColumnFilter: true,
filterFn: 'includesString',
cell: ExtractionTablePMIDCell,
Expand All @@ -192,9 +191,9 @@ const ExtractionTable: React.FC = () => {
}),
columnHelper.accessor('status', {
id: 'status',
size: 10,
minSize: 10,
maxSize: 10,
size: 120,
minSize: 120,
maxSize: 120,
enableSorting: true,
cell: ExtractionTableStatusCell,
filterFn: (row, columnId, filterValue: EExtractionStatus | null) => {
Expand Down Expand Up @@ -270,20 +269,25 @@ const ExtractionTable: React.FC = () => {
onChange={handlePaginationChangeMuiPaginator}
page={pagination.pageIndex + 1}
/>
<Typography variant="h5">Total: {data.length} studies</Typography>
</Box>
<TableContainer sx={{ marginBottom: '2rem' }}>
<Table
size="small"
sx={{ tableLayout: 'fixed', width: '100%', minWidth: '1300px' }}
sx={{ tableLayout: 'fixed', width: 'fit-content', minWidth: '1200px' }}
>
<TableHead>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableCell
key={header.id}
sx={{ width: `${header.column.getSize()}%` }}
sx={{
width:
header.column.id === 'name'
? '100%'
: `${header.column.getSize()}px`,
verticalAlign: 'bottom',
}}
>
<Box>
{flexRender(
Expand Down Expand Up @@ -416,7 +420,14 @@ const ExtractionTable: React.FC = () => {
</Box>
<Box>
<Typography sx={{ whiteSpace: 'nowrap' }}>
Viewing {table.getFilteredRowModel().rows.length} / {data.length}
{columnFilters.length > 0 ? (
<Typography>
Viewing {table.getFilteredRowModel().rows.length} /{' '}
{data.length}
</Typography>
) : (
<Typography>Total: {data.length} studies</Typography>
)}
</Typography>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,25 @@ export const ExtractionTableAuthorHeader: React.FC<
}
}}
>
<ArrowDownward sx={{ color: 'lightgray' }} />
<ArrowDownward
sx={{ width: '0.9em', height: '0.9em', color: 'lightgray' }}
/>
</IconButton>
</Tooltip>
) : isSorted === 'asc' ? (
<IconButton size="small" onClick={() => table.resetSorting()}>
<ArrowUpwardIcon sx={{ color: 'secondary.main' }} />
<ArrowUpwardIcon
sx={{ width: '0.9em', height: '0.9em', color: 'secondary.main' }}
/>
</IconButton>
) : (
<IconButton
size="small"
onClick={() => table.setSorting([{ id: 'authors', desc: false }])}
>
<ArrowDownward sx={{ color: 'secondary.main' }} />
<ArrowDownward
sx={{ width: '0.9em', height: '0.9em', color: 'secondary.main' }}
/>
</IconButton>
)}
</Box>
Expand Down
Loading

0 comments on commit 3ded631

Please sign in to comment.