Skip to content

[BUGFIX] Expand "$var" inside URL-encoded Explore panel links - #285

Merged
shahrokni merged 1 commit into
perses:mainfrom
colivi:fix/panel-link-vars-encoded-url
Sep 16, 2026
Merged

shahrokni merged 1 commit into
perses:mainfrom
colivi:fix/panel-link-vars-encoded-url

Conversation

@colivi

@colivi colivi commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

[BUGFIX] Expand "$var" inside URL-encoded Explore panel links

Description

Panel links that deep-link into Explore embed PromQL inside the "data=" query parameter. Dashboard template variables such as "$var" are percent-encoded there as "%24var".

"LinksDisplay" already called "useReplaceVariablesInString(link.url)", but only on the raw URL string. "VARIABLE_REGEX" looks for "$(\w+)", so it never matches "%24var". The Explore view then runs PromQL with literal "$var" and returns no series.

Fix: add "replaceVariablesInUrl":

  1. Run "replaceVariables" on the raw URL (unencoded path/query still work).
  2. For each query param value (already decoded once by "URLSearchParams"), run "replaceVariables" again so "$var" inside Explore JSON is expanded.
  3. Re-encode via "searchParams.set".

Files

  • "dashboards/src/utils/replaceVariablesInUrl.ts" (+ unit tests)
  • "dashboards/src/components/LinksDisplay/LinksDisplay.tsx" — "useLink" uses the new helper for "url"

Screenshots

N/A (behavior of existing link menu; no visual layout change).

Before: Explore query contained literal "stack=~"$var"" (empty result).
After: same link opens Explore with the current dashboard variable value substituted inside "data=".

Checklist

  • Pull request has a descriptive title and context useful to a reviewer.
  • Pull request title follows the "[<catalog_entry>] " naming convention using one of the
    following "catalog_entry" values: "FEATURE", "ENHANCEMENT", "BUGFIX", "BREAKINGCHANGE", "DOC","IGNORE".
  • All commits have DCO signoffs.

UI Changes

  • Changes that impact the UI include screenshots and/or screencasts of the relevant changes.
    (No layout change; unit tests cover the URL substitution. Happy to add a short before/after Explore screencast if preferred.)
  • Code follows the UI guidelines.
  • E2E tests are stable and unlikely to be flaky.
    (Covered by unit tests on "replaceVariablesInUrl"; no new E2E — pure string/URL logic, no time or network.)

@colivi
colivi requested a review from a team as a code owner September 9, 2026 14:47
@colivi
colivi force-pushed the fix/panel-link-vars-encoded-url branch 2 times, most recently from 344cb25 to 09173ac Compare September 9, 2026 16:27
@Nexucis
Nexucis requested a balanced review from Copilot September 10, 2026 11:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

URL reconstruction can change link targets and discard repeated query parameters.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes variable expansion inside URL-encoded Explore panel links.

Changes:

  • Adds URL-aware variable replacement with unit tests.
  • Integrates replacement into rendered dashboard and panel links.
  • Exports the new utility.
File summaries
File Description
dashboards/src/utils/replaceVariablesInUrl.ts Adds URL query-variable expansion.
dashboards/src/utils/replaceVariablesInUrl.test.ts Tests URL substitution behavior.
dashboards/src/utils/index.ts Exports the utility.
dashboards/src/components/LinksDisplay/LinksDisplay.tsx Applies the utility to rendered links.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread dashboards/src/utils/replaceVariablesInUrl.ts Outdated
Comment thread dashboards/src/utils/replaceVariablesInUrl.test.ts Outdated
Comment thread dashboards/src/utils/replaceVariablesInUrl.ts Outdated
@AntoineThebaud AntoineThebaud changed the title fix(dashboards): expand $var inside URL-encoded Explore panel links [BUGFIX] Expand "$var" inside URL-encoded Explore panel links Sep 14, 2026
Comment thread dashboards/src/utils/replaceVariablesInUrl.ts Outdated
@colivi
colivi force-pushed the fix/panel-link-vars-encoded-url branch 2 times, most recently from 7d44efd to 6bba7f5 Compare September 15, 2026 17:49
@shahrokni
shahrokni self-requested a review September 16, 2026 11:29
const isAbsolute = /^https?:\/\//i.test(result);
const isProtocolRelative = result.startsWith('//');
// Skip non-http schemes (mailto:, etc.) — only expand via step 1.
if (!isAbsolute && !isProtocolRelative && /^[a-z][a-z0-9+.-]*:/i.test(result)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improvement

For consistency and readability, could you please keep the result following statement in a descriptively named variable?

/^[a-z][a-z0-9+.-]*:/i.test(result)

Comment on lines +268 to +269
const parseInput = isProtocolRelative ? `http:${result}` : result;
const u = new URL(parseInput, isAbsolute || isProtocolRelative ? undefined : 'http://perses.local');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improvement

parsedUrl variable name would be better.

Comment on lines +280 to +284
u.searchParams.delete(key);
for (const v of replacedValues) {
u.searchParams.append(key, v);
}
}

@shahrokni shahrokni Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion

I think there might be a chance that the order of searchParams change. Ideally this should not happen.
Let's add a unit test as well.

Comment on lines +78 to +81
const out = replaceVariablesInUrl('?data=%24var', vars);
expect(out.startsWith('?')).toBe(true);
expect(out).toContain('my-value');
expect(out).not.toContain('%24var');

@shahrokni shahrokni Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improvement

Instead of 3 different expect statements, would it possible to simply compare it with the final string?

Comment on lines +66 to +70
it('leaves absolute URLs absolute', () => {
const url = 'https://example.com/explore?q=$var';
const out = replaceVariablesInUrl(url, vars);
expect(out).toMatch(/^https:\/\/example\.com\/explore\?q=my-value/);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colivi
colivi force-pushed the fix/panel-link-vars-encoded-url branch from d8b5d07 to 554b57f Compare September 16, 2026 12:51
replaceVariables only matched unencoded $name. Explore deep-links put
PromQL in data= where $var is percent-encoded.

- replaceVariablesInUrl next to replaceVariables
- useReplaceVariablesInUrl hook (mirror useReplaceVariablesInString)
- LinksDisplay uses the hook for all dashboard/panel link hrefs
- rebuild query pairs in original order; preserve relative path prefix

Signed-off-by: colivi <charles.olivi@gmail.com>
@colivi
colivi force-pushed the fix/panel-link-vars-encoded-url branch from 554b57f to 713feff Compare September 16, 2026 13:12
@shahrokni
shahrokni merged commit 8e272d1 into perses:main Sep 16, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

4 participants