feat(editor): Improve trigger panel (#3509)
* add panel * add workflow activation hints * support service trigger nodes * update polling state * support more views * update when trigger panel shows * update start/error nodes * add cron/interval info box * clean up start node * fix up webhook views * remove console log * add listening state * clean up loading state * update loading state * fix up animation * update views * add executions hint * update views * update accordian styling * address more issues * disable execute button if issues * disable if it has issues * add stop waiting button * can activate workflow when dsiabled * update el * fix has issues * add margin bttm * update views * close ndv * add shake * update copies * add error when polling node is missing one * update package lock * hide switch * hide binary data that's missing keys * hide main bar if ndv is open * remove waiting to execute * change accordion bg color * capitalize text * disable trigger panel in read only views * remove webhook title * update webhook desc * update component * update webhook executions note * update header * update webhook url * update exec help * bring back waiting to execute for non triggers * add transition fade * set shake * add helpful tooltip * add nonactive text * add inactive text * hide trigger panel by default * remove unused import * update pulse animation * handle empty values for options * update text * add flag for mock manual executions * add overrides * Add overrides * update check * update package lock; show button for others * hide more info * update other core nodes * update service name * remove panel from nodes * update panel * last tweaks * add telemetry event * add telemetry; address issues * address feedback * address feedback * address feedback * fix previous * fix previous * fix bug * fix bug with webhookbased * add extra break * update telemetry * update telemetry * add telemetry req * add info icon story; use icon component * clean css; en.json * clean en.json * rename key * add key * sort keys alpha * handle activation if active + add previous state to telemetry * stop activation if active * remove unnessary tracking * remove unused import * remove unused * remove unnessary flag * rewrite in ts * move pulse to design system * clean up * clean up * clean up * disable tslint check * disable tslint check
This commit is contained in:
@@ -17,6 +17,7 @@ import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { WORKFLOW_SETTINGS_MODAL_KEY } from '@/constants';
|
||||
import { getTriggerNodeServiceName } from '../helpers';
|
||||
|
||||
export const pushConnection = mixins(
|
||||
externalHooks,
|
||||
@@ -266,10 +267,29 @@ export const pushConnection = mixins(
|
||||
|
||||
const execution = this.$store.getters.getWorkflowExecution;
|
||||
if (execution && execution.executedNode) {
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('pushConnection.nodeExecutedSuccessfully'),
|
||||
type: 'success',
|
||||
});
|
||||
const node = this.$store.getters.getNodeByName(execution.executedNode);
|
||||
const nodeType = node && this.$store.getters.nodeType(node.type, node.typeVersion);
|
||||
const nodeOutput = execution && execution.executedNode && execution.data && execution.data.resultData && execution.data.resultData.runData && execution.data.resultData.runData[execution.executedNode];
|
||||
if (node && nodeType && !nodeOutput) {
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('pushConnection.pollingNode.dataNotFound', {
|
||||
interpolate: {
|
||||
service: getTriggerNodeServiceName(nodeType),
|
||||
},
|
||||
}),
|
||||
message: this.$locale.baseText('pushConnection.pollingNode.dataNotFound.message', {
|
||||
interpolate: {
|
||||
service: getTriggerNodeServiceName(nodeType),
|
||||
},
|
||||
}),
|
||||
type: 'success',
|
||||
});
|
||||
} else {
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('pushConnection.nodeExecutedSuccessfully'),
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.$showMessage({
|
||||
|
||||
98
packages/editor-ui/src/components/mixins/workflowActivate.ts
Normal file
98
packages/editor-ui/src/components/mixins/workflowActivate.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { externalHooks } from '@/components/mixins/externalHooks';
|
||||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
import { showMessage } from '@/components/mixins/showMessage';
|
||||
|
||||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { LOCAL_STORAGE_ACTIVATION_FLAG, PLACEHOLDER_EMPTY_WORKFLOW_ID, WORKFLOW_ACTIVE_MODAL_KEY } from '@/constants';
|
||||
|
||||
export const workflowActivate = mixins(
|
||||
externalHooks,
|
||||
workflowHelpers,
|
||||
showMessage,
|
||||
)
|
||||
.extend({
|
||||
data() {
|
||||
return {
|
||||
updatingWorkflowActivation: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async activateCurrentWorkflow(telemetrySource?: string) {
|
||||
const workflowId = this.$store.getters.workflowId;
|
||||
return this.updateWorkflowActivation(workflowId, true, telemetrySource);
|
||||
},
|
||||
async updateWorkflowActivation(workflowId: string | undefined, newActiveState: boolean, telemetrySource?: string) {
|
||||
this.updatingWorkflowActivation = true;
|
||||
const nodesIssuesExist = this.$store.getters.nodesIssuesExist as boolean;
|
||||
|
||||
let currWorkflowId: string | undefined = workflowId;
|
||||
if (!currWorkflowId || currWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
const saved = await this.saveCurrentWorkflow();
|
||||
if (!saved) {
|
||||
this.updatingWorkflowActivation = false;
|
||||
return;
|
||||
}
|
||||
currWorkflowId = this.$store.getters.workflowId as string;
|
||||
}
|
||||
|
||||
const isCurrentWorkflow = currWorkflowId === this.$store.getters['workflowId'];
|
||||
|
||||
const activeWorkflows = this.$store.getters.getActiveWorkflows;
|
||||
const isWorkflowActive = activeWorkflows.includes(currWorkflowId);
|
||||
|
||||
this.$telemetry.track('User set workflow active status', { workflow_id: currWorkflowId, is_active: newActiveState, previous_status: isWorkflowActive, ndv_input: telemetrySource === 'ndv' });
|
||||
|
||||
try {
|
||||
if (isWorkflowActive && newActiveState) {
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('workflowActivator.workflowIsActive'),
|
||||
type: 'success',
|
||||
});
|
||||
this.updatingWorkflowActivation = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCurrentWorkflow && nodesIssuesExist) {
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('workflowActivator.showMessage.activeChangedNodesIssuesExistTrue.title'),
|
||||
message: this.$locale.baseText('workflowActivator.showMessage.activeChangedNodesIssuesExistTrue.message'),
|
||||
type: 'error',
|
||||
});
|
||||
|
||||
this.updatingWorkflowActivation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await this.updateWorkflow({workflowId: currWorkflowId, active: newActiveState});
|
||||
} catch (error) {
|
||||
const newStateName = newActiveState === true ? 'activated' : 'deactivated';
|
||||
this.$showError(
|
||||
error,
|
||||
this.$locale.baseText(
|
||||
'workflowActivator.showError.title',
|
||||
{ interpolate: { newStateName } },
|
||||
) + ':',
|
||||
);
|
||||
this.updatingWorkflowActivation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const activationEventName = isCurrentWorkflow ? 'workflow.activeChangeCurrent' : 'workflow.activeChange';
|
||||
this.$externalHooks().run(activationEventName, { workflowId: currWorkflowId, active: newActiveState });
|
||||
|
||||
this.$emit('workflowActiveChanged', { id: currWorkflowId, active: newActiveState });
|
||||
this.updatingWorkflowActivation = false;
|
||||
|
||||
if (isCurrentWorkflow) {
|
||||
if (newActiveState && window.localStorage.getItem(LOCAL_STORAGE_ACTIVATION_FLAG) !== 'true') {
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_ACTIVE_MODAL_KEY);
|
||||
}
|
||||
else {
|
||||
this.$store.dispatch('settings/fetchPromptsData');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
NodeHelpers,
|
||||
IExecuteData,
|
||||
INodeConnection,
|
||||
IWebhookDescription,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
@@ -428,6 +429,33 @@ export const workflowHelpers = mixins(
|
||||
return nodeData;
|
||||
},
|
||||
|
||||
getWebhookExpressionValue (webhookData: IWebhookDescription, key: string): string {
|
||||
if (webhookData[key] === undefined) {
|
||||
return 'empty';
|
||||
}
|
||||
try {
|
||||
return this.resolveExpression(webhookData[key] as string) as string;
|
||||
} catch (e) {
|
||||
return this.$locale.baseText('nodeWebhooks.invalidExpression');
|
||||
}
|
||||
},
|
||||
|
||||
getWebhookUrl (webhookData: IWebhookDescription, node: INode, showUrlFor?: string): string {
|
||||
if (webhookData.restartWebhook === true) {
|
||||
return '$resumeWebhookUrl';
|
||||
}
|
||||
let baseUrl = this.$store.getters.getWebhookUrl;
|
||||
if (showUrlFor === 'test') {
|
||||
baseUrl = this.$store.getters.getWebhookTestUrl;
|
||||
}
|
||||
|
||||
const workflowId = this.$store.getters.workflowId;
|
||||
const path = this.getWebhookExpressionValue(webhookData, 'path');
|
||||
const isFullPath = this.getWebhookExpressionValue(webhookData, 'isFullPath') as unknown as boolean || false;
|
||||
|
||||
return NodeHelpers.getNodeWebhookUrl(baseUrl, workflowId, node, path, isFullPath);
|
||||
},
|
||||
|
||||
|
||||
resolveParameter(parameter: NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[]) {
|
||||
const itemIndex = 0;
|
||||
|
||||
@@ -60,12 +60,6 @@ export const workflowRun = mixins(
|
||||
async runWorkflow (nodeName?: string, source?: string): Promise<IExecutionPushResponse | undefined> {
|
||||
const workflow = this.getWorkflow();
|
||||
|
||||
if(nodeName) {
|
||||
this.$telemetry.track('User clicked execute node button', { node_type: nodeName, workflow_id: this.$store.getters.workflowId });
|
||||
} else {
|
||||
this.$telemetry.track('User clicked execute workflow button', { workflow_id: this.$store.getters.workflowId });
|
||||
}
|
||||
|
||||
if (this.$store.getters.isActionActive('workflowRunning') === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user