diff --git a/cypress/component/DataSearch/dataset_search_footer.spec.js b/cypress/component/DataSearch/dataset_search_footer.spec.js
new file mode 100644
index 000000000..4bf0c186c
--- /dev/null
+++ b/cypress/component/DataSearch/dataset_search_footer.spec.js
@@ -0,0 +1,65 @@
+/* eslint-disable no-undef */
+import {mount} from 'cypress/react';
+import {React} from 'react';
+import {DatasetSearchFooter} from '../../../src/components/data_search/DatasetSearchFooter';
+
+const datasets = [
+ {
+ datasetId: 123456,
+ study: {
+ studyId: 1,
+ }
+ },
+ {
+ datasetId: 234567,
+ study: {
+ studyId: 1,
+ }
+ },
+ {
+ datasetId: 345678,
+ study: {
+ studyId: 2,
+ }
+ },
+];
+
+const oneDatasetProps = {
+ selectedDatasets: [123456],
+ datasets: datasets,
+ onClick: () => {},
+};
+
+const oneStudyProps = {
+ selectedDatasets: [123456, 234567],
+ datasets: datasets,
+ onClick: () => {},
+};
+
+const twoStudiesProps = {
+ selectedDatasets: [123456, 234567, 345678],
+ datasets: datasets,
+ onClick: () => {},
+};
+
+describe('Dataset Search Footer renders correct text and button', () => {
+
+ it('Shows button and single dataset and study text', () => {
+ mount();
+ cy.contains('1 dataset selected from 1 study');
+ cy.contains('Apply for Access');
+ });
+
+
+ it('Shows button and two datasets from one study text', () => {
+ mount();
+ cy.contains('2 datasets selected from 1 study');
+ cy.contains('Apply for Access');
+ });
+
+ it('Shows button and three datasets from two studies text', () => {
+ mount();
+ cy.contains('3 datasets selected from 2 studies');
+ cy.contains('Apply for Access');
+ });
+});
diff --git a/cypress/component/DataSearch/dataset_search_table.spec.js b/cypress/component/DataSearch/dataset_search_table.spec.js
new file mode 100644
index 000000000..85c1e92c6
--- /dev/null
+++ b/cypress/component/DataSearch/dataset_search_table.spec.js
@@ -0,0 +1,43 @@
+/* eslint-disable no-undef */
+import {React} from 'react';
+import {mount} from 'cypress/react';
+import DatasetSearchTable from '../../../src/components/data_search/DatasetSearchTable';
+import {TerraDataRepo} from '../../../src/libs/ajax/TerraDataRepo';
+
+const datasets = [
+ {
+ datasetId: 123456,
+ datasetIdentifier: `DUOS-123456`,
+ datasetName: 'Some Dataset 1',
+ study: {
+ studyId: 1,
+ dataCustodianEmail: ['Some Data Custodian Email 1'],
+ }
+ }
+];
+
+const props = {
+ datasets: datasets,
+ history: {}
+};
+
+describe('Dataset Search Table tests', () => {
+
+ describe('Data library with three datasets', () => {
+ beforeEach(() => {
+ cy.stub(TerraDataRepo, 'listSnapshotsByDatasetIds').returns({});
+ mount();
+ });
+
+ it('When no datasets are selected the footer does not appear', () => {
+ cy.contains('1 dataset selected from 1 study').should('not.exist');
+ });
+
+
+ it('When a dataset is selected the footer appears', () => {
+ cy.get('#header-checkbox').click();
+ cy.contains('1 dataset selected from 1 study');
+ });
+
+ });
+});
diff --git a/src/components/dac_dataset_table/DACDatasetConstants.tsx b/src/components/dac_dataset_table/DACDatasetConstants.tsx
new file mode 100644
index 000000000..8fdb53e90
--- /dev/null
+++ b/src/components/dac_dataset_table/DACDatasetConstants.tsx
@@ -0,0 +1,51 @@
+import {Styles} from '../../libs/theme';
+
+export const styles = {
+ baseStyle: {
+ fontFamily: 'Montserrat',
+ fontSize: '1.6rem',
+ fontWeight: 400,
+ display: 'flex',
+ padding: '1rem 2%',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ whiteSpace: 'pre-wrap',
+ backgroundColor: 'white',
+ border: '1px solid #DEDEDE',
+ borderRadius: '4px',
+ margin: '0.5% 0'
+ },
+ columnStyle: Object.assign({}, Styles.TABLE.HEADER_ROW, {
+ justifyContent: 'space-between',
+ color: '#7B7B7B',
+ fontFamily: 'Montserrat',
+ fontSize: '1.2rem',
+ fontWeight: 'bold',
+ letterSpacing: '0.2px',
+ textTransform: 'uppercase',
+ backgroundColor: 'B8CDD3',
+ border: 'none'
+ }),
+ cellWidths: {
+ duosId: '10%',
+ phsId: '10%',
+ datasetName: '15%',
+ studyName: '15%',
+ dataSubmitter: '15%',
+ dataCustodian: '15%',
+ dataUse: '10%',
+ status: '10%'
+ },
+ color: {
+ dataUseGroup: '#000000',
+ votes: '#000000',
+ numberOfDatasets: '#000000',
+ datasets: '#000000',
+ },
+ fontSize: {
+ dataUseGroup: '1.4rem',
+ votes: '1.4rem',
+ numberOfDatasets: '1.4rem',
+ datasets: '1.4rem',
+ },
+};
diff --git a/src/components/dac_dataset_table/DACDatasetTableCellData.jsx b/src/components/dac_dataset_table/DACDatasetTableCellData.jsx
index cdf6d0421..3becb5847 100644
--- a/src/components/dac_dataset_table/DACDatasetTableCellData.jsx
+++ b/src/components/dac_dataset_table/DACDatasetTableCellData.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import style from '../../pages/DACDatasets.module.css';
-import {styles} from './DACDatasetsTable';
+import {styles} from './DACDatasetConstants';
import DACDatasetApprovalStatus from './DACDatasetApprovalStatus';
import ReactTooltip from 'react-tooltip';
diff --git a/src/components/dac_dataset_table/DACDatasetsTable.jsx b/src/components/dac_dataset_table/DACDatasetsTable.jsx
index 5cd8e556b..2f7aef1c4 100644
--- a/src/components/dac_dataset_table/DACDatasetsTable.jsx
+++ b/src/components/dac_dataset_table/DACDatasetsTable.jsx
@@ -1,63 +1,13 @@
import React, { useState, useEffect } from 'react';
-import { Styles } from '../../libs/theme';
import { Storage } from '../../libs/storage';
import PaginationBar from '../PaginationBar';
import SimpleTable from '../SimpleTable';
import cellData from './DACDatasetTableCellData';
+import {styles} from './DACDatasetConstants';
import {isNil} from 'lodash/fp';
import {goToPage as updatePage, recalculateVisibleTable} from '../../libs/utils';
import {useCallback} from 'react';
-export const styles = {
- baseStyle: {
- fontFamily: 'Montserrat',
- fontSize: '1.6rem',
- fontWeight: 400,
- display: 'flex',
- padding: '1rem 2%',
- justifyContent: 'space-between',
- alignItems: 'center',
- whiteSpace: 'pre-wrap',
- backgroundColor: 'white',
- border: '1px solid #DEDEDE',
- borderRadius: '4px',
- margin: '0.5% 0'
- },
- columnStyle: Object.assign({}, Styles.TABLE.HEADER_ROW, {
- justifyContent: 'space-between',
- color: '#7B7B7B',
- fontFamily: 'Montserrat',
- fontSize: '1.2rem',
- fontWeight: 'bold',
- letterSpacing: '0.2px',
- textTransform: 'uppercase',
- backgroundColor: 'B8CDD3',
- border: 'none'
- }),
- cellWidths: {
- duosId: '10%',
- phsId: '10%',
- datasetName: '15%',
- studyName: '15%',
- dataSubmitter: '15%',
- dataCustodian: '15%',
- dataUse: '10%',
- status: '10%'
- },
- color: {
- dataUseGroup: '#000000',
- votes: '#000000',
- numberOfDatasets: '#000000',
- datasets: '#000000',
- },
- fontSize: {
- dataUseGroup: '1.4rem',
- votes: '1.4rem',
- numberOfDatasets: '1.4rem',
- datasets: '1.4rem',
- },
-};
-
export const DACDatasetTableColumnOptions = {
DUOS_ID: 'duosId',
PHS_ID: 'phsId',
diff --git a/src/components/data_search/DatasetSearchFooter.tsx b/src/components/data_search/DatasetSearchFooter.tsx
new file mode 100644
index 000000000..ded789eaf
--- /dev/null
+++ b/src/components/data_search/DatasetSearchFooter.tsx
@@ -0,0 +1,40 @@
+import * as _ from 'lodash';
+import {Button} from '@mui/material';
+import * as React from 'react';
+import {Dataset} from 'src/types/model';
+
+interface DatasetSearchFooterProps {
+ selectedDatasets: number[];
+ datasets: Dataset[];
+ onClick: () => void;
+}
+export const DatasetSearchFooter = (props: DatasetSearchFooterProps) => {
+ const { selectedDatasets, datasets, onClick } = props;
+ const selectedStudies = _.uniq(
+ _.filter(datasets, dataset => selectedDatasets.includes(dataset.datasetId))
+ .map(dataset => dataset.study.studyId));
+ const datasetText = selectedDatasets.length > 1 ? 'datasets' : 'dataset';
+ const studyText = selectedStudies.length > 1 ? 'studies' : 'study';
+
+ return
+
{selectedDatasets.length} {datasetText} selected from {selectedStudies.length} {studyText}
+
+
;
+};
diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx
index a67f29e57..362cc7573 100644
--- a/src/components/data_search/DatasetSearchTable.jsx
+++ b/src/components/data_search/DatasetSearchTable.jsx
@@ -1,6 +1,6 @@
import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
-import useOnMount from '@mui/utils/useOnMount'
+import useOnMount from '@mui/utils/useOnMount';
import * as React from 'react';
import { Box, Button } from '@mui/material';
import { useEffect, useState } from 'react';
@@ -15,6 +15,7 @@ import DatasetFilterList from './DatasetFilterList';
import { Notifications } from '../../libs/utils';
import { Styles } from '../../libs/theme';
import * as _ from 'lodash';
+import {DatasetSearchFooter} from './DatasetSearchFooter';
const styles = {
subTab: {
@@ -140,7 +141,7 @@ export const DatasetSearchTable = (props) => {
'dac.dacName': term
}
}))
- }
+ }
});
if (filterTerms.length > 0) {
@@ -288,14 +289,8 @@ export const DatasetSearchTable = (props) => {
})()}
-
- {
- !isEmpty(datasets) &&
-
- }
-
+
+ {!isEmpty(selected) && }
>
);
diff --git a/src/components/data_search/DatasetSearchTableConstants.tsx b/src/components/data_search/DatasetSearchTableConstants.tsx
index c61bda76f..07925b37c 100644
--- a/src/components/data_search/DatasetSearchTableConstants.tsx
+++ b/src/components/data_search/DatasetSearchTableConstants.tsx
@@ -79,7 +79,7 @@ export const makeStudyTableHeaders = (datasets: DatasetTerm[], selected: number[
const selectableDatasetIds = datasets.filter(isSelectable).map(dataset => dataset.datasetId);
return [
{
- label: