mirror of https://github.com/grafana/grafana.git
[release-11.6.1] Dashboards: Fix time range bug when use_browser_locale is enabled 2 (#103108)
Dashboards: Fix time range bug when use_browser_locale is enabled 2 (#102750)
* revert
* make it work on initial load
* add integration test; cleanup
* fix test
* fix
(cherry picked from commit 39c33d421b
)
This commit is contained in:
parent
7b6db626ad
commit
cbcfe0bcff
|
@ -32,7 +32,7 @@ describe('dateTimeParse', () => {
|
|||
|
||||
const date = dateTimeParse('2025-03-12T07:09:37.253Z', { timeZone: 'browser' });
|
||||
expect(date.isValid()).toBe(true);
|
||||
expect(date.format()).toEqual('2025-03-12T02:09:37-05:00');
|
||||
expect(date.format()).toEqual('2025-03-12T07:09:37Z');
|
||||
});
|
||||
|
||||
it('should be able to parse array formats used by calendar', () => {
|
||||
|
|
|
@ -53,29 +53,31 @@ export const dateTimeParse: DateTimeParser<DateTimeOptionsWhenParsing> = (value,
|
|||
};
|
||||
|
||||
const parseString = (value: string, options?: DateTimeOptionsWhenParsing): DateTime => {
|
||||
const parsed = parse(value, options?.roundUp, options?.timeZone, options?.fiscalYearStartMonth);
|
||||
if (value.indexOf('now') !== -1) {
|
||||
if (!isValid(value)) {
|
||||
return dateTime();
|
||||
}
|
||||
|
||||
const parsed = parse(value, options?.roundUp, options?.timeZone, options?.fiscalYearStartMonth);
|
||||
return parsed || dateTime();
|
||||
}
|
||||
|
||||
const timeZone = getTimeZone(options);
|
||||
let timeZone = getTimeZone(options);
|
||||
let format = options?.format ?? systemDateFormats.fullDate;
|
||||
if (value.endsWith('Z')) {
|
||||
// This is a special case when we have an ISO date string
|
||||
// In this case we want to force the format to be ISO and the timeZone to be UTC
|
||||
// This logic is needed for initial load when parsing the URL params
|
||||
format = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
|
||||
timeZone = 'utc';
|
||||
}
|
||||
|
||||
const zone = moment.tz.zone(timeZone);
|
||||
const format = options?.format ?? systemDateFormats.fullDate;
|
||||
|
||||
if (zone && zone.name) {
|
||||
return dateTimeForTimeZone(zone.name, value, format);
|
||||
}
|
||||
|
||||
if (format === systemDateFormats.fullDate) {
|
||||
// We use parsed here to handle case when `use_browser_locale` is true
|
||||
// We need to pass the parsed value to handle case when value is an ISO 8601 date string
|
||||
return dateTime(parsed, format);
|
||||
}
|
||||
|
||||
switch (lowerCase(timeZone)) {
|
||||
case 'utc':
|
||||
return toUtc(value, format);
|
||||
|
|
|
@ -269,7 +269,7 @@ function valueAsString(value: DateTime | string, timeZone?: TimeZone): string {
|
|||
}
|
||||
|
||||
if (value.endsWith('Z')) {
|
||||
const dt = dateTimeParse(value, { timeZone: 'utc', format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' });
|
||||
const dt = dateTimeParse(value);
|
||||
return dateTimeFormat(dt, { timeZone });
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { useParams } from 'react-router-dom-v5-compat';
|
|||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
|
||||
|
||||
import { PanelProps } from '@grafana/data';
|
||||
import { PanelProps, systemDateFormats, SystemDateFormatsState } from '@grafana/data';
|
||||
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import {
|
||||
|
@ -229,6 +229,42 @@ describe('DashboardScenePage', () => {
|
|||
expect(await screen.findByTitle('Panel B')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('absolute time range', () => {
|
||||
it('should render with absolute time range when use_browser_locale is true', async () => {
|
||||
locationService.push('/d/my-dash-uid?from=2025-03-11T07:09:37.253Z&to=2025-03-12T07:09:37.253Z');
|
||||
systemDateFormats.update({
|
||||
fullDate: 'YYYY-MM-DD HH:mm:ss.SSS',
|
||||
interval: {} as SystemDateFormatsState['interval'],
|
||||
useBrowserLocale: true,
|
||||
});
|
||||
setup();
|
||||
|
||||
await waitForDashboardToRenderWithTimeRange({
|
||||
from: '03/11/2025, 02:09:37 AM',
|
||||
to: '03/12/2025, 02:09:37 AM',
|
||||
});
|
||||
});
|
||||
|
||||
it('should render correct time range when use_browser_locale is true and time range is other than default system date format', async () => {
|
||||
locationService.push('/d/my-dash-uid?from=2025-03-11T07:09:37.253Z&to=2025-03-12T07:09:37.253Z');
|
||||
// mocking navigator.languages to return 'de'
|
||||
// this property configured in the browser settings
|
||||
Object.defineProperty(navigator, 'languages', { value: ['de'] });
|
||||
systemDateFormats.update({
|
||||
// left fullDate empty to show that this should be overridden by the browser locale
|
||||
fullDate: '',
|
||||
interval: {} as SystemDateFormatsState['interval'],
|
||||
useBrowserLocale: true,
|
||||
});
|
||||
setup();
|
||||
|
||||
await waitForDashboardToRenderWithTimeRange({
|
||||
from: '11.03.2025, 02:09:37',
|
||||
to: '12.03.2025, 02:09:37',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('empty state', () => {
|
||||
it('Shows empty state when dashboard is empty', async () => {
|
||||
loadDashboardMock.mockResolvedValue({ dashboard: { uid: 'my-dash-uid', panels: [] }, meta: {} });
|
||||
|
@ -373,3 +409,8 @@ async function waitForDashboardToRender() {
|
|||
expect(await screen.findByText('Last 6 hours')).toBeInTheDocument();
|
||||
expect(await screen.findByTitle('Panel A')).toBeInTheDocument();
|
||||
}
|
||||
|
||||
async function waitForDashboardToRenderWithTimeRange(timeRange: { from: string; to: string }) {
|
||||
expect(await screen.findByText(`${timeRange.from} to ${timeRange.to}`)).toBeInTheDocument();
|
||||
expect(await screen.findByTitle('Panel A')).toBeInTheDocument();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue