diff --git a/cypress/e2e/iva/individual-browser-grid.cy.js b/cypress/e2e/iva/individual-browser-grid.cy.js index 69b9a267aa..ff21ff3cf1 100644 --- a/cypress/e2e/iva/individual-browser-grid.cy.js +++ b/cypress/e2e/iva/individual-browser-grid.cy.js @@ -111,6 +111,49 @@ context("Individual Browser Grid", () => { }); }); + // MODAL CREATE AUTOCOMPLETE + context("Modal Create Autocomplete", () => { + beforeEach(() => { + // eslint-disable-next-line cypress/unsafe-to-chain-command + cy.get("@container") + .find(`button[data-action="create"]`) + .click(); + cy.get("@container") + .find(`div[data-cy="modal-create"]`) + .as("modal-create"); + }); + + it("should autocomplete on searching and selecting one result", () => { + // eslint-disable-next-line cypress/unsafe-to-chain-command + cy.get("@modal-create") + .contains("ul.nav.nav-tabs > li", "Phenotypes") + .click(); + cy.get("@modal-create") + .contains("button", "Add Item") + .click(); + cy.get("cellbase-search-autocomplete") + .find("select-token-filter .select2-container") + .click(); + cy.get("cellbase-search-autocomplete") + .find("input.select2-search__field") + .type("gli"); + cy.get("cellbase-search-autocomplete") + .find("span.select2-results li") + .first() + .click(); + cy.get("cellbase-search-autocomplete") + .find("span.select2-selection__rendered") + .should("contain.text", "Glioblastoma multiforme"); + cy.get("@modal-create") + .find(`input[placeholder="Add phenotype ID......"]`) + .then(element => { + expect(element.val()).equal("HP:0012174"); + cy.wrap(element).should("be.disabled"); + }); + + }); + }); + // MODAL UPDATE context("Modal Update", () => { beforeEach(() => { @@ -352,7 +395,6 @@ context("Individual Browser Grid", () => { .find(`tbody tr[data-index="0"]`) .as("row"); }); - }); // 4. Extensions @@ -442,7 +484,7 @@ context("Individual Browser Grid", () => { .find(`td`) .eq(1) .trigger("click"); - + cy.get(`detail-tabs h3`) .should("contain.text", `Individual ${individual}`); }); @@ -452,7 +494,7 @@ context("Individual Browser Grid", () => { .find("li") .contains("JSON Data") .trigger("click"); - + cy.get("json-viewer") .should("be.visible"); }); diff --git a/src/core/clients/cellbase/cellbase-client.js b/src/core/clients/cellbase/cellbase-client.js index 66b1aa26c3..84337d9406 100644 --- a/src/core/clients/cellbase/cellbase-client.js +++ b/src/core/clients/cellbase/cellbase-client.js @@ -269,6 +269,7 @@ export class CellBaseClient { const url = this._createRestUrl(host, version, species, category, subcategory, ids, resource, params); const k = this.generateKey({...params, species, category, subcategory, resource, params}); + // FIXME: add try-catch-finally (see opencga-rest-input.js) return this.restClient.call(url, options, k); } diff --git a/src/sites/test-app/clients/cellbase-client-mock.js b/src/sites/test-app/clients/cellbase-client-mock.js index 40f559cff8..b7a9c7cac8 100644 --- a/src/sites/test-app/clients/cellbase-client-mock.js +++ b/src/sites/test-app/clients/cellbase-client-mock.js @@ -1,4 +1,5 @@ import UtilsNew from "../../../core/utils-new.js"; +import {RestResponse} from "../../../core/clients/rest-response"; export class CellBaseClientMock { @@ -42,6 +43,19 @@ export class CellBaseClientMock { return UtilsNew.importJSONFile(`./test-data/${this._config.testDataVersion}/genome-browser-region-17-43102293-43106467-variants.json`); } } + } + if (category === "feature") { + if (subcategory === "ontology" && resource === "search") { + switch (params.name) { + case "~/gli/i": + return UtilsNew.importJSONFile(`./test-data/${this._config.testDataVersion}/cellbase-autocomplete-phenotypes.json`) + .then(data => new RestResponse({responses: [{results: data}]})); + default: + break; + } + } + + } // Other request return Promise.reject(new Error("Not implemented")); diff --git a/src/webcomponents/commons/filters/cellbase-search-autocomplete.js b/src/webcomponents/commons/filters/cellbase-search-autocomplete.js new file mode 100644 index 0000000000..a56c358999 --- /dev/null +++ b/src/webcomponents/commons/filters/cellbase-search-autocomplete.js @@ -0,0 +1,275 @@ +/** + * Copyright 2015-2023 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {LitElement, html} from "lit"; +import LitUtils from "../utils/lit-utils.js"; +import "../forms/select-token-filter.js"; +import UtilsNew from "../../../core/utils-new"; + +export default class CellbaseSearchAutocomplete extends LitElement { + + constructor() { + super(); + + this.#init(); + } + + createRenderRoot() { + return this; + } + + static get properties() { + return { + value: { + type: Object + }, + resource: { + type: String, + }, + cellbaseClient: { + type: Object, + }, + classes: { + type: String + }, + config: { + type: Object + }, + searchField: { + type: String, + }, + }; + } + + #init() { + this.RESOURCES = {}; + this.endpoint = {}; + this.defaultQueryParams = { + limit: 10, + count: false, + }; + this.#initResourcesConfig(); + this.searchField = ""; + } + + #initResourcesConfig() { + this.RESOURCES = { + "PHENOTYPE": { + category: "feature", + subcategory: "ontology", + operation: "search", + getSearchField: term => /^[^:\s]+:/.test(term) ? "id": "name", + placeholder: "Start typing a phenotype ID or name...", + queryParams: {}, + // Pre-process the results of the query if needed. + }, + "DISORDER": { + category: "feature", + subcategory: "ontology", + operation: "search", + getSearchField: term => /^[^:\s]+:/.test(term) ? "id": "name", + placeholder: "Start typing a disorder ID or name ...", + queryParams: {}, + // Pre-process the results of the query if needed. + }, + "GENE": { + // CAUTION: In feature-filter.js L71, we are autocompleting: xref, ids, gene, geneName. + category: "feature", + subcategory: "gene", + operation: "search", + getSearchField: term => { + // FIXME: Query gene by id is not working! Temporarily returning ALWAYS name + // return term.startsWith("ENSG0") ? "id" : "name"; + return term.startsWith("ENSG0") ? "name" : "name"; + }, + valueField: "name", + placeholder: "Start typing an ensemble gene ID or name...", + queryParams: { + exclude: "transcripts,annotation", + }, // CAUTION: query params depends on the resource/operation (i.e. search, info) used + }, + "VARIANT": {}, + "PROTEIN": {}, + "TRANSCRIPT": {}, + "VARIATION": {}, + "REGULATORY": {}, + }; + } + + // Filter the fields that can be used to fill the form automatically + #filterResults(results) { + return results.map(item => ({ + id: item.id, + name: item.name, + source: item.source, + description: item.description, + text: item.name || item.id, + })); + } + + // Templating one option of dropdown + // TODO Vero: Style with default bootstrap + #viewResultStyle() { + return html ` + + `; + } + + #viewResult(option) { + return option.name ? $(` +