Skip to content

Commit 5a62c68

Browse files
Add sharing option for invocations
Opens a modal that does the following on `ok`: - Share workflow (make importable) - Share history (make importable) - Copy the link to your clipboard Fixes galaxyproject#19756
1 parent 3f69e7e commit 5a62c68

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<script setup lang="ts">
2+
import { faShareAlt } from "@fortawesome/free-solid-svg-icons";
3+
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
4+
import { BAlert, BButton, BModal } from "bootstrap-vue";
5+
import { computed, ref } from "vue";
6+
7+
import { GalaxyApi } from "@/api";
8+
import { getFullAppUrl } from "@/app/utils";
9+
import { Toast } from "@/composables/toast";
10+
import { useWorkflowInstance } from "@/composables/useWorkflowInstance";
11+
import { useHistoryStore } from "@/stores/historyStore";
12+
import { copy } from "@/utils/clipboard";
13+
14+
import LoadingSpan from "../LoadingSpan.vue";
15+
16+
const props = defineProps<{
17+
invocationId: string;
18+
workflowId: string;
19+
historyId: string;
20+
}>();
21+
22+
const modalToggle = ref(false);
23+
24+
// Workflow and History refs
25+
const { workflow, loading: workflowLoading, error: workflowError } = useWorkflowInstance(props.workflowId);
26+
const historyStore = useHistoryStore();
27+
28+
/** The link to the invocation. */
29+
const invocationLink = computed(() => getFullAppUrl(`workflows/invocations/${props.invocationId}`));
30+
31+
async function makeInvocationShareable() {
32+
if (!workflow.value) {
33+
return;
34+
}
35+
36+
// Note: Is it worth it to check here if the workflow and history are already shareable?
37+
38+
const { error: workflowShareError } = await GalaxyApi().PUT("/api/workflows/{workflow_id}/enable_link_access", {
39+
params: { path: { workflow_id: workflow.value.id } },
40+
});
41+
const { error: historyShareError } = await GalaxyApi().PUT("/api/histories/{history_id}/enable_link_access", {
42+
params: { path: { history_id: props.historyId } },
43+
});
44+
45+
if (workflowShareError || historyShareError) {
46+
Toast.error(`${workflowShareError || historyShareError}`, "Failed to make workflow and history shareable.");
47+
return;
48+
} else {
49+
Toast.success("Workflow and history are now shareable.");
50+
}
51+
52+
copy(invocationLink.value, "The link to the invocation has been copied to your clipboard.");
53+
}
54+
</script>
55+
56+
<template>
57+
<div>
58+
<BButton
59+
v-b-tooltip.noninteractive.hover
60+
title="Share Invocation"
61+
size="sm"
62+
class="text-decoration-none"
63+
variant="link"
64+
:disabled="!workflow"
65+
@click="modalToggle = true">
66+
<FontAwesomeIcon :icon="faShareAlt" fixed-width />
67+
</BButton>
68+
69+
<BModal
70+
v-model="modalToggle"
71+
title="Share Workflow Invocation"
72+
title-tag="h2"
73+
ok-title="Make Workflow and History Shareable, and Copy Link"
74+
@ok="makeInvocationShareable">
75+
<BAlert v-if="workflowError" variant="danger" show>
76+
{{ workflowError }}
77+
</BAlert>
78+
79+
<LoadingSpan v-else-if="workflowLoading" message="Loading details for invocation" />
80+
81+
<div v-else-if="!!workflow">
82+
<p v-localize>
83+
To share this invocation, you need to make sure that the workflow
84+
<strong>"{{ workflow.name }}"</strong>
85+
and history
86+
<strong>"{{ historyStore.getHistoryNameById(props.historyId) }}"</strong>
87+
are accessible via link.
88+
</p>
89+
<p v-localize>
90+
You can do this by clicking the <i>"Make Workflow and History Shareable, and Copy Link"</i>
91+
button below. This will generate a link that you can share with others, allowing them to view the
92+
invocation.
93+
</p>
94+
</div>
95+
</BModal>
96+
</div>
97+
</template>

client/src/components/WorkflowInvocationState/WorkflowInvocationState.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import WorkflowInvocationExportOptions from "./WorkflowInvocationExportOptions.v
2828
import WorkflowInvocationInputOutputTabs from "./WorkflowInvocationInputOutputTabs.vue";
2929
import WorkflowInvocationMetrics from "./WorkflowInvocationMetrics.vue";
3030
import WorkflowInvocationOverview from "./WorkflowInvocationOverview.vue";
31+
import WorkflowInvocationShare from "./WorkflowInvocationShare.vue";
3132
import LoadingSpan from "@/components/LoadingSpan.vue";
3233
3334
interface Props {
@@ -263,6 +264,10 @@ async function onCancel() {
263264
<FontAwesomeIcon :icon="faSquare" fixed-width />
264265
Cancel
265266
</BButton>
267+
<WorkflowInvocationShare
268+
:invocation-id="invocation.id"
269+
:workflow-id="invocation.workflow_id"
270+
:history-id="invocation.history_id" />
266271
</template>
267272
</WorkflowNavigationTitle>
268273
<WorkflowAnnotation

0 commit comments

Comments
 (0)