fix(whatsapp): load health status for regional locales (#15440)

The WhatsApp health status page fails to render for accounts using
underscore-based regional locales such as `pt_BR`. The browser rejects
that locale when formatting the last-onboarded timestamp, leaving the
page blank even though health data loaded successfully.

This change formats the timestamp with Chatwoot’s shared resolved
locale, which normalizes and validates the locale before passing it to
the browser. Other health status behavior remains unchanged.

### How to reproduce

1. Set the dashboard language to Portuguese (Brazil).
2. Open an inbox’s WhatsApp health status page when the response
includes `last_onboarded_time`.
3. Observe that the page remains blank with `RangeError: Invalid
language tag: pt_BR` in the browser console.

### How to test

1. Use an account with Portuguese (Brazil) selected.
2. Open the WhatsApp health status page for an inbox with onboarding
data.
3. Confirm the complete health status page loads and the last-onboarded
timestamp is formatted in the selected locale.

Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
This commit is contained in:
Muhsin Keloth
2026-08-13 10:26:06 +05:30
committed by GitHub
parent 3453e2975d
commit 10e9cb5b60
2 changed files with 18 additions and 3 deletions

View File

@@ -2,6 +2,7 @@
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { useLocale } from 'shared/composables/useLocale';
import ButtonV4 from 'next/button/Button.vue';
import Icon from 'dashboard/components-next/icon/Icon.vue';
@@ -28,7 +29,8 @@ const props = defineProps({
const emit = defineEmits(['registerWebhook', 'goToConfiguration']);
const { t, te, locale } = useI18n();
const { t, te } = useI18n();
const { resolvedLocale } = useLocale();
const QUALITY_COLORS = {
GREEN: 'text-n-teal-11',
@@ -77,7 +79,7 @@ const formatDateTime = value => {
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return new Intl.DateTimeFormat(locale.value, {
return new Intl.DateTimeFormat(resolvedLocale.value, {
dateStyle: 'medium',
timeStyle: 'short',
}).format(date);

View File

@@ -2,11 +2,13 @@ import { shallowMount } from '@vue/test-utils';
import ButtonV4 from 'next/button/Button.vue';
import AccountHealth from '../AccountHealth.vue';
const { locale } = vi.hoisted(() => ({ locale: { value: 'en' } }));
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: key => key,
te: () => false,
locale: { value: 'en' },
locale,
}),
}));
@@ -17,6 +19,7 @@ describe('AccountHealth', () => {
});
beforeEach(() => {
locale.value = 'en';
vi.spyOn(window, 'open').mockImplementation(() => {});
});
@@ -67,6 +70,16 @@ describe('AccountHealth', () => {
);
});
it('formats dates for underscore-based locales', () => {
locale.value = 'pt_BR';
const wrapper = mountComponent({
last_onboarded_time: '2026-05-29T20:11:58+0000',
});
expect(wrapper.text()).toContain('2026');
});
it('shows the current error instead of stale health data', () => {
const wrapper = mountComponent(
{ verified_name: 'Stale Business Name' },