feat: switch site locale

pull/6775/head
NGPixel 1 year ago
parent eed3675512
commit 2587778e52
No known key found for this signature in database
GPG Key ID: B755FB6870B30F63

@ -82,6 +82,7 @@ export default {
await WIKI.auth.activateStrategies() await WIKI.auth.activateStrategies()
await WIKI.db.commentProviders.initProvider() await WIKI.db.commentProviders.initProvider()
await WIKI.db.locales.reloadCache()
await WIKI.db.sites.reloadCache() await WIKI.db.sites.reloadCache()
await WIKI.db.storage.initTargets() await WIKI.db.storage.initTargets()

@ -4,17 +4,7 @@ import _ from 'lodash-es'
export default { export default {
Query: { Query: {
async locales(obj, args, context, info) { async locales(obj, args, context, info) {
let remoteLocales = await WIKI.cache.get('locales') return WIKI.db.locales.getLocales({ cache: false })
let localLocales = await WIKI.db.locales.query().select('code', 'isRTL', 'language', 'name', 'nativeName', 'createdAt', 'updatedAt', 'completeness')
remoteLocales = remoteLocales || localLocales
return _.map(remoteLocales, rl => {
let isInstalled = _.some(localLocales, ['code', rl.code])
return {
...rl,
isInstalled,
installDate: isInstalled ? _.find(localLocales, ['code', rl.code]).updatedAt : null
}
})
}, },
localeStrings (obj, args, context, info) { localeStrings (obj, args, context, info) {
return WIKI.db.locales.getStrings(args.locale) return WIKI.db.locales.getStrings(args.locale)

@ -323,5 +323,10 @@ export default {
return generateError(err) return generateError(err)
} }
} }
},
SiteLocales: {
async active (obj, args, context) {
return obj.active.map(l => WIKI.cache.get(`locale:${l}`))
}
} }
} }

