mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-11-04 23:43:20 +08:00
Merge branch 'release_24.0' into dev
This commit is contained in:
@@ -18,6 +18,8 @@ const rerunUrl = computed(() =>
|
||||
const showCollectionDetailsUrl = computed(() =>
|
||||
props.dsc.job_source_type == "Job" ? `/jobs/${props.dsc.job_source_id}/view` : null
|
||||
);
|
||||
const disableDownload = props.dsc.populated_state !== "ok";
|
||||
|
||||
function onDownload() {
|
||||
window.location.href = downloadUrl.value;
|
||||
}
|
||||
@@ -28,6 +30,7 @@ function onDownload() {
|
||||
<b-button-group>
|
||||
<b-button
|
||||
title="Download Collection"
|
||||
:disabled="disableDownload"
|
||||
class="rounded-0 text-decoration-none"
|
||||
size="sm"
|
||||
variant="link"
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ref } from "vue";
|
||||
import { useRouter } from "vue-router/composables";
|
||||
|
||||
import { withPrefix } from "@/utils/redirect";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
|
||||
interface Props {
|
||||
token?: string;
|
||||
@@ -36,8 +37,7 @@ async function submit() {
|
||||
router.push("/");
|
||||
} catch (error: any) {
|
||||
variant.value = "danger";
|
||||
const errMsg = error.response && error.response.data && error.response.data.err_msg;
|
||||
message.value = errMsg || "Password change failed for an unknown reason.";
|
||||
message.value = errorMessageAsString(error, "Password change failed for an unknown reason.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import axios, { type AxiosError } from "axios";
|
||||
import axios from "axios";
|
||||
import {
|
||||
BAlert,
|
||||
BButton,
|
||||
@@ -18,6 +18,7 @@ import { useRouter } from "vue-router/composables";
|
||||
|
||||
import localize from "@/utils/localization";
|
||||
import { withPrefix } from "@/utils/redirect";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
|
||||
import NewUserConfirmation from "@/components/Login/NewUserConfirmation.vue";
|
||||
import ExternalLogin from "@/components/User/ExternalIdentities/ExternalLogin.vue";
|
||||
@@ -106,14 +107,13 @@ async function submitLogin() {
|
||||
}
|
||||
} catch (e) {
|
||||
loading.value = false;
|
||||
const error = e as AxiosError<{ err_msg?: string }>;
|
||||
messageVariant.value = "danger";
|
||||
const message = error.response && error.response.data && error.response.data.err_msg;
|
||||
const message = errorMessageAsString(e, "Login failed for an unknown reason.");
|
||||
|
||||
if (connectExternalProvider.value && message && message.toLowerCase().includes("invalid")) {
|
||||
messageText.value = message + " Try logging in to the existing account through an external provider below.";
|
||||
} else {
|
||||
messageText.value = message || "Login failed for an unknown reason.";
|
||||
messageText.value = message;
|
||||
}
|
||||
if (message === "Invalid password.") {
|
||||
passwordState.value = false;
|
||||
@@ -132,10 +132,8 @@ async function resetLogin() {
|
||||
messageVariant.value = "info";
|
||||
messageText.value = response.data.message;
|
||||
} catch (e) {
|
||||
const error = e as AxiosError<{ err_msg?: string }>;
|
||||
messageVariant.value = "danger";
|
||||
const errMsg = error.response?.data && error.response.data.err_msg;
|
||||
messageText.value = errMsg || "Password reset failed for an unknown reason.";
|
||||
messageText.value = errorMessageAsString(e, "Password reset failed for an unknown reason.");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ref } from "vue";
|
||||
import { useRouter } from "vue-router/composables";
|
||||
|
||||
import { withPrefix } from "@/utils/redirect";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
|
||||
interface Props {
|
||||
termsUrl?: string;
|
||||
@@ -58,8 +59,7 @@ async function submit() {
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageVariant.value = "danger";
|
||||
const errMsg = error.response.data && error.response.data.err_msg;
|
||||
messageText.value = errMsg || "Login failed for an unknown reason.";
|
||||
messageText.value = errorMessageAsString(error, "Login failed for an unknown reason.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { computed, ref } from "vue";
|
||||
import { Toast } from "@/composables/toast";
|
||||
import localize from "@/utils/localization";
|
||||
import { withPrefix } from "@/utils/redirect";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
|
||||
import ExternalLogin from "@/components/User/ExternalIdentities/ExternalLogin.vue";
|
||||
|
||||
@@ -81,8 +82,7 @@ async function submit() {
|
||||
window.location.href = props.redirect || withPrefix("/");
|
||||
} catch (error: any) {
|
||||
disableCreate.value = false;
|
||||
const errMsg = error.response.data && error.response.data.err_msg;
|
||||
messageText.value = errMsg || "Registration failed for an unknown reason.";
|
||||
messageText.value = errorMessageAsString(error, "Registration failed for an unknown reason.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -215,7 +215,6 @@ async function submit() {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.embed-container {
|
||||
position: relative;
|
||||
|
||||
@@ -13,7 +13,7 @@ type WorkflowLabelKind = "input" | "output" | "step";
|
||||
const SINGLE_QUOTE = "'";
|
||||
const DOUBLE_QUOTE = '"';
|
||||
|
||||
export function splitMarkdown(markdown: string, preserveWhitespace: boolean = false) {
|
||||
export function splitMarkdown(markdown: string, preserveWhitespace = false) {
|
||||
const sections: Section[] = [];
|
||||
const markdownErrors = [];
|
||||
let digest = markdown;
|
||||
|
||||
@@ -186,19 +186,14 @@ export function usePopperjs(
|
||||
|
||||
case "hover": {
|
||||
on(referenceRef.value!, "mouseover", doMouseover);
|
||||
on(popperRef.value!, "mouseover", doMouseover);
|
||||
on(referenceRef.value!, "mouseout", doMouseout);
|
||||
on(popperRef.value!, "mouseout", doMouseout);
|
||||
on(referenceRef.value!, "mousedown", doMouseout);
|
||||
on(popperRef.value!, "mousedown", doMouseout);
|
||||
break;
|
||||
}
|
||||
|
||||
case "focus": {
|
||||
on(referenceRef.value!, "focus", doOpen);
|
||||
on(popperRef.value!, "focus", doOpen);
|
||||
on(referenceRef.value!, "blur", doClose);
|
||||
on(popperRef.value!, "blur", doClose);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -218,16 +213,11 @@ export function usePopperjs(
|
||||
off(referenceRef.value!, "click", doToggle);
|
||||
|
||||
off(referenceRef.value!, "mouseover", doMouseover);
|
||||
off(popperRef.value!, "mouseover", doMouseover);
|
||||
off(referenceRef.value!, "mouseout", doMouseout);
|
||||
off(popperRef.value!, "mouseout", doMouseout);
|
||||
off(referenceRef.value!, "mousedown", doMouseout);
|
||||
off(popperRef.value!, "mousedown", doMouseout);
|
||||
|
||||
off(referenceRef.value!, "focus", doOpen);
|
||||
off(popperRef.value!, "focus", doOpen);
|
||||
off(referenceRef.value!, "blur", doClose);
|
||||
off(popperRef.value!, "blur", doClose);
|
||||
};
|
||||
const doCloseForDocument = (e: Event) => {
|
||||
if (referenceRef.value?.contains(e.target as Element)) {
|
||||
|
||||
@@ -35,7 +35,7 @@ export async function fetchAllHistoriesSizeSummary(): Promise<ItemSizeSummary[]>
|
||||
|
||||
export async function fetchHistoryContentsSizeSummary(
|
||||
historyId: string,
|
||||
limit: number = 5000,
|
||||
limit = 5000,
|
||||
objectStoreId: string | null = null
|
||||
) {
|
||||
const q = ["purged", "history_content_type"];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import axios, { type AxiosError } from "axios";
|
||||
import { BAlert, BButton, BForm, BFormCheckbox, BFormGroup } from "bootstrap-vue";
|
||||
import { errorMessageAsString } from "utils/simple-error";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import Multiselect from "vue-multiselect";
|
||||
|
||||
@@ -82,10 +83,8 @@ async function submitOIDCLogin(idp: string) {
|
||||
window.location = data.redirect_uri;
|
||||
}
|
||||
} catch (e) {
|
||||
const error = e as AxiosError<{ err_msg?: string }>;
|
||||
messageVariant.value = "danger";
|
||||
const message = error.response?.data && error.response.data.err_msg;
|
||||
messageText.value = message || "Login failed for an unknown reason.";
|
||||
messageText.value = errorMessageAsString(e, "Login failed for an unknown reason.");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@@ -113,10 +112,8 @@ async function submitCILogon(idp: string | null) {
|
||||
window.location = data.redirect_uri;
|
||||
}
|
||||
} catch (e) {
|
||||
const error = e as AxiosError<{ err_msg?: string }>;
|
||||
messageVariant.value = "danger";
|
||||
const message = error.response?.data && error.response.data.err_msg;
|
||||
messageText.value = message || "Login failed for an unknown reason.";
|
||||
messageText.value = errorMessageAsString(e, "Login failed for an unknown reason.");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
@@ -392,17 +392,18 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
function resetStores() {
|
||||
async function resetStores() {
|
||||
hasChanges.value = false;
|
||||
connectionStore.$reset();
|
||||
stepStore.$reset();
|
||||
stateStore.$reset();
|
||||
commentStore.$reset();
|
||||
undoRedoStore.$reset();
|
||||
await nextTick();
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
resetStores();
|
||||
onUnmounted(async () => {
|
||||
await resetStores();
|
||||
emit("update:confirmation", false);
|
||||
});
|
||||
|
||||
@@ -574,7 +575,7 @@ export default {
|
||||
hide_modal(); // hide other modals created in utilities also...
|
||||
},
|
||||
async onRefactor(response) {
|
||||
this.resetStores();
|
||||
await this.resetStores();
|
||||
await fromSimple(this.id, response.workflow);
|
||||
this._loadEditorData(response.workflow);
|
||||
},
|
||||
@@ -887,7 +888,7 @@ export default {
|
||||
},
|
||||
async _loadCurrent(id, version) {
|
||||
if (!this.isNewTempWorkflow) {
|
||||
this.resetStores();
|
||||
await this.resetStores();
|
||||
this.onWorkflowMessage("Loading workflow...", "progress");
|
||||
|
||||
try {
|
||||
|
||||
@@ -167,7 +167,7 @@ class InvenioRDMFilesSource(RDMFilesSource):
|
||||
record = self.repository.create_draft_record(entry_data["name"], public_name, user_context=user_context)
|
||||
return {
|
||||
"uri": self.repository.to_plugin_uri(record["id"]),
|
||||
"name": record["metadata"]["title"],
|
||||
"name": record["title"],
|
||||
"external_link": record["links"]["self_html"],
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
|
||||
response = requests.post(self.records_url, json=create_record_request, headers=headers)
|
||||
self._ensure_response_has_expected_status_code(response, 201)
|
||||
record = response.json()
|
||||
record["title"] = self._get_record_title(record)
|
||||
return record
|
||||
|
||||
def upload_file_to_draft_record(
|
||||
@@ -359,16 +360,23 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
|
||||
for record in records:
|
||||
uri = self.to_plugin_uri(record_id=record["id"])
|
||||
path = self.plugin.to_relative_path(uri)
|
||||
name = self._get_record_title(record)
|
||||
rval.append(
|
||||
{
|
||||
"class": "Directory",
|
||||
"name": record["metadata"]["title"],
|
||||
"name": name,
|
||||
"uri": uri,
|
||||
"path": path,
|
||||
}
|
||||
)
|
||||
return rval
|
||||
|
||||
def _get_record_title(self, record: InvenioRecord) -> str:
|
||||
title = record.get("title")
|
||||
if not title and "metadata" in record:
|
||||
title = record["metadata"].get("title")
|
||||
return title or "No title"
|
||||
|
||||
def _get_record_files_from_response(self, record_id: str, response: dict) -> List[RemoteFile]:
|
||||
files_enabled = response.get("enabled", False)
|
||||
if not files_enabled:
|
||||
|
||||
@@ -9,6 +9,7 @@ import logging
|
||||
from typing import Dict
|
||||
|
||||
from galaxy import model
|
||||
from galaxy.exceptions import RequestParameterInvalidException
|
||||
from galaxy.managers import (
|
||||
annotatable,
|
||||
base,
|
||||
@@ -40,6 +41,8 @@ def stream_dataset_collection(dataset_collection_instance, upstream_mod_zip=Fals
|
||||
|
||||
|
||||
def write_dataset_collection(dataset_collection_instance, archive):
|
||||
if not dataset_collection_instance.collection.populated_optimized:
|
||||
raise RequestParameterInvalidException("Attempt to write dataset collection that has not been populated yet")
|
||||
names, hdas = get_hda_and_element_identifiers(dataset_collection_instance)
|
||||
for name, hda in zip(names, hdas):
|
||||
if hda.state != hda.states.OK:
|
||||
|
||||
@@ -626,8 +626,7 @@ class FastAPIHistoryContents:
|
||||
"""Download the content of a history dataset collection as a `zip` archive
|
||||
while maintaining approximate collection structure.
|
||||
"""
|
||||
archive = self.service.get_dataset_collection_archive_for_download(trans, id)
|
||||
return StreamingResponse(archive.response(), headers=archive.get_headers())
|
||||
return self._download_collection(trans, id)
|
||||
|
||||
@router.get(
|
||||
"/api/dataset_collections/{id}/download",
|
||||
@@ -644,8 +643,7 @@ class FastAPIHistoryContents:
|
||||
"""Download the content of a history dataset collection as a `zip` archive
|
||||
while maintaining approximate collection structure.
|
||||
"""
|
||||
archive = self.service.get_dataset_collection_archive_for_download(trans, id)
|
||||
return StreamingResponse(archive.response(), headers=archive.get_headers())
|
||||
return self._download_collection(trans, id)
|
||||
|
||||
@router.post(
|
||||
"/api/histories/{history_id}/contents/dataset_collections/{id}/prepare_download",
|
||||
@@ -1089,3 +1087,7 @@ class FastAPIHistoryContents:
|
||||
)
|
||||
rval = self.service.materialize(trans, materialize_request)
|
||||
return rval
|
||||
|
||||
def _download_collection(self, trans, id):
|
||||
archive = self.service.get_dataset_collection_archive_for_download(trans, id)
|
||||
return StreamingResponse(archive.response(), headers=archive.get_headers())
|
||||
|
||||
Reference in New Issue
Block a user