diff --git a/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal-docs.json b/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal-docs.json index b4a4c0dc49e..31052fbd0ac 100644 --- a/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal-docs.json +++ b/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal-docs.json @@ -2831,6 +2831,103 @@ "operationId": "getAllStudyResourceDataInStudyUsingGET" } }, + "/api/studies/{studyId}/resource-data-all": { + "get": { + "produces": [ + "application/json" + ], + "parameters": [ + { + "description": "Study ID e.g. acc_tcga", + "in": "path", + "name": "studyId", + "required": true, + "type": "string" + }, + { + "description": "Resource ID", + "in": "query", + "name": "resourceId", + "required": false, + "type": "string" + }, + { + "default": "SUMMARY", + "description": "Level of detail of the response", + "enum": [ + "ID", + "SUMMARY", + "DETAILED", + "META" + ], + "in": "query", + "name": "projection", + "required": false, + "type": "string" + }, + { + "default": 10000000, + "description": "Page size of the result list", + "format": "int32", + "in": "query", + "maximum": 10000000, + "minimum": 1, + "name": "pageSize", + "required": false, + "type": "integer" + }, + { + "default": 0, + "description": "Page number of the result list", + "format": "int32", + "in": "query", + "minimum": 0, + "name": "pageNumber", + "required": false, + "type": "integer" + }, + { + "description": "Name of the property that the result list is sorted by", + "enum": [ + "ResourceId", + "url" + ], + "in": "query", + "name": "sortBy", + "required": false, + "type": "string" + }, + { + "default": "ASC", + "description": "Direction of the sort", + "enum": [ + "ASC", + "DESC" + ], + "in": "query", + "name": "direction", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/ResourceData" + }, + "type": "array" + } + } + }, + "tags": [ + "Resource Data" + ], + "description": "Get all resource data for for all patients and all samples within a study", + "operationId": "getAllStudyResourceDataInStudyPatientSampleUsingGET" + } + }, "/api/studies/{studyId}/resource-definitions": { "get": { "produces": [ diff --git a/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal.ts b/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal.ts index d6793bfaaa4..7db0e3b4e3f 100644 --- a/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal.ts +++ b/packages/cbioportal-ts-api-client/src/generated/CBioPortalAPIInternal.ts @@ -6746,6 +6746,159 @@ export default class CBioPortalAPIInternal { return response.body; }); }; + getAllStudyResourceDataInStudyPatientSampleUsingGETURL(parameters: { + 'studyId': string, + 'resourceId' ? : string, + 'projection' ? : "ID" | "SUMMARY" | "DETAILED" | "META", + 'pageSize' ? : number, + 'pageNumber' ? : number, + 'sortBy' ? : "ResourceId" | "url", + 'direction' ? : "ASC" | "DESC", + $queryParameters ? : any + }): string { + let queryParameters: any = {}; + let path = '/api/studies/{studyId}/resource-data-all'; + + path = path.replace('{studyId}', parameters['studyId'] + ''); + if (parameters['resourceId'] !== undefined) { + queryParameters['resourceId'] = parameters['resourceId']; + } + + if (parameters['projection'] !== undefined) { + queryParameters['projection'] = parameters['projection']; + } + + if (parameters['pageSize'] !== undefined) { + queryParameters['pageSize'] = parameters['pageSize']; + } + + if (parameters['pageNumber'] !== undefined) { + queryParameters['pageNumber'] = parameters['pageNumber']; + } + + if (parameters['sortBy'] !== undefined) { + queryParameters['sortBy'] = parameters['sortBy']; + } + + if (parameters['direction'] !== undefined) { + queryParameters['direction'] = parameters['direction']; + } + + if (parameters.$queryParameters) { + Object.keys(parameters.$queryParameters).forEach(function(parameterName) { + var parameter = parameters.$queryParameters[parameterName]; + queryParameters[parameterName] = parameter; + }); + } + let keys = Object.keys(queryParameters); + return this.domain + path + (keys.length > 0 ? '?' + (keys.map(key => key + '=' + encodeURIComponent(queryParameters[key])).join('&')) : ''); + }; + + /** + * Get all resource data for for all patients and all samples within a study + * @method + * @name CBioPortalAPIInternal#getAllStudyResourceDataInStudyPatientSampleUsingGET + * @param {string} studyId - Study ID e.g. acc_tcga + * @param {string} resourceId - Resource ID + * @param {string} projection - Level of detail of the response + * @param {integer} pageSize - Page size of the result list + * @param {integer} pageNumber - Page number of the result list + * @param {string} sortBy - Name of the property that the result list is sorted by + * @param {string} direction - Direction of the sort + */ + getAllStudyResourceDataInStudyPatientSampleUsingGETWithHttpInfo(parameters: { + 'studyId': string, + 'resourceId' ? : string, + 'projection' ? : "ID" | "SUMMARY" | "DETAILED" | "META", + 'pageSize' ? : number, + 'pageNumber' ? : number, + 'sortBy' ? : "ResourceId" | "url", + 'direction' ? : "ASC" | "DESC", + $queryParameters ? : any, + $domain ? : string + }): Promise < request.Response > { + const domain = parameters.$domain ? parameters.$domain : this.domain; + const errorHandlers = this.errorHandlers; + const request = this.request; + let path = '/api/studies/{studyId}/resource-data-all'; + let body: any; + let queryParameters: any = {}; + let headers: any = {}; + let form: any = {}; + return new Promise(function(resolve, reject) { + headers['Accept'] = 'application/json'; + + path = path.replace('{studyId}', parameters['studyId'] + ''); + + if (parameters['studyId'] === undefined) { + reject(new Error('Missing required parameter: studyId')); + return; + } + + if (parameters['resourceId'] !== undefined) { + queryParameters['resourceId'] = parameters['resourceId']; + } + + if (parameters['projection'] !== undefined) { + queryParameters['projection'] = parameters['projection']; + } + + if (parameters['pageSize'] !== undefined) { + queryParameters['pageSize'] = parameters['pageSize']; + } + + if (parameters['pageNumber'] !== undefined) { + queryParameters['pageNumber'] = parameters['pageNumber']; + } + + if (parameters['sortBy'] !== undefined) { + queryParameters['sortBy'] = parameters['sortBy']; + } + + if (parameters['direction'] !== undefined) { + queryParameters['direction'] = parameters['direction']; + } + + if (parameters.$queryParameters) { + Object.keys(parameters.$queryParameters).forEach(function(parameterName) { + var parameter = parameters.$queryParameters[parameterName]; + queryParameters[parameterName] = parameter; + }); + } + + request('GET', domain + path, body, headers, queryParameters, form, reject, resolve, errorHandlers); + + }); + }; + + /** + * Get all resource data for for all patients and all samples within a study + * @method + * @name CBioPortalAPIInternal#getAllStudyResourceDataInStudyPatientSampleUsingGET + * @param {string} studyId - Study ID e.g. acc_tcga + * @param {string} resourceId - Resource ID + * @param {string} projection - Level of detail of the response + * @param {integer} pageSize - Page size of the result list + * @param {integer} pageNumber - Page number of the result list + * @param {string} sortBy - Name of the property that the result list is sorted by + * @param {string} direction - Direction of the sort + */ + getAllStudyResourceDataInStudyPatientSampleUsingGET(parameters: { + 'studyId': string, + 'resourceId' ? : string, + 'projection' ? : "ID" | "SUMMARY" | "DETAILED" | "META", + 'pageSize' ? : number, + 'pageNumber' ? : number, + 'sortBy' ? : "ResourceId" | "url", + 'direction' ? : "ASC" | "DESC", + $queryParameters ? : any, + $domain ? : string + }): Promise < Array < ResourceData > + > { + return this.getAllStudyResourceDataInStudyPatientSampleUsingGETWithHttpInfo(parameters).then(function(response: request.Response) { + return response.body; + }); + }; getAllResourceDefinitionsInStudyUsingGETURL(parameters: { 'studyId': string, 'projection' ? : "ID" | "SUMMARY" | "DETAILED" | "META", diff --git a/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI-docs.json b/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI-docs.json index 491e0aff186..6b4d73499e4 100644 --- a/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI-docs.json +++ b/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI-docs.json @@ -1606,6 +1606,15 @@ }, "ncitCode": { "type": "string" + }, + "synonyms": { + "type": "array", + "items": { + "type": "string" + } + }, + "uuid": { + "type": "string" } } }, diff --git a/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI.ts b/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI.ts index bf182857798..728174a2711 100644 --- a/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI.ts +++ b/packages/genome-nexus-ts-api-client/src/generated/GenomeNexusAPI.ts @@ -192,6 +192,10 @@ export type Drug = { 'ncitCode': string + 'synonyms': Array < string > + + 'uuid': string + }; export type EnsemblFilter = { 'geneIds': Array < string > diff --git a/packages/oncokb-ts-api-client/src/generated/OncoKbAPI-docs.json b/packages/oncokb-ts-api-client/src/generated/OncoKbAPI-docs.json index 731757ff0bc..312261803f0 100644 --- a/packages/oncokb-ts-api-client/src/generated/OncoKbAPI-docs.json +++ b/packages/oncokb-ts-api-client/src/generated/OncoKbAPI-docs.json @@ -112,7 +112,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -157,7 +157,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -218,7 +218,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -263,7 +263,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -324,7 +324,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -369,7 +369,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -480,7 +480,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -525,7 +525,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -633,7 +633,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -678,7 +678,7 @@ "400": { "description": "Error, error message will be given.", "schema": { - "type": "string" + "$ref": "#/definitions/ApiHttpError" } } } @@ -1177,6 +1177,27 @@ } } }, + "ApiHttpError": { + "type": "object", + "properties": { + "detail": { + "type": "string" + }, + "message": { + "type": "string" + }, + "path": { + "type": "string" + }, + "status": { + "type": "integer", + "format": "int32" + }, + "title": { + "type": "string" + } + } + }, "CancerGene": { "type": "object", "properties": { diff --git a/packages/oncokb-ts-api-client/src/generated/OncoKbAPI.ts b/packages/oncokb-ts-api-client/src/generated/OncoKbAPI.ts index 05678a1b934..7719c131c06 100644 --- a/packages/oncokb-ts-api-client/src/generated/OncoKbAPI.ts +++ b/packages/oncokb-ts-api-client/src/generated/OncoKbAPI.ts @@ -78,6 +78,18 @@ export type QueryGene = { 'hugoSymbol': string +}; +export type ApiHttpError = { + 'detail': string + + 'message': string + + 'path': string + + 'status': number + + 'title': string + }; export type CancerGene = { 'entrezGeneId': number diff --git a/src/pages/studyView/resources/FilesAndLinks.tsx b/src/pages/studyView/resources/FilesAndLinks.tsx index ec4a728d121..bc619c96984 100644 --- a/src/pages/studyView/resources/FilesAndLinks.tsx +++ b/src/pages/studyView/resources/FilesAndLinks.tsx @@ -14,7 +14,6 @@ import { getSampleViewUrlWithPathname, getPatientViewUrlWithPathname, } from 'shared/api/urls'; -import { getAllClinicalDataByStudyViewFilter } from '../StudyViewUtils'; import { StudyViewPageStore } from 'pages/studyView/StudyViewPageStore'; import { isUrl, remoteData } from 'cbioportal-frontend-commons'; import { makeObservable, observable, computed } from 'mobx'; @@ -34,6 +33,19 @@ class FilesLinksTableComponent extends LazyMobXTable<{ const RECORD_LIMIT = 500; +function getResourceDataOfEntireStudy(studyIds: string[]) { + // Only handle the first studyId for now. Can be expanded to make a call per + // studyId. + const studyId = studyIds[0]; + const allResources = internalClient.getAllStudyResourceDataInStudyPatientSampleUsingGET( + { + studyId: studyId, + projection: 'DETAILED', + } + ); + return allResources; +} + function getResourceDataOfPatients(studyClinicalData: { [uniqueSampleKey: string]: ClinicalData[]; }) { @@ -97,28 +109,35 @@ function buildItemsAndResources(resourceData: { async function fetchFilesLinksData( filters: StudyViewFilter, - sampleIdResourceData: { [sampleId: string]: ResourceData[] }, + selectedSamples: Array, searchTerm: string | undefined, sortAttributeId: string | undefined, sortDirection: 'asc' | 'desc' | undefined, recordLimit: number ) { - const studyClinicalDataResponse = await getAllClinicalDataByStudyViewFilter( - filters, - searchTerm, - sortAttributeId, - sortDirection, - recordLimit, - 0 - ); + const selectedStudyIds = [ + ...new Set(selectedSamples.map(item => item.studyId)), + ]; + + // sampleIds (+patientIds) for the selectedSamples + const selectedIds = new Map([ + ...selectedSamples.map(item => [item.sampleId, item.studyId] as const), + ...selectedSamples.map(item => [item.patientId, item.studyId] as const), + ]); - const resourcesForPatients = await getResourceDataOfPatients( - studyClinicalDataResponse.data + // Fetch resources for entire study + const resourcesForEntireStudy = await getResourceDataOfEntireStudy( + selectedStudyIds ); - const resourcesForPatientsAndSamples: { [key: string]: ResourceData[] } = { - ...sampleIdResourceData, - ...resourcesForPatients, - }; + + // Filter the resources to consist of only studyView selected samples + // Also keep patient level resources (e.g. Those don't have a sampleId) + const resourcesForPatientsAndSamples = _(resourcesForEntireStudy) + .filter(resource => + selectedIds.has(resource.sampleId || resource.patientId) + ) + .groupBy(r => r.patientId) + .value(); // we create objects with the necessary properties for each resource // calculate the total number of resources per patient. @@ -197,7 +216,6 @@ export class FilesAndLinks extends React.Component { await: () => [ this.props.store.selectedSamples, this.props.store.resourceDefinitions, - this.props.store.sampleResourceData, ], onError: () => {}, invoke: async () => { @@ -207,12 +225,13 @@ export class FilesAndLinks extends React.Component { const resources = await fetchFilesLinksData( this.props.store.filters, - this.props.store.sampleResourceData.result!, + this.props.store.selectedSamples.result, this.searchTerm, 'patientId', 'asc', RECORD_LIMIT ); + return Promise.resolve(resources); }, });