Skip to content

Commit 444e7e0

Browse files
committed
Merge branch 'TASK-8076' of github.com:opencb/jsorolla into TASK-8076
2 parents a967e04 + 755016d commit 444e7e0

9 files changed

+249
-216
lines changed

src/core/utils-new.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ export default class UtilsNew {
645645
const detail = internal.detail;
646646

647647
// Get default filters
648-
const defaultFilter = external?.menu?.defaultFilter || {};
648+
const defaultFilter = external?.menu?.defaultFilter || null;
649649

650650
if (external?.menu?.sections?.length) {
651651
sections = UtilsNew.mergeSections(sections, external.menu.sections);

src/webcomponents/clinical/clinical-analysis-browser.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ export default class ClinicalAnalysisBrowser extends LitElement {
226226
title: "Priority",
227227
description: ""
228228
},
229+
{
230+
id: "flags",
231+
title: "Flags",
232+
description: "",
233+
quick: true,
234+
},
235+
{
236+
id: "analysts",
237+
title: "Analysts",
238+
description: "",
239+
quick: true,
240+
},
229241
{
230242
id: "creationDate",
231243
title: "Creation Date",

src/webcomponents/commons/filters-toolbar.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ export default class FiltersToolbar extends LitElement {
611611
renderFilterItems(items, highlightActiveFilter = true, showFilterDelete = false) {
612612
return items.map(item => {
613613
const isActive = highlightActiveFilter && UtilsNew.objectCompare(this.preparedQuery, item.query);
614-
const filterParams = Object.keys(item.query)
614+
const filterParams = Object.keys(item.query || {})
615615
.filter(key => key !== "study" && !!item.query[key]);
616616
const filterTooltip = filterParams
617617
.map(key => `<b>${key}</b> = ${item.query[key]}`)
@@ -827,7 +827,8 @@ export default class FiltersToolbar extends LitElement {
827827
},
828828
sections: [],
829829
examples: [],
830-
defaultFilter: {},
830+
filters: [],
831+
defaultFilter: null,
831832
searchButton: true,
832833
searchButtonText: "Search",
833834
searchButtonIcon: "fas fa-search",

src/webcomponents/commons/opencga-browser-filter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export default class OpencgaBrowserFilter extends LitElement {
108108
"type": "type",
109109
"scope": "scope",
110110
"internalStatus": "internal.status.id",
111+
"flags": "flags.id",
112+
"analysts": "analysts.id",
111113
};
112114
}
113115

@@ -162,6 +164,8 @@ export default class OpencgaBrowserFilter extends LitElement {
162164
case "type":
163165
case "scope":
164166
case "internalStatus":
167+
case "flags":
168+
case "analysts":
165169
content = html`
166170
<catalog-distinct-autocomplete
167171
.value="${preparedQuery[subsection.id]}"

src/webcomponents/variant/interpretation/variant-interpreter-browser-cancer.js

Lines changed: 76 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class VariantInterpreterBrowserCancer extends LitElement {
4545
title: {
4646
type: String,
4747
},
48+
query: {
49+
type: Object,
50+
},
4851
settings: {
4952
type: Object
5053
},
@@ -57,11 +60,8 @@ class VariantInterpreterBrowserCancer extends LitElement {
5760
#init() {
5861
this.COMPONENT_ID = "variant-interpreter-cancer-snv";
5962
this._prefix = UtilsNew.randomString(8);
60-
61-
this.query = {};
62-
this.activeFilterFilters = [];
63-
this.savedVariants = [];
64-
63+
this._query = {};
64+
this._files = [];
6565
this._config = this.getDefaultConfig();
6666
}
6767

@@ -90,56 +90,56 @@ class VariantInterpreterBrowserCancer extends LitElement {
9090
}
9191

9292
clinicalAnalysisObserver() {
93+
// Configuration is using the clinicalAnalysis
94+
this._config = this.getDefaultConfig();
95+
96+
let activeFilterFilters = [];
97+
let query = {};
98+
9399
// Init the active filters with every new Case opened. Then we add the default filters for the given sample.
94-
let _activeFilterFilters;
95100
if (this.settings?.menu?.examples?.length > 0) {
96101
// Load custom filters if configured
97102
// We need to clone to make sure we reset active fields
98-
_activeFilterFilters = UtilsNew.objectClone(this.settings.menu.examples);
103+
activeFilterFilters = UtilsNew.objectClone(this.settings.menu.examples);
99104
} else {
100105
// Load default filters if not custom defined
101-
_activeFilterFilters = this._config?.filter?.examples ? [...this._config.filter.examples] : [];
106+
activeFilterFilters = this._config?.filter?.examples ? [...this._config.filter.examples] : [];
102107
}
103108

104109
// Check for adding the examples filters section
105-
if (_activeFilterFilters?.length > 0) {
106-
_activeFilterFilters.unshift({
110+
if (activeFilterFilters?.length > 0) {
111+
activeFilterFilters.unshift({
107112
category: true,
108113
name: "Example Filters",
109114
});
110115
}
111116

112-
this.somaticSample = this.clinicalAnalysis.proband.samples.find(sample => sample.somatic);
113-
if (this.somaticSample) {
114-
// Init query object if needed
115-
if (!this.query) {
116-
this.query = {};
117-
}
118-
117+
// get the somatic sample
118+
const somaticSample = this.clinicalAnalysis.proband.samples.find(sample => sample.somatic);
119+
if (somaticSample) {
119120
// 1. 'sample' query param: if sample is not defined then we must set the sample and genotype
120-
if (!this.query?.sample) {
121+
if (!query?.sample) {
121122
// We do not add GT filter ":0/1,1/1,NA" in cancer interpreter anymore
122123
// because variants with weird GT would not be displayed
123-
this.query.sample = this.somaticSample.id;
124+
query.sample = somaticSample.id;
124125
}
125126

126127
// 2. 'panel' query param: add case panels to query object
127128
if (this.clinicalAnalysis.interpretation?.panels?.length > 0) {
128-
this.query.panel = this.clinicalAnalysis.interpretation.panels.map(panel => panel.id).join(",");
129+
query.panel = this.clinicalAnalysis.interpretation.panels.map(panel => panel.id).join(",");
129130
} else {
130131
if (this.clinicalAnalysis.panels?.length > 0) {
131-
this.query.panel = this.clinicalAnalysis.panels.map(panel => panel.id).join(",");
132+
query.panel = this.clinicalAnalysis.panels.map(panel => panel.id).join(",");
132133
}
133134
}
134135

135136
// 3. panelIntersection param: if panel lock is enabled, this param should be also enabled
136137
if (this.clinicalAnalysis.panelLocked) {
137-
this.query.panelIntersection = true;
138+
query.panelIntersection = true;
138139
}
139140

140141
// 4. Get all files indexed
141-
this.indexedFiles = this.clinicalAnalysis.files
142-
.filter(file => file.format.toUpperCase() === "VCF");
142+
// const indexedFiles = this.clinicalAnalysis.files.filter(file => file.format.toUpperCase() === "VCF");
143143

144144
// 5. 'fileData' query param: fetch non SV files and set init query
145145
if (this.opencgaSession?.study?.internal?.configuration?.clinical?.interpretation?.variantCallers?.length > 0) {
@@ -153,50 +153,48 @@ class VariantInterpreterBrowserCancer extends LitElement {
153153
.filter(vc => vc.dataFilters.findIndex(filter => !filter.source || filter.source === "FILE") !== -1);
154154

155155
// Files matching the selected Variant Callers
156-
this.files = this.clinicalAnalysis.files
156+
this._files = this.clinicalAnalysis.files
157157
.filter(file => file.format.toUpperCase() === "VCF")
158-
.filter(file =>
159-
nonSvSomaticVariantCallers.findIndex(vc => vc.id.toUpperCase() === file.software?.name?.toUpperCase()) !== -1);
158+
.filter(file => {
159+
return nonSvSomaticVariantCallers.findIndex(vc => vc.id.toUpperCase() === file.software?.name?.toUpperCase()) !== -1;
160+
});
160161

161-
if (this.files?.length > 0) {
162+
if (this._files?.length > 0) {
162163
const fileDataFilters = [];
163-
nonSvSomaticVariantCallers
164-
.forEach(vc => {
165-
const filtersWithDefaultValues = vc.dataFilters
166-
.filter(filter => !filter.source || filter.source === "FILE")
167-
.filter(filter => !!filter.defaultValue)
168-
.map(filter => {
169-
// Notice that defaultValue includes the comparator, eg. =, >, ...
170-
return filter.id + (filter.id !== "FILTER" ? filter.defaultValue : "=PASS");
171-
});
172-
173-
// Only add this file to the filter if we have at least one default value
174-
if (filtersWithDefaultValues.length > 0) {
175-
// We need to find the file for that caller
176-
const fileId = this.files
177-
.filter(file => file.internal?.variant?.index?.status?.id === "READY")
178-
.find(file => file.software.name === vc.id)?.name;
179-
if (fileId) {
180-
fileDataFilters.push(fileId + ":" + filtersWithDefaultValues.join(";"));
181-
}
164+
nonSvSomaticVariantCallers.forEach(vc => {
165+
const filtersWithDefaultValues = vc.dataFilters
166+
.filter(filter => !filter.source || filter.source === "FILE")
167+
.filter(filter => !!filter.defaultValue)
168+
.map(filter => {
169+
// Notice that defaultValue includes the comparator, eg. =, >, ...
170+
return filter.id + (filter.id !== "FILTER" ? filter.defaultValue : "=PASS");
171+
});
172+
173+
// Only add this file to the filter if we have at least one default value
174+
if (filtersWithDefaultValues.length > 0) {
175+
// We need to find the file for that caller
176+
const fileId = this._files
177+
.filter(file => file.internal?.variant?.index?.status?.id === "READY")
178+
.find(file => file.software.name === vc.id)?.name;
179+
if (fileId) {
180+
fileDataFilters.push(fileId + ":" + filtersWithDefaultValues.join(";"));
182181
}
183-
});
182+
}
183+
});
184184

185185
// Update query with default 'fileData' parameters
186-
this.query.fileData = fileDataFilters.join(",");
186+
query.fileData = fileDataFilters.join(",");
187187
} else {
188-
this.files = this.clinicalAnalysis.files
189-
.filter(file => file.format.toUpperCase() === "VCF");
188+
this._files = this.clinicalAnalysis.files.filter(file => file.format.toUpperCase() === "VCF");
190189
}
191190
} else {
192-
this.files = this.clinicalAnalysis.files
193-
.filter(file => file.format.toUpperCase() === "VCF");
191+
this._files = this.clinicalAnalysis.files.filter(file => file.format.toUpperCase() === "VCF");
194192
}
195193

196194
// 6. Read defaultFilter from browser settings
197195
if (this.settings?.menu?.defaultFilter) {
198-
this.query = {
199-
...this.query,
196+
query = {
197+
...query,
200198
...this.settings.menu.defaultFilter,
201199
};
202200
}
@@ -207,13 +205,13 @@ class VariantInterpreterBrowserCancer extends LitElement {
207205

208206
// Add filter to Active Filter's menu
209207
// 1. Add variant stats saved queries to the Active Filters menu
210-
if (this.somaticSample.qualityControl?.variant?.variantStats?.length > 0) {
211-
_activeFilterFilters.push({
208+
if (somaticSample.qualityControl?.variant?.variantStats?.length > 0) {
209+
activeFilterFilters.push({
212210
category: true,
213211
name: "Variant Stats Filters",
214212
});
215-
_activeFilterFilters.push(
216-
...this.somaticSample.qualityControl.variant.variantStats.map(variantStat => ({
213+
activeFilterFilters.push(
214+
...somaticSample.qualityControl.variant.variantStats.map(variantStat => ({
217215
id: variantStat.id,
218216
active: false,
219217
query: variantStat.query,
@@ -222,21 +220,21 @@ class VariantInterpreterBrowserCancer extends LitElement {
222220
}
223221

224222
// 2. Add default initial query the active filter menu
225-
_activeFilterFilters.unshift({
223+
activeFilterFilters.unshift({
226224
id: "Default Filter",
227225
active: false,
228-
query: this.query,
226+
query: query,
229227
});
230228

231229
// Add 'file' filter if 'fileData' exists
232-
if (this.files) {
233-
const fileNames = this.files
230+
if (this._files) {
231+
const fileNames = this._files
234232
.filter(file => file.internal?.variant?.index?.status?.id === "READY")
235233
.map(f => f.name);
236234
// Only filter by file if there are more than 1 file indexed
237235
if (fileNames.length > 0) {
238236
const joinedFileNames = fileNames.join(",");
239-
for (const filter of _activeFilterFilters) {
237+
for (const filter of activeFilterFilters) {
240238
if (filter.query?.fileData && !filter.query?.file) {
241239
filter.query.file = joinedFileNames;
242240
}
@@ -245,35 +243,39 @@ class VariantInterpreterBrowserCancer extends LitElement {
245243
}
246244

247245
// Set active filters
248-
this._config.filter.activeFilters.filters = _activeFilterFilters;
249-
const activeFilter = this._config.filter.activeFilters.filters.find(filter => filter.active);
246+
this._config.filter.filters = activeFilterFilters;
247+
const activeFilter = this._config.filter.filters.find(filter => filter.active);
250248
if (activeFilter?.query) {
251-
this.query = {...this.query, ...activeFilter.query};
249+
query = {
250+
...query,
251+
...activeFilter.query,
252+
};
252253
}
253254
} else {
254255
// No somatic sample found, this is weird scenario but can happen if a case is created empty.
255256
// We init active filters anyway.
256-
this._config.filter.activeFilters.filters = [];
257+
this._config.filter.filters = [];
257258
}
258259

259-
this.query = {...this.query};
260+
// set the initial query: use the query from the property (to restore the previous query) or the default query
261+
this._query = this.query ? UtilsNew.objectClone(this.query) : query;
260262
}
261263

262264
onQueryChange(event) {
263-
this.query = event.detail.query;
265+
this._query = event.detail.query;
264266
}
265267

266268
render() {
267269
return html`
268270
<variant-interpreter-browser-template
269271
.clinicalAnalysis="${this.clinicalAnalysis}"
270-
.query="${this.query}"
272+
.query="${this._query}"
271273
.opencgaSession="${this.opencgaSession}"
272274
.settings="${this.settings}"
273275
.toolId="${this.COMPONENT_ID}"
274276
.config="${this._config}"
275277
.active="${this.active}"
276-
@queryChange="${this.onQueryChange}">
278+
@queryChange="${event => this.onQueryChange(event)}">
277279
</variant-interpreter-browser-template>
278280
`;
279281
}
@@ -316,9 +318,9 @@ class VariantInterpreterBrowserCancer extends LitElement {
316318
{
317319
id: "variant-file",
318320
title: "VCF File Filter",
319-
visible: () => this.files?.length > 1,
321+
visible: () => this._files?.length > 1,
320322
params: {
321-
files: this.files,
323+
files: this._files,
322324
},
323325
tooltip: tooltips.vcfFile,
324326
},

0 commit comments

Comments
 (0)