Skip to content

Commit 5da2f30

Browse files
add keydown handling to GFormInput; use it and GLink in ontology view
1 parent 1c18444 commit 5da2f30

3 files changed

Lines changed: 38 additions & 21 deletions

File tree

client/src/components/BaseComponents/Form/GFormInput.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const props = defineProps<{
77
88
const emit = defineEmits<{
99
(e: "input", value: string | null): void;
10+
(e: "keydown", event: KeyboardEvent): void;
1011
}>();
1112
1213
const inputValue = computed({
@@ -20,7 +21,7 @@ const inputValue = computed({
2021
</script>
2122

2223
<template>
23-
<input v-model="inputValue" class="g-form-input" />
24+
<input v-model="inputValue" class="g-form-input" @keydown="(event) => emit('keydown', event)" />
2425
</template>
2526

2627
<style scoped lang="scss">

client/src/components/Common/DelayedInput.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ watch(
7070
() => delayQuery(queryInput.value ?? ""),
7171
);
7272
73-
function clearBox() {
74-
queryInput.value = "";
75-
toolInput.value?.focus();
73+
function clearBox(event?: KeyboardEvent) {
74+
if (!event || event.key === "Escape") {
75+
queryInput.value = "";
76+
toolInput.value?.focus();
77+
}
7678
}
7779
7880
function onToggle() {
@@ -96,7 +98,7 @@ watchImmediate(
9698
autocomplete="off"
9799
:placeholder="placeholder"
98100
data-description="filter text input"
99-
@keydown.esc="clearBox" />
101+
@keydown="clearBox" />
100102

101103
<BInputGroupAppend>
102104
<GButton
@@ -120,7 +122,7 @@ watchImmediate(
120122
size="small"
121123
:title="localize(titleClear)"
122124
data-description="reset query"
123-
@click="clearBox">
125+
@click="clearBox(undefined)">
124126
<FontAwesomeIcon v-if="loading" fixed-width :icon="faSpinner" spin />
125127
<FontAwesomeIcon v-else fixed-width :icon="faTimes" />
126128
</GButton>

client/src/components/ToolsList/ToolOntologies.vue

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<script setup lang="ts">
22
import { faExternalLinkAlt, faFilter, faSortAlphaDown, faSortAlphaUp } from "@fortawesome/free-solid-svg-icons";
33
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
4-
import { BAlert, BBadge, BDropdown, BDropdownItem, BFormInput } from "bootstrap-vue";
4+
import { BAlert, BBadge, BDropdown, BDropdownItem } from "bootstrap-vue";
55
import { computed, ref, watch } from "vue";
66
77
import { type ToolSection, useToolStore } from "@/stores/toolStore";
88
import { errorMessageAsString } from "@/utils/simple-error";
99
1010
import { searchSections } from "../Panels/utilities";
1111
12+
import GFormInput from "../BaseComponents/Form/GFormInput.vue";
13+
import GLink from "../BaseComponents/GLink.vue";
1214
import ToolOntologyCard from "./ToolOntologyCard.vue";
1315
import GButton from "@/components/BaseComponents/GButton.vue";
1416
import BreadcrumbHeading from "@/components/Common/BreadcrumbHeading.vue";
@@ -73,17 +75,23 @@ const filtered = computed<{
7375
7476
const shownOntologies = computed(() => filtered.value.sections.slice(0, currentOffset.value));
7577
78+
/** A datalist for the search input, only rendered if the query is longer than 4 characters
79+
* _(otherwise it gets in the way)_.
80+
*/
7681
const ontologyDatalist = computed(() => {
77-
switch (showing.value) {
78-
case "topics":
79-
return toolStore.sectionDatalist("ontology:edam_topics");
80-
case "operations":
81-
return toolStore.sectionDatalist("ontology:edam_operations");
82-
default:
83-
return toolStore
84-
.sectionDatalist("ontology:edam_topics")
85-
.concat(toolStore.sectionDatalist("ontology:edam_operations"));
82+
if (ontologiesFilter.value.length > 4) {
83+
switch (showing.value) {
84+
case "topics":
85+
return toolStore.sectionDatalist("ontology:edam_topics");
86+
case "operations":
87+
return toolStore.sectionDatalist("ontology:edam_operations");
88+
default:
89+
return toolStore
90+
.sectionDatalist("ontology:edam_topics")
91+
.concat(toolStore.sectionDatalist("ontology:edam_operations"));
92+
}
8693
}
94+
return [];
8795
});
8896
8997
ensureOntologiesLoaded();
@@ -111,6 +119,12 @@ function changeSort() {
111119
}
112120
}
113121
122+
function clearIfEsc(event: KeyboardEvent) {
123+
if (event.key === "Escape") {
124+
ontologiesFilter.value = "";
125+
}
126+
}
127+
114128
/** Since we can have a massive list of ontologies, we use this method to paginate */
115129
async function loadMore(_: number, limit: number) {
116130
currentOffset.value += limit;
@@ -129,11 +143,11 @@ watch([ontologiesFilter, sortOrder, showing], async () => {
129143
<div class="d-flex flex-column flex-gapy-1 mb-2">
130144
<BreadcrumbHeading :items="breadcrumbItems" />
131145

132-
<BFormInput
146+
<GFormInput
133147
v-model="ontologiesFilter"
134-
type="text"
135148
placeholder="Filter ontologies"
136-
list="ontology-list-datalist" />
149+
list="ontology-list-datalist"
150+
@keydown="clearIfEsc" />
137151
<datalist v-if="ontologyDatalist.length" id="ontology-list-datalist">
138152
<option v-for="data in ontologyDatalist" :key="data.value" :label="data.text" :value="data.text" />
139153
</datalist>
@@ -145,9 +159,9 @@ watch([ontologiesFilter, sortOrder, showing], async () => {
145159
<BBadge v-else-if="filtered.closestTerm" class="alert-danger w-100">
146160
Did you mean:
147161
<i>
148-
<a href="javascript:void(0)" @click="ontologiesFilter = filtered.closestTerm">
162+
<GLink thin @click="ontologiesFilter = filtered.closestTerm">
149163
{{ filtered.closestTerm }}
150-
</a>
164+
</GLink>
151165
</i>
152166
?
153167
</BBadge>

0 commit comments

Comments
 (0)