diff --git a/src/pages/studyView/StudyViewPageStore.ts b/src/pages/studyView/StudyViewPageStore.ts index e008c43da76..08d797503cf 100644 --- a/src/pages/studyView/StudyViewPageStore.ts +++ b/src/pages/studyView/StudyViewPageStore.ts @@ -57,6 +57,7 @@ import { PatientTreatmentRow, ResourceData, Sample, + SampleFilter, SampleIdentifier, SampleMolecularIdentifier, SampleTreatmentRow, @@ -389,6 +390,15 @@ enum CustomDataTypeEnum { NUMERICAL = 'NUMERICAL', } +interface PatientIdentifierFilter { + patientIdentifiers: PatientIdentifier[]; +} + +interface PatientIdentifier { + patientId: string; + studyId: string; +} + export class StudyViewPageStore implements IAnnotationFilterSettings, ISettingsMenuButtonVisible { private reactionDisposers: IReactionDisposer[] = []; @@ -2165,14 +2175,23 @@ export class StudyViewPageStore // We do not support studyIds in the query filters let filters: Partial = {}; if (query.filterJson) { - try { - filters = JSON.parse( - decodeURIComponent(query.filterJson) - ) as Partial; - this.updateStoreByFilters(filters); - } catch (e) { - // TODO: add some logging here? + const parsedFilterJson = this.parseRawFilterJson(query.filterJson); + if (query.filterJson.includes('patientIdentifiers')) { + const samples = await this.fetchSamplesWithStudyIds(studyIds); + const { + patientIdentifiers, + } = parsedFilterJson as PatientIdentifierFilter; + const sampleIdentifiers = this.convertPatientIdentifiersToSampleIdentifiers( + patientIdentifiers, + samples + ); + if (sampleIdentifiers.length > 0) { + filters.sampleIdentifiers = sampleIdentifiers; + } + } else { + filters = parsedFilterJson as Partial; } + this.updateStoreByFilters(filters); } else if (query.filterAttributeId && query.filterValues) { const clinicalAttributes = _.uniqBy( await defaultClient.fetchClinicalAttributesUsingPOST({ @@ -2224,6 +2243,41 @@ export class StudyViewPageStore } } + parseRawFilterJson(filterJson: string): any { + let rawJson; + try { + rawJson = JSON.parse(decodeURIComponent(filterJson)); + } catch (e) { + console.error('FilterJson invalid Json: error: ', e); + } + return rawJson; + } + + fetchSamplesWithStudyIds(studyIds: string[]) { + return defaultClient.fetchSamplesUsingPOST({ + sampleFilter: { + sampleListIds: studyIds.map(s => s.concat('', '_all')), + } as SampleFilter, + projection: 'SUMMARY', + }); + } + + convertPatientIdentifiersToSampleIdentifiers( + patientIdentifiers: Array, + samples: Sample[] + ): SampleIdentifier[] { + return samples + .filter(s => + patientIdentifiers.some( + p => p.patientId === s.patientId && p.studyId === s.studyId + ) + ) + .map(s => ({ + sampleId: s.sampleId, + studyId: s.studyId, + })); + } + @computed get initialFilters(): StudyViewFilter { let initialFilter = {} as StudyViewFilter;