Skip to content

Commit

Permalink
Merge pull request galaxyproject#18370 from itisAliRH/workflow-card-p…
Browse files Browse the repository at this point in the history
…ublish-link-copy

[24.1] Add copy link to published workflow in `WorkflowCard`
  • Loading branch information
ahmedhamidawan authored Jun 11, 2024
2 parents b8e2bfc + b1614ba commit 94513b8
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 34 deletions.
9 changes: 2 additions & 7 deletions client/src/components/Sharing/Embeds/WorkflowEmbed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useDebounce } from "@vueuse/core";
import { BButton, BFormCheckbox, BFormInput, BInputGroup, BInputGroupAppend } from "bootstrap-vue";
import { computed, reactive, ref } from "vue";
import { getAppRoot } from "@/onload/loadConfig";
import { copy } from "@/utils/clipboard";
import { getFullAppUrl } from "@/utils/utils";
import ZoomControl from "@/components/Workflow/Editor/ZoomControl.vue";
import WorkflowPublished from "@/components/Workflow/Published/WorkflowPublished.vue";
Expand Down Expand Up @@ -39,13 +39,8 @@ function onChangePosition(event: Event, xy: "x" | "y") {
}
}
const root = computed(() => {
const port = window.location.port ? `:${window.location.port}` : "";
return `${window.location.protocol}//${window.location.hostname}${port}${getAppRoot()}`;
});
const embedUrl = computed(() => {
let url = `${root.value}published/workflow?id=${props.id}&embed=true`;
let url = getFullAppUrl(`published/workflow?id=${props.id}&embed=true`);
url += `&buttons=${settings.buttons}`;
url += `&about=${settings.about}`;
url += `&heading=${settings.heading}`;
Expand Down
8 changes: 2 additions & 6 deletions client/src/components/Sharing/SharingPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getGalaxyInstance } from "@/app";
import { useToast } from "@/composables/toast";
import { getAppRoot } from "@/onload/loadConfig";
import { errorMessageAsString } from "@/utils/simple-error";
import { getFullAppUrl } from "@/utils/utils";
import type { Item, ShareOption } from "./item";
Expand Down Expand Up @@ -52,11 +53,6 @@ const item = ref<Item>({
extra: defaultExtra(),
});
const itemRoot = computed(() => {
const port = window.location.port ? `:${window.location.port}` : "";
return `${window.location.protocol}//${window.location.hostname}${port}${getAppRoot()}`;
});
const itemUrl = reactive({
prefix: "",
slug: "",
Expand All @@ -68,7 +64,7 @@ watch(
if (value) {
const index = value.lastIndexOf("/");
itemUrl.prefix = itemRoot.value + value.substring(0, index + 1);
itemUrl.prefix = getFullAppUrl(value.substring(0, index + 1));
itemUrl.slug = value.substring(index + 1);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { computed } from "vue";
import { RouterLink } from "vue-router";
import { getAppRoot } from "@/onload/loadConfig";
import { useUserStore } from "@/stores/userStore";
import { getFullAppUrl } from "@/utils/utils";
import Heading from "@/components/Common/Heading.vue";
import CopyToClipboard from "@/components/CopyToClipboard.vue";
Expand Down Expand Up @@ -42,17 +42,12 @@ const gravatarSource = computed(
const publishedByUser = computed(() => `/workflows/list_published?owner=${props.workflowInfo?.owner}`);
const root = computed(() => {
const port = window.location.port ? `:${window.location.port}` : "";
return `${window.location.protocol}//${window.location.hostname}${port}${getAppRoot()}`;
});
const relativeLink = computed(() => {
return `/published/workflow?id=${props.workflowInfo.id}`;
});
const fullLink = computed(() => {
return `${root.value}${relativeLink.value.substring(1)}`;
return getFullAppUrl(relativeLink.value.substring(1));
});
const userOwned = computed(() => {
Expand Down
40 changes: 29 additions & 11 deletions client/src/components/Workflow/WorkflowActionsExtend.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faStar as farStar } from "@fortawesome/free-regular-svg-icons";
import {
faCaretDown,
faCopy,
faDownload,
faFileExport,
faShareAlt,
faStar,
faTrashRestore,
} from "@fortawesome/free-solid-svg-icons";
import { faCopy, faDownload, faLink, faShareAlt, faTrashRestore } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton } from "bootstrap-vue";
import { storeToRefs } from "pinia";
Expand All @@ -19,9 +10,11 @@ import { copyWorkflow, undeleteWorkflow } from "@/components/Workflow/workflows.
import { useConfirmDialog } from "@/composables/confirmDialog";
import { Toast } from "@/composables/toast";
import { useUserStore } from "@/stores/userStore";
import { copy } from "@/utils/clipboard";
import { withPrefix } from "@/utils/redirect";
import { getFullAppUrl } from "@/utils/utils";
library.add(faCaretDown, faCopy, faDownload, faFileExport, faShareAlt, farStar, faStar, faTrashRestore);
library.add(faCopy, faDownload, faLink, faShareAlt, faTrashRestore);
interface Props {
workflow: any;
Expand Down Expand Up @@ -72,11 +65,36 @@ async function onRestore() {
Toast.info("Workflow restored");
}
}
const relativeLink = computed(() => {
return `/published/workflow?id=${props.workflow.id}`;
});
const fullLink = computed(() => {
return getFullAppUrl(relativeLink.value.substring(1));
});
function onCopyPublicLink() {
copy(fullLink.value);
Toast.success("Link to workflow copied");
}
</script>

<template>
<div class="workflow-actions-extend flex-gapx-1">
<BButtonGroup>
<BButton
v-if="workflow.published && !workflow.deleted"
id="workflow-copy-public-button"
v-b-tooltip.hover.noninteractive
:size="buttonSize"
title="Copy link to workflow"
variant="outline-primary"
@click="onCopyPublicLink">
<FontAwesomeIcon :icon="faLink" fixed-width />
<span class="compact-view">Link to Workflow</span>
</BButton>

<BButton
v-if="!isAnonymous && !shared && !workflow.deleted"
id="workflow-copy-button"
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/Workflow/WorkflowIndicators.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faGlobe, faLink, faShieldAlt, faUser, faUsers } from "@fortawesome/free-solid-svg-icons";
import { faFileImport, faGlobe, faShieldAlt, faUser, faUsers } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BBadge, BButton } from "bootstrap-vue";
import { computed } from "vue";
Expand All @@ -12,7 +12,7 @@ import { copy } from "@/utils/clipboard";
import UtcDate from "@/components/UtcDate.vue";
library.add(faShieldAlt, faLink, faGlobe, faUsers, faUser);
library.add(faFileImport, faGlobe, faShieldAlt, faUsers, faUser);
interface Props {
workflow: any;
Expand Down Expand Up @@ -116,7 +116,7 @@ function onViewUserPublished() {
size="sm"
class="workflow-external-link inline-icon-button"
:title="sourceTitle">
<FontAwesomeIcon :icon="faLink" fixed-width @click="onCopyLink" />
<FontAwesomeIcon :icon="faFileImport" fixed-width @click="onCopyLink" />
</BButton>

<span class="mr-1">
Expand Down
12 changes: 12 additions & 0 deletions client/src/utils/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,16 @@ describe("test utils", () => {
]);
});
});

describe("test getFullAppUrl", () => {
it("should return the full app url", () => {
const appUrl = Utils.getFullAppUrl();
expect(appUrl).toBe("http://localhost/");
});

it("should return the full app url", () => {
const appUrl = Utils.getFullAppUrl("home");
expect(appUrl).toBe("http://localhost/home");
});
});
});
16 changes: 16 additions & 0 deletions client/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,21 @@ export function hasKeys(object: unknown, keys: string[]) {
}
}

/**
* Get the full URL path of the app
*
* @param path Path to append to the URL path
* @returns Full URL path of the app
*/
export function getFullAppUrl(path: string = ""): string {
const protocol = window.location.protocol;
const hostname = window.location.hostname;
const port = window.location.port ? `:${window.location.port}` : "";
const appRoot = getAppRoot();

return `${protocol}//${hostname}${port}${appRoot}${path}`;
}

export default {
cssLoadFile,
get,
Expand All @@ -460,4 +475,5 @@ export default {
waitForElementToBePresent,
wait,
mergeObjectListsById,
getFullAppUrl,
};

0 comments on commit 94513b8

Please sign in to comment.