Set up i18n

This commit is contained in:
Iván Ovejero
2021-11-09 09:59:48 +01:00
parent a46c7f827d
commit 1de9ecf4ec
19 changed files with 1891 additions and 13 deletions

View File

@@ -1,18 +1,18 @@
<template>
<span>
<el-dialog class="n8n-about" :visible="dialogVisible" append-to-body width="50%" title="About n8n" :before-close="closeDialog">
<el-dialog class="n8n-about" :visible="dialogVisible" append-to-body width="50%" :title="$baseText('about.aboutN8n')" :before-close="closeDialog">
<div>
<el-row>
<el-col :span="8" class="info-name">
n8n Version:
{{ $baseText('about.n8nVersion') }}
</el-col>
<el-col :span="16">
{{versionCli}}
{{ versionCli }}
</el-col>
</el-row>
<el-row>
<el-col :span="8" class="info-name">
Source Code:
{{ $baseText('about.sourceCode') }}
</el-col>
<el-col :span="16">
<a href="https://github.com/n8n-io/n8n" target="_blank">https://github.com/n8n-io/n8n</a>
@@ -20,15 +20,17 @@
</el-row>
<el-row>
<el-col :span="8" class="info-name">
License:
{{ $baseText('about.license') }}
</el-col>
<el-col :span="16">
<a href="https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md" target="_blank">Apache 2.0 with Commons Clause</a>
<a href="https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md" target="_blank">
{{ $baseText('about.apacheWithCommons20Clause') }}
</a>
</el-col>
</el-row>
<div class="action-buttons">
<n8n-button @click="closeDialog" label="Close" />
<n8n-button @click="closeDialog" :label="$baseText('about.close')" />
</div>
</div>
</el-dialog>

View File

@@ -1,9 +1,10 @@
import { showMessage } from '@/components/mixins/showMessage';
import { translate } from '@/components/mixins/translate';
import { debounce } from 'lodash';
import mixins from 'vue-typed-mixins';
export const genericHelpers = mixins(showMessage).extend({
export const genericHelpers = mixins(showMessage, translate).extend({
data () {
return {
loadingService: null as any | null, // tslint:disable-line:no-any

View File

@@ -0,0 +1,203 @@
// import { TranslationPath } from '@/Interface';
import Vue from 'vue';
/**
* Mixin to translate:
* - base strings, i.e. any string that is not node- or credentials-specific,
* - specific strings,
* - node-specific strings, i.e. those in `NodeView.vue`,
* - credentials-specific strings, i.e. those in `EditCredentials.vue`.
*/
export const translate = Vue.extend({
computed: {
/**
* Node type for the active node in `NodeView.vue`.
*/
activeNodeType (): string {
return this.$store.getters.activeNode.type;
},
},
methods: {
// -----------------------------------------
// main methods
// -----------------------------------------
/**
* Translate a base string. Called directly in Vue templates.
* Optionally, [interpolate a variable](https://kazupon.github.io/vue-i18n/guide/formatting.html#named-formatting).
*/
$baseText(
key: string,
options?: { interpolate?: { [key: string]: string } },
): string {
const translatedBaseString = options && options.interpolate
? this.$t(key, options.interpolate)
: this.$t(key);
return translatedBaseString.toString();
},
/**
* Translate a node- or credentials-specific string.
* Called in-mixin by node- or credentials-specific methods,
* which are called directly in Vue templates.
*/
translateSpecific(
{ key, fallback }: { key: string, fallback: string },
): string {
return this.$te(key) ? this.$t(key).toString() : fallback;
},
// -----------------------------------------
// node-specific methods
// -----------------------------------------
/**
* Translate a top-level node parameter name, i.e. leftmost parameter in `NodeView.vue`.
*/
$translateNodeParameterName(
{ name: parameterName, displayName }: { name: string; displayName: string; },
) {
return this.translateSpecific({
key: `${this.activeNodeType}.parameters.${parameterName}.displayName`,
fallback: displayName,
});
},
/**
* Translate a top-level parameter description for a node or for credentials.
*/
$translateDescription(
{ name: parameterName, description }: { name: string; description: string; },
) {
return this.translateSpecific({
key: `${this.activeNodeType}.parameters.${parameterName}.description`,
fallback: description,
});
},
/**
* Translate the name for an option in a `collection` or `fixed collection` parameter,
* e.g. an option name in an "Additional Options" fixed collection.
*/
$translateCollectionOptionName(
{ name: parameterName }: { name: string; },
{ name: optionName, displayName }: { name: string; displayName: string; },
) {
return this.translateSpecific({
key: `${this.activeNodeType}.parameters.${parameterName}.options.${optionName}.displayName`,
fallback: displayName,
});
},
/**
* Translate the label for a button that adds another field-input pair to a collection.
*/
$translateMultipleValueButtonText(
{ name: parameterName, typeOptions: { multipleValueButtonText } }:
{ name: string, typeOptions: { multipleValueButtonText: string } },
) {
return this.translateSpecific({
key: `${this.activeNodeType}.parameters.${parameterName}.multipleValueButtonText`,
fallback: multipleValueButtonText,
});
},
// -----------------------------------------
// creds-specific methods
// -----------------------------------------
/**
* Translate a credentials property name, i.e. leftmost parameter in `CredentialsEdit.vue`.
*/
$translateCredentialsPropertyName(
{ name: parameterName, displayName }: { name: string; displayName: string; },
{ nodeType, credentialsName }: { nodeType: string, credentialsName: string; },
) {
if (['clientId', 'clientSecret'].includes(parameterName)) {
return this.$t(`oauth2.${parameterName}`);
}
return this.translateSpecific({
key: `${nodeType}.credentials.${credentialsName}.${parameterName}.displayName`,
fallback: displayName,
});
},
/**
* Translate a credentials property description, i.e. label tooltip in `CredentialsEdit.vue`.
*/
$translateCredentialsPropertyDescription(
{ name: parameterName, description }: { name: string; description: string; },
{ nodeType, credentialsName }: { nodeType: string, credentialsName: string; },
) {
return this.translateSpecific({
key: `${nodeType}.credentials.${credentialsName}.${parameterName}.description`,
fallback: description,
});
},
// -----------------------------------------
// node- and creds-specific methods
// -----------------------------------------
/**
* Translate the placeholder inside the input field for a string-type parameter.
*/
$translatePlaceholder(
{ name: parameterName, placeholder }: { name: string; placeholder: string; },
isCredential = false,
{ nodeType, credentialsName } = { nodeType: '', credentialsName: '' },
) {
const key = isCredential
? `${nodeType}.credentials.${credentialsName}.placeholder`
: `${this.activeNodeType}.parameters.${parameterName}.placeholder`;
return this.translateSpecific({
key,
fallback: placeholder,
});
},
/**
* Translate the name for an option in an `options` parameter,
* e.g. an option name in a "Resource" or "Operation" dropdown menu.
*/
$translateOptionsOptionName(
{ name: parameterName }: { name: string },
{ value: optionName, name: displayName }: { value: string; name: string; },
isCredential = false,
{ nodeType, credentialsName } = { nodeType: '', credentialsName: '' },
) {
const key = isCredential
? `${nodeType}.credentials.${credentialsName}.options.${optionName}.displayName`
: `${this.activeNodeType}.parameters.${parameterName}.options.${optionName}.displayName`;
return this.translateSpecific({
key,
fallback: displayName,
});
},
/**
* Translate the description for an option in an `options` parameter,
* e.g. an option name in a "Resource" or "Operation" dropdown menu.
*/
$translateOptionsOptionDescription(
{ name: parameterName }: { name: string },
{ value: optionName, description }: { value: string; description: string; },
isCredential = false,
{ nodeType, credentialsName } = { nodeType: '', credentialsName: '' },
) {
const key = isCredential
? `${nodeType}.credentials.${credentialsName}.options.${optionName}.description`
: `${this.activeNodeType}.parameters.${parameterName}.options.${optionName}.description`;
return this.translateSpecific({
key,
fallback: description,
});
},
},
});