Skip to content

Commit 56dc017

Browse files
authored
Merge pull request #20797 from guerler/refactor_webhooks
Remove Backbone dependency from webhook wrappers
2 parents b186d0e + 68ebc87 commit 56dc017

File tree

8 files changed

+91
-138
lines changed

8 files changed

+91
-138
lines changed
Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
<script setup lang="ts">
22
import { onMounted, ref } from "vue";
33
4-
import Webhooks from "@/utils/webhooks";
4+
import { appendScriptStyle } from "@/utils/utils";
5+
import { loadWebhooks, pickWebhook } from "@/utils/webhooks";
56
67
interface Props {
78
type: string;
89
toolId?: string;
10+
toolVersion?: string;
911
}
1012
1113
const props = withDefaults(defineProps<Props>(), {
12-
toolId: undefined,
14+
toolId: "",
15+
toolVersion: "",
1316
});
1417
15-
const webhook = ref(null);
18+
const container = ref<HTMLElement | null>(null);
19+
const webhookId = ref<string | null>(null);
1620
17-
onMounted(() => {
18-
new Webhooks.WebhookView({
19-
webhook,
20-
type: props.type,
21-
toolId: props.toolId,
22-
});
21+
onMounted(async () => {
22+
if (container.value) {
23+
container.value.setAttribute("tool_id", props.toolId);
24+
container.value.setAttribute("tool_version", props.toolVersion);
25+
}
26+
27+
const webhooks = await loadWebhooks();
28+
if (webhooks.length > 0) {
29+
const model = pickWebhook(webhooks);
30+
webhookId.value = model.id;
31+
appendScriptStyle(model);
32+
}
2333
});
2434
</script>
2535

2636
<template>
27-
<div id="webhook-view" ref="webhook" />
37+
<div ref="container">
38+
<div v-if="webhookId" :id="webhookId"></div>
39+
</div>
2840
</template>

client/src/components/Masthead/Masthead.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { setupMockConfig } from "tests/jest/mockConfig";
99

1010
import { useUserStore } from "@/stores/userStore";
1111

12-
import { loadWebhookMenuItems } from "./_webhooks";
12+
import { loadMastheadWebhooks } from "./_webhooks";
1313

1414
import Masthead from "./Masthead.vue";
1515

@@ -38,7 +38,7 @@ describe("Masthead.vue", () => {
3838
});
3939
}
4040

41-
loadWebhookMenuItems.mockImplementation(stubLoadWebhooks);
41+
loadMastheadWebhooks.mockImplementation(stubLoadWebhooks);
4242

4343
beforeEach(async () => {
4444
localVue = getLocalVue();

client/src/components/Masthead/Masthead.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useRouter } from "vue-router/composables";
99
import { useConfig } from "@/composables/config";
1010
import { useUserStore } from "@/stores/userStore";
1111
12-
import { loadWebhookMenuItems } from "./_webhooks";
12+
import { loadMastheadWebhooks } from "./_webhooks";
1313
import MastheadDropdown from "./MastheadDropdown";
1414
import MastheadItem from "./MastheadItem";
1515
import QuotaMeter from "./QuotaMeter";
@@ -72,7 +72,7 @@ function onWindowToggle() {
7272
}
7373
7474
onMounted(() => {
75-
loadWebhookMenuItems(extensionTabs.value);
75+
loadMastheadWebhooks(extensionTabs.value);
7676
});
7777
</script>
7878

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
import Utils from "utils/utils";
2-
import Webhooks from "utils/webhooks";
1+
import { appendScriptStyle } from "utils/utils";
2+
import { loadWebhooks } from "utils/webhooks";
33

4-
export function loadWebhookMenuItems(items) {
5-
Webhooks.load({
6-
type: "masthead",
7-
callback: function (webhooks) {
8-
webhooks.forEach((webhook) => {
9-
if (webhook.activate) {
10-
const obj = {
11-
id: webhook.id,
12-
icon: webhook.config.icon,
13-
url: webhook.config.url,
14-
tooltip: webhook.config.tooltip,
15-
/*jslint evil: true */
16-
onclick: webhook.config.function && new Function(webhook.config.function),
17-
target: "_parent",
18-
};
19-
items.push(obj);
20-
// Append masthead script and styles to Galaxy main
21-
Utils.appendScriptStyle(webhook);
22-
}
23-
});
24-
},
4+
export async function loadMastheadWebhooks(items) {
5+
const webhooks = await loadWebhooks("masthead");
6+
webhooks.forEach((webhook) => {
7+
if (webhook.activate) {
8+
const obj = {
9+
id: webhook.id,
10+
icon: webhook.config.icon,
11+
url: webhook.config.url,
12+
tooltip: webhook.config.tooltip,
13+
/*jslint evil: true */
14+
onclick: webhook.config.function && new Function(webhook.config.function),
15+
target: "_parent",
16+
};
17+
items.push(obj);
18+
// Append masthead script and styles to Galaxy main
19+
appendScriptStyle(webhook);
20+
}
2521
});
2622
}

client/src/components/Tool/Buttons/ToolOptionsButton.vue

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { faCaretDown, faDownload, faExternalLinkAlt, faLink } from "@fortawesome
55
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
66
import ToolSourceMenuItem from "components/Tool/ToolSourceMenuItem";
77
import { storeToRefs } from "pinia";
8-
import Webhooks from "utils/webhooks";
8+
import { loadWebhooks } from "utils/webhooks";
99
import { computed, ref } from "vue";
1010
1111
import { useUserStore } from "@/stores/userStore";
@@ -37,24 +37,6 @@ const props = defineProps({
3737
3838
const webhookDetails = ref([]);
3939
40-
Webhooks.load({
41-
type: "tool-menu",
42-
callback: (webhooks) => {
43-
webhooks.forEach((webhook) => {
44-
if (webhook.activate && webhook.config.function) {
45-
webhookDetails.value.push({
46-
icon: `fa ${webhook.config.icon}`,
47-
title: webhook.config.title,
48-
onclick: () => {
49-
const func = new Function("options", webhook.config.function);
50-
func(props.options);
51-
},
52-
});
53-
}
54-
});
55-
},
56-
});
57-
5840
const showDownload = computed(() => currentUser.value?.is_admin);
5941
const showLink = computed(() => Boolean(props.sharableUrl));
6042
@@ -73,6 +55,24 @@ function onDownload() {
7355
function onLink() {
7456
openLink(props.sharableUrl);
7557
}
58+
59+
async function loadToolMenuWebhooks() {
60+
const webhooks = await loadWebhooks("tool-menu");
61+
webhooks.forEach((webhook) => {
62+
if (webhook.activate && webhook.config.function) {
63+
webhookDetails.value.push({
64+
icon: `fa ${webhook.config.icon}`,
65+
title: webhook.config.title,
66+
onclick: () => {
67+
const func = new Function("options", webhook.config.function);
68+
func(props.options);
69+
},
70+
});
71+
}
72+
});
73+
}
74+
75+
loadToolMenuWebhooks();
7676
</script>
7777
7878
<template>
Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script setup lang="ts">
2-
import { onMounted } from "vue";
2+
import { computed, onMounted } from "vue";
33
44
import type { WorkflowInvocation } from "@/api/invocations";
5-
import Webhooks from "@/utils/webhooks";
65
import { startWatchingHistory } from "@/watch/watchHistoryProvided";
76
7+
import Webhook from "@/components/Common/Webhook.vue";
88
import GridInvocation from "@/components/Grid/GridInvocation.vue";
99
import WorkflowInvocationState from "@/components/WorkflowInvocationState/WorkflowInvocationState.vue";
1010
@@ -14,20 +14,17 @@ const props = defineProps<{
1414
}>();
1515
1616
onMounted(() => {
17-
new Webhooks.WebhookView({
18-
type: "workflow",
19-
toolId: null,
20-
toolVersion: null,
21-
});
2217
startWatchingHistory();
2318
});
2419
25-
const targetHistories = props.invocations.reduce((histories, invocation) => {
26-
if (invocation.history_id && !histories.includes(invocation.history_id)) {
27-
histories.push(invocation.history_id);
28-
}
29-
return histories;
30-
}, [] as string[]);
20+
const targetHistories = computed(() =>
21+
props.invocations.reduce((histories, invocation) => {
22+
if (invocation.history_id && !histories.includes(invocation.history_id)) {
23+
histories.push(invocation.history_id);
24+
}
25+
return histories;
26+
}, [] as string[])
27+
);
3128
</script>
3229

3330
<template>
@@ -46,6 +43,6 @@ const targetHistories = props.invocations.reduce((histories, invocation) => {
4643
:invocation-id="props.invocations[0].id"
4744
is-full-page
4845
success />
49-
<div id="webhook-view"></div>
46+
<Webhook type="workflow" />
5047
</div>
5148
</template>
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
import Utils from "utils/utils";
2-
import Webhooks from "utils/webhooks";
1+
import { appendScriptStyle } from "utils/utils";
2+
import { loadWebhooks } from "utils/webhooks";
33

4-
export function onloadWebhooks(Galaxy) {
4+
export async function onloadWebhooks(Galaxy) {
55
if (Galaxy.config.enable_webhooks) {
6-
Webhooks.load({
7-
type: "onload",
8-
callback: function (webhooks) {
9-
webhooks.forEach((webhook) => {
10-
if (webhook.activate && webhook.script) {
11-
Utils.appendScriptStyle(webhook);
12-
}
13-
});
14-
},
6+
const webhooks = await loadWebhooks("onload");
7+
webhooks.forEach((webhook) => {
8+
if (webhook.activate && webhook.script) {
9+
appendScriptStyle(webhook);
10+
}
1511
});
1612
}
1713
}

client/src/utils/webhooks.js

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import axios from "axios";
2-
import Backbone from "backbone";
32
import { getAppRoot } from "onload/loadConfig";
4-
import Utils from "utils/utils";
53

64
import { rethrowSimple } from "@/utils/simple-error";
75

86
let webhookData = undefined;
97

10-
async function getWebHookData() {
8+
async function getWebhookData() {
119
if (webhookData === undefined) {
1210
try {
1311
const { data } = await axios.get(`${getAppRoot()}api/webhooks`);
@@ -19,57 +17,16 @@ async function getWebHookData() {
1917
return webhookData;
2018
}
2119

22-
const WebhookView = Backbone.View.extend({
23-
el: "#webhook-view",
24-
25-
initialize: function (options) {
26-
const toolId = options.toolId || "";
27-
const toolVersion = options.toolVersion || "";
28-
29-
this.$el.attr("tool_id", toolId);
30-
this.$el.attr("tool_version", toolVersion);
31-
32-
getWebHookData().then((data) => {
33-
const filteredData = filterData(data, options);
34-
if (filteredData.length > 0) {
35-
this.render(weightedRandomPick(filteredData));
36-
}
37-
});
38-
},
39-
40-
render: function (model) {
41-
this.$el.html(`<div id="${model.id}"></div>`);
42-
Utils.appendScriptStyle(model);
43-
return this;
44-
},
45-
});
46-
47-
function filterData(data, options) {
48-
let filteredData = data;
49-
if (options.type) {
50-
filteredData = filterType(data, options.type);
20+
export async function loadWebhooks(type) {
21+
const webhooks = await getWebhookData();
22+
if (type) {
23+
return webhooks.filter((item) => item.type && item.type.indexOf(type) !== -1);
24+
} else {
25+
return webhooks;
5126
}
52-
return filteredData;
53-
}
54-
55-
const load = (options) => {
56-
getWebHookData().then((data) => {
57-
options.callback(filterData(data, options));
58-
});
59-
};
60-
61-
function filterType(data, type) {
62-
return data.filter((item) => {
63-
const itype = item.type;
64-
if (itype) {
65-
return itype.indexOf(type) !== -1;
66-
} else {
67-
return false;
68-
}
69-
});
7027
}
7128

72-
function weightedRandomPick(data) {
29+
export function pickWebhook(data) {
7330
const weights = data.map((d) => d.weight);
7431
const sum = weights.reduce((a, b) => a + b);
7532

@@ -87,8 +44,3 @@ function weightedRandomPick(data) {
8744

8845
return data.at(table[Math.floor(Math.random() * table.length)]);
8946
}
90-
91-
export default {
92-
WebhookView: WebhookView,
93-
load: load,
94-
};

0 commit comments

Comments
 (0)