refactor(editor): Migrate NodeWebhooks to Composition API (no-changelog) (#10710)
Some checks failed
Test Master / install-and-build (push) Has been cancelled
Benchmark Docker Image CI / build (push) Has been cancelled
Test Master / Unit tests (18.x) (push) Has been cancelled
Test Master / Unit tests (20.x) (push) Has been cancelled
Test Master / Unit tests (22.4) (push) Has been cancelled
Test Master / Lint (push) Has been cancelled
Test Master / Notify Slack on failure (push) Has been cancelled

This commit is contained in:
Alex Grozav 2024-09-06 16:12:05 +03:00 committed by GitHub
parent e4c9035915
commit 6ea0856085
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 154 additions and 152 deletions

View file

@ -1025,7 +1025,7 @@ onBeforeUnmount(() => {
" "
/> />
<div v-show="openPanel === 'params'"> <div v-show="openPanel === 'params'">
<NodeWebhooks :node="node" :node-type="nodeType" /> <NodeWebhooks :node="node" :node-type-description="nodeType" />
<ParameterInputList <ParameterInputList
v-if="nodeValuesInitialized" v-if="nodeValuesInitialized"

View file

@ -1,7 +1,5 @@
<script lang="ts"> <script lang="ts" setup>
import type { INodeTypeDescription, IWebhookDescription } from 'n8n-workflow'; import type { INodeTypeDescription, IWebhookDescription } from 'n8n-workflow';
import { defineComponent } from 'vue';
import { useToast } from '@/composables/useToast'; import { useToast } from '@/composables/useToast';
import { import {
CHAT_TRIGGER_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE,
@ -12,159 +10,163 @@ import {
import { useClipboard } from '@/composables/useClipboard'; import { useClipboard } from '@/composables/useClipboard';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import type { INodeUi } from '@/Interface';
import { computed, ref, watch } from 'vue';
import { useI18n } from '@/composables/useI18n';
import { useTelemetry } from '@/composables/useTelemetry';
export default defineComponent({ const props = defineProps<{
name: 'NodeWebhooks', node: INodeUi;
props: [ nodeTypeDescription: INodeTypeDescription | null;
'node', // NodeUi }>();
'nodeType', // INodeTypeDescription
], const router = useRouter();
setup() { const clipboard = useClipboard();
const router = useRouter(); const workflowHelpers = useWorkflowHelpers({ router });
const clipboard = useClipboard(); const toast = useToast();
const workflowHelpers = useWorkflowHelpers({ router }); const i18n = useI18n();
return { const telemetry = useTelemetry();
clipboard,
workflowHelpers, const isMinimized = ref(
...useToast(), props.nodeTypeDescription &&
}; !OPEN_URL_PANEL_TRIGGER_NODE_TYPES.includes(props.nodeTypeDescription.name),
}, );
data() { const showUrlFor = ref('test');
return {
isMinimized: this.nodeType && !OPEN_URL_PANEL_TRIGGER_NODE_TYPES.includes(this.nodeType.name), const isProductionOnly = computed(() => {
showUrlFor: 'test', return (
}; props.nodeTypeDescription &&
}, PRODUCTION_ONLY_TRIGGER_NODE_TYPES.includes(props.nodeTypeDescription.name)
computed: { );
isProductionOnly(): boolean { });
return this.nodeType && PRODUCTION_ONLY_TRIGGER_NODE_TYPES.includes(this.nodeType.name);
}, const urlOptions = computed(() => [
urlOptions(): Array<{ label: string; value: string }> { ...(isProductionOnly.value ? [] : [{ label: baseText.value.testUrl, value: 'test' }]),
return [
...(this.isProductionOnly ? [] : [{ label: this.baseText.testUrl, value: 'test' }]),
{ {
label: this.baseText.productionUrl, label: baseText.value.productionUrl,
value: 'production', value: 'production',
}, },
]; ]);
},
visibleWebhookUrls(): IWebhookDescription[] { const visibleWebhookUrls = computed(() => {
return this.webhooksNode.filter((webhook) => { return webhooksNode.value.filter((webhook) => {
if (typeof webhook.ndvHideUrl === 'string') { if (typeof webhook.ndvHideUrl === 'string') {
return !this.workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideUrl'); return !workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideUrl');
} }
return !webhook.ndvHideUrl; return !webhook.ndvHideUrl;
}); });
}, });
webhooksNode(): IWebhookDescription[] {
if (this.nodeType === null || this.nodeType.webhooks === undefined) { const webhooksNode = computed(() => {
if (props.nodeTypeDescription?.webhooks === undefined) {
return []; return [];
} }
return (this.nodeType as INodeTypeDescription).webhooks!.filter( return props.nodeTypeDescription.webhooks.filter(
(webhookData) => webhookData.restartWebhook !== true, (webhookData) => webhookData.restartWebhook !== true,
); );
}, });
baseText() {
const nodeType = this.nodeType.name; const baseText = computed(() => {
const nodeType = props.nodeTypeDescription?.name;
switch (nodeType) { switch (nodeType) {
case CHAT_TRIGGER_NODE_TYPE: case CHAT_TRIGGER_NODE_TYPE:
return { return {
toggleTitle: this.$locale.baseText('nodeWebhooks.webhookUrls.chatTrigger'), toggleTitle: i18n.baseText('nodeWebhooks.webhookUrls.chatTrigger'),
clickToDisplay: this.$locale.baseText( clickToDisplay: i18n.baseText('nodeWebhooks.clickToDisplayWebhookUrls.formTrigger'),
'nodeWebhooks.clickToDisplayWebhookUrls.formTrigger', clickToHide: i18n.baseText('nodeWebhooks.clickToHideWebhookUrls.chatTrigger'),
), clickToCopy: i18n.baseText('nodeWebhooks.clickToCopyWebhookUrls.chatTrigger'),
clickToHide: this.$locale.baseText('nodeWebhooks.clickToHideWebhookUrls.chatTrigger'), testUrl: i18n.baseText('nodeWebhooks.testUrl'),
clickToCopy: this.$locale.baseText('nodeWebhooks.clickToCopyWebhookUrls.chatTrigger'), productionUrl: i18n.baseText('nodeWebhooks.productionUrl'),
testUrl: this.$locale.baseText('nodeWebhooks.testUrl'), copyTitle: i18n.baseText('nodeWebhooks.showMessage.title.chatTrigger'),
productionUrl: this.$locale.baseText('nodeWebhooks.productionUrl'), copyMessage: i18n.baseText('nodeWebhooks.showMessage.message.chatTrigger'),
copyTitle: this.$locale.baseText('nodeWebhooks.showMessage.title.chatTrigger'),
copyMessage: this.$locale.baseText('nodeWebhooks.showMessage.message.chatTrigger'),
}; };
case FORM_TRIGGER_NODE_TYPE: case FORM_TRIGGER_NODE_TYPE:
return { return {
toggleTitle: this.$locale.baseText('nodeWebhooks.webhookUrls.formTrigger'), toggleTitle: i18n.baseText('nodeWebhooks.webhookUrls.formTrigger'),
clickToDisplay: this.$locale.baseText( clickToDisplay: i18n.baseText('nodeWebhooks.clickToDisplayWebhookUrls.formTrigger'),
'nodeWebhooks.clickToDisplayWebhookUrls.formTrigger', clickToHide: i18n.baseText('nodeWebhooks.clickToHideWebhookUrls.formTrigger'),
), clickToCopy: i18n.baseText('nodeWebhooks.clickToCopyWebhookUrls.formTrigger'),
clickToHide: this.$locale.baseText('nodeWebhooks.clickToHideWebhookUrls.formTrigger'), testUrl: i18n.baseText('nodeWebhooks.testUrl'),
clickToCopy: this.$locale.baseText('nodeWebhooks.clickToCopyWebhookUrls.formTrigger'), productionUrl: i18n.baseText('nodeWebhooks.productionUrl'),
testUrl: this.$locale.baseText('nodeWebhooks.testUrl'), copyTitle: i18n.baseText('nodeWebhooks.showMessage.title.formTrigger'),
productionUrl: this.$locale.baseText('nodeWebhooks.productionUrl'), copyMessage: i18n.baseText('nodeWebhooks.showMessage.message.formTrigger'),
copyTitle: this.$locale.baseText('nodeWebhooks.showMessage.title.formTrigger'),
copyMessage: this.$locale.baseText('nodeWebhooks.showMessage.message.formTrigger'),
}; };
default: default:
return { return {
toggleTitle: this.$locale.baseText('nodeWebhooks.webhookUrls'), toggleTitle: i18n.baseText('nodeWebhooks.webhookUrls'),
clickToDisplay: this.$locale.baseText('nodeWebhooks.clickToDisplayWebhookUrls'), clickToDisplay: i18n.baseText('nodeWebhooks.clickToDisplayWebhookUrls'),
clickToHide: this.$locale.baseText('nodeWebhooks.clickToHideWebhookUrls'), clickToHide: i18n.baseText('nodeWebhooks.clickToHideWebhookUrls'),
clickToCopy: this.$locale.baseText('nodeWebhooks.clickToCopyWebhookUrls'), clickToCopy: i18n.baseText('nodeWebhooks.clickToCopyWebhookUrls'),
testUrl: this.$locale.baseText('nodeWebhooks.testUrl'), testUrl: i18n.baseText('nodeWebhooks.testUrl'),
productionUrl: this.$locale.baseText('nodeWebhooks.productionUrl'), productionUrl: i18n.baseText('nodeWebhooks.productionUrl'),
copyTitle: this.$locale.baseText('nodeWebhooks.showMessage.title'), copyTitle: i18n.baseText('nodeWebhooks.showMessage.title'),
copyMessage: undefined, copyMessage: undefined,
}; };
} }
}, });
},
watch: {
node() {
this.isMinimized = !OPEN_URL_PANEL_TRIGGER_NODE_TYPES.includes(this.nodeType.name);
},
},
methods: {
copyWebhookUrl(webhookData: IWebhookDescription): void {
const webhookUrl = this.getWebhookUrlDisplay(webhookData);
void this.clipboard.copy(webhookUrl);
this.showMessage({ function copyWebhookUrl(webhookData: IWebhookDescription): void {
title: this.baseText.copyTitle, const webhookUrl = getWebhookUrlDisplay(webhookData);
message: this.baseText.copyMessage, void clipboard.copy(webhookUrl);
toast.showMessage({
title: baseText.value.copyTitle,
message: baseText.value.copyMessage,
type: 'success', type: 'success',
}); });
this.$telemetry.track('User copied webhook URL', {
telemetry.track('User copied webhook URL', {
pane: 'parameters', pane: 'parameters',
type: `${this.showUrlFor} url`, type: `${showUrlFor.value} url`,
}); });
}, }
getWebhookUrlDisplay(webhookData: IWebhookDescription): string {
if (this.node) { function getWebhookUrlDisplay(webhookData: IWebhookDescription): string {
return this.workflowHelpers.getWebhookUrl( if (props.node) {
return workflowHelpers.getWebhookUrl(
webhookData, webhookData,
this.node, props.node,
this.isProductionOnly ? 'production' : this.showUrlFor, isProductionOnly.value ? 'production' : showUrlFor.value,
); );
} }
return ''; return '';
}, }
isWebhookMethodVisible(webhook: IWebhookDescription): boolean {
function isWebhookMethodVisible(webhook: IWebhookDescription): boolean {
try { try {
const method = this.workflowHelpers.getWebhookExpressionValue(webhook, 'httpMethod', false); const method = workflowHelpers.getWebhookExpressionValue(webhook, 'httpMethod', false);
if (Array.isArray(method) && method.length !== 1) { if (Array.isArray(method) && method.length !== 1) {
return false; return false;
} }
} catch (error) {} } catch (error) {}
if (typeof webhook.ndvHideMethod === 'string') { if (typeof webhook.ndvHideMethod === 'string') {
return !this.workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideMethod'); return !workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideMethod');
} }
return !webhook.ndvHideMethod; return !webhook.ndvHideMethod;
}, }
getWebhookHttpMethod(webhook: IWebhookDescription): string { function getWebhookHttpMethod(webhook: IWebhookDescription): string {
const method = this.workflowHelpers.getWebhookExpressionValue(webhook, 'httpMethod', false); const method = workflowHelpers.getWebhookExpressionValue(webhook, 'httpMethod', false);
if (Array.isArray(method)) { if (Array.isArray(method)) {
return method[0]; return method[0];
} }
return method; return method;
}
watch(
() => props.node,
() => {
isMinimized.value =
props.nodeTypeDescription &&
!OPEN_URL_PANEL_TRIGGER_NODE_TYPES.includes(props.nodeTypeDescription.name);
}, },
}, );
});
</script> </script>
<template> <template>