mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
refactor(editor): Migrate part of the vuex store to pinia (#4484)
* ✨ Added pinia support. Migrated community nodes module. * ✨ Added ui pinia store, moved some data from root store to it, updated modals to work with pinia stores * ✨ Added ui pinia store and migrated a part of the root store * ✨ Migrated `settings` store to pinia * ✨ Removing vuex store refs from router * ✨ Migrated `users` module to pinia store * ⚡ Fixing errors after sync with master * ⚡ One more error after merge * ⚡ Created `workflows` pinia store. Moved large part of root store to it. Started updating references. * ✨ Finished migrating workflows store to pinia * ⚡ Renaming some getters and actions to make more sense * ✨ Finished migrating the root store to pinia * ✨ Migrated ndv store to pinia * ⚡ Renaming main panel dimensions getter so it doesn't clash with data prop name * ✔️ Fixing lint errors * ✨ Migrated `templates` store to pinia * ✨ Migrated the `nodeTypes`store * ⚡ Removed unused pieces of code and oold vuex modules * ✨ Adding vuex calls to pinia store, fi xing wrong references * 💄 Removing leftover $store refs * ⚡ Added legacy getters and mutations to store to support webhooks * ⚡ Added missing front-end hooks, updated vuex state subscriptions to pinia * ✔️ Fixing linting errors * ⚡ Removing vue composition api plugin * ⚡ Fixing main sidebar state when loading node view * 🐛 Fixing an error when activating workflows * 🐛 Fixing isses with workflow settings and executions auto-refresh * 🐛 Removing duplicate listeners which cause import error * 🐛 Fixing route authentication * ⚡ Updating freshly pulled $store refs * Adding deleted const * ⚡ Updating store references in ee features. Reseting NodeView credentials update flag when resetting workspace * ⚡ Adding return type to email submission modal * ⚡ Making NodeView only react to paste event when active * 🐛 Fixing signup view errors * 👌 Addressing PR review comments * 👌 Addressing new PR comments * 👌 Updating invite id logic in signup view
This commit is contained in:
parent
c2c7927414
commit
40e413d958
100
package-lock.json
generated
100
package-lock.json
generated
|
@ -9090,6 +9090,11 @@
|
|||
"yallist": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-api": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
|
||||
"integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
|
||||
},
|
||||
"node_modules/@vue/eslint-config-typescript": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-11.0.2.tgz",
|
||||
|
@ -27057,6 +27062,31 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "2.0.23",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz",
|
||||
"integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.4.4",
|
||||
"vue-demi": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.4.0",
|
||||
"typescript": ">=4.4.4",
|
||||
"vue": "^2.6.14 || ^3.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinkie": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
||||
|
@ -35718,6 +35748,31 @@
|
|||
"tinycolor2": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-demi": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
|
||||
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-docgen-api": {
|
||||
"version": "4.54.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-4.54.2.tgz",
|
||||
|
@ -38517,6 +38572,7 @@
|
|||
"n8n-design-system": "~0.40.0",
|
||||
"n8n-workflow": "~0.122.1",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"pinia": "^2.0.22",
|
||||
"prismjs": "^1.17.1",
|
||||
"quill": "2.0.0-dev.4",
|
||||
"quill-autoformat": "^0.1.1",
|
||||
|
@ -42784,7 +42840,7 @@
|
|||
"functional-red-black-tree": "^1.0.1",
|
||||
"glob-parent": "^6.0.1",
|
||||
"globals": "^13.15.0",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^11.1.0",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.0.0",
|
||||
|
@ -43016,7 +43072,7 @@
|
|||
"@oclif/errors": "^1.3.6",
|
||||
"@oclif/parser": "^3.8.8",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^11.1.0",
|
||||
"is-wsl": "^2.1.1",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
|
@ -43042,10 +43098,10 @@
|
|||
"clean-stack": "^3.0.1",
|
||||
"cli-progress": "^3.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"ejs": "^3.1.8",
|
||||
"ejs": "^3.1.6",
|
||||
"fs-extra": "^9.1.0",
|
||||
"get-package-type": "^0.1.0",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^11.1.0",
|
||||
"hyperlinker": "^1.0.0",
|
||||
"indent-string": "^4.0.0",
|
||||
"is-wsl": "^2.2.0",
|
||||
|
@ -43262,7 +43318,7 @@
|
|||
"@oclif/errors": "^1.3.3",
|
||||
"@oclif/parser": "^3.8.0",
|
||||
"debug": "^4.1.1",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^11.0.1",
|
||||
"is-wsl": "^2.1.1",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
|
@ -43855,7 +43911,7 @@
|
|||
"css-loader": "^3.6.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"find-up": "^5.0.0",
|
||||
"fork-ts-checker-webpack-plugin": "^6.0.4",
|
||||
"fork-ts-checker-webpack-plugin": "^4.1.6",
|
||||
"glob": "^7.1.6",
|
||||
"glob-promise": "^3.4.0",
|
||||
"global": "^4.4.0",
|
||||
|
@ -45971,7 +46027,7 @@
|
|||
"@typescript-eslint/types": "5.42.0",
|
||||
"@typescript-eslint/visitor-keys": "5.42.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.7",
|
||||
"tsutils": "^3.21.0"
|
||||
|
@ -46249,6 +46305,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@vue/devtools-api": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
|
||||
"integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
|
||||
},
|
||||
"@vue/eslint-config-typescript": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-11.0.2.tgz",
|
||||
|
@ -47273,7 +47334,7 @@
|
|||
"integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.21.3",
|
||||
"browserslist": "^4.12.0",
|
||||
"caniuse-lite": "^1.0.30001109",
|
||||
"normalize-range": "^0.1.2",
|
||||
"num2fraction": "^1.2.2",
|
||||
|
@ -49868,7 +49929,7 @@
|
|||
"integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.21.3"
|
||||
"browserslist": "^4.21.4"
|
||||
}
|
||||
},
|
||||
"core-js-pure": {
|
||||
|
@ -49936,7 +49997,7 @@
|
|||
"requires": {
|
||||
"arrify": "^2.0.1",
|
||||
"cp-file": "^7.0.0",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^9.2.0",
|
||||
"has-glob": "^1.0.0",
|
||||
"junk": "^3.1.0",
|
||||
"nested-error-stacks": "^2.1.0",
|
||||
|
@ -58963,6 +59024,7 @@
|
|||
"n8n-design-system": "~0.40.0",
|
||||
"n8n-workflow": "~0.122.1",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"pinia": "^2.0.22",
|
||||
"prismjs": "^1.17.1",
|
||||
"quill": "2.0.0-dev.4",
|
||||
"quill-autoformat": "^0.1.1",
|
||||
|
@ -61151,6 +61213,15 @@
|
|||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
|
||||
"dev": true
|
||||
},
|
||||
"pinia": {
|
||||
"version": "2.0.23",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz",
|
||||
"integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.4.4",
|
||||
"vue-demi": "*"
|
||||
}
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
||||
|
@ -61952,7 +62023,7 @@
|
|||
"fs-extra": "^6.0.1",
|
||||
"get-stream": "^5.1.0",
|
||||
"glob": "^7.1.2",
|
||||
"globby": "^11.0.2",
|
||||
"globby": "^10.0.1",
|
||||
"http-call": "^5.1.2",
|
||||
"load-json-file": "^6.2.0",
|
||||
"pkg-dir": "^4.2.0",
|
||||
|
@ -67643,7 +67714,7 @@
|
|||
"consola": "^2.15.3",
|
||||
"dotenv": "^16.0.0",
|
||||
"dotenv-expand": "^8.0.2",
|
||||
"ejs": "^3.1.8",
|
||||
"ejs": "^3.1.6",
|
||||
"fast-glob": "^3.2.11",
|
||||
"fs-extra": "^10.0.1",
|
||||
"html-minifier-terser": "^6.1.0",
|
||||
|
@ -67820,6 +67891,11 @@
|
|||
"tinycolor2": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"vue-demi": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
|
||||
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A=="
|
||||
},
|
||||
"vue-docgen-api": {
|
||||
"version": "4.54.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-4.54.2.tgz",
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
"n8n-design-system": "~0.41.0",
|
||||
"n8n-workflow": "~0.123.0",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"pinia": "^2.0.22",
|
||||
"prismjs": "^1.17.1",
|
||||
"quill": "2.0.0-dev.4",
|
||||
"quill-autoformat": "^0.1.1",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
id="app"
|
||||
:class="{
|
||||
[$style.container]: true,
|
||||
[$style.sidebarCollapsed]: sidebarMenuCollapsed
|
||||
[$style.sidebarCollapsed]: uiStore.sidebarMenuCollapsed
|
||||
}"
|
||||
>
|
||||
<div id="header" :class="$style.header">
|
||||
|
@ -35,11 +35,17 @@ import { HIRING_BANNER, LOCAL_STORAGE_THEME, VIEWS } from './constants';
|
|||
import mixins from 'vue-typed-mixins';
|
||||
import { showMessage } from './components/mixins/showMessage';
|
||||
import { IUser } from './Interface';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { userHelpers } from './components/mixins/userHelpers';
|
||||
import { loadLanguage } from './plugins/i18n';
|
||||
import { restApi } from '@/components/mixins/restApi';
|
||||
import { globalLinkActions } from '@/components/mixins/globalLinkActions';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from './stores/ui';
|
||||
import { useSettingsStore } from './stores/settings';
|
||||
import { useUsersStore } from './stores/users';
|
||||
import { useRootStore } from './stores/n8nRootStore';
|
||||
import { useTemplatesStore } from './stores/templates';
|
||||
import { useNodeTypesStore } from './stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -54,11 +60,16 @@ export default mixins(
|
|||
Modals,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('settings', ['isHiringBannerEnabled', 'isTemplatesEnabled', 'isTemplatesEndpointReachable', 'isUserManagementEnabled', 'showSetupPage']),
|
||||
...mapGetters('users', ['currentUser']),
|
||||
...mapGetters('ui', ['sidebarMenuCollapsed']),
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useTemplatesStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
),
|
||||
defaultLocale (): string {
|
||||
return this.$store.getters.defaultLocale;
|
||||
return this.rootStore.defaultLocale;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
@ -69,7 +80,7 @@ export default mixins(
|
|||
methods: {
|
||||
async initSettings(): Promise<void> {
|
||||
try {
|
||||
await this.$store.dispatch('settings/getSettings');
|
||||
await this.settingsStore.getSettings();
|
||||
} catch (e) {
|
||||
this.$showToast({
|
||||
title: this.$locale.baseText('startupError'),
|
||||
|
@ -81,23 +92,22 @@ export default mixins(
|
|||
throw e;
|
||||
}
|
||||
},
|
||||
async loginWithCookie(): Promise<void> {
|
||||
loginWithCookie(): void {
|
||||
try {
|
||||
await this.$store.dispatch('users/loginWithCookie');
|
||||
this.usersStore.loginWithCookie();
|
||||
} catch (e) {}
|
||||
},
|
||||
async initTemplates(): Promise<void> {
|
||||
if (!this.isTemplatesEnabled) {
|
||||
if (!this.settingsStore.isTemplatesEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('settings/testTemplatesEndpoint');
|
||||
} catch (e) {
|
||||
await this.settingsStore.testTemplatesEndpoint();
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
logHiringBanner() {
|
||||
if (this.isHiringBannerEnabled && this.$route.name !== VIEWS.DEMO) {
|
||||
if (this.settingsStore.isHiringBannerEnabled && this.$route.name !== VIEWS.DEMO) {
|
||||
console.log(HIRING_BANNER); // eslint-disable-line no-console
|
||||
}
|
||||
},
|
||||
|
@ -105,20 +115,20 @@ export default mixins(
|
|||
await this.initSettings();
|
||||
await Promise.all([this.loginWithCookie(), this.initTemplates()]);
|
||||
},
|
||||
trackPage() {
|
||||
this.$store.commit('ui/setCurrentView', this.$route.name);
|
||||
trackPage(): void {
|
||||
this.uiStore.currentView = this.$route.name || '';
|
||||
if (this.$route && this.$route.meta && this.$route.meta.templatesEnabled) {
|
||||
this.$store.commit('templates/setSessionId');
|
||||
this.templatesStore.setSessionId();
|
||||
}
|
||||
else {
|
||||
this.$store.commit('templates/resetSessionId'); // reset telemetry session id when user leaves template pages
|
||||
this.templatesStore.resetSessionId(); // reset telemetry session id when user leaves template pages
|
||||
}
|
||||
|
||||
this.$telemetry.page(this.$route);
|
||||
},
|
||||
authenticate() {
|
||||
// redirect to setup page. user should be redirected to this only once
|
||||
if (this.isUserManagementEnabled && this.showSetupPage) {
|
||||
if (this.settingsStore.isUserManagementEnabled && this.settingsStore.showSetupPage) {
|
||||
if (this.$route.name === VIEWS.SETUP) {
|
||||
return;
|
||||
}
|
||||
|
@ -132,7 +142,7 @@ export default mixins(
|
|||
}
|
||||
|
||||
// if cannot access page and not logged in, ask to sign in
|
||||
const user = this.currentUser as IUser | null;
|
||||
const user = this.usersStore.currentUser;
|
||||
if (!user) {
|
||||
const redirect =
|
||||
this.$route.query.redirect ||
|
||||
|
@ -154,7 +164,7 @@ export default mixins(
|
|||
this.$router.replace({ name: VIEWS.HOMEPAGE });
|
||||
},
|
||||
redirectIfNecessary() {
|
||||
const redirect = this.$route.meta && typeof this.$route.meta.getRedirect === 'function' && this.$route.meta.getRedirect(this.$store);
|
||||
const redirect = this.$route.meta && typeof this.$route.meta.getRedirect === 'function' && this.$route.meta.getRedirect();
|
||||
if (redirect) {
|
||||
this.$router.replace(redirect);
|
||||
}
|
||||
|
@ -176,10 +186,11 @@ export default mixins(
|
|||
this.loading = false;
|
||||
|
||||
this.trackPage();
|
||||
// TODO: Un-comment once front-end hooks are updated to work with pinia store
|
||||
this.$externalHooks().run('app.mount');
|
||||
|
||||
if (this.defaultLocale !== 'en') {
|
||||
void this.$store.dispatch('nodeTypes/getNodeTranslationHeaders');
|
||||
await this.nodeTypesStore.getNodeTranslationHeaders();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { IMenuItem } from 'n8n-design-system';
|
||||
import {
|
||||
jsPlumbInstance,
|
||||
DragOptions,
|
||||
|
@ -33,6 +34,7 @@ import {
|
|||
ILoadOptions,
|
||||
INodeCredentials,
|
||||
INodeListSearchItems,
|
||||
NodeParameterValueType,
|
||||
} from 'n8n-workflow';
|
||||
import { FAKE_DOOR_FEATURES } from './constants';
|
||||
|
||||
|
@ -152,8 +154,8 @@ export type IJsPlumbInstance = Omit<jsPlumbInstance, 'addEndpoint' | 'draggable'
|
|||
|
||||
export interface IUpdateInformation {
|
||||
name: string;
|
||||
key: string;
|
||||
value: string | number | { [key: string]: string | number | boolean }; // with null makes problems in NodeSettings.vue
|
||||
key?: string;
|
||||
value: string | number | { [key: string]: string | number | boolean } | NodeParameterValueType | INodeParameters; // with null makes problems in NodeSettings.vue
|
||||
node?: string;
|
||||
oldValue?: string | number;
|
||||
}
|
||||
|
@ -887,6 +889,47 @@ export interface INodeMetadata {
|
|||
parametersLastUpdatedAt?: number;
|
||||
}
|
||||
|
||||
export interface WorkflowsState {
|
||||
activeExecutions: IExecutionsCurrentSummaryExtended[];
|
||||
activeWorkflows: string[];
|
||||
activeWorkflowExecution: IExecutionsSummary | null;
|
||||
currentWorkflowExecutions: IExecutionsSummary[];
|
||||
activeExecutionId: string | null;
|
||||
executingNode: string | null;
|
||||
executionWaitingForWebhook: boolean;
|
||||
finishedExecutionsCount: number;
|
||||
nodeMetadata: NodeMetadataMap;
|
||||
subWorkflowExecutionError: Error | null;
|
||||
workflow: IWorkflowDb;
|
||||
workflowExecutionData: IExecutionResponse | null;
|
||||
workflowExecutionPairedItemMappings: {[itemId: string]: Set<string>};
|
||||
workflowsById: IWorkflowsMap;
|
||||
}
|
||||
|
||||
export interface RootState {
|
||||
baseUrl: string;
|
||||
defaultLocale: string;
|
||||
endpointWebhook: string;
|
||||
endpointWebhookTest: string;
|
||||
pushConnectionActive: boolean;
|
||||
timezone: string;
|
||||
executionTimeout: number;
|
||||
maxExecutionTimeout: number;
|
||||
versionCli: string;
|
||||
oauthCallbackUrls: object;
|
||||
n8nMetadata: {
|
||||
[key: string]: string | number | undefined;
|
||||
};
|
||||
sessionId: string;
|
||||
urlBaseWebhook: string;
|
||||
urlBaseEditor: string;
|
||||
instanceId: string;
|
||||
isNpmAvailable: boolean;
|
||||
}
|
||||
|
||||
export interface NodeMetadataMap {
|
||||
[nodeName: string]: INodeMetadata;
|
||||
}
|
||||
export interface IRootState {
|
||||
activeExecutions: IExecutionsCurrentSummaryExtended[];
|
||||
activeWorkflows: string[];
|
||||
|
@ -924,12 +967,12 @@ export interface IRootState {
|
|||
workflowsById: IWorkflowsMap;
|
||||
sidebarMenuItems: IMenuItem[];
|
||||
instanceId: string;
|
||||
nodeMetadata: {[nodeName: string]: INodeMetadata};
|
||||
nodeMetadata: NodeMetadataMap;
|
||||
isNpmAvailable: boolean;
|
||||
subworkflowExecutionError: Error | null;
|
||||
}
|
||||
|
||||
export interface ICommunityPackageMap {
|
||||
export interface CommunityPackageMap {
|
||||
[name: string]: PublicInstalledPackage;
|
||||
}
|
||||
|
||||
|
@ -964,6 +1007,7 @@ export interface IModalState {
|
|||
}
|
||||
|
||||
export type IRunDataDisplayMode = 'table' | 'json' | 'binary';
|
||||
export type nodePanelType = 'input' | 'output';
|
||||
|
||||
export interface TargetItem {
|
||||
nodeName: string;
|
||||
|
@ -1023,6 +1067,37 @@ export interface IUiState {
|
|||
executionSidebarAutoRefresh: boolean;
|
||||
}
|
||||
|
||||
export interface UIState {
|
||||
activeActions: string[];
|
||||
activeCredentialType: string | null;
|
||||
sidebarMenuCollapsed: boolean;
|
||||
modalStack: string[];
|
||||
modals: {
|
||||
[key: string]: IModalState;
|
||||
};
|
||||
isPageLoading: boolean;
|
||||
currentView: string;
|
||||
mainPanelPosition: number;
|
||||
fakeDoorFeatures: IFakeDoor[];
|
||||
draggable: {
|
||||
isDragging: boolean;
|
||||
type: string;
|
||||
data: string;
|
||||
canDrop: boolean;
|
||||
stickyPosition: null | XYPosition;
|
||||
};
|
||||
stateIsDirty: boolean;
|
||||
lastSelectedNode: string | null;
|
||||
lastSelectedNodeOutputIndex: number | null;
|
||||
nodeViewOffsetPosition: XYPosition;
|
||||
nodeViewMoveInProgress: boolean;
|
||||
selectedNodes: INodeUi[];
|
||||
sidebarMenuItems: IMenuItem[];
|
||||
nodeViewInitialized: boolean;
|
||||
addFirstStepOnLoad: boolean;
|
||||
executionSidebarAutoRefresh: boolean;
|
||||
}
|
||||
|
||||
export type ILogLevel = 'info' | 'debug' | 'warn' | 'error' | 'verbose';
|
||||
|
||||
export type IFakeDoor = {
|
||||
|
@ -1059,6 +1134,9 @@ export interface ISettingsState {
|
|||
path: string;
|
||||
};
|
||||
onboardingCallPromptEnabled: boolean;
|
||||
saveDataErrorExecution: string;
|
||||
saveDataSuccessExecution: string;
|
||||
saveManualExecutions: boolean;
|
||||
}
|
||||
|
||||
export interface INodeTypesState {
|
||||
|
@ -1109,11 +1187,9 @@ export interface IWorkflowsState {
|
|||
[name: string]: IWorkflowDb;
|
||||
}
|
||||
|
||||
export interface IWorkflowsState {}
|
||||
|
||||
export interface ICommunityNodesState {
|
||||
export interface CommunityNodesState {
|
||||
availablePackageCount: number;
|
||||
installedPackages: ICommunityPackageMap;
|
||||
installedPackages: CommunityPackageMap;
|
||||
}
|
||||
|
||||
export interface IRestApiContext {
|
||||
|
@ -1149,8 +1225,8 @@ export interface IOnboardingCallPromptResponse {
|
|||
|
||||
export interface IOnboardingCallPrompt {
|
||||
title: string;
|
||||
body: string;
|
||||
index: number;
|
||||
description: string;
|
||||
toast_sequence_number: number;
|
||||
}
|
||||
|
||||
export interface ITab {
|
||||
|
@ -1182,3 +1258,14 @@ export interface IResourceLocatorReqParams {
|
|||
export interface IResourceLocatorResultExpanded extends INodeListSearchItems {
|
||||
linkAlt?: string;
|
||||
}
|
||||
|
||||
export interface CurlToJSONResponse {
|
||||
"parameters.url": string;
|
||||
"parameters.authentication": string;
|
||||
"parameters.method": string;
|
||||
"parameters.sendHeaders": boolean;
|
||||
"parameters.headerParameters.parameters.0.name": string;
|
||||
"parameters.headerParameters.parameters.0.value": string;
|
||||
"parameters.sendQuery": boolean;
|
||||
"parameters.sendBody": boolean;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ export async function uninstallPackage(context: IRestApiContext, name: string):
|
|||
return await makeRestApiRequest(context, 'DELETE', '/nodes', { name });
|
||||
}
|
||||
|
||||
export async function updatePackage(context: IRestApiContext, name: string): Promise<void> {
|
||||
export async function updatePackage(context: IRestApiContext, name: string): Promise<PublicInstalledPackage> {
|
||||
return await makeRestApiRequest(context, 'PATCH', '/nodes', { name });
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {IRestApiContext} from "@/Interface";
|
||||
import {CurlToJSONResponse, IRestApiContext} from "@/Interface";
|
||||
import {makeRestApiRequest} from "@/api/helpers";
|
||||
|
||||
export function getCurlToJson(context: IRestApiContext, curlCommand: string): Promise<{ curlCommand: string | null }> {
|
||||
export function getCurlToJson(context: IRestApiContext, curlCommand: string): Promise<CurlToJSONResponse> {
|
||||
return makeRestApiRequest(context, 'POST', '/curl-to-json', { curlCommand });
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { IRestApiContext, IN8nPrompts, IN8nValueSurveyData, IN8nUISettings } from '../Interface';
|
||||
import { IRestApiContext, IN8nPrompts, IN8nValueSurveyData, IN8nUISettings, IN8nPromptResponse } from '../Interface';
|
||||
import { makeRestApiRequest, get, post } from './helpers';
|
||||
import { N8N_IO_BASE_URL, NPM_COMMUNITY_NODE_SEARCH_API_URL } from '@/constants';
|
||||
|
||||
|
@ -10,11 +10,11 @@ export async function getPromptsData(instanceId: string, userId: string): Promis
|
|||
return await get(N8N_IO_BASE_URL, '/prompts', {}, {'n8n-instance-id': instanceId, 'n8n-user-id': userId});
|
||||
}
|
||||
|
||||
export async function submitContactInfo(instanceId: string, userId: string, email: string): Promise<void> {
|
||||
export async function submitContactInfo(instanceId: string, userId: string, email: string): Promise<IN8nPromptResponse> {
|
||||
return await post(N8N_IO_BASE_URL, '/prompt', { email }, {'n8n-instance-id': instanceId, 'n8n-user-id': userId});
|
||||
}
|
||||
|
||||
export async function submitValueSurvey(instanceId: string, userId: string, params: IN8nValueSurveyData): Promise<IN8nPrompts> {
|
||||
export async function submitValueSurvey(instanceId: string, userId: string, params: IN8nValueSurveyData): Promise<IN8nPromptResponse> {
|
||||
return await post(N8N_IO_BASE_URL, '/value-survey', params, {'n8n-instance-id': instanceId, 'n8n-user-id': userId});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { IOnboardingCallPromptResponse, IUser } from "@/Interface";
|
||||
import { IOnboardingCallPrompt, IOnboardingCallPromptResponse, IUser } from "@/Interface";
|
||||
import { get, post } from "./helpers";
|
||||
|
||||
const N8N_API_BASE_URL = 'https://api.n8n.io/api';
|
||||
const ONBOARDING_PROMPTS_ENDPOINT = '/prompts/onboarding';
|
||||
const CONTACT_EMAIL_SUBMISSION_ENDPOINT = '/accounts/onboarding';
|
||||
|
||||
export async function fetchNextOnboardingPrompt(instanceId: string, currentUer: IUser): Promise<IOnboardingCallPromptResponse> {
|
||||
export async function fetchNextOnboardingPrompt(instanceId: string, currentUer: IUser): Promise<IOnboardingCallPrompt> {
|
||||
return await get(
|
||||
N8N_API_BASE_URL,
|
||||
ONBOARDING_PROMPTS_ENDPOINT,
|
||||
|
@ -35,7 +35,7 @@ export async function applyForOnboardingCall(instanceId: string, currentUer: IUs
|
|||
}
|
||||
}
|
||||
|
||||
export async function submitEmailOnSignup(instanceId: string, currentUer: IUser, email: string, agree: boolean): Promise<string> {
|
||||
export async function submitEmailOnSignup(instanceId: string, currentUer: IUser, email: string | undefined, agree: boolean): Promise<string> {
|
||||
return await post(
|
||||
N8N_API_BASE_URL,
|
||||
CONTACT_EMAIL_SUBMISSION_ENDPOINT,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<n8n-text>{{ $locale.baseText('about.n8nVersion') }}</n8n-text>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<n8n-text>{{ versionCli }}</n8n-text>
|
||||
<n8n-text>{{ rootStore.versionCli }}</n8n-text>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
|
@ -39,7 +39,7 @@
|
|||
<n8n-text>{{ $locale.baseText('about.instanceID') }}</n8n-text>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<n8n-text>{{ instanceId }}</n8n-text>
|
||||
<n8n-text>{{ rootStore.instanceId }}</n8n-text>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -55,9 +55,11 @@
|
|||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import Modal from './Modal.vue';
|
||||
import { ABOUT_MODAL_KEY } from '../constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'About',
|
||||
|
@ -71,8 +73,10 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('settings', ['versionCli']),
|
||||
...mapGetters(['instanceId']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
closeDialog() {
|
||||
|
|
|
@ -37,9 +37,13 @@
|
|||
import Vue from 'vue';
|
||||
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import { WORKFLOW_ACTIVE_MODAL_KEY, EXECUTIONS_MODAL_KEY, WORKFLOW_SETTINGS_MODAL_KEY, LOCAL_STORAGE_ACTIVATION_FLAG, VIEWS } from '../constants';
|
||||
import { WORKFLOW_ACTIVE_MODAL_KEY, WORKFLOW_SETTINGS_MODAL_KEY, LOCAL_STORAGE_ACTIVATION_FLAG, VIEWS } from '../constants';
|
||||
import { getActivatableTriggerNodes, getTriggerNodeServiceName } from './helpers';
|
||||
import { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'ActivationModal',
|
||||
|
@ -58,8 +62,8 @@ export default Vue.extend({
|
|||
},
|
||||
methods: {
|
||||
async showExecutionsList () {
|
||||
const activeExecution = this.$store.getters['workflows/getActiveWorkflowExecution'];
|
||||
const currentWorkflow = this.$store.getters.workflowId;
|
||||
const activeExecution = this.workflowsStore.activeWorkflowExecution;
|
||||
const currentWorkflow = this.workflowsStore.workflowId;
|
||||
|
||||
if (activeExecution) {
|
||||
this.$router.push({
|
||||
|
@ -69,10 +73,10 @@ export default Vue.extend({
|
|||
} else {
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME, params: { name: currentWorkflow } }).catch(() => {});
|
||||
}
|
||||
this.$store.commit('ui/closeModal', WORKFLOW_ACTIVE_MODAL_KEY);
|
||||
this.uiStore.closeModal(WORKFLOW_ACTIVE_MODAL_KEY);
|
||||
},
|
||||
async showSettings() {
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
},
|
||||
handleCheckboxChange (checkboxValue: boolean) {
|
||||
this.checked = checkboxValue;
|
||||
|
@ -80,8 +84,13 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
triggerContent (): string {
|
||||
const foundTriggers = getActivatableTriggerNodes(this.$store.getters.workflowTriggerNodes);
|
||||
const foundTriggers = getActivatableTriggerNodes(this.workflowsStore.workflowTriggerNodes);
|
||||
if (!foundTriggers.length) {
|
||||
return '';
|
||||
}
|
||||
|
@ -92,27 +101,28 @@ export default Vue.extend({
|
|||
|
||||
const trigger = foundTriggers[0];
|
||||
|
||||
const triggerNodeType = this.$store.getters['nodeTypes/getNodeType'](trigger.type, trigger.typeVersion) as INodeTypeDescription;
|
||||
if (triggerNodeType.activationMessage) {
|
||||
return triggerNodeType.activationMessage;
|
||||
}
|
||||
const triggerNodeType = this.nodeTypesStore.getNodeType(trigger.type, trigger.typeVersion);
|
||||
if (triggerNodeType) {
|
||||
if (triggerNodeType.activationMessage) {
|
||||
return triggerNodeType.activationMessage;
|
||||
}
|
||||
|
||||
const serviceName = getTriggerNodeServiceName(triggerNodeType);
|
||||
if (trigger.webhookId) {
|
||||
return this.$locale.baseText('activationModal.yourWorkflowWillNowListenForEvents', {
|
||||
interpolate: {
|
||||
serviceName,
|
||||
},
|
||||
});
|
||||
} else if (triggerNodeType.polling) {
|
||||
return this.$locale.baseText('activationModal.yourWorkflowWillNowRegularlyCheck', {
|
||||
interpolate: {
|
||||
serviceName,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return this.$locale.baseText('activationModal.yourTriggerWillNowFire');
|
||||
const serviceName = getTriggerNodeServiceName(triggerNodeType);
|
||||
if (trigger.webhookId) {
|
||||
return this.$locale.baseText('activationModal.yourWorkflowWillNowListenForEvents', {
|
||||
interpolate: {
|
||||
serviceName,
|
||||
},
|
||||
});
|
||||
} else if (triggerNodeType.polling) {
|
||||
return this.$locale.baseText('activationModal.yourWorkflowWillNowRegularlyCheck', {
|
||||
interpolate: {
|
||||
serviceName,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return this.$locale.baseText('activationModal.yourTriggerWillNowFire');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -32,6 +32,8 @@ import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
|||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { restApi } from '@/components/mixins/restApi';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export default mixins(
|
||||
nodeHelpers,
|
||||
|
@ -47,6 +49,9 @@ export default mixins(
|
|||
'windowVisible', // boolean
|
||||
],
|
||||
computed: {
|
||||
...mapStores(
|
||||
useWorkflowsStore,
|
||||
),
|
||||
binaryData (): IBinaryData | null {
|
||||
const binaryData = this.getBinaryData(this.workflowRunData, this.displayData.node, this.displayData.runIndex, this.displayData.outputIndex);
|
||||
|
||||
|
@ -72,12 +77,12 @@ export default mixins(
|
|||
},
|
||||
|
||||
workflowRunData (): IRunData | null {
|
||||
const workflowExecution = this.$store.getters.getWorkflowExecution;
|
||||
const workflowExecution = this.workflowsStore.getWorkflowExecution;
|
||||
if (workflowExecution === null) {
|
||||
return null;
|
||||
}
|
||||
const executionData: IRunExecutionData = workflowExecution.data;
|
||||
return executionData.resultData.runData;
|
||||
const executionData = workflowExecution.data;
|
||||
return executionData? executionData.resultData.runData : null;
|
||||
},
|
||||
|
||||
},
|
||||
|
|
|
@ -31,6 +31,8 @@ import Modal from "./Modal.vue";
|
|||
import Vue from "vue";
|
||||
import { IFormInputs } from "@/Interface";
|
||||
import { CHANGE_PASSWORD_MODAL_KEY } from '../constants';
|
||||
import { mapStores } from "pinia";
|
||||
import { useUsersStore } from "@/stores/users";
|
||||
|
||||
export default mixins(showMessage).extend({
|
||||
components: { Modal },
|
||||
|
@ -50,6 +52,9 @@ export default mixins(showMessage).extend({
|
|||
CHANGE_PASSWORD_MODAL_KEY,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUsersStore),
|
||||
},
|
||||
mounted() {
|
||||
this.config = [
|
||||
{
|
||||
|
@ -115,7 +120,7 @@ export default mixins(showMessage).extend({
|
|||
async onSubmit(values: {[key: string]: string}) {
|
||||
try {
|
||||
this.loading = true;
|
||||
await this.$store.dispatch('users/updateCurrentUserPassword', values);
|
||||
await this.usersStore.updateCurrentUserPassword(values);
|
||||
|
||||
this.$showMessage({
|
||||
type: 'success',
|
||||
|
|
|
@ -32,6 +32,10 @@ import {
|
|||
PLACEHOLDER_FILLED_AT_EXECUTION_TIME,
|
||||
} from '@/constants';
|
||||
import { CodeEditor } from './forms';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
genericHelpers,
|
||||
|
@ -42,6 +46,13 @@ export default mixins(
|
|||
CodeEditor,
|
||||
},
|
||||
props: ['codeAutocomplete', 'parameter', 'path', 'type', 'value', 'readonly'],
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useRootStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
loadAutocompleteData(): string[] {
|
||||
if (['function', 'functionItem'].includes(this.codeAutocomplete)) {
|
||||
|
@ -50,16 +61,16 @@ export default mixins(
|
|||
const mode = 'manual';
|
||||
let runIndex = 0;
|
||||
|
||||
const executedWorkflow: IExecutionResponse | null = this.$store.getters.getWorkflowExecution;
|
||||
const executedWorkflow = this.workflowsStore.getWorkflowExecution;
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const activeNode: INodeUi | null = this.$store.getters['ndv/activeNode'];
|
||||
const activeNode: INodeUi | null = this.ndvStore.activeNode;
|
||||
const parentNode = workflow.getParentNodes(activeNode!.name, inputName, 1);
|
||||
const nodeConnection = workflow.getNodeConnectionIndexes(activeNode!.name, parentNode[0]) || {
|
||||
sourceIndex: 0,
|
||||
destinationIndex: 0,
|
||||
};
|
||||
|
||||
const executionData = this.$store.getters.getWorkflowExecution as IExecutionResponse | null;
|
||||
const executionData = this.workflowsStore.getWorkflowExecution;
|
||||
|
||||
let runExecutionData: IRunExecutionData;
|
||||
if (!executionData || !executionData.data) {
|
||||
|
@ -89,7 +100,7 @@ export default mixins(
|
|||
$resumeWebhookUrl: PLACEHOLDER_FILLED_AT_EXECUTION_TIME,
|
||||
};
|
||||
|
||||
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, activeNode!.name, connectionInputData || [], {}, mode, this.$store.getters.timezone, additionalProxyKeys);
|
||||
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, activeNode!.name, connectionInputData || [], {}, mode, this.rootStore.timezone, additionalProxyKeys);
|
||||
const proxy = dataProxy.getDataProxy();
|
||||
|
||||
const autoCompleteItems = [
|
||||
|
|
|
@ -17,6 +17,8 @@ import { workflowHelpers } from '../mixins/workflowHelpers'; // for json field c
|
|||
import { codeNodeEditorEventBus } from '@/event-bus/code-node-editor-event-bus';
|
||||
import { CODE_NODE_TYPE } from '@/constants';
|
||||
import { ALL_ITEMS_PLACEHOLDER, EACH_ITEM_PLACEHOLDER } from './constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default mixins(linterExtension, completerExtension, workflowHelpers).extend({
|
||||
name: 'code-node-editor',
|
||||
|
@ -47,6 +49,9 @@ export default mixins(linterExtension, completerExtension, workflowHelpers).exte
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
content(): string {
|
||||
if (!this.editor) return '';
|
||||
|
||||
|
@ -119,7 +124,7 @@ export default mixins(linterExtension, completerExtension, workflowHelpers).exte
|
|||
}
|
||||
|
||||
this.$telemetry.track('User autocompleted code', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
node_type: CODE_NODE_TYPE,
|
||||
field_name: this.mode === 'runOnceForAllItems' ? 'jsCodeAllItems' : 'jsCodeEachItem',
|
||||
field_type: 'code',
|
||||
|
|
|
@ -4,6 +4,8 @@ import { addVarType } from '../utils';
|
|||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
function getAutocompletableNodeNames(nodes: INodeUi[]) {
|
||||
return nodes
|
||||
|
@ -12,6 +14,11 @@ function getAutocompletableNodeNames(nodes: INodeUi[]) {
|
|||
}
|
||||
|
||||
export const baseCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
computed: {
|
||||
...mapStores(
|
||||
useWorkflowsStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* - Complete `$` to `$execution $input $prevNode $runIndex $workflow $now $today
|
||||
|
@ -58,7 +65,7 @@ export const baseCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
const options: Completion[] = TOP_LEVEL_COMPLETIONS_IN_BOTH_MODES.map(addVarType);
|
||||
|
||||
options.push(
|
||||
...getAutocompletableNodeNames(this.$store.getters.allNodes).map((nodeName) => {
|
||||
...getAutocompletableNodeNames(this.workflowsStore.allNodes).map((nodeName) => {
|
||||
return {
|
||||
label: `$('${nodeName}')`,
|
||||
type: 'variable',
|
||||
|
@ -96,7 +103,7 @@ export const baseCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
|
||||
if (!preCursor || (preCursor.from === preCursor.to && !context.explicit)) return null;
|
||||
|
||||
const options: Completion[] = getAutocompletableNodeNames(this.$store.getters.allNodes).map(
|
||||
const options: Completion[] = getAutocompletableNodeNames(this.workflowsStore.allNodes).map(
|
||||
(nodeName) => {
|
||||
return {
|
||||
label: `$('${nodeName}')`,
|
||||
|
|
|
@ -3,8 +3,17 @@ import { isAllowedInDotNotation, escape, toVariableOption } from '../utils';
|
|||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { IDataObject, IPinData, IRunData } from 'n8n-workflow';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export const jsonFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* - Complete `x.first().json.` to `.field`.
|
||||
|
@ -206,11 +215,13 @@ export const jsonFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
|
||||
getInputNodeName() {
|
||||
try {
|
||||
const activeNode = this.$store.getters['ndv/activeNode'];
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const input = workflow.connectionsByDestinationNode[activeNode.name];
|
||||
const activeNode = this.ndvStore.activeNode;
|
||||
if (activeNode) {
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const input = workflow.connectionsByDestinationNode[activeNode.name];
|
||||
|
||||
return input.main[0][0].node;
|
||||
return input.main[0][0].node;
|
||||
}
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
|
@ -263,7 +274,7 @@ export const jsonFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
getJsonOutput(quotedNodeName: string, options?: { accessor?: string; index?: number }) {
|
||||
const nodeName = quotedNodeName.replace(/['"]/g, '');
|
||||
|
||||
const pinData: IPinData | undefined = this.$store.getters.pinData;
|
||||
const pinData: IPinData | undefined = this.workflowsStore.getPinData;
|
||||
|
||||
const nodePinData = pinData && pinData[nodeName];
|
||||
|
||||
|
@ -279,7 +290,7 @@ export const jsonFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
} catch (_) {}
|
||||
}
|
||||
|
||||
const runData: IRunData | null = this.$store.getters.getWorkflowRunData;
|
||||
const runData: IRunData | null = this.workflowsStore.getWorkflowRunData;
|
||||
|
||||
const nodeRunData = runData && runData[nodeName];
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
|||
import { AUTOCOMPLETABLE_BUILT_IN_MODULES } from '../constants';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
export const requireCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
methods: {
|
||||
|
@ -14,22 +15,26 @@ export const requireCompletions = (Vue as CodeNodeEditorMixin).extend({
|
|||
if (!preCursor || (preCursor.from === preCursor.to && !context.explicit)) return null;
|
||||
|
||||
const options: Completion[] = [];
|
||||
|
||||
const allowedModules = this.$store.getters['settings/allowedModules'];
|
||||
const settingsStore = useSettingsStore();
|
||||
const allowedModules = settingsStore.allowedModules;
|
||||
|
||||
const toOption = (moduleName: string) => ({
|
||||
label: `require('${moduleName}');`,
|
||||
type: 'variable',
|
||||
});
|
||||
|
||||
if (allowedModules?.builtIn?.includes('*')) {
|
||||
options.push(...AUTOCOMPLETABLE_BUILT_IN_MODULES.map(toOption));
|
||||
} else if (allowedModules?.builtIn?.length > 0) {
|
||||
options.push(...allowedModules.builtIn.map(toOption));
|
||||
if (allowedModules.builtIn) {
|
||||
if (allowedModules.builtIn.includes('*')) {
|
||||
options.push(...AUTOCOMPLETABLE_BUILT_IN_MODULES.map(toOption));
|
||||
} else if (allowedModules?.builtIn?.length > 0) {
|
||||
options.push(...allowedModules.builtIn.map(toOption));
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedModules?.external?.length > 0) {
|
||||
options.push(...allowedModules.external.map(toOption));
|
||||
if (allowedModules.external) {
|
||||
if (allowedModules?.external?.length > 0) {
|
||||
options.push(...allowedModules.external.map(toOption));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -49,6 +49,8 @@ import { get } from 'lodash';
|
|||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import {Component} from "vue";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
nodeHelpers,
|
||||
|
@ -72,6 +74,9 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
getPlaceholderText (): string {
|
||||
const placeholder = this.$locale.nodeText().placeholder(this.parameter, this.path);
|
||||
return placeholder ? placeholder : this.$locale.baseText('collectionParameter.choose');
|
||||
|
@ -93,8 +98,8 @@ export default mixins(
|
|||
return this.displayNodeParameter(option as INodeProperties);
|
||||
});
|
||||
},
|
||||
node (): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
node (): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
// Returns all the options which did not get added already
|
||||
parameterOptions (): Array<INodePropertyOptions | INodeProperties> {
|
||||
|
|
|
@ -55,7 +55,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { PublicInstalledPackage } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import {
|
||||
NPM_PACKAGE_DOCS_BASE_URL,
|
||||
|
@ -91,6 +93,9 @@ export default mixins(
|
|||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
methods: {
|
||||
async onAction(value: string) {
|
||||
switch (value) {
|
||||
|
@ -102,14 +107,14 @@ export default mixins(
|
|||
window.open(`${NPM_PACKAGE_DOCS_BASE_URL}${this.communityPackage.packageName}`, '_blank');
|
||||
break;
|
||||
case COMMUNITY_PACKAGE_MANAGE_ACTIONS.UNINSTALL:
|
||||
this.$store.dispatch('ui/openCommunityPackageUninstallConfirmModal', this.communityPackage.packageName);
|
||||
this.uiStore.openCommunityPackageUninstallConfirmModal(this.communityPackage.packageName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
onUpdateClick() {
|
||||
this.$store.dispatch('ui/openCommunityPackageUpdateConfirmModal', this.communityPackage.packageName);
|
||||
this.uiStore.openCommunityPackageUpdateConfirmModal(this.communityPackage.packageName);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -92,6 +92,8 @@ import {
|
|||
} from '../constants';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { showMessage } from './mixins/showMessage';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -114,6 +116,9 @@ export default mixins(
|
|||
COMMUNITY_NODES_RISKS_DOCS_URL,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useCommunityNodesStore),
|
||||
},
|
||||
methods: {
|
||||
openNPMPage() {
|
||||
this.$telemetry.track('user clicked cnr browse button', { source: 'cnr install modal' });
|
||||
|
@ -127,9 +132,9 @@ export default mixins(
|
|||
this.$telemetry.track('user started cnr package install', { input_string: this.packageName, source: 'cnr settings page' });
|
||||
this.infoTextErrorMessage = '';
|
||||
this.loading = true;
|
||||
await this.$store.dispatch('communityNodes/installPackage', this.packageName);
|
||||
await this.communityNodesStore.installPackage(this.packageName);
|
||||
// TODO: We need to fetch a fresh list of installed packages until proper response is implemented on the back-end
|
||||
await this.$store.dispatch('communityNodes/fetchInstalledPackages');
|
||||
await this.communityNodesStore.fetchInstalledPackages();
|
||||
this.loading = false;
|
||||
this.modalBus.$emit('close');
|
||||
this.$showMessage({
|
||||
|
|
|
@ -37,6 +37,8 @@ import mixins from 'vue-typed-mixins';
|
|||
import Modal from './Modal.vue';
|
||||
import { COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '../constants';
|
||||
import { showMessage } from './mixins/showMessage';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes';
|
||||
|
||||
export default mixins(showMessage).extend({
|
||||
name: 'CommunityPackageManageConfirmModal',
|
||||
|
@ -65,8 +67,9 @@ export default mixins(showMessage).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useCommunityNodesStore),
|
||||
activePackage() {
|
||||
return this.$store.getters['communityNodes/getInstalledPackageByName'](this.activePackageName);
|
||||
return this.communityNodesStore.getInstalledPackageByName(this.activePackageName);
|
||||
},
|
||||
getModalContent() {
|
||||
if (this.mode === COMMUNITY_PACKAGE_MANAGE_ACTIONS.UNINSTALL) {
|
||||
|
@ -120,7 +123,7 @@ export default mixins(showMessage).extend({
|
|||
package_author_email: this.activePackage.authorEmail,
|
||||
});
|
||||
this.loading = true;
|
||||
await this.$store.dispatch('communityNodes/uninstallPackage', this.activePackageName);
|
||||
await this.communityNodesStore.uninstallPackage(this.activePackageName);
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('settings.communityNodes.messages.uninstall.success.title'),
|
||||
type: 'success',
|
||||
|
@ -144,7 +147,7 @@ export default mixins(showMessage).extend({
|
|||
});
|
||||
this.loading = true;
|
||||
const updatedVersion = this.activePackage.updateAvailable;
|
||||
await this.$store.dispatch('communityNodes/updatePackage', this.activePackageName);
|
||||
await this.communityNodesStore.updatePackage(this.activePackageName);
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('settings.communityNodes.messages.update.success.title'),
|
||||
message: this.$locale.baseText('settings.communityNodes.messages.update.success.message', {
|
||||
|
|
|
@ -35,12 +35,14 @@
|
|||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
import { IN8nPromptResponse } from '@/Interface';
|
||||
import { VALID_EMAIL_REGEX } from '@/constants';
|
||||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
import Modal from './Modal.vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default mixins(workflowHelpers).extend({
|
||||
components: { Modal },
|
||||
|
@ -53,19 +55,20 @@ export default mixins(workflowHelpers).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
promptsData: 'settings/getPromptsData',
|
||||
}),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
),
|
||||
title(): string {
|
||||
if (this.promptsData && this.promptsData.title) {
|
||||
return this.promptsData.title;
|
||||
if (this.settingsStore.promptsData && this.settingsStore.promptsData.title) {
|
||||
return this.settingsStore.promptsData.title;
|
||||
}
|
||||
|
||||
return 'You’re a power user 💪';
|
||||
},
|
||||
description(): string {
|
||||
if (this.promptsData && this.promptsData.message) {
|
||||
return this.promptsData.message;
|
||||
if (this.settingsStore.promptsData && this.settingsStore.promptsData.message) {
|
||||
return this.settingsStore.promptsData.message;
|
||||
}
|
||||
|
||||
return 'Your experience with n8n can help us improve — for you and our entire community.';
|
||||
|
@ -78,21 +81,18 @@ export default mixins(workflowHelpers).extend({
|
|||
closeDialog(): void {
|
||||
if (!this.isEmailValid) {
|
||||
this.$telemetry.track('User closed email modal', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
email: null,
|
||||
});
|
||||
}
|
||||
},
|
||||
async send() {
|
||||
if (this.isEmailValid) {
|
||||
const response: IN8nPromptResponse = await this.$store.dispatch(
|
||||
'settings/submitContactInfo',
|
||||
this.email,
|
||||
);
|
||||
const response = await this.settingsStore.submitContactInfo(this.email) as IN8nPromptResponse;
|
||||
|
||||
if (response.updated) {
|
||||
this.$telemetry.track('User closed email modal', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
email: this.email,
|
||||
});
|
||||
this.$showMessage({
|
||||
|
|
|
@ -46,8 +46,10 @@ import {EnterpriseEditionFeature} from '@/constants';
|
|||
import {showMessage} from "@/components/mixins/showMessage";
|
||||
import CredentialIcon from '@/components/CredentialIcon.vue';
|
||||
import {getCredentialPermissions, IPermissions} from "@/permissions";
|
||||
import {mapGetters} from "vuex";
|
||||
import dateformat from "dateformat";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
|
||||
export const CREDENTIAL_LIST_ITEM_ACTIONS = {
|
||||
OPEN: 'open',
|
||||
|
@ -86,8 +88,12 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
),
|
||||
currentUser (): IUser {
|
||||
return this.$store.getters['users/currentUser'];
|
||||
return this.usersStore.currentUser || {} as IUser;
|
||||
},
|
||||
credentialType(): ICredentialType {
|
||||
return this.$store.getters['credentials/getCredentialTypeByName'](this.data.type);
|
||||
|
@ -114,7 +120,7 @@ export default mixins(
|
|||
},
|
||||
methods: {
|
||||
async onClick() {
|
||||
this.$store.dispatch('ui/openExistingCredential', { id: this.data.id});
|
||||
this.uiStore.openExistingCredential(this.data.id);
|
||||
},
|
||||
async onAction(action: string) {
|
||||
if (action === CREDENTIAL_LIST_ITEM_ACTIONS.OPEN) {
|
||||
|
|
|
@ -102,6 +102,11 @@ import { addCredentialTranslation } from '@/plugins/i18n';
|
|||
import mixins from 'vue-typed-mixins';
|
||||
import { BUILTIN_CREDENTIALS_DOCS_URL, EnterpriseEditionFeature } from '@/constants';
|
||||
import { IPermissions } from "@/permissions";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(restApi).extend({
|
||||
name: 'CredentialConfig',
|
||||
|
@ -160,9 +165,9 @@ export default mixins(restApi).extend({
|
|||
};
|
||||
},
|
||||
async beforeMount() {
|
||||
if (this.$store.getters.defaultLocale === 'en') return;
|
||||
if (this.rootStore.defaultLocale === 'en') return;
|
||||
|
||||
this.$store.commit('setActiveCredentialType', this.credentialType.name);
|
||||
this.uiStore.activeCredentialType = this.credentialType.name;
|
||||
|
||||
const key = `n8n-nodes-base.credentials.${this.credentialType.name}`;
|
||||
|
||||
|
@ -172,10 +177,16 @@ export default mixins(restApi).extend({
|
|||
|
||||
addCredentialTranslation(
|
||||
{ [this.credentialType.name]: credTranslation },
|
||||
this.$store.getters.defaultLocale,
|
||||
this.rootStore.defaultLocale,
|
||||
);
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useRootStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
appName(): string {
|
||||
if (!this.credentialType) {
|
||||
return '';
|
||||
|
@ -195,7 +206,7 @@ export default mixins(restApi).extend({
|
|||
},
|
||||
documentationUrl(): string {
|
||||
const type = this.credentialType as ICredentialType;
|
||||
const activeNode = this.$store.getters['ndv/activeNode'];
|
||||
const activeNode = this.ndvStore.activeNode;
|
||||
const isCommunityNode = activeNode ? isCommunityPackageName(activeNode.type) : false;
|
||||
|
||||
if (!type || !type.documentationUrl) {
|
||||
|
@ -219,7 +230,7 @@ export default mixins(restApi).extend({
|
|||
this.parentTypes.includes('oAuth2Api')
|
||||
? 'oauth2'
|
||||
: 'oauth1';
|
||||
return this.$store.getters.oauthCallbackUrls[oauthType];
|
||||
return this.rootStore.oauthCallbackUrls[oauthType as keyof {}];
|
||||
},
|
||||
showOAuthSuccessBanner(): boolean {
|
||||
return this.isOAuthType && this.requiredPropertiesFilled && this.isOAuthConnected && !this.authError;
|
||||
|
@ -234,7 +245,7 @@ export default mixins(restApi).extend({
|
|||
docs_link: this.documentationUrl,
|
||||
credential_type: this.credentialTypeName,
|
||||
source: 'modal',
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
@ -109,6 +109,7 @@ import {
|
|||
ICredentialsDecryptedResponse,
|
||||
ICredentialsResponse,
|
||||
IFakeDoor,
|
||||
IUser,
|
||||
} from '@/Interface';
|
||||
|
||||
import {
|
||||
|
@ -123,7 +124,6 @@ import {
|
|||
INodeProperties,
|
||||
INodeTypeDescription,
|
||||
ITelemetryTrackProperties,
|
||||
IUser,
|
||||
NodeHelpers,
|
||||
} from 'n8n-workflow';
|
||||
import CredentialIcon from '../CredentialIcon.vue';
|
||||
|
@ -141,10 +141,15 @@ import InlineNameEdit from '../InlineNameEdit.vue';
|
|||
import {EnterpriseEditionFeature} from "@/constants";
|
||||
import {IDataObject} from "n8n-workflow";
|
||||
import FeatureComingSoon from '../FeatureComingSoon.vue';
|
||||
import {mapGetters} from "vuex";
|
||||
import {getCredentialPermissions, IPermissions} from "@/permissions";
|
||||
import { IMenuItem } from 'n8n-design-system';
|
||||
import { BaseTextKey } from '@/plugins/i18n';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
interface NodeAccessMap {
|
||||
[nodeType: string]: ICredentialNodeAccess | null;
|
||||
|
@ -236,7 +241,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
this.$externalHooks().run('credentialsEdit.credentialModalOpened', {
|
||||
credentialType: this.credentialTypeName,
|
||||
isEditingCredential: this.mode === 'edit',
|
||||
activeNode: this.$store.getters['ndv/activeNode'],
|
||||
activeNode: this.ndvStore.activeNode,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
|
@ -253,7 +258,16 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
this.loading = false;
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('users', ['currentUser']),
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
currentUser(): IUser {
|
||||
return this.usersStore.currentUser || {} as IUser;
|
||||
},
|
||||
currentCredential(): ICredentialsResponse | null {
|
||||
if (!this.credentialId) {
|
||||
return null;
|
||||
|
@ -387,7 +401,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
return true;
|
||||
},
|
||||
credentialsFakeDoorFeatures(): IFakeDoor[] {
|
||||
return this.$store.getters['ui/getFakeDoorByLocation']('credentialsModal');
|
||||
return this.uiStore.getFakeDoorByLocation('credentialsModal');
|
||||
},
|
||||
credentialPermissions(): IPermissions {
|
||||
if (this.loading) {
|
||||
|
@ -431,7 +445,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
return items;
|
||||
},
|
||||
isSharingAvailable(): boolean {
|
||||
return this.$store.getters['settings/isEnterpriseFeatureEnabled'](EnterpriseEditionFeature.Sharing) === true;
|
||||
return this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -561,13 +575,13 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
this.activeTab = tab;
|
||||
const tabName: string = tab.replaceAll('coming-soon/', '');
|
||||
const credType: string = this.credentialType ? this.credentialType.name : '';
|
||||
const activeNode: INode | null = this.$store.getters['ndv/activeNode'];
|
||||
const activeNode: INode | null = this.ndvStore.activeNode;
|
||||
|
||||
this.$telemetry.track('User viewed credential tab', {
|
||||
credential_type: credType,
|
||||
node_type: activeNode ? activeNode.type : null,
|
||||
tab: tabName,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
credential_id: this.credentialId,
|
||||
sharing_enabled: EnterpriseEditionFeature.Sharing,
|
||||
});
|
||||
|
@ -715,7 +729,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
|
||||
let sharedWith: IUser[] | undefined;
|
||||
let ownedBy: IUser | undefined;
|
||||
if (this.$store.getters['settings/isEnterpriseFeatureEnabled'](EnterpriseEditionFeature.Sharing)) {
|
||||
if (this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing)) {
|
||||
sharedWith = this.credentialData.sharedWith as unknown as IUser[];
|
||||
ownedBy = this.credentialData.ownedBy as unknown as IUser;
|
||||
}
|
||||
|
@ -765,7 +779,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
|
||||
const trackProperties: ITelemetryTrackProperties = {
|
||||
credential_type: credentialDetails.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
credential_id: credential.id,
|
||||
is_complete: !!this.requiredPropertiesFilled,
|
||||
is_new: isNewCredential,
|
||||
|
@ -777,8 +791,8 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
trackProperties.is_valid = !!this.testedSuccessfully;
|
||||
}
|
||||
|
||||
if (this.$store.getters['ndv/activeNode']) {
|
||||
trackProperties.node_type = this.$store.getters['ndv/activeNode'].type;
|
||||
if (this.ndvStore.activeNode) {
|
||||
trackProperties.node_type = this.ndvStore.activeNode.type;
|
||||
}
|
||||
|
||||
if (this.authError && this.authError !== '') {
|
||||
|
@ -821,7 +835,7 @@ export default mixins(showMessage, nodeHelpers).extend({
|
|||
this.$telemetry.track('User created credentials', {
|
||||
credential_type: credentialDetails.type,
|
||||
credential_id: credential.id,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
|
||||
return credential;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
v-if="credentialPermissions.updateSharing"
|
||||
size="large"
|
||||
:users="usersList"
|
||||
:currentUserId="currentUser.id"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:placeholder="$locale.baseText('credentialEdit.credentialSharing.select.placeholder')"
|
||||
@input="onAddSharee"
|
||||
>
|
||||
|
@ -25,7 +25,7 @@
|
|||
</n8n-user-select>
|
||||
<n8n-users-list
|
||||
:users="sharedWithList"
|
||||
:currentUserId="currentUser.id"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:delete-label="$locale.baseText('credentialEdit.credentialSharing.list.delete')"
|
||||
:readonly="!credentialPermissions.updateSharing"
|
||||
@delete="onRemoveSharee"
|
||||
|
@ -34,11 +34,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import {IUser} from "@/Interface";
|
||||
import mixins from "vue-typed-mixins";
|
||||
import {showMessage} from "@/components/mixins/showMessage";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -46,10 +46,10 @@ export default mixins(
|
|||
name: 'CredentialSharing',
|
||||
props: ['credential', 'credentialId', 'credentialData', 'sharedWith', 'credentialPermissions'],
|
||||
computed: {
|
||||
...mapGetters('users', ['allUsers', 'currentUser']),
|
||||
...mapStores(useUsersStore),
|
||||
usersList(): IUser[] {
|
||||
return this.allUsers.filter((user: IUser) => {
|
||||
const isCurrentUser = user.id === this.currentUser.id;
|
||||
return this.usersStore.allUsers.filter((user: IUser) => {
|
||||
const isCurrentUser = user.id === this.usersStore.currentUser?.id;
|
||||
const isAlreadySharedWithUser = (this.credentialData.sharedWith || []).find((sharee: IUser) => sharee.id === user.id);
|
||||
|
||||
return !isCurrentUser && !isAlreadySharedWithUser;
|
||||
|
@ -58,7 +58,7 @@ export default mixins(
|
|||
sharedWithList(): IUser[] {
|
||||
return [
|
||||
{
|
||||
...(this.credential ? this.credential.ownedBy : this.currentUser),
|
||||
...(this.credential ? this.credential.ownedBy : this.usersStore.currentUser),
|
||||
isOwner: true,
|
||||
},
|
||||
].concat(this.credentialData.sharedWith || []);
|
||||
|
@ -69,30 +69,30 @@ export default mixins(
|
|||
},
|
||||
methods: {
|
||||
async onAddSharee(userId: string) {
|
||||
const { id, firstName, lastName, email } = this.$store.getters['users/getUserById'](userId);
|
||||
const sharee = { id, firstName, lastName, email };
|
||||
|
||||
const sharee = this.usersStore.getUserById(userId);
|
||||
this.$emit('change', (this.credentialData.sharedWith || []).concat(sharee));
|
||||
},
|
||||
async onRemoveSharee(userId: string) {
|
||||
const user = this.$store.getters['users/getUserById'](userId);
|
||||
const user = this.usersStore.getUserById(userId);
|
||||
|
||||
const confirm = await this.confirmMessage(
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.message', { interpolate: { name: user.fullName } }),
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.title'),
|
||||
null,
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.confirmButtonText'),
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.cancelButtonText'),
|
||||
);
|
||||
if (user) {
|
||||
const confirm = await this.confirmMessage(
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.message', { interpolate: { name: user.fullName || '' } }),
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.title'),
|
||||
null,
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.confirmButtonText'),
|
||||
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.cancelButtonText'),
|
||||
);
|
||||
|
||||
if (confirm) {
|
||||
this.$emit('change', this.credentialData.sharedWith.filter((sharee: IUser) => {
|
||||
return sharee.id !== user.id;
|
||||
}));
|
||||
if (confirm) {
|
||||
this.$emit('change', this.credentialData.sharedWith.filter((sharee: IUser) => {
|
||||
return sharee.id !== user.id;
|
||||
}));
|
||||
}
|
||||
}
|
||||
},
|
||||
async loadUsers() {
|
||||
await this.$store.dispatch('users/fetchUsers');
|
||||
await this.usersStore.fetchUsers();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
|
||||
|
@ -27,8 +29,11 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
basePath(): string {
|
||||
return this.$store.getters.getBaseUrl;
|
||||
return this.rootStore.baseUrl;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
import { ICredentialType, INodeTypeDescription } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -17,6 +20,10 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useRootStore,
|
||||
),
|
||||
credentialWithIcon(): ICredentialType | null {
|
||||
return this.credentialTypeName ? this.getCredentialWithIcon(this.credentialTypeName) : null;
|
||||
},
|
||||
|
@ -26,15 +33,14 @@ export default Vue.extend({
|
|||
return null;
|
||||
}
|
||||
|
||||
const restUrl = this.$store.getters.getRestUrl;
|
||||
const restUrl = this.rootStore.getRestUrl;
|
||||
|
||||
return `${restUrl}/credential-icon/${this.credentialWithIcon.name}`;
|
||||
},
|
||||
relevantNode(): INodeTypeDescription | null {
|
||||
if (this.credentialWithIcon && this.credentialWithIcon.icon && this.credentialWithIcon.icon.startsWith('node:')) {
|
||||
const nodeType = this.credentialWithIcon.icon.replace('node:', '');
|
||||
|
||||
return this.$store.getters['nodeTypes/getNodeType'](nodeType);
|
||||
return this.nodeTypesStore.getNodeType(nodeType);
|
||||
}
|
||||
|
||||
const nodesWithAccess = this.$store.getters['credentials/getNodesWithAccess'](this.credentialTypeName);
|
||||
|
|
|
@ -56,6 +56,9 @@ import mixins from 'vue-typed-mixins';
|
|||
import Modal from './Modal.vue';
|
||||
import { CREDENTIAL_SELECT_MODAL_KEY } from '../constants';
|
||||
import { externalHooks } from '@/components/mixins/externalHooks';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export default mixins(externalHooks).extend({
|
||||
name: 'CredentialsSelectModal',
|
||||
|
@ -85,6 +88,10 @@ export default mixins(externalHooks).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapGetters('credentials', ['allCredentialTypes']),
|
||||
},
|
||||
methods: {
|
||||
|
@ -93,13 +100,13 @@ export default mixins(externalHooks).extend({
|
|||
},
|
||||
openCredentialType () {
|
||||
this.modalBus.$emit('close');
|
||||
this.$store.dispatch('ui/openNewCredential', { type: this.selected });
|
||||
this.uiStore.openNewCredential(this.selected);
|
||||
|
||||
const telemetryPayload = {
|
||||
credential_type: this.selected,
|
||||
source: 'primary_menu',
|
||||
new_credential: true,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
};
|
||||
|
||||
this.$telemetry.track('User opened Credential modal', telemetryPayload);
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
<div :class="$style.optionInput" v-if="operation === 'transfer'">
|
||||
<n8n-input-label :label="$locale.baseText('settings.users.userToTransferTo')">
|
||||
<n8n-user-select
|
||||
:users="allUsers"
|
||||
:users="usersStore.allUsers"
|
||||
:value="transferId"
|
||||
:ignoreIds="ignoreIds"
|
||||
:currentUserId="currentUserId"
|
||||
:currentUserId="usersStore.currentUserId"
|
||||
@input="setTransferId"
|
||||
/>
|
||||
</n8n-input-label>
|
||||
|
@ -53,7 +53,8 @@ import { showMessage } from "@/components/mixins/showMessage";
|
|||
import Modal from "./Modal.vue";
|
||||
import Vue from "vue";
|
||||
import { IUser } from "../Interface";
|
||||
import { mapGetters } from "vuex";
|
||||
import { mapStores } from "pinia";
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
|
||||
export default mixins(showMessage).extend({
|
||||
components: {
|
||||
|
@ -79,13 +80,12 @@ export default mixins(showMessage).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('users', ['allUsers', 'currentUserId']),
|
||||
userToDelete(): IUser {
|
||||
const getUserById = this.$store.getters['users/getUserById'];
|
||||
return getUserById(this.activeId);
|
||||
...mapStores(useUsersStore),
|
||||
userToDelete(): IUser | null {
|
||||
return this.usersStore.getUserById(this.activeId);
|
||||
},
|
||||
isPending(): boolean {
|
||||
return this.userToDelete && !this.userToDelete.firstName;
|
||||
return this.userToDelete ? this.userToDelete && !this.userToDelete.firstName : false;
|
||||
},
|
||||
title(): string {
|
||||
const user = this.userToDelete && (this.userToDelete.fullName || this.userToDelete.email) || '';
|
||||
|
@ -133,16 +133,17 @@ export default mixins(showMessage).extend({
|
|||
params.transferId = this.transferId;
|
||||
}
|
||||
|
||||
await this.$store.dispatch('users/deleteUser', params);
|
||||
await this.usersStore.deleteUser(params);
|
||||
|
||||
let message = '';
|
||||
if (this.transferId) {
|
||||
const getUserById = this.$store.getters['users/getUserById'];
|
||||
const transferUser: IUser = getUserById(this.transferId);
|
||||
message = this.$locale.baseText(
|
||||
'settings.users.transferredToUser',
|
||||
{ interpolate: { user: transferUser.fullName || '' }},
|
||||
);
|
||||
const transferUser: IUser | null = this.usersStore.getUserById(this.transferId);
|
||||
if (transferUser) {
|
||||
message = this.$locale.baseText(
|
||||
'settings.users.transferredToUser',
|
||||
{ interpolate: { user: transferUser.fullName || '' }},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.$showMessage({
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { XYPosition } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -66,11 +68,14 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
canDrop(): boolean {
|
||||
return this.$store.getters['ndv/canDraggableDrop'];
|
||||
return this.ndvStore.canDraggableDrop;
|
||||
},
|
||||
stickyPosition(): XYPosition | null {
|
||||
return this.$store.getters['ndv/draggableStickyPos'];
|
||||
return this.ndvStore.draggableStickyPos;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -111,7 +116,7 @@ export default Vue.extend({
|
|||
this.isDragging = true;
|
||||
|
||||
const data = this.targetDataKey && this.draggingEl ? this.draggingEl.dataset.value : (this.data || '');
|
||||
this.$store.commit('ndv/draggableStartDragging', {type: this.type, data });
|
||||
this.ndvStore.draggableStartDragging({type: this.type, data: data || '' });
|
||||
|
||||
this.$emit('dragstart', this.draggingEl);
|
||||
document.body.style.cursor = 'grabbing';
|
||||
|
@ -141,7 +146,7 @@ export default Vue.extend({
|
|||
this.$emit('dragend', this.draggingEl);
|
||||
this.isDragging = false;
|
||||
this.draggingEl = null;
|
||||
this.$store.commit('ndv/draggableStopDragging');
|
||||
this.ndvStore.draggableStopDragging();
|
||||
}, 0);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -37,11 +39,14 @@ export default Vue.extend({
|
|||
window.removeEventListener('mouseup', this.onMouseUp);
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
isDragging(): boolean {
|
||||
return this.$store.getters['ndv/isDraggableDragging'];
|
||||
return this.ndvStore.isDraggableDragging;
|
||||
},
|
||||
draggableType(): string {
|
||||
return this.$store.getters['ndv/draggableType'];
|
||||
return this.ndvStore.draggableType;
|
||||
},
|
||||
droppable(): boolean {
|
||||
return !this.disabled && this.isDragging && this.draggableType === this.type;
|
||||
|
@ -60,20 +65,20 @@ export default Vue.extend({
|
|||
this.hovering = e.clientX >= dim.left && e.clientX <= dim.right && e.clientY >= dim.top && e.clientY <= dim.bottom;
|
||||
|
||||
if (!this.disabled && this.sticky && this.hovering) {
|
||||
this.$store.commit('ndv/setDraggableStickyPos', [dim.left + this.stickyOffset, dim.top + this.stickyOffset]);
|
||||
this.ndvStore.setDraggableStickyPos([dim.left + this.stickyOffset, dim.top + this.stickyOffset]);
|
||||
}
|
||||
}
|
||||
},
|
||||
onMouseUp(e: MouseEvent) {
|
||||
if (this.activeDrop) {
|
||||
const data = this.$store.getters['ndv/draggableData'];
|
||||
const data = this.ndvStore.draggableData;
|
||||
this.$emit('drop', data);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
activeDrop(active) {
|
||||
this.$store.commit('ndv/setDraggableCanDrop', active);
|
||||
this.ndvStore.setDraggableCanDrop(active);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:maxlength="MAX_WORKFLOW_NAME_LENGTH"
|
||||
/>
|
||||
<TagsDropdown
|
||||
v-if="areTagsEnabled"
|
||||
v-if="settingsStore.areTagsEnabled"
|
||||
:createEnabled="true"
|
||||
:currentTagIds="currentTagIds"
|
||||
:eventBus="dropdownBus"
|
||||
|
@ -46,9 +46,10 @@ import { workflowHelpers } from "@/components/mixins/workflowHelpers";
|
|||
import { showMessage } from "@/components/mixins/showMessage";
|
||||
import TagsDropdown from "@/components/TagsDropdown.vue";
|
||||
import Modal from "./Modal.vue";
|
||||
import { mapGetters } from "vuex";
|
||||
import {restApi} from "@/components/mixins/restApi";
|
||||
import {IWorkflowDb} from "@/Interface";
|
||||
import { mapStores } from "pinia";
|
||||
import { useSettingsStore } from "@/stores/settings";
|
||||
import { useWorkflowsStore } from "@/stores/workflows";
|
||||
|
||||
export default mixins(showMessage, workflowHelpers, restApi).extend({
|
||||
components: { TagsDropdown, Modal },
|
||||
|
@ -68,11 +69,14 @@ export default mixins(showMessage, workflowHelpers, restApi).extend({
|
|||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.name = await this.$store.dispatch('workflows/getDuplicateCurrentWorkflowName', this.data.name);
|
||||
this.name = await this.workflowsStore.getDuplicateCurrentWorkflowName(this.data.name);
|
||||
this.$nextTick(() => this.focusOnNameInput());
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('settings', ['areTagsEnabled']),
|
||||
...mapStores(
|
||||
useSettingsStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
isActive(active) {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import {EnterpriseEditionFeature} from "@/constants";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'EnterpriseEdition',
|
||||
|
@ -18,9 +20,10 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useSettingsStore),
|
||||
canAccess(): boolean {
|
||||
return this.features.reduce((acc: boolean, feature) => {
|
||||
return acc && !!this.$store.getters['settings/isEnterpriseFeatureEnabled'](feature);
|
||||
return acc && !!this.settingsStore.isEnterpriseFeatureEnabled(feature as EnterpriseEditionFeature);
|
||||
}, true);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -109,6 +109,9 @@ import {
|
|||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
import { sanitizeHtml } from '@/utils';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
copyPaste,
|
||||
|
@ -122,15 +125,19 @@ export default mixins(
|
|||
VueJsonPretty,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
),
|
||||
displayCause(): boolean {
|
||||
return JSON.stringify(this.error.cause).length < MAX_DISPLAY_DATA_SIZE;
|
||||
},
|
||||
parameters (): INodeProperties[] {
|
||||
const node = this.$store.getters['ndv/activeNode'];
|
||||
const node = this.ndvStore.activeNode;
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](node.type, node.typeVersion);
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
|
||||
if (nodeType === null) {
|
||||
return [];
|
||||
|
|
|
@ -203,6 +203,9 @@ import {
|
|||
} from 'lodash';
|
||||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -249,7 +252,7 @@ export default mixins(
|
|||
this.handleAutoRefreshToggle();
|
||||
|
||||
this.$externalHooks().run('executionsList.openDialog');
|
||||
this.$telemetry.track('User opened Executions log', { workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User opened Executions log', { workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.autoRefreshInterval) {
|
||||
|
@ -258,6 +261,10 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
statuses () {
|
||||
return [
|
||||
{
|
||||
|
@ -283,7 +290,7 @@ export default mixins(
|
|||
];
|
||||
},
|
||||
activeExecutions (): IExecutionsCurrentSummaryExtended[] {
|
||||
return this.$store.getters.getActiveExecutions;
|
||||
return this.workflowsStore.activeExecutions;
|
||||
},
|
||||
combinedExecutions (): IExecutionsSummary[] {
|
||||
const returnData: IExecutionsSummary[] = [];
|
||||
|
@ -408,27 +415,28 @@ export default mixins(
|
|||
await this.restApi().deleteExecutions(sendData);
|
||||
let removedCurrentlyLoadedExecution = false;
|
||||
let removedActiveExecution = false;
|
||||
const currentWorkflow: string = this.$store.getters.workflowId;
|
||||
const activeExecution: IExecutionsSummary = this.$store.getters['workflows/getActiveWorkflowExecution'];
|
||||
const currentWorkflow: string = this.workflowsStore.workflowId;
|
||||
const activeExecution: IExecutionsSummary | null = this.workflowsStore.activeWorkflowExecution;
|
||||
// Also update current workflow executions view if needed
|
||||
for (const selectedId of Object.keys(this.selectedItems)) {
|
||||
const execution: IExecutionsSummary = this.$store.getters['workflows/getExecutionDataById'](selectedId);
|
||||
const execution: IExecutionsSummary | undefined = this.workflowsStore.getExecutionDataById(selectedId);
|
||||
if (execution && execution.workflowId === currentWorkflow) {
|
||||
this.$store.commit('workflows/deleteExecution', execution);
|
||||
this.workflowsStore.deleteExecution(execution);
|
||||
removedCurrentlyLoadedExecution = true;
|
||||
}
|
||||
if (execution.id === activeExecution.id) {
|
||||
if ((execution !== undefined && activeExecution !== null) && execution.id === activeExecution.id) {
|
||||
removedActiveExecution = true;
|
||||
}
|
||||
}
|
||||
// Also update route if needed
|
||||
if (removedCurrentlyLoadedExecution) {
|
||||
const currentWorkflowExecutions: IExecutionsSummary[] = this.$store.getters['workflows/currentWorkflowExecutions'];
|
||||
const currentWorkflowExecutions: IExecutionsSummary[] = this.workflowsStore.currentWorkflowExecutions;
|
||||
if (currentWorkflowExecutions.length === 0) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', null);
|
||||
this.workflowsStore.activeWorkflowExecution = null;
|
||||
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME, params: { name: currentWorkflow } });
|
||||
} else if (removedActiveExecution) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', currentWorkflowExecutions[0]);
|
||||
this.workflowsStore.activeWorkflowExecution = currentWorkflowExecutions[0];
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: currentWorkflow, executionId: currentWorkflowExecutions[0].id },
|
||||
|
@ -468,7 +476,7 @@ export default mixins(
|
|||
this.retryExecution(commandData.row, loadWorkflow);
|
||||
|
||||
this.$telemetry.track('User clicked retry execution button', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
execution_id: commandData.row.id,
|
||||
retry_type: loadWorkflow ? 'current' : 'original',
|
||||
});
|
||||
|
@ -497,7 +505,7 @@ export default mixins(
|
|||
}
|
||||
}
|
||||
|
||||
this.$store.commit('setActiveExecutions', activeExecutions);
|
||||
this.workflowsStore.activeExecutions = activeExecutions;
|
||||
},
|
||||
async loadAutoRefresh () : Promise<void> {
|
||||
const filter = this.workflowFilterPast;
|
||||
|
@ -517,7 +525,7 @@ export default mixins(
|
|||
}
|
||||
}
|
||||
|
||||
this.$store.commit('setActiveExecutions', results[1]);
|
||||
this.workflowsStore.activeExecutions = results[1];
|
||||
|
||||
// execution IDs are typed as string, int conversion is necessary so we can order.
|
||||
const alreadyPresentExecutionIds = this.finishedExecutions.map(exec => parseInt(exec.id, 10));
|
||||
|
|
|
@ -65,6 +65,8 @@ import { showMessage } from '../mixins/showMessage';
|
|||
import WorkflowPreview from '@/components/WorkflowPreview.vue';
|
||||
import { executionHelpers, IExecutionUIData } from '../mixins/executionsHelpers';
|
||||
import { VIEWS } from '../../constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
|
||||
export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
name: 'execution-preview',
|
||||
|
@ -77,11 +79,14 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
),
|
||||
executionUIDetails(): IExecutionUIData | null {
|
||||
return this.activeExecution ? this.getExecutionUIDetails(this.activeExecution) : null;
|
||||
},
|
||||
sidebarCollapsed(): boolean {
|
||||
return this.$store.getters['ui/sidebarMenuCollapsed'];
|
||||
return this.uiStore.sidebarMenuCollapsed;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { mapStores } from 'pinia';
|
||||
import { PLACEHOLDER_EMPTY_WORKFLOW_ID, WORKFLOW_SETTINGS_MODAL_KEY } from '@/constants';
|
||||
import { deepCopy, IWorkflowSettings } from 'n8n-workflow';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
|
@ -60,9 +65,9 @@ export default mixins(workflowHelpers).extend({
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.defaultValues.saveFailedExecutions = this.$store.getters.saveDataErrorExecution;
|
||||
this.defaultValues.saveSuccessfulExecutions = this.$store.getters.saveDataSuccessExecution;
|
||||
this.defaultValues.saveManualExecutions = this.$store.getters.saveManualExecutions;
|
||||
this.defaultValues.saveFailedExecutions = this.settingsStore.saveDataErrorExecution;
|
||||
this.defaultValues.saveSuccessfulExecutions = this.settingsStore.saveDataSuccessExecution;
|
||||
this.defaultValues.saveManualExecutions = this.settingsStore.saveManualExecutions;
|
||||
this.updateSettings(this.workflowSettings);
|
||||
},
|
||||
watch: {
|
||||
|
@ -71,7 +76,13 @@ export default mixins(workflowHelpers).extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
accordionItems(): Object[] {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
accordionItems(): Object[] {
|
||||
return [
|
||||
{
|
||||
id: 'productionExecutions',
|
||||
|
@ -115,7 +126,7 @@ export default mixins(workflowHelpers).extend({
|
|||
}
|
||||
},
|
||||
workflowSettings(): IWorkflowSettings {
|
||||
const workflowSettings = deepCopy(this.$store.getters.workflowSettings);
|
||||
const workflowSettings = deepCopy(this.workflowsStore.workflowSettings);
|
||||
return workflowSettings;
|
||||
},
|
||||
accordionIcon(): { icon: string, color: string }|null {
|
||||
|
@ -125,16 +136,16 @@ export default mixins(workflowHelpers).extend({
|
|||
return null;
|
||||
},
|
||||
currentWorkflowId(): string {
|
||||
return this.$store.getters.workflowId;
|
||||
return this.workflowsStore.workflowId;
|
||||
},
|
||||
isNewWorkflow(): boolean {
|
||||
return !this.currentWorkflowId || (this.currentWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID || this.currentWorkflowId === 'new');
|
||||
},
|
||||
workflowName(): string {
|
||||
return this.$store.getters.workflowName;
|
||||
return this.workflowsStore.workflowName;
|
||||
},
|
||||
currentWorkflowTagIds(): string[] {
|
||||
return this.$store.getters.workflowTags;
|
||||
return this.workflowsStore.workflowTags;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -146,17 +157,17 @@ export default mixins(workflowHelpers).extend({
|
|||
onAccordionClick(event: MouseEvent): void {
|
||||
if (event.target instanceof HTMLAnchorElement) {
|
||||
event.preventDefault();
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
}
|
||||
},
|
||||
onItemTooltipClick(item: string, event: MouseEvent): void {
|
||||
if (item === 'productionExecutions' && event.target instanceof HTMLAnchorElement) {
|
||||
event.preventDefault();
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
}
|
||||
},
|
||||
openWorkflowSettings(event: MouseEvent): void {
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
},
|
||||
async onSaveWorkflowClick(event: MouseEvent): void {
|
||||
let currentId = undefined;
|
||||
|
@ -166,7 +177,7 @@ export default mixins(workflowHelpers).extend({
|
|||
currentId = this.$route.params.name;
|
||||
}
|
||||
const saved = await this.saveCurrentWorkflow({ id: currentId, name: this.workflowName, tags: this.currentWorkflowTagIds });
|
||||
if (saved) this.$store.dispatch('settings/fetchPromptsData');
|
||||
if (saved) this.settingsStore.fetchPromptsData();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { PLACEHOLDER_EMPTY_WORKFLOW_ID, VIEWS } from '@/constants';
|
||||
import { IExecutionsSummary } from '@/Interface';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
import ExecutionsInfoAccordion from './ExecutionsInfoAccordion.vue';
|
||||
|
||||
|
@ -37,24 +39,25 @@ export default Vue.extend({
|
|||
ExecutionsInfoAccordion,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
executionCount(): number {
|
||||
return (this.$store.getters['workflows/currentWorkflowExecutions'] as IExecutionsSummary[]).length;
|
||||
return this.workflowsStore.currentWorkflowExecutions.length;
|
||||
},
|
||||
containsTrigger(): boolean {
|
||||
return this.$store.getters.workflowTriggerNodes.length > 0;
|
||||
},
|
||||
currentWorkflowId(): string {
|
||||
return this.$store.getters.workflowId;
|
||||
return this.workflowsStore.workflowTriggerNodes.length > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSetupFirstStep(event: MouseEvent): void {
|
||||
this.$store.commit('ui/setAddFirstStepOnLoad', true);
|
||||
this.uiStore.addFirstStepOnLoad = true;
|
||||
const workflowRoute = this.getWorkflowRoute();
|
||||
this.$router.push(workflowRoute);
|
||||
},
|
||||
getWorkflowRoute(): { name: string, params: {}} {
|
||||
const workflowId = this.currentWorkflowId || this.$route.params.name;
|
||||
const workflowId = this.workflowsStore.workflowId || this.$route.params.name;
|
||||
if (workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
return { name: VIEWS.NEW_WORKFLOW, params: {} };
|
||||
} else {
|
||||
|
|
|
@ -90,6 +90,8 @@ import { IExecutionsSummary } from "@/Interface";
|
|||
import { Route } from 'vue-router';
|
||||
import Vue from 'vue';
|
||||
import { PropType } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'executions-sidebar',
|
||||
|
@ -122,6 +124,9 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
),
|
||||
statusFilterApplied(): boolean {
|
||||
return this.filter.status !== '';
|
||||
},
|
||||
|
@ -143,7 +148,7 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
this.autoRefresh = this.$store.getters['ui/isExecutionSidebarAutoRefreshOn'];
|
||||
this.autoRefresh = this.uiStore.executionSidebarAutoRefresh === true;
|
||||
if (this.autoRefresh) {
|
||||
this.autoRefreshInterval = setInterval(() => this.onRefresh(), 4000);
|
||||
}
|
||||
|
@ -179,7 +184,7 @@ export default Vue.extend({
|
|||
this.$emit('reloadExecutions');
|
||||
},
|
||||
onAutoRefreshToggle(): void {
|
||||
this.$store.commit('ui/setExecutionsSidebarAutoRefresh', this.autoRefresh);
|
||||
this.uiStore.executionSidebarAutoRefresh = this.autoRefresh;
|
||||
if (this.autoRefreshInterval) {
|
||||
// Clear any previously existing intervals (if any - there shouldn't)
|
||||
clearInterval(this.autoRefreshInterval);
|
||||
|
|
|
@ -37,6 +37,11 @@ import { range as _range } from 'lodash';
|
|||
import { debounceHelper } from '../mixins/debounce';
|
||||
import { getNodeViewTab } from '../helpers';
|
||||
import { workflowHelpers } from '../mixins/workflowHelpers';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(restApi, showMessage, executionHelpers, debounceHelper, workflowHelpers).extend({
|
||||
name: 'executions-page',
|
||||
|
@ -51,6 +56,12 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
hidePreview(): boolean {
|
||||
const nothingToShow = this.executions.length === 0 && this.filterApplied;
|
||||
const activeNotPresent = this.filterApplied && (this.executions as IExecutionsSummary[]).find(ex => ex.id === this.activeExecution.id) === undefined;
|
||||
|
@ -66,13 +77,13 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
return this.filter.status !== '';
|
||||
},
|
||||
workflowDataNotLoaded(): boolean {
|
||||
return this.$store.getters.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID && this.$store.getters.workflowName === '';
|
||||
return this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID && this.workflowsStore.workflowName === '';
|
||||
},
|
||||
loadedFinishedExecutionsCount(): number {
|
||||
return (this.$store.getters['workflows/getAllLoadedFinishedExecutions'] as IExecutionsSummary[]).length;
|
||||
return this.workflowsStore.getAllLoadedFinishedExecutions.length;
|
||||
},
|
||||
totalFinishedExecutionsCount(): number {
|
||||
return this.$store.getters['workflows/getTotalFinishedExecutionsCount'];
|
||||
return this.workflowsStore.getTotalFinishedExecutionsCount;
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
|
@ -81,9 +92,9 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
this.initView(workflowChanged);
|
||||
|
||||
if (to.params.executionId) {
|
||||
const execution = this.$store.getters['workflows/getExecutionDataById'](to.params.executionId);
|
||||
const execution = this.workflowsStore.getExecutionDataById(to.params.executionId);
|
||||
if (execution) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', execution);
|
||||
this.workflowsStore.activeWorkflowExecution = execution;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -92,7 +103,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
const nextTab = getNodeViewTab(to);
|
||||
// When leaving for a page that's not a workflow view tab, ask to save changes
|
||||
if (!nextTab) {
|
||||
const result = this.$store.getters.getStateIsDirty;
|
||||
const result = this.uiStore.stateIsDirty;
|
||||
if (result) {
|
||||
const confirmModal = await this.confirmModal(
|
||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||
|
@ -105,11 +116,11 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
|
||||
if (confirmModal === MODAL_CONFIRMED) {
|
||||
const saved = await this.saveCurrentWorkflow({}, false);
|
||||
if (saved) this.$store.dispatch('settings/fetchPromptsData');
|
||||
this.$store.commit('setStateDirty', false);
|
||||
if (saved) this.settingsStore.fetchPromptsData();
|
||||
this.uiStore.stateIsDirty = false;
|
||||
next();
|
||||
} else if (confirmModal === MODAL_CANCEL) {
|
||||
this.$store.commit('setStateDirty', false);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
next();
|
||||
} else if (confirmModal === MODAL_CLOSE) {
|
||||
next(false);
|
||||
|
@ -122,8 +133,8 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
},
|
||||
async mounted() {
|
||||
this.loading = true;
|
||||
const workflowUpdated = this.$route.params.name !== this.$store.getters.workflowId;
|
||||
const onNewWorkflow = this.$route.params.name === 'new' && this.$store.getters.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||
const workflowUpdated = this.$route.params.name !== this.workflowsStore.workflowId;
|
||||
const onNewWorkflow = this.$route.params.name === 'new' && this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||
const shouldUpdate = workflowUpdated && !onNewWorkflow;
|
||||
await this.initView(shouldUpdate);
|
||||
if (!shouldUpdate) {
|
||||
|
@ -134,11 +145,11 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
methods: {
|
||||
async initView(loadWorkflow: boolean) : Promise<void> {
|
||||
if (loadWorkflow) {
|
||||
if (this.$store.getters['nodeTypes/allNodeTypes'].length === 0) {
|
||||
await this.$store.dispatch('nodeTypes/getNodeTypes');
|
||||
if (this.nodeTypesStore.allNodeTypes.length === 0) {
|
||||
await this.nodeTypesStore.getNodeTypes();
|
||||
}
|
||||
await this.openWorkflow(this.$route.params.name);
|
||||
this.$store.commit('ui/setNodeViewInitialized', false);
|
||||
this.uiStore.nodeViewInitialized = false;
|
||||
this.setExecutions();
|
||||
if (this.activeExecution) {
|
||||
this.$router.push({
|
||||
|
@ -193,7 +204,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
currentExecutions.push(newExecution);
|
||||
}
|
||||
}
|
||||
this.$store.commit('workflows/setCurrentWorkflowExecutions', currentExecutions);
|
||||
this.workflowsStore.currentWorkflowExecutions = currentExecutions;
|
||||
this.loadingMore = false;
|
||||
},
|
||||
async onDeleteCurrentExecution(): Promise<void> {
|
||||
|
@ -203,13 +214,13 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
await this.setExecutions();
|
||||
// Select first execution in the list after deleting the current one
|
||||
if (this.executions.length > 0) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', this.executions[0]);
|
||||
this.workflowsStore.activeWorkflowExecution = this.executions[0];
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
}).catch(()=>{});;
|
||||
} else { // If there are no executions left, show empty state and clear active execution from the store
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', null);
|
||||
this.workflowsStore.activeWorkflowExecution = null;
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME, params: { name: this.currentWorkflow } });
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -233,7 +244,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
},
|
||||
async setExecutions(): Promise<void> {
|
||||
const workflowExecutions = await this.loadExecutions();
|
||||
this.$store.commit('workflows/setCurrentWorkflowExecutions', workflowExecutions);
|
||||
this.workflowsStore.currentWorkflowExecutions = workflowExecutions;
|
||||
this.setActiveExecution();
|
||||
},
|
||||
async loadAutoRefresh(): Promise<void> {
|
||||
|
@ -284,12 +295,12 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
}
|
||||
|
||||
existingExecutions = existingExecutions.filter(execution => !gaps.includes(parseInt(execution.id, 10)) && lastId >= parseInt(execution.id, 10));
|
||||
this.$store.commit('workflows/setCurrentWorkflowExecutions', existingExecutions);
|
||||
this.workflowsStore.currentWorkflowExecutions = existingExecutions;
|
||||
if (updatedActiveExecution !== null) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', updatedActiveExecution);
|
||||
this.workflowsStore.activeWorkflowExecution = updatedActiveExecution;
|
||||
} else {
|
||||
const activeNotInTheList = existingExecutions.find(ex => ex.id === this.activeExecution.id) === undefined;
|
||||
if (activeNotInTheList) {
|
||||
if (activeNotInTheList && this.executions.length > 0) {
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
|
@ -303,7 +314,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
}
|
||||
try {
|
||||
const executions: IExecutionsSummary[] =
|
||||
await this.$store.dispatch('workflows/loadCurrentWorkflowExecutions', this.filter);
|
||||
await this.workflowsStore.loadCurrentWorkflowExecutions(this.filter);
|
||||
return executions;
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
|
@ -316,14 +327,14 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
setActiveExecution(): void {
|
||||
const activeExecutionId = this.$route.params.executionId;
|
||||
if (activeExecutionId) {
|
||||
const execution = this.$store.getters['workflows/getExecutionDataById'](activeExecutionId);
|
||||
const execution = this.workflowsStore.getExecutionDataById(activeExecutionId);
|
||||
if (execution) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', execution);
|
||||
this.workflowsStore.activeWorkflowExecution = execution;
|
||||
}
|
||||
}
|
||||
// If there is no execution in the route, select the first one
|
||||
if (this.$store.getters['workflows/getActiveWorkflowExecution'] === null && this.executions.length > 0) {
|
||||
this.$store.commit('workflows/setActiveWorkflowExecution', this.executions[0]);
|
||||
if (this.workflowsStore.activeWorkflowExecution === null && this.executions.length > 0) {
|
||||
this.workflowsStore.activeWorkflowExecution = this.executions[0];
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
|
@ -353,19 +364,20 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
}
|
||||
await this.addNodes(data.nodes, data.connections);
|
||||
|
||||
this.$store.commit('setActive', data.active || false);
|
||||
this.$store.commit('setWorkflowId', workflowId);
|
||||
this.$store.commit('setWorkflowName', { newName: data.name, setStateDirty: false });
|
||||
this.$store.commit('setWorkflowSettings', data.settings || {});
|
||||
this.$store.commit('setWorkflowPinData', data.pinData || {});
|
||||
this.workflowsStore.setActive(data.active || false);
|
||||
this.workflowsStore.setWorkflowId(workflowId);
|
||||
this.workflowsStore.setWorkflowName({ newName: data.name, setStateDirty: false });
|
||||
this.workflowsStore.setWorkflowSettings(data.settings || {});
|
||||
this.workflowsStore.setWorkflowPinData(data.pinData || {});
|
||||
const tags = (data.tags || []) as ITag[];
|
||||
this.$store.commit('tags/upsertTags', tags);
|
||||
const tagIds = tags.map((tag) => tag.id);
|
||||
this.$store.commit('setWorkflowTagIds', tagIds || []);
|
||||
this.$store.commit('setWorkflowHash', data.hash);
|
||||
this.workflowsStore.setWorkflowTagIds(tagIds || []);
|
||||
this.workflowsStore.setWorkflowHash(data.hash);
|
||||
|
||||
this.$store.commit('tags/upsertTags', tags);
|
||||
|
||||
this.$externalHooks().run('workflow.open', { workflowId, workflowName: data.name });
|
||||
this.$store.commit('setStateDirty', false);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
},
|
||||
async addNodes(nodes: INodeUi[], connections?: IConnections) {
|
||||
if (!nodes || !nodes.length) {
|
||||
|
@ -380,7 +392,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
node.id = uuid();
|
||||
}
|
||||
|
||||
nodeType = this.$store.getters['nodeTypes/getNodeType'](node.type, node.typeVersion) as INodeTypeDescription | null;
|
||||
nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
|
||||
// Make sure that some properties always exist
|
||||
if (!node.hasOwnProperty('disabled')) {
|
||||
|
@ -409,7 +421,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
}
|
||||
}
|
||||
|
||||
this.$store.commit('addNode', node);
|
||||
this.workflowsStore.addNode(node);
|
||||
});
|
||||
|
||||
// Load the connections
|
||||
|
@ -438,7 +450,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
},
|
||||
] as [IConnection, IConnection];
|
||||
|
||||
this.$store.commit('addConnection', { connection: connectionData, setStateDirty: false });
|
||||
this.workflowsStore.addConnection({ connection: connectionData, setStateDirty: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -446,7 +458,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
}
|
||||
},
|
||||
async loadNodesProperties(nodeInfos: INodeTypeNameVersion[]): Promise<void> {
|
||||
const allNodes: INodeTypeDescription[] = this.$store.getters['nodeTypes/allNodeTypes'];
|
||||
const allNodes: INodeTypeDescription[] = this.nodeTypesStore.allNodeTypes;
|
||||
|
||||
const nodesToBeFetched: INodeTypeNameVersion[] = [];
|
||||
allNodes.forEach(node => {
|
||||
|
@ -463,12 +475,12 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
|
||||
if (nodesToBeFetched.length > 0) {
|
||||
// Only call API if node information is actually missing
|
||||
await this.$store.dispatch('nodeTypes/getNodesInformation', nodesToBeFetched);
|
||||
await this.nodeTypesStore.getNodesInformation(nodesToBeFetched);
|
||||
}
|
||||
},
|
||||
async loadActiveWorkflows(): Promise<void> {
|
||||
const activeWorkflows = await this.restApi().getActiveWorkflows();
|
||||
this.$store.commit('setActiveWorkflows', activeWorkflows);
|
||||
this.workflowsStore.activeWorkflows = activeWorkflows;
|
||||
},
|
||||
async onRetryExecution(payload: { execution: IExecutionsSummary, command: string }) {
|
||||
const loadWorkflow = payload.command === 'current-workflow';
|
||||
|
@ -482,7 +494,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
|||
this.loadAutoRefresh();
|
||||
|
||||
this.$telemetry.track('User clicked retry execution button', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
execution_id: payload.execution.id,
|
||||
retry_type: loadWorkflow ? 'current' : 'original',
|
||||
});
|
||||
|
|
|
@ -54,6 +54,9 @@ import { genericHelpers } from '@/components/mixins/genericHelpers';
|
|||
import mixins from 'vue-typed-mixins';
|
||||
import { hasExpressionMapping } from './helpers';
|
||||
import { debounceHelper } from './mixins/debounce';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -78,6 +81,12 @@ export default mixins(
|
|||
latestValue: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
valueChanged (value: string, forceUpdate = false) {
|
||||
this.latestValue = value;
|
||||
|
@ -120,11 +129,11 @@ export default mixins(
|
|||
node_name: string;
|
||||
} = {
|
||||
event_version: '2',
|
||||
node_type_dest: this.$store.getters['ndv/activeNode'].type,
|
||||
node_type_dest: this.ndvStore.activeNode? this.ndvStore.activeNode.type : '',
|
||||
parameter_name_dest: this.parameter.displayName,
|
||||
is_immediate_input: false,
|
||||
variable_expression: eventData.variable,
|
||||
node_name: this.$store.getters['ndv/activeNode'].name,
|
||||
node_name: this.ndvStore.activeNode? this.ndvStore.activeNode.name : '',
|
||||
};
|
||||
|
||||
if (eventData.variable) {
|
||||
|
@ -142,9 +151,9 @@ export default mixins(
|
|||
|
||||
if (splitVar[0].startsWith('$node')) {
|
||||
const sourceNodeName = splitVar[0].split('"')[1];
|
||||
trackProperties.node_type_source = this.$store.getters.getNodeByName(sourceNodeName).type;
|
||||
const nodeConnections: Array<Array<{ node: string }>> = this.$store.getters.outgoingConnectionsByNodeName(sourceNodeName).main;
|
||||
trackProperties.is_immediate_input = (nodeConnections && nodeConnections[0] && !!nodeConnections[0].find(({ node }) => node === this.$store.getters['ndv/activeNode'].name)) ? true : false;
|
||||
trackProperties.node_type_source = this.workflowsStore.getNodeByName(sourceNodeName)?.type;
|
||||
const nodeConnections: Array<Array<{ node: string }>> = this.workflowsStore.outgoingConnectionsByNodeName(sourceNodeName).main;
|
||||
trackProperties.is_immediate_input = (nodeConnections && nodeConnections[0] && !!nodeConnections[0].find(({ node }) => node === this.ndvStore.activeNode?.name || '')) ? true : false;
|
||||
|
||||
if (splitVar[1].startsWith('parameter')) {
|
||||
trackProperties.parameter_name_source = splitVar[1].split('"')[1];
|
||||
|
@ -173,9 +182,9 @@ export default mixins(
|
|||
if (!newValue) {
|
||||
const telemetryPayload = {
|
||||
empty_expression: (this.value === '=') || (this.value === '={{}}') || !this.value,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
source: this.eventSource,
|
||||
session_id: this.$store.getters['ndv/ndvSessionId'],
|
||||
session_id: this.ndvStore.sessionId,
|
||||
has_parameter: this.value.includes('$parameter'),
|
||||
has_mapping: hasExpressionMapping(this.value),
|
||||
};
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
<script lang="ts">
|
||||
import {IFakeDoor} from '@/Interface';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -43,23 +48,28 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
),
|
||||
userId(): string {
|
||||
return this.$store.getters['users/currentUserId'];
|
||||
},
|
||||
versionCli(): string {
|
||||
return this.$store.getters['settings/versionCli'];
|
||||
return this.usersStore.currentUserId || '';
|
||||
},
|
||||
instanceId(): string {
|
||||
return this.$store.getters.instanceId;
|
||||
return this.rootStore.instanceId;
|
||||
},
|
||||
featureInfo(): IFakeDoor {
|
||||
return this.$store.getters['ui/getFakeDoorById'](this.featureId);
|
||||
featureInfo(): IFakeDoor | undefined {
|
||||
return this.uiStore.getFakeDoorById(this.featureId);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openLinkPage() {
|
||||
window.open(`${this.featureInfo.linkURL}&u=${this.instanceId}#${this.userId}&v=${this.versionCli}`, '_blank');
|
||||
this.$telemetry.track('user clicked feature waiting list button', {feature: this.featureId});
|
||||
if (this.featureInfo) {
|
||||
window.open(`${this.featureInfo.linkURL}&u=${this.instanceId}#${this.userId}&v=${this.rootStore.versionCli}`, '_blank');
|
||||
this.$telemetry.track('user clicked feature waiting list button', {feature: this.featureId});
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import { VIEWS } from '@/constants';
|
|||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'TemplateList',
|
||||
name: 'GoBackButton',
|
||||
data() {
|
||||
return {
|
||||
routeHasHistory: false,
|
||||
|
|
|
@ -42,6 +42,8 @@ import Vue from 'vue';
|
|||
|
||||
import { ITemplatesNode } from '@/Interface';
|
||||
import { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
interface NodeIconData {
|
||||
type: string;
|
||||
|
@ -72,6 +74,9 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
fontStyleData(): object {
|
||||
return {
|
||||
'max-width': this.size + 'px',
|
||||
|
@ -115,7 +120,7 @@ export default Vue.extend({
|
|||
return (nodeType as ITemplatesNode).iconData;
|
||||
}
|
||||
|
||||
const restUrl = this.$store.getters.getRestUrl;
|
||||
const restUrl = this.rootStore.getRestUrl;
|
||||
|
||||
if (nodeType.icon) {
|
||||
const [type, path] = nodeType.icon.split(':');
|
||||
|
|
|
@ -50,6 +50,9 @@ import {
|
|||
import { showMessage } from './mixins/showMessage';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { INodeUi } from '@/Interface';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(showMessage).extend({
|
||||
name: 'ImportCurlModal',
|
||||
|
@ -64,8 +67,12 @@ export default mixins(showMessage).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
node(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
),
|
||||
node(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -80,8 +87,7 @@ export default mixins(showMessage).extend({
|
|||
if (curlCommand === '') return;
|
||||
|
||||
try {
|
||||
const parameters = await this.$store.dispatch('ui/getCurlToJson', curlCommand);
|
||||
|
||||
const parameters = await this.uiStore.getCurlToJson(curlCommand);
|
||||
const url = parameters['parameters.url'];
|
||||
|
||||
const invalidProtocol = CURL_IMPORT_NOT_SUPPORTED_PROTOCOLS.find((p) =>
|
||||
|
@ -89,7 +95,8 @@ export default mixins(showMessage).extend({
|
|||
);
|
||||
|
||||
if (!invalidProtocol) {
|
||||
this.$store.dispatch('ui/setHttpNodeParameters', {
|
||||
this.uiStore.setHttpNodeParameters({
|
||||
name: IMPORT_CURL_MODAL_KEY,
|
||||
parameters: JSON.stringify(parameters),
|
||||
});
|
||||
|
||||
|
@ -114,7 +121,7 @@ export default mixins(showMessage).extend({
|
|||
|
||||
this.sendTelemetry({ success: false, invalidProtocol: false });
|
||||
} finally {
|
||||
this.$store.dispatch('ui/setCurlCommand', { command: this.curlCommand });
|
||||
this.uiStore.setCurlCommand({ name: IMPORT_CURL_MODAL_KEY, command: this.curlCommand });
|
||||
}
|
||||
},
|
||||
showProtocolErrorWithSupportedNode(protocol: string, node: string): void {
|
||||
|
@ -168,7 +175,7 @@ export default mixins(showMessage).extend({
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
this.curlCommand = this.$store.getters['ui/getCurlCommand'];
|
||||
this.curlCommand = this.uiStore.getCurlCommand || '';
|
||||
setTimeout(() => {
|
||||
(this.$refs.input as HTMLTextAreaElement).focus();
|
||||
});
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { IMPORT_CURL_MODAL_KEY } from '@/constants';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { mapStores } from 'pinia';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { showMessage } from './mixins/showMessage';
|
||||
|
||||
|
@ -23,9 +25,12 @@ export default mixins(showMessage).extend({
|
|||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
methods: {
|
||||
onImportCurlClicked() {
|
||||
this.$store.dispatch('ui/openModal', IMPORT_CURL_MODAL_KEY);
|
||||
this.uiStore.openModal(IMPORT_CURL_MODAL_KEY);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -76,6 +76,10 @@ import mixins from 'vue-typed-mixins';
|
|||
import NodeExecuteButton from './NodeExecuteButton.vue';
|
||||
import WireMeUp from './WireMeUp.vue';
|
||||
import { CRON_NODE_TYPE, INTERVAL_NODE_TYPE, LOCAL_STORAGE_MAPPING_FLAG, MANUAL_TRIGGER_NODE_TYPE, SCHEDULE_TRIGGER_NODE_TYPE, START_NODE_TYPE } from '@/constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
workflowHelpers,
|
||||
|
@ -111,8 +115,13 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
focusedMappableInput(): string {
|
||||
return this.$store.getters['ndv/focusedMappableInput'];
|
||||
return this.ndvStore.focusedMappableInput;
|
||||
},
|
||||
isUserOnboarded(): boolean {
|
||||
return window.localStorage.getItem(LOCAL_STORAGE_MAPPING_FLAG) === 'true';
|
||||
|
@ -129,8 +138,8 @@ export default mixins(
|
|||
if (!this.workflowRunning) {
|
||||
return false;
|
||||
}
|
||||
const triggeredNode = this.$store.getters.executedNode;
|
||||
const executingNode = this.$store.getters.executingNode;
|
||||
const triggeredNode = this.workflowsStore.executedNode;
|
||||
const executingNode = this.workflowsStore.executingNode;
|
||||
if (this.activeNode && triggeredNode === this.activeNode.name && this.activeNode.name !== executingNode) {
|
||||
return true;
|
||||
}
|
||||
|
@ -141,16 +150,16 @@ export default mixins(
|
|||
return false;
|
||||
},
|
||||
workflowRunning (): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
currentWorkflow(): Workflow {
|
||||
return this.workflow as Workflow;
|
||||
},
|
||||
activeNode (): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
currentNode (): INodeUi | null {
|
||||
return this.$store.getters.getNodeByName(this.currentNodeName);
|
||||
return this.workflowsStore.getNodeByName(this.currentNodeName);
|
||||
},
|
||||
connectedCurrentNodeOutputs(): number[] | undefined {
|
||||
const search = this.parentNodes.find(({name}) => name === this.currentNodeName);
|
||||
|
@ -174,7 +183,7 @@ export default mixins(
|
|||
activeNodeType () : INodeTypeDescription | null {
|
||||
if (!this.activeNode) return null;
|
||||
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.activeNode.type, this.activeNode.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.activeNode.type, this.activeNode.typeVersion);
|
||||
},
|
||||
isMultiInputNode (): boolean {
|
||||
return this.activeNodeType !== null && this.activeNodeType.inputs.length > 1;
|
||||
|
@ -214,7 +223,7 @@ export default mixins(
|
|||
if (this.activeNode) {
|
||||
this.$telemetry.track('User clicked ndv button', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'input',
|
||||
type: 'executePrevious',
|
||||
|
@ -238,7 +247,7 @@ export default mixins(
|
|||
if (this.activeNode) {
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'input',
|
||||
type: 'not-connected-help',
|
||||
|
|
|
@ -32,6 +32,8 @@ import Vue from "vue";
|
|||
import { IFormInputs, IInviteResponse } from "@/Interface";
|
||||
import { VALID_EMAIL_REGEX, INVITE_USER_MODAL_KEY } from "@/constants";
|
||||
import { ROLE } from "@/modules/userHelpers";
|
||||
import { mapStores } from "pinia";
|
||||
import { useUsersStore } from "@/stores/users";
|
||||
|
||||
const NAME_EMAIL_FORMAT_REGEX = /^.* <(.*)>$/;
|
||||
|
||||
|
@ -101,6 +103,7 @@ export default mixins(showMessage).extend({
|
|||
];
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUsersStore),
|
||||
emailsCount(): number {
|
||||
return this.emails.split(',').filter((email: string) => !!email.trim()).length;
|
||||
},
|
||||
|
@ -156,7 +159,7 @@ export default mixins(showMessage).extend({
|
|||
throw new Error(this.$locale.baseText('settings.users.noUsersToInvite'));
|
||||
}
|
||||
|
||||
const invited: IInviteResponse[] = await this.$store.dispatch('users/inviteUsers', emails);
|
||||
const invited: IInviteResponse[] = await this.usersStore.inviteUsers(emails);
|
||||
const invitedEmails = invited.reduce((accu, {user, error}) => {
|
||||
if (error) {
|
||||
accu.error.push(user.email);
|
||||
|
|
|
@ -7,12 +7,17 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
basePath(): string {
|
||||
return this.$store.getters.getBaseUrl;
|
||||
return this.rootStore.baseUrl;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -43,12 +43,14 @@
|
|||
<script lang="ts">
|
||||
import mixins from "vue-typed-mixins";
|
||||
|
||||
import { IExecutionResponse } from "../../../Interface";
|
||||
import { IExecutionResponse, IExecutionsSummary } from "../../../Interface";
|
||||
|
||||
import { titleChange } from "@/components/mixins/titleChange";
|
||||
|
||||
import ShortenName from "@/components/ShortenName.vue";
|
||||
import ReadOnly from "@/components/MainHeader/ExecutionDetails/ReadOnly.vue";
|
||||
import { mapStores } from "pinia";
|
||||
import { useWorkflowsStore } from "@/stores/workflows";
|
||||
|
||||
export default mixins(titleChange).extend({
|
||||
name: "ExecutionDetails",
|
||||
|
@ -57,24 +59,27 @@ export default mixins(titleChange).extend({
|
|||
ReadOnly,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useWorkflowsStore,
|
||||
),
|
||||
executionId(): string | undefined {
|
||||
return this.$route.params.id;
|
||||
},
|
||||
executionFinished(): boolean {
|
||||
const fullExecution = this.$store.getters.getWorkflowExecution;
|
||||
const fullExecution = this.workflowsStore.getWorkflowExecution;
|
||||
|
||||
return !!fullExecution && fullExecution.finished;
|
||||
},
|
||||
executionWaiting(): boolean {
|
||||
const fullExecution = this.$store.getters.getWorkflowExecution;
|
||||
const fullExecution = this.workflowsStore.getWorkflowExecution as IExecutionsSummary;
|
||||
|
||||
return !!fullExecution && !!fullExecution.waitTill;
|
||||
},
|
||||
workflowExecution(): IExecutionResponse | null {
|
||||
return this.$store.getters.getWorkflowExecution;
|
||||
return this.workflowsStore.getWorkflowExecution;
|
||||
},
|
||||
workflowName(): string {
|
||||
return this.$store.getters.workflowName;
|
||||
return this.workflowsStore.workflowName;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div :class="{'main-header': true, expanded: !sidebarMenuCollapsed}">
|
||||
<div :class="{'main-header': true, expanded: !this.uiStore.sidebarMenuCollapsed}">
|
||||
<div v-show="!hideMenuBar" class="top-menu">
|
||||
<ExecutionDetails v-if="isExecutionPage" />
|
||||
<WorkflowDetails v-else />
|
||||
|
@ -12,7 +12,6 @@
|
|||
|
||||
<script lang="ts">
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { pushConnection } from '@/components/mixins/pushConnection';
|
||||
import WorkflowDetails from '@/components/MainHeader/WorkflowDetails.vue';
|
||||
import ExecutionDetails from '@/components/MainHeader/ExecutionDetails/ExecutionDetails.vue';
|
||||
|
@ -21,6 +20,9 @@ import { MAIN_HEADER_TABS, PLACEHOLDER_EMPTY_WORKFLOW_ID, STICKY_NODE_TYPE, VIEW
|
|||
import { IExecutionsSummary, INodeUi, ITabBarItem } from '@/Interface';
|
||||
import { workflowHelpers } from '../mixins/workflowHelpers';
|
||||
import { Route } from 'vue-router';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
pushConnection,
|
||||
|
@ -36,13 +38,14 @@ export default mixins(
|
|||
return {
|
||||
activeHeaderTab: MAIN_HEADER_TABS.WORKFLOW,
|
||||
workflowToReturnTo: '',
|
||||
dirtyState: this.$store.getters.getStateIsDirty,
|
||||
dirtyState: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('ui', [
|
||||
'sidebarMenuCollapsed',
|
||||
]),
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
),
|
||||
tabBarItems(): ITabBarItem[] {
|
||||
return [
|
||||
{ value: MAIN_HEADER_TABS.WORKFLOW, label: this.$locale.baseText('generic.workflow') },
|
||||
|
@ -53,25 +56,26 @@ export default mixins(
|
|||
return this.$route.name === VIEWS.EXECUTION;
|
||||
},
|
||||
activeNode (): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
hideMenuBar(): boolean {
|
||||
return Boolean(this.activeNode && this.activeNode.type !== STICKY_NODE_TYPE);
|
||||
},
|
||||
workflowName (): string {
|
||||
return this.$store.getters.workflowName;
|
||||
return this.workflowsStore.workflowName;
|
||||
},
|
||||
currentWorkflow (): string {
|
||||
return this.$route.params.name || this.$store.getters.workflowId;
|
||||
return this.$route.params.name || this.workflowsStore.workflowId;
|
||||
},
|
||||
onWorkflowPage(): boolean {
|
||||
return this.$route.meta && (this.$route.meta.nodeView || this.$route.meta.keepWorkflowAlive === true);
|
||||
},
|
||||
activeExecution(): IExecutionsSummary {
|
||||
return this.$store.getters['workflows/getActiveWorkflowExecution'];
|
||||
return this.workflowsStore.activeWorkflowExecution as IExecutionsSummary;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.dirtyState = this.uiStore.stateIsDirty;
|
||||
this.syncTabsWithRoute(this.$route);
|
||||
// Initialize the push connection
|
||||
this.pushConnect();
|
||||
|
@ -109,13 +113,13 @@ export default mixins(
|
|||
} else {
|
||||
if (this.$route.name !== VIEWS.NEW_WORKFLOW) {
|
||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
||||
this.$store.commit('setStateDirty', this.dirtyState);
|
||||
this.uiStore.stateIsDirty = this.dirtyState;
|
||||
}
|
||||
}
|
||||
this.activeHeaderTab = MAIN_HEADER_TABS.WORKFLOW;
|
||||
break;
|
||||
case MAIN_HEADER_TABS.EXECUTIONS:
|
||||
this.dirtyState = this.$store.getters.getStateIsDirty;
|
||||
this.dirtyState = this.uiStore.stateIsDirty;
|
||||
this.workflowToReturnTo = this.currentWorkflow;
|
||||
const routeWorkflowId = this.currentWorkflow === PLACEHOLDER_EMPTY_WORKFLOW_ID ? 'new' : this.currentWorkflow;
|
||||
if (this.activeExecution) {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
import Vue, { PropType } from 'vue';
|
||||
import { ITabBarItem } from '@/Interface';
|
||||
import { MAIN_HEADER_TABS } from '@/constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'tab-bar',
|
||||
|
@ -31,8 +33,11 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
),
|
||||
mainSidebarCollapsed(): boolean {
|
||||
return this.$store.getters['ui/sidebarMenuCollapsed'];
|
||||
return this.uiStore.sidebarMenuCollapsed;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</template>
|
||||
</BreakpointsObserver>
|
||||
|
||||
<span v-if="areTagsEnabled" class="tags">
|
||||
<span v-if="settingsStore.areTagsEnabled" class="tags">
|
||||
<div
|
||||
v-if="isTagsEditEnabled">
|
||||
<TagsDropdown
|
||||
|
@ -105,6 +105,11 @@ import { IWorkflowDataUpdate, IWorkflowToShare } from "@/Interface";
|
|||
import { saveAs } from 'file-saver';
|
||||
import { titleChange } from "../mixins/titleChange";
|
||||
import type { MessageBoxInputData } from 'element-ui/types/message-box';
|
||||
import { mapStores } from "pinia";
|
||||
import { useUIStore } from "@/stores/ui";
|
||||
import { useSettingsStore } from "@/stores/settings";
|
||||
import { useWorkflowsStore } from "@/stores/workflows";
|
||||
import { useRootStore } from "@/stores/n8nRootStore";
|
||||
|
||||
const hasChanged = (prev: string[], curr: string[]) => {
|
||||
if (prev.length !== curr.length) {
|
||||
|
@ -138,24 +143,32 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isWorkflowActive: "isActive",
|
||||
workflowName: "workflowName",
|
||||
isDirty: "getStateIsDirty",
|
||||
currentWorkflowTagIds: "workflowTags",
|
||||
}),
|
||||
...mapGetters('settings', ['areTagsEnabled']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
isWorkflowActive(): boolean {
|
||||
return this.workflowsStore.isWorkflowActive;
|
||||
},
|
||||
workflowName(): string {
|
||||
return this.workflowsStore.workflowName;
|
||||
},
|
||||
isDirty(): boolean {
|
||||
return this.uiStore.stateIsDirty;
|
||||
},
|
||||
currentWorkflowTagIds(): string[] {
|
||||
return this.workflowsStore.workflowTags;
|
||||
},
|
||||
isNewWorkflow(): boolean {
|
||||
return !this.currentWorkflowId || (this.currentWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID || this.currentWorkflowId === 'new');
|
||||
},
|
||||
isWorkflowSaving(): boolean {
|
||||
return this.$store.getters.isActionActive("workflowSaving");
|
||||
return this.uiStore.isActionActive('workflowSaving');
|
||||
},
|
||||
currentWorkflowId(): string {
|
||||
return this.$store.getters.workflowId;
|
||||
},
|
||||
workflowName (): string {
|
||||
return this.$store.getters.workflowName;
|
||||
return this.workflowsStore.workflowId;
|
||||
},
|
||||
onWorkflowPage(): boolean {
|
||||
return this.$route.meta && (this.$route.meta.nodeView || this.$route.meta.keepWorkflowAlive === true);
|
||||
|
@ -209,7 +222,7 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
currentId = this.$route.params.name;
|
||||
}
|
||||
const saved = await this.saveCurrentWorkflow({ id: currentId, name: this.workflowName, tags: this.currentWorkflowTagIds });
|
||||
if (saved) this.$store.dispatch('settings/fetchPromptsData');
|
||||
if (saved) await this.settingsStore.fetchPromptsData();
|
||||
},
|
||||
onTagsEditEnable() {
|
||||
this.$data.appliedTagIds = this.currentWorkflowTagIds;
|
||||
|
@ -314,12 +327,12 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
async onWorkflowMenuSelect(action: string): Promise<void> {
|
||||
switch (action) {
|
||||
case WORKFLOW_MENU_ACTIONS.DUPLICATE: {
|
||||
await this.$store.dispatch('ui/openModalWithData', {
|
||||
this.uiStore.openModalWithData({
|
||||
name: DUPLICATE_MODAL_KEY,
|
||||
data: {
|
||||
id: this.$store.getters.workflowId,
|
||||
name: this.$store.getters.workflowName,
|
||||
tags: this.$store.getters.workflowTags,
|
||||
id: this.workflowsStore.workflowId,
|
||||
name: this.workflowsStore.workflowName,
|
||||
tags: this.workflowsStore.workflowTags,
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
@ -334,7 +347,7 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
const exportData: IWorkflowToShare = {
|
||||
...data,
|
||||
meta: {
|
||||
instanceId: this.$store.getters.instanceId,
|
||||
instanceId: this.rootStore.instanceId,
|
||||
},
|
||||
tags: (tags || []).map(tagId => {
|
||||
const {usageCount, ...tag} = this.$store.getters["tags/getTagById"](tagId);
|
||||
|
@ -347,7 +360,7 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
type: 'application/json;charset=utf-8',
|
||||
});
|
||||
|
||||
let workflowName = this.$store.getters.workflowName || 'unsaved_workflow';
|
||||
let workflowName = this.workflowName || 'unsaved_workflow';
|
||||
workflowName = workflowName.replace(/[^a-z0-9]/gi, '_');
|
||||
|
||||
this.$telemetry.track('User exported workflow', { workflow_id: workflowData.id });
|
||||
|
@ -376,7 +389,7 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
break;
|
||||
}
|
||||
case WORKFLOW_MENU_ACTIONS.SETTINGS: {
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
break;
|
||||
}
|
||||
case WORKFLOW_MENU_ACTIONS.DELETE: {
|
||||
|
@ -404,7 +417,7 @@ export default mixins(workflowHelpers, titleChange).extend({
|
|||
);
|
||||
return;
|
||||
}
|
||||
this.$store.commit('setStateDirty', false);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
// Reset tab title since workflow is deleted.
|
||||
this.$titleReset();
|
||||
this.$showMessage({
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!-- This dropdown is only enabled when sidebar is collapsed -->
|
||||
<el-dropdown :disabled="!isCollapsed" placement="right-end" trigger="click" @command="onUserActionToggle">
|
||||
<div :class="{[$style.avatar]: true, ['clickable']: isCollapsed }">
|
||||
<n8n-avatar :firstName="currentUser.firstName" :lastName="currentUser.lastName" size="small" />
|
||||
<n8n-avatar :firstName="usersStore.currentUser.firstName" :lastName="usersStore.currentUser.lastName" size="small" />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="settings">{{ $locale.baseText('settings') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">{{ $locale.baseText('auth.signout') }}</el-dropdown-item>
|
||||
|
@ -40,7 +40,7 @@
|
|||
</el-dropdown>
|
||||
</div>
|
||||
<div :class="{ ['ml-2xs']: true, [$style.userName]: true, [$style.expanded]: fullyExpanded }">
|
||||
<n8n-text size="small" :bold="true" color="text-dark">{{currentUser.fullName}}</n8n-text>
|
||||
<n8n-text size="small" :bold="true" color="text-dark">{{usersStore.currentUser.fullName}}</n8n-text>
|
||||
</div>
|
||||
<div :class="{ [$style.userActions]: true, [$style.expanded]: fullyExpanded }">
|
||||
<n8n-action-dropdown :items="userMenuItems" placement="top-start" @select="onUserActionToggle" />
|
||||
|
@ -78,12 +78,17 @@ import {
|
|||
VERSIONS_MODAL_KEY,
|
||||
EXECUTIONS_MODAL_KEY,
|
||||
VIEWS,
|
||||
WORKFLOW_OPEN_MODAL_KEY,
|
||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||
} from '@/constants';
|
||||
import { userHelpers } from './mixins/userHelpers';
|
||||
import { debounceHelper } from './mixins/debounce';
|
||||
import Vue from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default mixins(
|
||||
genericHelpers,
|
||||
|
@ -105,36 +110,34 @@ export default mixins(
|
|||
data () {
|
||||
return {
|
||||
// @ts-ignore
|
||||
basePath: this.$store.getters.getBaseUrl,
|
||||
basePath: '',
|
||||
fullyExpanded: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('ui', {
|
||||
isCollapsed: 'sidebarMenuCollapsed',
|
||||
isNodeView: 'isNodeView',
|
||||
}),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapGetters('versions', [
|
||||
'hasVersionUpdates',
|
||||
'nextVersions',
|
||||
]),
|
||||
...mapGetters('users', [
|
||||
'canUserAccessSidebarUserInfo',
|
||||
'currentUser',
|
||||
]),
|
||||
...mapGetters('settings', [
|
||||
'isTemplatesEnabled',
|
||||
'isUserManagementEnabled',
|
||||
]),
|
||||
isCollapsed(): boolean {
|
||||
return this.uiStore.sidebarMenuCollapsed;
|
||||
},
|
||||
canUserAccessSettings(): boolean {
|
||||
const accessibleRoute = this.findFirstAccessibleSettingsRoute();
|
||||
return accessibleRoute !== null;
|
||||
},
|
||||
showUserArea(): boolean {
|
||||
return this.isUserManagementEnabled && this.canUserAccessSidebarUserInfo && this.currentUser;
|
||||
return this.settingsStore.isUserManagementEnabled && this.usersStore.canUserAccessSidebarUserInfo && this.usersStore.currentUser !== null;
|
||||
},
|
||||
workflowExecution (): IExecutionResponse | null {
|
||||
return this.$store.getters.getWorkflowExecution;
|
||||
return this.workflowsStore.getWorkflowExecution;
|
||||
},
|
||||
userMenuItems (): object[] {
|
||||
return [
|
||||
|
@ -150,7 +153,7 @@ export default mixins(
|
|||
},
|
||||
mainMenuItems (): IMenuItem[] {
|
||||
const items: IMenuItem[] = [];
|
||||
const injectedItems = this.$store.getters.sidebarMenuItems as IMenuItem[];
|
||||
const injectedItems = this.uiStore.sidebarMenuItems;
|
||||
|
||||
if (injectedItems && injectedItems.length > 0) {
|
||||
for(const item of injectedItems) {
|
||||
|
@ -182,7 +185,7 @@ export default mixins(
|
|||
icon: 'box-open',
|
||||
label: this.$locale.baseText('mainSidebar.templates'),
|
||||
position: 'top',
|
||||
available: this.isTemplatesEnabled,
|
||||
available: this.settingsStore.isTemplatesEnabled,
|
||||
activateOnRouteNames: [ VIEWS.TEMPLATES ],
|
||||
},
|
||||
{
|
||||
|
@ -204,7 +207,7 @@ export default mixins(
|
|||
icon: 'cog',
|
||||
label: this.$locale.baseText('settings'),
|
||||
position: 'bottom',
|
||||
available: this.canUserAccessSettings && this.currentUser,
|
||||
available: this.canUserAccessSettings && this.usersStore.currentUser !== null,
|
||||
activateOnRouteNames: [ VIEWS.USERS_SETTINGS, VIEWS.API_SETTINGS, VIEWS.PERSONAL_SETTINGS ],
|
||||
},
|
||||
{
|
||||
|
@ -266,13 +269,14 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.basePath = this.rootStore.baseUrl;
|
||||
if (this.$refs.user) {
|
||||
this.$externalHooks().run('mainSidebar.mounted', { userRef: this.$refs.user });
|
||||
}
|
||||
if (window.innerWidth < 900 || this.isNodeView) {
|
||||
this.$store.commit('ui/collapseSidebarMenu');
|
||||
if (window.innerWidth < 900 || this.uiStore.isNodeView) {
|
||||
this.uiStore.sidebarMenuCollapsed = true;
|
||||
} else {
|
||||
this.$store.commit('ui/expandSidebarMenu');
|
||||
this.uiStore.sidebarMenuCollapsed = false;
|
||||
}
|
||||
await Vue.nextTick();
|
||||
this.fullyExpanded = !this.isCollapsed;
|
||||
|
@ -285,7 +289,7 @@ export default mixins(
|
|||
},
|
||||
methods: {
|
||||
trackHelpItemClick (itemType: string) {
|
||||
this.$telemetry.track('User clicked help resource', { type: itemType, workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User clicked help resource', { type: itemType, workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
async onUserActionToggle(action: string) {
|
||||
switch (action) {
|
||||
|
@ -301,8 +305,7 @@ export default mixins(
|
|||
},
|
||||
async onLogout() {
|
||||
try {
|
||||
await this.$store.dispatch('users/logout');
|
||||
|
||||
await this.usersStore.logout();
|
||||
const route = this.$router.resolve({ name: VIEWS.SIGNIN });
|
||||
window.open(route.href, '_self');
|
||||
} catch (e) {
|
||||
|
@ -310,7 +313,7 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
toggleCollapse () {
|
||||
this.$store.commit('ui/toggleSidebarMenuCollapse');
|
||||
this.uiStore.toggleSidebarMenuCollapse();
|
||||
// When expanding, delay showing some element to ensure smooth animation
|
||||
if (!this.isCollapsed) {
|
||||
setTimeout(() => {
|
||||
|
@ -321,7 +324,7 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
openUpdatesPanel() {
|
||||
this.$store.dispatch('ui/openModal', VERSIONS_MODAL_KEY);
|
||||
this.uiStore.openModal(VERSIONS_MODAL_KEY);
|
||||
},
|
||||
async handleSelect (key: string) {
|
||||
switch (key) {
|
||||
|
@ -344,7 +347,7 @@ export default mixins(
|
|||
break;
|
||||
}
|
||||
case 'executions': {
|
||||
this.$store.dispatch('ui/openModal', EXECUTIONS_MODAL_KEY);
|
||||
this.uiStore.openModal(EXECUTIONS_MODAL_KEY);
|
||||
break;
|
||||
}
|
||||
case 'settings': {
|
||||
|
@ -359,7 +362,7 @@ export default mixins(
|
|||
}
|
||||
case 'about': {
|
||||
this.trackHelpItemClick('about');
|
||||
this.$store.dispatch('ui/openModal', ABOUT_MODAL_KEY);
|
||||
this.uiStore.openModal(ABOUT_MODAL_KEY);
|
||||
break;
|
||||
}
|
||||
case 'quickstart':
|
||||
|
@ -373,7 +376,7 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
async createNewWorkflow (): Promise<void> {
|
||||
const result = this.$store.getters.getStateIsDirty;
|
||||
const result = this.uiStore.stateIsDirty;
|
||||
if(result) {
|
||||
const confirmModal = await this.confirmModal(
|
||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||
|
@ -385,7 +388,7 @@ export default mixins(
|
|||
);
|
||||
if (confirmModal === MODAL_CONFIRMED) {
|
||||
const saved = await this.saveCurrentWorkflow({}, false);
|
||||
if (saved) this.$store.dispatch('settings/fetchPromptsData');
|
||||
if (saved) await this.settingsStore.fetchPromptsData();
|
||||
if (this.$router.currentRoute.name === VIEWS.NEW_WORKFLOW) {
|
||||
this.$root.$emit('newWorkflow');
|
||||
} else {
|
||||
|
@ -396,11 +399,11 @@ export default mixins(
|
|||
type: 'success',
|
||||
});
|
||||
} else if (confirmModal === MODAL_CANCEL) {
|
||||
this.$store.commit('setStateDirty', false);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
if (this.$router.currentRoute.name === VIEWS.NEW_WORKFLOW) {
|
||||
this.$root.$emit('newWorkflow');
|
||||
} else {
|
||||
this.$store.commit('setWorkflowId', PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
||||
}
|
||||
this.$showMessage({
|
||||
|
@ -412,7 +415,7 @@ export default mixins(
|
|||
}
|
||||
} else {
|
||||
if (this.$router.currentRoute.name !== VIEWS.NEW_WORKFLOW) {
|
||||
this.$store.commit('setWorkflowId', PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
||||
}
|
||||
this.$showMessage({
|
||||
|
@ -447,7 +450,7 @@ export default mixins(
|
|||
},
|
||||
checkWidthAndAdjustSidebar (width: number) {
|
||||
if (width < 900) {
|
||||
this.$store.commit('ui/collapseSidebarMenu');
|
||||
this.uiStore.sidebarMenuCollapsed = true;
|
||||
Vue.nextTick(() => {
|
||||
this.fullyExpanded = !this.isCollapsed;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:visible="visible"
|
||||
:visible="uiStore.isModalOpen(this.$props.name)"
|
||||
:before-close="closeDialog"
|
||||
:class="{'dialog-wrapper': true, [$style.center]: center, scrollable: scrollable}"
|
||||
:width="width"
|
||||
|
@ -38,6 +38,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { mapStores } from "pinia";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "Modal",
|
||||
|
@ -118,7 +120,7 @@ export default Vue.extend({
|
|||
});
|
||||
|
||||
this.$props.eventBus.$on('closeAll', () => {
|
||||
this.closeAllDialogs();
|
||||
this.uiStore.closeAllModals();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -130,51 +132,8 @@ export default Vue.extend({
|
|||
beforeDestroy() {
|
||||
window.removeEventListener('keydown', this.onWindowKeydown);
|
||||
},
|
||||
methods: {
|
||||
onWindowKeydown(event: KeyboardEvent) {
|
||||
if (!this.isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event && event.keyCode === 13) {
|
||||
this.handleEnter();
|
||||
}
|
||||
},
|
||||
handleEnter() {
|
||||
if (this.isActive) {
|
||||
this.$emit('enter');
|
||||
}
|
||||
},
|
||||
closeAllDialogs() {
|
||||
this.$store.commit('ui/closeAllModals');
|
||||
},
|
||||
async closeDialog() {
|
||||
if (this.beforeClose) {
|
||||
const shouldClose = await this.beforeClose();
|
||||
if (shouldClose === false) { // must be strictly false to stop modal from closing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.$store.commit('ui/closeModal', this.$props.name);
|
||||
},
|
||||
getCustomClass() {
|
||||
let classes = this.$props.customClass || '';
|
||||
|
||||
if (this.$props.classic) {
|
||||
classes = `${classes} classic`;
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isActive(): boolean {
|
||||
return this.$store.getters['ui/isModalActive'](this.$props.name);
|
||||
},
|
||||
visible(): boolean {
|
||||
return this.$store.getters['ui/isModalOpen'](this.$props.name);
|
||||
},
|
||||
...mapStores(useUIStore),
|
||||
styles() {
|
||||
const styles: {[prop: string]: string} = {};
|
||||
if (this.height) {
|
||||
|
@ -195,6 +154,40 @@ export default Vue.extend({
|
|||
return styles;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onWindowKeydown(event: KeyboardEvent) {
|
||||
if (!this.uiStore.isModalActive(this.$props.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event && event.keyCode === 13) {
|
||||
this.handleEnter();
|
||||
}
|
||||
},
|
||||
handleEnter() {
|
||||
if (this.uiStore.isModalActive(this.$props.name)) {
|
||||
this.$emit('enter');
|
||||
}
|
||||
},
|
||||
async closeDialog() {
|
||||
if (this.beforeClose) {
|
||||
const shouldClose = await this.beforeClose();
|
||||
if (shouldClose === false) { // must be strictly false to stop modal from closing
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.uiStore.closeModal(this.$props.name);
|
||||
},
|
||||
getCustomClass() {
|
||||
let classes = this.$props.customClass || '';
|
||||
|
||||
if (this.$props.classic) {
|
||||
classes = `${classes} classic`;
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-drawer
|
||||
:direction="direction"
|
||||
:visible="visible"
|
||||
:visible="uiStore.isModalOpen(this.$props.name)"
|
||||
:size="width"
|
||||
:before-close="close"
|
||||
:modal="modal"
|
||||
|
@ -19,6 +19,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useUIStore } from "@/stores/ui";
|
||||
import { mapStores } from "pinia";
|
||||
import Vue from "vue";
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -65,9 +67,12 @@ export default Vue.extend({
|
|||
beforeDestroy() {
|
||||
window.removeEventListener('keydown', this.onWindowKeydown);
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
methods: {
|
||||
onWindowKeydown(event: KeyboardEvent) {
|
||||
if (!this.isActive) {
|
||||
if (!this.uiStore.isModalActive(this.$props.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -76,7 +81,7 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
handleEnter() {
|
||||
if (this.isActive) {
|
||||
if (this.uiStore.isModalActive(this.$props.name)) {
|
||||
this.$emit('enter');
|
||||
}
|
||||
},
|
||||
|
@ -87,16 +92,7 @@ export default Vue.extend({
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.$store.commit('ui/closeModal', this.$props.name);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isActive(): boolean {
|
||||
return this.$store.getters['ui/isModalActive'](this.$props.name);
|
||||
},
|
||||
visible(): boolean {
|
||||
return this.$store.getters['ui/isModalOpen'](this.$props.name);
|
||||
this.uiStore.closeModal(this.$props.name);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,40 +1,36 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="isOpen(name) || keepAlive"
|
||||
v-if="uiStore.isModalOpen(name) || keepAlive"
|
||||
>
|
||||
<slot
|
||||
:modalName="name"
|
||||
:active="isActive(name)"
|
||||
:open="isOpen(name)"
|
||||
:activeId="getActiveId(name)"
|
||||
:mode="getMode(name)"
|
||||
:data="getData(name)"
|
||||
:active="uiStore.isModalActive(name)"
|
||||
:open="uiStore.isModalOpen(name)"
|
||||
:activeId="uiStore.getModalActiveId(name)"
|
||||
:mode="uiStore.getModalMode(name)"
|
||||
:data="uiStore.getModalData(name)"
|
||||
></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { mapStores } from "pinia";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "ModalRoot",
|
||||
props: ["name", "keepAlive"],
|
||||
methods: {
|
||||
isActive(name: string) {
|
||||
return this.$store.getters['ui/isModalActive'](name);
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
isOpen(name: string) {
|
||||
return this.$store.getters['ui/isModalOpen'](name);
|
||||
},
|
||||
getData(name: string) {
|
||||
return this.$store.getters['ui/getModalData'](name);
|
||||
},
|
||||
getMode(name: string) {
|
||||
return this.$store.getters['ui/getModalMode'](name);
|
||||
},
|
||||
getActiveId(name: string) {
|
||||
return this.$store.getters['ui/getModalActiveId'](name);
|
||||
keepAlive: {
|
||||
type: Boolean,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -49,6 +49,9 @@ import {
|
|||
} from '@/constants';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { debounceHelper } from './mixins/debounce';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { nodePanelType } from '@/Interface';
|
||||
|
||||
|
||||
const SIDE_MARGIN = 24;
|
||||
|
@ -116,32 +119,35 @@ export default mixins(debounceHelper).extend({
|
|||
window.removeEventListener('resize', this.setTotalWidth);
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
mainPanelDimensions(): {
|
||||
relativeWidth: number,
|
||||
relativeLeft: number,
|
||||
relativeRight: number
|
||||
} {
|
||||
return this.$store.getters['ndv/mainPanelDimensions'](this.currentNodePaneType);
|
||||
return this.ndvStore.getMainPanelDimensions(this.currentNodePaneType as nodePanelType);
|
||||
},
|
||||
supportedResizeDirections() {
|
||||
supportedResizeDirections(): string[] {
|
||||
const supportedDirections = ['right'];
|
||||
|
||||
if(this.isDraggable) supportedDirections.push('left');
|
||||
return supportedDirections;
|
||||
},
|
||||
currentNodePaneType() {
|
||||
currentNodePaneType(): string {
|
||||
if(!this.hasInputSlot) return 'inputless';
|
||||
if(!this.isDraggable) return 'dragless';
|
||||
if(this.nodeType === null) return 'unknown';
|
||||
return get(this, 'nodeType.parameterPane') || 'regular';
|
||||
},
|
||||
hasInputSlot() {
|
||||
hasInputSlot(): boolean {
|
||||
return this.$slots.input !== undefined;
|
||||
},
|
||||
inputPanelMargin(): number {
|
||||
return this.pxToRelativeWidth(SIDE_PANELS_MARGIN);
|
||||
},
|
||||
minWindowWidth() {
|
||||
minWindowWidth(): number {
|
||||
return 2 * (SIDE_MARGIN + SIDE_PANELS_MARGIN) + MIN_PANEL_WIDTH;
|
||||
},
|
||||
minimumLeftPosition(): number {
|
||||
|
@ -196,7 +202,7 @@ export default mixins(debounceHelper).extend({
|
|||
const currentRelativeLeftDelta = this.calculatedPositions.outputPanelRelativeLeft - panelMinLeft;
|
||||
return currentRelativeLeftDelta > 0 ? currentRelativeLeftDelta : 0;
|
||||
},
|
||||
hasDoubleWidth() {
|
||||
hasDoubleWidth(): boolean {
|
||||
return get(this, 'nodeType.parameterPane') === 'wide';
|
||||
},
|
||||
fixedPanelWidth(): number {
|
||||
|
@ -244,7 +250,7 @@ export default mixins(debounceHelper).extend({
|
|||
setMainPanelWidth(relativeWidth?: number) {
|
||||
const mainPanelRelativeWidth = relativeWidth || this.pxToRelativeWidth(initialMainPanelWidth[this.currentNodePaneType]);
|
||||
|
||||
this.$store.commit('ndv/setMainPanelDimensions', {
|
||||
this.ndvStore.setMainPanelDimensions({
|
||||
panelType: this.currentNodePaneType,
|
||||
dimensions: {
|
||||
relativeWidth: mainPanelRelativeWidth,
|
||||
|
@ -260,7 +266,7 @@ export default mixins(debounceHelper).extend({
|
|||
const isInputless = this.currentNodePaneType === 'inputless';
|
||||
|
||||
if(isMinLeft) {
|
||||
this.$store.commit('ndv/setMainPanelDimensions', {
|
||||
this.ndvStore.setMainPanelDimensions({
|
||||
panelType: this.currentNodePaneType,
|
||||
dimensions: {
|
||||
relativeLeft: this.minimumLeftPosition,
|
||||
|
@ -271,18 +277,18 @@ export default mixins(debounceHelper).extend({
|
|||
}
|
||||
|
||||
if(isMaxRight) {
|
||||
this.$store.commit('ndv/setMainPanelDimensions', {
|
||||
panelType: this.currentNodePaneType,
|
||||
this.ndvStore.setMainPanelDimensions({
|
||||
panelType: this.currentNodePaneType as nodePanelType,
|
||||
dimensions: {
|
||||
relativeLeft: 1 - this.mainPanelDimensions.relativeWidth - this.maximumRightPosition,
|
||||
relativeRight: this.maximumRightPosition,
|
||||
relativeRight: this.maximumRightPosition as number,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit('ndv/setMainPanelDimensions', {
|
||||
panelType: this.currentNodePaneType,
|
||||
this.ndvStore.setMainPanelDimensions({
|
||||
panelType: this.currentNodePaneType as nodePanelType,
|
||||
dimensions: {
|
||||
relativeLeft: isInputless ? this.minimumLeftPosition : mainPanelRelativeLeft,
|
||||
relativeRight: mainPanelRelativeRight,
|
||||
|
|
|
@ -111,8 +111,13 @@ import mixins from 'vue-typed-mixins';
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { getStyleTokenValue, getTriggerNodeServiceName } from './helpers';
|
||||
import { INodeUi, XYPosition } from '@/Interface';
|
||||
import { IExecutionsSummary, INodeUi, XYPosition } from '@/Interface';
|
||||
import { debounceHelper } from './mixins/debounce';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -128,6 +133,12 @@ export default mixins(
|
|||
NodeIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
isDuplicatable(): boolean {
|
||||
if(!this.nodeType) return true;
|
||||
return this.nodeType.maxNodes === undefined || this.sameTypeNodes.length < this.nodeType.maxNodes;
|
||||
|
@ -136,7 +147,7 @@ export default mixins(
|
|||
return this.nodeType?.group.includes('schedule') === true;
|
||||
},
|
||||
nodeRunData(): ITaskData[] {
|
||||
return this.$store.getters.getWorkflowResultDataByNodeName(this.data.name);
|
||||
return this.workflowsStore.getWorkflowResultDataByNodeName(this.data?.name || '') || [];
|
||||
},
|
||||
hasIssues (): boolean {
|
||||
if (this.hasPinData) return false;
|
||||
|
@ -154,7 +165,7 @@ export default mixins(
|
|||
return workflowResultDataNode.length;
|
||||
},
|
||||
canvasOffsetPosition() {
|
||||
return this.$store.getters.getNodeViewOffsetPosition;
|
||||
return this.uiStore.nodeViewOffsetPosition;
|
||||
},
|
||||
getTriggerNodeTooltip (): string | undefined {
|
||||
if (this.nodeType !== null && this.nodeType.hasOwnProperty('eventTriggerDescription')) {
|
||||
|
@ -179,11 +190,11 @@ export default mixins(
|
|||
return !!(this.nodeType && this.nodeType.polling);
|
||||
},
|
||||
isExecuting (): boolean {
|
||||
return this.$store.getters.executingNode === this.data.name;
|
||||
return this.workflowsStore.executingNode === this.data.name;
|
||||
},
|
||||
isSingleActiveTriggerNode (): boolean {
|
||||
const nodes = this.$store.getters.workflowTriggerNodes.filter((node: INodeUi) => {
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](node.type, node.typeVersion) as INodeTypeDescription | null;
|
||||
const nodes = this.workflowsStore.workflowTriggerNodes.filter((node: INodeUi) => {
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
return nodeType && nodeType.eventTriggerDescription !== '' && !node.disabled;
|
||||
});
|
||||
|
||||
|
@ -193,7 +204,7 @@ export default mixins(
|
|||
return this.data.type === MANUAL_TRIGGER_NODE_TYPE;
|
||||
},
|
||||
isTriggerNode (): boolean {
|
||||
return this.$store.getters['nodeTypes/isTriggerNode'](this.data.type);
|
||||
return this.nodeTypesStore.isTriggerNode(this.data?.type || '');
|
||||
},
|
||||
isTriggerNodeTooltipEmpty () : boolean {
|
||||
return this.nodeType !== null ? this.nodeType.eventTriggerDescription === '' : false;
|
||||
|
@ -202,13 +213,13 @@ export default mixins(
|
|||
return this.node && this.node.disabled;
|
||||
},
|
||||
nodeType (): INodeTypeDescription | null {
|
||||
return this.data && this.$store.getters['nodeTypes/getNodeType'](this.data.type, this.data.typeVersion);
|
||||
return this.data && this.nodeTypesStore.getNodeType(this.data.type, this.data.typeVersion);
|
||||
},
|
||||
node (): INodeUi | undefined { // same as this.data but reactive..
|
||||
return this.$store.getters.nodesByName[this.name] as INodeUi | undefined;
|
||||
return this.workflowsStore.nodesByName[this.name] as INodeUi | undefined;
|
||||
},
|
||||
sameTypeNodes (): INodeUi[] {
|
||||
return this.$store.getters.allNodes.filter((node: INodeUi) => node.type === this.data.type);
|
||||
return this.workflowsStore.allNodes.filter((node: INodeUi) => node.type === this.data.type);
|
||||
},
|
||||
nodeClass (): object {
|
||||
return {
|
||||
|
@ -261,7 +272,7 @@ export default mixins(
|
|||
return this.data.name;
|
||||
},
|
||||
waiting (): string | undefined {
|
||||
const workflowExecution = this.$store.getters.getWorkflowExecution;
|
||||
const workflowExecution = this.workflowsStore.getWorkflowExecution as IExecutionsSummary;
|
||||
|
||||
if (workflowExecution && workflowExecution.waitTill) {
|
||||
const lastNodeExecuted = get(workflowExecution, 'data.resultData.lastNodeExecuted');
|
||||
|
@ -285,7 +296,7 @@ export default mixins(
|
|||
return;
|
||||
},
|
||||
workflowRunning (): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
nodeStyle (): object {
|
||||
let borderColor = getStyleTokenValue('--color-foreground-xdark');
|
||||
|
@ -312,7 +323,7 @@ export default mixins(
|
|||
return returnStyles;
|
||||
},
|
||||
isSelected (): boolean {
|
||||
return this.$store.getters.getSelectedNodes.find((node: INodeUi) => node.name === this.data.name);
|
||||
return this.uiStore.getSelectedNodes.find((node: INodeUi) => node.name === this.data.name) !== undefined;
|
||||
},
|
||||
shiftOutputCount (): boolean {
|
||||
return !!(this.nodeType && this.nodeType.outputs.length > 2);
|
||||
|
@ -408,14 +419,14 @@ export default mixins(
|
|||
},
|
||||
disableNode () {
|
||||
this.disableNodes([this.data]);
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'disable', workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'disable', workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
executeNode () {
|
||||
this.$emit('runWorkflow', this.data.name, 'Node.executeNode');
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'execute', workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'execute', workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
deleteNode () {
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'delete', workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'delete', workflow_id: this.workflowsStore.workflowId });
|
||||
|
||||
Vue.nextTick(() => {
|
||||
// Wait a tick else vue causes problems because the data is gone
|
||||
|
@ -423,7 +434,7 @@ export default mixins(
|
|||
});
|
||||
},
|
||||
duplicateNode () {
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'duplicate', workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User clicked node hover button', { node_type: this.data.type, button_name: 'duplicate', workflow_id: this.workflowsStore.workflowId });
|
||||
Vue.nextTick(() => {
|
||||
// Wait a tick else vue causes problems because the data is gone
|
||||
this.$emit('duplicateNode', this.data.name);
|
||||
|
@ -444,7 +455,7 @@ export default mixins(
|
|||
},
|
||||
|
||||
setNodeActive () {
|
||||
this.$store.commit('ndv/setActiveNodeName', this.data.name);
|
||||
this.ndvStore.activeNodeName = this.data ? this.data.name : '';
|
||||
this.pinDataDiscoveryTooltipVisible = false;
|
||||
},
|
||||
touchStart () {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
import Vue from "vue";
|
||||
import * as CanvasHelpers from "@/views/canvasHelpers";
|
||||
import {DEFAULT_STICKY_HEIGHT, DEFAULT_STICKY_WIDTH, STICKY_NODE_TYPE} from "@/constants";
|
||||
import { mapStores } from "pinia";
|
||||
import { useUIStore } from "@/stores/ui";
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'node-creation',
|
||||
|
@ -41,6 +43,9 @@ export default Vue.extend({
|
|||
showStickyButton: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
methods: {
|
||||
onCreateMenuHoverIn(mouseinEvent: MouseEvent) {
|
||||
const buttonsWrapper = mouseinEvent.target as Element;
|
||||
|
@ -73,7 +78,7 @@ export default Vue.extend({
|
|||
(document.activeElement as HTMLElement).blur();
|
||||
}
|
||||
|
||||
const offset: [number, number] = [...(this.$store.getters.getNodeViewOffsetPosition as [number, number])];
|
||||
const offset: [number, number] = [...(this.uiStore.nodeViewOffsetPosition)];
|
||||
|
||||
const position = CanvasHelpers.getMidCanvasPosition(this.nodeViewScale, offset);
|
||||
position[0] -= DEFAULT_STICKY_WIDTH / 2;
|
||||
|
|
|
@ -92,6 +92,10 @@ import { matchesNodeType, matchesSelectType } from './helpers';
|
|||
import { BaseTextKey } from '@/plugins/i18n';
|
||||
import { intersection } from '@/utils';
|
||||
import { sublimeSearch } from './sortUtils';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(externalHooks, globalLinkActions).extend({
|
||||
name: 'CategorizedItems',
|
||||
|
@ -146,6 +150,11 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
this.unregisterCustomAction('showAllNodeCreatorNodes');
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useRootStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
activeSubcategory(): INodeCreateElement | null {
|
||||
return this.activeSubcategoryHistory[this.activeSubcategoryHistory.length - 1] || null;
|
||||
},
|
||||
|
@ -156,10 +165,10 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
return this.$store.getters['nodeCreator/selectedType'];
|
||||
},
|
||||
categoriesWithNodes(): ICategoriesWithNodes {
|
||||
return this.$store.getters['nodeTypes/categoriesWithNodes'];
|
||||
return this.nodeTypesStore.categoriesWithNodes;
|
||||
},
|
||||
categorizedItems(): INodeCreateElement[] {
|
||||
return this.$store.getters['nodeTypes/categorizedItems'];
|
||||
return this.nodeTypesStore.categorizedItems;
|
||||
},
|
||||
activeSubcategoryTitle(): string {
|
||||
if(!this.activeSubcategory || !this.activeSubcategory.properties) return '';
|
||||
|
@ -178,7 +187,7 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
return this.nodeFilter.toLowerCase().trim();
|
||||
},
|
||||
defaultLocale (): string {
|
||||
return this.$store.getters.defaultLocale;
|
||||
return this.rootStore.defaultLocale;
|
||||
},
|
||||
filteredNodeTypes(): INodeCreateElement[] {
|
||||
const filter = this.searchFilter;
|
||||
|
@ -337,7 +346,7 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
newValue,
|
||||
selectedType: this.selectedType,
|
||||
filteredNodes: this.filteredNodeTypes,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -444,7 +453,7 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
);
|
||||
} else {
|
||||
this.activeCategory = [...this.activeCategory, category];
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.onCategoryExpanded', { category_name: category, workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.onCategoryExpanded', { category_name: category, workflow_id: this.workflowsStore.workflowId });
|
||||
}
|
||||
|
||||
this.activeIndex = this.categorized.findIndex(
|
||||
|
@ -456,7 +465,7 @@ export default mixins(externalHooks, globalLinkActions).extend({
|
|||
this.$store.commit('nodeCreator/setShowTabs', false);
|
||||
this.activeSubcategoryIndex = 0;
|
||||
this.activeSubcategoryHistory.push(selected);
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.onSubcategorySelected', { selected, workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.onSubcategorySelected', { selected, workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
|
||||
onSubcategoryClose() {
|
||||
|
|
|
@ -18,6 +18,8 @@ import camelcase from 'lodash.camelcase';
|
|||
import { CategoryName } from '@/plugins/i18n';
|
||||
import { INodeCreateElement, ICategoriesWithNodes } from '@/Interface';
|
||||
import { NODE_TYPE_COUNT_MAPPER } from '@/constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -27,20 +29,23 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
),
|
||||
selectedType(): "Regular" | "Trigger" | "All" {
|
||||
return this.$store.getters['nodeCreator/selectedType'];
|
||||
},
|
||||
categoriesWithNodes(): ICategoriesWithNodes {
|
||||
return this.$store.getters['nodeTypes/categoriesWithNodes'];
|
||||
return this.nodeTypesStore.categoriesWithNodes;
|
||||
},
|
||||
categorizedItems(): INodeCreateElement[] {
|
||||
return this.$store.getters['nodeTypes/categorizedItems'];
|
||||
return this.nodeTypesStore.categorizedItems;
|
||||
},
|
||||
categoryName() {
|
||||
return camelcase(this.item.category);
|
||||
},
|
||||
nodesCount(): number {
|
||||
const currentCategory = this.categoriesWithNodes[this.item.category];
|
||||
const currentCategory= (this.categoriesWithNodes as ICategoriesWithNodes)[this.item.category];
|
||||
const subcategories = Object.keys(currentCategory);
|
||||
|
||||
// We need to sum subcategories count for the curent nodeType view
|
||||
|
|
|
@ -33,6 +33,8 @@ import { ALL_NODE_FILTER, TRIGGER_NODE_FILTER, OTHER_TRIGGER_NODES_SUBCATEGORY,
|
|||
import CategorizedItems from './CategorizedItems.vue';
|
||||
import TypeSelector from './TypeSelector.vue';
|
||||
import { INodeCreateElement } from '@/Interface';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export default mixins(externalHooks).extend({
|
||||
name: 'NodeCreateList',
|
||||
|
@ -55,6 +57,9 @@ export default mixins(externalHooks).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useWorkflowsStore,
|
||||
),
|
||||
selectedType(): string {
|
||||
return this.$store.getters['nodeCreator/selectedType'];
|
||||
},
|
||||
|
@ -68,7 +73,7 @@ export default mixins(externalHooks).extend({
|
|||
this.$telemetry.trackNodesPanel('nodeCreateList.selectedTypeChanged', {
|
||||
old_filter: oldValue,
|
||||
new_filter: newValue,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -80,7 +85,7 @@ export default mixins(externalHooks).extend({
|
|||
destroyed() {
|
||||
this.$store.commit('nodeCreator/setSelectedType', ALL_NODE_FILTER);
|
||||
this.$externalHooks().run('nodeCreateList.destroyed');
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.destroyed', { workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.trackNodesPanel('nodeCreateList.destroyed', { workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<aside :class="{'node-creator-scrim': true, expanded: !sidebarMenuCollapsed, active: showScrim}" />
|
||||
<aside :class="{'node-creator-scrim': true, expanded: !uiStore.sidebarMenuCollapsed, active: showScrim}" />
|
||||
|
||||
<slide-transition>
|
||||
<div
|
||||
|
@ -29,6 +29,9 @@ import { INodeTypeDescription } from 'n8n-workflow';
|
|||
import SlideTransition from '../../transitions/SlideTransition.vue';
|
||||
|
||||
import MainPanel from './MainPanel.vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'NodeCreator',
|
||||
|
@ -42,14 +45,15 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useUIStore,
|
||||
),
|
||||
showScrim(): boolean {
|
||||
return this.$store.getters['nodeCreator/showScrim'];
|
||||
},
|
||||
sidebarMenuCollapsed(): boolean {
|
||||
return this.$store.getters['ui/sidebarMenuCollapsed'];
|
||||
},
|
||||
visibleNodeTypes(): INodeTypeDescription[] {
|
||||
return this.$store.getters['nodeTypes/visibleNodeTypes'];
|
||||
return this.nodeTypesStore.visibleNodeTypes;
|
||||
},
|
||||
searchItems(): INodeCreateElement[] {
|
||||
const sorted = [...this.visibleNodeTypes];
|
||||
|
|
|
@ -63,6 +63,7 @@ import {
|
|||
ICredentialsResponse,
|
||||
INodeUi,
|
||||
INodeUpdatePropertiesInformation,
|
||||
IUser,
|
||||
} from '@/Interface';
|
||||
import {
|
||||
ICredentialType,
|
||||
|
@ -81,6 +82,11 @@ import { mapGetters } from "vuex";
|
|||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import {getCredentialPermissions} from "@/permissions";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
genericHelpers,
|
||||
|
@ -103,11 +109,19 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('users', ['currentUser']),
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapGetters('credentials', {
|
||||
allCredentialsByType: 'allCredentialsByType',
|
||||
getCredentialTypeByName: 'getCredentialTypeByName',
|
||||
}),
|
||||
currentUser (): IUser {
|
||||
return this.usersStore.currentUser || {} as IUser;
|
||||
},
|
||||
credentialTypesNode (): string[] {
|
||||
return this.credentialTypesNodeDescription
|
||||
.map((credentialTypeDescription) => credentialTypeDescription.name);
|
||||
|
@ -125,7 +139,7 @@ export default mixins(
|
|||
|
||||
if (credType) return [credType];
|
||||
|
||||
const activeNodeType = this.$store.getters['nodeTypes/getNodeType'](node.type, node.typeVersion) as INodeTypeDescription | null;
|
||||
const activeNodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (activeNodeType && activeNodeType.credentials) {
|
||||
return activeNodeType.credentials;
|
||||
}
|
||||
|
@ -220,8 +234,8 @@ export default mixins(
|
|||
onCredentialSelected (credentialType: string, credentialId: string | null | undefined) {
|
||||
if (credentialId === this.NEW_CREDENTIALS_TEXT) {
|
||||
this.listenForNewCredentials(credentialType);
|
||||
this.$store.dispatch('ui/openNewCredential', { type: credentialType });
|
||||
this.$telemetry.track('User opened Credential modal', { credential_type: credentialType, source: 'node', new_credential: true, workflow_id: this.$store.getters.workflowId });
|
||||
this.uiStore.openNewCredential(credentialType);
|
||||
this.$telemetry.track('User opened Credential modal', { credential_type: credentialType, source: 'node', new_credential: true, workflow_id: this.workflowsStore.workflowId });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,7 +245,7 @@ export default mixins(
|
|||
credential_type: credentialType,
|
||||
node_type: this.node.type,
|
||||
...(this.hasProxyAuth(this.node) ? { is_service_specific: true } : {}),
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
credential_id: credentialId,
|
||||
},
|
||||
);
|
||||
|
@ -244,7 +258,7 @@ export default mixins(
|
|||
// if credentials has been string or neither id matched nor name matched uniquely
|
||||
if (oldCredentials.id === null || (oldCredentials.id && !this.$store.getters['credentials/getCredentialByIdAndType'](oldCredentials.id, credentialType))) {
|
||||
// update all nodes in the workflow with the same old/invalid credentials
|
||||
this.$store.commit('replaceInvalidWorkflowCredentials', {
|
||||
this.workflowsStore.replaceInvalidWorkflowCredentials({
|
||||
credentials: selected,
|
||||
invalid: oldCredentials,
|
||||
type: credentialType,
|
||||
|
@ -316,9 +330,9 @@ export default mixins(
|
|||
|
||||
editCredential(credentialType: string): void {
|
||||
const { id } = this.node.credentials[credentialType];
|
||||
this.$store.dispatch('ui/openExistingCredential', { id });
|
||||
this.uiStore.openExistingCredential(id);
|
||||
|
||||
this.$telemetry.track('User opened Credential modal', { credential_type: credentialType, source: 'node', new_credential: false, workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User opened Credential modal', { credential_type: credentialType, source: 'node', new_credential: false, workflow_id: this.workflowsStore.workflowId });
|
||||
|
||||
this.listenForNewCredentials(credentialType);
|
||||
},
|
||||
|
|
|
@ -141,6 +141,11 @@ import {
|
|||
import { workflowActivate } from './mixins/workflowActivate';
|
||||
import { pinData } from "@/components/mixins/pinData";
|
||||
import { dataPinningEventBus } from '@/event-bus/data-pinning-event-bus';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -182,8 +187,7 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$store.commit('ndv/setNDVSessionId');
|
||||
|
||||
this.ndvStore.setNDVSessionId;
|
||||
dataPinningEventBus.$on('data-pinning-discovery', ({ isTooltipVisible }: { isTooltipVisible: boolean }) => {
|
||||
this.pinDataDiscoveryTooltipVisible = isTooltipVisible;
|
||||
});
|
||||
|
@ -192,12 +196,17 @@ export default mixins(
|
|||
dataPinningEventBus.$off('data-pinning-discovery');
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['executionWaitingForWebhook']),
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
sessionId(): string {
|
||||
return this.$store.getters['ndv/ndvSessionId'];
|
||||
return this.ndvStore.sessionId;
|
||||
},
|
||||
workflowRunning(): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
showTriggerWaitingWarning(): boolean {
|
||||
return (
|
||||
|
@ -205,25 +214,25 @@ export default mixins(
|
|||
!!this.activeNodeType &&
|
||||
!this.activeNodeType.group.includes('trigger') &&
|
||||
this.workflowRunning &&
|
||||
this.executionWaitingForWebhook
|
||||
this.workflowsStore.executionWaitingForWebhook
|
||||
);
|
||||
},
|
||||
activeNode(): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
inputNodeName(): string | undefined {
|
||||
return this.selectedInput || this.parentNode;
|
||||
},
|
||||
inputNode(): INodeUi | null {
|
||||
if (this.inputNodeName) {
|
||||
return this.$store.getters.getNodeByName(this.inputNodeName);
|
||||
return this.workflowsStore.getNodeByName(this.inputNodeName);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
activeNodeType(): INodeTypeDescription | null {
|
||||
if (this.activeNode) {
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.activeNode.type, this.activeNode.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.activeNode.type, this.activeNode.typeVersion);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
@ -257,11 +266,11 @@ export default mixins(
|
|||
},
|
||||
isActiveStickyNode(): boolean {
|
||||
return (
|
||||
!!this.$store.getters['ndv/activeNode'] && this.$store.getters['ndv/activeNode'].type === STICKY_NODE_TYPE
|
||||
!!this.ndvStore.activeNode && this.ndvStore.activeNode .type === STICKY_NODE_TYPE
|
||||
);
|
||||
},
|
||||
workflowExecution(): IExecutionResponse | null {
|
||||
return this.$store.getters.getWorkflowExecution;
|
||||
return this.workflowsStore.getWorkflowExecution;
|
||||
},
|
||||
workflowRunData(): IRunData | null {
|
||||
if (this.workflowExecution === null) {
|
||||
|
@ -340,13 +349,13 @@ export default mixins(
|
|||
return `${BASE_NODE_SURVEY_URL}${this.activeNodeType.name}`;
|
||||
},
|
||||
outputPanelEditMode(): { enabled: boolean; value: string; } {
|
||||
return this.$store.getters['ndv/outputPanelEditMode'];
|
||||
return this.ndvStore.outputPanelEditMode;
|
||||
},
|
||||
isWorkflowRunning(): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
isExecutionWaitingForWebhook(): boolean {
|
||||
return this.$store.getters.executionWaitingForWebhook;
|
||||
return this.workflowsStore.executionWaitingForWebhook;
|
||||
},
|
||||
blockUi(): boolean {
|
||||
return this.isWorkflowRunning || this.isExecutionWaitingForWebhook;
|
||||
|
@ -364,7 +373,7 @@ export default mixins(
|
|||
this.avgInputRowHeight = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
this.$store.commit('ndv/setNDVSessionId');
|
||||
this.ndvStore.setNDVSessionId;
|
||||
}, 0);
|
||||
this.$externalHooks().run('dataDisplay.nodeTypeChanged', {
|
||||
nodeSubtitle: this.getNodeSubtitle(node, this.activeNodeType, this.getCurrentWorkflow()),
|
||||
|
@ -374,24 +383,24 @@ export default mixins(
|
|||
|
||||
setTimeout(() => {
|
||||
if (this.activeNode) {
|
||||
const outogingConnections = this.$store.getters.outgoingConnectionsByNodeName(
|
||||
const outgoingConnections = this.workflowsStore.outgoingConnectionsByNodeName(
|
||||
this.activeNode.name,
|
||||
) as INodeConnections;
|
||||
|
||||
this.$telemetry.track('User opened node modal', {
|
||||
node_type: this.activeNodeType ? this.activeNodeType.name : '',
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
parameters_pane_position: this.mainPanelPosition,
|
||||
input_first_connector_runs: this.maxInputRun,
|
||||
output_first_connector_runs: this.maxOutputRun,
|
||||
selected_view_inputs: this.isTriggerNode
|
||||
? 'trigger'
|
||||
: this.$store.getters['ndv/inputPanelDisplayMode'],
|
||||
selected_view_outputs: this.$store.getters['ndv/outputPanelDisplayMode'],
|
||||
: this.ndvStore.inputPanelDisplayMode,
|
||||
selected_view_outputs: this.ndvStore.outputPanelDisplayMode,
|
||||
input_connectors: this.parentNodes.length,
|
||||
output_connectors:
|
||||
outogingConnections && outogingConnections.main && outogingConnections.main.length,
|
||||
outgoingConnections && outgoingConnections.main && outgoingConnections.main.length,
|
||||
input_displayed_run_index: this.inputRun,
|
||||
output_displayed_run_index: this.outputRun,
|
||||
data_pinning_tooltip_presented: this.pinDataDiscoveryTooltipVisible,
|
||||
|
@ -413,12 +422,12 @@ export default mixins(
|
|||
},
|
||||
inputNodeName(nodeName: string | undefined) {
|
||||
setTimeout(() => {
|
||||
this.$store.commit('ndv/setInputNodeName', nodeName);
|
||||
this.ndvStore.setInputNodeName(nodeName);
|
||||
}, 0);
|
||||
},
|
||||
inputRun() {
|
||||
setTimeout(() => {
|
||||
this.$store.commit('ndv/setInputRunIndex', this.inputRun);
|
||||
this.ndvStore.setInputRunIndex(this.inputRun);
|
||||
}, 0);
|
||||
},
|
||||
},
|
||||
|
@ -428,7 +437,7 @@ export default mixins(
|
|||
return;
|
||||
}
|
||||
if (e === null) {
|
||||
this.$store.commit('ndv/setHoveringItem', null);
|
||||
this.ndvStore.setHoveringItem(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -438,11 +447,11 @@ export default mixins(
|
|||
outputIndex: e.outputIndex,
|
||||
itemIndex: e.itemIndex,
|
||||
};
|
||||
this.$store.commit('ndv/setHoveringItem', item);
|
||||
this.ndvStore.setHoveringItem(item);
|
||||
},
|
||||
onOutputItemHover(e: {itemIndex: number, outputIndex: number} | null) {
|
||||
if (e === null || !this.activeNode) {
|
||||
this.$store.commit('ndv/setHoveringItem', null);
|
||||
this.ndvStore.setHoveringItem(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -452,7 +461,7 @@ export default mixins(
|
|||
outputIndex: e.outputIndex,
|
||||
itemIndex: e.itemIndex,
|
||||
};
|
||||
this.$store.commit('ndv/setHoveringItem', item);
|
||||
this.ndvStore.setHoveringItem(item);
|
||||
},
|
||||
onInputTableMounted(e: { avgRowHeight: number }) {
|
||||
this.avgInputRowHeight = e.avgRowHeight;
|
||||
|
@ -461,7 +470,7 @@ export default mixins(
|
|||
this.avgOutputRowHeight = e.avgRowHeight;
|
||||
},
|
||||
onWorkflowActivate() {
|
||||
this.$store.commit('ndv/setActiveNodeName', null);
|
||||
this.ndvStore.activeNodeName = null;
|
||||
setTimeout(() => {
|
||||
this.activateCurrentWorkflow('ndv');
|
||||
}, 1000);
|
||||
|
@ -471,7 +480,7 @@ export default mixins(
|
|||
if (this.activeNode) {
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'main',
|
||||
type: 'i-wish-this-node-would',
|
||||
|
@ -493,7 +502,7 @@ export default mixins(
|
|||
end_position: e.position,
|
||||
node_type: this.activeNodeType ? this.activeNodeType.name : '',
|
||||
session_id: this.sessionId,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
this.mainPanelPosition = e.position;
|
||||
},
|
||||
|
@ -567,21 +576,23 @@ export default mixins(
|
|||
return;
|
||||
}
|
||||
|
||||
this.$store.commit('pinData', { node: this.activeNode, data: jsonParse(value) });
|
||||
if (this.activeNode) {
|
||||
this.workflowsStore.pinData({ node: this.activeNode, data: jsonParse(value) });
|
||||
}
|
||||
}
|
||||
|
||||
this.$store.commit('ndv/setOutputPanelEditModeEnabled', false);
|
||||
this.ndvStore.setOutputPanelEditModeEnabled(false);
|
||||
}
|
||||
|
||||
this.$externalHooks().run('dataDisplay.nodeEditingFinished');
|
||||
this.$telemetry.track('User closed node modal', {
|
||||
node_type: this.activeNodeType ? this.activeNodeType.name : '',
|
||||
session_id: this.sessionId,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
this.triggerWaitingWarningEnabled = false;
|
||||
this.$store.commit('ndv/setActiveNodeName', null);
|
||||
this.$store.commit('ndv/resetNDVSessionId');
|
||||
this.ndvStore.activeNodeName = null;
|
||||
this.ndvStore.resetNDVSessionId();
|
||||
},
|
||||
onRunOutputIndexChange(run: number) {
|
||||
this.runOutputIndex = run;
|
||||
|
@ -610,7 +621,7 @@ export default mixins(
|
|||
this.$telemetry.track('User changed ndv input dropdown', {
|
||||
node_type: this.activeNode ? this.activeNode.type : '',
|
||||
session_id: this.sessionId,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
selection_value: index,
|
||||
input_node_type: this.inputNode ? this.inputNode.type : '',
|
||||
});
|
||||
|
|
|
@ -23,6 +23,10 @@ import mixins from 'vue-typed-mixins';
|
|||
import { workflowRun } from './mixins/workflowRun';
|
||||
import { pinData } from './mixins/pinData';
|
||||
import { dataPinningEventBus } from '@/event-bus/data-pinning-event-bus';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
workflowRun,
|
||||
|
@ -54,25 +58,30 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
node (): INodeUi {
|
||||
return this.$store.getters.getNodeByName(this.nodeName);
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
node (): INodeUi | null {
|
||||
return this.workflowsStore.getNodeByName(this.nodeName);
|
||||
},
|
||||
nodeType (): INodeTypeDescription | null {
|
||||
if (this.node) {
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.node.type, this.node.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
nodeRunning (): boolean {
|
||||
const triggeredNode = this.$store.getters.executedNode;
|
||||
const executingNode = this.$store.getters.executingNode;
|
||||
const triggeredNode = this.workflowsStore.executedNode;
|
||||
const executingNode = this.workflowsStore.executingNode;
|
||||
return this.workflowRunning && (executingNode === this.node.name || triggeredNode === this.node.name);
|
||||
},
|
||||
workflowRunning (): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
isTriggerNode (): boolean {
|
||||
return this.$store.getters['nodeTypes/isTriggerNode'](this.node.type);
|
||||
return this.nodeTypesStore.isTriggerNode(this.node.type);
|
||||
},
|
||||
isManualTriggerNode (): boolean {
|
||||
return Boolean(this.nodeType && this.nodeType.name === MANUAL_TRIGGER_NODE_TYPE);
|
||||
|
@ -87,8 +96,8 @@ export default mixins(
|
|||
return Boolean(this.nodeType && this.nodeType.name === WEBHOOK_NODE_TYPE);
|
||||
},
|
||||
isListeningForEvents(): boolean {
|
||||
const waitingOnWebhook = this.$store.getters.executionWaitingForWebhook as boolean;
|
||||
const executedNode = this.$store.getters.executedNode as string | undefined;
|
||||
const waitingOnWebhook = this.workflowsStore.executionWaitingForWebhook;
|
||||
const executedNode = this.workflowsStore.executedNode;
|
||||
|
||||
return (
|
||||
this.node &&
|
||||
|
@ -114,7 +123,8 @@ export default mixins(
|
|||
}
|
||||
|
||||
if (this.isTriggerNode && this.hasIssues) {
|
||||
if (this.$store.getters['ndv/activeNode'] && this.$store.getters['ndv/activeNode'].name !== this.nodeName) {
|
||||
const activeNode = this.ndvStore.activeNode;
|
||||
if (activeNode && activeNode.name !== this.nodeName) {
|
||||
return this.$locale.baseText('ndv.execute.fixPrevious');
|
||||
}
|
||||
|
||||
|
@ -154,7 +164,7 @@ export default mixins(
|
|||
methods: {
|
||||
async stopWaitingForWebhook () {
|
||||
try {
|
||||
await this.restApi().removeTestWebhook(this.$store.getters.workflowId);
|
||||
await this.restApi().removeTestWebhook(this.workflowsStore.workflowId);
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
|
@ -182,14 +192,14 @@ export default mixins(
|
|||
|
||||
if (shouldUnpinAndExecute) {
|
||||
dataPinningEventBus.$emit('data-unpinning', { source: 'unpin-and-execute-modal' });
|
||||
this.$store.commit('unpinData', { node: this.node });
|
||||
this.workflowsStore.unpinData({ node: this.node });
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.hasPinData || shouldUnpinAndExecute) {
|
||||
const telemetryPayload = {
|
||||
node_type: this.nodeType ? this.nodeType.name : null,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
source: this.telemetrySource,
|
||||
};
|
||||
this.$telemetry.track('User clicked execute node button', telemetryPayload);
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { IVersionNode } from '@/Interface';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
interface NodeIconSource {
|
||||
|
@ -47,6 +49,9 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
type (): string {
|
||||
const nodeType = this.nodeType as INodeTypeDescription | IVersionNode | null;
|
||||
let iconType = 'unknown';
|
||||
|
@ -68,7 +73,7 @@ export default Vue.extend({
|
|||
},
|
||||
iconSource () : NodeIconSource {
|
||||
const nodeType = this.nodeType as INodeTypeDescription | IVersionNode | null;
|
||||
const restUrl = this.$store.getters.getRestUrl;
|
||||
const restUrl = this.rootStore.getRestUrl;
|
||||
const iconSource = {} as NodeIconSource;
|
||||
|
||||
if (nodeType) {
|
||||
|
|
|
@ -152,6 +152,11 @@ import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
|||
import mixins from 'vue-typed-mixins';
|
||||
import NodeExecuteButton from './NodeExecuteButton.vue';
|
||||
import { isCommunityPackageName } from './helpers';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(externalHooks, nodeHelpers).extend({
|
||||
name: 'NodeSettings',
|
||||
|
@ -165,8 +170,14 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
NodeExecuteButton,
|
||||
},
|
||||
computed: {
|
||||
isCurlImportModalOpen() {
|
||||
return this.$store.getters['ui/isModalOpen'](IMPORT_CURL_MODAL_KEY);
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
isCurlImportModalOpen(): boolean {
|
||||
return this.uiStore.isModalOpen(IMPORT_CURL_MODAL_KEY);
|
||||
},
|
||||
nodeTypeName(): string {
|
||||
if (this.nodeType) {
|
||||
|
@ -201,8 +212,8 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
'background-color': this.node.color,
|
||||
};
|
||||
},
|
||||
node(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
node(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
parametersSetting(): INodeProperties[] {
|
||||
return this.parameters.filter((item) => {
|
||||
|
@ -222,13 +233,13 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
return this.nodeType.properties;
|
||||
},
|
||||
outputPanelEditMode(): { enabled: boolean; value: string } {
|
||||
return this.$store.getters['ndv/outputPanelEditMode'];
|
||||
return this.ndvStore.outputPanelEditMode;
|
||||
},
|
||||
isCommunityNode(): boolean {
|
||||
return isCommunityPackageName(this.node.type);
|
||||
},
|
||||
isTriggerNode(): boolean {
|
||||
return this.$store.getters['nodeTypes/isTriggerNode'](this.node.type);
|
||||
return this.nodeTypesStore.isTriggerNode(this.node.type);
|
||||
},
|
||||
},
|
||||
props: {
|
||||
|
@ -366,7 +377,7 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
},
|
||||
isCurlImportModalOpen(newValue, oldValue) {
|
||||
if (newValue === false) {
|
||||
let parameters = this.$store.getters['ui/getHttpNodeParameters'];
|
||||
let parameters = this.uiStore.getHttpNodeParameters || '';
|
||||
|
||||
if (!parameters) return;
|
||||
|
||||
|
@ -382,7 +393,7 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
value: parameters,
|
||||
});
|
||||
|
||||
this.$store.dispatch('ui/setHttpNodeParameters', { parameters: '' });
|
||||
this.uiStore.setHttpNodeParameters({ name: IMPORT_CURL_MODAL_KEY, parameters: '' });
|
||||
} catch (_) {}
|
||||
}
|
||||
},
|
||||
|
@ -452,12 +463,14 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
},
|
||||
credentialSelected(updateInformation: INodeUpdatePropertiesInformation) {
|
||||
// Update the values on the node
|
||||
this.$store.commit('updateNodeProperties', updateInformation);
|
||||
this.workflowsStore.updateNodeProperties(updateInformation);
|
||||
|
||||
const node = this.$store.getters.getNodeByName(updateInformation.name);
|
||||
const node = this.workflowsStore.getNodeByName(updateInformation.name);
|
||||
|
||||
// Update the issues
|
||||
this.updateNodeCredentialIssues(node);
|
||||
if (node) {
|
||||
// Update the issues
|
||||
this.updateNodeCredentialIssues(node);
|
||||
}
|
||||
|
||||
this.$externalHooks().run('nodeSettings.credentialSelected', { updateInformation });
|
||||
},
|
||||
|
@ -481,7 +494,12 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
// Save the node name before we commit the change because
|
||||
// we need the old name to rename the node properly
|
||||
const nodeNameBefore = parameterData.node || this.node.name;
|
||||
const node = this.$store.getters.getNodeByName(nodeNameBefore);
|
||||
const node = this.workflowsStore.getNodeByName(nodeNameBefore);
|
||||
|
||||
if (node === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parameterData.name === 'name') {
|
||||
// Name of node changed so we have to set also the new node name as active
|
||||
|
||||
|
@ -494,10 +512,7 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
this.$emit('valueChanged', sendData);
|
||||
} else if (parameterData.name === 'parameters') {
|
||||
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](
|
||||
node.type,
|
||||
node.typeVersion,
|
||||
) as INodeTypeDescription | null;
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (!nodeType) {
|
||||
return;
|
||||
}
|
||||
|
@ -573,23 +588,21 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
}
|
||||
}
|
||||
|
||||
// Update the data in vuex
|
||||
const updateInformation = {
|
||||
name: node.name,
|
||||
value: nodeParameters,
|
||||
};
|
||||
if (nodeParameters) {
|
||||
const updateInformation: IUpdateInformation = {
|
||||
name: node.name,
|
||||
value: nodeParameters,
|
||||
};
|
||||
|
||||
this.$store.commit('setNodeParameters', updateInformation);
|
||||
this.workflowsStore.setNodeParameters(updateInformation);
|
||||
|
||||
this.updateNodeParameterIssues(node, nodeType);
|
||||
this.updateNodeCredentialIssues(node);
|
||||
this.updateNodeParameterIssues(node, nodeType);
|
||||
this.updateNodeCredentialIssues(node);
|
||||
}
|
||||
} else if (parameterData.name.startsWith('parameters.')) {
|
||||
// A node parameter changed
|
||||
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](
|
||||
node.type,
|
||||
node.typeVersion,
|
||||
) as INodeTypeDescription | null;
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (!nodeType) {
|
||||
return;
|
||||
}
|
||||
|
@ -657,7 +670,7 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
value: nodeParameters,
|
||||
};
|
||||
|
||||
this.$store.commit('setNodeParameters', updateInformation);
|
||||
this.workflowsStore.setNodeParameters(updateInformation);
|
||||
|
||||
this.$externalHooks().run('nodeSettings.valueChanged', {
|
||||
parameterPath,
|
||||
|
@ -680,7 +693,8 @@ export default mixins(externalHooks, nodeHelpers).extend({
|
|||
key: parameterData.name,
|
||||
value: newValue,
|
||||
};
|
||||
this.$store.commit('setNodeValue', updateInformation);
|
||||
|
||||
this.workflowsStore.setNodeValue(updateInformation);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
import { externalHooks } from '@/components/mixins/externalHooks';
|
||||
import { BUILTIN_NODES_DOCS_URL, COMMUNITY_NODES_INSTALLATION_DOCS_URL, NPM_PACKAGE_DOCS_BASE_URL } from '@/constants';
|
||||
import { INodeUi, ITab } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { isCommunityPackageName } from './helpers';
|
||||
|
@ -26,8 +29,12 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
activeNode(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
activeNode(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
documentationUrl (): string {
|
||||
const nodeType = this.nodeType as INodeTypeDescription | null;
|
||||
|
@ -113,7 +120,7 @@ export default mixins(
|
|||
this.$externalHooks().run('dataDisplay.onDocumentationUrlClick', { nodeType: this.nodeType as INodeTypeDescription, documentationUrl: this.documentationUrl });
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'main',
|
||||
type: 'docs',
|
||||
|
@ -121,7 +128,7 @@ export default mixins(
|
|||
}
|
||||
|
||||
if(tab === 'settings' && this.nodeType) {
|
||||
this.$telemetry.track('User viewed node settings', { node_type: (this.nodeType as INodeTypeDescription).name, workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User viewed node settings', { node_type: (this.nodeType as INodeTypeDescription).name, workflow_id: this.workflowsStore.workflowId });
|
||||
}
|
||||
|
||||
if (tab === 'settings' || tab === 'params') {
|
||||
|
|
|
@ -55,6 +55,8 @@ import Modal from './Modal.vue';
|
|||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { showMessage } from './mixins/showMessage';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -75,6 +77,7 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
isEmailValid(): boolean {
|
||||
return VALID_EMAIL_REGEX.test(String(this.email).toLowerCase());
|
||||
},
|
||||
|
@ -90,7 +93,7 @@ export default mixins(
|
|||
this.okToClose = false;
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('ui/applyForOnboardingCall', { email: this.email });
|
||||
await this.uiStore.applyForOnboardingCall(this.email);
|
||||
this.$showMessage({
|
||||
type: 'success',
|
||||
title: this.$locale.baseText('onboardingCallSignupSucess.title'),
|
||||
|
|
|
@ -86,6 +86,11 @@ import RunData, { EnterEditModeArgs } from './RunData.vue';
|
|||
import RunInfo from './RunInfo.vue';
|
||||
import { pinData } from "@/components/mixins/pinData";
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
type RunDataRef = Vue & { enterEditMode: (args: EnterEditModeArgs) => void };
|
||||
|
||||
|
@ -116,17 +121,23 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
node(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
node(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
nodeType (): INodeTypeDescription | null {
|
||||
if (this.node) {
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.node.type, this.node.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
isTriggerNode (): boolean {
|
||||
return this.$store.getters['nodeTypes/isTriggerNode'](this.node.type);
|
||||
return this.nodeTypesStore.isTriggerNode(this.node.type);
|
||||
},
|
||||
isPollingTypeNode (): boolean {
|
||||
return !!(this.nodeType && this.nodeType.polling);
|
||||
|
@ -135,14 +146,14 @@ export default mixins(
|
|||
return !!(this.nodeType && this.nodeType.group.includes('schedule'));
|
||||
},
|
||||
isNodeRunning(): boolean {
|
||||
const executingNode = this.$store.getters.executingNode;
|
||||
const executingNode = this.workflowsStore.executingNode;
|
||||
return this.node && executingNode === this.node.name;
|
||||
},
|
||||
workflowRunning (): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
workflowExecution(): IExecutionResponse | null {
|
||||
return this.$store.getters.getWorkflowExecution;
|
||||
return this.workflowsStore.getWorkflowExecution;
|
||||
},
|
||||
workflowRunData(): IRunData | null {
|
||||
if (this.workflowExecution === null) {
|
||||
|
@ -155,7 +166,7 @@ export default mixins(
|
|||
return executionData.resultData.runData;
|
||||
},
|
||||
hasNodeRun(): boolean {
|
||||
if (this.$store.getters.subworkflowExecutionError) return true;
|
||||
if (this.workflowsStore.subWorkflowExecutionError) return true;
|
||||
|
||||
return Boolean(
|
||||
this.node && this.workflowRunData && this.workflowRunData.hasOwnProperty(this.node.name),
|
||||
|
@ -199,7 +210,7 @@ export default mixins(
|
|||
if (!this.node) {
|
||||
return false;
|
||||
}
|
||||
const updatedAt = this.$store.getters.getParametersLastUpdated(this.node.name);
|
||||
const updatedAt = this.workflowsStore.getParametersLastUpdate(this.node.name);
|
||||
if (!updatedAt || !this.runTaskData) {
|
||||
return false;
|
||||
}
|
||||
|
@ -207,7 +218,7 @@ export default mixins(
|
|||
return updatedAt > runAt;
|
||||
},
|
||||
outputPanelEditMode(): { enabled: boolean; value: string; } {
|
||||
return this.$store.getters['ndv/outputPanelEditMode'];
|
||||
return this.ndvStore.outputPanelEditMode;
|
||||
},
|
||||
canPinData(): boolean {
|
||||
return this.isPinDataNodeType && !this.isReadOnly;
|
||||
|
@ -221,7 +232,7 @@ export default mixins(
|
|||
});
|
||||
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
node_type: this.node.type,
|
||||
pane: 'output',
|
||||
|
@ -239,7 +250,7 @@ export default mixins(
|
|||
this.$emit('openSettings');
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
node_type: this.node.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'output',
|
||||
type: 'settings',
|
||||
|
|
|
@ -339,6 +339,10 @@ import { mapGetters } from 'vuex';
|
|||
import { CODE_NODE_TYPE } from '@/constants';
|
||||
import { PropType } from 'vue';
|
||||
import { debounceHelper } from './mixins/debounce';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -472,6 +476,11 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapGetters('credentials', ['allCredentialTypes']),
|
||||
expressionDisplayValue(): string {
|
||||
if (this.activeDrop || this.forceShowExpression) {
|
||||
|
@ -499,7 +508,7 @@ export default mixins(
|
|||
}
|
||||
|
||||
// Get the resolved parameter values of the current node
|
||||
const currentNodeParameters = this.$store.getters['ndv/activeNode'].parameters;
|
||||
const currentNodeParameters = this.ndvStore.activeNode?.parameters;
|
||||
try {
|
||||
const resolvedNodeParameters = this.resolveParameter(currentNodeParameters);
|
||||
|
||||
|
@ -514,7 +523,7 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
node (): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
displayTitle (): string {
|
||||
const interpolation = { interpolate: { shortPath: this.shortPath } };
|
||||
|
@ -742,12 +751,14 @@ export default mixins(
|
|||
},
|
||||
credentialSelected (updateInformation: INodeUpdatePropertiesInformation) {
|
||||
// Update the values on the node
|
||||
this.$store.commit('updateNodeProperties', updateInformation);
|
||||
this.workflowsStore.updateNodeProperties(updateInformation);
|
||||
|
||||
const node = this.$store.getters.getNodeByName(updateInformation.name);
|
||||
const node = this.workflowsStore.getNodeByName(updateInformation.name);
|
||||
|
||||
// Update the issues
|
||||
this.updateNodeCredentialIssues(node);
|
||||
if (node) {
|
||||
// Update the issues
|
||||
this.updateNodeCredentialIssues(node);
|
||||
}
|
||||
|
||||
this.$externalHooks().run('nodeSettings.credentialSelected', { updateInformation });
|
||||
},
|
||||
|
@ -784,12 +795,12 @@ export default mixins(
|
|||
// Get the resolved parameter values of the current node
|
||||
|
||||
try {
|
||||
const currentNodeParameters = (this.$store.getters['ndv/activeNode'] as INodeUi).parameters;
|
||||
const currentNodeParameters = (this.ndvStore.activeNode as INodeUi).parameters;
|
||||
const resolvedNodeParameters = this.resolveParameter(currentNodeParameters) as INodeParameters;
|
||||
const loadOptionsMethod = this.getArgument('loadOptionsMethod') as string | undefined;
|
||||
const loadOptions = this.getArgument('loadOptions') as ILoadOptions | undefined;
|
||||
|
||||
const options = await this.$store.dispatch('nodeTypes/getNodeParameterOptions',
|
||||
const options = await this.nodeTypesStore.getNodeParameterOptions(
|
||||
{
|
||||
nodeTypeAndVersion: {
|
||||
name: this.node.type,
|
||||
|
@ -827,8 +838,8 @@ export default mixins(
|
|||
parameter_name: this.parameter.displayName,
|
||||
parameter_field_type: this.parameter.type,
|
||||
new_expression: !this.isValueExpression,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
session_id: this.$store.getters['ndv/ndvSessionId'],
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.ndvStore.sessionId,
|
||||
source: this.eventSource || 'ndv',
|
||||
});
|
||||
}
|
||||
|
@ -956,11 +967,11 @@ export default mixins(
|
|||
|
||||
if (this.parameter.name === 'operation' || this.parameter.name === 'mode') {
|
||||
this.$telemetry.track('User set node operation or mode', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
node_type: this.node && this.node.type,
|
||||
resource: this.node && this.node.parameters.resource,
|
||||
is_custom: value === CUSTOM_API_CALL_KEY,
|
||||
session_id: this.$store.getters['ndv/ndvSessionId'],
|
||||
session_id: this.ndvStore.sessionId,
|
||||
parameter: this.parameter.name,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ import Vue, { PropType } from 'vue';
|
|||
import ParameterInputWrapper from './ParameterInputWrapper.vue';
|
||||
import { isValueExpression } from './helpers';
|
||||
import { INodeParameterResourceLocator, INodeProperties } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'parameter-input-expanded',
|
||||
|
@ -85,6 +87,9 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useWorkflowsStore,
|
||||
),
|
||||
showRequiredErrors(): boolean {
|
||||
if (!this.$props.parameter.required) {
|
||||
return false;
|
||||
|
@ -136,7 +141,7 @@ export default Vue.extend({
|
|||
this.$telemetry.track('User clicked credential modal docs link', {
|
||||
docs_link: this.documentationUrl,
|
||||
source: 'field',
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
@ -79,6 +79,8 @@ import { hasOnlyListMode } from '@/components/ResourceLocator/helpers';
|
|||
import { INodeParameters, INodeProperties, INodePropertyMode } from 'n8n-workflow';
|
||||
import { isResourceLocatorValue } from '@/typeGuards';
|
||||
import { BaseTextKey } from "@/plugins/i18n";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -135,8 +137,11 @@ export default mixins(
|
|||
];
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
node (): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
hint (): string | null {
|
||||
return this.$locale.nodeText().hint(this.parameter, this.path);
|
||||
|
@ -154,10 +159,10 @@ export default mixins(
|
|||
return this.isResourceLocator ? !hasOnlyListMode(this.parameter): true;
|
||||
},
|
||||
isInputDataEmpty (): boolean {
|
||||
return this.$store.getters['ndv/getNDVDataIsEmpty']('input');
|
||||
return this.ndvStore.isDNVDataEmpty('input');
|
||||
},
|
||||
displayMode(): IRunDataDisplayMode {
|
||||
return this.$store.getters['ndv/inputPanelDisplayMode'];
|
||||
return this.ndvStore.inputPanelDisplayMode;
|
||||
},
|
||||
showMappingTooltip (): boolean {
|
||||
return this.focused && this.isInputTypeString && !this.isInputDataEmpty && window.localStorage.getItem(LOCAL_STORAGE_MAPPING_FLAG) !== 'true';
|
||||
|
@ -167,13 +172,13 @@ export default mixins(
|
|||
onFocus() {
|
||||
this.focused = true;
|
||||
if (!this.parameter.noDataExpression) {
|
||||
this.$store.commit('ndv/setMappableNDVInputFocus', this.parameter.displayName);
|
||||
this.ndvStore.setMappableNDVInputFocus(this.parameter.displayName);
|
||||
}
|
||||
},
|
||||
onBlur() {
|
||||
this.focused = false;
|
||||
if (!this.parameter.noDataExpression) {
|
||||
this.$store.commit('ndv/setMappableNDVInputFocus', '');
|
||||
this.ndvStore.setMappableNDVInputFocus('');
|
||||
}
|
||||
},
|
||||
onMenuExpanded(expanded: boolean) {
|
||||
|
@ -250,7 +255,7 @@ export default mixins(
|
|||
window.localStorage.setItem(LOCAL_STORAGE_MAPPING_FLAG, 'true');
|
||||
}
|
||||
|
||||
this.$store.commit('ndv/setMappingTelemetry', {
|
||||
this.ndvStore.setMappingTelemetry({
|
||||
dest_node_type: this.node.type,
|
||||
dest_parameter: this.path,
|
||||
dest_parameter_mode: typeof prevValue === 'string' && prevValue.startsWith('=')? 'expression': 'fixed',
|
||||
|
|
|
@ -119,6 +119,9 @@ import { get, set } from 'lodash';
|
|||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import {Component} from "vue";
|
||||
import { mapState, mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(
|
||||
workflowHelpers,
|
||||
|
@ -141,6 +144,10 @@ export default mixins(
|
|||
'isReadOnly',
|
||||
],
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
),
|
||||
nodeTypeVersion(): number | null {
|
||||
if (this.node) {
|
||||
return this.node.typeVersion;
|
||||
|
@ -159,8 +166,8 @@ export default mixins(
|
|||
filteredParameterNames (): string[] {
|
||||
return this.filteredParameters.map(parameter => parameter.name);
|
||||
},
|
||||
node (): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
node (): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
indexToShowSlotAt (): number {
|
||||
let index = 0;
|
||||
|
@ -179,7 +186,7 @@ export default mixins(
|
|||
methods: {
|
||||
getCredentialsDependencies() {
|
||||
const dependencies = new Set();
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](this.node.type, this.node.typeVersion) as INodeTypeDescription | undefined;
|
||||
const nodeType = this.nodeTypesStore.getNodeType(this.node?.type || '', this.node?.typeVersion);
|
||||
|
||||
// Get names of all fields that credentials rendering depends on (using displayOptions > show)
|
||||
if(nodeType && nodeType.credentials) {
|
||||
|
@ -323,7 +330,7 @@ export default mixins(
|
|||
if (!newValue.includes(parameter)) {
|
||||
const parameterData = {
|
||||
name: `${this.path}.${parameter}`,
|
||||
node: this.$store.getters['ndv/activeNode'].name,
|
||||
node: this.ndvStore.activeNode?.name || '',
|
||||
value: undefined,
|
||||
};
|
||||
this.$emit('valueChanged', parameterData);
|
||||
|
|
|
@ -37,6 +37,8 @@ import { INodeProperties, INodePropertyMode, IRunData, isResourceLocatorValue, N
|
|||
import { INodeUi, IUiState, IUpdateInformation, TargetItem } from '@/Interface';
|
||||
import { workflowHelpers } from './mixins/workflowHelpers';
|
||||
import { isValueExpression } from './helpers';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
export default mixins(
|
||||
showMessage,
|
||||
|
@ -97,11 +99,14 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
isValueExpression () {
|
||||
return isValueExpression(this.parameter, this.value);
|
||||
},
|
||||
activeNode(): INodeUi | null {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
selectedRLMode(): INodePropertyMode | undefined {
|
||||
if (typeof this.value !== 'object' ||this.parameter.type !== 'resourceLocator' || !isResourceLocatorValue(this.value)) {
|
||||
|
@ -126,17 +131,17 @@ export default mixins(
|
|||
return this.hint;
|
||||
},
|
||||
targetItem(): TargetItem | null {
|
||||
return this.$store.getters['ndv/hoveringItem'];
|
||||
return this.ndvStore.hoveringItem;
|
||||
},
|
||||
expressionValueComputed (): string | null {
|
||||
const inputNodeName: string | undefined = this.$store.getters['ndv/ndvInputNodeName'];
|
||||
const inputNodeName: string | undefined = this.ndvStore.ndvInputNodeName;
|
||||
const value = isResourceLocatorValue(this.value)? this.value.value: this.value;
|
||||
if (this.activeNode === null || !this.isValueExpression || typeof value !== 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const inputRunIndex: number | undefined = this.$store.getters['ndv/ndvInputRunIndex'];
|
||||
const inputBranchIndex: number | undefined = this.$store.getters['ndv/ndvInputBranchIndex'];
|
||||
const inputRunIndex: number | undefined = this.ndvStore.ndvInputRunIndex;
|
||||
const inputBranchIndex: number | undefined = this.ndvStore.ndvInputBranchIndex;
|
||||
|
||||
let computedValue: NodeParameterValue;
|
||||
try {
|
||||
|
@ -157,7 +162,7 @@ export default mixins(
|
|||
},
|
||||
expressionOutput(): string | null {
|
||||
if (this.isValueExpression && this.expressionValueComputed) {
|
||||
const inputData = this.$store.getters['ndv/ndvInputData'];
|
||||
const inputData = this.ndvStore.ndvInputData;
|
||||
if (!inputData || (inputData && inputData.length <= 1)) {
|
||||
return this.expressionValueComputed;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
>
|
||||
<template v-slot:content>
|
||||
<div v-if="submitted" :class="$style.submittedContainer">
|
||||
<img :class="$style.demoImage" :src="baseUrl + 'suggestednodes.png'" />
|
||||
<img :class="$style.demoImage" :src="rootStore.baseUrl + 'suggestednodes.png'" />
|
||||
<n8n-text>{{ $locale.baseText('personalizationModal.lookOutForThingsMarked') }}</n8n-text>
|
||||
</div>
|
||||
<div :class="$style.container" v-else>
|
||||
|
@ -50,7 +50,6 @@ import mixins from 'vue-typed-mixins';
|
|||
const SURVEY_VERSION = 'v3';
|
||||
|
||||
import {
|
||||
CODING_SKILL_KEY,
|
||||
COMPANY_SIZE_100_499,
|
||||
COMPANY_SIZE_1000_OR_MORE,
|
||||
COMPANY_SIZE_20_OR_LESS,
|
||||
|
@ -116,11 +115,15 @@ import {
|
|||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
import { showMessage } from '@/components/mixins/showMessage';
|
||||
import Modal from './Modal.vue';
|
||||
import { IFormInputs, IPersonalizationLatestVersion } from '@/Interface';
|
||||
import { IFormInputs, IPersonalizationLatestVersion, IPersonalizationSurveyAnswersV3, IUser } from '@/Interface';
|
||||
import Vue from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { getAccountAge } from '@/modules/userHelpers';
|
||||
import { GenericValue } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
|
||||
export default mixins(showMessage, workflowHelpers).extend({
|
||||
components: { Modal },
|
||||
|
@ -138,15 +141,12 @@ export default mixins(showMessage, workflowHelpers).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
baseUrl: 'getBaseUrl',
|
||||
}),
|
||||
...mapGetters('users', [
|
||||
'currentUser',
|
||||
]),
|
||||
...mapGetters('settings', [
|
||||
'isOnboardingCallPromptFeatureEnabled',
|
||||
]),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
),
|
||||
survey() {
|
||||
const survey: IFormInputs = [
|
||||
{
|
||||
|
@ -470,12 +470,12 @@ export default mixins(showMessage, workflowHelpers).extend({
|
|||
...values,
|
||||
version: SURVEY_VERSION,
|
||||
personalization_survey_submitted_at: new Date().toISOString(),
|
||||
personalization_survey_n8n_version: this.$store.getters.versionCli,
|
||||
personalization_survey_n8n_version: this.rootStore.versionCli,
|
||||
};
|
||||
|
||||
this.$externalHooks().run('personalizationModal.onSubmit', survey);
|
||||
|
||||
await this.$store.dispatch('users/submitPersonalizationSurvey', survey);
|
||||
await this.usersStore.submitPersonalizationSurvey(survey as IPersonalizationSurveyAnswersV3);
|
||||
|
||||
if (Object.keys(values).length === 0) {
|
||||
this.closeDialog();
|
||||
|
@ -490,8 +490,8 @@ export default mixins(showMessage, workflowHelpers).extend({
|
|||
this.$data.isSaving = false;
|
||||
},
|
||||
async fetchOnboardingPrompt() {
|
||||
if (this.isOnboardingCallPromptFeatureEnabled && getAccountAge(this.currentUser) <= ONBOARDING_PROMPT_TIMEBOX) {
|
||||
const onboardingResponse = await this.$store.dispatch('ui/getNextOnboardingPrompt');
|
||||
if (this.settingsStore.onboardingCallPromptEnabled && getAccountAge(this.usersStore.currentUser || {} as IUser) <= ONBOARDING_PROMPT_TIMEBOX) {
|
||||
const onboardingResponse = await this.uiStore.getNextOnboardingPrompt();
|
||||
const promptTimeout = onboardingResponse.toast_sequence_number === 1 ? FIRST_ONBOARDING_PROMPT_TIMEOUT : 1000;
|
||||
|
||||
if (onboardingResponse.title && onboardingResponse.description) {
|
||||
|
@ -509,7 +509,7 @@ export default mixins(showMessage, workflowHelpers).extend({
|
|||
title: onboardingResponse.title,
|
||||
description: onboardingResponse.description,
|
||||
});
|
||||
this.$store.commit('ui/openModal', ONBOARDING_CALL_SIGNUP_MODAL_KEY, {root: true});
|
||||
this.uiStore.openModal(ONBOARDING_CALL_SIGNUP_MODAL_KEY);
|
||||
},
|
||||
});
|
||||
}, promptTimeout);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<span>
|
||||
<div class="push-connection-lost primary-color" v-if="!pushConnectionActive">
|
||||
<div class="push-connection-lost primary-color" v-if="!rootStore.pushConnectionActive">
|
||||
<n8n-tooltip placement="bottom-end" >
|
||||
<div slot="content" v-html="$locale.baseText('pushConnectionTracker.cannotConnectToServer')"></div>
|
||||
<span>
|
||||
|
@ -13,13 +13,16 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useRootStore } from "@/stores/n8nRootStore";
|
||||
import { mapStores } from "pinia";
|
||||
import Vue from "vue";
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "PushConnectionTracker",
|
||||
computed: {
|
||||
...mapGetters(["pushConnectionActive"]),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -172,6 +172,12 @@ import { workflowHelpers } from '../mixins/workflowHelpers';
|
|||
import { nodeHelpers } from '../mixins/nodeHelpers';
|
||||
import { getAppNameFromNodeName } from '../helpers';
|
||||
import { isResourceLocatorValue } from '@/typeGuards';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
interface IResourceLocatorQuery {
|
||||
results: INodeListSearchItems[];
|
||||
|
@ -248,7 +254,6 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
mainPanelMutationSubscription: () => {},
|
||||
showResourceDropdown: false,
|
||||
searchFilter: '',
|
||||
cachedResponses: {} as { [key: string]: IResourceLocatorQuery },
|
||||
|
@ -257,13 +262,20 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useRootStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
appName(): string {
|
||||
if (!this.node) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const nodeType = this.$store.getters['nodeTypes/getNodeType'](this.node.type);
|
||||
return getAppNameFromNodeName(nodeType.displayName);
|
||||
const nodeType = this.nodeTypesStore.getNodeType(this.node.type);
|
||||
return getAppNameFromNodeName(nodeType?.displayName || '');
|
||||
},
|
||||
selectedMode(): string {
|
||||
if (typeof this.value !== 'object') { // legacy mode
|
||||
|
@ -280,7 +292,7 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
return this.selectedMode === 'list';
|
||||
},
|
||||
hasCredential(): boolean {
|
||||
const node = this.$store.getters['ndv/activeNode'] as INodeUi | null;
|
||||
const node = this.ndvStore.activeNode;
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
@ -425,24 +437,21 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
mounted() {
|
||||
this.$on('refreshList', this.refreshList);
|
||||
window.addEventListener('resize', this.setWidth);
|
||||
this.mainPanelMutationSubscription = this.$store.subscribe(this.setWidthOnMainPanelResize);
|
||||
useNDVStore().$subscribe((mutation, state) => {
|
||||
// Update the width when main panel dimension change
|
||||
this.setWidth();
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setWidth();
|
||||
}, 0);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// Unsubscribe
|
||||
this.mainPanelMutationSubscription();
|
||||
window.removeEventListener('resize', this.setWidth);
|
||||
},
|
||||
methods: {
|
||||
setWidth() {
|
||||
this.width = (this.$refs.container as HTMLElement).offsetWidth;
|
||||
},
|
||||
setWidthOnMainPanelResize(mutation: { type: string }) {
|
||||
// Update the width when main panel dimension change
|
||||
if(mutation.type === 'ndv/setMainPanelDimensions') this.setWidth();
|
||||
},
|
||||
getLinkAlt(entity: string) {
|
||||
if (this.selectedMode === 'list' && entity) {
|
||||
return this.$locale.baseText('resourceLocator.openSpecificResource', { interpolate: { entity, appName: this.appName } });
|
||||
|
@ -480,7 +489,7 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
return parameter.typeOptions[argumentName];
|
||||
},
|
||||
openCredential(): void {
|
||||
const node = this.$store.getters['ndv/activeNode'] as INodeUi | null;
|
||||
const node = this.ndvStore.activeNode;
|
||||
if (!node || !node.credentials) {
|
||||
return;
|
||||
}
|
||||
|
@ -489,7 +498,7 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
return;
|
||||
}
|
||||
const id = node.credentials[credentialKey].id;
|
||||
this.$store.dispatch('ui/openExistingCredential', { id });
|
||||
this.uiStore.openExistingCredential(id);
|
||||
},
|
||||
findModeByName(name: string): INodePropertyMode | null {
|
||||
if (this.parameter.modes) {
|
||||
|
@ -533,8 +542,8 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
},
|
||||
trackEvent(event: string, params?: {[key: string]: string}): void {
|
||||
this.$telemetry.track(event, {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
node_type: this.node && this.node.type,
|
||||
resource: this.node && this.node.parameters && this.node.parameters.resource,
|
||||
operation: this.node && this.node.parameters && this.node.parameters.operation,
|
||||
|
@ -618,10 +627,7 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
|||
...(paginationToken ? { paginationToken } : {}),
|
||||
};
|
||||
|
||||
const response: INodeListSearchResult = await this.$store.dispatch(
|
||||
'nodeTypes/getResourceLocatorResults',
|
||||
requestParams,
|
||||
);
|
||||
const response = await this.nodeTypesStore.getResourceLocatorResults(requestParams);
|
||||
|
||||
this.setResponse(paramsKey, {
|
||||
results: (cachedResponse ? cachedResponse.results : []).concat(response.results),
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
:value="editMode.value"
|
||||
:options="{ scrollBeyondLastLine: false }"
|
||||
type="json"
|
||||
@input="$store.commit('ndv/setOutputPanelEditModeValue', $event)"
|
||||
@input="ndvStore.setOutputPanelEditModeValue($event)"
|
||||
/>
|
||||
</div>
|
||||
<div :class="$style['edit-mode-footer']">
|
||||
|
@ -344,6 +344,7 @@ import {
|
|||
IBinaryDisplayData,
|
||||
IExecutionResponse,
|
||||
INodeUi,
|
||||
INodeUpdatePropertiesInformation,
|
||||
IRunDataDisplayMode,
|
||||
ITab,
|
||||
} from '@/Interface';
|
||||
|
@ -373,6 +374,10 @@ import { clearJsonKey, executionDataToJson, stringSizeInBytes } from './helpers'
|
|||
import RunDataTable from './RunDataTable.vue';
|
||||
import RunDataJson from '@/components/RunDataJson.vue';
|
||||
import { isEmpty } from '@/utils';
|
||||
import { useWorkflowsStore } from "@/stores/workflows";
|
||||
import { mapStores } from "pinia";
|
||||
import { useNDVStore } from "@/stores/ndv";
|
||||
import { useNodeTypesStore } from "@/stores/nodeTypes";
|
||||
|
||||
export type EnterEditModeArgs = {
|
||||
origin: 'editIconButton' | 'insertTestDataLink',
|
||||
|
@ -475,8 +480,8 @@ export default mixins(
|
|||
this.showPinDataDiscoveryTooltip(this.jsonData);
|
||||
}
|
||||
}
|
||||
this.$store.commit('ndv/setNDVBranchIndex', {
|
||||
pane: this.paneType,
|
||||
this.ndvStore.setNDVBranchIndex({
|
||||
pane: this.paneType as "input" | "output",
|
||||
branchIndex: this.currentOutputIndex,
|
||||
});
|
||||
},
|
||||
|
@ -486,8 +491,13 @@ export default mixins(
|
|||
this.eventBus.$off('data-unpinning', this.onDataUnpinning);
|
||||
},
|
||||
computed: {
|
||||
activeNode(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
activeNode(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
dataPinningDocsUrl(): string {
|
||||
return DATA_PINNING_DOCS_URL;
|
||||
|
@ -496,19 +506,19 @@ export default mixins(
|
|||
return DATA_EDITING_DOCS_URL;
|
||||
},
|
||||
displayMode(): IRunDataDisplayMode {
|
||||
return this.$store.getters['ndv/getPanelDisplayMode'](this.paneType);
|
||||
return this.ndvStore.getPanelDisplayMode(this.paneType as "input" | "output");
|
||||
},
|
||||
node(): INodeUi | null {
|
||||
return (this.nodeUi as INodeUi | null) || null;
|
||||
},
|
||||
nodeType (): INodeTypeDescription | null {
|
||||
if (this.node) {
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.node.type, this.node.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
isTriggerNode (): boolean {
|
||||
return this.$store.getters['nodeTypes/isTriggerNode'](this.node.type);
|
||||
return this.nodeTypesStore.isTriggerNode(this.node.type);
|
||||
},
|
||||
canPinData (): boolean {
|
||||
return !this.isPaneTypeInput &&
|
||||
|
@ -532,7 +542,7 @@ export default mixins(
|
|||
return Boolean(!this.isExecuting && this.node && (this.workflowRunData && this.workflowRunData.hasOwnProperty(this.node.name) || this.hasPinData));
|
||||
},
|
||||
subworkflowExecutionError(): Error | null {
|
||||
return this.$store.getters.subworkflowExecutionError;
|
||||
return this.workflowsStore.subWorkflowExecutionError;
|
||||
},
|
||||
hasSubworkflowExecutionError(): boolean {
|
||||
return Boolean(this.subworkflowExecutionError);
|
||||
|
@ -541,7 +551,7 @@ export default mixins(
|
|||
return Boolean(this.node && this.workflowRunData && this.workflowRunData[this.node.name] && this.workflowRunData[this.node.name][this.runIndex] && this.workflowRunData[this.node.name][this.runIndex].error);
|
||||
},
|
||||
workflowExecution (): IExecutionResponse | null {
|
||||
return this.$store.getters.getWorkflowExecution;
|
||||
return this.workflowsStore.getWorkflowExecution;
|
||||
},
|
||||
workflowRunData (): IRunData | null {
|
||||
if (this.workflowExecution === null) {
|
||||
|
@ -680,7 +690,7 @@ export default mixins(
|
|||
editMode(): { enabled: boolean; value: string; } {
|
||||
return this.isPaneTypeInput
|
||||
? { enabled: false, value: '' }
|
||||
: this.$store.getters['ndv/outputPanelEditMode'];
|
||||
: this.ndvStore.outputPanelEditMode;
|
||||
},
|
||||
isPaneTypeInput(): boolean {
|
||||
return this.paneType === 'input';
|
||||
|
@ -700,9 +710,9 @@ export default mixins(
|
|||
},
|
||||
onClickDataPinningDocsLink() {
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
node_type: this.activeNode.type,
|
||||
node_type: this.activeNode?.type,
|
||||
pane: 'output',
|
||||
type: 'data-pinning-docs',
|
||||
});
|
||||
|
@ -742,11 +752,11 @@ export default mixins(
|
|||
? inputData
|
||||
: TEST_PIN_DATA;
|
||||
|
||||
this.$store.commit('ndv/setOutputPanelEditModeEnabled', true);
|
||||
this.$store.commit('ndv/setOutputPanelEditModeValue', JSON.stringify(data, null, 2));
|
||||
this.ndvStore.setOutputPanelEditModeEnabled(true);
|
||||
this.ndvStore.setOutputPanelEditModeValue(JSON.stringify(data, null, 2));
|
||||
|
||||
this.$telemetry.track('User opened ndv edit state', {
|
||||
node_type: this.activeNode.type,
|
||||
node_type: this.activeNode?.type,
|
||||
click_type: origin === 'editIconButton' ? 'button' : 'link',
|
||||
session_id: this.sessionId,
|
||||
run_index: this.runIndex,
|
||||
|
@ -756,8 +766,8 @@ export default mixins(
|
|||
});
|
||||
},
|
||||
onClickCancelEdit() {
|
||||
this.$store.commit('ndv/setOutputPanelEditModeEnabled', false);
|
||||
this.$store.commit('ndv/setOutputPanelEditModeValue', '');
|
||||
this.ndvStore.setOutputPanelEditModeEnabled(false);
|
||||
this.ndvStore.setOutputPanelEditModeValue('');
|
||||
this.onExitEditMode({ type: 'cancel' });
|
||||
},
|
||||
onClickSaveEdit() {
|
||||
|
@ -775,8 +785,8 @@ export default mixins(
|
|||
return;
|
||||
}
|
||||
|
||||
this.$store.commit('ndv/setOutputPanelEditModeEnabled', false);
|
||||
this.$store.commit('pinData', { node: this.node, data: clearJsonKey(value) });
|
||||
this.ndvStore.setOutputPanelEditModeEnabled(false);
|
||||
this.workflowsStore.pinData({ node: this.node, data: clearJsonKey(value) as INodeExecutionData[] });
|
||||
|
||||
this.onDataPinningSuccess({ source: 'save-edit' });
|
||||
|
||||
|
@ -784,7 +794,7 @@ export default mixins(
|
|||
},
|
||||
onExitEditMode({ type }: { type: 'save' | 'cancel' }) {
|
||||
this.$telemetry.track('User closed ndv edit state', {
|
||||
node_type: this.activeNode.type,
|
||||
node_type: this.activeNode?.type,
|
||||
session_id: this.sessionId,
|
||||
run_index: this.runIndex,
|
||||
view: this.displayMode,
|
||||
|
@ -795,7 +805,7 @@ export default mixins(
|
|||
{ source }: { source: 'banner-link' | 'pin-icon-click' | 'unpin-and-execute-modal' },
|
||||
) {
|
||||
this.$telemetry.track('User unpinned ndv data', {
|
||||
node_type: this.activeNode.type,
|
||||
node_type: this.activeNode?.type,
|
||||
session_id: this.sessionId,
|
||||
run_index: this.runIndex,
|
||||
source,
|
||||
|
@ -849,11 +859,11 @@ export default mixins(
|
|||
|
||||
if (this.hasPinData) {
|
||||
this.onDataUnpinning({ source });
|
||||
this.$store.commit('unpinData', { node: this.node });
|
||||
this.workflowsStore.unpinData({ node: this.node });
|
||||
return;
|
||||
}
|
||||
|
||||
const data = executionDataToJson(this.rawInputData);
|
||||
const data = executionDataToJson(this.rawInputData) as INodeExecutionData[];
|
||||
|
||||
if (!this.isValidPinDataSize(data)) {
|
||||
this.onDataPinningError({ errorType: 'data-too-large', source: 'pin-icon-click' });
|
||||
|
@ -862,7 +872,7 @@ export default mixins(
|
|||
|
||||
this.onDataPinningSuccess({ source: 'pin-icon-click' });
|
||||
|
||||
this.$store.commit('pinData', { node: this.node, data });
|
||||
this.workflowsStore.pinData({ node: this.node, data });
|
||||
|
||||
if (this.maxRunIndex > 0) {
|
||||
this.$showToast({
|
||||
|
@ -898,7 +908,7 @@ export default mixins(
|
|||
this.showData = true;
|
||||
this.$telemetry.track('User clicked ndv button', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: this.paneType,
|
||||
type: 'showTooMuchData',
|
||||
|
@ -912,8 +922,8 @@ export default mixins(
|
|||
},
|
||||
onCurrentPageChange() {
|
||||
this.$telemetry.track('User changed ndv page', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
node_type: this.activeNode?.type,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: this.paneType,
|
||||
page_selected: this.currentPage,
|
||||
|
@ -929,8 +939,8 @@ export default mixins(
|
|||
}
|
||||
|
||||
this.$telemetry.track('User changed ndv page size', {
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
node_type: this.activeNode?.type,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: this.paneType,
|
||||
page_selected: this.currentPage,
|
||||
|
@ -940,7 +950,7 @@ export default mixins(
|
|||
},
|
||||
onDisplayModeChange(displayMode: IRunDataDisplayMode) {
|
||||
const previous = this.displayMode;
|
||||
this.$store.commit('ndv/setPanelDisplayMode', {pane: this.paneType, mode: displayMode});
|
||||
this.ndvStore.setPanelDisplayMode({pane: this.paneType as "input" | "output", mode: displayMode});
|
||||
|
||||
const dataContainer = this.$refs.dataContainer;
|
||||
if (dataContainer) {
|
||||
|
@ -958,7 +968,7 @@ export default mixins(
|
|||
previous_view: previous,
|
||||
new_view: displayMode,
|
||||
node_type: this.activeNode.type,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: this.paneType,
|
||||
});
|
||||
|
@ -1012,10 +1022,10 @@ export default mixins(
|
|||
this.refreshDataSize();
|
||||
this.closeBinaryDataDisplay();
|
||||
if (this.binaryData.length > 0) {
|
||||
this.$store.commit('ndv/setPanelDisplayMode', {pane: this.paneType, mode: 'binary'});
|
||||
this.ndvStore.setPanelDisplayMode({pane: this.paneType as "input" | "output", mode: 'binary'});
|
||||
}
|
||||
else if (this.displayMode === 'binary') {
|
||||
this.$store.commit('ndv/setPanelDisplayMode', {pane: this.paneType, mode: 'table'});
|
||||
this.ndvStore.setPanelDisplayMode({pane: this.paneType as "input" | "output", mode: 'table'});
|
||||
}
|
||||
},
|
||||
closeBinaryDataDisplay () {
|
||||
|
@ -1023,7 +1033,7 @@ export default mixins(
|
|||
this.binaryDataDisplayData = null;
|
||||
},
|
||||
clearExecutionData () {
|
||||
this.$store.commit('setWorkflowExecutionData', null);
|
||||
this.workflowsStore.setWorkflowExecutionData(null);
|
||||
this.updateNodesExecutionIssues();
|
||||
},
|
||||
isDownloadable (index: number, key: string): boolean {
|
||||
|
@ -1093,15 +1103,15 @@ export default mixins(
|
|||
name: this.node.name,
|
||||
properties: {
|
||||
disabled: !this.node.disabled,
|
||||
},
|
||||
};
|
||||
} as IDataObject,
|
||||
} as INodeUpdatePropertiesInformation;
|
||||
|
||||
this.$store.commit('updateNodeProperties', updateInformation);
|
||||
this.workflowsStore.updateNodeProperties(updateInformation);
|
||||
}
|
||||
},
|
||||
goToErroredNode() {
|
||||
if (this.node) {
|
||||
this.$store.commit('ndv/setActiveNodeName', this.node.name);
|
||||
this.ndvStore.activeNodeName = this.node.name;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -1112,7 +1122,7 @@ export default mixins(
|
|||
inputData:{
|
||||
handler(data: INodeExecutionData[]) {
|
||||
if(this.paneType && data){
|
||||
this.$store.commit('ndv/setNDVPanelDataIsEmpty', { panel: this.paneType, isEmpty: data.every(item => isEmpty(item.json)) });
|
||||
this.ndvStore.setNDVPanelDataIsEmpty({ panel: this.paneType as "input" | "output", isEmpty: data.every(item => isEmpty(item.json)) });
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
|
@ -1135,8 +1145,8 @@ export default mixins(
|
|||
}
|
||||
},
|
||||
currentOutputIndex(branchIndex: number) {
|
||||
this.$store.commit('ndv/setNDVBranchIndex', {
|
||||
pane: this.paneType,
|
||||
this.ndvStore.setNDVBranchIndex({
|
||||
pane: this.paneType as "input" | "output",
|
||||
branchIndex,
|
||||
});
|
||||
},
|
||||
|
|
|
@ -66,6 +66,8 @@ import { convertPath, executionDataToJson, isString, isStringNumber } from "@/co
|
|||
import { INodeUi } from "@/Interface";
|
||||
import { shorten } from './helpers';
|
||||
import { externalHooks } from "@/components/mixins/externalHooks";
|
||||
import { mapStores } from "pinia";
|
||||
import { useNDVStore } from "@/stores/ndv";
|
||||
|
||||
const runDataJsonActions = () => import('@/components/RunDataJsonActions.vue');
|
||||
|
||||
|
@ -137,6 +139,9 @@ export default mixins(externalHooks).extend({
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
),
|
||||
jsonData(): IDataObject[] {
|
||||
return executionDataToJson(this.inputData as INodeExecutionData[]);
|
||||
},
|
||||
|
@ -165,13 +170,13 @@ export default mixins(externalHooks).extend({
|
|||
this.draggingPath = el.dataset.path;
|
||||
}
|
||||
|
||||
this.$store.commit('ndv/resetMappingTelemetry');
|
||||
this.ndvStore.resetMappingTelemetry();
|
||||
},
|
||||
onDragEnd(el: HTMLElement) {
|
||||
this.draggingPath = null;
|
||||
|
||||
setTimeout(() => {
|
||||
const mappingTelemetry = this.$store.getters['ndv/mappingTelemetry'];
|
||||
const mappingTelemetry = this.ndvStore.mappingTelemetry;
|
||||
const telemetryPayload = {
|
||||
src_node_type: this.node.type,
|
||||
src_field_name: el.dataset.name || '',
|
||||
|
|
|
@ -35,6 +35,9 @@ import { pinData } from "@/components/mixins/pinData";
|
|||
import { nodeHelpers } from "@/components/mixins/nodeHelpers";
|
||||
import { genericHelpers } from "@/components/mixins/genericHelpers";
|
||||
import { clearJsonKey, convertPath, executionDataToJson } from "@/components/helpers";
|
||||
import { mapStores } from "pinia";
|
||||
import { useWorkflowsStore } from "@/stores/workflows";
|
||||
import { useNDVStore } from "@/stores/ndv";
|
||||
|
||||
type JsonPathData = {
|
||||
path: string;
|
||||
|
@ -83,8 +86,12 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
activeNode(): INodeUi {
|
||||
return this.$store.getters['ndv/activeNode'];
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
activeNode(): INodeUi | null {
|
||||
return this.ndvStore.activeNode;
|
||||
},
|
||||
normalisedJsonPath(): string {
|
||||
const isNotSelected = this.selectedJsonPath === nonExistingJsonPath;
|
||||
|
@ -189,7 +196,7 @@ export default mixins(
|
|||
run_index: this.runIndex,
|
||||
view: 'json',
|
||||
copy_type: copyType,
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
pane: this.paneType,
|
||||
in_execution_log: this.isReadOnly,
|
||||
});
|
||||
|
|
|
@ -152,14 +152,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { INodeUi, IRootState, ITableData, NDVState } from '@/Interface';
|
||||
/* eslint-disable prefer-spread */
|
||||
import { INodeUi, ITableData, NDVState } from '@/Interface';
|
||||
import { getPairedItemId } from '@/pairedItemUtils';
|
||||
import Vue, { PropType } from 'vue';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { GenericValue, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import Draggable from '@/components/Draggable.vue';
|
||||
import { shorten } from '@/components/helpers';
|
||||
import { externalHooks } from '@/components/mixins/externalHooks';
|
||||
import Draggable from './Draggable.vue';
|
||||
import { shorten } from './helpers';
|
||||
import { externalHooks } from './mixins/externalHooks';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
const MAX_COLUMNS_LIMIT = 40;
|
||||
|
||||
|
@ -217,11 +221,15 @@ export default mixins(externalHooks).extend({
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
hoveringItem(): NDVState['hoveringItem'] {
|
||||
return this.$store.getters['ndv/hoveringItem'];
|
||||
return this.ndvStore.hoveringItem;
|
||||
},
|
||||
pairedItemMappings(): IRootState['workflowExecutionPairedItemMappings'] {
|
||||
return this.$store.getters['workflowExecutionPairedItemMappings'];
|
||||
pairedItemMappings(): {[itemId: string]: Set<string>} {
|
||||
return this.workflowsStore.workflowExecutionPairedItemMappings;
|
||||
},
|
||||
tableData(): ITableData {
|
||||
return this.convertToTable(this.inputData);
|
||||
|
@ -360,8 +368,7 @@ export default mixins(externalHooks).extend({
|
|||
},
|
||||
onDragStart() {
|
||||
this.draggedColumn = true;
|
||||
|
||||
this.$store.commit('ndv/resetMappingTelemetry');
|
||||
this.ndvStore.resetMappingTelemetry();
|
||||
},
|
||||
onCellDragStart(el: HTMLElement) {
|
||||
if (el && el.dataset.value) {
|
||||
|
@ -384,7 +391,7 @@ export default mixins(externalHooks).extend({
|
|||
},
|
||||
onDragEnd(column: string, src: string, depth = '0') {
|
||||
setTimeout(() => {
|
||||
const mappingTelemetry = this.$store.getters['ndv/mappingTelemetry'];
|
||||
const mappingTelemetry = this.ndvStore.mappingTelemetry;
|
||||
const telemetryPayload = {
|
||||
src_node_type: this.node.type,
|
||||
src_field_name: column,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<template #menuSuffix>
|
||||
<div :class="$style.versionContainer">
|
||||
<n8n-link @click="onVersionClick" size="small">
|
||||
{{ $locale.baseText('settings.version') }} {{ versionCli }}
|
||||
{{ $locale.baseText('settings.version') }} {{ rootStore.versionCli }}
|
||||
</n8n-link>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -29,6 +29,10 @@ import { pushConnection } from "@/components/mixins/pushConnection";
|
|||
import { IFakeDoor } from '@/Interface';
|
||||
import { IMenuItem } from 'n8n-design-system';
|
||||
import { BaseTextKey } from '@/plugins/i18n';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default mixins(
|
||||
userHelpers,
|
||||
|
@ -36,9 +40,13 @@ export default mixins(
|
|||
).extend({
|
||||
name: 'SettingsSidebar',
|
||||
computed: {
|
||||
...mapGetters('settings', ['versionCli']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
),
|
||||
settingsFakeDoorFeatures(): IFakeDoor[] {
|
||||
return this.$store.getters['ui/getFakeDoorByLocation']('settings');
|
||||
return this.uiStore.getFakeDoorByLocation('settings');
|
||||
},
|
||||
sidebarMenuItems(): IMenuItem[] {
|
||||
|
||||
|
@ -113,13 +121,13 @@ export default mixins(
|
|||
return this.canUserAccessRouteByName(VIEWS.API_SETTINGS);
|
||||
},
|
||||
onVersionClick() {
|
||||
this.$store.dispatch('ui/openModal', ABOUT_MODAL_KEY);
|
||||
this.uiStore.openModal(ABOUT_MODAL_KEY);
|
||||
},
|
||||
onReturn() {
|
||||
this.$router.push({name: VIEWS.HOMEPAGE});
|
||||
},
|
||||
openUpdatesPanel() {
|
||||
this.$store.dispatch('ui/openModal', VERSIONS_MODAL_KEY);
|
||||
this.uiStore.openModal(VERSIONS_MODAL_KEY);
|
||||
},
|
||||
async handleSelect (key: string) {
|
||||
switch (key) {
|
||||
|
|
|
@ -50,12 +50,18 @@ import { nodeBase } from '@/components/mixins/nodeBase';
|
|||
import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
||||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
import { getStyleTokenValue, isNumber, isString } from './helpers';
|
||||
import { INodeUi, XYPosition } from '@/Interface';
|
||||
import { INodeUi, INodeUpdatePropertiesInformation, IUpdateInformation, XYPosition } from '@/Interface';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
import { QUICKSTART_NOTE_NAME } from '@/constants';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).extend({
|
||||
name: 'Sticky',
|
||||
|
@ -68,6 +74,12 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
defaultText (): string {
|
||||
if (!this.nodeType) {
|
||||
return '';
|
||||
|
@ -78,13 +90,13 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
return content && isString(content.default) ? content.default : '';
|
||||
},
|
||||
isSelected (): boolean {
|
||||
return this.$store.getters.getSelectedNodes.find((node: INodeUi) => node.name === this.data.name);
|
||||
return this.uiStore.getSelectedNodes.find((node: INodeUi) => node.name === this.data.name) !== undefined;
|
||||
},
|
||||
nodeType (): INodeTypeDescription | null {
|
||||
return this.data && this.$store.getters['nodeTypes/getNodeType'](this.data.type, this.data.typeVersion);
|
||||
return this.data && this.nodeTypesStore.getNodeType(this.data.type, this.data.typeVersion);
|
||||
},
|
||||
node (): INodeUi | undefined { // same as this.data but reactive..
|
||||
return this.$store.getters.nodesByName[this.name] as INodeUi | undefined;
|
||||
node (): INodeUi | null { // same as this.data but reactive..
|
||||
return this.workflowsStore.getNodeByName(this.name);
|
||||
},
|
||||
position (): XYPosition {
|
||||
if (this.node) {
|
||||
|
@ -124,7 +136,7 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
return !(this.hideActions || this.isReadOnly || this.workflowRunning || this.isResizing);
|
||||
},
|
||||
workflowRunning (): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
},
|
||||
data () {
|
||||
|
@ -142,10 +154,10 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
},
|
||||
onEdit(edit: boolean) {
|
||||
if (edit && !this.isActive && this.node) {
|
||||
this.$store.commit('ndv/setActiveNodeName', this.node.name);
|
||||
this.ndvStore.activeNodeName = this.node.name;
|
||||
}
|
||||
else if (this.isActive && !edit) {
|
||||
this.$store.commit('ndv/setActiveNodeName', null);
|
||||
this.ndvStore.activeNodeName = null;
|
||||
}
|
||||
},
|
||||
onMarkdownClick ( link:HTMLAnchorElement, event: Event ) {
|
||||
|
@ -191,12 +203,13 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
width: isNumber(params.width) ? params.width : this.node.parameters.width,
|
||||
};
|
||||
|
||||
const updateInformation = {
|
||||
const updateInformation: IUpdateInformation = {
|
||||
key: this.node.id,
|
||||
name: this.node.name,
|
||||
value: nodeParameters,
|
||||
};
|
||||
|
||||
this.$store.commit('setNodeParameters', updateInformation);
|
||||
this.workflowsStore.setNodeParameters(updateInformation);
|
||||
}
|
||||
},
|
||||
setPosition(position: XYPosition) {
|
||||
|
@ -204,14 +217,14 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext
|
|||
return;
|
||||
}
|
||||
|
||||
const updateInformation = {
|
||||
const updateInformation: INodeUpdatePropertiesInformation = {
|
||||
name: this.node.name,
|
||||
properties: {
|
||||
position,
|
||||
position: { position },
|
||||
},
|
||||
};
|
||||
|
||||
this.$store.commit('updateNodeProperties', updateInformation);
|
||||
this.workflowsStore.updateNodeProperties(updateInformation);
|
||||
},
|
||||
touchStart () {
|
||||
if (this.isTouchDevice === true && this.isMacOs === false && this.isTouchActive === false) {
|
||||
|
|
|
@ -60,6 +60,8 @@ import { ITag } from "@/Interface";
|
|||
import { MAX_TAG_NAME_LENGTH, TAGS_MANAGER_MODAL_KEY } from "@/constants";
|
||||
|
||||
import { showMessage } from "@/components/mixins/showMessage";
|
||||
import { mapStores } from "pinia";
|
||||
import { useUIStore } from "@/stores/ui";
|
||||
|
||||
const MANAGE_KEY = "__manage";
|
||||
const CREATE_KEY = "__create";
|
||||
|
@ -113,6 +115,7 @@ export default mixins(showMessage).extend({
|
|||
this.$store.dispatch("tags/fetchAll");
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useUIStore),
|
||||
...mapGetters("tags", ["allTags", "isLoading", "hasTags"]),
|
||||
options(): ITag[] {
|
||||
return this.allTags
|
||||
|
@ -156,7 +159,7 @@ export default mixins(showMessage).extend({
|
|||
);
|
||||
if (ops === MANAGE_KEY) {
|
||||
this.$data.filter = "";
|
||||
this.$store.dispatch("ui/openModal", TAGS_MANAGER_MODAL_KEY);
|
||||
this.uiStore.openModal(TAGS_MANAGER_MODAL_KEY);
|
||||
} else if (ops === CREATE_KEY) {
|
||||
this.onCreate();
|
||||
} else {
|
||||
|
|
|
@ -32,6 +32,8 @@ import { ITag, ITagRow } from "@/Interface";
|
|||
import TagsTableHeader from "@/components/TagsManager/TagsView/TagsTableHeader.vue";
|
||||
import TagsTable from "@/components/TagsManager/TagsView/TagsTable.vue";
|
||||
import { mapGetters } from 'vuex';
|
||||
import { mapStores } from "pinia";
|
||||
import { useUsersStore } from "@/stores/users";
|
||||
|
||||
const matches = (name: string, filter: string) => name.toLowerCase().trim().includes(filter.toLowerCase().trim());
|
||||
|
||||
|
@ -51,7 +53,7 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('users', ['canUserDeleteTags']),
|
||||
...mapStores(useUsersStore),
|
||||
isCreateEnabled(): boolean {
|
||||
return (this.$props.tags || []).length === 0 || this.$data.createEnabled;
|
||||
},
|
||||
|
@ -69,7 +71,7 @@ export default Vue.extend({
|
|||
disable: disabled && tag.id !== this.deleteId && tag.id !== this.$data.updateId,
|
||||
update: disabled && tag.id === this.$data.updateId,
|
||||
delete: disabled && tag.id === this.$data.deleteId,
|
||||
canDelete: this.canUserDeleteTags,
|
||||
canDelete: this.usersStore.canUserDeleteTags,
|
||||
}));
|
||||
|
||||
return this.isCreateEnabled
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { ITelemetrySettings } from 'n8n-workflow';
|
||||
import { mapStores } from 'pinia';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
|
||||
import { mapGetters } from 'vuex';
|
||||
import { externalHooks } from './mixins/externalHooks';
|
||||
|
||||
export default mixins(externalHooks).extend({
|
||||
|
@ -17,12 +19,20 @@ export default mixins(externalHooks).extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('settings', ['telemetry']),
|
||||
...mapGetters('users', ['currentUserId']),
|
||||
...mapGetters(['instanceId']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUsersStore,
|
||||
),
|
||||
currentUserId(): string {
|
||||
return this.usersStore.currentUserId || '';
|
||||
},
|
||||
isTelemetryEnabledOnRoute(): boolean {
|
||||
return this.$route.meta && this.$route.meta.telemetry ? !this.$route.meta.telemetry.disabled: true;
|
||||
},
|
||||
telemetry(): ITelemetrySettings {
|
||||
return this.settingsStore.telemetry;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
|
@ -40,15 +50,15 @@ export default mixins(externalHooks).extend({
|
|||
this.$telemetry.init(
|
||||
telemetrySettings,
|
||||
{
|
||||
instanceId: this.instanceId,
|
||||
instanceId: this.rootStore.instanceId,
|
||||
userId: this.currentUserId,
|
||||
store: this.$store,
|
||||
versionCli: this.$store.getters['settings/versionCli'],
|
||||
versionCli: this.rootStore.versionCli,
|
||||
},
|
||||
);
|
||||
|
||||
this.$externalHooks().run('telemetry.currentUserIdChanged', {
|
||||
instanceId: this.instanceId,
|
||||
instanceId: this.rootStore.instanceId,
|
||||
userId: this.currentUserId,
|
||||
});
|
||||
|
||||
|
@ -60,9 +70,9 @@ export default mixins(externalHooks).extend({
|
|||
this.init();
|
||||
},
|
||||
currentUserId(userId) {
|
||||
this.$telemetry.identify(this.instanceId, userId);
|
||||
this.$telemetry.identify(this.rootStore.instanceId, userId);
|
||||
this.$externalHooks().run('telemetry.currentUserIdChanged', {
|
||||
instanceId: this.instanceId,
|
||||
instanceId: this.rootStore.instanceId,
|
||||
userId,
|
||||
});
|
||||
},
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</template-details-block>
|
||||
|
||||
<template-details-block
|
||||
v-if="!loading && template.categories.length > 0"
|
||||
v-if="!loading && template?.categories.length > 0"
|
||||
:title="$locale.baseText('template.details.categories')"
|
||||
>
|
||||
<n8n-tags :tags="template.categories" @click="redirectToCategory" />
|
||||
|
@ -52,6 +52,8 @@ import TemplateDetailsBlock from '@/components/TemplateDetailsBlock.vue';
|
|||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import { abbreviateNumber, filterTemplateNodes } from '@/components/helpers';
|
||||
import { ITemplatesNode, ITemplatesWorkflow, ITemplatesWorkflowFull } from '@/Interface';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useTemplatesStore } from '@/stores/templates';
|
||||
export default Vue.extend({
|
||||
name: 'TemplateDetails',
|
||||
props: {
|
||||
|
@ -69,15 +71,20 @@ export default Vue.extend({
|
|||
NodeIcon,
|
||||
TemplateDetailsBlock,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useTemplatesStore,
|
||||
),
|
||||
},
|
||||
methods: {
|
||||
abbreviateNumber,
|
||||
filterTemplateNodes,
|
||||
redirectToCategory(id: string) {
|
||||
this.$store.commit('templates/resetSessionId');
|
||||
this.templatesStore.resetSessionId();
|
||||
this.$router.push(`/templates?categories=${id}`);
|
||||
},
|
||||
redirectToSearchPage(node: ITemplatesNode) {
|
||||
this.$store.commit('templates/resetSessionId');
|
||||
this.templatesStore.resetSessionId();
|
||||
this.$router.push(`/templates?search=${node.displayName}`);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,6 +9,8 @@ import { format, LocaleFunc, register } from 'timeago.js';
|
|||
import { convertToHumanReadableDate } from './helpers';
|
||||
import Vue from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'TimeAgo',
|
||||
|
@ -48,7 +50,12 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultLocale']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
),
|
||||
defaultLocale(): string {
|
||||
return this.rootStore.defaultLocale;
|
||||
},
|
||||
format(): string {
|
||||
const text = format(this.date, this.defaultLocale);
|
||||
|
||||
|
|
|
@ -108,6 +108,11 @@ import NodeIcon from './NodeIcon.vue';
|
|||
import { copyPaste } from './mixins/copyPaste';
|
||||
import { showMessage } from '@/components/mixins/showMessage';
|
||||
import Vue from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
|
||||
export default mixins(workflowHelpers, copyPaste, showMessage).extend({
|
||||
name: 'TriggerPanel',
|
||||
|
@ -125,12 +130,18 @@ export default mixins(workflowHelpers, copyPaste, showMessage).extend({
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNodeTypesStore,
|
||||
useNDVStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
node(): INodeUi | null {
|
||||
return this.$store.getters.getNodeByName(this.nodeName);
|
||||
return this.workflowsStore.getNodeByName(this.nodeName);
|
||||
},
|
||||
nodeType(): INodeTypeDescription | null {
|
||||
if (this.node) {
|
||||
return this.$store.getters['nodeTypes/getNodeType'](this.node.type, this.node.typeVersion);
|
||||
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -195,8 +206,8 @@ export default mixins(workflowHelpers, copyPaste, showMessage).extend({
|
|||
return Boolean(this.nodeType && this.nodeType.polling);
|
||||
},
|
||||
isListeningForEvents(): boolean {
|
||||
const waitingOnWebhook = this.$store.getters.executionWaitingForWebhook as boolean;
|
||||
const executedNode = this.$store.getters.executedNode as string | undefined;
|
||||
const waitingOnWebhook = this.workflowsStore.executionWaitingForWebhook as boolean;
|
||||
const executedNode = this.workflowsStore.executedNode as string | undefined;
|
||||
return (
|
||||
!!this.node &&
|
||||
!this.node.disabled &&
|
||||
|
@ -206,15 +217,15 @@ export default mixins(workflowHelpers, copyPaste, showMessage).extend({
|
|||
);
|
||||
},
|
||||
workflowRunning(): boolean {
|
||||
return this.$store.getters.isActionActive('workflowRunning');
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
isActivelyPolling(): boolean {
|
||||
const triggeredNode = this.$store.getters.executedNode;
|
||||
const triggeredNode = this.workflowsStore.executedNode;
|
||||
|
||||
return this.workflowRunning && this.isPollingNode && this.nodeName === triggeredNode;
|
||||
},
|
||||
isWorkflowActive(): boolean {
|
||||
return this.$store.getters.isActive;
|
||||
return this.workflowsStore.isWorkflowActive;
|
||||
},
|
||||
header(): string {
|
||||
const serviceName = this.nodeType ? getTriggerNodeServiceName(this.nodeType) : '';
|
||||
|
@ -369,15 +380,15 @@ export default mixins(workflowHelpers, copyPaste, showMessage).extend({
|
|||
this.$emit('activate');
|
||||
} else if (target.dataset.key === 'executions') {
|
||||
this.$telemetry.track('User clicked ndv link', {
|
||||
workflow_id: this.$store.getters.workflowId,
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
session_id: this.sessionId,
|
||||
pane: 'input',
|
||||
type: 'open-executions-log',
|
||||
});
|
||||
this.$store.commit('ndv/setActiveNodeName', null);
|
||||
this.$store.dispatch('ui/openModal', EXECUTIONS_MODAL_KEY);
|
||||
this.ndvStore.activeNodeName = null;
|
||||
this.uiStore.openModal(EXECUTIONS_MODAL_KEY);
|
||||
} else if (target.dataset.key === 'settings') {
|
||||
this.$store.dispatch('ui/openModal', WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -64,6 +64,9 @@ import ModalDrawer from './ModalDrawer.vue';
|
|||
import mixins from 'vue-typed-mixins';
|
||||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
import Vue from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
const DEFAULT_TITLE = `How likely are you to recommend n8n to a friend or colleague?`;
|
||||
const GREAT_FEEDBACK_TITLE = `Great to hear! Can we reach out to see how we can make n8n even better for you?`;
|
||||
|
@ -79,12 +82,16 @@ export default mixins(workflowHelpers).extend({
|
|||
isActive(isActive) {
|
||||
if (isActive) {
|
||||
this.$telemetry.track('User shown value survey', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
),
|
||||
getTitle(): string {
|
||||
if (this.form.value !== '') {
|
||||
if (Number(this.form.value) > 7) {
|
||||
|
@ -115,13 +122,13 @@ export default mixins(workflowHelpers).extend({
|
|||
closeDialog(): void {
|
||||
if (this.form.value === '') {
|
||||
this.$telemetry.track('User responded value survey score', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
nps: '',
|
||||
});
|
||||
}
|
||||
if (this.form.value !== '' && this.form.email === '') {
|
||||
this.$telemetry.track('User responded value survey email', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
email: '',
|
||||
});
|
||||
}
|
||||
|
@ -133,31 +140,25 @@ export default mixins(workflowHelpers).extend({
|
|||
this.form.value = value;
|
||||
this.showButtons = false;
|
||||
|
||||
const response: IN8nPromptResponse = await this.$store.dispatch(
|
||||
'settings/submitValueSurvey',
|
||||
{ value: this.form.value },
|
||||
);
|
||||
const response: IN8nPromptResponse | undefined = await this.settingsStore.submitValueSurvey({ value: this.form.value });
|
||||
|
||||
if (response.updated) {
|
||||
if (response && response.updated) {
|
||||
this.$telemetry.track('User responded value survey score', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
nps: this.form.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
async send() {
|
||||
if (this.isEmailValid) {
|
||||
const response: IN8nPromptResponse = await this.$store.dispatch(
|
||||
'settings/submitValueSurvey',
|
||||
{
|
||||
email: this.form.email,
|
||||
value: this.form.value,
|
||||
},
|
||||
);
|
||||
const response: IN8nPromptResponse | undefined = await this.settingsStore.submitValueSurvey({
|
||||
email: this.form.email,
|
||||
value: this.form.value,
|
||||
});
|
||||
|
||||
if (response.updated) {
|
||||
if (response && response.updated) {
|
||||
this.$telemetry.track('User responded value survey email', {
|
||||
instance_id: this.$store.getters.instanceId,
|
||||
instance_id: this.rootStore.instanceId,
|
||||
email: this.form.email,
|
||||
});
|
||||
this.$showMessage({
|
||||
|
|
|
@ -40,6 +40,10 @@ import {
|
|||
import { workflowHelpers } from '@/components/mixins/workflowHelpers';
|
||||
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
import { useNDVStore } from '@/stores/ndv';
|
||||
|
||||
// Node types that should not be displayed in variable selector
|
||||
const SKIPPED_NODE_TYPES = [
|
||||
|
@ -64,6 +68,11 @@ export default mixins(
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useNDVStore,
|
||||
useRootStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
extendAll (): boolean {
|
||||
if (this.variableFilter) {
|
||||
return true;
|
||||
|
@ -406,7 +415,7 @@ export default mixins(
|
|||
const runIndex = 0;
|
||||
const returnData: IVariableSelectorOption[] = [];
|
||||
|
||||
const activeNode: INodeUi | null = this.$store.getters['ndv/activeNode'];
|
||||
const activeNode: INodeUi | null = this.ndvStore.activeNode;
|
||||
|
||||
if (activeNode === null) {
|
||||
return returnData;
|
||||
|
@ -431,7 +440,7 @@ export default mixins(
|
|||
$resumeWebhookUrl: PLACEHOLDER_FILLED_AT_EXECUTION_TIME,
|
||||
};
|
||||
|
||||
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, {}, 'manual', this.$store.getters.timezone, additionalKeys);
|
||||
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, {}, 'manual', this.rootStore.timezone, additionalKeys);
|
||||
const proxy = dataProxy.getDataProxy();
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -486,15 +495,15 @@ export default mixins(
|
|||
getFilterResults (filterText: string, itemIndex: number): IVariableSelectorOption[] {
|
||||
const inputName = 'main';
|
||||
|
||||
const activeNode: INodeUi | null = this.$store.getters['ndv/activeNode'];
|
||||
const activeNode: INodeUi | null = this.ndvStore.activeNode;
|
||||
|
||||
if (activeNode === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const executionData = this.$store.getters.getWorkflowExecution as IExecutionResponse | null;
|
||||
const executionData = this.workflowsStore.getWorkflowExecution;
|
||||
let parentNode = this.workflow.getParentNodes(activeNode.name, inputName, 1);
|
||||
let runData = this.$store.getters.getWorkflowRunData as IRunData | null;
|
||||
let runData = this.workflowsStore.getWorkflowRunData;
|
||||
|
||||
if (runData === null) {
|
||||
runData = {};
|
||||
|
@ -543,7 +552,7 @@ export default mixins(
|
|||
},
|
||||
];
|
||||
parentNode.forEach((parentNodeName) => {
|
||||
const pinData = this.$store.getters['pinDataByNodeName'](parentNodeName);
|
||||
const pinData = this.workflowsStore.pinDataByNodeName(parentNodeName);
|
||||
|
||||
if (pinData) {
|
||||
const output = this.getNodePinDataOutput(parentNodeName, pinData, filterText, true);
|
||||
|
@ -677,7 +686,7 @@ export default mixins(
|
|||
|
||||
if (upstreamNodes.includes(nodeName)) {
|
||||
// If the node is an upstream node add also the output data which can be referenced
|
||||
const pinData = this.$store.getters['pinDataByNodeName'](nodeName);
|
||||
const pinData = this.workflowsStore.pinDataByNodeName(nodeName);
|
||||
tempOutputData = pinData
|
||||
? this.getNodePinDataOutput(nodeName, pinData, filterText)
|
||||
: this.getNodeRunDataOutput(nodeName, runData, filterText, itemIndex);
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
|
||||
import { showMessage } from '@/components/mixins/showMessage';
|
||||
import { workflowActivate } from '@/components/mixins/workflowActivate';
|
||||
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { mapStores } from 'pinia';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
import { getActivatableTriggerNodes } from './helpers';
|
||||
|
||||
export default mixins(
|
||||
|
@ -53,14 +53,18 @@ export default mixins(
|
|||
'workflowId',
|
||||
],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
dirtyState: "getStateIsDirty",
|
||||
}),
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
getStateIsDirty (): boolean {
|
||||
return this.uiStore.stateIsDirty;
|
||||
},
|
||||
nodesIssuesExist (): boolean {
|
||||
return this.$store.getters.nodesIssuesExist;
|
||||
return this.workflowsStore.nodesIssuesExist;
|
||||
},
|
||||
isWorkflowActive (): boolean {
|
||||
const activeWorkflows = this.$store.getters.getActiveWorkflows;
|
||||
const activeWorkflows = this.workflowsStore.activeWorkflows;
|
||||
return activeWorkflows.includes(this.workflowId);
|
||||
},
|
||||
couldNotBeStarted (): boolean {
|
||||
|
@ -73,7 +77,7 @@ export default mixins(
|
|||
return '#13ce66';
|
||||
},
|
||||
isCurrentWorkflow(): boolean {
|
||||
return this.$store.getters['workflowId'] === this.workflowId;
|
||||
return this.workflowsStore.workflowId === this.workflowId;
|
||||
},
|
||||
disabled(): boolean {
|
||||
const isNewWorkflow = !this.workflowId;
|
||||
|
@ -84,7 +88,7 @@ export default mixins(
|
|||
return false;
|
||||
},
|
||||
containsTrigger(): boolean {
|
||||
const foundTriggers = getActivatableTriggerNodes(this.$store.getters.workflowTriggerNodes);
|
||||
const foundTriggers = getActivatableTriggerNodes(this.workflowsStore.workflowTriggerNodes);
|
||||
return foundTriggers.length > 0;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<n8n-text color="text-light" size="small">
|
||||
<span v-show="data">{{$locale.baseText('workflows.item.updated')}} <time-ago :date="data.updatedAt" /> | </span>
|
||||
<span v-show="data" class="mr-2xs">{{$locale.baseText('workflows.item.created')}} {{ formattedCreatedAtDate }} </span>
|
||||
<span v-if="areTagsEnabled && data.tags && data.tags.length > 0" v-show="data">
|
||||
<span v-if="settingsStore.areTagsEnabled && data.tags && data.tags.length > 0" v-show="data">
|
||||
<n8n-tags
|
||||
:tags="data.tags"
|
||||
:truncateAt="3"
|
||||
|
@ -62,6 +62,11 @@ import dateformat from "dateformat";
|
|||
import { restApi } from '@/components/mixins/restApi';
|
||||
import WorkflowActivator from '@/components/WorkflowActivator.vue';
|
||||
import Vue from "vue";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
|
||||
export const WORKFLOW_LIST_ITEM_ACTIONS = {
|
||||
OPEN: 'open',
|
||||
|
@ -103,11 +108,14 @@ export default mixins(
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useUsersStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
currentUser (): IUser {
|
||||
return this.$store.getters['users/currentUser'];
|
||||
},
|
||||
areTagsEnabled(): boolean {
|
||||
return this.$store.getters['settings/areTagsEnabled'];
|
||||
return this.usersStore.currentUser || {} as IUser;
|
||||
},
|
||||
credentialPermissions(): IPermissions {
|
||||
return getWorkflowPermissions(this.currentUser, this.data, this.$store);
|
||||
|
@ -162,7 +170,7 @@ export default mixins(
|
|||
if (action === WORKFLOW_LIST_ITEM_ACTIONS.OPEN) {
|
||||
await this.onClick();
|
||||
} else if (action === WORKFLOW_LIST_ITEM_ACTIONS.DUPLICATE) {
|
||||
await this.$store.dispatch('ui/openModalWithData', {
|
||||
this.uiStore.openModalWithData({
|
||||
name: DUPLICATE_MODAL_KEY,
|
||||
data: {
|
||||
id: this.data.id,
|
||||
|
@ -188,7 +196,7 @@ export default mixins(
|
|||
|
||||
try {
|
||||
await this.restApi().deleteWorkflow(this.data.id);
|
||||
this.$store.commit('deleteWorkflow', this.data.id);
|
||||
this.workflowsStore.deleteWorkflow(this.data.id);
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
|
|
|
@ -220,10 +220,12 @@ import { restApi } from '@/components/mixins/restApi';
|
|||
import { genericHelpers } from '@/components/mixins/genericHelpers';
|
||||
import { showMessage } from '@/components/mixins/showMessage';
|
||||
import {
|
||||
IN8nUISettings,
|
||||
ITimeoutHMS,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowSettings,
|
||||
IWorkflowShortResponse,
|
||||
WorkflowCallerPolicyDefaultOption,
|
||||
} from '@/Interface';
|
||||
import Modal from './Modal.vue';
|
||||
import { PLACEHOLDER_EMPTY_WORKFLOW_ID, WORKFLOW_SETTINGS_MODAL_KEY } from '../constants';
|
||||
|
@ -232,6 +234,10 @@ import mixins from 'vue-typed-mixins';
|
|||
|
||||
import { mapGetters } from "vuex";
|
||||
import { deepCopy } from "n8n-workflow";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useRootStore } from '@/stores/n8nRootStore';
|
||||
|
||||
export default mixins(
|
||||
externalHooks,
|
||||
|
@ -274,8 +280,8 @@ export default mixins(
|
|||
timezones: [] as Array<{ key: string, value: string }>,
|
||||
workflowSettings: {} as IWorkflowSettings,
|
||||
workflows: [] as IWorkflowShortResponse[],
|
||||
executionTimeout: this.$store.getters.executionTimeout,
|
||||
maxExecutionTimeout: this.$store.getters.maxExecutionTimeout,
|
||||
executionTimeout: 0,
|
||||
maxExecutionTimeout: 0,
|
||||
timeoutHMS: { hours: 0, minutes: 0, seconds: 0 } as ITimeoutHMS,
|
||||
modalBus: new Vue(),
|
||||
WORKFLOW_SETTINGS_MODAL_KEY,
|
||||
|
@ -283,13 +289,25 @@ export default mixins(
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['workflowName', 'workflowId']),
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
workflowName(): string {
|
||||
return this.workflowsStore.workflowName;
|
||||
},
|
||||
workflowId(): string {
|
||||
return this.workflowsStore.workflowId;
|
||||
},
|
||||
isWorkflowSharingEnabled(): boolean {
|
||||
return this.$store.getters['settings/isWorkflowSharingEnabled'];
|
||||
return this.settingsStore.isWorkflowSharingEnabled;
|
||||
},
|
||||
},
|
||||
|
||||
async mounted () {
|
||||
this.executionTimeout = this.rootStore.executionTimeout;
|
||||
this.maxExecutionTimeout = this.rootStore.maxExecutionTimeout;
|
||||
|
||||
if (!this.workflowId || this.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
this.$showMessage({
|
||||
title: 'No workflow active',
|
||||
|
@ -301,11 +319,11 @@ export default mixins(
|
|||
return;
|
||||
}
|
||||
|
||||
this.defaultValues.saveDataErrorExecution = this.$store.getters.saveDataErrorExecution;
|
||||
this.defaultValues.saveDataSuccessExecution = this.$store.getters.saveDataSuccessExecution;
|
||||
this.defaultValues.saveManualExecutions = this.$store.getters.saveManualExecutions;
|
||||
this.defaultValues.timezone = this.$store.getters.timezone;
|
||||
this.defaultValues.workflowCallerPolicy = this.$store.getters['settings/workflowCallerPolicyDefaultOption'];
|
||||
this.defaultValues.saveDataErrorExecution = this.settingsStore.saveDataErrorExecution;
|
||||
this.defaultValues.saveDataSuccessExecution = this.settingsStore.saveDataSuccessExecution;
|
||||
this.defaultValues.saveManualExecutions = this.settingsStore.saveManualExecutions;
|
||||
this.defaultValues.timezone = this.rootStore.timezone;
|
||||
this.defaultValues.workflowCallerPolicy = this.settingsStore.workflowCallerPolicyDefaultOption;
|
||||
|
||||
this.isLoading = true;
|
||||
const promises = [];
|
||||
|
@ -323,7 +341,7 @@ export default mixins(
|
|||
this.$showError(error, 'Problem loading settings', 'The following error occurred loading the data:');
|
||||
}
|
||||
|
||||
const workflowSettings = deepCopy(this.$store.getters.workflowSettings);
|
||||
const workflowSettings = deepCopy(this.workflowsStore.workflowSettings) as IWorkflowSettings;
|
||||
|
||||
if (workflowSettings.timezone === undefined) {
|
||||
workflowSettings.timezone = 'DEFAULT';
|
||||
|
@ -338,16 +356,16 @@ export default mixins(
|
|||
workflowSettings.saveExecutionProgress = 'DEFAULT';
|
||||
}
|
||||
if (workflowSettings.saveManualExecutions === undefined) {
|
||||
workflowSettings.saveManualExecutions = 'DEFAULT';
|
||||
workflowSettings.saveManualExecutions = this.defaultValues.saveManualExecutions;
|
||||
}
|
||||
if (workflowSettings.callerPolicy === undefined) {
|
||||
workflowSettings.callerPolicy = this.defaultValues.workflowCallerPolicy;
|
||||
workflowSettings.callerPolicy = this.defaultValues.workflowCallerPolicy as WorkflowCallerPolicyDefaultOption;
|
||||
}
|
||||
if (workflowSettings.executionTimeout === undefined) {
|
||||
workflowSettings.executionTimeout = this.$store.getters.executionTimeout;
|
||||
workflowSettings.executionTimeout = this.rootStore.executionTimeout;
|
||||
}
|
||||
if (workflowSettings.maxExecutionTimeout === undefined) {
|
||||
workflowSettings.maxExecutionTimeout = this.$store.getters.maxExecutionTimeout;
|
||||
workflowSettings.maxExecutionTimeout = this.rootStore.maxExecutionTimeout;
|
||||
}
|
||||
|
||||
Vue.set(this, 'workflowSettings', workflowSettings);
|
||||
|
@ -355,7 +373,7 @@ export default mixins(
|
|||
this.isLoading = false;
|
||||
|
||||
this.$externalHooks().run('workflowSettings.dialogVisibleChanged', { dialogVisible: true });
|
||||
this.$telemetry.track('User opened workflow settings', { workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User opened workflow settings', { workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
methods: {
|
||||
onCallerIdsInput(str: string) {
|
||||
|
@ -589,11 +607,11 @@ export default mixins(
|
|||
delete data.settings!.maxExecutionTimeout;
|
||||
|
||||
this.isLoading = true;
|
||||
data.hash = this.$store.getters.workflowHash;
|
||||
data.hash = this.workflowsStore.workflowHash;
|
||||
|
||||
try {
|
||||
const workflow = await this.restApi().updateWorkflow(this.$route.params.name, data);
|
||||
this.$store.commit('setWorkflowHash', workflow.hash);
|
||||
this.workflowsStore.setWorkflowHash(workflow.hash || '');
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
|
@ -611,9 +629,9 @@ export default mixins(
|
|||
}
|
||||
}
|
||||
|
||||
const oldSettings = deepCopy(this.$store.getters.workflowSettings);
|
||||
const oldSettings = deepCopy(this.workflowsStore.workflowSettings);
|
||||
|
||||
this.$store.commit('setWorkflowSettings', localWorkflowSettings);
|
||||
this.workflowsStore.setWorkflowSettings(localWorkflowSettings);
|
||||
|
||||
this.isLoading = false;
|
||||
|
||||
|
@ -625,7 +643,7 @@ export default mixins(
|
|||
this.closeDialog();
|
||||
|
||||
this.$externalHooks().run('workflowSettings.saveSettings', { oldSettings });
|
||||
this.$telemetry.track('User updated workflow settings', { workflow_id: this.$store.getters.workflowId });
|
||||
this.$telemetry.track('User updated workflow settings', { workflow_id: this.workflowsStore.workflowId });
|
||||
},
|
||||
toggleTimeout() {
|
||||
this.workflowSettings.executionTimeout = this.workflowSettings.executionTimeout === -1 ? 0 : -1;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
/>
|
||||
<n8n-user-select
|
||||
:users="ownedByUsers"
|
||||
:currentUserId="currentUser.id"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:value="value.ownedBy"
|
||||
size="small"
|
||||
@input="setKeyValue('ownedBy', $event)"
|
||||
|
@ -48,7 +48,7 @@
|
|||
/>
|
||||
<n8n-user-select
|
||||
:users="sharedWithUsers"
|
||||
:currentUserId="currentUser.id"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:value="value.sharedWith"
|
||||
size="small"
|
||||
@input="setKeyValue('sharedWith', $event)"
|
||||
|
@ -66,8 +66,9 @@
|
|||
<script lang="ts">
|
||||
import Vue, { PropType } from 'vue';
|
||||
import {EnterpriseEditionFeature} from "@/constants";
|
||||
import {IResource} from "@/components/layouts/ResourcesListLayout.vue";
|
||||
import {IUser} from "@/Interface";
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUsersStore } from '@/stores/users';
|
||||
|
||||
export type IResourceFiltersType = Record<string, boolean | string | string[]>;
|
||||
|
||||
|
@ -95,17 +96,12 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
currentUser(): IUser {
|
||||
return this.$store.getters['users/currentUser'];
|
||||
},
|
||||
allUsers(): IUser[] {
|
||||
return this.$store.getters['users/allUsers'];
|
||||
},
|
||||
...mapStores(useUsersStore),
|
||||
ownedByUsers(): IUser[] {
|
||||
return this.allUsers.map((user) => user.id === this.value.sharedWith ? { ...user, disabled: true } : user);
|
||||
return this.usersStore.allUsers.map((user) => user.id === this.value.sharedWith ? { ...user, disabled: true } : user);
|
||||
},
|
||||
sharedWithUsers(): IUser[] {
|
||||
return this.allUsers.map((user) => user.id === this.value.ownedBy ? { ...user, disabled: true } : user);
|
||||
return this.usersStore.allUsers.map((user) => user.id === this.value.ownedBy ? { ...user, disabled: true } : user);
|
||||
},
|
||||
filtersLength(): number {
|
||||
let length = 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="[$style.wrapper, !sidebarMenuCollapsed && $style.expandedSidebar]">
|
||||
<div :class="[$style.wrapper, !this.uiStore.sidebarMenuCollapsed && $style.expandedSidebar]">
|
||||
<div :class="$style.container">
|
||||
<aside :class="$style.aside" v-if="$slots.aside">
|
||||
<slot name="aside" />
|
||||
|
@ -12,6 +12,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useUIStore } from '@/stores/ui';
|
||||
import { mapStores } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -22,9 +24,7 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
sidebarMenuCollapsed(): boolean {
|
||||
return this.$store.getters['ui/sidebarMenuCollapsed'];
|
||||
},
|
||||
...mapStores(useUIStore),
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue