mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-28 02:58:18 +08:00
Improved index filtering input for workflow list.
This commit is contained in:
@@ -23,14 +23,23 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
incomingValue(val) {
|
||||
if (this.delay === 0) {
|
||||
this.sendUpdate(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
const debounced$ = this.watch$("incomingValue").pipe(
|
||||
debounceTime(this.delay),
|
||||
distinctUntilChanged(),
|
||||
filter((val) => val !== null && val !== this.value),
|
||||
finalize(() => this.sendUpdate(this.incomingValue))
|
||||
);
|
||||
this.$subscribeTo(debounced$, (val) => this.sendUpdate(val));
|
||||
if (this.delay !== 0) {
|
||||
const debounced$ = this.watch$("incomingValue").pipe(
|
||||
debounceTime(this.delay),
|
||||
distinctUntilChanged(),
|
||||
filter((val) => val !== null && val !== this.value),
|
||||
finalize(() => this.sendUpdate(this.incomingValue))
|
||||
);
|
||||
this.$subscribeTo(debounced$, (val) => this.sendUpdate(val));
|
||||
}
|
||||
},
|
||||
render() {
|
||||
return this.$scopedSlots.default({
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<span>
|
||||
<b-input-group>
|
||||
<DebouncedInput :delay="debounceDelay" v-slot="{ value, input }" v-model="localFilter">
|
||||
<b-form-input
|
||||
:id="id"
|
||||
name="query"
|
||||
:value="value"
|
||||
autocomplete="off"
|
||||
:placeholder="placeholder | localize"
|
||||
data-description="filter index input"
|
||||
@input="input"
|
||||
@keyup.esc="onReset" />
|
||||
</DebouncedInput>
|
||||
<b-input-group-append>
|
||||
<b-button data-description="show deleted filter toggle" @click="onHelp" title="Advanced Filtering Help">
|
||||
<icon icon="question" />
|
||||
</b-button>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
<b-modal v-model="showHelp" title="Filtering Options Help" ok-only>
|
||||
<div v-html="helpHtml"></div>
|
||||
</b-modal>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DebouncedInput from "components/DebouncedInput";
|
||||
|
||||
import { BInputGroup, BInputGroupAppend, BButton, BModal } from "bootstrap-vue";
|
||||
|
||||
/**
|
||||
* Component for the search/filter button on the top of Galaxy object index grids.
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
DebouncedInput,
|
||||
BInputGroup,
|
||||
BInputGroupAppend,
|
||||
BButton,
|
||||
BModal,
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
helpHtml: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
debounceDelay: {
|
||||
type: Number,
|
||||
default: 500,
|
||||
},
|
||||
value: {},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showHelp: false,
|
||||
localFilter: this.value,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
this.localFilter = newValue;
|
||||
},
|
||||
localFilter(newVal) {
|
||||
this.$emit("input", newVal);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onHelp() {
|
||||
this.showHelp = true;
|
||||
},
|
||||
onReset() {
|
||||
this.localFilter = "";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,2 @@
|
||||
This directory contains utilities for building out grids and lists for arrays of
|
||||
Galaxy objects coming from the API.
|
||||
@@ -5,14 +5,13 @@
|
||||
<b-alert :variant="messageVariant" :show="showMessage">{{ message }}</b-alert>
|
||||
<b-row class="mb-3">
|
||||
<b-col cols="6">
|
||||
<b-input
|
||||
<index-filter
|
||||
:debounce-delay="inputDebounceDelay"
|
||||
id="workflow-search"
|
||||
class="m-1"
|
||||
name="query"
|
||||
:placeholder="titleSearchWorkflows"
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
v-model="filter" />
|
||||
:help-html="helpHtml"
|
||||
v-model="filter">
|
||||
</index-filter>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<span class="float-right">
|
||||
@@ -116,15 +115,49 @@ import WorkflowDropdown from "./WorkflowDropdown";
|
||||
import UtcDate from "components/UtcDate";
|
||||
import { getGalaxyInstance } from "app";
|
||||
import paginationMixin from "./paginationMixin";
|
||||
import IndexFilter from "components/Indices/IndexFilter";
|
||||
|
||||
library.add(faPlus, faUpload, faSpinner, faGlobe, faShareAlt, farStar, faStar);
|
||||
|
||||
const helpHtml = `<div>
|
||||
<p>This textbox box can be used to filter the workflows displayed.
|
||||
|
||||
<p>Text entered here will be searched against workflow names and tags. Additionally, advanced
|
||||
filtering tags can be used to refine the search more precisely. Tags are of the form
|
||||
<code><tag_name>:<tag_value></code> or <code><tag_name>:'<tag_value>'</code>.
|
||||
For instance to search just for RNAseq in the workflow name, <code>name:rnsseq</code> can be used.
|
||||
Notice by default the search is not case-sensitive.
|
||||
|
||||
If the quoted version of tag is used, the search is not case sensitive and only full matches will be
|
||||
returned. So <code>name:'RNAseq'</code> would show only workflows named exactly <code>RNAseq</code>.
|
||||
|
||||
<p>The available tags are:
|
||||
<dl>
|
||||
<dt><code>name</code></dt>
|
||||
<dd>This filters only against the workflow name.</dd>
|
||||
<dt><code>tag</code></dt>
|
||||
<dd>This filters only against the workflow tag. You may also just click on a tag in your list of workflows to filter on that tag using this directly.</dd>
|
||||
<dt><code>is:published</code></dt>
|
||||
<dd>This filters the workflows such that only published workflows are shown. You may also just click on the "published" icon of a worklfow in your list to filter on this directly.</dd>
|
||||
<dt><code>is:shared</code></dt>
|
||||
<dd>This filters the workflows such that only workflows shared from another user directly with you are are shown. You may also just click on the "shared with me" icon of a worklfow in your list to filter on this directly.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FontAwesomeIcon,
|
||||
UtcDate,
|
||||
Tags,
|
||||
WorkflowDropdown,
|
||||
IndexFilter,
|
||||
},
|
||||
props: {
|
||||
inputDebounceDelay: {
|
||||
type: Number,
|
||||
default: 500,
|
||||
},
|
||||
},
|
||||
mixins: [paginationMixin],
|
||||
data() {
|
||||
@@ -172,6 +205,7 @@ export default {
|
||||
titleRunWorkflow: _l("Run workflow"),
|
||||
workflowItemsModel: [],
|
||||
workflowItems: [],
|
||||
helpHtml: helpHtml,
|
||||
perPage: this.rowsPerPage(50),
|
||||
};
|
||||
},
|
||||
|
||||
@@ -52,7 +52,9 @@ describe("WorkflowList.vue", () => {
|
||||
axiosMock
|
||||
.onGet("/api/workflows", { params: { limit: 50, offset: 0, skip_step_counts: true, search: "" } })
|
||||
.reply(200, mockWorkflowsData, { total_matches: "1" });
|
||||
const propsData = {};
|
||||
const propsData = {
|
||||
inputDebounceDelay: 0,
|
||||
};
|
||||
wrapper = mount(Workflows, {
|
||||
propsData,
|
||||
localVue,
|
||||
@@ -90,8 +92,9 @@ describe("WorkflowList.vue", () => {
|
||||
.onGet("/api/workflows", { params: { limit: 50, offset: 0, skip_step_counts: true, search: "mytext" } })
|
||||
.reply(200, [], { total_matches: "0" });
|
||||
|
||||
wrapper.find("#workflow-search").setValue("mytext");
|
||||
await wrapper.find("#workflow-search").setValue("mytext");
|
||||
flushPromises();
|
||||
expect(wrapper.find("#workflow-search").element.value).toBe("mytext");
|
||||
expect(wrapper.vm.filter).toBe("mytext");
|
||||
});
|
||||
|
||||
|
||||
@@ -566,10 +566,15 @@ class NavigatesGalaxy(HasDriver):
|
||||
return "email" in self.get_logged_in_user()
|
||||
|
||||
@retry_during_transitions
|
||||
def _inline_search_for(self, selector, search_term=None):
|
||||
def _inline_search_for(self, selector, search_term=None, escape_to_clear=False):
|
||||
# Clear tooltip resulting from clicking on the masthead to get here.
|
||||
self.clear_tooltips()
|
||||
search_box = self.wait_for_and_click(selector)
|
||||
if escape_to_clear:
|
||||
# The combination of DebouncedInput+b-input doesn't seem to uniformly respect
|
||||
# .clear() below. We use escape handling a lot - and that does cauase to the input
|
||||
# to reset correctly and fire the required re-active events/handlers.
|
||||
self.send_escape(search_box)
|
||||
search_box.clear()
|
||||
if search_term is not None:
|
||||
search_box.send_keys(search_term)
|
||||
@@ -1218,6 +1223,7 @@ class NavigatesGalaxy(HasDriver):
|
||||
return self._inline_search_for(
|
||||
self.navigation.workflows.search_box,
|
||||
search_term,
|
||||
escape_to_clear=True,
|
||||
)
|
||||
|
||||
def workflow_index_click_import(self):
|
||||
|
||||
Reference in New Issue
Block a user