fix(editor): Fix most ts errors in credential components (no-changelog) (#9576)

This commit is contained in:
Tomi Turtiainen 2024-06-03 11:28:41 +03:00 committed by GitHub
parent 379e2da547
commit 0e10c84efd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 51 deletions

View file

@ -118,6 +118,9 @@ declare global {
} }
} }
/** String that represents a timestamp in the ISO8601 format, i.e. YYYY-MM-DDTHH:MM:SS.sssZ */
export type Iso8601String = string;
export type EndpointStyle = { export type EndpointStyle = {
width?: number; width?: number;
height?: number; height?: number;
@ -351,8 +354,8 @@ export interface IShareWorkflowsPayload {
export interface ICredentialsResponse extends ICredentialsEncrypted { export interface ICredentialsResponse extends ICredentialsEncrypted {
id: string; id: string;
createdAt: number | string; createdAt: Iso8601String;
updatedAt: number | string; updatedAt: Iso8601String;
sharedWithProjects?: ProjectSharingData[]; sharedWithProjects?: ProjectSharingData[];
homeProject?: ProjectSharingData; homeProject?: ProjectSharingData;
currentUserHasAccess?: boolean; currentUserHasAccess?: boolean;
@ -361,8 +364,8 @@ export interface ICredentialsResponse extends ICredentialsEncrypted {
} }
export interface ICredentialsBase { export interface ICredentialsBase {
createdAt: number | string; createdAt: Iso8601String;
updatedAt: number | string; updatedAt: Iso8601String;
} }
export interface ICredentialsDecryptedResponse extends ICredentialsBase, ICredentialsDecrypted { export interface ICredentialsDecryptedResponse extends ICredentialsBase, ICredentialsDecrypted {

View file

@ -70,7 +70,6 @@ export default defineComponent({
updatedAt: '', updatedAt: '',
type: '', type: '',
name: '', name: '',
nodesAccess: [],
sharedWithProjects: [], sharedWithProjects: [],
homeProject: {} as ProjectSharingData, homeProject: {} as ProjectSharingData,
}), }),
@ -118,7 +117,7 @@ export default defineComponent({
); );
}, },
formattedCreatedAtDate(): string { formattedCreatedAtDate(): string {
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear().toString();
return dateformat( return dateformat(
this.data.createdAt, this.data.createdAt,
@ -128,10 +127,9 @@ export default defineComponent({
}, },
methods: { methods: {
async onClick(event: Event) { async onClick(event: Event) {
if ( const cardActionsEl = this.$refs.cardActions as HTMLDivElement | undefined;
this.$refs.cardActions === event.target || const clickTarget = event.target as HTMLElement | null;
this.$refs.cardActions?.contains(event.target) if (cardActionsEl === clickTarget || (clickTarget && cardActionsEl?.contains(clickTarget))) {
) {
return; return;
} }

View file

@ -115,8 +115,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { defineComponent, type PropType } from 'vue';
import type { ICredentialsResponse, IUser } from '@/Interface'; import type { ICredentialsResponse, IUser } from '@/Interface';
@ -158,6 +158,7 @@ import { useNDVStore } from '@/stores/ndv.store';
import { useCredentialsStore } from '@/stores/credentials.store'; import { useCredentialsStore } from '@/stores/credentials.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store'; import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import type { ProjectSharingData } from '@/features/projects/projects.types'; import type { ProjectSharingData } from '@/features/projects/projects.types';
import { assert } from '@/utils/assert';
import { import {
getNodeAuthOptions, getNodeAuthOptions,
@ -190,9 +191,11 @@ export default defineComponent({
activeId: { activeId: {
type: [String, Number], type: [String, Number],
required: false, required: false,
default: undefined,
}, },
mode: { mode: {
type: String, type: String as PropType<'new' | 'edit'>,
default: 'new',
}, },
}, },
setup() { setup() {
@ -380,13 +383,14 @@ export default defineComponent({
return []; return [];
} }
const properties = this.credentialType.properties.filter((propertyData: INodeProperties) => { const credentialType = this.credentialType;
const properties = credentialType.properties.filter((propertyData: INodeProperties) => {
if (!this.displayCredentialParameter(propertyData)) { if (!this.displayCredentialParameter(propertyData)) {
return false; return false;
} }
return ( return (
!this.credentialType!.__overwrittenProperties || !credentialType.__overwrittenProperties ||
!this.credentialType!.__overwrittenProperties.includes(propertyData.name) !credentialType.__overwrittenProperties.includes(propertyData.name)
); );
}); });
@ -407,16 +411,17 @@ export default defineComponent({
continue; continue;
} }
if (property.type === 'string' && !this.credentialData[property.name]) { const credentialProperty = this.credentialData[property.name];
if (property.type === 'string' && !credentialProperty) {
return false; return false;
} }
if (property.type === 'number') { if (property.type === 'number') {
const isExpression = const containsExpression =
typeof this.credentialData[property.name] === 'string' && typeof credentialProperty === 'string' && credentialProperty.startsWith('=');
this.credentialData[property.name].startsWith('=');
if (typeof this.credentialData[property.name] !== 'number' && !isExpression) { if (typeof credentialProperty !== 'number' && !containsExpression) {
return false; return false;
} }
} }
@ -463,7 +468,7 @@ export default defineComponent({
credentialTypeName = this.activeNodeType.credentials[0].name; credentialTypeName = this.activeNodeType.credentials[0].name;
} }
} }
return credentialTypeName || ''; return credentialTypeName ?? '';
}, },
showSaveButton(): boolean { showSaveButton(): boolean {
return ( return (
@ -757,7 +762,7 @@ export default defineComponent({
}, },
async retestCredential() { async retestCredential() {
if (!this.isCredentialTestable) { if (!this.isCredentialTestable || !this.credentialTypeName) {
this.authError = ''; this.authError = '';
this.testedSuccessfully = false; this.testedSuccessfully = false;
@ -768,7 +773,7 @@ export default defineComponent({
const details: ICredentialsDecrypted = { const details: ICredentialsDecrypted = {
id: this.credentialId, id: this.credentialId,
name: this.credentialName, name: this.credentialName,
type: this.credentialTypeName!, type: this.credentialTypeName,
data: credentialData, data: credentialData,
}; };
@ -801,20 +806,21 @@ export default defineComponent({
this.isSaving = true; this.isSaving = true;
// Save only the none default data // Save only the none default data
assert(this.credentialType);
const data = NodeHelpers.getNodeParameters( const data = NodeHelpers.getNodeParameters(
this.credentialType!.properties, this.credentialType.properties,
this.credentialData as INodeParameters, this.credentialData as INodeParameters,
false, false,
false, false,
null, null,
); );
assert(this.credentialTypeName);
const credentialDetails: ICredentialsDecrypted = { const credentialDetails: ICredentialsDecrypted = {
id: this.credentialId, id: this.credentialId,
name: this.credentialName, name: this.credentialName,
type: this.credentialTypeName!, type: this.credentialTypeName,
data: data as unknown as ICredentialDataDecryptedObject, data: data as unknown as ICredentialDataDecryptedObject,
nodesAccess: [],
}; };
if ( if (
@ -825,7 +831,7 @@ export default defineComponent({
.sharedWithProjects as ProjectSharingData[]; .sharedWithProjects as ProjectSharingData[];
} }
let credential; let credential: ICredentialsResponse | null = null;
const isNewCredential = this.mode === 'new' && !this.credentialId; const isNewCredential = this.mode === 'new' && !this.credentialId;
@ -954,7 +960,7 @@ export default defineComponent({
async updateCredential( async updateCredential(
credentialDetails: ICredentialsDecrypted, credentialDetails: ICredentialsDecrypted,
): Promise<ICredentialsResponse | null> { ): Promise<ICredentialsResponse | null> {
let credential; let credential: ICredentialsResponse | null = null;
try { try {
if (this.credentialPermissions.update) { if (this.credentialPermissions.update) {
credential = await this.credentialsStore.updateCredential({ credential = await this.credentialsStore.updateCredential({
@ -974,6 +980,14 @@ export default defineComponent({
this.isSharedWithChanged = false; this.isSharedWithChanged = false;
} }
this.hasUnsavedChanges = false; this.hasUnsavedChanges = false;
if (credential) {
await this.externalHooks.run('credential.saved', {
credential_type: credentialDetails.type,
credential_id: credential.id,
is_new: false,
});
}
} catch (error) { } catch (error) {
this.showError( this.showError(
error, error,
@ -983,12 +997,6 @@ export default defineComponent({
return null; return null;
} }
await this.externalHooks.run('credential.saved', {
credential_type: credentialDetails.type,
credential_id: credential.id,
is_new: false,
});
// Now that the credentials changed check if any nodes use credentials // Now that the credentials changed check if any nodes use credentials
// which have now a different name // which have now a different name
this.nodeHelpers.updateNodesCredentialsIssues(); this.nodeHelpers.updateNodesCredentialsIssues();

View file

@ -105,8 +105,8 @@ export default defineComponent({
}, },
props: { props: {
credential: { credential: {
type: Object as PropType<ICredentialsResponse>, type: Object as PropType<ICredentialsResponse | null>,
required: true, default: null,
}, },
credentialId: { credentialId: {
type: String, type: String,
@ -162,7 +162,7 @@ export default defineComponent({
return this.credentialsStore.getCredentialOwnerNameById(`${this.credentialId}`); return this.credentialsStore.getCredentialOwnerNameById(`${this.credentialId}`);
}, },
isCredentialSharedWithCurrentUser(): boolean { isCredentialSharedWithCurrentUser(): boolean {
return (this.credentialData.sharedWithProjects || []).some((sharee: IUser) => { return (this.credentialData.sharedWithProjects ?? []).some((sharee: IUser) => {
return sharee.id === this.usersStore.currentUser?.id; return sharee.id === this.usersStore.currentUser?.id;
}); });
}, },

View file

@ -11,7 +11,7 @@ describe('OauthButton', () => {
test.each([ test.each([
['GoogleAuthButton', true], ['GoogleAuthButton', true],
['n8n-button', false], ['n8n-button', false],
])('should emit click event only once when %s is clicked', async (name, isGoogleOAuthType) => { ])('should emit click event only once when %s is clicked', async (_, isGoogleOAuthType) => {
const { emitted, getByRole } = renderComponent({ const { emitted, getByRole } = renderComponent({
props: { isGoogleOAuthType }, props: { isGoogleOAuthType },
}); });

View file

@ -6,13 +6,11 @@
:size="inputSize" :size="inputSize"
filterable filterable
:model-value="displayValue" :model-value="displayValue"
:placeholder=" :placeholder="$locale.baseText('parameterInput.select')"
parameter.placeholder ? getPlaceholder() : $locale.baseText('parameterInput.select')
"
:title="displayTitle" :title="displayTitle"
:disabled="isReadOnly" :disabled="isReadOnly"
data-test-id="credential-select" data-test-id="credential-select"
@update:model-value="(value) => $emit('update:modelValue', value)" @update:model-value="(value: string) => $emit('update:modelValue', value)"
@keydown.stop @keydown.stop
@focus="$emit('setFocus')" @focus="$emit('setFocus')"
@blur="$emit('onBlur')" @blur="$emit('onBlur')"
@ -28,11 +26,6 @@
<div class="option-headline"> <div class="option-headline">
{{ credType.displayName }} {{ credType.displayName }}
</div> </div>
<div
v-if="credType.description"
class="option-description"
v-html="credType.description"
/>
</div> </div>
</n8n-option> </n8n-option>
</n8n-select> </n8n-select>
@ -62,9 +55,6 @@ import ScopesNotice from '@/components/ScopesNotice.vue';
import NodeCredentials from '@/components/NodeCredentials.vue'; import NodeCredentials from '@/components/NodeCredentials.vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useCredentialsStore } from '@/stores/credentials.store'; import { useCredentialsStore } from '@/stores/credentials.store';
import type { N8nSelect } from 'n8n-design-system';
type N8nSelectRef = InstanceType<typeof N8nSelect>;
export default defineComponent({ export default defineComponent({
name: 'CredentialsSelect', name: 'CredentialsSelect',
@ -81,6 +71,7 @@ export default defineComponent({
'isReadOnly', 'isReadOnly',
'displayTitle', 'displayTitle',
], ],
emits: ['update:modelValue', 'setFocus', 'onBlur', 'credentialSelected'],
computed: { computed: {
...mapStores(useCredentialsStore), ...mapStores(useCredentialsStore),
allCredentialTypes(): ICredentialType[] { allCredentialTypes(): ICredentialType[] {
@ -97,7 +88,7 @@ export default defineComponent({
}, },
methods: { methods: {
focus() { focus() {
const selectRef = this.$refs.innerSelect as N8nSelectRef | undefined; const selectRef = this.$refs.innerSelect as HTMLElement | undefined;
if (selectRef) { if (selectRef) {
selectRef.focus(); selectRef.focus();
} }