Skip to content

Commit

Permalink
[24.1] Disable state filter for collections in HistoryFilters
Browse files Browse the repository at this point in the history
Adds a `disablesFilters` property to the `ValidFilter` class which allows for the functionality of disabling other filters given certain values for a given filter.

Note: This only works for ranged, input-field and dropdown type filters in the `FilterMenu`

Fixes galaxyproject#18264
  • Loading branch information
ahmedhamidawan committed Jun 4, 2024
1 parent c681c0c commit f3ed250
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 6 deletions.
24 changes: 23 additions & 1 deletion client/src/components/Common/FilterMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { faAngleDoubleUp, faQuestion, faSearch } from "@fortawesome/free-solid-s
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton, BModal, BPopover } from "bootstrap-vue";
import { kebabCase } from "lodash";
import { computed, ref } from "vue";
import { computed, ref, set, watch } from "vue";

Check failure on line 7 in client/src/components/Common/FilterMenu.vue

View workflow job for this annotation

GitHub Actions / client-unit-test (18)

'watch' is defined but never used. Allowed unused vars must match /_.+/u
import type Filtering from "@/utils/filtering";
import { type Alias, type ErrorType, getOperatorForAlias, type ValidFilter } from "@/utils/filtering";
Expand Down Expand Up @@ -91,6 +91,8 @@ const toggleMenuButton = computed(() => {
// Boolean for showing the help modal for the whole filter menu (if provided)
const showHelp = ref(false);
const isDisabled = ref<Record<string, boolean>>({});
const formattedSearchError = computed<ErrorType | null>(() => {
if (props.searchError) {
const { column, col, operation, op, value, val, err_msg, ValueError } = props.searchError;
Expand Down Expand Up @@ -144,6 +146,8 @@ function getValidFilter(filter: string): ValidFilter<any> {
function onOption(filter: string, value: any) {
filters.value[filter] = value;
setDisabled(filter, value);
// for the compact view, we want to immediately search
if (props.view === "compact") {
onSearch();
Expand Down Expand Up @@ -177,6 +181,21 @@ function onToggle() {
emit("update:show-advanced", !props.showAdvanced);
}
function setDisabled(filter: string, newVal: any) {
const disablesFilters = validFilters.value[filter]?.disablesFilters;
const type = validFilters.value[filter]?.type;
if (disablesFilters && type !== Boolean) {
for (const [disabledFilter, disablingValues] of Object.entries(disablesFilters)) {
if (newVal && (disablingValues === null || disablingValues.includes(newVal))) {
set(isDisabled.value, disabledFilter, true);
filters.value[disabledFilter] = undefined;
} else {
set(isDisabled.value, disabledFilter, false);
}
}
}
}
function updateFilterText(newFilterText: string) {
emit("update:filter-text", newFilterText);
}
Expand Down Expand Up @@ -243,6 +262,7 @@ function updateFilterText(newFilterText: string) {
:filters="filters"
:error="formattedSearchError || undefined"
:identifier="identifier"
:disabled="isDisabled[filter] || false"
@change="onOption"
@on-enter="onSearch"
@on-esc="onToggle" />
Expand All @@ -269,6 +289,7 @@ function updateFilterText(newFilterText: string) {
:filter="getValidFilter(filter)"
:filters="filters"
:identifier="identifier"
:disabled="isDisabled[filter] || false"
@change="onOption" />
<FilterMenuInput
v-else-if="validFilters[filter]?.type !== Boolean"
Expand All @@ -277,6 +298,7 @@ function updateFilterText(newFilterText: string) {
:filters="filters"
:error="errorForField(filter) || undefined"
:identifier="identifier"
:disabled="isDisabled[filter] || false"
@change="onOption"
@on-enter="onSearch"
@on-esc="onToggle" />
Expand Down
6 changes: 5 additions & 1 deletion client/src/components/Common/FilterMenuDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface Props {
[k: string]: FilterValue;
};
identifier: string;
disabled?: boolean;
}
const props = defineProps<Props>();
Expand Down Expand Up @@ -76,7 +77,9 @@ const helpToggle = ref(false);
const modalTitle = `${capitalize(props.filter.placeholder)} Help`;
function onHelp(_: string, value: string) {
helpToggle.value = false;
localValue.value = value;
if (!props.disabled) {
localValue.value = value;
}
}
// Quota Source refs and operations
Expand Down Expand Up @@ -140,6 +143,7 @@ function setValue(val: string | QuotaUsage | undefined) {
menu-class="w-100"
size="sm"
boundary="window"
:disabled="props.disabled"
:toggle-class="props.error ? 'text-danger' : ''">
<BDropdownItem href="#" @click="setValue(undefined)"><i>(any)</i></BDropdownItem>

Expand Down
11 changes: 9 additions & 2 deletions client/src/components/Common/FilterMenuInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface Props {
filters: {
[k: string]: FilterType;
};
disabled?: boolean;
}
const props = defineProps<Props>();
Expand All @@ -47,14 +48,18 @@ const modalTitle = `${capitalize(props.filter.placeholder)} Help`;
function onHelp(_: string, value: string) {
helpToggle.value = false;
localValue.value = value;
if (!props.disabled) {
localValue.value = value;
}
}
watch(
() => localValue.value,
(newFilter) => {
emit("change", props.name, newFilter);
}
},
{ immediate: true }
);
watch(
Expand All @@ -79,6 +84,7 @@ watch(
size="sm"
:state="props.error ? false : null"
:placeholder="`any ${props.filter.placeholder}`"
:disabled="props.disabled"
:list="props.filter.datalist ? `${identifier}-${props.name}-selectList` : null"
@keyup.enter="emit('on-enter')"
@keyup.esc="emit('on-esc')" />
Expand All @@ -99,6 +105,7 @@ watch(
v-model="localValue"
reset-button
button-only
:disabled="props.disabled"
size="sm" />
</BInputGroupAppend>
</BInputGroup>
Expand Down
7 changes: 5 additions & 2 deletions client/src/components/Common/FilterMenuRanged.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface Props {
filters: {
[k: string]: FilterType;
};
disabled?: boolean;
}
const props = defineProps<Props>();
Expand Down Expand Up @@ -93,11 +94,12 @@ watch(
size="sm"
:state="hasError(localNameGt) ? false : null"
:placeholder="localPlaceholder('gt')"
:disabled="props.disabled"
@keyup.enter="emit('on-enter')"
@keyup.esc="emit('on-esc')" />

<BInputGroupAppend v-if="isDateType">
<BFormDatepicker v-model="localValueGt" reset-button button-only size="sm" />
<BFormDatepicker v-model="localValueGt" reset-button button-only size="sm" :disabled="props.disabled" />
</BInputGroupAppend>
<!--------------------------------------------------------------------->

Expand All @@ -109,11 +111,12 @@ watch(
size="sm"
:state="hasError(localNameLt) ? false : null"
:placeholder="localPlaceholder('lt')"
:disabled="props.disabled"
@keyup.enter="emit('on-enter')"
@keyup.esc="emit('on-esc')" />

<BInputGroupAppend v-if="isDateType">
<BFormDatepicker v-model="localValueLt" reset-button button-only size="sm" />
<BFormDatepicker v-model="localValueLt" reset-button button-only size="sm" :disabled="props.disabled" />
</BInputGroupAppend>
<!--------------------------------------------------------------------->
</BInputGroup>
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/History/Content/model/StatesInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ function onFilter(value: string) {
(Note that the colors for each state correspond to content item state colors in the history, and if it
exists, hovering over the icon on a history item will display the state message.)
</i>
<br />
<b>You cannot filter a history for collections given a state.</b>
</p>
<dl v-for="(state, key, index) in states" :key="index">
<div :class="['alert', 'content-item', 'alert-' + state.status]" :data-state="dataState(key)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ function setItemDragstart(

<FilterMenu
v-if="filterable"
:key="props.history.id"
class="content-operations-filters mx-3"
name="History Items"
placeholder="search datasets"
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/History/HistoryFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const validFilters = {
{ value: "dataset_collection", text: "Collections Only" },
],
menuItem: true,
disablesFilters: { state: ["dataset_collection"] },
},
tag: { placeholder: "tag", type: String, handler: contains("tags", "tag", expandNameTag), menuItem: true },
state: {
Expand All @@ -35,6 +36,7 @@ const validFilters = {
datalist: states,
helpInfo: StatesInfo,
menuItem: true,
disablesFilters: { history_content_type: null },
},
genome_build: { placeholder: "database", type: String, handler: contains("genome_build"), menuItem: true },
genome_build_eq: { handler: equals("genome_build"), menuItem: false },
Expand Down
6 changes: 6 additions & 0 deletions client/src/utils/filtering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ export type ValidFilter<T> = {
helpInfo?: DefineComponent | string;
/** A default value (will make this a default filter for an empty `filterText`) */
default?: T;
/** A dict of filters and corresponding values for this filter that disable them.
* Note: if value is null, the filter is disabled for any value of this filter.
*/
disablesFilters?: {
[filter: string]: T[] | null;
};
};

/** Converts user input to backend compatible date
Expand Down

0 comments on commit f3ed250

Please sign in to comment.