From 9032adba172e08a1fe611a3aabd3950047a52c22 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Thu, 18 Jul 2024 17:16:56 -0400 Subject: [PATCH 1/8] feat: first pass at modal not working --- .../data_search/DatasetSearchTable.jsx | 17 +++- src/components/modals/DatasetModal.jsx | 95 +++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 src/components/modals/DatasetModal.jsx diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index 0ff445202..42c721f79 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -15,6 +15,7 @@ import { Notifications } from '../../libs/utils'; import { Styles } from '../../libs/theme'; import isEqual from 'lodash/isEqual'; import TranslatedDulModal from '../modals/TranslatedDulModal'; +import DatasetModal from '../modals/DatasetModal'; const studyTableHeader = [ @@ -49,6 +50,7 @@ export const DatasetSearchTable = (props) => { const [tdrApiUrl, setTdrApiUrl] = useState(''); const [showTranslatedDULModal, setShowTranslatedDULModal] = useState(false); const [dataUse, setDataUse] = useState(); + const [showDatasetModal, setShowDatasetModal] = useState(false); const searchRef = useRef(''); const isFiltered = (filter) => filters.indexOf(filter) > -1; @@ -221,9 +223,10 @@ export const DatasetSearchTable = (props) => { }; const applyForAccess = async () => { - const draftDatasets = selected.map((id) => parseInt(id.replace('dataset-', ''))); - const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); - history.push(`/dar_application/${darDraft.referenceId}`); + setShowDatasetModal(true); + // const draftDatasets = selected.map((id) => parseInt(id.replace('dataset-', ''))); + // const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); + // history.push(`/dar_application/${darDraft.referenceId}`); }; const clearSearchRef = () => { @@ -461,6 +464,14 @@ export const DatasetSearchTable = (props) => { onCloseRequest={()=>setShowTranslatedDULModal(false)} /> } + { + showDatasetModal && + setShowDatasetModal(false)} + /> + } ); }; diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx new file mode 100644 index 000000000..f4dafda1a --- /dev/null +++ b/src/components/modals/DatasetModal.jsx @@ -0,0 +1,95 @@ +import React from 'react'; +import { + Dialog, DialogTitle, DialogContent, DialogActions, Button, IconButton +} from '@mui/material'; +import { Close as CloseIcon } from '@mui/icons-material'; +import { useState, useEffect } from 'react'; +import { isEmpty, isNil } from 'lodash/fp'; +import { DataSet } from '../../libs/ajax/DataSet'; + +const listStyle = { + listStyle: 'none', + padding: '0', + fontSize:'1rem' +}; + +async function FormattedDatasets(datasets) { + + return datasets.map((dataset) => { + return ( +
  • + {dataset.datasetName}: + {dataset.datasetName} +
  • + ); + }); +} + +export default function DatasetModal(props) { + const { showModal, onCloseRequest, datasetIds } = props; + const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); + const [formattedDatasets, setFormattedDatasets] = useState([]); + const [datasets, setDatasets] = useState([]); + + + + const closeHandler = () => { + onCloseRequest(); + }; + + const fetchAllDatasets = async (datasets) => { + const filteredDatasetIds = datasets.filter((id) => !isNil(id) && Number.isInteger(id) && id > 0); + if (isEmpty(filteredDatasetIds)) { + return []; + } + // filter just for safety + return DataSet.getDatasetsByIds(filteredDatasetIds); + }; + + useEffect(() => { + console.log('allDatasets', allDatasets); + fetchAllDatasets(datasetIds).then((datasets) => { + setDatasets(datasets); + }); + const getFormattedDatasets = async () => { + const datasetList = await FormattedDatasets(allDatasets); + setFormattedDatasets(datasetList); + }; + + getFormattedDatasets(); + }, [datasets]); + + return ( + + + Data Use Terms + theme.palette.grey[500], + }} + > + + + + +
      + {formattedDatasets} +
    +
    + + + +
    + ); +} From 9d829c9abc8d886d81657206d342194f4618b644 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 24 Jul 2024 10:09:33 -0400 Subject: [PATCH 2/8] feat: progress with filtering but not quite --- .../data_search/DatasetSearchTable.jsx | 16 ++- src/components/modals/DatasetModal.jsx | 111 ++++++++++++------ 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index 42c721f79..7fae38eb9 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -222,11 +222,14 @@ export const DatasetSearchTable = (props) => { setExportableDatasets({}); }; - const applyForAccess = async () => { + const filterApprovedDatasets = async () => { setShowDatasetModal(true); - // const draftDatasets = selected.map((id) => parseInt(id.replace('dataset-', ''))); - // const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); - // history.push(`/dar_application/${darDraft.referenceId}`); + }; + + const applyForAccess = async () => { + const draftDatasets = selected.map((id) => parseInt(id.replace('dataset-', ''))); + const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); + history.push(`/dar_application/${darDraft.referenceId}`); }; const clearSearchRef = () => { @@ -450,7 +453,7 @@ export const DatasetSearchTable = (props) => { { !isEmpty(datasets) && - } @@ -468,8 +471,9 @@ export const DatasetSearchTable = (props) => { showDatasetModal && setShowDatasetModal(false)} + onApply={applyForAccess} /> } diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx index f4dafda1a..1cf599caa 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/modals/DatasetModal.jsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { Dialog, DialogTitle, DialogContent, DialogActions, Button, IconButton } from '@mui/material'; -import { Close as CloseIcon } from '@mui/icons-material'; -import { useState, useEffect } from 'react'; import { isEmpty, isNil } from 'lodash/fp'; import { DataSet } from '../../libs/ajax/DataSet'; +import { DAA } from '../../libs/ajax/DAA'; +import { Storage } from '../../libs/storage'; const listStyle = { listStyle: 'none', @@ -13,51 +13,79 @@ const listStyle = { fontSize:'1rem' }; -async function FormattedDatasets(datasets) { - - return datasets.map((dataset) => { - return ( -
  • - {dataset.datasetName}: - {dataset.datasetName} -
  • - ); - }); +function FormattedDatasets({ datasets }) { + return ( +
    +
      + {datasets.map((dataset) => ( +
    • + {dataset.datasetIdentifier} + + {dataset.datasetName.length > 50 + ? `${dataset.datasetName.substring(0, 50)}...` + : dataset.datasetName} + +
    • + ))} +
    +
    + ); } export default function DatasetModal(props) { - const { showModal, onCloseRequest, datasetIds } = props; + const { showModal, onCloseRequest, onApply, datasetIds } = props; + console.log(props.datasetIds); + const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); - const [formattedDatasets, setFormattedDatasets] = useState([]); - const [datasets, setDatasets] = useState([]); + console.log('allDatasets', allDatasets); - + const [datasets, setDatasets] = useState([]); + const [user, setUser] = useState(null); + const [libraryCard, setLibraryCard] = useState({}); + console.log(datasets); const closeHandler = () => { onCloseRequest(); }; - const fetchAllDatasets = async (datasets) => { - const filteredDatasetIds = datasets.filter((id) => !isNil(id) && Number.isInteger(id) && id > 0); + const applyHandler = () => { + onApply(); + }; + + const fetchAllDatasets = async (datasetIds) => { + const filteredDatasetIds = datasetIds.filter((id) => !isNil(id) && Number.isInteger(id) && id > 0); if (isEmpty(filteredDatasetIds)) { return []; } - // filter just for safety return DataSet.getDatasetsByIds(filteredDatasetIds); }; useEffect(() => { - console.log('allDatasets', allDatasets); - fetchAllDatasets(datasetIds).then((datasets) => { - setDatasets(datasets); - }); - const getFormattedDatasets = async () => { - const datasetList = await FormattedDatasets(allDatasets); - setFormattedDatasets(datasetList); + const getData = async () => { + const user = Storage.getCurrentUser(); + setUser(user); + console.log(Storage.getCurrentUser()); + const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; + setLibraryCard(libraryCard); + const fetchedDatasets = await fetchAllDatasets(allDatasets); + console.log(fetchedDatasets); + const daas = await DAA.getDaas(); + + const filteredDatasets = fetchedDatasets.filter((dataset) => { + const datasetDacId = dataset.dacId; + const daa = daas.find((daa) => daa.dacs?.some((d) => d.dacId === datasetDacId)); + console.log('daa',daa); + if (libraryCard.daaIds.includes(daa?.daaId)) { + return dataset; + } + }); + + console.log(filteredDatasets); + setDatasets(filteredDatasets); }; - getFormattedDatasets(); - }, [datasets]); + getData(); + }, [datasetIds]); return ( - Data Use Terms - Datasets available for Data Access Request + {/* - + */} -
      - {formattedDatasets} -
    +
    +
    Based on your credentials you can fill out a Data Access Request form for these dataset(s):
    + +
    - + +
    ); From b018c85ed014561638d621680e1af39ccea31750 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 24 Jul 2024 16:55:57 -0400 Subject: [PATCH 3/8] feat: implement filtering of datasets --- .../data_search/DatasetSearchTable.jsx | 6 +++--- src/components/modals/DatasetModal.jsx | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index 7fae38eb9..673855c9a 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -191,7 +191,7 @@ export const DatasetSearchTable = (props) => { } else { newSelected = selected.concat(idsToModify); } - + setSelected(newSelected); }; @@ -226,8 +226,8 @@ export const DatasetSearchTable = (props) => { setShowDatasetModal(true); }; - const applyForAccess = async () => { - const draftDatasets = selected.map((id) => parseInt(id.replace('dataset-', ''))); + const applyForAccess = async (datasets) => { + const draftDatasets = datasets.map((id) => parseInt(id.replace('dataset-', ''))); const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); history.push(`/dar_application/${darDraft.referenceId}`); }; diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx index 1cf599caa..9d1e57d7f 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/modals/DatasetModal.jsx @@ -5,6 +5,7 @@ import { import { isEmpty, isNil } from 'lodash/fp'; import { DataSet } from '../../libs/ajax/DataSet'; import { DAA } from '../../libs/ajax/DAA'; +import { User } from '../../libs/ajax/User'; import { Storage } from '../../libs/storage'; const listStyle = { @@ -34,7 +35,6 @@ function FormattedDatasets({ datasets }) { export default function DatasetModal(props) { const { showModal, onCloseRequest, onApply, datasetIds } = props; - console.log(props.datasetIds); const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); console.log('allDatasets', allDatasets); @@ -42,14 +42,16 @@ export default function DatasetModal(props) { const [datasets, setDatasets] = useState([]); const [user, setUser] = useState(null); const [libraryCard, setLibraryCard] = useState({}); - console.log(datasets); + console.log('datasets',datasets); const closeHandler = () => { onCloseRequest(); }; - const applyHandler = () => { - onApply(); + const applyHandler = (filteredDatasets) => { + // take the filteredDatasets and convert it to a list of strings with are prefaced with 'dataset-' and the datasetId + const datasetStrings = filteredDatasets.map(dataset => `dataset-${dataset.dataSetId}`); + onApply(datasetStrings); }; const fetchAllDatasets = async (datasetIds) => { @@ -64,12 +66,13 @@ export default function DatasetModal(props) { const getData = async () => { const user = Storage.getCurrentUser(); setUser(user); - console.log(Storage.getCurrentUser()); + console.log('user',Storage.getCurrentUser()); const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; setLibraryCard(libraryCard); const fetchedDatasets = await fetchAllDatasets(allDatasets); - console.log(fetchedDatasets); + console.log('fetchedDatasets',fetchedDatasets); const daas = await DAA.getDaas(); + console.log('daas', daas); const filteredDatasets = fetchedDatasets.filter((dataset) => { const datasetDacId = dataset.dacId; @@ -80,7 +83,7 @@ export default function DatasetModal(props) { } }); - console.log(filteredDatasets); + console.log('filteredDatasets', filteredDatasets); setDatasets(filteredDatasets); }; @@ -125,7 +128,7 @@ export default function DatasetModal(props) { - + ); From 7b75ee1e37530ee174bcb5ca8e5820eeb6b2e55d Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 24 Jul 2024 17:07:55 -0400 Subject: [PATCH 4/8] feat: make scrollable and clean up --- src/components/modals/DatasetModal.jsx | 30 ++++++++------------------ 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx index 9d1e57d7f..a63b6c8b2 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/modals/DatasetModal.jsx @@ -16,17 +16,17 @@ const listStyle = { function FormattedDatasets({ datasets }) { return ( -
    +
      {datasets.map((dataset) => ( -
    • - {dataset.datasetIdentifier} - - {dataset.datasetName.length > 50 - ? `${dataset.datasetName.substring(0, 50)}...` - : dataset.datasetName} - -
    • +
    • + {dataset.datasetIdentifier} + + {dataset.datasetName.length > 50 + ? `${dataset.datasetName.substring(0, 50)}...` + : dataset.datasetName} + +
    • ))}
    @@ -107,18 +107,6 @@ export default function DatasetModal(props) { > Datasets available for Data Access Request - {/* theme.palette.grey[500], - }} - > - - */}
    From 2a1358fe53b8564ddee0a990179273e1d5b60f8c Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 24 Jul 2024 17:09:58 -0400 Subject: [PATCH 5/8] refactor: cleanup --- src/components/modals/DatasetModal.jsx | 28 ++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx index a63b6c8b2..62f3b5e85 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/modals/DatasetModal.jsx @@ -1,11 +1,10 @@ import React, { useState, useEffect } from 'react'; import { - Dialog, DialogTitle, DialogContent, DialogActions, Button, IconButton + Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material'; import { isEmpty, isNil } from 'lodash/fp'; import { DataSet } from '../../libs/ajax/DataSet'; import { DAA } from '../../libs/ajax/DAA'; -import { User } from '../../libs/ajax/User'; import { Storage } from '../../libs/storage'; const listStyle = { @@ -22,8 +21,8 @@ function FormattedDatasets({ datasets }) {
  • {dataset.datasetIdentifier} - {dataset.datasetName.length > 50 - ? `${dataset.datasetName.substring(0, 50)}...` + {dataset.datasetName.length > 50 + ? `${dataset.datasetName.substring(0, 50)}...` : dataset.datasetName}
  • @@ -37,11 +36,11 @@ export default function DatasetModal(props) { const { showModal, onCloseRequest, onApply, datasetIds } = props; const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); - console.log('allDatasets', allDatasets); + // console.log('allDatasets', allDatasets); const [datasets, setDatasets] = useState([]); - const [user, setUser] = useState(null); - const [libraryCard, setLibraryCard] = useState({}); + // const [user, setUser] = useState(null); + // const [libraryCard, setLibraryCard] = useState({}); console.log('datasets',datasets); const closeHandler = () => { @@ -49,7 +48,6 @@ export default function DatasetModal(props) { }; const applyHandler = (filteredDatasets) => { - // take the filteredDatasets and convert it to a list of strings with are prefaced with 'dataset-' and the datasetId const datasetStrings = filteredDatasets.map(dataset => `dataset-${dataset.dataSetId}`); onApply(datasetStrings); }; @@ -65,25 +63,25 @@ export default function DatasetModal(props) { useEffect(() => { const getData = async () => { const user = Storage.getCurrentUser(); - setUser(user); - console.log('user',Storage.getCurrentUser()); + // setUser(user); + // console.log('user',Storage.getCurrentUser()); const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; - setLibraryCard(libraryCard); + // setLibraryCard(libraryCard); const fetchedDatasets = await fetchAllDatasets(allDatasets); - console.log('fetchedDatasets',fetchedDatasets); + // console.log('fetchedDatasets',fetchedDatasets); const daas = await DAA.getDaas(); - console.log('daas', daas); + // console.log('daas', daas); const filteredDatasets = fetchedDatasets.filter((dataset) => { const datasetDacId = dataset.dacId; const daa = daas.find((daa) => daa.dacs?.some((d) => d.dacId === datasetDacId)); - console.log('daa',daa); + // console.log('daa',daa); if (libraryCard.daaIds.includes(daa?.daaId)) { return dataset; } }); - console.log('filteredDatasets', filteredDatasets); + // console.log('filteredDatasets', filteredDatasets); setDatasets(filteredDatasets); }; From a5a5f80c5f4620feaac67470f0f2a65194720d9d Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Thu, 25 Jul 2024 15:50:56 -0400 Subject: [PATCH 6/8] feat: add ternary and clean up --- src/components/data_search/DatasetSearchTable.jsx | 10 +++++----- src/components/modals/DatasetModal.jsx | 14 +------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index 673855c9a..c63f94acb 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -16,7 +16,7 @@ import { Styles } from '../../libs/theme'; import isEqual from 'lodash/isEqual'; import TranslatedDulModal from '../modals/TranslatedDulModal'; import DatasetModal from '../modals/DatasetModal'; - +import { DAAUtils } from '../../utils/DAAUtils'; const studyTableHeader = [ 'Study Name', @@ -191,7 +191,7 @@ export const DatasetSearchTable = (props) => { } else { newSelected = selected.concat(idsToModify); } - + setSelected(newSelected); }; @@ -224,7 +224,7 @@ export const DatasetSearchTable = (props) => { const filterApprovedDatasets = async () => { setShowDatasetModal(true); - }; + }; const applyForAccess = async (datasets) => { const draftDatasets = datasets.map((id) => parseInt(id.replace('dataset-', ''))); @@ -453,9 +453,9 @@ export const DatasetSearchTable = (props) => { { !isEmpty(datasets) && - + } diff --git a/src/components/modals/DatasetModal.jsx b/src/components/modals/DatasetModal.jsx index 62f3b5e85..595f6154e 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/modals/DatasetModal.jsx @@ -35,13 +35,7 @@ function FormattedDatasets({ datasets }) { export default function DatasetModal(props) { const { showModal, onCloseRequest, onApply, datasetIds } = props; - const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); - // console.log('allDatasets', allDatasets); - const [datasets, setDatasets] = useState([]); - // const [user, setUser] = useState(null); - // const [libraryCard, setLibraryCard] = useState({}); - console.log('datasets',datasets); const closeHandler = () => { onCloseRequest(); @@ -63,25 +57,19 @@ export default function DatasetModal(props) { useEffect(() => { const getData = async () => { const user = Storage.getCurrentUser(); - // setUser(user); - // console.log('user',Storage.getCurrentUser()); const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; - // setLibraryCard(libraryCard); + const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); const fetchedDatasets = await fetchAllDatasets(allDatasets); - // console.log('fetchedDatasets',fetchedDatasets); const daas = await DAA.getDaas(); - // console.log('daas', daas); const filteredDatasets = fetchedDatasets.filter((dataset) => { const datasetDacId = dataset.dacId; const daa = daas.find((daa) => daa.dacs?.some((d) => d.dacId === datasetDacId)); - // console.log('daa',daa); if (libraryCard.daaIds.includes(daa?.daaId)) { return dataset; } }); - // console.log('filteredDatasets', filteredDatasets); setDatasets(filteredDatasets); }; From 3aa5c112e4f999aff3eed4e8e32276c1f6a482d8 Mon Sep 17 00:00:00 2001 From: rushtong Date: Mon, 29 Jul 2024 12:18:56 -0400 Subject: [PATCH 7/8] feat: minor refactoring; handle no datasets allowed condition --- .../data_search/DatasetSearchTable.jsx | 4 +- .../DatasetSelectionModal.jsx} | 47 ++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) rename src/components/{modals/DatasetModal.jsx => data_search/DatasetSelectionModal.jsx} (65%) diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index c63f94acb..900dc8000 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -15,7 +15,7 @@ import { Notifications } from '../../libs/utils'; import { Styles } from '../../libs/theme'; import isEqual from 'lodash/isEqual'; import TranslatedDulModal from '../modals/TranslatedDulModal'; -import DatasetModal from '../modals/DatasetModal'; +import DatasetSelectionModal from './DatasetSelectionModal'; import { DAAUtils } from '../../utils/DAAUtils'; const studyTableHeader = [ @@ -469,7 +469,7 @@ export const DatasetSearchTable = (props) => { } { showDatasetModal && - setShowDatasetModal(false)} diff --git a/src/components/modals/DatasetModal.jsx b/src/components/data_search/DatasetSelectionModal.jsx similarity index 65% rename from src/components/modals/DatasetModal.jsx rename to src/components/data_search/DatasetSelectionModal.jsx index 595f6154e..fd7fb8ad6 100644 --- a/src/components/modals/DatasetModal.jsx +++ b/src/components/data_search/DatasetSelectionModal.jsx @@ -17,24 +17,25 @@ function FormattedDatasets({ datasets }) { return (
      - {datasets.map((dataset) => ( -
    • + {datasets.map((dataset) => { + const displayName = dataset.datasetName.length > 50 + ? `${dataset.datasetName.substring(0, 50)}...` + : dataset.datasetName; + return
    • {dataset.datasetIdentifier} - - {dataset.datasetName.length > 50 - ? `${dataset.datasetName.substring(0, 50)}...` - : dataset.datasetName} - -
    • - ))} + {displayName} + ; + })}
    ); } -export default function DatasetModal(props) { +export default function DatasetSelectionModal(props) { const { showModal, onCloseRequest, onApply, datasetIds } = props; + const [allDatasets, setAllDatasets] = useState([]); const [datasets, setDatasets] = useState([]); const closeHandler = () => { @@ -60,6 +61,7 @@ export default function DatasetModal(props) { const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); const fetchedDatasets = await fetchAllDatasets(allDatasets); + setAllDatasets(fetchedDatasets); const daas = await DAA.getDaas(); const filteredDatasets = fetchedDatasets.filter((dataset) => { @@ -69,7 +71,6 @@ export default function DatasetModal(props) { return dataset; } }); - setDatasets(filteredDatasets); }; @@ -95,14 +96,24 @@ export default function DatasetModal(props) { Datasets available for Data Access Request -
    -
    Based on your credentials you can fill out a Data Access Request form for these dataset(s):
    - -
    + {(datasets.length > 0) ? +
    +
    Based on your credentials + you can fill out a Data Access Request form for these dataset(s): +
    + +
    + : +
    +
    The requested datasets require that your Signing Official issues you a Library Card before proceeding.
    + +
    + }
    - - - + + + {(datasets.length > 0) && + } ); From 26fb0073ed970dc55c4ea62a45b17ed2b925ac63 Mon Sep 17 00:00:00 2001 From: rushtong Date: Mon, 5 Aug 2024 11:45:50 -0400 Subject: [PATCH 8/8] feat: refactor apply button to its own logical component --- src/components/data_search/ApplyForAccess.jsx | 102 ++++++++++++++++++ .../data_search/DatasetSearchTable.jsx | 32 ++---- .../data_search/DatasetSelectionModal.jsx | 84 ++++++--------- 3 files changed, 142 insertions(+), 76 deletions(-) create mode 100644 src/components/data_search/ApplyForAccess.jsx diff --git a/src/components/data_search/ApplyForAccess.jsx b/src/components/data_search/ApplyForAccess.jsx new file mode 100644 index 000000000..bb90151c5 --- /dev/null +++ b/src/components/data_search/ApplyForAccess.jsx @@ -0,0 +1,102 @@ +import React, {useEffect, useState} from 'react'; +import {Button} from '@mui/material'; +import {DAA} from '../../libs/ajax/DAA'; +import {DAAUtils} from '../../utils/DAAUtils'; +import {DAR} from '../../libs/ajax/DAR'; +import {Storage} from '../../libs/storage'; +import DatasetSelectionModal from './DatasetSelectionModal'; + + +export default function ApplyForAccess(props) { + + const { datasets, selectedDatasetKeys, history } = props; + const [showDatasetModal, setShowDatasetModal] = useState(false); + const [allowableTermSelections, setAllowableTermSelections] = useState([]); + const [openTermSelections, setOpenTermSelections] = useState([]); + const [externalTermSelections, setExternalTermSelections] = useState([]); + const [unselectableTermSelections, setUnselectableTermSelections] = useState([]); + + useEffect(() => { + const init = async () => { + // Logical cases: + // 1. If the user has access to all datasets - go straight to apply + // 2. If the user has access to some datasets show the partially selected datasets modal + // 3. If the user requests access to Open or External Access datasets, show the partially selected datasets modal + // 4. If the user has no access to any datasets, show custom message in modal + const allDAAs = await DAA.getDaas(); + const selectedDatasetIds = selectedDatasetKeys.map((id) => parseInt(id.replace('dataset-', ''))); + const selectedTerms = datasets.filter(d => selectedDatasetIds.includes(d.datasetId)); + const user = Storage.getCurrentUser(); + const userLibraryCardDAAIds = user.libraryCards.flatMap(lc => lc.daaIds); + const userDAAs = allDAAs.filter(daa => userLibraryCardDAAIds.includes(daa.daaId)); + + // Ensure that the dataset's DAC is one of the DACs that match any of the DACs in the user's list of DAAs + let allowable = []; + let open = []; + let external = []; + let unAllowable = []; + selectedTerms.forEach(term => { + if (term.accessManagement === 'open') { + open.push(term); + } else if (term.accessManagement === 'external') { + external.push(term); + } else { + const selectedTermDacId = term.dac?.dacId; + const matchingDatasetDAA = userDAAs.filter(daa => { + const daaDacIds = daa.dacs?.map(dac => dac.dacId); + return daaDacIds?.includes(selectedTermDacId); + }); + if (matchingDatasetDAA.length > 0) { + allowable.push(term); + } else { + unAllowable.push(term); + } + } + }); + setAllowableTermSelections(allowable); + setOpenTermSelections(open); + setExternalTermSelections(external); + setUnselectableTermSelections(unAllowable); + }; + init(); + }, [datasets, selectedDatasetKeys]); + + const preCheckApply = async () => { + const selectedDatasetIds = selectedDatasetKeys.map((id) => parseInt(id.replace('dataset-', ''))); + const selectedTerms = datasets.filter(d => selectedDatasetIds.includes(d.datasetId)); + if (allowableTermSelections.length === selectedTerms.length) { + // Go straight to Apply for Access: + await applyForAccess(); + } else { + // Some combination of partially allowed, open, external, or no available terms are selected + setShowDatasetModal(true); + } + }; + + const applyForAccess = async () => { + const draftDatasetIds = allowableTermSelections.map((d) => d.datasetId); + const darDraft = await DAR.postDarDraft({ datasetId: draftDatasetIds }); + history.push(`/dar_application/${darDraft.referenceId}`); + }; + + return ( + <> + + { + showDatasetModal && + setShowDatasetModal(false)} + onApply={applyForAccess} + datasets={datasets} + allowableTermSelections={allowableTermSelections} + openTermSelections={openTermSelections} + externalTermSelections={externalTermSelections} + unselectableTermSelections={unselectableTermSelections} + /> + } + + ); +} \ No newline at end of file diff --git a/src/components/data_search/DatasetSearchTable.jsx b/src/components/data_search/DatasetSearchTable.jsx index 137c6723b..81f23394c 100644 --- a/src/components/data_search/DatasetSearchTable.jsx +++ b/src/components/data_search/DatasetSearchTable.jsx @@ -7,7 +7,6 @@ import CollapsibleTable from '../CollapsibleTable'; import TableHeaderSection from '../TableHeaderSection'; import DatasetExportButton from './DatasetExportButton'; import { DataSet } from '../../libs/ajax/DataSet'; -import { DAR } from '../../libs/ajax/DAR'; import eventList from '../../libs/events'; import { Config } from '../../libs/config'; import DatasetFilterList from './DatasetFilterList'; @@ -17,8 +16,7 @@ import { Styles } from '../../libs/theme'; import { TerraDataRepo } from '../../libs/ajax/TerraDataRepo'; import isEqual from 'lodash/isEqual'; import TranslatedDulModal from '../modals/TranslatedDulModal'; -import DatasetSelectionModal from './DatasetSelectionModal'; -import { DAAUtils } from '../../utils/DAAUtils'; +import ApplyForAccess from './ApplyForAccess'; const studyTableHeader = [ 'Study Name', @@ -52,7 +50,6 @@ export const DatasetSearchTable = (props) => { const [tdrApiUrl, setTdrApiUrl] = useState(''); const [showTranslatedDULModal, setShowTranslatedDULModal] = useState(false); const [dataUse, setDataUse] = useState(); - const [showDatasetModal, setShowDatasetModal] = useState(false); const searchRef = useRef(''); const isFiltered = (filter) => filters.indexOf(filter) > -1; @@ -232,16 +229,6 @@ export const DatasetSearchTable = (props) => { setExportableDatasets({}); }; - const filterApprovedDatasets = async () => { - setShowDatasetModal(true); - }; - - const applyForAccess = async (datasets) => { - const draftDatasets = datasets.map((id) => parseInt(id.replace('dataset-', ''))); - const darDraft = await DAR.postDarDraft({ datasetId: draftDatasets }); - history.push(`/dar_application/${darDraft.referenceId}`); - }; - const clearSearchRef = () => { searchRef.current.value = ''; filterHandler(null, datasets, '', ''); @@ -463,9 +450,11 @@ export const DatasetSearchTable = (props) => { { !isEmpty(datasets) && - + + } @@ -477,15 +466,6 @@ export const DatasetSearchTable = (props) => { onCloseRequest={()=>setShowTranslatedDULModal(false)} /> } - { - showDatasetModal && - setShowDatasetModal(false)} - onApply={applyForAccess} - /> - } ); }; diff --git a/src/components/data_search/DatasetSelectionModal.jsx b/src/components/data_search/DatasetSelectionModal.jsx index fd7fb8ad6..842aed49c 100644 --- a/src/components/data_search/DatasetSelectionModal.jsx +++ b/src/components/data_search/DatasetSelectionModal.jsx @@ -1,11 +1,7 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material'; -import { isEmpty, isNil } from 'lodash/fp'; -import { DataSet } from '../../libs/ajax/DataSet'; -import { DAA } from '../../libs/ajax/DAA'; -import { Storage } from '../../libs/storage'; const listStyle = { listStyle: 'none', @@ -33,50 +29,19 @@ function FormattedDatasets({ datasets }) { } export default function DatasetSelectionModal(props) { - const { showModal, onCloseRequest, onApply, datasetIds } = props; + const { showModal, onCloseRequest, onApply, allowableTermSelections, openTermSelections, externalTermSelections, unselectableTermSelections } = props; - const [allDatasets, setAllDatasets] = useState([]); - const [datasets, setDatasets] = useState([]); + useEffect(() => { + // console.log('allowableTermSelections:', allowableTermSelections); + // console.log('openTermSelections:', openTermSelections); + // console.log('externalTermSelections:', externalTermSelections); + // console.log('unselectableTermSelections:', unselectableTermSelections); + }, [allowableTermSelections, openTermSelections, unselectableTermSelections]); const closeHandler = () => { onCloseRequest(); }; - const applyHandler = (filteredDatasets) => { - const datasetStrings = filteredDatasets.map(dataset => `dataset-${dataset.dataSetId}`); - onApply(datasetStrings); - }; - - const fetchAllDatasets = async (datasetIds) => { - const filteredDatasetIds = datasetIds.filter((id) => !isNil(id) && Number.isInteger(id) && id > 0); - if (isEmpty(filteredDatasetIds)) { - return []; - } - return DataSet.getDatasetsByIds(filteredDatasetIds); - }; - - useEffect(() => { - const getData = async () => { - const user = Storage.getCurrentUser(); - const libraryCard = !isEmpty(user.libraryCards) ? user.libraryCards[0] : {}; - const allDatasets = datasetIds.map((id) => parseInt(id.replace('dataset-', ''))); - const fetchedDatasets = await fetchAllDatasets(allDatasets); - setAllDatasets(fetchedDatasets); - const daas = await DAA.getDaas(); - - const filteredDatasets = fetchedDatasets.filter((dataset) => { - const datasetDacId = dataset.dacId; - const daa = daas.find((daa) => daa.dacs?.some((d) => d.dacId === datasetDacId)); - if (libraryCard.daaIds.includes(daa?.daaId)) { - return dataset; - } - }); - setDatasets(filteredDatasets); - }; - - getData(); - }, [datasetIds]); - return ( Datasets available for Data Access Request - {(datasets.length > 0) ? + {(allowableTermSelections.length > 0) &&
    Based on your credentials you can fill out a Data Access Request form for these dataset(s):
    - +
    - : + } + {(unselectableTermSelections.length > 0) && +
    +
    The requested datasets + require that your Signing Official issues you a Library Card before proceeding. +
    + +
    + } + {(openTermSelections.length > 0) &&
    -
    The requested datasets require that your Signing Official issues you a Library Card before proceeding.
    - +
    The following datasets + are Open Access and do not require a Data Access Request. +
    + +
    + } + {(externalTermSelections.length > 0) && +
    +
    The following datasets + are External Access and do not require a Data Access Request. +
    +
    }
    - {(datasets.length > 0) && - } + {(allowableTermSelections.length > 0) && + }
    );