diff --git a/client/src/components/Grid/GridList.vue b/client/src/components/Grid/GridList.vue
index 42ce5ca1e9cb..8c73ba0e5d44 100644
--- a/client/src/components/Grid/GridList.vue
+++ b/client/src/components/Grid/GridList.vue
@@ -82,7 +82,8 @@ const filterClass = props.gridConfig.filtering;
const rawFilters = computed(() => Object.fromEntries(filterClass.getFiltersForText(filterText.value, true, false)));
const validFilters = computed(() => filterClass.getValidFilters(rawFilters.value, true).validFilters);
const invalidFilters = computed(() => filterClass.getValidFilters(rawFilters.value, true).invalidFilters);
-const hasInvalidFilters = computed(() => Object.keys(invalidFilters.value).length > 0);
+const isSurroundedByQuotes = computed(() => /^["'].*["']$/.test(filterText.value));
+const hasInvalidFilters = computed(() => !isSurroundedByQuotes.value && Object.keys(invalidFilters.value).length > 0);
// hide message helper
const hideMessage = useDebounceFn(() => {
@@ -221,8 +222,11 @@ function onSelectAll(current: boolean): void {
* A valid filter/query for the backend
*/
function validatedFilterText() {
- // there are no filters derived from the `filterText`; return the `filterText` as is
- if (Object.keys(rawFilters.value).length === 0) {
+ if (isSurroundedByQuotes.value) {
+ // the filterText is surrounded by quotes, remove them
+ return filterText.value.slice(1, -1);
+ } else if (Object.keys(rawFilters.value).length === 0) {
+ // there are no filters derived from the `filterText`
return filterText.value;
}
// there are valid filters derived from the `filterText`
@@ -311,6 +315,15 @@ watch(operationMessage, () => {
Remove invalid filters from query
+ or
+
+ Match the exact query provided
+
diff --git a/client/src/components/Workflow/WorkflowList.vue b/client/src/components/Workflow/WorkflowList.vue
index 85b93caeb86f..45a1b9dee14d 100644
--- a/client/src/components/Workflow/WorkflowList.vue
+++ b/client/src/components/Workflow/WorkflowList.vue
@@ -57,7 +57,7 @@ const searchPlaceHolder = computed(() => {
placeHolder = "Search workflows shared with me";
}
- placeHolder += " by name or use the advanced filtering options";
+ placeHolder += " by query or use the advanced filtering options";
return placeHolder;
});
@@ -72,13 +72,15 @@ const sortBy = computed(() => (listHeader.value && listHeader.value.sortBy) || "
const noItems = computed(() => !loading.value && workflowsLoaded.value.length === 0 && !filterText.value);
const noResults = computed(() => !loading.value && workflowsLoaded.value.length === 0 && filterText.value);
+// Filtering computed refs
const workflowFilters = computed(() => WorkflowFilters(props.activeList));
const rawFilters = computed(() =>
Object.fromEntries(workflowFilters.value.getFiltersForText(filterText.value, true, false))
);
const validFilters = computed(() => workflowFilters.value.getValidFilters(rawFilters.value, true).validFilters);
const invalidFilters = computed(() => workflowFilters.value.getValidFilters(rawFilters.value, true).invalidFilters);
-const hasInvalidFilters = computed(() => Object.keys(invalidFilters.value).length > 0);
+const isSurroundedByQuotes = computed(() => /^["'].*["']$/.test(filterText.value));
+const hasInvalidFilters = computed(() => !isSurroundedByQuotes.value && Object.keys(invalidFilters.value).length > 0);
function updateFilterValue(filterKey: string, newValue: any) {
const currentFilterText = filterText.value;
@@ -155,8 +157,11 @@ async function onPageChange(page: number) {
}
function validatedFilterText() {
- // there are no filters derived from the `filterText`
- if (Object.keys(rawFilters.value).length === 0) {
+ if (isSurroundedByQuotes.value) {
+ // the `filterText` is surrounded by quotes, remove them
+ return filterText.value.slice(1, -1);
+ } else if (Object.keys(rawFilters.value).length === 0) {
+ // there are no filters derived from the `filterText`
return filterText.value;
}
// there are valid filters derived from the `filterText`
@@ -277,6 +282,15 @@ onMounted(() => {
Remove invalid filters from query
+ or
+
+ Match the exact query provided
+
diff --git a/test/integration_selenium/test_trs_import.py b/test/integration_selenium/test_trs_import.py
index 7d6f4395227a..d6031a805377 100644
--- a/test/integration_selenium/test_trs_import.py
+++ b/test/integration_selenium/test_trs_import.py
@@ -49,7 +49,8 @@ def trs_config_dir(cls):
return cls.temp_config_dir("trs")
def assert_workflow_imported(self, name):
- self.workflow_index_search_for(name)
+ # surround name with quotes to consider case where name contains colons
+ self.workflow_index_search_for(f'"{name}"')
assert len(self.workflow_card_elements()) == 1, f"workflow ${name} not imported"
def test_import_workflow_by_url_dockstore(self):