add override locale selector for dates and currencies (#648)

* feat: add override locale selector

* fix: dateExample computed property to ensure Vue updates with locale changes in LanguageSelector.vue
This commit is contained in:
Tonya
2025-05-04 17:11:28 +00:00
committed by GitHub
parent 16bcffac45
commit 89aaa8c595
5 changed files with 59 additions and 11 deletions

View File

@@ -1,31 +1,51 @@
<script setup lang="ts">
import { computed } from "vue";
import * as Locales from "date-fns/locale";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { fmtDate } from "~~/composables/use-formatters";
import { useViewPreferences } from "~~/composables/use-preferences";
const preferences = useViewPreferences();
const locales = Object.values(Locales).map(l => {
return {
code: l.code,
name: new Intl.DisplayNames([preferences.value.language ?? "en-US"], { type: "language" }).of(l.code) ?? l.code,
localName: new Intl.DisplayNames([l.code], { type: "language" }).of(l.code) ?? l.code,
};
});
defineProps({
includeText: {
expanded: {
type: Boolean,
default: true,
},
});
const preferences = useViewPreferences();
function setLanguage(lang: string) {
preferences.value.language = lang;
}
function setOverrideLocale(locale: string | undefined) {
if (locale === undefined || locale === preferences.value.overrideFormatLocale) {
preferences.value.overrideFormatLocale = undefined;
} else {
preferences.value.overrideFormatLocale = locale;
}
}
const dateExample = computed(() => {
// hack to force vue to update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const locale = preferences.value.overrideFormatLocale;
return fmtDate(new Date(Date.now() - 15 * 60000), "relative");
});
</script>
<template>
<div class="w-full" :class="{ 'p-5 pt-0': includeText }">
<Label v-if="includeText" for="language"> {{ $t("profile.language") }} </Label>
<div class="w-full" :class="{ 'p-5 pt-0': expanded }">
<Label v-if="expanded" for="language"> {{ $t("profile.language") }} </Label>
<Select
id="language"
v-model="$i18n.locale"
@@ -44,8 +64,27 @@
</SelectItem>
</SelectContent>
</Select>
<p v-if="includeText" class="m-2 text-sm">
{{ $t("profile.example") }}: {{ $t("global.created") }} {{ dateExample }}
</p>
<template v-if="expanded">
<Label for="overrideLocale"> {{ $t("profile.override_locale") }} </Label>
<Select
id="overrideLocale"
:model-value="preferences.overrideFormatLocale"
@update:model-value="
val => {
setOverrideLocale(val?.toString());
}
"
>
<SelectTrigger>
<SelectValue :placeholder="$t('profile.no_override')" />
</SelectTrigger>
<SelectContent>
<SelectItem v-for="locale in locales" :key="locale.code" :value="locale.code">
{{ locale.name }} - ({{ locale.localName }})
</SelectItem>
</SelectContent>
</Select>
<p class="m-2 text-sm">{{ $t("profile.example") }}: {{ $t("global.created") }} {{ dateExample }}</p>
</template>
</div>
</template>

View File

@@ -29,6 +29,11 @@ export type DateTimeType = "date" | "time" | "datetime";
export function getLocaleCode() {
const { $i18nGlobal } = useNuxtApp();
const preferences = useViewPreferences();
// TODO: make reactive
if (preferences.value.overrideFormatLocale) {
return preferences.value.overrideFormatLocale;
}
return ($i18nGlobal?.locale?.value as string) ?? "en-US";
}

View File

@@ -14,6 +14,7 @@ export type LocationViewPreferences = {
tableHeaders?: TableHeaderType[];
displayHeaderDecor: boolean;
language?: string;
overrideFormatLocale?: string;
};
/**
@@ -32,6 +33,7 @@ export function useViewPreferences(): Ref<LocationViewPreferences> {
itemsPerTablePage: 10,
displayHeaderDecor: true,
language: null,
overrideFormatLocale: null,
},
{ mergeDefaults: true }
);

View File

@@ -279,9 +279,9 @@
"zh-CN": "Chinese (Simplified)",
"zh-HK": "Chinese (Hong Kong)",
"zh-MO": "Chinese (Macau)",
"zh-TW": "Chinese (Traditional)"
"zh-TW": "Chinese (Traditional)",
"sq-AL": "Albanian"
},
"languages.sq-AL": "Albanian",
"locations": {
"child_locations": "Child Locations",
"collapse_tree": "Collapse Tree",
@@ -351,6 +351,8 @@
"group_settings_sub": "Shared Group Settings. You may need to refresh your browser for some settings to apply.",
"inactive": "Inactive",
"language": "Language",
"override_locale": "Override Date and Currency Language",
"no_override": "No override",
"new_password": "New Password",
"no_notifiers": "No notifiers configured",
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Notifier",

View File

@@ -202,7 +202,7 @@
<TooltipContent>{{ $t("global.read_docs") }}</TooltipContent>
</Tooltip>
<LanguageSelector class="z-10 text-primary" :include-text="false" />
<LanguageSelector class="z-10 text-primary" :expanded="false" />
</div>
</TooltipProvider>
</header>