Skip to content

Commit

Permalink
HP-1261 Feat/disco single file download (#1492)
Browse files Browse the repository at this point in the history
* feat(downloadVariableMetadataButton): initial commit

* feat(downloadVariableMetadataButton): Got zip DL to work

* feat(downloadVariableMetadataButton): Made DownloadAllModal a reusable DownloadModal, sorted out promise.all logic

* feat(downloadVariableMetadataButton): Cleaned up lint issues, added interface for dataDictionaries

* feat(downloadVariableMetadataButton): fixed failing unit test for DownloadModal

* feat(downloadVariableMetadataButton): Got unit test to work

* feat(downloadVariableMetadataButton): Improved unit tesT

* feat(downloadVariableMetadataButton): Removed commented code from unit test and update var ref

* feat(downloadVariableMetadataButton): Moved constant to constants file

* feat(downloadVariableMetadataButton): Ran linter

* feat(downloadVariableMetadataButton): Removed commented test code

* feat(downloadVariableMetadataButton): updated logic for rendering download variable metadata button, ran linter

* feat(downloadVariableMetadataButton): added function createUniqueDownloadErrorMsg

* feat(downloadVariableMetadataButton): formatted code for readability in DiscoveryConfig.d.ts and DiscoveryDetails.tsx

* feat(downloadVariableMetadataButton): updated unit test for downloadVariableMetadata

* feat(downloadVariableMetadataButton): Updated test to pass

* feat(downloadVariableMetadataButton): Ran linter

* feat(downloadVariableMetadataButton): Updated download failed msg respose

* feat(downloadVariableMetadataButton): Change em to strong in messages for readability

* feat(downloadVariableMetadataButton): Removed excessive spacing in DownloadVariableMetadata.test.tsx

* feat(downloadVariableMetadataButton): Added space for code readability in DownloadVariableMetadata.test.tsx

* feat(downloadVariableMetadataButton): Updated to use one modal and disable buttons during downloading

* feat(downloadVariableMetadataButton): Added support for loading state for DownloadAllFiles button and DownloadVariableMetadata button

* feat(downloadVariableMetadataButton): Made data type for inProgress always a string to improve consistency

* feat(downloadVariableMetadataButton): removed unneeded console statement

* feat(downloadVariableMetadataButton): Added inline solution for checking noVariableLevelMetadata

* feat(downloadVariableMetadataButton): Wrote initial unit test for DownloadDataDictionaryInfo

* feat(downloadVariableMetadatabutton): Got second test to pass

* feat(downloadVariableMetadataButton): Wrote additional unit tests for DownloadDataDictionaryInfo

* feat(downloadVariableMetadataButton): Cleaned up unit test, ran linter

* feat(downloadVariableMetadataButton): Updated unit tests based on refacotring of DataDownloadList and DownloadVariableMetadata

* feat(downloadVariableMetadataButton): Replaced test data with constant to improve maintainability, ran linter

* feat(downloadVariableMetadataButton): Renamed variable showList with resourceFieldValueIsValid to increase clarity, updated unit tests and ran linter

* feat(downloadVariableMetadataButton): Updated initial declaration of value for Data Dictionary to an empty object casted to a Data Dictionary type to improve code clarity, removed unneeded console log statement

* feat(downloadVariableMetadataButton):removed unneeded console log statement

* feat(downloadVariableMetadataButton):removed unintentionally changed file

* feat(downloadVariableMetadataButton): Added additional data type checks to CheckHealLoginNeeded to avoid error introduced by function being called with an array containing an empty object

* feat individual download button

* update redirection, style and popover update

* fix tests

* fix test

* update css

* add comment

* fix grid gutter

* use button title from config

* fix test

* rename variable

* renaming variables and functions

* fix

* reorg code and add tests

* fix redirect to disco detail with slash

* disable button base on user access

* update test

* fix typo

* address review comments

---------

Co-authored-by: Jarvis Raymond <[email protected]>
Co-authored-by: Jarvis <[email protected]>
  • Loading branch information
3 people authored Feb 29, 2024
1 parent db53b47 commit f749b9c
Show file tree
Hide file tree
Showing 24 changed files with 578 additions and 168 deletions.
4 changes: 4 additions & 0 deletions src/Discovery/Discovery.css
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@
max-width: 500px;
}

.discovery-detail-popover {
max-width: 250px;
}

.discovery-popover__text {
color: var(--g3-color__titanium);
font-size: 0.625rem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,53 @@
import React, { useEffect, useState } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import {
Col, Row, Button, Popover,
} from 'antd';
import { useHistory, useLocation } from 'react-router-dom';
import { DiscoveryConfig } from '../../../DiscoveryConfig';
import { DiscoveryResource } from '../../../Discovery';
import { INITIAL_DOWNLOAD_STATUS } from './DownloadUtils/Constants';
import UseHandleRedirectToLoginClick from './DownloadUtils/UseHandleRedirectToLoginClick';
import HandleDownloadManifestClick from './DownloadUtils/HandleDownloadManifestClick';
import DownloadModal from './DownloadModal/DownloadModal';
import DownloadAllFiles from './DownloadUtils/DownloadAllFiles/DownloadAllFiles';
import DownloadDataFiles from './DownloadUtils/DownloadDataFiles/DownloadDataFiles';
import DownloadJsonFile from './DownloadUtils/DownloadJsonFile';
import DownloadVariableMetadata from './DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata';
import './ActionButtons.css';
import DownloadDataDictionaryInfo from './DownloadUtils/DownloadDataDictionaryInfo';
import DataDictionaries from '../Interfaces/DataDictionaries';
import DownloadStatus from '../Interfaces/DownloadStatus';

interface ActionButtonsProps {
isUserLoggedIn: boolean;
userHasAccessToDownload: boolean;
discoveryConfig: DiscoveryConfig;
resourceInfo: DiscoveryResource;
healLoginNeeded: boolean;
missingRequiredIdentityProviders: string[];
noData: boolean;
downloadStatus: DownloadStatus;
setDownloadStatus: React.Dispatch<React.SetStateAction<DownloadStatus>>;
history: RouteComponentProps['history'],
location: RouteComponentProps['location'],
}

const ActionButtons = ({
isUserLoggedIn,
userHasAccessToDownload,
discoveryConfig,
resourceInfo,
healLoginNeeded,
missingRequiredIdentityProviders,
noData,
downloadStatus,
setDownloadStatus,
history,
location,
}: ActionButtonsProps): JSX.Element => {
const [downloadStatus, setDownloadStatus] = useState(INITIAL_DOWNLOAD_STATUS);
const { HandleRedirectToLoginClick } = UseHandleRedirectToLoginClick();
const history = useHistory();
const location = useLocation();
const { HandleRedirectFromDiscoveryDetailsToLoginClick } = UseHandleRedirectToLoginClick();

const studyMetadataFieldNameReference: string | undefined = discoveryConfig?.features.exportToWorkspace.studyMetadataFieldName;
const manifestFieldName: string | undefined = discoveryConfig?.features.exportToWorkspace.manifestFieldName;
const manifestFieldName: string = discoveryConfig?.features.exportToWorkspace.manifestFieldName || '';
let fileManifest: any[] = [];
if (manifestFieldName) {
fileManifest = resourceInfo?.[manifestFieldName] || [];
}
const showDownloadStudyLevelMetadataButton = Boolean(
discoveryConfig?.features.exportToWorkspace.enableDownloadStudyMetadata
&& studyMetadataFieldNameReference
Expand All @@ -52,16 +62,21 @@ const ActionButtons = ({
const verifyExternalLoginsNeeded = Boolean(
discoveryConfig?.features.exportToWorkspace.verifyExternalLogins,
);

const showDownloadVariableMetadataButton = Boolean(
discoveryConfig.features.exportToWorkspace.variableMetadataFieldName
&& discoveryConfig.features.exportToWorkspace.enableDownloadVariableMetadata,
);

const [dataDictionaryInfo, setDataDictionaryInfo] = useState({
noVariableLevelMetadata: true,
dataDictionaries: {} as DataDictionaries,
});

let uid = '';
if (resourceInfo) {
uid = resourceInfo[discoveryConfig.minimalFieldMapping.uid] || '';
}

useEffect(() => {
DownloadDataDictionaryInfo(
discoveryConfig,
Expand All @@ -71,23 +86,53 @@ const ActionButtons = ({
);
}, [resourceInfo]);

const ConditionalPopover = ({ children }) => (noData ? (
<Popover title={'This file is not available for the selected study'}>
{children}
</Popover>
) : (
children
));
const ConditionalPopover = ({ children }) => {
if (noData) {
return (
<Popover content={'This file is not available for the selected study'}>
{children}
</Popover>
);
}
if (!userHasAccessToDownload) {
return (
<Popover content={'You don\'t have access to this data'}>
{children}
</Popover>
);
}
if (missingRequiredIdentityProviders.length) {
const onlyInCommonMsg = missingRequiredIdentityProviders.length > 1 ? `Data selection requires [${missingRequiredIdentityProviders.join(', ')}] credentials to access. Please change selection to only need one set of credentials and log in using appropriate credentials`
: `This dataset is only accessible to users who have authenticated via ${missingRequiredIdentityProviders}. Please log in using the ${missingRequiredIdentityProviders} option.`;
return (
<Popover
className='discovery-detail-popover'
arrowPointAtCenter
overlayInnerStyle={{ maxWidth: '300px' }}
content={(
<React.Fragment>
{onlyInCommonMsg}
</React.Fragment>
)}
>
{children}
</Popover>
);
}
return children;
};

const isHEALLoginNeeded = Boolean(missingRequiredIdentityProviders.length);
const downloadManifestButtonText = discoveryConfig.features?.exportToWorkspace?.downloadManifestButtonText || 'Download Manifest';
return (
<div className='discovery-modal_buttons-row' data-testid='actionButtons'>
<DownloadModal
downloadStatus={downloadStatus}
setDownloadStatus={setDownloadStatus}
/>
<Row className='row'>
<Row
className='row'
justify='space-between'
gutter={[8, 8]}
>
{showDownloadVariableMetadataButton && (
<Col flex='1 0 auto'>
<Col>
<Button
className='discovery-action-bar-button'
disabled={Boolean(
Expand All @@ -109,7 +154,7 @@ const ActionButtons = ({
</Col>
)}
{showDownloadStudyLevelMetadataButton && (
<Col flex='1 0 auto'>
<Col>
<ConditionalPopover>
<Button
className='discovery-action-bar-button'
Expand All @@ -127,80 +172,75 @@ const ActionButtons = ({
</Col>
)}
{showDownloadFileManifestButtons && (
<Col flex='1 0 auto'>
{isUserLoggedIn && !healLoginNeeded && (
<Col>
{isUserLoggedIn && !isHEALLoginNeeded && (
<ConditionalPopover>
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
disabled={Boolean(noData || downloadStatus.inProgress || !userHasAccessToDownload)}
onClick={() => {
HandleDownloadManifestClick(
discoveryConfig,
[resourceInfo],
healLoginNeeded,
missingRequiredIdentityProviders,
);
}}
>
Download File Manifest
{downloadManifestButtonText}
</Button>
</ConditionalPopover>
)}
{(!isUserLoggedIn || healLoginNeeded) && (
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
onClick={() => {
HandleRedirectToLoginClick(
resourceInfo,
discoveryConfig,
'manifest',
);
}}
>
{(!isUserLoggedIn || isHEALLoginNeeded) && (
<ConditionalPopover>
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
onClick={() => {
HandleRedirectFromDiscoveryDetailsToLoginClick(uid);
}}
>
Login to
<br /> Download Manifest
</Button>
<br /> {downloadManifestButtonText}
</Button>
</ConditionalPopover>
)}
</Col>
)}
{showDownloadAllFilesButtons && (
<Col flex='1 0 auto'>
{isUserLoggedIn && !healLoginNeeded && (
<Col>
{isUserLoggedIn && !isHEALLoginNeeded && (
<ConditionalPopover>
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
loading={downloadStatus.inProgress === 'DownloadAllFiles'}
onClick={() => DownloadAllFiles(
resourceInfo,
disabled={Boolean(noData || downloadStatus.inProgress || !userHasAccessToDownload)}
loading={downloadStatus.inProgress === 'DownloadDataFiles'}
onClick={() => DownloadDataFiles(
downloadStatus,
setDownloadStatus,
history,
location,
healLoginNeeded,
missingRequiredIdentityProviders,
verifyExternalLoginsNeeded,
manifestFieldName,
fileManifest,
)}
>
Download All Files
</Button>
</ConditionalPopover>
)}
{(!isUserLoggedIn || healLoginNeeded) && (
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
onClick={() => {
HandleRedirectToLoginClick(
resourceInfo,
discoveryConfig,
'download',
);
}}
>
{(!isUserLoggedIn || isHEALLoginNeeded) && (
<ConditionalPopover>
<Button
className='discovery-action-bar-button'
disabled={Boolean(noData || downloadStatus.inProgress)}
onClick={() => {
HandleRedirectFromDiscoveryDetailsToLoginClick(uid);
}}
>
Login to
<br /> Download All Files
</Button>
<br /> Download All Files
</Button>
</ConditionalPopover>
)}
</Col>
)}
Expand Down
Loading

0 comments on commit f749b9c

Please sign in to comment.