diff --git a/client/src/components/Panels/Common/ToolSearch.test.js b/client/src/components/Panels/Common/ToolSearch.test.js index 4762ce0ec931..9549e458b995 100644 --- a/client/src/components/Panels/Common/ToolSearch.test.js +++ b/client/src/components/Panels/Common/ToolSearch.test.js @@ -2,6 +2,7 @@ import "jest-location-mock"; import { mount } from "@vue/test-utils"; import DelayedInput from "components/Common/DelayedInput"; +import { createPinia } from "pinia"; import { getLocalVue } from "tests/jest/helpers"; import VueRouter from "vue-router"; @@ -12,19 +13,22 @@ localVue.use(VueRouter); const router = new VueRouter(); describe("ToolSearch", () => { - it("test tools advanced filter panel", async () => { + it("test tools advanced filter panel navigation", async () => { + const pinia = createPinia(); const wrapper = mount(ToolSearch, { propsData: { currentPanelView: "default", enableAdvanced: false, showAdvanced: false, - toolbox: [], + toolsList: [], + currentPanel: {}, }, localVue, router, stubs: { icon: { template: "
" }, }, + pinia, }); const $router = wrapper.vm.$router; @@ -34,13 +38,6 @@ describe("ToolSearch", () => { expect(wrapper.find("[data-description='toggle advanced search']").exists()).toBe(true); expect(wrapper.find("[description='advanced tool filters']").exists()).toBe(true); - // Test: changing panel view should change search by section field to search by ontology - expect(wrapper.find("[placeholder='any section']").exists()).toBe(true); - await wrapper.setProps({ currentPanelView: "ontology:edam_operations" }); - expect(wrapper.find("[placeholder='any section']").exists()).toBe(false); - expect(wrapper.find("[placeholder='any ontology']").exists()).toBe(true); - await wrapper.setProps({ currentPanelView: "default" }); - // Test: keyup.esc (should toggle the view out) --- doesn't work from name (DelayedInput) field const sectionField = wrapper.find("[placeholder='any section']"); expect(wrapper.emitted()["update:show-advanced"]).toBeUndefined(); @@ -52,6 +49,7 @@ describe("ToolSearch", () => { const filterInputs = { name: "name-filter", "[placeholder='any section']": "section-filter", + "[placeholder='any ontology']": "ontology-filter", "[placeholder='any id']": "id-filter", "[placeholder='any owner']": "owner-filter", "[placeholder='any help text']": "help-filter", @@ -75,6 +73,7 @@ describe("ToolSearch", () => { const filterSettings = { name: "name-filter", section: "section-filter", + ontology: "ontology-filter", id: "id-filter", owner: "owner-filter", help: "help-filter", diff --git a/client/src/components/Panels/Common/ToolSearch.vue b/client/src/components/Panels/Common/ToolSearch.vue index 062dc3ccab57..235c780c1cda 100644 --- a/client/src/components/Panels/Common/ToolSearch.vue +++ b/client/src/components/Panels/Common/ToolSearch.vue @@ -7,11 +7,15 @@ import { type FilterSettings, type Tool, type ToolSection } from "@/stores/toolS import { useToolStore } from "@/stores/toolStore"; import _l from "@/utils/localization"; +import { type ToolSearchKeys } from "../utilities"; + import DelayedInput from "@/components/Common/DelayedInput.vue"; const router = useRouter(); -const KEYS = { exact: 4, startsWith: 3, name: 2, description: 1, combined: 0 }; +// Note: These are ordered by result priority (exact matches very top; words matches very bottom) +const KEYS: ToolSearchKeys = { exact: 5, startsWith: 4, name: 3, description: 2, combined: 1, wordMatch: 0 }; + const FAVORITES = ["#favs", "#favorites", "#favourites"]; const MIN_QUERY_LENGTH = 3; diff --git a/client/src/components/Panels/Common/ToolSection.test.js b/client/src/components/Panels/Common/ToolSection.test.js index 0790bb125a6d..59324ea02299 100644 --- a/client/src/components/Panels/Common/ToolSection.test.js +++ b/client/src/components/Panels/Common/ToolSection.test.js @@ -1,5 +1,6 @@ import { mount } from "@vue/test-utils"; import { useConfig } from "composables/config"; +import { createPinia } from "pinia"; import { getLocalVue } from "tests/jest/helpers"; import ToolSection from "./ToolSection"; @@ -13,6 +14,11 @@ useConfig.mockReturnValue({ }); const localVue = getLocalVue(); +const pinia = createPinia(); + +function sectionIsOpened(wrapper) { + return wrapper.find("[data-description='opened tool panel section']").exists(); +} describe("ToolSection", () => { test("test tool section", () => { @@ -23,6 +29,7 @@ describe("ToolSection", () => { }, }, localVue, + pinia, }); const nameElement = wrapper.findAll(".name"); expect(nameElement.at(0).text()).toBe("name"); @@ -46,8 +53,9 @@ describe("ToolSection", () => { }, }, localVue, + pinia, }); - expect(wrapper.vm.opened).toBe(false); + expect(sectionIsOpened(wrapper)).toBe(false); const $sectionName = wrapper.find(".name"); expect($sectionName.text()).toBe("tool_section"); await $sectionName.trigger("click"); @@ -76,22 +84,23 @@ describe("ToolSection", () => { queryFilter: "test", }, localVue, + pinia, }); - expect(wrapper.vm.opened).toBe(true); + expect(sectionIsOpened(wrapper)).toBe(true); const $sectionName = wrapper.find(".name"); await $sectionName.trigger("click"); - expect(wrapper.vm.opened).toBe(false); + expect(sectionIsOpened(wrapper)).toBe(false); await wrapper.setProps({ queryFilter: "" }); - expect(wrapper.vm.opened).toBe(false); + expect(sectionIsOpened(wrapper)).toBe(false); await wrapper.setProps({ queryFilter: "test" }); - expect(wrapper.vm.opened).toBe(true); + expect(sectionIsOpened(wrapper)).toBe(true); await wrapper.setProps({ disableFilter: true }); - expect(wrapper.vm.opened).toBe(true); + expect(sectionIsOpened(wrapper)).toBe(true); await wrapper.setProps({ queryFilter: "" }); - expect(wrapper.vm.opened).toBe(false); + expect(sectionIsOpened(wrapper)).toBe(false); await $sectionName.trigger("click"); - expect(wrapper.vm.opened).toBe(true); + expect(sectionIsOpened(wrapper)).toBe(true); await wrapper.setProps({ queryFilter: "test" }); - expect(wrapper.vm.opened).toBe(false); + expect(sectionIsOpened(wrapper)).toBe(false); }); }); diff --git a/client/src/components/Panels/Common/ToolSection.vue b/client/src/components/Panels/Common/ToolSection.vue index 1e3a668944ee..f3d303c881ca 100644 --- a/client/src/components/Panels/Common/ToolSection.vue +++ b/client/src/components/Panels/Common/ToolSection.vue @@ -3,9 +3,8 @@ import { computed, onMounted, onUnmounted, ref, watch } from "vue"; import { eventHub } from "@/components/plugins/eventHub.js"; import { useConfig } from "@/composables/config"; -import { type Tool as ToolType, type ToolSectionLabel as LabelType } from "@/stores/toolStore"; +import { ToolSectionLabel } from "@/stores/toolStore"; import { useToolStore } from "@/stores/toolStore"; -import { type Workflow } from "@/stores/workflowStore"; import ariaAlert from "@/utils/ariaAlert"; import Tool from "./Tool.vue"; @@ -13,8 +12,8 @@ import ToolPanelLabel from "./ToolPanelLabel.vue"; import ToolPanelLinks from "./ToolPanelLinks.vue"; const emit = defineEmits<{ - (e: "onClick", tool: ToolType | Workflow, evt: Event): void; - (e: "onOperation", tool: ToolType | Workflow, evt: Event): void; + (e: "onClick", tool: any, evt: Event): void; + (e: "onOperation", tool: any, evt: Event): void; }>(); const props = defineProps({ @@ -70,7 +69,7 @@ const elems = computed(() => { const tool = toolStore.getToolForId(toolId); if (!tool && toolId.startsWith("panel_label_") && props.category.panel_labels) { const labelId = toolId.split("panel_label_")[1]; - return props.category.panel_labels.find((label: LabelType) => label.id === labelId); + return props.category.panel_labels.find((label: ToolSectionLabel) => label.id === labelId); } else { return tool; } @@ -97,7 +96,7 @@ const sortedElements = computed(() => { isConfigLoaded.value && config.value.toolbox_auto_sort === true && props.sortItems === true && - !elems.value.some((el: ToolType) => el.text !== undefined && el.text !== "") + !elems.value.some((el: ToolSectionLabel) => el.text !== undefined && el.text !== "") ) { const elements = [...elems.value]; const sorted = elements.sort((a, b) => { @@ -150,10 +149,10 @@ function openToolSection(sectionId: string) { function checkFilter() { return !props.disableFilter && !!props.queryFilter; } -function onClick(tool: ToolType | Workflow, evt: Event) { +function onClick(tool: any, evt: Event) { emit("onClick", tool, evt); } -function onOperation(tool: ToolType | Workflow, evt: Event) { +function onOperation(tool: any, evt: Event) { emit("onOperation", tool, evt); } function toggleMenu(nextState = !opened.value) { @@ -175,7 +174,7 @@ function toggleMenu(nextState = !opened.value) { -
+