@@ -18,12 +18,12 @@ import {
18
18
} from '@ant-design/icons' ;
19
19
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
20
20
import { Link , useLocation } from 'react-router-dom' ;
21
-
22
21
import './StudyRegistration.css' ;
23
22
import { userHasMethodForServiceOnResource } from '../authMappingUtils' ;
24
23
import { useArboristUI , studyRegistrationConfig } from '../localconf' ;
25
24
import loadStudiesFromMDS from '../Discovery/MDSUtils' ;
26
25
import { registerStudyInMDS , preprocessStudyRegistrationMetadata , createCEDARInstance } from './utils' ;
26
+ import Spinner from '../components/Spinner' ;
27
27
28
28
const { Option } = Select ;
29
29
const { Text } = Typography ;
@@ -73,13 +73,13 @@ const handleClinicalTrialIDValidation = async (_, ctID: string): Promise<boolean
73
73
if ( ! ctID ) {
74
74
return Promise . resolve ( true ) ;
75
75
}
76
- const resp = await fetch ( `https://classic. clinicaltrials.gov/api/query/field_values?expr= ${ encodeURIComponent ( `SEARCH[Study](AREA[NCTId] ${ ctID } )` ) } &field =NCTId&fmt=json ` ) ;
76
+ const resp = await fetch ( `https://clinicaltrials.gov/api/v2/studies/ ${ ctID } ?fields =NCTId` ) ;
77
77
if ( ! resp || resp . status !== 200 ) {
78
78
return Promise . reject ( 'Unable to verify ClinicalTrials.gov ID' ) ;
79
79
}
80
80
try {
81
81
const respJson = await resp . json ( ) ;
82
- if ( respJson . FieldValuesResponse ?. FieldValues ?. length === 1 && respJson . FieldValuesResponse . FieldValues [ 0 ] . FieldValue === ctID ) {
82
+ if ( respJson . protocolSection ?. identificationModule ?. nctId === ctID ) {
83
83
return Promise . resolve ( true ) ;
84
84
}
85
85
return Promise . reject ( 'Invalid ClinicalTrials.gov ID' ) ;
@@ -90,55 +90,18 @@ const handleClinicalTrialIDValidation = async (_, ctID: string): Promise<boolean
90
90
91
91
const getClinicalTrialMetadata = async ( ctID : string ) : Promise < object > => {
92
92
const errMsg = 'Unable to fetch study metadata from ClinicalTrials.gov' ;
93
-
94
- // get metadata from the clinicaltrials.gov API
95
- const promiseList : Promise < any > [ ] = [ ] ;
96
- const limit = 20 ; // the API has a limit of 20 fields
97
- let offset = 0 ;
98
93
const clinicalTrialFieldsToFetch = studyRegistrationConfig . clinicalTrialFields || [ ] ;
99
- while ( offset < clinicalTrialFieldsToFetch . length ) {
100
- const fieldsToFetch = clinicalTrialFieldsToFetch . slice ( offset , offset + limit ) ;
101
- offset += limit ;
102
- promiseList . push (
103
- fetch ( `https://classic.clinicaltrials.gov/api/query/study_fields?expr=${ encodeURIComponent ( `SEARCH[Study](AREA[NCTId] ${ ctID } )` ) } &fields=${ fieldsToFetch . join ( ',' ) } &fmt=json` )
104
- . then (
105
- ( resp ) => {
106
- if ( ! resp || resp . status !== 200 ) {
107
- return Promise . reject ( errMsg ) ;
108
- }
109
- return resp . json ( ) ;
110
- } ,
111
- ) ,
112
- ) ;
94
+ // get metadata from the clinicaltrials.gov API
95
+ const resp = await fetch ( `https://clinicaltrials.gov/api/v2/studies/${ ctID } ?fields=${ clinicalTrialFieldsToFetch . join ( '|' ) } ` ) ;
96
+ if ( ! resp || resp . status !== 200 ) {
97
+ return Promise . reject ( 'Unable to verify ClinicalTrials.gov ID' ) ;
98
+ }
99
+ try {
100
+ const respJson = await resp . json ( ) ;
101
+ return respJson ;
102
+ } catch {
103
+ throw errMsg ;
113
104
}
114
- const responsesJson = await Promise . all ( promiseList ) ;
115
-
116
- // add the metadata returned by each call to a single `metadata` object
117
- let metadata = { } ;
118
- responsesJson . forEach ( ( respJson ) => {
119
- // it should return data for a single study
120
- if ( respJson . StudyFieldsResponse ?. StudyFields ?. length !== 1 ) {
121
- // eslint-disable-next-line no-console
122
- console . error ( `${ errMsg } ; received response:` , respJson ) ;
123
- throw new Error ( errMsg ) ;
124
- }
125
- // `respData` looks like this:
126
- // {Rank: value to discard, FieldWithData: [value], FieldWithoutData: []}
127
- const respData = respJson . StudyFieldsResponse . StudyFields [ 0 ] ;
128
- // `partialMetadata` looks like this: (remove Rank and fields without data)
129
- // {FieldWithData: value}
130
- delete respData . Rank ;
131
- const partialMetadata = Object . keys ( respData ) . reduce ( ( res , key ) => {
132
- if ( respData [ key ] . length > 0 ) {
133
- res [ key ] = respData [ key ] [ 0 ] ;
134
- }
135
- return res ;
136
- } , { } ) ;
137
- // add the new key:value pairs to the ones we already have
138
- metadata = { ...metadata , ...partialMetadata } ;
139
- } ) ;
140
-
141
- return Promise . resolve ( metadata ) ;
142
105
} ;
143
106
144
107
const isUUID = ( input : string ) => {
@@ -272,7 +235,9 @@ const StudyRegistration: React.FunctionComponent<StudyRegistrationProps> = (prop
272
235
</ div >
273
236
) ;
274
237
}
275
-
238
+ if ( ! studies ) {
239
+ return < Spinner text = { 'Loading study registration form, please wait...' } /> ;
240
+ }
276
241
return (
277
242
< div className = 'study-reg-container' >
278
243
< div className = 'study-reg-form-container' >
@@ -292,7 +257,7 @@ const StudyRegistration: React.FunctionComponent<StudyRegistrationProps> = (prop
292
257
key = { study [ studyRegistrationConfig . studyRegistrationUIDField ] }
293
258
value = { study [ studyRegistrationConfig . studyRegistrationUIDField ] }
294
259
>
295
- { `${ study . project_number } : ${ study . project_title } : ${ study . appl_id } ` }
260
+ { `${ study . project_number || 'N/A' } : ${ study . study_metadata ?. minimal_info ?. study_name || 'N/A' } : ${ study . study_metadata ?. metadata_location ?. nih_application_id || 'N/A' } ` }
296
261
</ Option >
297
262
) ) }
298
263
</ Select >
@@ -345,12 +310,14 @@ const StudyRegistration: React.FunctionComponent<StudyRegistrationProps> = (prop
345
310
name = 'repository'
346
311
label = 'Study Data Repository'
347
312
hasFeedback
348
- help = { (
349
- < React . Fragment > If you have already selected a data repository, indicate it here; otherwise, leave empty.< br />
350
- If you have deposited your data and you have a unique Study ID for the data at the repository, enter it below; otherwise, leave blank.
351
- </ React . Fragment >
352
- ) }
353
- >
313
+ help = { (
314
+ < React . Fragment > If you have already selected a data repository, indicate it here;
315
+ otherwise, leave empty.< br />
316
+ If you have deposited your data and you have a unique Study ID for the data at
317
+ the repository, enter it below; otherwise, leave blank.
318
+ </ React . Fragment >
319
+ ) }
320
+ >
354
321
< Select placeholder = 'Select a data repository' showSearch allowClear >
355
322
< Option value = 'BioSystics-AP' > BioSystics-AP</ Option >
356
323
< Option value = 'Database of Genotypes and Phenotypes (dbGaP)' > Database of Genotypes and Phenotypes (dbGaP)</ Option >
0 commit comments