DataLinks: Default to percentEncoding (#64841)

This commit is contained in:
Ryan McKinley 2023-03-17 06:51:06 -07:00 committed by GitHub
parent 7d1ebe6b75
commit b39039eadd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 10 deletions

View File

@ -2,6 +2,8 @@ import { isNumber, set, unset, get, cloneDeep } from 'lodash';
import { useMemo, useRef } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import { VariableFormatID } from '@grafana/schema';
import { compareArrayValues, compareDataFrameStructures, guessFieldTypeForField } from '../dataframe';
import { getTimeField } from '../dataframe/processDataFrame';
import { PanelPlugin } from '../panel/PanelPlugin';
@ -455,7 +457,6 @@ export const getLinksSupplier =
replaceVariables,
});
}
let href = link.onBuildUrl
? link.onBuildUrl({
origin: field,
@ -464,8 +465,8 @@ export const getLinksSupplier =
: link.url;
if (href) {
locationUtil.assureBaseUrl(href.replace(/\n/g, ''));
href = replaceVariables(href, variables);
href = locationUtil.assureBaseUrl(href.replace(/\n/g, ''));
href = replaceVariables(href, variables, VariableFormatID.PercentEncode);
href = locationUtil.processUrl(href);
}

View File

@ -749,6 +749,29 @@ export type TimeZoneUtc = 'utc';
*/
export type TimeZoneBrowser = 'browser';
/**
* Optional formats for the template variable replace functions
* See also https://grafana.com/docs/grafana/latest/dashboards/variables/variable-syntax/#advanced-variable-format-options
*/
export enum VariableFormatID {
CSV = 'csv',
Date = 'date',
Distributed = 'distributed',
DoubleQuote = 'doublequote',
Glob = 'glob',
HTML = 'html',
JSON = 'json',
Lucene = 'lucene',
PercentEncode = 'percentencode',
Pipe = 'pipe',
QueryParam = 'queryparam',
Raw = 'raw',
Regex = 'regex',
SQLString = 'sqlstring',
SingleQuote = 'singlequote',
Text = 'text',
}
export interface DataSourceRef {
/**
* The plugin type-id

View File

@ -0,0 +1,37 @@
package common
// Optional formats for the template variable replace functions
// See also https://grafana.com/docs/grafana/latest/dashboards/variables/variable-syntax/#advanced-variable-format-options
VariableFormatID:
// Values are lucene escaped and multi-valued variables generate an OR expression
"lucene" |
// Raw values
"raw" |
// Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression
"regex" |
// Values are separated by | character
"pipe" |
// Multiple values are formatted like variable=value
"distributed" |
// Comma seperated values
"csv" |
// HTML escaped
"html" |
// JSON values
"json" |
// Percent encode
"percentencode" |
// Single quote
"singlequote" |
// Double quote
"doublequote" |
// SQL string quoting and commas for use in IN statements and other scenarios
"sqlstring" |
// Date
"date" |
// Format multi-valued variables using glob syntax, example {value1,value2}
"glob" |
// Format variables in their text representation. Example in multi-variable scenario A + B + C.
"text" |
// Format variables as URL parameters. Example in multi-variable scenario A + B + C => var-foo=A&var-foo=B&var-foo=C.
"queryparam" @cuetsy(kind="enum",memberNames="Lucene|Raw|Regex|Pipe|Distributed|CSV|HTML|JSON|PercentEncode|SingleQuote|DoubleQuote|SQLString|Date|Glob|Text|QueryParam")

View File

@ -122,15 +122,15 @@ describe('getFieldLinksSupplier', () => {
expect(links).toMatchInlineSnapshot(`
[
{
"href": "http://go/100.200 kW",
"href": "http://go/100.200%20kW",
"title": "By Name",
},
{
"href": "http://go/100.200 kW",
"href": "http://go/100.200%20kW",
"title": "By Index",
},
{
"href": "http://go/100.200 kW",
"href": "http://go/100.200%20kW",
"title": "By Title",
},
{
@ -146,7 +146,7 @@ describe('getFieldLinksSupplier', () => {
"title": "Unknown Field",
},
{
"href": "http://go/Hello Templates",
"href": "http://go/Hello%20Templates",
"title": "Data Frame name",
},
{

View File

@ -20,6 +20,7 @@ import {
VariableSuggestionsScope,
} from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { FormatRegistryID } from '@grafana/scenes';
import { getConfig } from 'app/core/config';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
@ -304,7 +305,7 @@ export class LinkSrv implements LinkService {
};
if (replaceVariables) {
info.href = replaceVariables(info.href);
info.href = replaceVariables(info.href, undefined, FormatRegistryID.percentEncode);
info.title = replaceVariables(link.title);
}

View File

@ -1,6 +1,7 @@
import { dateTime, TimeRange } from '@grafana/data';
import { setDataSourceSrv } from '@grafana/runtime';
import { FormatRegistryID, TestVariable } from '@grafana/scenes';
import { VariableFormatID } from '@grafana/schema';
import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput';
import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv';
@ -388,12 +389,12 @@ describe('templateSrv', () => {
});
it('multi value and csv format should render csv string', () => {
const result = _templateSrv.formatValue(['test', 'test2'], 'csv');
const result = _templateSrv.formatValue(['test', 'test2'], VariableFormatID.CSV);
expect(result).toBe('test,test2');
});
it('multi value and percentencode format should render percent-encoded string', () => {
const result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode');
const result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], VariableFormatID.PercentEncode);
expect(result).toBe('%7Bfoo%28%29bar%20BAZ%2Ctest2%7D');
});