From 22179d22095fbd1205226620ab2ba68947e9b953 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Wed, 4 Dec 2024 13:42:59 -0600 Subject: [PATCH 1/6] [24.2] Build collection only if populated in collection builder Fixes https://github.com/galaxyproject/galaxy/issues/19243 --- .../Collections/ListCollectionCreator.vue | 16 +++++++++++++++- .../PairedListCollectionCreator.vue | 19 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/client/src/components/Collections/ListCollectionCreator.vue b/client/src/components/Collections/ListCollectionCreator.vue index 17324166aca9..730819ccc588 100644 --- a/client/src/components/Collections/ListCollectionCreator.vue +++ b/client/src/components/Collections/ListCollectionCreator.vue @@ -41,6 +41,7 @@ const invalidElements = ref([]); const workingElements = ref([]); const selectedDatasetElements = ref([]); const hideSourceItems = ref(props.defaultHideSourceItems || false); +const atLeastOneElement = ref(true); const atLeastOneDatasetIsSelected = computed(() => { return selectedDatasetElements.value.length > 0; @@ -232,8 +233,9 @@ function clickedCreate(collectionName: string) { checkForDuplicates(); const returnedElements = props.fromSelection ? workingElements.value : inListElements.value; + atLeastOneElement.value = returnedElements.length > 0; - if (state.value !== "error") { + if (state.value !== "error" && atLeastOneElement.value) { emit("clicked-create", returnedElements, collectionName, hideSourceItems.value); } } @@ -370,6 +372,18 @@ function renameElement(element: any, name: string) { +
+ + {{ localize("At least one element is needed for the list.") }} + + + {{ localize("Cancel") }} + + {{ localize("and reselect new elements.") }} + + +
+
{{ diff --git a/client/src/components/Collections/PairedListCollectionCreator.vue b/client/src/components/Collections/PairedListCollectionCreator.vue index 86e4914cb193..41e37d4d9ae8 100644 --- a/client/src/components/Collections/PairedListCollectionCreator.vue +++ b/client/src/components/Collections/PairedListCollectionCreator.vue @@ -81,6 +81,7 @@ const invalidElements = ref([]); const generatedPairs = ref([]); const selectedForwardElement = ref(null); const selectedReverseElement = ref(null); +const atLeastOnePair = ref(true); // Filters const forwardFilter = ref(COMMON_FILTERS[DEFAULT_FILTER][0] || ""); @@ -751,7 +752,8 @@ function addUploadedFiles(files: HDASummary[]) { async function clickedCreate(collectionName: string) { checkForDuplicates(); - if (state.value == "build") { + atLeastOnePair.value = generatedPairs.value.length > 0; + if (state.value == "build" && atLeastOnePair.value) { emit("clicked-create", generatedPairs.value, collectionName, hideSourceItems.value); } } @@ -827,6 +829,19 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
+ +
+ + {{ localize("At least one pair is needed for the paired list.") }} + + + {{ localize("Cancel") }} + + {{ localize("and reselect new elements.") }} + + +
+
{{ @@ -842,6 +857,7 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
+
{{ @@ -853,6 +869,7 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) { {{ localize("Please fix these duplicates and try again.") }}
+ Date: Wed, 4 Dec 2024 13:43:47 -0600 Subject: [PATCH 2/6] remove commented out duplicate function in paired list creator --- .../PairedListCollectionCreator.vue | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/client/src/components/Collections/PairedListCollectionCreator.vue b/client/src/components/Collections/PairedListCollectionCreator.vue index 41e37d4d9ae8..b2b13d1fd36c 100644 --- a/client/src/components/Collections/PairedListCollectionCreator.vue +++ b/client/src/components/Collections/PairedListCollectionCreator.vue @@ -553,32 +553,6 @@ function _addToUnpaired(dataset: HDASummary) { workingElements.value.splice(binSearchSortedIndex(0, workingElements.value.length), 0, dataset); } -// /** add a dataset to the unpaired list in it's proper order */ -// _addToUnpaired: function (dataset) { -// // currently, unpaired is natural sorted by name, use binary search to find insertion point -// var binSearchSortedIndex = (low, hi) => { -// if (low === hi) { -// return low; -// } - -// var mid = Math.floor((hi - low) / 2) + low; - -// var compared = naturalSort(dataset.name, this.workingElements[mid].name); - -// if (compared < 0) { -// return binSearchSortedIndex(low, mid); -// } else if (compared > 0) { -// return binSearchSortedIndex(mid + 1, hi); -// } -// // walk the equal to find the last -// while (this.workingElements[mid] && this.workingElements[mid].name === dataset.name) { -// mid++; -// } -// return mid; -// }; - -// this.workingElements.splice(binSearchSortedIndex(0, this.workingElements.length), 0, dataset); -// }, /** * Unpair a pair, removing it from paired, and adding the fwd,rev From 1c9e972cbb0ebd529b2a9a836358eacbd670e480 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Wed, 4 Dec 2024 14:41:06 -0600 Subject: [PATCH 3/6] use confirmation dialogue to still allow empty collection creation --- .../Collections/ListCollectionCreator.vue | 15 +++++++++++++-- .../Collections/PairedListCollectionCreator.vue | 17 +++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/client/src/components/Collections/ListCollectionCreator.vue b/client/src/components/Collections/ListCollectionCreator.vue index 730819ccc588..841a206a3635 100644 --- a/client/src/components/Collections/ListCollectionCreator.vue +++ b/client/src/components/Collections/ListCollectionCreator.vue @@ -9,6 +9,7 @@ import { computed, ref, watch } from "vue"; import draggable from "vuedraggable"; import type { HDASummary, HistoryItemSummary } from "@/api"; +import { useConfirmDialog } from "@/composables/confirmDialog"; import { Toast } from "@/composables/toast"; import STATES from "@/mvc/dataset/states"; import { useDatatypesMapperStore } from "@/stores/datatypesMapperStore"; @@ -228,14 +229,24 @@ function clickSelectAll() { return element.id; }); } +const { confirm } = useConfirmDialog(); -function clickedCreate(collectionName: string) { +async function clickedCreate(collectionName: string) { checkForDuplicates(); const returnedElements = props.fromSelection ? workingElements.value : inListElements.value; atLeastOneElement.value = returnedElements.length > 0; - if (state.value !== "error" && atLeastOneElement.value) { + let confirmed = false; + if (!atLeastOneElement.value) { + confirmed = await confirm("Are you sure you want to create a list with no datasets?", { + title: "Create an empty list", + okTitle: "Create", + okVariant: "primary", + }); + } + + if (state.value !== "error" && (atLeastOneElement.value || confirmed)) { emit("clicked-create", returnedElements, collectionName, hideSourceItems.value); } } diff --git a/client/src/components/Collections/PairedListCollectionCreator.vue b/client/src/components/Collections/PairedListCollectionCreator.vue index b2b13d1fd36c..ba46d2139934 100644 --- a/client/src/components/Collections/PairedListCollectionCreator.vue +++ b/client/src/components/Collections/PairedListCollectionCreator.vue @@ -13,6 +13,7 @@ import { computed, ref, watch } from "vue"; import draggable from "vuedraggable"; import type { HDASummary, HistoryItemSummary } from "@/api"; +import { useConfirmDialog } from "@/composables/confirmDialog"; import { Toast } from "@/composables/toast"; import STATES from "@/mvc/dataset/states"; import { useDatatypesMapperStore } from "@/stores/datatypesMapperStore"; @@ -724,10 +725,22 @@ function addUploadedFiles(files: HDASummary[]) { }); } +const { confirm } = useConfirmDialog(); + async function clickedCreate(collectionName: string) { checkForDuplicates(); atLeastOnePair.value = generatedPairs.value.length > 0; - if (state.value == "build" && atLeastOnePair.value) { + + let confirmed = false; + if (!atLeastOnePair.value) { + confirmed = await confirm("Are you sure you want to create a list with no pairs?", { + title: "Create an empty list of pairs", + okTitle: "Create", + okVariant: "primary", + }); + } + + if (state.value == "build" && (atLeastOnePair.value || confirmed)) { emit("clicked-create", generatedPairs.value, collectionName, hideSourceItems.value); } } @@ -806,7 +819,7 @@ function _naiveStartingAndEndingLCS(s1: string, s2: string) {
- {{ localize("At least one pair is needed for the paired list.") }} + {{ localize("At least one pair is needed for the list of pairs.") }} {{ localize("Cancel") }} From 5f8340626bf3d3e39ba7e886d8a08eb3f0f548b6 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Wed, 4 Dec 2024 16:00:53 -0500 Subject: [PATCH 4/6] More protection around redirect cookie handling for psa. Sets expiration to 24h, clears to default if next isn't provided, and clears after use. --- lib/galaxy/webapps/galaxy/controllers/authnz.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/authnz.py b/lib/galaxy/webapps/galaxy/controllers/authnz.py index af7330e5c0c0..f7e3f459ec3f 100644 --- a/lib/galaxy/webapps/galaxy/controllers/authnz.py +++ b/lib/galaxy/webapps/galaxy/controllers/authnz.py @@ -79,7 +79,10 @@ def login(self, trans, provider, idphint=None, next=None): log.debug(msg) return trans.show_error_message(msg) if next: - trans.set_cookie(value=next, name=LOGIN_NEXT_COOKIE_NAME) + trans.set_cookie(value=next, name=LOGIN_NEXT_COOKIE_NAME, age=1) + else: + # If no next parameter is provided, ensure we unset any existing next cookie. + trans.set_cookie(value="/", name=LOGIN_NEXT_COOKIE_NAME) success, message, redirect_uri = trans.app.authnz_manager.authenticate(provider, trans, idphint) if success: return {"redirect_uri": redirect_uri} @@ -138,6 +141,8 @@ def callback(self, trans, provider, idphint=None, **kwargs): trans.handle_user_login(user) # Record which idp provider was logged into, so we can logout of it later trans.set_cookie(value=provider, name=PROVIDER_COOKIE_NAME) + # Clear the login next cookie back to default. + trans.set_cookie(value="/", name=LOGIN_NEXT_COOKIE_NAME) return trans.response.send_redirect(url_for(redirect_url)) @web.expose From 5ee4dfbc32a1e131bbfd222e4dddaa6f672a7cd4 Mon Sep 17 00:00:00 2001 From: John Davis Date: Wed, 4 Dec 2024 19:23:29 -0500 Subject: [PATCH 5/6] Fix version number --- lib/galaxy/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/version.py b/lib/galaxy/version.py index 83b664d1d26f..b6b769c3412e 100644 --- a/lib/galaxy/version.py +++ b/lib/galaxy/version.py @@ -1,3 +1,3 @@ -VERSION_MAJOR = "25.0" -VERSION_MINOR = "dev0" +VERSION_MAJOR = "24.2" +VERSION_MINOR = "rc1" VERSION = VERSION_MAJOR + (f".{VERSION_MINOR}" if VERSION_MINOR else "") From 5909843c2998220bfcca71d26c9a7b2c33e41aa0 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Thu, 5 Dec 2024 17:28:58 -0500 Subject: [PATCH 6/6] Restore dev to version 25.0. --- lib/galaxy/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/version.py b/lib/galaxy/version.py index b6b769c3412e..83b664d1d26f 100644 --- a/lib/galaxy/version.py +++ b/lib/galaxy/version.py @@ -1,3 +1,3 @@ -VERSION_MAJOR = "24.2" -VERSION_MINOR = "rc1" +VERSION_MAJOR = "25.0" +VERSION_MINOR = "dev0" VERSION = VERSION_MAJOR + (f".{VERSION_MINOR}" if VERSION_MINOR else "")