mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 19:11:13 +00:00
refactor(editor): Decouple REST calls from views (no-changelog) (#5202)
* decouple rest calls * remove console.log
This commit is contained in:
committed by
GitHub
parent
7aa65315cc
commit
b69f480d4c
54
packages/editor-ui/src/api/eventbus.ee.ts
Normal file
54
packages/editor-ui/src/api/eventbus.ee.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { IRestApiContext } from '@/Interface';
|
||||||
|
import { makeRestApiRequest } from '@/utils';
|
||||||
|
import { IDataObject, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||||
|
|
||||||
|
export async function saveDestinationToDb(
|
||||||
|
context: IRestApiContext,
|
||||||
|
destination: MessageEventBusDestinationOptions,
|
||||||
|
subscribedEvents: string[] = [],
|
||||||
|
) {
|
||||||
|
if (destination.id) {
|
||||||
|
const data: IDataObject = {
|
||||||
|
...destination,
|
||||||
|
subscribedEvents,
|
||||||
|
};
|
||||||
|
return makeRestApiRequest(context, 'POST', '/eventbus/destination', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteDestinationFromDb(context: IRestApiContext, destinationId: string) {
|
||||||
|
return makeRestApiRequest(context, 'DELETE', `/eventbus/destination?id=${destinationId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendTestMessageToDestination(
|
||||||
|
context: IRestApiContext,
|
||||||
|
destination: MessageEventBusDestinationOptions,
|
||||||
|
) {
|
||||||
|
if (destination.id) {
|
||||||
|
const data: IDataObject = {
|
||||||
|
...destination,
|
||||||
|
};
|
||||||
|
return makeRestApiRequest(context, 'GET', '/eventbus/testmessage', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getEventNamesFromBackend(context: IRestApiContext): Promise<string[]> {
|
||||||
|
return makeRestApiRequest(context, 'GET', '/eventbus/eventnames');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getDestinationsFromBackend(
|
||||||
|
context: IRestApiContext,
|
||||||
|
): Promise<MessageEventBusDestinationOptions[]> {
|
||||||
|
return makeRestApiRequest(context, 'GET', '/eventbus/destination');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getExecutionEvents(context: IRestApiContext, executionId: string) {
|
||||||
|
return makeRestApiRequest(context, 'GET', `/eventbus/execution/${executionId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function recoverExecutionDataFromEvents(
|
||||||
|
context: IRestApiContext,
|
||||||
|
executionId: string,
|
||||||
|
) {
|
||||||
|
return makeRestApiRequest(context, 'GET', `/eventbus/execution-recover/${executionId}`);
|
||||||
|
}
|
||||||
@@ -51,7 +51,6 @@ import mixins from 'vue-typed-mixins';
|
|||||||
import { EnterpriseEditionFeature } from '@/constants';
|
import { EnterpriseEditionFeature } from '@/constants';
|
||||||
import { showMessage } from '@/mixins/showMessage';
|
import { showMessage } from '@/mixins/showMessage';
|
||||||
import { useLogStreamingStore } from '../../stores/logStreamingStore';
|
import { useLogStreamingStore } from '../../stores/logStreamingStore';
|
||||||
import { restApi } from '@/mixins/restApi';
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import {
|
import {
|
||||||
@@ -59,7 +58,6 @@ import {
|
|||||||
defaultMessageEventBusDestinationOptions,
|
defaultMessageEventBusDestinationOptions,
|
||||||
MessageEventBusDestinationOptions,
|
MessageEventBusDestinationOptions,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { saveDestinationToDb } from './Helpers.ee';
|
|
||||||
import { BaseTextKey } from '../../plugins/i18n';
|
import { BaseTextKey } from '../../plugins/i18n';
|
||||||
|
|
||||||
export const DESTINATION_LIST_ITEM_ACTIONS = {
|
export const DESTINATION_LIST_ITEM_ACTIONS = {
|
||||||
@@ -67,7 +65,7 @@ export const DESTINATION_LIST_ITEM_ACTIONS = {
|
|||||||
DELETE: 'delete',
|
DELETE: 'delete',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default mixins(showMessage, restApi).extend({
|
export default mixins(showMessage).extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
EnterpriseEditionFeature,
|
EnterpriseEditionFeature,
|
||||||
@@ -142,7 +140,7 @@ export default mixins(showMessage, restApi).extend({
|
|||||||
this.saveDestination();
|
this.saveDestination();
|
||||||
},
|
},
|
||||||
async saveDestination() {
|
async saveDestination() {
|
||||||
await saveDestinationToDb(this.restApi(), this.nodeParameters);
|
await this.logStreamingStore.saveDestination(this.nodeParameters);
|
||||||
},
|
},
|
||||||
async onAction(action: string) {
|
async onAction(action: string) {
|
||||||
if (action === DESTINATION_LIST_ITEM_ACTIONS.OPEN) {
|
if (action === DESTINATION_LIST_ITEM_ACTIONS.OPEN) {
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ import mixins from 'vue-typed-mixins';
|
|||||||
import { useLogStreamingStore } from '../../stores/logStreamingStore';
|
import { useLogStreamingStore } from '../../stores/logStreamingStore';
|
||||||
import { useNDVStore } from '../../stores/ndv';
|
import { useNDVStore } from '../../stores/ndv';
|
||||||
import { useWorkflowsStore } from '../../stores/workflows';
|
import { useWorkflowsStore } from '../../stores/workflows';
|
||||||
import { restApi } from '../../mixins/restApi';
|
|
||||||
import ParameterInputList from '@/components/ParameterInputList.vue';
|
import ParameterInputList from '@/components/ParameterInputList.vue';
|
||||||
import NodeCredentials from '@/components/NodeCredentials.vue';
|
import NodeCredentials from '@/components/NodeCredentials.vue';
|
||||||
import { IMenuItem, INodeUi, ITab, IUpdateInformation } from '../../Interface';
|
import { IMenuItem, INodeUi, ITab, IUpdateInformation } from '../../Interface';
|
||||||
@@ -200,7 +199,7 @@ import Modal from '@/components/Modal.vue';
|
|||||||
import { showMessage } from '@/mixins/showMessage';
|
import { showMessage } from '@/mixins/showMessage';
|
||||||
import { useUIStore } from '../../stores/ui';
|
import { useUIStore } from '../../stores/ui';
|
||||||
import { useUsersStore } from '../../stores/users';
|
import { useUsersStore } from '../../stores/users';
|
||||||
import { destinationToFakeINodeUi, saveDestinationToDb, sendTestMessage } from './Helpers.ee';
|
import { destinationToFakeINodeUi } from './Helpers.ee';
|
||||||
import {
|
import {
|
||||||
webhookModalDescription,
|
webhookModalDescription,
|
||||||
sentryModalDescription,
|
sentryModalDescription,
|
||||||
@@ -212,7 +211,7 @@ import SaveButton from '../SaveButton.vue';
|
|||||||
import EventSelection from '@/components/SettingsLogStreaming/EventSelection.ee.vue';
|
import EventSelection from '@/components/SettingsLogStreaming/EventSelection.ee.vue';
|
||||||
import { Checkbox } from 'element-ui';
|
import { Checkbox } from 'element-ui';
|
||||||
|
|
||||||
export default mixins(showMessage, restApi).extend({
|
export default mixins(showMessage).extend({
|
||||||
name: 'event-destination-settings-modal',
|
name: 'event-destination-settings-modal',
|
||||||
props: {
|
props: {
|
||||||
modalName: String,
|
modalName: String,
|
||||||
@@ -427,12 +426,14 @@ export default mixins(showMessage, restApi).extend({
|
|||||||
this.nodeParameters = deepCopy(nodeParameters);
|
this.nodeParameters = deepCopy(nodeParameters);
|
||||||
this.workflowsStore.updateNodeProperties({
|
this.workflowsStore.updateNodeProperties({
|
||||||
name: this.node.name,
|
name: this.node.name,
|
||||||
properties: { parameters: this.nodeParameters as unknown as IDataObject },
|
properties: { parameters: this.nodeParameters as unknown as IDataObject, position: [0, 0] },
|
||||||
});
|
});
|
||||||
this.logStreamingStore.updateDestination(this.nodeParameters);
|
if (this.hasOnceBeenSaved) {
|
||||||
|
this.logStreamingStore.updateDestination(this.nodeParameters);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async sendTestEvent() {
|
async sendTestEvent() {
|
||||||
this.testMessageResult = await sendTestMessage(this.restApi(), this.nodeParameters);
|
this.testMessageResult = await this.logStreamingStore.sendTestMessage(this.nodeParameters);
|
||||||
this.testMessageSent = true;
|
this.testMessageSent = true;
|
||||||
},
|
},
|
||||||
async removeThis() {
|
async removeThis() {
|
||||||
@@ -467,12 +468,14 @@ export default mixins(showMessage, restApi).extend({
|
|||||||
if (this.unchanged || !this.destination.id) {
|
if (this.unchanged || !this.destination.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await saveDestinationToDb(this.restApi(), this.nodeParameters);
|
const saveResult = await this.logStreamingStore.saveDestination(this.nodeParameters);
|
||||||
this.hasOnceBeenSaved = true;
|
if (saveResult === true) {
|
||||||
this.testMessageSent = false;
|
this.hasOnceBeenSaved = true;
|
||||||
this.unchanged = true;
|
this.testMessageSent = false;
|
||||||
this.$props.eventBus.$emit('destinationWasSaved', this.destination.id);
|
this.unchanged = true;
|
||||||
this.uiStore.stateIsDirty = false;
|
this.$props.eventBus.$emit('destinationWasSaved', this.destination.id);
|
||||||
|
this.uiStore.stateIsDirty = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { INodeCredentials, INodeParameters, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
import { INodeCredentials, INodeParameters, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||||
import { INodeUi, IRestApi } from '../../Interface';
|
import { INodeUi } from '../../Interface';
|
||||||
import { useLogStreamingStore } from '../../stores/logStreamingStore';
|
|
||||||
|
|
||||||
export function destinationToFakeINodeUi(
|
export function destinationToFakeINodeUi(
|
||||||
destination: MessageEventBusDestinationOptions,
|
destination: MessageEventBusDestinationOptions,
|
||||||
@@ -20,39 +19,3 @@ export function destinationToFakeINodeUi(
|
|||||||
},
|
},
|
||||||
} as INodeUi;
|
} as INodeUi;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveDestinationToDb(
|
|
||||||
restApi: IRestApi,
|
|
||||||
destination: MessageEventBusDestinationOptions,
|
|
||||||
) {
|
|
||||||
const logStreamingStore = useLogStreamingStore();
|
|
||||||
if (destination.id) {
|
|
||||||
const data: MessageEventBusDestinationOptions = {
|
|
||||||
...destination,
|
|
||||||
subscribedEvents: logStreamingStore.getSelectedEvents(destination.id),
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
await restApi.makeRestApiRequest('POST', '/eventbus/destination', data);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
logStreamingStore.updateDestination(destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sendTestMessage(
|
|
||||||
restApi: IRestApi,
|
|
||||||
destination: MessageEventBusDestinationOptions,
|
|
||||||
) {
|
|
||||||
if (destination.id) {
|
|
||||||
try {
|
|
||||||
const sendResult = await restApi.makeRestApiRequest('GET', '/eventbus/testmessage', {
|
|
||||||
id: destination.id,
|
|
||||||
});
|
|
||||||
return sendResult;
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
import { deepCopy, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
import { deepCopy, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
|
import {
|
||||||
|
deleteDestinationFromDb,
|
||||||
|
getDestinationsFromBackend,
|
||||||
|
getEventNamesFromBackend,
|
||||||
|
saveDestinationToDb,
|
||||||
|
sendTestMessageToDestination,
|
||||||
|
} from '../api/eventbus.ee';
|
||||||
|
import { useRootStore } from './n8nRootStore';
|
||||||
|
|
||||||
export interface EventSelectionItem {
|
export interface EventSelectionItem {
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
@@ -8,18 +16,19 @@ export interface EventSelectionItem {
|
|||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventSelectionGroup extends EventSelectionItem {
|
interface EventSelectionGroup extends EventSelectionItem {
|
||||||
children: EventSelectionItem[];
|
children: EventSelectionItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TreeAndSelectionStoreItem {
|
interface DestinationStoreItem {
|
||||||
destination: MessageEventBusDestinationOptions;
|
destination: MessageEventBusDestinationOptions;
|
||||||
selectedEvents: Set<string>;
|
selectedEvents: Set<string>;
|
||||||
eventGroups: EventSelectionGroup[];
|
eventGroups: EventSelectionGroup[];
|
||||||
|
isNew: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DestinationSettingsStore {
|
export interface DestinationSettingsStore {
|
||||||
[key: string]: TreeAndSelectionStoreItem;
|
[key: string]: DestinationStoreItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useLogStreamingStore = defineStore('logStreaming', {
|
export const useLogStreamingStore = defineStore('logStreaming', {
|
||||||
@@ -51,13 +60,15 @@ export const useLogStreamingStore = defineStore('logStreaming', {
|
|||||||
return destinations;
|
return destinations;
|
||||||
},
|
},
|
||||||
updateDestination(destination: MessageEventBusDestinationOptions) {
|
updateDestination(destination: MessageEventBusDestinationOptions) {
|
||||||
this.$patch((state) => {
|
if (destination.id && destination.id in this.items) {
|
||||||
if (destination.id && destination.id in this.items) {
|
this.$patch((state) => {
|
||||||
state.items[destination.id].destination = destination;
|
if (destination.id && destination.id in this.items) {
|
||||||
}
|
state.items[destination.id].destination = destination;
|
||||||
// to trigger refresh
|
}
|
||||||
state.items = deepCopy(state.items);
|
// to trigger refresh
|
||||||
});
|
state.items = deepCopy(state.items);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
removeDestination(destinationId: string) {
|
removeDestination(destinationId: string) {
|
||||||
if (!destinationId) return;
|
if (!destinationId) return;
|
||||||
@@ -159,7 +170,8 @@ export const useLogStreamingStore = defineStore('logStreaming', {
|
|||||||
destination,
|
destination,
|
||||||
selectedEvents: new Set<string>(),
|
selectedEvents: new Set<string>(),
|
||||||
eventGroups: [],
|
eventGroups: [],
|
||||||
} as TreeAndSelectionStoreItem;
|
isNew: false,
|
||||||
|
} as DestinationStoreItem;
|
||||||
}
|
}
|
||||||
this.items[destination.id]?.selectedEvents?.clear();
|
this.items[destination.id]?.selectedEvents?.clear();
|
||||||
if (destination.subscribedEvents) {
|
if (destination.subscribedEvents) {
|
||||||
@@ -173,6 +185,44 @@ export const useLogStreamingStore = defineStore('logStreaming', {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async saveDestination(destination: MessageEventBusDestinationOptions): Promise<boolean> {
|
||||||
|
if (destination.id) {
|
||||||
|
const rootStore = useRootStore();
|
||||||
|
const selectedEvents = this.getSelectedEvents(destination.id);
|
||||||
|
try {
|
||||||
|
await saveDestinationToDb(rootStore.getRestApiContext, destination, selectedEvents);
|
||||||
|
this.updateDestination(destination);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
async sendTestMessage(destination: MessageEventBusDestinationOptions) {
|
||||||
|
if (destination.id) {
|
||||||
|
const rootStore = useRootStore();
|
||||||
|
const testResult = await sendTestMessageToDestination(
|
||||||
|
rootStore.getRestApiContext,
|
||||||
|
destination,
|
||||||
|
);
|
||||||
|
return testResult;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
async fetchEventNames(): Promise<string[]> {
|
||||||
|
const rootStore = useRootStore();
|
||||||
|
return getEventNamesFromBackend(rootStore.getRestApiContext);
|
||||||
|
},
|
||||||
|
async fetchDestinations(): Promise<MessageEventBusDestinationOptions[]> {
|
||||||
|
const rootStore = useRootStore();
|
||||||
|
return getDestinationsFromBackend(rootStore.getRestApiContext);
|
||||||
|
},
|
||||||
|
async deleteDestination(destinationId: string) {
|
||||||
|
const rootStore = useRootStore();
|
||||||
|
await deleteDestinationFromDb(rootStore.getRestApiContext, destinationId);
|
||||||
|
this.removeDestination(destinationId);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ import { useSettingsStore } from '../stores/settings';
|
|||||||
import { useUIStore } from '../stores/ui';
|
import { useUIStore } from '../stores/ui';
|
||||||
import { LOG_STREAM_MODAL_KEY, EnterpriseEditionFeature } from '../constants';
|
import { LOG_STREAM_MODAL_KEY, EnterpriseEditionFeature } from '../constants';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { restApi } from '../mixins/restApi';
|
|
||||||
import {
|
import {
|
||||||
deepCopy,
|
deepCopy,
|
||||||
defaultMessageEventBusDestinationOptions,
|
defaultMessageEventBusDestinationOptions,
|
||||||
@@ -99,7 +98,7 @@ import {
|
|||||||
import PageViewLayout from '@/components/layouts/PageViewLayout.vue';
|
import PageViewLayout from '@/components/layouts/PageViewLayout.vue';
|
||||||
import EventDestinationCard from '@/components/SettingsLogStreaming/EventDestinationCard.ee.vue';
|
import EventDestinationCard from '@/components/SettingsLogStreaming/EventDestinationCard.ee.vue';
|
||||||
|
|
||||||
export default mixins(restApi).extend({
|
export default mixins().extend({
|
||||||
name: 'SettingsLogStreamingView',
|
name: 'SettingsLogStreamingView',
|
||||||
props: {},
|
props: {},
|
||||||
components: {
|
components: {
|
||||||
@@ -125,7 +124,7 @@ export default mixins(restApi).extend({
|
|||||||
this.uiStore.nodeViewInitialized = false;
|
this.uiStore.nodeViewInitialized = false;
|
||||||
|
|
||||||
// fetch Destination data from the backend
|
// fetch Destination data from the backend
|
||||||
await this.getDestinationDataFromREST();
|
await this.getDestinationDataFromBackend();
|
||||||
|
|
||||||
// since we are not really integrated into the hooks, we listen to the store and refresh the destinations
|
// since we are not really integrated into the hooks, we listen to the store and refresh the destinations
|
||||||
this.logStreamingStore.$onAction(({ name, after }) => {
|
this.logStreamingStore.$onAction(({ name, after }) => {
|
||||||
@@ -174,18 +173,18 @@ export default mixins(restApi).extend({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getDestinationDataFromREST(): Promise<any> {
|
async getDestinationDataFromBackend(): Promise<void> {
|
||||||
this.logStreamingStore.clearEventNames();
|
this.logStreamingStore.clearEventNames();
|
||||||
this.logStreamingStore.clearDestinationItemTrees();
|
this.logStreamingStore.clearDestinationItemTrees();
|
||||||
this.allDestinations = [];
|
this.allDestinations = [];
|
||||||
const eventNamesData = await this.restApi().makeRestApiRequest('get', '/eventbus/eventnames');
|
const eventNamesData = await this.logStreamingStore.fetchEventNames();
|
||||||
if (eventNamesData) {
|
if (eventNamesData) {
|
||||||
for (const eventName of eventNamesData) {
|
for (const eventName of eventNamesData) {
|
||||||
this.logStreamingStore.addEventName(eventName);
|
this.logStreamingStore.addEventName(eventName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const destinationData: MessageEventBusDestinationOptions[] =
|
const destinationData: MessageEventBusDestinationOptions[] =
|
||||||
await this.restApi().makeRestApiRequest('get', '/eventbus/destination');
|
await this.logStreamingStore.fetchDestinations();
|
||||||
if (destinationData) {
|
if (destinationData) {
|
||||||
for (const destination of destinationData) {
|
for (const destination of destinationData) {
|
||||||
this.logStreamingStore.addDestination(destination);
|
this.logStreamingStore.addDestination(destination);
|
||||||
@@ -218,11 +217,7 @@ export default mixins(restApi).extend({
|
|||||||
},
|
},
|
||||||
async onRemove(destinationId?: string) {
|
async onRemove(destinationId?: string) {
|
||||||
if (!destinationId) return;
|
if (!destinationId) return;
|
||||||
await this.restApi().makeRestApiRequest(
|
await this.logStreamingStore.deleteDestination(destinationId);
|
||||||
'DELETE',
|
|
||||||
`/eventbus/destination?id=${destinationId}`,
|
|
||||||
);
|
|
||||||
this.logStreamingStore.removeDestination(destinationId);
|
|
||||||
const foundNode = this.workflowsStore.getNodeByName(destinationId);
|
const foundNode = this.workflowsStore.getNodeByName(destinationId);
|
||||||
if (foundNode) {
|
if (foundNode) {
|
||||||
this.workflowsStore.removeNode(foundNode);
|
this.workflowsStore.removeNode(foundNode);
|
||||||
|
|||||||
Reference in New Issue
Block a user