aboutsummaryrefslogtreecommitdiffstats
path: root/apps/settings/src/components/PersonalInfo/LanguageSection
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings/src/components/PersonalInfo/LanguageSection')
-rw-r--r--apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue127
-rw-r--r--apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue72
2 files changed, 199 insertions, 0 deletions
diff --git a/apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue b/apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue
new file mode 100644
index 00000000000..8f42b2771c0
--- /dev/null
+++ b/apps/settings/src/components/PersonalInfo/LanguageSection/Language.vue
@@ -0,0 +1,127 @@
+<!--
+ - SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <div class="language">
+ <NcSelect :aria-label-listbox="t('settings', 'Languages')"
+ class="language__select"
+ :clearable="false"
+ :input-id="inputId"
+ label="name"
+ label-outside
+ :options="allLanguages"
+ :value="language"
+ @option:selected="onLanguageChange" />
+
+ <a href="https://www.transifex.com/nextcloud/nextcloud/"
+ target="_blank"
+ rel="noreferrer noopener">
+ <em>{{ t('settings', 'Help translate') }}</em>
+ </a>
+ </div>
+</template>
+
+<script>
+import { ACCOUNT_SETTING_PROPERTY_ENUM } from '../../../constants/AccountPropertyConstants.js'
+import { savePrimaryAccountProperty } from '../../../service/PersonalInfo/PersonalInfoService.js'
+import { validateLanguage } from '../../../utils/validate.js'
+import { handleError } from '../../../utils/handlers.ts'
+
+import NcSelect from '@nextcloud/vue/components/NcSelect'
+
+export default {
+ name: 'Language',
+
+ components: {
+ NcSelect,
+ },
+
+ props: {
+ inputId: {
+ type: String,
+ default: null,
+ },
+ commonLanguages: {
+ type: Array,
+ required: true,
+ },
+ otherLanguages: {
+ type: Array,
+ required: true,
+ },
+ language: {
+ type: Object,
+ required: true,
+ },
+ },
+
+ data() {
+ return {
+ initialLanguage: this.language,
+ }
+ },
+
+ computed: {
+ /**
+ * All available languages, sorted like: current, common, other
+ */
+ allLanguages() {
+ const common = this.commonLanguages.filter(l => l.code !== this.language.code)
+ const other = this.otherLanguages.filter(l => l.code !== this.language.code)
+ return [this.language, ...common, ...other]
+ },
+ },
+
+ methods: {
+ async onLanguageChange(language) {
+ this.$emit('update:language', language)
+
+ if (validateLanguage(language)) {
+ await this.updateLanguage(language)
+ }
+ },
+
+ async updateLanguage(language) {
+ try {
+ const responseData = await savePrimaryAccountProperty(ACCOUNT_SETTING_PROPERTY_ENUM.LANGUAGE, language.code)
+ this.handleResponse({
+ language,
+ status: responseData.ocs?.meta?.status,
+ })
+ window.location.reload()
+ } catch (e) {
+ this.handleResponse({
+ errorMessage: t('settings', 'Unable to update language'),
+ error: e,
+ })
+ }
+ },
+
+ handleResponse({ language, status, errorMessage, error }) {
+ if (status === 'ok') {
+ // Ensure that local state reflects server state
+ this.initialLanguage = language
+ } else {
+ handleError(error, errorMessage)
+ }
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.language {
+ display: grid;
+
+ #{&}__select {
+ margin-top: 6px; // align with other inputs
+ }
+
+ a {
+ text-decoration: none;
+ width: max-content;
+ }
+}
+</style>
diff --git a/apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue b/apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue
new file mode 100644
index 00000000000..4e92436fd63
--- /dev/null
+++ b/apps/settings/src/components/PersonalInfo/LanguageSection/LanguageSection.vue
@@ -0,0 +1,72 @@
+<!--
+ - SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <section>
+ <HeaderBar :input-id="inputId"
+ :readable="propertyReadable" />
+
+ <Language v-if="isEditable"
+ :input-id="inputId"
+ :common-languages="commonLanguages"
+ :other-languages="otherLanguages"
+ :language.sync="language" />
+
+ <span v-else>
+ {{ t('settings', 'No language set') }}
+ </span>
+ </section>
+</template>
+
+<script>
+import { loadState } from '@nextcloud/initial-state'
+
+import Language from './Language.vue'
+import HeaderBar from '../shared/HeaderBar.vue'
+
+import { ACCOUNT_SETTING_PROPERTY_ENUM, ACCOUNT_SETTING_PROPERTY_READABLE_ENUM } from '../../../constants/AccountPropertyConstants.js'
+
+const { languageMap: { activeLanguage, commonLanguages, otherLanguages } } = loadState('settings', 'personalInfoParameters', {})
+
+export default {
+ name: 'LanguageSection',
+
+ components: {
+ Language,
+ HeaderBar,
+ },
+
+ setup() {
+ // Non reactive instance properties
+ return {
+ commonLanguages,
+ otherLanguages,
+ propertyReadable: ACCOUNT_SETTING_PROPERTY_READABLE_ENUM.LANGUAGE,
+ }
+ },
+
+ data() {
+ return {
+ language: activeLanguage,
+ }
+ },
+
+ computed: {
+ inputId() {
+ return `account-setting-${ACCOUNT_SETTING_PROPERTY_ENUM.LANGUAGE}`
+ },
+
+ isEditable() {
+ return Boolean(this.language)
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+section {
+ padding: 10px 10px;
+}
+</style>