From e4a6eec3c59c946db89114fdad145df407415bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Wed, 13 Apr 2022 13:52:09 +0200 Subject: [PATCH 01/10] :blue_book: Type `baseText()` to i18n keys --- packages/editor-ui/src/plugins/i18n/index.ts | 22 ++++++++++++++++--- .../editor-ui/src/plugins/i18n/types.d.ts | 7 ------ packages/editor-ui/tsconfig.json | 1 + 3 files changed, 20 insertions(+), 10 deletions(-) delete mode 100644 packages/editor-ui/src/plugins/i18n/types.d.ts diff --git a/packages/editor-ui/src/plugins/i18n/index.ts b/packages/editor-ui/src/plugins/i18n/index.ts index 89e064c8309fd..54c6108e37c54 100644 --- a/packages/editor-ui/src/plugins/i18n/index.ts +++ b/packages/editor-ui/src/plugins/i18n/index.ts @@ -14,7 +14,7 @@ import { locale, } from 'n8n-design-system'; -const englishBaseText = require('./locales/en'); +import englishBaseText from './locales/en.json'; Vue.use(VueI18n); locale.use('en'); @@ -62,8 +62,8 @@ export class I18nClass { * Render a string of base text, i.e. a string with a fixed path to the localized value. Optionally allows for [interpolation](https://kazupon.github.io/vue-i18n/guide/formatting.html#named-formatting) when the localized value contains a string between curly braces. */ baseText( - key: string, - options?: { adjustToNumber: number; interpolate: { [key: string]: string } }, + key: BaseTextKey, + options?: { adjustToNumber?: number; interpolate: { [key: string]: string } }, ): string { if (options && options.adjustToNumber) { return this.i18n.tc(key, options.adjustToNumber, options && options.interpolate).toString(); @@ -469,3 +469,19 @@ export function addHeaders( Object.assign(i18nInstance.messages[language], { headers }), ); } + +// ---------------------------------- +// typings +// ---------------------------------- + +declare module 'vue/types/vue' { + interface Vue { + $locale: I18nClass; + } +} + +type NonArgumentKey = 'reusableBaseText' | 'reusableDynamicText'; + +type GetBaseTextKey = keyof T extends `${NonArgumentKey}.${string}` ? never : keyof T; + +type BaseTextKey = GetBaseTextKey diff --git a/packages/editor-ui/src/plugins/i18n/types.d.ts b/packages/editor-ui/src/plugins/i18n/types.d.ts deleted file mode 100644 index 27f10d50380a7..0000000000000 --- a/packages/editor-ui/src/plugins/i18n/types.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { i18nClass } from '.'; - -declare module 'vue/types/vue' { - interface Vue { - $locale: I18nClass; - } -} \ No newline at end of file diff --git a/packages/editor-ui/tsconfig.json b/packages/editor-ui/tsconfig.json index 8e6dc8f622821..ce5055c3310d3 100644 --- a/packages/editor-ui/tsconfig.json +++ b/packages/editor-ui/tsconfig.json @@ -13,6 +13,7 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "useUnknownInCatchVariables": false, + "resolveJsonModule": true, "sourceMap": true, "baseUrl": ".", "types": [ From 55f174bfa1c187ace42fefd306e0b3ab9173ac06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Wed, 13 Apr 2022 14:16:37 +0200 Subject: [PATCH 02/10] :blue_book: Adjust `baseText()` signature --- packages/editor-ui/src/plugins/i18n/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor-ui/src/plugins/i18n/index.ts b/packages/editor-ui/src/plugins/i18n/index.ts index 54c6108e37c54..f90c534ada124 100644 --- a/packages/editor-ui/src/plugins/i18n/index.ts +++ b/packages/editor-ui/src/plugins/i18n/index.ts @@ -63,7 +63,7 @@ export class I18nClass { */ baseText( key: BaseTextKey, - options?: { adjustToNumber?: number; interpolate: { [key: string]: string } }, + options?: { adjustToNumber?: number; interpolate?: { [key: string]: string } }, ): string { if (options && options.adjustToNumber) { return this.i18n.tc(key, options.adjustToNumber, options && options.interpolate).toString(); @@ -484,4 +484,4 @@ type NonArgumentKey = 'reusableBaseText' | 'reusableDynamicText'; type GetBaseTextKey = keyof T extends `${NonArgumentKey}.${string}` ? never : keyof T; -type BaseTextKey = GetBaseTextKey +export type BaseTextKey = GetBaseTextKey; From a0c4acda3baffe0da8f82ab0e5a1e980d33382a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Wed, 13 Apr 2022 14:17:06 +0200 Subject: [PATCH 03/10] :shirt: Except JSON files from Vue ESLint --- packages/editor-ui/tslint.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/editor-ui/tslint.json b/packages/editor-ui/tslint.json index 2fda8666d2480..fd305c3c48bbc 100644 --- a/packages/editor-ui/tslint.json +++ b/packages/editor-ui/tslint.json @@ -2,7 +2,8 @@ "linterOptions": { "exclude": [ "node_modules/**/*", - "../../node_modules/**/*" + "../../node_modules/**/*", + "**/*.json" ] }, "defaultSeverity": "error", From 545564ad2da191e9aade383acf122160cbbfd05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Wed, 13 Apr 2022 14:18:04 +0200 Subject: [PATCH 04/10] :bug: Fix errors surfaced by `baseText()` typing --- packages/editor-ui/src/components/DeleteUserModal.vue | 10 ++++++++-- packages/editor-ui/src/components/InviteUsersModal.vue | 5 ++++- packages/editor-ui/src/components/Node.vue | 7 +++++-- .../src/components/NodeCreator/CategoryItem.vue | 5 +++-- packages/editor-ui/src/components/WorkflowSettings.vue | 2 +- packages/editor-ui/src/views/SettingsUsersView.vue | 5 ++++- packages/editor-ui/src/views/SetupView.vue | 4 ++-- 7 files changed, 27 insertions(+), 11 deletions(-) diff --git a/packages/editor-ui/src/components/DeleteUserModal.vue b/packages/editor-ui/src/components/DeleteUserModal.vue index de21bcb4bbefa..3e4db714b1cdb 100644 --- a/packages/editor-ui/src/components/DeleteUserModal.vue +++ b/packages/editor-ui/src/components/DeleteUserModal.vue @@ -91,7 +91,10 @@ export default mixins(showMessage).extend({ }, title(): string { const user = this.userToDelete && (this.userToDelete.fullName || this.userToDelete.email); - return this.$locale.baseText('settings.users.deleteUser', { interpolate: { user }}); + return this.$locale.baseText( + 'settings.users.deleteUser', + { interpolate: { user: user || '' }}, + ); }, enabled(): boolean { if (this.isPending) { @@ -138,7 +141,10 @@ export default mixins(showMessage).extend({ 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 }}); + message = this.$locale.baseText( + 'settings.users.transferredToUser', + { interpolate: { user: transferUser.fullName || '' }}, + ); } this.$showMessage({ diff --git a/packages/editor-ui/src/components/InviteUsersModal.vue b/packages/editor-ui/src/components/InviteUsersModal.vue index 18730fe580884..d52ebd1ae59e9 100644 --- a/packages/editor-ui/src/components/InviteUsersModal.vue +++ b/packages/editor-ui/src/components/InviteUsersModal.vue @@ -106,7 +106,10 @@ export default mixins(showMessage).extend({ }, buttonLabel(): string { if (this.emailsCount > 1) { - return this.$locale.baseText('settings.users.inviteXUser', { interpolate: { count: this.emailsCount }}); + return this.$locale.baseText( + 'settings.users.inviteXUser', + { interpolate: { count: this.emailsCount.toString() }}, + ); } return this.$locale.baseText('settings.users.inviteUser'); diff --git a/packages/editor-ui/src/components/Node.vue b/packages/editor-ui/src/components/Node.vue index 2c7e9abfe78fb..1120a05e356c4 100644 --- a/packages/editor-ui/src/components/Node.vue +++ b/packages/editor-ui/src/components/Node.vue @@ -125,13 +125,16 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext if (this.nodeType !== null && this.nodeType.hasOwnProperty('eventTriggerDescription')) { const nodeName = this.$locale.shortNodeType(this.nodeType.name); const { eventTriggerDescription } = this.nodeType; - return this.$locale.nodeText().eventTriggerDescription(nodeName, eventTriggerDescription); + return this.$locale.nodeText().eventTriggerDescription( + nodeName, + eventTriggerDescription || '', + ); } else { return this.$locale.baseText( 'node.waitingForYouToCreateAnEventIn', { interpolate: { - nodeType: this.nodeType && getTriggerNodeServiceName(this.nodeType.displayName), + nodeType: this.nodeType ? getTriggerNodeServiceName(this.nodeType.displayName) : '', }, }, ); diff --git a/packages/editor-ui/src/components/NodeCreator/CategoryItem.vue b/packages/editor-ui/src/components/NodeCreator/CategoryItem.vue index dcf9bafe1bc5e..6b8a3b1c353a0 100644 --- a/packages/editor-ui/src/components/NodeCreator/CategoryItem.vue +++ b/packages/editor-ui/src/components/NodeCreator/CategoryItem.vue @@ -15,6 +15,7 @@