Skip to content

Commit

Permalink
- ADD: Initial support for RTL languages.
Browse files Browse the repository at this point in the history
- ADD: Added support for non-latin numbers.
- CHG: Changed locale encoding from using "_" to "-" to be easier to use with Intl etc.
  • Loading branch information
sebastian-raubach committed Sep 27, 2023
1 parent 63249e6 commit 0e53244
Show file tree
Hide file tree
Showing 15 changed files with 59 additions and 38 deletions.
14 changes: 3 additions & 11 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import BrapiModal from '@/components/modals/BrapiModal'
import ChangelogModal from '@/components/modals/ChangelogModal'
import MissingTrialModal from '@/components/modals/MissingTrialModal'
import { mapGetters } from 'vuex'
import { loadLanguageAsync } from '@/plugins/i18n'
import { loadLanguageAsync, locales } from '@/plugins/i18n'
import { init } from '@/plugins/datastore'
import { VuePlausible } from 'vue-plausible'
import Vue from 'vue'
Expand Down Expand Up @@ -121,15 +121,7 @@ export default {
},
data: function () {
return {
languages: [{
locale: 'en_GB',
name: 'British English',
icon: '🇬🇧'
}, {
locale: 'de_DE',
name: 'Deutsch - Deutschland',
icon: '🇩🇪'
}],
languages: locales,
loadingVisible: false,
refreshing: false,
registration: null,
Expand Down Expand Up @@ -276,7 +268,7 @@ export default {
initDb()
},
mounted: function () {
loadLanguageAsync(this.storeLocale)
loadLanguageAsync(this.storeLocale.replace('_', '-'))
document.documentElement.className = this.storeDarkMode ? 'dark-mode' : 'light-mode'
Expand Down
4 changes: 2 additions & 2 deletions src/components/TraitInputSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</BIconstack>
</b-badge>
<b-badge class="mx-1 trait-set-size" variant="light" v-b-tooltip="$t('tooltipTraitSetSize')">
<BIconSegmentedNav :rotate="90" /> {{ trait.setSize || 1 }}
<BIconSegmentedNav :rotate="90" /> {{ $n(trait.setSize || 1) }}
</b-badge>
</span>
</span>
Expand All @@ -35,7 +35,7 @@
</div>
<p class="text-muted trait-description" :title="trait.description" v-if="trait.description">{{ trait.description }}</p>

<b-form-group :label="$t('formLabelMeasurementSet', { position: index })"
<b-form-group :label="$t('formLabelMeasurementSet', { position: $n(index) })"
v-for="index in (trait.setSize || 1)"
:key="`${trait.id}-${index}`"
:label-for="`trait-input-${trait.id}-${index}`">
Expand Down
2 changes: 1 addition & 1 deletion src/components/TrialSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

<b-card no-body>
<b-tabs card v-model="tabIndex">
<b-tab lazy :title="group === UNCATEGORIZED_TRIALS ? $t(trialListMode === TRIAL_LIST_ALL ? 'tabTitleAllTrials' : 'tabTitleUncategorizedTrials', { count: (trials || []).length }) : `${group} (${(trials || []).length})`" v-for="(trials, group) in sortedTrials" :key="`tab-${group}`">
<b-tab lazy :title="group === UNCATEGORIZED_TRIALS ? $t(trialListMode === TRIAL_LIST_ALL ? 'tabTitleAllTrials' : 'tabTitleUncategorizedTrials', { count: $n((trials || []).length) }) : `${group} (${$n((trials || []).length)})`" v-for="(trials, group) in sortedTrials" :key="`tab-${group}`">
<template v-if="trials && trials.length > 0">
<b-list-group v-if="storeTrialListArrangement === TRIAL_LIST_LIST">
<TrialListGroupItem :trial="trial"
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/ColumnHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default {
this.ctx.fillRect(x, y, this.dimensions.cellWidth, this.dimensions.columnHeaderHeight)
this.ctx.fillStyle = this.fillStyleText
this.ctx.fillText(this.trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? (this.trial.layout.columns - col) : (col + 1), x + this.dimensions.cellWidth / 2, y + this.dimensions.padding + this.dimensions.fontSize / 2)
this.ctx.fillText(this.trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? this.$n(this.trial.layout.columns - col) : this.$n(col + 1), x + this.dimensions.cellWidth / 2, y + this.dimensions.padding + this.dimensions.fontSize / 2)
},
reset: function () {
if (this.resizeRunning) {
Expand Down
6 changes: 5 additions & 1 deletion src/components/canvas/PlotCanvas.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="cell d-block position-relative" v-if="dimensions">
<div class="canvas-wrapper cell d-block position-relative" v-if="dimensions">
<canvas id="main-canvas" class="position-absolute" ref="plotCanvas" :width="dimensions.scaledCanvasWidth" :height="dimensions.scaledCanvasHeight" />
<canvas id="user-position-canvas" class="position-absolute" ref="userCanvas" :width="dimensions.scaledCanvasWidth" :height="dimensions.scaledCanvasHeight" />

Expand Down Expand Up @@ -892,4 +892,8 @@ export default {
#user-position-canvas {
pointer-events: none;
}
.canvas-wrapper {
/* This is added to "fix" the main data display on RTL languages. */
direction: ltr !important;
}
</style>
2 changes: 1 addition & 1 deletion src/components/canvas/RowHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default {
this.ctx.fillRect(0, y, this.dimensions.rowHeaderWidth, this.dimensions.cellHeight)
this.ctx.fillStyle = this.fillStyleText
this.ctx.fillText(this.trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? (this.trial.layout.rows - row) : (row + 1), x, y + this.dimensions.cellHeight / 2)
this.ctx.fillText(this.trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? this.$n(this.trial.layout.rows - row) : this.$n(row + 1), x, y + this.dimensions.cellHeight / 2)
},
reset: function () {
if (this.resizeRunning) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/charts/FieldHeatmap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ export default {
const traces = [{
// X values are the column indices
x: Array.from({ length: this.trial.layout.columns }, (v, k) => k + 1),
x: Array.from({ length: this.trial.layout.columns }, (v, k) => this.$n(k + 1)),
// Y Values are the row indices
y: Array.from({ length: this.trial.layout.rows }, (v, k) => k + 1),
y: Array.from({ length: this.trial.layout.rows }, (v, k) => this.$n(k + 1)),
z: z,
text: text,
customdata: customdata,
Expand Down
4 changes: 2 additions & 2 deletions src/components/charts/GermplasmRepHeatmap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ export default {
}
const traces = [{
x: this.reps.map((r, i) => i),
x: this.reps.map((r, i) => this.$n(i)),
// Y Values are the row indices
y: Array.from(Array(this.allGermplasm.length).keys()).map(i => i + 1),
y: Array.from(Array(this.allGermplasm.length).keys()).map(i => this.$n(i + 1)),
z: z,
text: text,
customdata: customdata,
Expand Down
2 changes: 2 additions & 0 deletions src/components/dropdowns/JumpToDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ export default {
grid-template-columns: repeat(3, 1fr);
column-gap: 10px;
row-gap: 10px;
/* Force the direction here to keep the buttons in place. They shouldn't change based on the language. */
direction: ltr;
}
.direction-grid > div {
justify-self: center;
Expand Down
4 changes: 2 additions & 2 deletions src/components/modals/DataInputModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<div v-if="cell && trial">
<b-row v-if="guidedWalk" class="mb-3">
<b-col cols=4>
<b-card class="text-center h-100" :title="guidedWalk.prev.displayName" :sub-title="$t('widgetGuidedWalkPreviewColumnRow', { column: trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? (trial.layout.columns - guidedWalk.prev.column) : (guidedWalk.prev.column + 1), row: trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? (trial.layout.rows - guidedWalk.prev.row) : (guidedWalk.prev.row + 1) })" v-if="guidedWalk.prev" />
<b-card class="text-center h-100" :title="guidedWalk.prev.displayName" :sub-title="$t('widgetGuidedWalkPreviewColumnRow', { column: trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? $n(trial.layout.columns - guidedWalk.prev.column) : $n(guidedWalk.prev.column + 1), row: trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? $n(trial.layout.rows - guidedWalk.prev.row) : $n(guidedWalk.prev.row + 1) })" v-if="guidedWalk.prev" />
</b-col>
<b-col cols=4>
<b-card class="text-center h-100">
Expand All @@ -80,7 +80,7 @@
</b-card>
</b-col>
<b-col cols=4>
<b-card class="text-center h-100" :title="guidedWalk.next.displayName" :sub-title="$t('widgetGuidedWalkPreviewColumnRow', { column: trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? (trial.layout.columns - guidedWalk.next.column) : (guidedWalk.next.column + 1), row: trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? (trial.layout.rows - guidedWalk.next.row) : (guidedWalk.next.row + 1) })" v-if="guidedWalk.next" />
<b-card class="text-center h-100" :title="guidedWalk.next.displayName" :sub-title="$t('widgetGuidedWalkPreviewColumnRow', { column: trial.layout.columnOrder === DISPLAY_ORDER_RIGHT_TO_LEFT ? $n(trial.layout.columns - guidedWalk.next.column) : $n(guidedWalk.next.column + 1), row: trial.layout.rowOrder === DISPLAY_ORDER_BOTTOM_TO_TOP ? $n(trial.layout.rows - guidedWalk.next.row) : $n(guidedWalk.next.row + 1) })" v-if="guidedWalk.next" />
</b-col>
</b-row>
<b-tabs v-model="traitGroupTabIndex" id="trait-group-tabs">
Expand Down
41 changes: 31 additions & 10 deletions src/plugins/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,62 @@ import VueI18n from 'vue-i18n'

import deDE from '@/plugins/i18n/de_DE.json'
import enGB from '@/plugins/i18n/en_GB.json'
// import arMA from '@/plugins/i18n/ar_MA.json'

const locales = [{
locale: 'en_GB',
locale: 'en-GB',
name: 'British English',
direction: 'ltr',
icon: '🇬🇧'
}, {
locale: 'de_DE',
locale: 'de-DE',
name: 'Deutsch - Deutschland',
direction: 'ltr',
icon: '🇩🇪'
// }, {
// locale: 'ar-MA',
// name: 'العربية - المغرب',
// direction: 'rtl',
// icon: '🇲🇦'
}]

Vue.use(VueI18n)

const messages = {
en_GB: enGB,
de_DE: deDE
'en-GB': enGB,
'de-DE': deDE
// 'ar-MA': arMA
}

export const i18n = new VueI18n({
locale: 'en_GB',
fallbackLocale: 'en_GB',
messages: messages
locale: 'en-GB',
fallbackLocale: 'en-GB',
messages: messages,
numberFormats: {
'en-GB': {},
'de-DE': {},
'ar-MA': {}
}
})

const loadedLanguages = ['en_GB']
const loadedLanguages = ['en-GB']

function setI18nLanguage (lang) {
i18n.locale = lang

let htmlTag = lang
const underscoreIndex = lang.indexOf('_')
const underscoreIndex = lang.indexOf('-')
if (underscoreIndex !== -1) {
htmlTag = lang.substring(0, underscoreIndex)
}
document.querySelector('html').setAttribute('lang', htmlTag)

const match = locales.find(l => l.locale === lang)

if (match) {
document.querySelector('html').setAttribute('dir', match.direction)
}

return lang
}

Expand All @@ -53,7 +74,7 @@ const loadLanguageAsync = (lang) => {
}

// If the language hasn't been loaded yet
return import(/* webpackChunkName: "lang-[request]" */`@/plugins/i18n/${lang}.json`).then(messages => {
return import(/* webpackChunkName: "lang-[request]" */`@/plugins/i18n/${lang.replace('-', '_')}.json`).then(messages => {
i18n.setLocaleMessage(lang, messages.default)
loadedLanguages.push(lang)
return setI18nLanguage(lang)
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/i18n/ar_MA.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
2 changes: 1 addition & 1 deletion src/plugins/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ const getNumberWithSuffix = (value, decimals = 2, k = 1000, separator = '') => {

// Check if advanced number formatting is available
if ('Intl' in window && Intl.NumberFormat) {
const locale = (store.getters.storeLocale || 'en_GB').replace('_', '-')
const locale = (store.getters.storeLocale || 'en-GB').replace('_', '-')
let formatter
if (k === 1024) {
// Handle byte values
Expand Down
6 changes: 3 additions & 3 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default new Vuex.Store({
uniqueClientId: null,
runCount: 0,
serverUrl: null,
locale: 'en_GB',
locale: 'en-GB',
darkMode: false,
hideCitationMessage: false,
displayMarkerIndicators: true,
Expand Down Expand Up @@ -55,8 +55,8 @@ export default new Vuex.Store({
storeIsOffline: (state) => state.isOffline,
storeUniqueClientId: (state) => state.uniqueClientId,
storeRunCount: (state) => state.runCount,
storeLocale: (state) => state.locale,
storeCalendarLocale: (state) => (state.locale || 'en_GB').replace('_', '-'),
storeLocale: (state) => (state.locale || 'en-GB').replace('_', '-'),
storeCalendarLocale: (state) => (state.locale || 'en-GB').replace('_', '-'),
storeDarkMode: (state) => state.darkMode,
storeHideCitationMessage: (state) => state.hideCitationMessage,
storeDisplayMarkerIndicators: (state) => state.displayMarkerIndicators,
Expand Down
2 changes: 1 addition & 1 deletion src/views/SettingsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

<b-form-group :label="$t('formLabelSettingsMinCellWidth')" :description="$t('formDescriptionSettingsMinCellWidth')" label-for="displayMinCellWidth">
<b-form-input id="displayMinCellWidth" type="range" :min=2 :max=10 v-model.number="displayMinCellWidth" />
<small>{{ $t('formPreviewSettingsMinCellWidth', { value: displayMinCellWidth }) }}</small>
<small>{{ $t('formPreviewSettingsMinCellWidth', { value: $n(displayMinCellWidth) }) }}</small>
</b-form-group>

<b-form-group :label="$t('formLabelSettingsCanvasShape')" :description="$t('formDescriptionSettingsCanvasShape')" label-for="canvasShape">
Expand Down

0 comments on commit 0e53244

Please sign in to comment.