@ -28,8 +28,6 @@ type LocalizationLocale {
completeness: Int completeness: Int
code: String code: String
createdAt: Date createdAt: Date
installDate: Date
isInstalled: Boolean
isRTL: Boolean isRTL: Boolean
language: String language: String
name: String name: String

@ -99,7 +99,7 @@ type SiteUploads {
type SiteLocales { type SiteLocales {
primary: String primary: String
active: [String] active: [LocalizationLocale]
} }
type SiteEditors { type SiteEditors {

@ -100,11 +100,26 @@ export class Locale extends Model {
} }
} }
static async getLocales ({ cache = true } = {}) {
if (!WIKI.cache.has('locales') || !cache) {
const locales = await WIKI.db.locales.query().select('code', 'isRTL', 'language', 'name', 'nativeName', 'createdAt', 'updatedAt', 'completeness')
WIKI.cache.set('locales', locales)
for (const locale of locales) {
WIKI.cache.set(`locale:${locale.code}`, locale)
}
}
return WIKI.cache.get('locales')
}
static async getStrings (locale) { static async getStrings (locale) {
const { strings } = await WIKI.db.locales.query().findOne('code', locale).column('strings') const { strings } = await WIKI.db.locales.query().findOne('code', locale).column('strings')
return strings return strings
} }
static async reloadCache () {
await WIKI.db.locales.getLocales({ cache: false })
}
static async getNavLocales({ cache = false } = {}) { static async getNavLocales({ cache = false } = {}) {
return [] return []
// if (!WIKI.config.lang.namespacing) { // if (!WIKI.config.lang.namespacing) {

@ -143,7 +143,7 @@ router.beforeEach(async (to, from) => {
} }
// -> Locale // -> Locale
if (!commonStore.desiredLocale || !siteStore.locales.active.includes(commonStore.desiredLocale)) { if (!commonStore.desiredLocale || !siteStore.locales.active.some(l => l.code === commonStore.desiredLocale)) {
commonStore.setLocale(siteStore.locales.primary) commonStore.setLocale(siteStore.locales.primary)
} else { } else {
applyLocale(commonStore.desiredLocale) applyLocale(commonStore.desiredLocale)

@ -0,0 +1,43 @@
<template lang="pug">
q-menu.translucent-menu(
auto-close
anchor='top right'
self='top left'
)
q-list(padding, style='min-width: 200px;')
q-item(
v-for='lang of siteStore.locales.active'
clickable
@click='commonStore.setLocale(lang.code)'
)
q-item-section(side)
q-avatar(rounded, :color='lang.code === commonStore.locale ? `secondary` : `primary`', text-color='white', size='sm')
.text-caption.text-uppercase: strong {{ lang.language }}
q-item-section
q-item-label {{ lang.nativeName }}
q-item-label(caption) {{ lang.name }}
</template>
<script setup>
import { useI18n } from 'vue-i18n'
import { useQuasar } from 'quasar'
import { useCommonStore } from 'src/stores/common'
import { useSiteStore } from 'src/stores/site'
// QUASAR
const $q = useQuasar()
// STORES
const commonStore = useCommonStore()
const siteStore = useSiteStore()
// I18N
const { t } = useI18n()
// METHODS
</script>

@ -25,7 +25,7 @@ q-layout.admin(view='hHh Lpr lff')
q-btn.q-ml-md(flat, dense, icon='las la-times-circle', :label='t(`common.actions.exit`)' color='pink', to='/') q-btn.q-ml-md(flat, dense, icon='las la-times-circle', :label='t(`common.actions.exit`)' color='pink', to='/')
q-btn.q-ml-md(flat, dense, icon='las la-language', :label='commonStore.locale' color='grey-4') q-btn.q-ml-md(flat, dense, icon='las la-language', :label='commonStore.locale' color='grey-4')
q-menu.translucent-menu(auto-close, anchor='bottom right', self='top right') q-menu.translucent-menu(auto-close, anchor='bottom right', self='top right')
q-list(separator) q-list(separator, padding)
q-item( q-item(
v-for='lang of adminStore.locales' v-for='lang of adminStore.locales'
clickable clickable
@ -35,8 +35,8 @@ q-layout.admin(view='hHh Lpr lff')
q-avatar(rounded, :color='lang.code === commonStore.locale ? `secondary` : `primary`', text-color='white', size='sm') q-avatar(rounded, :color='lang.code === commonStore.locale ? `secondary` : `primary`', text-color='white', size='sm')
.text-caption.text-uppercase: strong {{ lang.language }} .text-caption.text-uppercase: strong {{ lang.language }}
q-item-section q-item-section
q-item-label {{ lang.name }} q-item-label {{ lang.nativeName }}
q-item-label(caption) {{ lang.nativeName }} q-item-label(caption) {{ lang.name }}
account-menu account-menu
q-drawer.admin-sidebar(v-model='leftDrawerOpen', show-if-above, bordered) q-drawer.admin-sidebar(v-model='leftDrawerOpen', show-if-above, bordered)
q-scroll-area.admin-nav( q-scroll-area.admin-nav(

@ -14,10 +14,11 @@ q-layout(view='hHh Lpr lff')
icon='las la-globe' icon='las la-globe'
color='blue-7' color='blue-7'
text-color='blue-2' text-color='blue-2'
label='EN' :label='commonStore.locale'
aria-label='EN' :aria-label='commonStore.locale'
size='sm' size='sm'
) )
locale-selector-menu
q-separator(vertical) q-separator(vertical)
q-btn.q-px-sm.col( q-btn.q-px-sm.col(
flat flat
@ -87,6 +88,7 @@ import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useCommonStore } from 'src/stores/common'
import { useEditorStore } from 'src/stores/editor' import { useEditorStore } from 'src/stores/editor'
import { useFlagsStore } from 'src/stores/flags' import { useFlagsStore } from 'src/stores/flags'
import { useSiteStore } from 'src/stores/site' import { useSiteStore } from 'src/stores/site'
@ -96,6 +98,7 @@ import { useUserStore } from 'src/stores/user'
import FooterNav from 'src/components/FooterNav.vue' import FooterNav from 'src/components/FooterNav.vue'
import HeaderNav from 'src/components/HeaderNav.vue' import HeaderNav from 'src/components/HeaderNav.vue'
import LocaleSelectorMenu from 'src/components/LocaleSelectorMenu.vue'
import MainOverlayDialog from 'src/components/MainOverlayDialog.vue' import MainOverlayDialog from 'src/components/MainOverlayDialog.vue'
// QUASAR // QUASAR
@ -104,6 +107,7 @@ const $q = useQuasar()
// STORES // STORES
const commonStore = useCommonStore()
const editorStore = useEditorStore() const editorStore = useEditorStore()
const flagsStore = useFlagsStore() const flagsStore = useFlagsStore()
const siteStore = useSiteStore() const siteStore = useSiteStore()

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { clone, cloneDeep } from 'lodash-es' import { clone, cloneDeep, sortBy } from 'lodash-es'
import semverGte from 'semver/functions/gte' import semverGte from 'semver/functions/gte'
/* global APOLLO_CLIENT */ /* global APOLLO_CLIENT */
@ -48,7 +48,7 @@ export const useAdminStore = defineStore('admin', {
} }
` `
}) })
this.locales = cloneDeep(resp?.data?.locales ?? []) this.locales = sortBy(cloneDeep(resp?.data?.locales ?? []), ['nativeName', 'name'])
}, },
async fetchInfo () { async fetchInfo () {
const resp = await APOLLO_CLIENT.query({ const resp = await APOLLO_CLIENT.query({

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { clone } from 'lodash-es' import { clone, sortBy } from 'lodash-es'
import { useUserStore } from './user' import { useUserStore } from './user'
@ -39,7 +39,12 @@ export const useSiteStore = defineStore('site', {
}, },
locales: { locales: {
primary: 'en', primary: 'en',
active: ['en'] active: [{
code: 'en',
language: 'en',
name: 'English',
nativeName: 'English'
}]
}, },
theme: { theme: {
dark: false, dark: false,
@ -134,7 +139,12 @@ export const useSiteStore = defineStore('site', {
id id
locales { locales {
primary primary
active active {
code
language
name
nativeName
}
} }
logoText logoText
theme { theme {
@ -182,7 +192,7 @@ export const useSiteStore = defineStore('site', {
}, },
locales: { locales: {
primary: clone(siteInfo.locales.primary), primary: clone(siteInfo.locales.primary),
active: clone(siteInfo.locales.active) active: sortBy(clone(siteInfo.locales.active), ['nativeName', 'name'])
}, },
theme: { theme: {
...this.theme, ...this.theme,

Loading…
Cancel
Save