diff --git a/devenv/dev-dashboards/panel-dashlist/dashlist_url_variables.json b/devenv/dev-dashboards/panel-dashlist/dashlist_url_variables.json new file mode 100644 index 00000000000..0906d56a78a --- /dev/null +++ b/devenv/dev-dashboards/panel-dashlist/dashlist_url_variables.json @@ -0,0 +1,139 @@ +{ + "__inputs": [ + { + "name": "DS_GDEV-TESTDATA", + "label": "gdev-testdata", + "description": "", + "type": "datasource", + "pluginId": "grafana-testdata-datasource", + "pluginName": "TestData" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "dashlist", + "name": "Dashboard list", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.3.0-pre" + }, + { + "type": "datasource", + "id": "grafana-testdata-datasource", + "name": "TestData", + "version": "1.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "${DS_GDEV-TESTDATA}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "folderUID": "", + "includeVars": true, + "keepTime": false, + "maxItems": 10, + "query": "", + "showHeadings": true, + "showRecentlyViewed": true, + "showSearch": false, + "showStarred": false, + "tags": [] + }, + "pluginVersion": "10.3.0-pre", + "title": "Dashboard list panel", + "type": "dashlist" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "a", + "value": "a" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "query0", + "options": [ + { + "selected": true, + "text": "a", + "value": "a" + }, + { + "selected": false, + "text": "b", + "value": "b" + }, + { + "selected": false, + "text": "c", + "value": "c" + }, + { + "selected": false, + "text": "d", + "value": "d" + } + ], + "query": "a,b,c,d", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Panel Tests - DashList variables", + "uid": "a6801696-cc53-4196-b1f9-2403e3909185", + "version": 1, + "weekStart": "" +} diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index 959a28a7dad..0eb1ac5a7f0 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -149,6 +149,13 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('dashlist_url_variables', import '../dev-dashboards/panel-dashlist/dashlist_url_variables.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, dashboard.new('datadata-macros', import '../dev-dashboards/feature-templating/datadata-macros.json') + resource.addMetadata('folder', 'dev-dashboards') + { diff --git a/e2e/panels-suite/dashlist.spec.ts b/e2e/panels-suite/dashlist.spec.ts new file mode 100644 index 00000000000..066d7c44d84 --- /dev/null +++ b/e2e/panels-suite/dashlist.spec.ts @@ -0,0 +1,37 @@ +import { e2e } from '../utils'; +const PAGE_UNDER_TEST = 'a6801696-cc53-4196-b1f9-2403e3909185/panel-tests-dashlist-variables'; + +describe('DashList panel', () => { + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); + }); + + // this is to prevent the fix for https://github.com/grafana/grafana/issues/76800 from regressing + it('should pass current variable values correctly when `Include current template variable values` is set', () => { + e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST }); + + // check the initial value of the urls contain the variable value correctly + e2e.components.Panels.Panel.title('Dashboard list panel') + .should('be.visible') + .within(() => { + cy.get('a').each(($el) => { + cy.wrap($el).should('have.attr', 'href').and('contain', 'var-query0=a'); + }); + }); + + // update variable to b + e2e.pages.Dashboard.SubMenu.submenuItemLabels('query0').click(); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('b').click(); + // blur the dropdown + cy.get('body').click(); + + // check the urls are updated with the new variable value + e2e.components.Panels.Panel.title('Dashboard list panel') + .should('be.visible') + .within(() => { + cy.get('a').each(($el) => { + cy.wrap($el).should('have.attr', 'href').and('contain', 'var-query0=b'); + }); + }); + }); +}); diff --git a/public/app/plugins/panel/dashlist/DashList.tsx b/public/app/plugins/panel/dashlist/DashList.tsx index 9f773eb0099..1b03c175743 100644 --- a/public/app/plugins/panel/dashlist/DashList.tsx +++ b/public/app/plugins/panel/dashlist/DashList.tsx @@ -1,9 +1,18 @@ import { take } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; -import { DateTime, InterpolateFunction, PanelProps, textUtil, UrlQueryValue, urlUtil } from '@grafana/data'; +import { + DateTime, + InterpolateFunction, + PanelProps, + textUtil, + UrlQueryMap, + UrlQueryValue, + urlUtil, +} from '@grafana/data'; import { CustomScrollbar, useStyles2, IconButton } from '@grafana/ui'; import { getConfig } from 'app/core/config'; +import { appEvents } from 'app/core/core'; import { setStarred } from 'app/core/reducers/navBarTree'; import { getBackendSrv } from 'app/core/services/backend_srv'; import impressionSrv from 'app/core/services/impression_srv'; @@ -11,6 +20,7 @@ import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { DashboardSearchItem } from 'app/features/search/types'; import { getVariablesUrlParams } from 'app/features/variables/getAllVariableValuesForUrl'; +import { VariablesChanged } from 'app/features/variables/types'; import { useDispatch } from 'app/types'; import { Options } from './panelcfg.gen'; @@ -89,9 +99,29 @@ async function fetchDashboards(options: Options, replaceVars: InterpolateFunctio return dashMap; } +function useVariablesForURL(subscribe: boolean) { + const [variables, setVariables] = useState(() => getVariablesUrlParams()); + + useEffect(() => { + if (!subscribe) { + return; + } + + const sub = appEvents.subscribe(VariablesChanged, () => { + setVariables(getVariablesUrlParams()); + }); + + return () => sub.unsubscribe(); + }, [subscribe]); + + return variables; +} + export function DashList(props: PanelProps) { const [dashboards, setDashboards] = useState(new Map()); const dispatch = useDispatch(); + const urlVariables = useVariablesForURL(props.options.includeVars); + useEffect(() => { fetchDashboards(props.options, props.replaceVariables).then((dashes) => { setDashboards(dashes); @@ -156,7 +186,7 @@ export function DashList(props: PanelProps) { if (props.options.includeVars) { params = { ...params, - ...getVariablesUrlParams(), + ...urlVariables, }; }