mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Fix type errors in NodeCredentials (no-changelog) (#9567)
This commit is contained in:
parent
3745313064
commit
c1b1ee57b1
|
@ -10,7 +10,6 @@
|
||||||
<n8n-input-label
|
<n8n-input-label
|
||||||
:label="getCredentialsFieldLabel(credentialTypeDescription)"
|
:label="getCredentialsFieldLabel(credentialTypeDescription)"
|
||||||
:bold="false"
|
:bold="false"
|
||||||
:set="(issues = getIssues(credentialTypeDescription.name))"
|
|
||||||
size="small"
|
size="small"
|
||||||
color="text-dark"
|
color="text-dark"
|
||||||
data-test-id="credentials-label"
|
data-test-id="credentials-label"
|
||||||
|
@ -25,15 +24,24 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
:class="issues.length && !hideIssues ? $style.hasIssues : $style.input"
|
:class="
|
||||||
|
getIssues(credentialTypeDescription.name).length && !hideIssues
|
||||||
|
? $style.hasIssues
|
||||||
|
: $style.input
|
||||||
|
"
|
||||||
data-test-id="node-credentials-select"
|
data-test-id="node-credentials-select"
|
||||||
>
|
>
|
||||||
<n8n-select
|
<n8n-select
|
||||||
:model-value="getSelectedId(credentialTypeDescription.name)"
|
:model-value="getSelectedId(credentialTypeDescription.name)"
|
||||||
:placeholder="getSelectPlaceholder(credentialTypeDescription.name, issues)"
|
:placeholder="
|
||||||
|
getSelectPlaceholder(
|
||||||
|
credentialTypeDescription.name,
|
||||||
|
getIssues(credentialTypeDescription.name),
|
||||||
|
)
|
||||||
|
"
|
||||||
size="small"
|
size="small"
|
||||||
@update:model-value="
|
@update:model-value="
|
||||||
(value) =>
|
(value: string) =>
|
||||||
onCredentialSelected(
|
onCredentialSelected(
|
||||||
credentialTypeDescription.name,
|
credentialTypeDescription.name,
|
||||||
value,
|
value,
|
||||||
|
@ -65,12 +73,15 @@
|
||||||
</n8n-option>
|
</n8n-option>
|
||||||
</n8n-select>
|
</n8n-select>
|
||||||
|
|
||||||
<div v-if="issues.length && !hideIssues" :class="$style.warning">
|
<div
|
||||||
|
v-if="getIssues(credentialTypeDescription.name).length && !hideIssues"
|
||||||
|
:class="$style.warning"
|
||||||
|
>
|
||||||
<n8n-tooltip placement="top">
|
<n8n-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
<TitledList
|
<TitledList
|
||||||
:title="`${$locale.baseText('nodeCredentials.issues')}:`"
|
:title="`${$locale.baseText('nodeCredentials.issues')}:`"
|
||||||
:items="issues"
|
:items="getIssues(credentialTypeDescription.name)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<font-awesome-icon icon="exclamation-triangle" />
|
<font-awesome-icon icon="exclamation-triangle" />
|
||||||
|
@ -109,7 +120,6 @@ import type {
|
||||||
IUser,
|
IUser,
|
||||||
} from '@/Interface';
|
} from '@/Interface';
|
||||||
import type {
|
import type {
|
||||||
ICredentialType,
|
|
||||||
INodeCredentialDescription,
|
INodeCredentialDescription,
|
||||||
INodeCredentialsDetails,
|
INodeCredentialsDetails,
|
||||||
INodeParameters,
|
INodeParameters,
|
||||||
|
@ -136,6 +146,7 @@ import {
|
||||||
updateNodeAuthType,
|
updateNodeAuthType,
|
||||||
isRequiredCredential,
|
isRequiredCredential,
|
||||||
} from '@/utils/nodeTypesUtils';
|
} from '@/utils/nodeTypesUtils';
|
||||||
|
import { assert } from '@/utils/assert';
|
||||||
|
|
||||||
interface CredentialDropdownOption extends ICredentialsResponse {
|
interface CredentialDropdownOption extends ICredentialsResponse {
|
||||||
typeDisplayName: string;
|
typeDisplayName: string;
|
||||||
|
@ -157,6 +168,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
overrideCredType: {
|
overrideCredType: {
|
||||||
type: String,
|
type: String,
|
||||||
|
default: '',
|
||||||
},
|
},
|
||||||
showAll: {
|
showAll: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -167,6 +179,7 @@ export default defineComponent({
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
emits: { credentialSelected: null, valueChanged: null, blur: null },
|
||||||
setup() {
|
setup() {
|
||||||
const nodeHelpers = useNodeHelpers();
|
const nodeHelpers = useNodeHelpers();
|
||||||
|
|
||||||
|
@ -182,6 +195,60 @@ export default defineComponent({
|
||||||
listeningForAuthChange: false,
|
listeningForAuthChange: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(
|
||||||
|
useCredentialsStore,
|
||||||
|
useNodeTypesStore,
|
||||||
|
useNDVStore,
|
||||||
|
useUIStore,
|
||||||
|
useUsersStore,
|
||||||
|
useWorkflowsStore,
|
||||||
|
),
|
||||||
|
currentUser(): IUser {
|
||||||
|
return this.usersStore.currentUser ?? ({} as IUser);
|
||||||
|
},
|
||||||
|
credentialTypesNode(): string[] {
|
||||||
|
return this.credentialTypesNodeDescription.map(
|
||||||
|
(credentialTypeDescription) => credentialTypeDescription.name,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
credentialTypesNodeDescriptionDisplayed(): INodeCredentialDescription[] {
|
||||||
|
return this.credentialTypesNodeDescription.filter((credentialTypeDescription) => {
|
||||||
|
return this.displayCredentials(credentialTypeDescription);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
credentialTypesNodeDescription(): INodeCredentialDescription[] {
|
||||||
|
const credType = this.credentialsStore.getCredentialTypeByName(this.overrideCredType);
|
||||||
|
|
||||||
|
if (credType) return [credType];
|
||||||
|
|
||||||
|
const activeNodeType = this.nodeType;
|
||||||
|
if (activeNodeType?.credentials) {
|
||||||
|
return activeNodeType.credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
credentialTypeNames() {
|
||||||
|
const returnData: Record<string, string> = {};
|
||||||
|
for (const credentialTypeName of this.credentialTypesNode) {
|
||||||
|
const credentialType = this.credentialsStore.getCredentialTypeByName(credentialTypeName);
|
||||||
|
returnData[credentialTypeName] = credentialType
|
||||||
|
? credentialType.displayName
|
||||||
|
: credentialTypeName;
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
selected(): Record<string, INodeCredentialsDetails> {
|
||||||
|
return this.node.credentials ?? {};
|
||||||
|
},
|
||||||
|
nodeType(): INodeTypeDescription | null {
|
||||||
|
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
||||||
|
},
|
||||||
|
mainNodeAuthField(): INodeProperties | null {
|
||||||
|
return getMainAuthField(this.nodeType);
|
||||||
|
},
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'node.parameters': {
|
'node.parameters': {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
@ -197,10 +264,9 @@ export default defineComponent({
|
||||||
const newAuth = newValue[this.mainNodeAuthField.name];
|
const newAuth = newValue[this.mainNodeAuthField.name];
|
||||||
|
|
||||||
if (newAuth) {
|
if (newAuth) {
|
||||||
const credentialType = getNodeCredentialForSelectedAuthType(
|
const authType =
|
||||||
nodeType,
|
typeof newAuth === 'object' ? JSON.stringify(newAuth) : newAuth.toString();
|
||||||
newAuth.toString(),
|
const credentialType = getNodeCredentialForSelectedAuthType(nodeType, authType);
|
||||||
);
|
|
||||||
if (credentialType) {
|
if (credentialType) {
|
||||||
this.subscribedToCredentialType = credentialType.name;
|
this.subscribedToCredentialType = credentialType.name;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +278,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// Listen for credentials store changes so credential selection can be updated if creds are changed from the modal
|
// Listen for credentials store changes so credential selection can be updated if creds are changed from the modal
|
||||||
this.credentialsStore.$onAction(({ name, after, store, args }) => {
|
this.credentialsStore.$onAction(({ name, after, args }) => {
|
||||||
const listeningForActions = ['createNewCredential', 'updateCredential', 'deleteCredential'];
|
const listeningForActions = ['createNewCredential', 'updateCredential', 'deleteCredential'];
|
||||||
const credentialType = this.subscribedToCredentialType;
|
const credentialType = this.subscribedToCredentialType;
|
||||||
if (!credentialType) {
|
if (!credentialType) {
|
||||||
|
@ -269,68 +335,10 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
...mapStores(
|
|
||||||
useCredentialsStore,
|
|
||||||
useNodeTypesStore,
|
|
||||||
useNDVStore,
|
|
||||||
useUIStore,
|
|
||||||
useUsersStore,
|
|
||||||
useWorkflowsStore,
|
|
||||||
),
|
|
||||||
currentUser(): IUser {
|
|
||||||
return this.usersStore.currentUser || ({} as IUser);
|
|
||||||
},
|
|
||||||
credentialTypesNode(): string[] {
|
|
||||||
return this.credentialTypesNodeDescription.map(
|
|
||||||
(credentialTypeDescription) => credentialTypeDescription.name,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
credentialTypesNodeDescriptionDisplayed(): INodeCredentialDescription[] {
|
|
||||||
return this.credentialTypesNodeDescription.filter((credentialTypeDescription) => {
|
|
||||||
return this.displayCredentials(credentialTypeDescription);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
credentialTypesNodeDescription(): INodeCredentialDescription[] {
|
|
||||||
const credType = this.credentialsStore.getCredentialTypeByName(this.overrideCredType);
|
|
||||||
|
|
||||||
if (credType) return [credType];
|
|
||||||
|
|
||||||
const activeNodeType = this.nodeType;
|
|
||||||
if (activeNodeType?.credentials) {
|
|
||||||
return activeNodeType.credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
credentialTypeNames() {
|
|
||||||
const returnData: {
|
|
||||||
[key: string]: string;
|
|
||||||
} = {};
|
|
||||||
let credentialType: ICredentialType | undefined;
|
|
||||||
for (const credentialTypeName of this.credentialTypesNode) {
|
|
||||||
credentialType = this.credentialsStore.getCredentialTypeByName(credentialTypeName);
|
|
||||||
returnData[credentialTypeName] = credentialType
|
|
||||||
? credentialType.displayName
|
|
||||||
: credentialTypeName;
|
|
||||||
}
|
|
||||||
return returnData;
|
|
||||||
},
|
|
||||||
selected(): { [type: string]: INodeCredentialsDetails } {
|
|
||||||
return this.node.credentials || {};
|
|
||||||
},
|
|
||||||
nodeType(): INodeTypeDescription | null {
|
|
||||||
return this.nodeTypesStore.getNodeType(this.node.type, this.node.typeVersion);
|
|
||||||
},
|
|
||||||
mainNodeAuthField(): INodeProperties | null {
|
|
||||||
return getMainAuthField(this.nodeType);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getAllRelatedCredentialTypes(credentialType: INodeCredentialDescription): string[] {
|
getAllRelatedCredentialTypes(credentialType: INodeCredentialDescription): string[] {
|
||||||
const isRequiredCredential = this.showMixedCredentials(credentialType);
|
const credentialIsRequired = this.showMixedCredentials(credentialType);
|
||||||
if (isRequiredCredential) {
|
if (credentialIsRequired) {
|
||||||
if (this.mainNodeAuthField) {
|
if (this.mainNodeAuthField) {
|
||||||
const credentials = getAllNodeCredentialForAuthType(
|
const credentials = getAllNodeCredentialForAuthType(
|
||||||
this.nodeType,
|
this.nodeType,
|
||||||
|
@ -401,6 +409,7 @@ export default defineComponent({
|
||||||
name: this.node.name,
|
name: this.node.name,
|
||||||
properties: {
|
properties: {
|
||||||
credentials,
|
credentials,
|
||||||
|
position: this.node.position,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -439,16 +448,14 @@ export default defineComponent({
|
||||||
|
|
||||||
const selectedCredentials = this.credentialsStore.getCredentialById(credentialId);
|
const selectedCredentials = this.credentialsStore.getCredentialById(credentialId);
|
||||||
const selectedCredentialsType = this.showAll ? selectedCredentials.type : credentialType;
|
const selectedCredentialsType = this.showAll ? selectedCredentials.type : credentialType;
|
||||||
const oldCredentials = this.node.credentials?.[selectedCredentialsType]
|
const oldCredentials = this.node.credentials?.[selectedCredentialsType] ?? null;
|
||||||
? this.node.credentials[selectedCredentialsType]
|
|
||||||
: {};
|
|
||||||
|
|
||||||
const selected = { id: selectedCredentials.id, name: selectedCredentials.name };
|
const selected = { id: selectedCredentials.id, name: selectedCredentials.name };
|
||||||
|
|
||||||
// if credentials has been string or neither id matched nor name matched uniquely
|
// if credentials has been string or neither id matched nor name matched uniquely
|
||||||
if (
|
if (
|
||||||
oldCredentials.id === null ||
|
oldCredentials?.id === null ||
|
||||||
(oldCredentials.id &&
|
(oldCredentials?.id &&
|
||||||
!this.credentialsStore.getCredentialByIdAndType(
|
!this.credentialsStore.getCredentialByIdAndType(
|
||||||
oldCredentials.id,
|
oldCredentials.id,
|
||||||
selectedCredentialsType,
|
selectedCredentialsType,
|
||||||
|
@ -492,7 +499,7 @@ export default defineComponent({
|
||||||
const node: INodeUi = this.node;
|
const node: INodeUi = this.node;
|
||||||
|
|
||||||
const credentials = {
|
const credentials = {
|
||||||
...(node.credentials || {}),
|
...(node.credentials ?? {}),
|
||||||
[selectedCredentialsType]: selected,
|
[selectedCredentialsType]: selected,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -500,6 +507,7 @@ export default defineComponent({
|
||||||
name: this.node.name,
|
name: this.node.name,
|
||||||
properties: {
|
properties: {
|
||||||
credentials,
|
credentials,
|
||||||
|
position: this.node.position,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -543,8 +551,10 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
editCredential(credentialType: string): void {
|
editCredential(credentialType: string): void {
|
||||||
const { id } = this.node.credentials[credentialType];
|
const credential = this.node.credentials?.[credentialType];
|
||||||
this.uiStore.openExistingCredential(id);
|
assert(credential?.id);
|
||||||
|
|
||||||
|
this.uiStore.openExistingCredential(credential.id);
|
||||||
|
|
||||||
this.$telemetry.track('User opened Credential modal', {
|
this.$telemetry.track('User opened Credential modal', {
|
||||||
credential_type: credentialType,
|
credential_type: credentialType,
|
||||||
|
|
Loading…
Reference in a new issue