diff --git a/src/components/SimpleTable.jsx b/src/components/SimpleTable.jsx index 0e36547b2..800e33642 100644 --- a/src/components/SimpleTable.jsx +++ b/src/components/SimpleTable.jsx @@ -45,32 +45,44 @@ const ColumnRow = ({columnHeaders, baseStyle, columnStyle, sort, onSort}) => { return (
{columnHeaders.map((header, colIndex) => { - const { cellStyle, label } = header; + const { cellStyle, label, data } = header; //style here pertains to styling for individual cells //should be used to set dimensions of specific columns return (
- {header.sortable && onSort ? ( -
{ - onSort({ - colIndex: colIndex, - dir: sort.colIndex === colIndex ? sort.dir * -1 : 1 - }); - }} - > - {label} -
- - -
-
- ) : ( - label - )} + {(() => { + if (header.sortable && onSort) { + return (
{ + onSort({ + colIndex: colIndex, + dir: sort.colIndex === colIndex ? sort.dir * -1 : 1 + }); + }} + > + {label} +
+ + +
+
); + } else if (header.data) { + return (
  • +
    +
    + {label} + +
    +
    + {data} +
  • ); + } else { + return (label); + } + })()}
    ); })} @@ -83,7 +95,7 @@ const DataRows = ({rowData, baseStyle, columnHeaders, rowWrapper = ({renderedRow return rowData.map((row, index) => { const id = rowData[index][0].id; const mapKey = id || `noId-index-${index}`; - if (rowData[index][0].label === "display-names") { + if (rowData[index][0].striped) { baseStyle.backgroundColor = index % 2 === 0 ? 'white' : '#e2e8f4'; } const renderedRow = ( diff --git a/src/libs/ajax/DAA.js b/src/libs/ajax/DAA.js index e212bd33f..a529342f6 100644 --- a/src/libs/ajax/DAA.js +++ b/src/libs/ajax/DAA.js @@ -1,6 +1,5 @@ -import * as fp from 'lodash/fp'; import fileDownload from 'js-file-download'; -import { getApiUrl, fetchOk } from '../ajax'; +import { getApiUrl } from '../ajax'; import { Config } from '../config'; import axios from 'axios'; @@ -38,7 +37,7 @@ export const DAA = { bulkRemoveUsersFromDaa: async (daaId, userList) => { const url = `${await getApiUrl()}/api/daa/bulk/${daaId}`; - const res = await axios.delete(url, userList, Config.authOpts()); + const res = await axios.delete(url, { ...Config.authOpts(), data: userList }); return res.data; }, @@ -52,7 +51,7 @@ export const DAA = { const url = `${await getApiUrl()}/api/daa/bulk/user/${userId}`; const res = await axios.delete(url, { ...Config.authOpts(), data: daaList }); return res.data; - }, + }, getDaaFileById: async (daaId, daaFileName) => { const authOpts = Object.assign(Config.authOpts(), { responseType: 'blob' }); diff --git a/src/pages/signing_official_console/DAACell.jsx b/src/pages/signing_official_console/DAACell.jsx new file mode 100644 index 000000000..3d162f5d7 --- /dev/null +++ b/src/pages/signing_official_console/DAACell.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Checkbox } from '@mui/material'; +import { DAA } from '../../libs/ajax/DAA'; +import { Notifications } from '../../libs/utils'; + +export default function DAACell(props) { + const {rowDac, researcher, institutionId, daas, refreshResearchers, setResearchers} = props; + const id = researcher?.userId || researcher?.email; + const libraryCards = researcher?.libraryCards; + const card = libraryCards?.find(card => card.institutionId === institutionId); + const daaIds = researcher && card?.daaIds; + const filteredDaas = daaIds && daas?.filter(daa => daaIds.includes(daa.daaId)); + const hasDacId = filteredDaas && filteredDaas.some(daa => daa.dacs.some(dac => dac.dacId === rowDac.dacId)); + + const createDaaLcLink = async (daaId, researcher, dacName) => { + try { + await DAA.createDaaLcLink(daaId, researcher.userId); + Notifications.showSuccess({text: `Approved access to ${dacName} to user: ${researcher.displayName}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error approving access to ${dacName} to user: ${researcher.displayName}`}); + } + }; + + const deleteDaaLcLink = async (daaId, researcher, dacName) => { + try { + await DAA.deleteDaaLcLink(daaId, researcher.userId); + Notifications.showSuccess({text: `Removed approval of access to ${dacName} to user: ${researcher.displayName}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error removing approval of access to ${dacName} to user: ${researcher.displayName}`}); + } + }; + + const handleClick = async (daas, specificDac, researcher) => { + const daaId = daas.find(daa => daa.dacs.some(dac => dac.dacId === specificDac.dacId))?.daaId; + if (!hasDacId) { + createDaaLcLink(daaId, researcher, specificDac.name); + } else { + deleteDaaLcLink(daaId, researcher, specificDac.name); + } + }; + + return { + isComponent: true, + id, + label: 'lc-button', + data: ( +
    + handleClick(daas, rowDac, researcher)}/> +
    + ), + }; +} \ No newline at end of file diff --git a/src/pages/signing_official_console/ManageDaasDropdown.jsx b/src/pages/signing_official_console/ManageDaasDropdown.jsx new file mode 100644 index 000000000..83f27c099 --- /dev/null +++ b/src/pages/signing_official_console/ManageDaasDropdown.jsx @@ -0,0 +1,87 @@ +import React, { useState } from 'react'; +import { Button } from '@mui/material'; +import { DownloadLink } from '../../components/DownloadLink'; +import { DAA } from '../../libs/ajax/DAA'; +import { Notifications } from '../../libs/utils'; + +export default function ManageDaasDropdown(props) { + const [applyAll, setApplyAll] = useState(null); + const {actionsTitle, download, moreData, researchers, refreshResearchers, setResearchers} = props; + + const handleApplyAllChange = (event) => { + setApplyAll(event.target.checked); + }; + + const handleRemoveAllChange = (event) => { + setApplyAll(!event.target.checked); + }; + + const addUsersToDaa = async (userList) => { + try { + await DAA.bulkAddUsersToDaa(moreData.id, userList); + Notifications.showSuccess({text: `Approved all users access to request from: ${moreData.name}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error approving all users access to request from: ${moreData.name}`}); + } + }; + + const removeUsersFromDaa = async (userList) => { + try { + await DAA.bulkRemoveUsersFromDaa(moreData.id, userList); + Notifications.showSuccess({text: `Removed all users' approval to request from: ${moreData.name}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error removing all users' approval to request from: ${moreData.name}`}); + } + }; + + const handleApplyAll = async () => { + const userList = { 'users': researchers.map(researcher => researcher.userId) }; + if (applyAll) { + addUsersToDaa(userList); + } else { + removeUsersFromDaa(userList); + } + }; + + return ( + + ); +} diff --git a/src/pages/signing_official_console/ManageResearcherDAAsTable.jsx b/src/pages/signing_official_console/ManageResearcherDAAsTable.jsx index 19638fcb9..6d2af0f57 100644 --- a/src/pages/signing_official_console/ManageResearcherDAAsTable.jsx +++ b/src/pages/signing_official_console/ManageResearcherDAAsTable.jsx @@ -1,6 +1,5 @@ import React from 'react'; import { useState, useEffect, useCallback, useRef } from 'react'; -import { Checkbox } from '@mui/material'; import { Styles } from '../../libs/theme'; import { isEmpty } from 'lodash/fp'; import SimpleTable from '../../components/SimpleTable'; @@ -12,9 +11,11 @@ import { getSearchFilterFunctions, searchOnFilteredList } from '../../libs/utils'; -import { DAA } from '../../libs/ajax/DAA'; import {User} from '../../libs/ajax/User'; import { USER_ROLES } from '../../libs/utils'; +import ManageUsersDropdown from './ManageUsersDropdown'; +import ManageDaasDropdown from './ManageDaasDropdown'; +import DAACell from './DAACell'; //Styles specific to this table const styles = { @@ -50,28 +51,6 @@ let columnHeaderFormat = { const researcherFilterFunction = getSearchFilterFunctions().signingOfficialResearchers; -const handleClick = async (researcher, specificDac, filteredDaas, checked, refreshResearchers, setResearchers) => { - if (!checked) { - try { - const daaId = filteredDaas.find(daa => daa.dacs.some(dac => dac.dacId === specificDac.dacId))?.daaId; - await DAA.createDaaLcLink(daaId, researcher.userId); - Notifications.showSuccess({text: `Approved access to ${specificDac.name} to user: ${researcher.displayName}`}); - refreshResearchers(setResearchers); - } catch(error) { - Notifications.showError({text: `Error approving access to ${specificDac.name} to user: ${researcher.displayName}`}); - } - } else { - try { - const daaId = filteredDaas.find(daa => daa.dacs.some(dac => dac.dacId === specificDac.dacId))?.daaId; - await DAA.deleteDaaLcLink(daaId, researcher.userId); - Notifications.showSuccess({text: `Removed approval of access to ${specificDac.name} to user: ${researcher.displayName}`}); - refreshResearchers(setResearchers); - } catch(error) { - Notifications.showError({text: `Error removing approval of access to ${specificDac.name} to user: ${researcher.displayName}`}); - } - } -}; - const refreshResearchers = async (setResearchers) => { const researcherList = await User.list(USER_ROLES.signingOfficial); // the construction of this list is currently a work-around because our endpoint in the backend @@ -84,46 +63,26 @@ const refreshResearchers = async (setResearchers) => { setResearchers(researcherObjectList); }; -const DAACell = ( - rowDac, - researcher, - institutionId, - daas, - refreshResearchers, - setResearchers -) => { - const id = researcher && (researcher.userId || researcher.email); - const libraryCards = researcher && researcher.libraryCards; - const card = libraryCards && libraryCards.find(card => card.institutionId === institutionId); - const daaIds = researcher && card && card.daaIds; - const filteredDaas = daaIds && daas.filter(daa => daaIds.includes(daa.daaId)); - const hasDacId = filteredDaas && filteredDaas.some(daa => daa.dacs.some(dac => dac.dacId === rowDac.dacId)); - - return { - isComponent: true, - id, - label: 'lc-button', - data: ( -
    - handleClick(researcher,rowDac, daas, hasDacId, refreshResearchers, setResearchers)}/> -
    - ), - }; -}; - - - -const displayNameCell = (displayName, email, id) => { +const displayNameCell = (displayName, email, id, daas, setResearchers) => { return { data: ( <> -
    {displayName || 'Invite sent, pending registration'}
    -
    {email || '- -'}
    +
  • +
    +
    + {displayName || 'Invite sent, pending registration'} + + {email || '- -'} +
    +
    + +
  • ), id, style: {}, - label: 'display-names' + label: 'display-names', + striped: true }; }; @@ -142,7 +101,10 @@ export default function ManageResearcherDAAsTable(props) { columnHeaderFormat = { ...columnHeaderFormat, ...dacs.reduce((acc, dac) => { - acc[dac.name] = { label: dac.name, cellStyle: { width: `${dacColumnWidth}%` }}; + const daa = daas.find(daa => daa.dacs.some(d => d.dacId === dac.dacId)); + const id = daa.daaId; + const fileName = daa.file.fileName; + acc[dac.name] = { label: dac.name, cellStyle: { width: `${dacColumnWidth}%` }, data: }; return acc; }, {}), }; @@ -214,13 +176,13 @@ export default function ManageResearcherDAAsTable(props) { const processResearcherRowData = (researchers = []) => { return researchers.map(researcher => { - const {displayName, libraryCards} = researcher; + const { displayName, libraryCards } = researcher; const libraryCard = !isEmpty(libraryCards) ? libraryCards[0] : {}; const email = researcher.email || libraryCard.userEmail; const id = researcher.userId || email; return [ - displayNameCell(displayName, email, id), - ...dacs.map(dac => DAACell(dac, researcher, signingOfficial.institutionId, daas, refreshResearchers, setResearchers)) + displayNameCell(displayName, email, id, daas, setResearchers), + ...dacs.map(dac => DAACell({ rowDac: dac, researcher: researcher, institutionId: signingOfficial.institutionId, daas: daas, refreshResearchers: refreshResearchers,setResearchers: setResearchers })), ]; }); }; diff --git a/src/pages/signing_official_console/ManageUsersDropdown.jsx b/src/pages/signing_official_console/ManageUsersDropdown.jsx new file mode 100644 index 000000000..c412b524b --- /dev/null +++ b/src/pages/signing_official_console/ManageUsersDropdown.jsx @@ -0,0 +1,84 @@ +import React, { useState } from 'react'; +import { Button } from '@mui/material'; +import { DAA } from '../../libs/ajax/DAA'; +import { Notifications } from '../../libs/utils'; + +export default function ManageUsersDropdown(props) { + const [applyAll, setApplyAll] = useState(null); + const {daas, refreshResearchers, setResearchers, moreData} = props; + + const handleApplyAllChange = (event) => { + setApplyAll(event.target.checked); + }; + + const handleRemoveAllChange = (event) => { + setApplyAll(!event.target.checked); + }; + + const addDaasToUser = async (daaList) => { + try { + await DAA.bulkAddDaasToUser(moreData.id, daaList); + Notifications.showSuccess({text: `Approved access to request data from all DACs to user: ${moreData.name}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error approving access to request data from all DACs to user: ${moreData.name}`}); + } + }; + + const removeDaasFromUser = async (daaList) => { + try { + await DAA.bulkRemoveDaasFromUser(moreData.id, daaList); + Notifications.showSuccess({text: `Removed approval of access to request data from all DACs from user: ${moreData.name}`}); + refreshResearchers(setResearchers); + } catch(error) { + Notifications.showError({text: `Error removing approval of access to request data from all DACs from user: ${moreData.name}`}); + } + }; + + const handleApplyAll = async () => { + const daaList = { 'daaList': daas.map(daa => daa.daaId) }; + if (applyAll) { + addDaasToUser(daaList); + } else { + removeDaasFromUser(daaList); + } + }; + + return ( + + ); +} \ No newline at end of file