From 5398ef11033c533bb706bf01bab3eda9ef9512c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 13 Aug 2020 14:38:27 +0200 Subject: [PATCH] Templating: Fixed recursive url update issue for textbox variable (#26981) * Templating: Fixed recursive url update issue for textbox variable * Updated link * updated e2e --- .../global-variables-and-interpolation.json | 2 +- .../testdata-variables-textbox.json | 235 ++++++++++++++++++ e2e/suite1/specs/dashboard-templating.spec.ts | 4 +- .../src/components/Table/DefaultCell.tsx | 39 ++- public/app/core/services/bridge_srv.ts | 10 +- 5 files changed, 263 insertions(+), 27 deletions(-) create mode 100644 devenv/dev-dashboards/feature-templating/testdata-variables-textbox.json diff --git a/devenv/dev-dashboards/feature-templating/global-variables-and-interpolation.json b/devenv/dev-dashboards/feature-templating/global-variables-and-interpolation.json index acd403af6ac..1a8dd87b76a 100644 --- a/devenv/dev-dashboards/feature-templating/global-variables-and-interpolation.json +++ b/devenv/dev-dashboards/feature-templating/global-variables-and-interpolation.json @@ -104,7 +104,7 @@ "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", - "title": "Global variables and interpolation", + "title": "Templating - Global variables and interpolation", "uid": "HYaGDGIMk", "version": 5 } diff --git a/devenv/dev-dashboards/feature-templating/testdata-variables-textbox.json b/devenv/dev-dashboards/feature-templating/testdata-variables-textbox.json new file mode 100644 index 00000000000..10a26d6b6b5 --- /dev/null +++ b/devenv/dev-dashboards/feature-templating/testdata-variables-textbox.json @@ -0,0 +1,235 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1597300832273, + "links": [], + "panels": [ + { + "datasource": "CsvData", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Query" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Search", + "url": "/d/spVR9LSMk/templating-textbox-and-data-links?var-query=${__value.raw:percentencode}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "showHeader": true + }, + "pluginVersion": "7.2.0-pre", + "targets": [ + { + "data": [ + { + "fields": [ + { + "config": {}, + "name": "Query", + "type": "string", + "values": ["Contains+Plus", "Contains&Ampersand", "Contains white space"] + }, + { + "config": {}, + "name": " Test", + "type": "string", + "values": ["asd", "asd", "asd"] + } + ] + } + ], + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Data", + "type": "table" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "${query}", + "refId": "A", + "scenarioId": "random_walk" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Query: ${query}", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": ["gdev", "templating"], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "asdasda+", + "value": "asdasda+" + }, + "hide": 0, + "label": null, + "name": "query", + "options": [ + { + "selected": true, + "text": "asdasda+", + "value": "asdasda+" + } + ], + "query": "asdasda+", + "skipUrlSync": false, + "type": "textbox" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] + }, + "timezone": "", + "title": "Templating - Textbox & data links", + "uid": "spVR9LSMk", + "version": 9 +} diff --git a/e2e/suite1/specs/dashboard-templating.spec.ts b/e2e/suite1/specs/dashboard-templating.spec.ts index 134fecd5e15..91fd9c372a4 100644 --- a/e2e/suite1/specs/dashboard-templating.spec.ts +++ b/e2e/suite1/specs/dashboard-templating.spec.ts @@ -12,8 +12,8 @@ e2e.scenario({ const items: any = []; const expectedItems: string[] = [ - '__dashboard = Global variables and interpolation', - '__dashboard.name = Global variables and interpolation', + '__dashboard = Templating - Global variables and interpolation', + '__dashboard.name = Templating - Global variables and interpolation', '__dashboard.uid = HYaGDGIMk', '__org.name = Main Org.', '__org.id = 1', diff --git a/packages/grafana-ui/src/components/Table/DefaultCell.tsx b/packages/grafana-ui/src/components/Table/DefaultCell.tsx index 09ad685b71b..41ba509b7ea 100644 --- a/packages/grafana-ui/src/components/Table/DefaultCell.tsx +++ b/packages/grafana-ui/src/components/Table/DefaultCell.tsx @@ -1,7 +1,6 @@ import React, { FC } from 'react'; import { TableCellProps } from './types'; import { formattedValueToString, LinkModel } from '@grafana/data'; -import { Tooltip } from '../Tooltip/Tooltip'; export const DefaultCell: FC = props => { const { field, cell, tableStyles, row } = props; @@ -19,27 +18,25 @@ export const DefaultCell: FC = props => { return (
{link ? ( - - { - // Allow opening in new tab - if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) { - event.preventDefault(); - link!.onClick(event); - } + { + // Allow opening in new tab + if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) { + event.preventDefault(); + link!.onClick(event); } - : undefined - } - target={link.target} - title={link.title} - className={tableStyles.tableCellLink} - > - {value} - - + } + : undefined + } + target={link.target} + title={link.title} + className={tableStyles.tableCellLink} + > + {value} + ) : ( value )} diff --git a/public/app/core/services/bridge_srv.ts b/public/app/core/services/bridge_srv.ts index bde6894c1d3..6ba9d98dbdc 100644 --- a/public/app/core/services/bridge_srv.ts +++ b/public/app/core/services/bridge_srv.ts @@ -82,9 +82,13 @@ export class BridgeSrv { }); } - // Check for template variable changes on a dashboard - if (state.location.path === this.lastPath) { + // if only query params changed, check if variables changed + if (state.location.path === this.lastPath && state.location.query !== this.lastQuery) { + // Find template variable changes const changes = findTemplateVarChanges(state.location.query, this.lastQuery); + // Store current query params to avoid recursion + this.lastQuery = state.location.query; + if (changes) { const dash = getDashboardSrv().getCurrent(); if (dash) { @@ -93,8 +97,8 @@ export class BridgeSrv { } } - this.lastQuery = state.location.query; this.lastPath = state.location.path; + this.lastQuery = state.location.query; this.lastUrl = state.location.url; });