Skip to content

Commit

Permalink
Merge pull request #936 from opencb/TASK-6385
Browse files Browse the repository at this point in the history
TASK-6385 - Issues with the Study Filter dropdown of Variant Browser
  • Loading branch information
jmjuanes authored Jul 5, 2024
2 parents 23c477b + d574a0a commit d2a8fe0
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 58 deletions.
145 changes: 88 additions & 57 deletions src/webcomponents/commons/filters/study-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import UtilsNew from "../../../core/utils-new.js";
import LitUtils from "../utils/lit-utils.js";
import "../forms/select-field-filter.js";

import {guardPage} from "../html-utils.js";

export default class StudyFilter extends LitElement {

constructor() {
Expand All @@ -44,90 +42,116 @@ export default class StudyFilter extends LitElement {
}

#init() {
$.fn.selectpicker.Constructor.BootstrapVersion = "5";
this._prefix = UtilsNew.randomString(8);
this.operator = ",";
this.selectedStudies = [];
this.differentStudies = [];
this._studies = [];
this._operator = ",";
this._selection = [];
this._config = this.getDefaultConfig();
}

update(changedProperties) {
if (changedProperties.has("opencgaSession")) {
if (this.opencgaSession?.project?.studies?.length) {
this.differentStudies = this.opencgaSession.project.studies
.filter(study => this.opencgaSession.study.id !== study.id);
}
this.opencgaSessionObserver();
}

if (changedProperties.has("opencgaSession") || changedProperties.has("value")) {
this.selectedStudies = Array.from(new Set([
this.opencgaSession.study.fqn,
...(this.value || "").split(this.operator).filter(v => !!v),
]));
this.valueObserver();
}
if (changedProperties.has("config")) {
this._config = {
...this.getDefaultConfig(),
...this.config,
};
}

super.update(changedProperties);
}

updated(changedProperties) {
if (changedProperties.has("opencgaSession")) {
$(".selectpicker", this).selectpicker("refresh");
opencgaSessionObserver() {
this._studies = [];
if (this.opencgaSession?.project?.studies?.length) {
// 1. Add current study as the first element and mark it as disabled
this._studies.push({
name: this.opencgaSession.study.name,
id: this.opencgaSession.study.fqn,
selected: true,
disabled: true,
});
// 2. Add other studies to the studies dropdown
this.opencgaSession.project.studies.forEach(study => {
if (study.fqn !== this.opencgaSession.study.fqn) {
this._studies.push({
name: study.name,
id: study.fqn,
});
}
});
}
$(".selectpicker", this).selectpicker("val", this.selectedStudies);
}

filterChange() {
let querystring;
// AND or OR operators
if (this.operator !== "!") {
querystring = [...this.selectedStudies.map(study => `${study}`)].join(this.operator);
} else {
// NOT operator (not visible/not implemented)
querystring = [...this.selectedStudies.map(study => `${this.operator}${study}`)].join(";");
}
LitUtils.dispatchCustomEvent(this, "filterChange", querystring);
valueObserver() {
// 1. Reset the operator value. If the current value does not contain ';', maintain the current selected operator
this._operator = (this.value || "").indexOf(";") > -1 ? ";" : this._operator;
// 2. Reset the selection
this._selection = Array.from(new Set([
this.opencgaSession.study.fqn,
...(this.value || "").split(this._operator).filter(v => !!v),
]));
}

onChangeOperator(e) {
this.operator = e.target.value;
this.filterChange();
onStudyChange(event) {
// 1. Split values returned from select-field-filter and remove empty items
// Note: select-field-filter returns values joined with a comma character
const values = (event.detail.value || "")
.split(",")
.filter(value => !!value);
// 2. Trigger 'filterChange' event with the values joined with the current operator
LitUtils.dispatchCustomEvent(this, "filterChange", values.join(this._operator));
}

onChangeSelectedStudy() {
const selected = $(".selectpicker", this).selectpicker("val");
// Active study is always the first element
this.selectedStudies = [this.opencgaSession.study.fqn, ...selected];
this.requestUpdate();
this.filterChange();
onOperatorChange(event) {
// 1. Save the new operator value
this._operator = event.target.value || ",";
// 2. Trigger the 'filterChange' event
LitUtils.dispatchCustomEvent(this, "filterChange", this._selection.join(this._operator));
}

render() {
// Check Project exists
if (!this.opencgaSession && !this.opencgaSession.project) {
return guardPage();
return nothing;
}

return html`
<div class="mb-3" id="${this._prefix}DifferentStudies">
<select multiple class="form-control selectpicker" @change="${this.onChangeSelectedStudy}">
<option value="${this.opencgaSession.study.fqn}" selected="selected" disabled>
${this.opencgaSession.study.name}
</option>
${(this.differentStudies || []).map(study => html`
<option value="${study.fqn}">${study.name}</option>
`)}
</select>
<fieldset class="d-grid my-1 mx-0" ?disabled="${this.selectedStudies.length < 2}">
<div class="mb-3">
<select-field-filter
.data="${this._studies}"
.value="${this._selection}"
.config="${this._config}"
@filterChange="${event => this.onStudyChange(event)}">
</select-field-filter>
<fieldset class="d-grid my-1 mx-0" ?disabled="${this._selection.length < 2}">
<div class="btn-group" role="group">
<input class="btn-check" id="${this._prefix}orInput" name="pss"
type="radio" value="," @change="${this.onChangeOperator}"
autocomplete="off" checked>
<input
id="${this._prefix}orInput"
name="studyFilterOperator"
type="radio"
class="btn-check"
value=","
?checked="${this._operator === ","}"
?disabled="${this._selection.length < 2}"
@change="${event => this.onOperatorChange(event)}"
/>
<label class="btn btn-outline-primary" for="${this._prefix}orInput">
In any of (OR)
</label>
<input class="btn-check" id="${this._prefix}andInput" name="pss"
type="radio" value=";" @change="${this.onChangeOperator}"
autocomplete="off">
<input
id="${this._prefix}andInput"
name="studyFilterOperator"
type="radio"
class="btn-check"
value=";"
?checked="${this._operator === ";"}"
?disabled="${this._selection.length < 2}"
@change="${event => this.onOperatorChange(event)}"
/>
<label class="btn btn-outline-primary" for="${this._prefix}andInput">
In all (AND)
</label>
Expand All @@ -137,6 +161,13 @@ export default class StudyFilter extends LitElement {
`;
}

getDefaultConfig() {
return {
multiple: true,
disabled: false,
};
}

}

customElements.define("study-filter", StudyFilter);
2 changes: 1 addition & 1 deletion src/webcomponents/variant/variant-browser-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ export default class VariantBrowserFilter extends LitElement {

render() {
return html`
<div class="d-grid gap-1 mb-3" id="${this._prefix}Accordion" role="tablist" aria-multiselectable="true">
<div class="d-flex flex-column gap-3" id="${this._prefix}Accordion" role="tablist" aria-multiselectable="true">
${this.renderFilterMenu()}
</div>
`;
Expand Down

0 comments on commit d2a8fe0

Please sign in to comment.