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'">
<NodeWebhooks :node="node" :node-type="nodeType" />
<NodeWebhooks :node="node" :node-type-description="nodeType" />
<ParameterInputList
v-if="nodeValuesInitialized"

View file

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