Dashboard List: Fix how link query part is created when variables are included (#109861)

Fix how link query part is created
This commit is contained in:
Andrej Ocenas
2025-08-19 17:43:15 +02:00
committed by GitHub
parent a31323578f
commit e159d25fdd
3 changed files with 59 additions and 34 deletions
+3 -34
View File
@@ -2,31 +2,21 @@ import { take } from 'lodash';
import { SyntheticEvent, useEffect, useMemo, useState } from 'react';
import { useThrottle } from 'react-use';
import {
DataLinkBuiltInVars,
DateTime,
InterpolateFunction,
PanelProps,
textUtil,
UrlQueryValue,
urlUtil,
} from '@grafana/data';
import { InterpolateFunction, PanelProps, textUtil } from '@grafana/data';
import { useStyles2, IconButton, ScrollContainer } from '@grafana/ui';
import { updateNavIndex } from 'app/core/actions';
import { getConfig } from 'app/core/config';
import { appEvents } from 'app/core/core';
import { useBusEvent } from 'app/core/hooks/useBusEvent';
import { ID_PREFIX, setStarred } from 'app/core/reducers/navBarTree';
import { removeNavIndex } from 'app/core/reducers/navModel';
import { getBackendSrv } from 'app/core/services/backend_srv';
import impressionSrv from 'app/core/services/impression_srv';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { DashboardSearchItem } from 'app/features/search/types';
import { VariablesChanged } from 'app/features/variables/types';
import { useDispatch, useSelector } from 'app/types/store';
import { Options } from './panelcfg.gen';
import { getStyles } from './styles';
import { useDashListUrlParams } from './utils';
type Dashboard = DashboardSearchItem & { id?: number; isSearchResult?: boolean; isRecent?: boolean };
@@ -179,9 +169,7 @@ export function DashList(props: PanelProps<Options>) {
const renderList = (dashboards: Dashboard[]) => (
<ul>
{dashboards.map((dash) => {
let url = dash.url;
url = urlUtil.appendQueryToUrl(url, urlParams);
let url = dash.url + urlParams;
url = getConfig().disableSanitizeHtml ? url : textUtil.sanitizeUrl(url);
return (
@@ -220,22 +208,3 @@ export function DashList(props: PanelProps<Options>) {
</ScrollContainer>
);
}
function useDashListUrlParams(props: PanelProps<Options>) {
// We don't care about the payload just want to get re-render when this event is published
useBusEvent(appEvents, VariablesChanged);
let params: { [key: string]: string | DateTime | UrlQueryValue } = {};
if (props.options.keepTime) {
params[`\$${DataLinkBuiltInVars.keepTime}`] = true;
}
if (props.options.includeVars) {
params[`\$${DataLinkBuiltInVars.includeVars}`] = true;
}
const urlParms = props.replaceVariables(urlUtil.toUrlParams(params));
return urlParms;
}
@@ -0,0 +1,32 @@
import { PanelProps } from '@grafana/data';
import { Options } from './panelcfg.gen';
import { useDashListUrlParams } from './utils';
// Mock the dependencies
jest.mock('../../../core/hooks/useBusEvent', () => ({
useBusEvent: jest.fn(),
}));
describe('useDashListUrlParams', () => {
const createPanelProps = (keepTime: boolean, includeVars: boolean): PanelProps<Options> =>
({
options: {
keepTime,
includeVars,
},
replaceVariables: (str) => str,
}) as PanelProps<Options>;
it('should not add any parameters when both keepTime and includeVars are false', () => {
const props = createPanelProps(false, false);
expect(useDashListUrlParams(props)).toBe('');
});
it('should add both parameters when both keepTime and includeVars are true in correct format', () => {
const props = createPanelProps(true, true);
// Normally this would be interpolated but we mocked that function so we just check if the variables are correct
// in the string.
expect(useDashListUrlParams(props)).toBe('?$__url_time_range&$__all_variables');
});
});
@@ -0,0 +1,24 @@
import { DataLinkBuiltInVars, PanelProps, urlUtil } from '@grafana/data';
import { appEvents } from '../../../core/core';
import { useBusEvent } from '../../../core/hooks/useBusEvent';
import { VariablesChanged } from '../../../features/variables/types';
import { Options } from './panelcfg.gen';
export function useDashListUrlParams(props: PanelProps<Options>) {
// We don't care about the payload just want to get re-render when this event is published
useBusEvent(appEvents, VariablesChanged);
let query = '';
if (props.options.keepTime) {
query = urlUtil.appendQueryToUrl(query, `\$${DataLinkBuiltInVars.keepTime}`);
}
if (props.options.includeVars) {
query = urlUtil.appendQueryToUrl(query, `\$${DataLinkBuiltInVars.includeVars}`);
}
return props.replaceVariables(query);
}