Skip to content

Commit

Permalink
Merge pull request #992 from Gepardgame/feat/systemwide-language
Browse files Browse the repository at this point in the history
Feat: Systemwide Default Language
  • Loading branch information
nscuro authored Sep 17, 2024
2 parents f28c630 + 3139754 commit 0c57f1a
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 24 deletions.
28 changes: 23 additions & 5 deletions src/i18n/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import axios from 'axios';
import api from '../shared/api.json';

Vue.use(VueI18n);

async function getDefaultLanguage() {
try {
let url = `${api.BASE_URL}/${api.URL_CONFIG_PROPERTY}/public/general/default.locale`;
let response = await axios.get(url);
return decodeURIComponent(response.data.propertyValue);
} catch (error) {
console.error('Error fetching default language:', error);
return '';
}
}

function loadLocaleMessages() {
const locales = require.context(
'./locales',
Expand Down Expand Up @@ -54,15 +67,20 @@ function matchLocale(requestedLocale) {
);
return 'en';
}

const i18n = new VueI18n({
locale: matchLocale(
locale: 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: localeMessages,
});

getDefaultLanguage().then((defaultLanguage) => {
const matchedLocale = matchLocale(
(localStorage && localStorage.getItem('Locale')) ||
defaultLanguage ||
navigator.language ||
navigator.userLanguage,
),
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: localeMessages,
);
i18n.locale = matchedLocale;
});

export default i18n;
3 changes: 3 additions & 0 deletions src/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Vorlage erstellen",
"create_user": "Benutzer erstellen",
"default": "Standard",
"default_language": "Standardsprache",
"default_language_desc": "Standardsprache, die für alle verwendet wird, wenn sie keine angegeben haben. \nWenn dies deaktiviert ist, wird die Sprache des Browsers verwendet.",
"default_language_enable": "Aktivieren Sie die Standardsprache",
"default_template_restored": "Standardvorlagen wiederhergestellt",
"defectdojo": "DefectDojo",
"delete_alert": "Alarm löschen",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Create Template",
"create_user": "Create User",
"default": "Default",
"default_language": "Default Language",
"default_language_desc": "Default language, which is used for everyone, when they didn't specify one. Langauge from Browser will be used, when this is disabled.",
"default_language_enable": "Enable Default language",
"default_template_restored": "Default templates restored",
"defectdojo": "DefectDojo",
"delete_alert": "Delete Alert",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Crear plantilla",
"create_user": "Crear usuario",
"default": "Por defecto",
"default_language": "Idioma predeterminado",
"default_language_desc": "Idioma predeterminado, que se usa para todos, cuando no especificaron uno. \nSe utilizará el idioma del navegador cuando esté deshabilitado.",
"default_language_enable": "Habilitar idioma predeterminado",
"default_template_restored": "Plantillas predeterminadas restauradas",
"defectdojo": "DefectoDojo",
"delete_alert": "Eliminar alerta",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Créer un modèle",
"create_user": "Créer un utilisateur",
"default": "Défaut",
"default_language": "Langue par défaut",
"default_language_desc": "Langue par défaut, qui est utilisée par tout le monde, lorsqu'ils n'en ont pas spécifié. \nLa langue du navigateur sera utilisée lorsqu'elle est désactivée.",
"default_language_enable": "Activer la langue par défaut",
"default_template_restored": "Modèles par défaut restaurés",
"defectdojo": "DefectDojo",
"delete_alert": "Supprimer l'alerte",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "टेम्पलेट बनाएं",
"create_user": "उपयोगकर्ता बनाइये",
"default": "गलती करना",
"default_language": "डिफ़ॉल्ट भाषा",
"default_language_desc": "डिफ़ॉल्ट भाषा, जिसका उपयोग सभी के लिए किया जाता है, जब उन्होंने किसी एक को निर्दिष्ट नहीं किया हो। \nइसे अक्षम करने पर ब्राउज़र से लैंग्वेज का उपयोग किया जाएगा।",
"default_language_enable": "डिफ़ॉल्ट भाषा सक्षम करें",
"default_template_restored": "डिफ़ॉल्ट टेम्पलेट्स पुनर्स्थापित किए गए",
"defectdojo": "डिफेक्टडोजो",
"delete_alert": "अलर्ट हटाएं",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Crea modello",
"create_user": "Creare un utente",
"default": "Predefinito",
"default_language": "Lingua predefinita",
"default_language_desc": "Lingua predefinita, utilizzata da tutti quando non ne è stata specificata una. \nQuando questa opzione è disabilitata, verrà utilizzata la lingua del browser.",
"default_language_enable": "Abilita la lingua predefinita",
"default_template_restored": "Modelli predefiniti ripristinati",
"defectdojo": "DifettoDojo",
"delete_alert": "Elimina avviso",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "テンプレートを作成",
"create_user": "ユーザーを作成",
"default": "デフォルト",
"default_language": "デフォルトの言語",
"default_language_desc": "デフォルトの言語。指定しなかった場合に全員に使用されます。\nこれを無効にすると、ブラウザの言語が使用されます。",
"default_language_enable": "デフォルト言語を有効にする",
"default_template_restored": "デフォルトのテンプレートが復元されました",
"defectdojo": "DefectDojo",
"delete_alert": "アラートを削除",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Utwórz szablon",
"create_user": "Stwórz użytkownika",
"default": "Domyślny",
"default_language": "Domyślny język",
"default_language_desc": "Domyślny język, którego używają wszyscy, jeśli go nie określili. \nJeśli ta opcja jest wyłączona, używany będzie język z przeglądarki.",
"default_language_enable": "Włącz język domyślny",
"default_template_restored": "Przywrócono domyślne szablony",
"defectdojo": "DefektDojo",
"delete_alert": "Usuń alert",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Criar modelo",
"create_user": "Criar usuário",
"default": "Padrão",
"default_language": "Idioma padrão",
"default_language_desc": "Idioma padrão, que é usado por todos, quando não especificam um. \nO idioma do navegador será usado quando estiver desabilitado.",
"default_language_enable": "Ativar idioma padrão",
"default_template_restored": "Modelos padrão restaurados",
"defectdojo": "DefectDojo",
"delete_alert": "Excluir alerta",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Criar modelo",
"create_user": "Criar utilizador",
"default": "Padrão",
"default_language": "Idioma padrão",
"default_language_desc": "Idioma padrão, que é usado por todos, quando não especificam um. \nO idioma do navegador será usado quando estiver desabilitado.",
"default_language_enable": "Ativar idioma padrão",
"default_template_restored": "Modelos padrão restaurados",
"defectdojo": "DefectDojo",
"delete_alert": "Excluir alerta",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Создать шаблон",
"create_user": "Создать пользователя",
"default": "По умолчанию",
"default_language": "Язык по умолчанию",
"default_language_desc": "Язык по умолчанию, который используется всеми, если они его не указали. \nЕсли эта опция отключена, будет использоваться язык из браузера.",
"default_language_enable": "Включить язык по умолчанию",
"default_template_restored": "Шаблоны по умолчанию восстановлены",
"defectdojo": "ДефектДодзё",
"delete_alert": "Удалить оповещение",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/uk-UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "Створити шаблон",
"create_user": "Створити користувача",
"default": "За замовчуванням",
"default_language": "Мова за замовчуванням",
"default_language_desc": "Мова за замовчуванням, яка використовується для всіх, якщо вони не вказали її. \nЯкщо цей параметр вимкнено, використовуватиметься мова з браузера.",
"default_language_enable": "Увімкнути мову за замовчуванням",
"default_template_restored": "Стандартні шаблони відновлено",
"defectdojo": "DefectDojo",
"delete_alert": "Видалити сповіщення",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"create_template": "创建模板",
"create_user": "创建用户",
"default": "默认",
"default_language": "默认语言",
"default_language_desc": "默认语言,当他们没有指定一种语言时,每个人都使用它。\n禁用时,将使用浏览器中的语言。",
"default_language_enable": "启用默认语言",
"default_template_restored": "恢复默认模板",
"defectdojo": "DefectDojo (一个开源的应用程序安全漏洞协调和管理平台)",
"delete_alert": "删除告警",
Expand Down
121 changes: 102 additions & 19 deletions src/views/administration/configuration/General.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,77 @@
<template>
<b-card no-body :header="header">
<b-card-body>
<b-validated-input-group-form-input
id="base_url"
:label="$t('admin.base_url')"
input-group-size="mb-3"
rules="required"
type="url"
v-model="baseUrl"
tooltip="This URL is used to construct links back to Dependency-Track from external systems."
/>
<c-switch
id="isBadgesEnabled"
color="primary"
v-model="isBadgesEnabled"
label
v-bind="labelIcon"
/>{{ $t('admin.enable_svg_badge') }}
<b-form-group>
<b-validated-input-group-form-input
id="base_url"
:label="$t('admin.base_url')"
input-group-size="mb-3"
rules="required"
type="url"
v-model="baseUrl"
tooltip="This URL is used to construct links back to Dependency-Track from external systems."
/>
<c-switch
id="isBadgesEnabled"
color="primary"
v-model="isBadgesEnabled"
label
v-bind="labelIcon"
/>{{ $t('admin.enable_svg_badge') }}
</b-form-group>
<b-form-group>
<b-form-group
:label="$t('admin.default_language')"
label-size="lg"
label-class="font-weight-bold pt-0 mb-2"
>
<p>{{ $t('admin.default_language_desc') }}</p>
<div id="customToolbar">
<c-switch
id="default-language-enabled"
color="primary"
v-model="isDefaultLanguageEnabled"
label
v-bind="labelIcon"
/>{{ $t('admin.default_language_enable') }}
</div>
</b-form-group>
<b-input-group>
<b-input-group-prepend :title="this.$t('message.language')" is-text>
<span class="fa fa-language text-primary"></span>
</b-input-group-prepend>
<b-form-select
class="bg-widget"
v-model="defaultLanguage"
:disabled="!isDefaultLanguageEnabled"
>
<b-form-select-option
v-for="locale in $i18n.availableLocales"
:key="`locale-${locale}`"
:value="locale"
:title="$t(`language.${locale}`)"
>
<span class="mr-2">{{ localeToFlag(locale) }}</span>
{{ locale.toUpperCase() }}</b-form-select-option
>
</b-form-select>
</b-input-group>
</b-form-group>
</b-card-body>
<b-card-footer>
<b-button variant="outline-primary" class="px-4" @click="saveChanges">{{
$t('message.update')
}}</b-button>
<b-button
variant="outline-primary"
class="px-4"
@click="saveChanges"
:disabled="this.isDefaultLanguageEnabled && this.defaultLanguage === ''"
>{{ $t('message.update') }}</b-button
>
</b-card-footer>
</b-card>
</template>

<script>
import LocalePicker from '@/views/components/LocalePicker.vue';
import { Switch as cSwitch } from '@coreui/vue';
import { ValidationObserver } from 'vee-validate';
import BValidatedInputGroupFormInput from '../../../forms/BValidatedInputGroupFormInput';
Expand All @@ -39,6 +84,7 @@ export default {
header: String,
},
components: {
LocalePicker,
cSwitch,
ValidationObserver,
BValidatedInputGroupFormInput,
Expand All @@ -47,6 +93,8 @@ export default {
return {
baseUrl: '',
isBadgesEnabled: false,
isDefaultLanguageEnabled: false,
defaultLanguage: 'en',
labelIcon: {
dataOn: '\u2713',
dataOff: '\u2715',
Expand All @@ -66,8 +114,35 @@ export default {
propertyName: 'badge.enabled',
propertyValue: this.isBadgesEnabled,
},
{
groupName: 'general',
propertyName: 'default.locale',
propertyValue: this.isDefaultLanguageEnabled
? this.defaultLanguage
: null,
},
]);
},
localeToFlag: function (locale) {
// Largely taken from wojtekmaj/country-code-to-flag-emoji. Adopted to be able to deal with locale codes as inputs.
// https://github.com/wojtekmaj/country-code-to-flag-emoji/blob/ff0d3d2dd9680b6f860d85fc9e713e93e396adb7/src/index.ts
let countryCode = locale.split('-').pop().toUpperCase();
if (countryCode === 'EN') {
countryCode = 'US'; // Sorry Britain!
} else if (countryCode === 'HI') {
countryCode = 'IN';
} else if (countryCode === 'JA') {
countryCode = 'JP';
} else if (countryCode === 'ZH') {
countryCode = 'CN';
}
return Array.from(countryCode)
.map((letter) => letter.toLowerCase().charCodeAt(0) + 127365)
.map((charCode) => String.fromCodePoint(charCode))
.join('');
},
},
created() {
this.axios.get(this.configUrl).then((response) => {
Expand All @@ -83,6 +158,14 @@ export default {
case 'badge.enabled':
this.isBadgesEnabled = common.toBoolean(item.propertyValue);
break;
case 'default.locale':
this.isDefaultLanguageEnabled = !!common.trimToNull(
item.propertyValue,
);
this.defaultLanguage = this.isDefaultLanguageEnabled
? item.propertyValue
: '';
break;
}
}
});
Expand Down

0 comments on commit 0c57f1a

Please sign in to comment.