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:
Milorad FIlipović
2022-11-04 14:04:31 +01:00
committed by GitHub
parent c2c7927414
commit 40e413d958
160 changed files with 5141 additions and 4378 deletions

View File

@@ -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,
});
},
},

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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;
},
},
});