diff --git a/docs/portal_config.md b/docs/portal_config.md index 7ab0d90288..79888a0709 100644 --- a/docs/portal_config.md +++ b/docs/portal_config.md @@ -463,12 +463,19 @@ Below is an example, with inline comments describing what each JSON block config "exportToWorkspace": { // configures the export to workspace feature. If enabled, the Discovery page data must contain a field which is a list of GUIDs for each study. See `manifestFieldName` "enable": true, "enableDownloadManifest": true, // enables a button which allows user to download a manifest file for gen3 client - "downloadManifestButtonText": true, // text to be displayed on the download manifest button + "downloadManifestButtonText": "Download Manifest", // text to be displayed on the download manifest button "manifestFieldName": "__manifest", // the field in the Discovery page data that contains the list of GUIDs that link to each study's data files. + "enableDownloadZip": true, // enables a button which allows user to download all the files as a zip file (with pre-set size limits) + "downloadZipButtonText": "Download Zip", // text to be displayed on the download zip file button + "enableDownloadVariableMetadata": true, // enables a button (on discovery details page) which allows user to download variable-level metadata + "variableMetadataFieldName": "variable_level_metadata", // field name in metadata record to reference variable-level metadata + "enableDownloadStudyMetadata": true, // enables a button (on discovery details page) which allows user to download study-level metadata + "studyMetadataFieldName": "study_metadata", // field name in metadata record to reference study-level metadata "documentationLinks": { "gen3Client": "https://gen3-client", // link to documentation about the gen3 client. Used for button tooltips "gen3Workspaces": "https://gen3-workspace-docs", // link to documentation about gen3 workspaces. Used for button tooltips. - } + }, + "verifyExternalLogins": true // enables verification if the user has access to all the data files selected, by using WTS (a Gen3 ecosystem feature) }, "pageTitle": { "enabled": true, @@ -758,9 +765,10 @@ Below is an example, with inline comments describing what each JSON block config "studyRegistrationUIDField": "_hdp_uid", // optional, if omitted, value defaults the same as the "minimalFieldMapping.uid" value. In metadata, values from this field MUST be the same as their GUIDs for each metadata record "studyRegistrationFormDisclaimerField": "This is a disclaimer", //optional, the disclaimer text that appears under the submit button on the study registration request access form. Defaults to undefined "clinicalTrialFields": [], // optional, list of fields to fetch from ClinicalTrials.gov - "dataDictionaryField": "data_dictionaries", // optional, specify the field name in metadata for variable-level metadata, default to "" - "dataDictionarySubmissionBucket": "bucket-1", // optional, customize the S3 bucket that will be used for VLMD submission. Default to the data upload bucket from fence config if omitted - "dataDictionarySubmissionDisclaimerField": "some disclaimer text" // optional, the disclaimer text that appears under the submit button on the VLMD submission page. Defaults to undefined + "variableMetadataField": "variable_level_metadata", // optional, specify the field name in metadata for variable-level metadata, default to "" + "dataDictionarySubmissionBucket": "bucket-1", // optional, customize the S3 bucket that will be used for data dictionary submission. Default to the data upload bucket from fence config if omitted + "dataDictionarySubmissionDisclaimerField": "some disclaimer text", // optional, the disclaimer text that appears under the submit button on the data dictionary submission page. Defaults to undefined + "cdeSubmissionDisclaimerField": "some disclaimer text" // optional, the disclaimer text that appears under the submit button on the CDE submission page. Defaults to undefined }, "workspaceRegistrationConfig" : { // optional, config for Workspace Registration Request Access page. "workspacePolicyId": "workspace", // optional, name of the policy that is needed to provide workspace access; if missing, defaults to 'workspace' diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/ActionButtons.tsx b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/ActionButtons.tsx index 93f7225250..d76a3350c4 100644 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/ActionButtons.tsx +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/ActionButtons.tsx @@ -11,8 +11,8 @@ import DownloadDataFiles from './DownloadUtils/DownloadDataFiles/DownloadDataFil 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 DownloadVariableMetadataInfo from './DownloadUtils/DownloadVariableMetadataInfo'; +import VariableLevelMetadata from '../Interfaces/VariableLevelMetadata'; import DownloadStatus from '../Interfaces/DownloadStatus'; interface ActionButtonsProps { @@ -49,7 +49,7 @@ const ActionButtons = ({ fileManifest = resourceInfo?.[manifestFieldName] || []; } - // Study level metabutton should show only if the downloading study level metadata value is enabled + // Study level meta button should show only if the downloading study level metadata value is enabled // and resourceInfo includes the study metadata field name reference from the discovery config const showDownloadStudyLevelMetadataButton = Boolean( discoveryConfig?.features.exportToWorkspace.enableDownloadStudyMetadata @@ -70,9 +70,9 @@ const ActionButtons = ({ && discoveryConfig.features.exportToWorkspace.enableDownloadVariableMetadata, ); - const [dataDictionaryInfo, setDataDictionaryInfo] = useState({ + const [variableMetadataInfo, setVariableMetadataInfo] = useState({ noVariableLevelMetadata: true, - dataDictionaries: {} as DataDictionaries, + variableLevelMetadataRecords: {} as VariableLevelMetadata, }); let uid = ''; @@ -81,11 +81,11 @@ const ActionButtons = ({ } useEffect(() => { - DownloadDataDictionaryInfo( + DownloadVariableMetadataInfo( discoveryConfig, resourceInfo, showDownloadVariableMetadataButton, - setDataDictionaryInfo, + setVariableMetadataInfo, ); }, [resourceInfo]); @@ -141,12 +141,12 @@ const ActionButtons = ({ data-testid='download-variable-level-metadata' disabled={Boolean( downloadStatus.inProgress - || dataDictionaryInfo.noVariableLevelMetadata, + || variableMetadataInfo.noVariableLevelMetadata, )} loading={downloadStatus.inProgress === 'DownloadVariableMetadata'} onClick={() => { DownloadVariableMetadata( - dataDictionaryInfo.dataDictionaries, + variableMetadataInfo.variableLevelMetadataRecords, resourceInfo, setDownloadStatus, ); diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.ts b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.ts deleted file mode 100644 index 6ab9a25da9..0000000000 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { DiscoveryConfig } from '../../../../../../../DiscoveryConfig'; -import { DiscoveryResource } from '../../../../../../../Discovery'; -import { mdsURL } from '../../../../../../../../localconf'; -import { fetchWithCreds } from '../../../../../../../../actions'; - -const DownloadDataDictionaryInfo = ( - discoveryConfig: DiscoveryConfig, - resourceInfo: DiscoveryResource, - showDownloadVariableMetadataButton: Boolean, - setDataDictionaryInfo: Function, -) => { - const dataDictionaryReference = discoveryConfig.features.exportToWorkspace.variableMetadataFieldName; - if (showDownloadVariableMetadataButton) { - const studyID = resourceInfo._hdp_uid; - fetchWithCreds({ path: `${mdsURL}/${studyID}` }).then((statusResponse) => { - const { data } = statusResponse; - if ( - statusResponse.status === 200 - && data - && data[dataDictionaryReference as string] - && Object.keys(data[dataDictionaryReference as string]).length !== 0 - ) { - setDataDictionaryInfo({ - noVariableLevelMetadata: false, - dataDictionaries: data.data_dictionaries, - }); - } - }); - } -}; - -export default DownloadDataDictionaryInfo; diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.test.tsx b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.test.tsx index 18b1f8d6ff..c3717b3891 100644 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.test.tsx +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.test.tsx @@ -17,8 +17,8 @@ const mockResourceInfo = { project_title: 'Sample Project', }; -const mockDataDictionaries = { - 'anotherDataDictionary.json': 'string-associated-with-file-name', +const mockVariableLevelMetadata = { + dataDictionaries: { 'anotherDataDictionary.json': 'string-associated-with-file-name' }, }; const mockSetDownloadStatus = jest.fn(); @@ -41,7 +41,7 @@ describe('DownloadVariableMetadata', () => { (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { await DownloadVariableMetadata( - mockDataDictionaries, + mockVariableLevelMetadata, mockResourceInfo as unknown as DiscoveryResource, mockSetDownloadStatus, ); @@ -66,7 +66,7 @@ describe('DownloadVariableMetadata', () => { (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { await DownloadVariableMetadata( - mockDataDictionaries, + mockVariableLevelMetadata, mockResourceInfo as unknown as DiscoveryResource, mockSetDownloadStatus, ); diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.tsx b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.tsx index 4c90e55ab4..b4bdea6936 100644 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.tsx +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadata/DownloadVariableMetadata.tsx @@ -6,11 +6,16 @@ import { mdsURL } from '../../../../../../../../../localconf'; import { INITIAL_DOWNLOAD_STATUS } from '../Constants'; import DownloadStatus from '../../../Interfaces/DownloadStatus'; import { DiscoveryResource } from '../../../../../../../../Discovery'; -import DataDictionaries from '../../../Interfaces/DataDictionaries'; +import VariableLevelMetadata from '../../../Interfaces/VariableLevelMetadata'; import SanitizeFileName from './SanitizeFileName'; +enum fetchType { + CDE = 'cde', + DD = 'dd' +} + const DownloadVariableMetadata = async ( - dataDictionaries: DataDictionaries, + variableLevelMetadataRecords: VariableLevelMetadata, resourceInfo: DiscoveryResource, setDownloadStatus: Function, ) => { @@ -33,16 +38,24 @@ const DownloadVariableMetadata = async ( }, } as DownloadStatus); - const fetchData = async (key: string, value: string) => new Promise((resolve, reject) => { + const fetchData = async (key: string, value: string, type: fetchType) => new Promise((resolve, reject) => { fetchWithCreds({ path: `${mdsURL}/${value}` }).then((statusResponse) => { - const { data } = statusResponse; + let { data } = statusResponse; if (statusResponse.status !== 200 || !data) { setDownloadStatus(createUniqueDownloadErrorMsg(key)); reject(new Error(`Issue with ${key}: ${value}`)); } else { const sanitizedFileName = SanitizeFileName(key); - zip.file(sanitizedFileName, JSON.stringify(data)); - resolve(`Data resolved for ${key}: ${value}`); + let subDirectoryName = ''; + if (type === fetchType.CDE) { + subDirectoryName = 'common_data_elements/'; + data = data.cde_metadata; + } else if (type === fetchType.DD) { + subDirectoryName = 'data_dictionaries/'; + data = data.data_dictionary; + } + zip.file(`${subDirectoryName}${sanitizedFileName}`, JSON.stringify(data)); + resolve(`Data resolved for ${key}: ${value}, with type ${type}`); } }); }); @@ -54,11 +67,13 @@ const DownloadVariableMetadata = async ( inProgress: 'DownloadVariableMetadata', }); await Promise.all( - Object.entries(dataDictionaries).map(([key, value]) => fetchData(key, value), + [...Object.entries(variableLevelMetadataRecords.dataDictionaries || []).map(([key, value]) => fetchData(key, value, fetchType.DD), ), + ...Object.entries(variableLevelMetadataRecords.cdeMetadata || []).map(([key, value]) => fetchData(key, value, fetchType.CDE), + )], ).then(() => { zip.generateAsync({ type: 'blob' }).then((content) => { - FileSaver.saveAs(content, 'variable-metadata.zip'); + FileSaver.saveAs(content, 'variable-level-metadata.zip'); }); setDownloadStatus(INITIAL_DOWNLOAD_STATUS); }); diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.test.ts b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.test.ts similarity index 67% rename from src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.test.ts rename to src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.test.ts index ebb4952be7..4f6a99dcab 100644 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadDataDictionaryInfo.test.ts +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.test.ts @@ -1,17 +1,23 @@ import { act } from 'react-dom/test-utils'; -import DownloadDataDictionaryInfo from './DownloadDataDictionaryInfo'; +import DownloadVariableMetadataInfo from './DownloadVariableMetadataInfo'; import { DiscoveryConfig } from '../../../../../../../DiscoveryConfig'; import { DiscoveryResource } from '../../../../../../../Discovery'; import { mdsURL } from '../../../../../../../../localconf'; import { fetchWithCreds } from '../../../../../../../../actions'; -const mockDataDictionaries = { - 'QA_minimal_json_20230817.json': 'f79114a6-93bd-4970-b096-7b47aa6c16fa', +const mockVariableLevelMetadata = { + data_dictionaries: { 'QA_minimal_json_20230817.json': 'f79114a6-93bd-4970-b096-7b47aa6c16fa' }, + common_data_elements: { '5131 Pediatric Demographics': 'HDPCDE5131' }, +}; + +const mockVariableLevelMetadataRecords = { + dataDictionaries: { 'QA_minimal_json_20230817.json': 'f79114a6-93bd-4970-b096-7b47aa6c16fa' }, + cdeMetadata: { '5131 Pediatric Demographics': 'HDPCDE5131' }, }; const discoveryConfig = { features: { - exportToWorkspace: { variableMetadataFieldName: 'data_dictionaries' }, + exportToWorkspace: { variableMetadataFieldName: 'variable_level_metadata' }, }, } as DiscoveryConfig; @@ -26,17 +32,17 @@ afterEach(() => { jest.clearAllMocks(); }); -describe('DownloadDataDictionaryInfo', () => { - it('should not set download data dictionary info when called with invalid status number', async () => { +describe('DownloadVariableMetadataInfo', () => { + it('should not set download variable-level metadata info when called with invalid status number', async () => { const mockStatusResponse = { status: 500, data: { - data_dictionaries: mockDataDictionaries, + variable_level_metadata: mockVariableLevelMetadata, }, }; (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { - DownloadDataDictionaryInfo( + DownloadVariableMetadataInfo( discoveryConfig, resourceInfo as unknown as DiscoveryResource, showDownloadVariableMetadataButton, @@ -49,16 +55,16 @@ describe('DownloadDataDictionaryInfo', () => { expect(mockSetDownloadStatus).not.toHaveBeenCalled(); }); - it('should not download data dictionary info when called with invalid data', async () => { + it('should not download variable-level metadata info when called with invalid data', async () => { const mockStatusResponse = { status: 200, data: { - data_dictionaries: {}, + variable_level_metadata: {}, }, }; (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { - DownloadDataDictionaryInfo( + DownloadVariableMetadataInfo( discoveryConfig, resourceInfo as unknown as DiscoveryResource, showDownloadVariableMetadataButton, @@ -71,17 +77,17 @@ describe('DownloadDataDictionaryInfo', () => { expect(mockSetDownloadStatus).not.toHaveBeenCalled(); }); - it(`should not call fetchWithCreds or download data dictionary info when + it(`should not call fetchWithCreds or variable-level metadata info when called with showDownloadVariableMetadataButton = false`, async () => { const mockStatusResponse = { status: 200, data: { - data_dictionaries: mockDataDictionaries, + variable_level_metadata: mockVariableLevelMetadata, }, }; (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { - DownloadDataDictionaryInfo( + DownloadVariableMetadataInfo( discoveryConfig, resourceInfo as unknown as DiscoveryResource, false, // showDownloadVariableMetadataButton @@ -92,16 +98,16 @@ describe('DownloadDataDictionaryInfo', () => { expect(mockSetDownloadStatus).not.toHaveBeenCalled(); }); - it('should set data dictionary info when called with valid params', async () => { + it('should set variable-level metadata info when called with valid params', async () => { const mockStatusResponse = { status: 200, data: { - data_dictionaries: mockDataDictionaries, + variable_level_metadata: mockVariableLevelMetadata, }, }; (fetchWithCreds as jest.Mock).mockResolvedValue(mockStatusResponse); await act(async () => { - DownloadDataDictionaryInfo( + DownloadVariableMetadataInfo( discoveryConfig, resourceInfo as unknown as DiscoveryResource, showDownloadVariableMetadataButton, @@ -113,7 +119,7 @@ describe('DownloadDataDictionaryInfo', () => { }); expect(mockSetDownloadStatus).toHaveBeenCalledWith({ noVariableLevelMetadata: false, - dataDictionaries: mockDataDictionaries, + variableLevelMetadataRecords: mockVariableLevelMetadataRecords, }); }); }); diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.ts b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.ts new file mode 100644 index 0000000000..37f6f7cf52 --- /dev/null +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/ActionButtons/DownloadUtils/DownloadVariableMetadataInfo.ts @@ -0,0 +1,42 @@ +import { DiscoveryConfig } from '../../../../../../../DiscoveryConfig'; +import { DiscoveryResource } from '../../../../../../../Discovery'; +import { mdsURL } from '../../../../../../../../localconf'; +import { fetchWithCreds } from '../../../../../../../../actions'; +import VariableLevelMetadata from '../../Interfaces/VariableLevelMetadata'; + +const DownloadVariableMetadataInfo = ( + discoveryConfig: DiscoveryConfig, + resourceInfo: DiscoveryResource, + showDownloadVariableMetadataButton: Boolean, + setVariableMetadataInfo: Function, +) => { + const vlmdFieldReference = discoveryConfig.features.exportToWorkspace.variableMetadataFieldName; + if (showDownloadVariableMetadataButton) { + const studyID = resourceInfo._hdp_uid; + fetchWithCreds({ path: `${mdsURL}/${studyID}` }).then((statusResponse) => { + const { data } = statusResponse; + if ( + statusResponse.status === 200 + && data + && data[vlmdFieldReference as string] + && Object.keys(data[vlmdFieldReference as string]).length !== 0 + ) { + const variableLevelMetadataRecords: VariableLevelMetadata = {}; + if (data[vlmdFieldReference as string].data_dictionaries) { + variableLevelMetadataRecords.dataDictionaries = data[vlmdFieldReference as string].data_dictionaries; + } + if (data[vlmdFieldReference as string].common_data_elements) { + variableLevelMetadataRecords.cdeMetadata = data[vlmdFieldReference as string].common_data_elements; + } + if (Object.keys(variableLevelMetadataRecords).length) { + setVariableMetadataInfo({ + noVariableLevelMetadata: false, + variableLevelMetadataRecords, + }); + } + } + }); + } +}; + +export default DownloadVariableMetadataInfo; diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/DataDictionaries.ts b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/DataDictionaries.ts deleted file mode 100644 index fa054fc84e..0000000000 --- a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/DataDictionaries.ts +++ /dev/null @@ -1,4 +0,0 @@ -interface DataDictionaries { - [key: string]: string; -} -export default DataDictionaries; diff --git a/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/VariableLevelMetadata.ts b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/VariableLevelMetadata.ts new file mode 100644 index 0000000000..5aba196acc --- /dev/null +++ b/src/Discovery/DiscoveryDetails/Components/FieldGrouping/TabField/DataDownloadList/Interfaces/VariableLevelMetadata.ts @@ -0,0 +1,9 @@ +interface VariableLevelMetadata { + dataDictionaries?: { + [key: string]: string; + }, + cdeMetadata?: { + [key: string]: string; + }, +} +export default VariableLevelMetadata; diff --git a/src/Discovery/DiscoveryDetails/Components/HeaderButtons/HeaderButtons.tsx b/src/Discovery/DiscoveryDetails/Components/HeaderButtons/HeaderButtons.tsx index b7821ee664..18f32f7979 100644 --- a/src/Discovery/DiscoveryDetails/Components/HeaderButtons/HeaderButtons.tsx +++ b/src/Discovery/DiscoveryDetails/Components/HeaderButtons/HeaderButtons.tsx @@ -20,6 +20,8 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { studyNumber: string | null = null, studyUID: string | number | null = null, existingDataDictionaryName: Array = [], + existingCDEName: Array = [], + disableCDESubmissionForm: boolean = false, ) => { history.push(redirectURL, { studyName, @@ -27,6 +29,8 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { studyRegistrationAuthZ, studyUID, existingDataDictionaryName, + existingCDEName, + disableCDESubmissionForm, }); }; const permalink = GetPermaLink( @@ -66,7 +70,7 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { props.userAuthMapping, ); - const showSubmitDataDictionaryButton = props.modalData[studyRegistrationConfig.studyRegistrationValidationField] + const showSubmitVLMDButton = props.modalData[studyRegistrationConfig.studyRegistrationValidationField] && props.user.username && userHasMethodForServiceOnResource( 'access', @@ -144,13 +148,13 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { ) : null} - {showSubmitDataDictionaryButton ? ( + {showSubmitVLMDButton ? ( // user is authenticated, VLMD submission button should be visible only on registered studies that they have access to ) : null} {showRequestAccessButton ? ( @@ -176,7 +188,7 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { type='text' className='discovery-modal__request-button' onClick={() => handleRedirectClick( - '/data-dictionary-submission/request-access', + '/vlmd-submission/request-access', props.modalData[ studyRegistrationConfig.studyRegistrationAccessCheckField ], @@ -188,14 +200,14 @@ const HeaderButtons = ({ props, setTabActiveKey }) => { )} > - Request Access to Submit a Data Dictionary + Request Access to Submit Variable-level Metadata ) : null} {showLoginButton ? ( // user is NOT authenticated, Login in to VLMD submission button should be visible only on registered studies ) : null} + , + ]} + /> + + + ); + case 'error': + return ( +
+
+ { setCDEFormSubmitting(false); setFormSubmissionStatus(null); }}> + Close + , + ]} + /> +
+
+ ); + default: + return null; + } + } + + return ( +
+
+
{ setCDEFormSubmitting(false); }} + validateMessages={VALIDATE_MESSAGE} + onValuesChange={(changedValues) => { + if (Object.keys(changedValues).includes('coreCDEs')) { + const changedCoreCDECheckboxValues = changedValues.coreCDEs; + setSelectedCoreCDEs(changedCoreCDECheckboxValues); + } + if (Object.keys(changedValues).includes('selectedCDEs')) { + const changedCDESelectValues = changedValues.selectedCDEs; + const updatedCoreCDESelectValues: any[] = []; + const updatedNonCoreCDEselectValues: any[] = []; + changedCDESelectValues.forEach((element) => { + if (cdeInfoFromMDS.findIndex((entry) => (entry.option === element && entry.isCoreCDE)) !== -1) { + updatedCoreCDESelectValues.push(element); + } else { + updatedNonCoreCDEselectValues.push(element); + } + }); + setSelectedCoreCDEs(updatedCoreCDESelectValues); + setSelectedNonCoreCDEs(updatedNonCoreCDEselectValues); + } + }} + > + HEAL CDEs + {(props.disableCDESubmissionForm) ? ( + + We have received your CDE selections from the HEAL CDE team. If you need to update your selections, please contact heal_cde@hsc.utah.edu. + + ) : ( + + Use this form to indicate which HEAL Common Data Elements (CDEs) are utilized in this study (select all that apply). View the HEAL CDE Repository here. + + )} + +
* Indicates required fields
+ +