Skip to content

Commit

Permalink
Merge branch 'release_24.1' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
mvdbeek committed Jun 6, 2024
2 parents ec17295 + 4966062 commit 1865c43
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 26 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 } from "vue";
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
4 changes: 4 additions & 0 deletions client/src/components/Common/Heading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ const element = computed(() => {
<style lang="scss" scoped>
@import "scss/theme/blue.scss";
.heading {
word-break: break-all;
}
.heading:deep(svg) {
font-size: 0.75em;
}
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/Form/_form-elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
word-wrap: break-word;
font-weight: bold;

.ui-form-title-text {
word-break: break-all;
}

.ui-form-title-message {
font-size: $font-size-base * 0.7;
font-weight: 300;
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: 2 additions & 4 deletions client/src/components/Sharing/EditableUrl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,9 @@ function onCopyOut() {
@import "theme/blue.scss";
.editable-url {
height: 1.5rem;
display: flex;
align-items: center;
gap: 0.25rem;
word-break: break-all;
}
.inline-icon-button:disabled:hover {
background-color: $brand-secondary;
color: unset;
Expand Down
4 changes: 4 additions & 0 deletions client/src/style/scss/overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ button {
overflow: auto;
}

.modal-title {
word-break: break-all;
}

// Tabs -- border color is hardcoded in navs.scss, change to $btnBorder here

.nav-tabs {
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
2 changes: 1 addition & 1 deletion lib/galaxy/managers/citations.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def to_bibtex(self):
try:
self.raw_bibtex = self.doi_cache.get_bibtex(self.__doi)
except Exception:
log.exception("Failed to fetch bibtex for DOI %s", self.__doi)
log.debug("Failed to fetch bibtex for DOI %s", self.__doi)

if self.raw_bibtex is DoiCitation.BIBTEX_UNSET:
return f"""@MISC{{{self.__doi},
Expand Down
3 changes: 3 additions & 0 deletions lib/galaxy/schema/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ class LimitedUserModel(Model):
email: Optional[str] = None


MaybeLimitedUserModel = Union[UserModel, LimitedUserModel]


class DiskUsageUserModel(Model):
total_disk_usage: float = TotalDiskUsageField
nice_total_disk_usage: str = NiceTotalDiskUsageField
Expand Down
4 changes: 4 additions & 0 deletions lib/galaxy/webapps/base/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,10 @@ def get_or_create_default_history(self):
self.set_history(history)
return history

# Don't create new history if login required and user is anonymous
if self.app.config.require_login and not self.user:
return None

# No suitable history found, create a new one.
return self.new_history()

Expand Down
7 changes: 3 additions & 4 deletions lib/galaxy/webapps/galaxy/api/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@
FavoriteObjectsSummary,
FavoriteObjectType,
FlexibleUserIdType,
LimitedUserModel,
MaybeLimitedUserModel,
RemoteUserCreationPayload,
UserBeaconSetting,
UserCreationPayload,
UserDeletionPayload,
UserModel,
)
from galaxy.security.validate_user_input import (
validate_email,
Expand Down Expand Up @@ -203,7 +202,7 @@ def index_deleted(
f_email: Optional[str] = FilterEmailQueryParam,
f_name: Optional[str] = FilterNameQueryParam,
f_any: Optional[str] = FilterAnyQueryParam,
) -> List[Union[UserModel, LimitedUserModel]]:
) -> List[MaybeLimitedUserModel]:
return self.service.get_index(trans=trans, deleted=True, f_email=f_email, f_name=f_name, f_any=f_any)

@router.post(
Expand Down Expand Up @@ -651,7 +650,7 @@ def index(
f_email: Optional[str] = FilterEmailQueryParam,
f_name: Optional[str] = FilterNameQueryParam,
f_any: Optional[str] = FilterAnyQueryParam,
) -> List[Union[UserModel, LimitedUserModel]]:
) -> List[MaybeLimitedUserModel]:
return self.service.get_index(trans=trans, deleted=deleted, f_email=f_email, f_name=f_name, f_any=f_any)

@router.get(
Expand Down
23 changes: 12 additions & 11 deletions lib/galaxy/webapps/galaxy/services/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
DetailedUserModel,
FlexibleUserIdType,
LimitedUserModel,
MaybeLimitedUserModel,
UserModel,
)
from galaxy.security.idencoding import IdEncodingHelper
Expand Down Expand Up @@ -204,8 +205,8 @@ def get_index(
f_email: Optional[str],
f_name: Optional[str],
f_any: Optional[str],
) -> List[Union[UserModel, LimitedUserModel]]:
rval = []
) -> List[MaybeLimitedUserModel]:
rval: List[MaybeLimitedUserModel] = []
stmt = select(User)

if f_email and (trans.user_is_admin or trans.app.config.expose_user_email):
Expand Down Expand Up @@ -240,13 +241,12 @@ def get_index(
and not trans.app.config.expose_user_email
):
if trans.user:
item = trans.user.to_dict()
return [item]
return [UserModel(**trans.user.to_dict())]
else:
return []
stmt = stmt.filter(User.deleted == false())
for user in trans.sa_session.scalars(stmt).all():
item = user.to_dict()
user_dict = user.to_dict()
# If NOT configured to expose_email, do not expose email UNLESS the user is self, or
# the user is an admin
if user is not trans.user and not trans.user_is_admin:
Expand All @@ -255,12 +255,13 @@ def get_index(
expose_keys.append("username")
if trans.app.config.expose_user_email:
expose_keys.append("email")
new_item = {}
for key, value in item.items():
limited_user = {}
for key, value in user_dict.items():
if key in expose_keys:
new_item[key] = value
item = new_item
limited_user[key] = value
user = LimitedUserModel(**limited_user)
else:
user = UserModel(**user_dict)

# TODO: move into api_values
rval.append(item)
rval.append(user)
return rval
Loading

0 comments on commit 1865c43

Please sign in to comment.