From af390e823b9618d7441ea6dea11fbfd68ba690de Mon Sep 17 00:00:00 2001 From: "flashduty[bot]" Date: Wed, 30 Sep 2026 16:53:34 +0000 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20doc-review=202026-09-30=20(diff)=20?= =?UTF-8?q?=E2=80=94=20dashboards=20page,=20RUM=20repository=20linking,=20?= =?UTF-8?q?on-prem=20license=20reminders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Daily incremental doc review for 2026-09-29T08:04:41Z → 2026-09-30T16:35Z against the mapped source repos. 11 findings (2 high, 5 medium, 4 low); 9 applied. - new page zh|en/monitors/dashboards/dashboards.mdx (+ docs.json nav in both languages) for the Monitors 仪表盘 surface, which had no page at all - RUM 应用 代码仓库 tab documented; 远程配置 account rollout gate corrected - Slack AISRE bot scope table gains files:read - on-prem License expiry reminders documented - two new session attributes for the RUM explorer - 2026-09-30 changelog entry - flagship change_key instance-scope caveat --- docs.json | 14 + en/ai-sre/apps.mdx | 4 + en/changelog/changelog.mdx | 28 ++ en/monitors/dashboards/dashboards.mdx | 288 ++++++++++++++++++ .../integration/instant-messaging/slack.mdx | 3 + en/platform/pricing.mdx | 27 ++ en/rum/explorer/data-query.mdx | 10 + en/rum/quickstart/app-management.mdx | 50 ++- zh/ai-sre/apps.mdx | 4 + zh/changelog/changelog.mdx | 28 ++ zh/monitors/dashboards/dashboards.mdx | 288 ++++++++++++++++++ .../integration/instant-messaging/slack.mdx | 3 + zh/platform/pricing.mdx | 27 ++ zh/rum/explorer/data-query.mdx | 10 + zh/rum/quickstart/app-management.mdx | 50 ++- 15 files changed, 832 insertions(+), 2 deletions(-) create mode 100644 en/monitors/dashboards/dashboards.mdx create mode 100644 zh/monitors/dashboards/dashboards.mdx diff --git a/docs.json b/docs.json index 9410da20f..f551a53a0 100644 --- a/docs.json +++ b/docs.json @@ -2132,6 +2132,13 @@ "zh/monitors/explore/explore" ] }, + { + "group": "仪表盘", + "icon": "chart-line", + "pages": [ + "zh/monitors/dashboards/dashboards" + ] + }, { "group": "实体树", "icon": "sitemap", @@ -3628,6 +3635,13 @@ "en/monitors/explore/explore" ] }, + { + "group": "Dashboards", + "icon": "chart-line", + "pages": [ + "en/monitors/dashboards/dashboards" + ] + }, { "group": "Entity Tree", "icon": "sitemap", diff --git a/en/ai-sre/apps.mdx b/en/ai-sre/apps.mdx index 6f1edfb4d..afec858c4 100644 --- a/en/ai-sre/apps.mdx +++ b/en/ai-sre/apps.mdx @@ -27,6 +27,10 @@ AI SRE sessions run in a **Flashduty cloud sandbox** by default. The sandbox is **BYOC (self-hosted Runner) generally doesn't need it.** A Runner runs on your own machine, which usually **already has `gh` / `glab` / `git` credentials configured** (you work with repositories on it every day). In that case the agent just uses the host's own credentials — **no App authorization needed**. (If the host happens to have no credentials configured, authorizing the App lets BYOC sessions use it too.) For the differences between environments, see [Environments (BYOC)](/en/ai-sre/environments). + +A RUM application can also record the repositories that build it (several may be linked; the first one is the primary), so that AI goes straight to the code when it analyses a RUM problem — see [Application Management · Code repositories](/en/rum/quickstart/app-management#code-repositories). Linking a repository there **grants no access by itself**: what a cloud AI session can read is still only what is authorized for the account here. + + ## Where to Find It --- diff --git a/en/changelog/changelog.mdx b/en/changelog/changelog.mdx index f4e7f750f..46f7fb140 100644 --- a/en/changelog/changelog.mdx +++ b/en/changelog/changelog.mdx @@ -4,6 +4,34 @@ description: "This page documents important updates and feature releases for Fla keywords: ["Changelog", "Product Release", "Feature Updates", "Flashduty", "Version History"] --- + + +### Monitors dashboards: comparisons, cross-panel cursor linking and point-value filtering + +A dashboard panel's query options gain **Compare** (period-over-period): "Previous 1 day / Previous 1 week" re-runs the same query over the window one period earlier — a time-series panel overlays a same-colour dashed line (the legend reads "N days ago / N weeks ago") and a stat panel shows the change against that period; only time-series and stat panels offer the setting, and a failed comparison query only drops the comparison line without affecting the current result. Time-series panels on one dashboard now share a cursor: moving the pointer over any of them draws the vertical line and dots at the same timestamp on all of them, with the tooltip only on the hovered panel (panels with a relative time or a time shift do not take part). When a data point's label — or a table's label column — has the same name as a dashboard variable, the click menu offers "Filter dashboard by k = v", which is the same as selecting that value in the variable bar and refreshes the whole dashboard (datasource variables are excluded); version history now matches an alert rule's change log — tick two versions, **Compare** their saved JSON, then restore. See [Dashboards](/en/monitors/dashboards/dashboards). + +### RUM applications can link to code repositories + +The RUM application detail page gains a **Code repositories** tab that links an application to the GitHub repositories that build it, so AI analysis can go straight to the code: up to 10 repositories, kept in order with the first one primary (use **Set as primary** to reorder), each entered as `owner/name` (a GitHub web or clone URL is accepted too) plus the directory holding the app inside that repository (defaults to `.`, at most 255 characters). Linking **grants no access by itself**: cloud AI sessions can only read repositories granted to the account's GitHub App installations, entries outside that grant carry a warning and a link to grant more, and manually entered repositories only help local (BYOC) AI; the tab appears only when AI SRE is enabled for the account. See [Application Management](/en/rum/quickstart/app-management#code-repositories). + +### Remote Configuration opens to every account + +The RUM application **Remote Configuration** tab is now open to every account instead of rolling out account by account: the account-level switch that decided which accounts could see the tab has been removed, and whether the tab appears depends only on whether the application's platform supports that channel. The previous advice to contact support when the tab is missing no longer applies. See [Application Management](/en/rum/quickstart/app-management#remote-configuration). + +### AI SRE sessions understand RUM issues as context + +AI SRE sessions gain a **RUM issue** context-ref kind (bug icon): entering a session through the **AI fix** button at the top right of a RUM issue detail page carries that capsule into the input box and pre-fills a fix question — fetch the issue's context through the issue-fix flow, then locate the failing code in the repositories linked to the application; when the root cause is confirmed and the change is safe, create a branch and submit a Draft PR that links the issue, and otherwise report only the analysis and recommendation, never pushing to the default branch. See [Sessions · Attachments and Context References](/en/ai-sre/sessions#attachments-and-context-references). + +### On-premises License expiry reminders + +Before an on-premises License expires, the platform reminds the contacts registered for the deployment: once each when **10, 3 and 1 days** remain (at most three per License), every contact's email address receives the reminder email and contacts with a valid mainland China phone number also receive an SMS, sent only between **08:00 and 22:00 Beijing time**, and Licenses that expired more than 7 days ago are skipped. The reminder email is fixed Chinese copy, and once the License expires the platform **stops ingesting data**; to renew, paste the new License into the License prompt in the console sidebar — the console reports "License updated, will take effect in 5 minutes" — with no service restart. See [Pricing · On-Premises License expiry and renewal](/en/platform/pricing#on-premises-license-expiry-and-renewal). + +### 46 new alert sources and 9 new change integrations + +This window registered **46 alert sources** (CrowdStrike, BigPanda, Monte Carlo, Falco, Gatus, OpenSearch and more) and **9 change integrations** (Argo Rollouts, Azure DevOps, Bitbucket, CircleCI, Flagsmith, Gitea, Octopus Deploy, Rundeck and Unleash). How to connect them and what they map are covered by [Alert sources](/en/on-call/integration/alert-integration/alert-sources/standard-alert) and [Change integrations](/en/on-call/integration/change-integration/custom-event). + + + ### AI SRE billing goes live diff --git a/en/monitors/dashboards/dashboards.mdx b/en/monitors/dashboards/dashboards.mdx new file mode 100644 index 000000000..1672c3242 --- /dev/null +++ b/en/monitors/dashboards/dashboards.mdx @@ -0,0 +1,288 @@ +--- +title: "Dashboards" +description: "Turn queries into dashboard panels in Flashduty Monitors: folder organisation, template variables, period-over-period comparison, cross-panel cursor linking, click-to-filter, version history and restore." +keywords: ["dashboard", "panel", "template variables", "comparison", "version history", "drill-down"] +--- + +A dashboard turns queries into charts: it is made of tabs, sections and panels, and each panel binds one data source with a set of queries, evaluated live for the current time range and variable selections every time it opens. It is the right place to pin down the few charts you keep opening for routine inspection and incident review, instead of rewriting the queries in the [Query Workbench](/en/monitors/explore/explore) every time. + +## Overview and entry points + +- **Menu entry**: **Visualization → Dashboards** in the left menu (frontend route `/monit/dashboards`). Both the menu item and the page routes are gated on the "Datasource Visit" permission, so anyone who can see data sources can see the dashboard entry. +- **From the Query Workbench**: a query that has produced a result can be saved straight to a dashboard through **Save to dashboard**, see [Create and save a dashboard](#create-and-save-a-dashboard). + +Access to a dashboard is decided by the **folder** it lives in, not by the dashboard itself: reads inherit the folder read permission, while write operations require the "Dashboard Manage" permission plus read access to the folder. See [Permissions](#permissions). + +## List and folders + +**Menu entry**: Visualization → Dashboards + +The left side is the folder tree shared with alert rules (the same `/monit/folder/list` API), and the right side lists the dashboards in the selected folder. Creating, renaming, moving and deleting folders all happen on that tree, and are governed by folder permissions — see [Folder management](/en/monitors/folders/folders). + +| Column | Description | +|--------|-------------| +| **Title** | Dashboard name; click to open the viewer | +| **Updated by** | The user who last saved this dashboard | +| **Updated at** | Time of the last save | +| **Actions** | Shown with the "Dashboard Manage" permission: edit, delete, and the **More** menu (Move to another folder / Clone in this folder / Clone to another folder) | + +- **The search box only searches the current folder**, never across folders. Input is debounced by 300 ms, and the folder, search term and page number are all reflected in the URL (`folder_id`, `q`), so a list link can be shared and survives a refresh. Clicking the breadcrumb in the viewer returns you to the list with the same conditions you left it in. +- **Paging** defaults to 20 rows per page. +- An empty folder shows "No dashboards in this folder yet", and users with manage permission can create one straight from that empty state. + +## Create and save a dashboard + +**Create**: **New dashboard** at the top right of the list page (manage permission required), which opens `/monit/dashboards/new?edit=1`. A new dashboard starts with the title "Untitled dashboard", a default time range of the last hour, auto-refresh off, a single tab titled `Overview`, and no panels. + +**Save from the Query Workbench**: the workbench's **Save to dashboard** button turns the current query into a panel. In the dialog you can choose: + +| Option | Description | +|--------|-------------| +| **New dashboard** | Pick a folder and type a dashboard title; the dashboard is really created in that folder first, then opened in edit mode | +| **Existing dashboard** | Pick a folder, then pick one of the dashboards in it; the dashboard opens in edit mode with this panel appended to the bottom of its first tab — **nothing is written until you save** | +| **Panel title** | Panel name; empty means "Untitled panel" | +| **Visualization** | Recommended from the last successful result (logs → Logs, sampled time series → Time series, otherwise → Table), and changeable | + +Prometheus runs both a range and an instant query in the workbench (Both); when the panel is saved it is stored as `Range` with the notice "Query type Both was saved as Range" — dashboards do not accept Both. + +**Edit mode** works on a whole-dashboard draft kept in the browser: + +- The header lets you change the folder (new dashboards only) and the title; on the right are the time range, undo / redo (`⌘Z` / `⌘⇧Z`), cancel and save. +- Every change (adding a panel, dragging the layout, editing variables or configuration) goes into the draft, one undo step per action, and is **lost when you refresh** (there is no server-side draft); leaving the page with unsaved changes is intercepted with "The draft is not saved. Leave anyway?". +- **Save**: the title is required, and a new dashboard also requires a folder. The dialog takes an optional **version message** (up to 1024 characters) and states "The full definition will be submitted as a new revision (current vN)". The whole definition is submitted and a successful save creates a new revision; when the server finds nothing changed it reports "No changes". For an existing dashboard with no changes the save button is disabled. +- **Use the current time range as the dashboard default**: when the range you browsed with is one of the relative presets (15m / 30m / 1h / 3h / 6h / 12h / 24h / 7d) and differs from the stored default, the save dialog offers the checkbox "Set current time range (…) as dashboard default". +- **Concurrent edits**: if someone saved while you were editing, the save fails with "Dashboard was updated by someone else" and three options: **Save as copy…** (pick a folder and save a second copy), **Discard draft and load latest** (drop your draft and return to the viewer), or **Keep editing** (keep the draft — it is never merged automatically). +- **Validation failure**: a "Save failed: definition validation errors" dialog lists each offending JSON Pointer path with its reason. + +**The remaining list actions**: + +| Action | Description | +|--------|-------------| +| **Clone in this folder / Clone to another folder** | Builds a second dashboard from the full definition (new ID, title suffixed with "(copy)") and **does not carry history** | +| **Move to another folder** | Changes the folder; the destination must be readable | +| **Edit** | Opens the dashboard in edit mode | +| **Delete** | See [Delete and trash](#delete-and-trash) | + +## Tabs, sections and panel layout + +- **Tabs** are the top-level divisions of a dashboard: one by default, at most 10. Double-click a tab title to rename it; deleting a tab asks for confirmation first and reports "Contains N sections and M panels." +- **Sections** sit inside a tab, like Grafana rows: the title row is always visible and the section can be collapsed. **A collapsed section loads no data**, and its header reads "(N panels · collapsed, not loading)". A tab holds at most 10 sections. +- **Panels** are laid out on a 24-column grid. A new panel is `12×8` and lands at the bottom of its container; on the canvas you can drag, resize, duplicate (the copy is inserted below the original) and delete them. +- A tab holds at most 30 panels and a whole dashboard at most 100. +- A panel can carry a description next to its title: by default it is tucked into the ⓘ tooltip, and the panel option **Use as subtitle** moves it below the title. Descriptions render Markdown like text panels do, without images or raw HTML. +- An empty canvas points you at "Start with your first chart / Pick a datasource, write a query, and refine with live preview", with **Add panel** and **New section** buttons. + +Panels are **lazy-loaded**: only the panels of the active tab and of expanded sections are scheduled, at most 4 queries are in flight at once, and panels inside the viewport go first. While refreshing, the previous chart stays on screen at half opacity; only the very first load shows a skeleton. + +## Panel types and queries + +The panel editor shows a preview on the left and configuration on the right, grouped like Grafana: panel / legend / graph styles / standard options / thresholds / drill-down. **Visualization** offers seven types: + +| Visualization | Description | Selectable | +|---------------|-------------|-----------| +| **Time series** | Trends over time; compare multiple series | Yes | +| **Table** | Rows and columns of details; good for instant queries | Yes | +| **Stat** | One key number with threshold coloring | Yes | +| **Text** | Markdown notes, without a data source or queries | Yes | +| **Bar** | Compare values across categories | Greyed out, marked "Coming in a later release" | +| **Gauge** | Where a value sits within a range | Greyed out, marked "Coming in a later release" | +| **Logs** | Stream of log lines | Greyed out, marked "Coming in a later release" | + +Bar, gauge and logs are supported by the backend contract but have no renderer in the console yet, so they cannot be selected in the type picker. If you saved a Logs panel through the workbench's "Save to dashboard", the viewer shows "This visualization (logs) will be supported in a later release". + +The **datasource** dropdown only lists the types a dashboard can query at runtime — **prometheus, mysql, loki** (the same set as Dashboard Runtime; diagnostic-only data source types never appear) — and a panel can reference either a **fixed datasource** or a **datasource variable** (switch the variable to move every panel that uses it to another datasource). + +The **query type** follows from the data source and the visualization and is not chosen by hand: MySQL data sources run a time-window query (`window`), tables take an instant snapshot (`instant`), and time series and stats take a range (`range`). + +| Setting | Description | +|---------|-------------| +| **Query expression** | Supports `${variable}` templates; PromQL data sources prompt for a PromQL query, other types prompt by type | +| **Multiple queries** | Queries are labelled `A`~`Z`; only time series support more than one. Switching to any other visualization forces you to pick which one to keep, and the rest are removed | +| **Series name** | Shown for time series only. Sets the display name used by the legend, tooltip and data links; `{{instance}}` is replaced with that series' `instance` label value, and leaving it empty shows all labels. If both the legend and the tooltip are hidden, the editor tells you the setting is invisible | +| **Min step** | Shown for Prometheus range queries only. A lower bound for the query step, 15s by default (matching Prometheus' default scrape interval); it is dropped when you switch to a data source or query type that does not accept it | +| **Value fields** | Which fields a stat panel shows as values (several are shown side by side, names are case-sensitive); a Prometheus result has only `value`, so a Prometheus stat is fixed to it | +| **Unit / decimals / thresholds** | Threshold direction "Higher is worse / Lower is worse", with warning and critical levels colored as text or as background | +| **Table column configuration** | Tables configure unit, thresholds and coloring per numeric column; a Prometheus table has only the `value` column to configure. Coloring can be "None / Text / Background", and a background-colored column can be **applied to the entire row** | +| **Value mappings** | Turn numbers into text and color (e.g. show 0 as "Offline" in red). The first matching mapping from the top wins, and its color overrides threshold colors | +| **Drill-down** | Panel links and data links, see [Click-to-filter and drill-down links](#click-to-filter-and-drill-down-links) | + +### Panel-level query options + +**Query options** sit next to the datasource and apply to **every query on the panel** (A / B share them): + +| Option | Description | +|--------|-------------| +| **Max data points** | Maximum points per series, which sets the query step (time range ÷ max data points). Leave it empty to derive it from the panel width; the placeholder shows the value currently in effect | +| **Relative time** | This panel always queries the last N and ignores the dashboard time range — e.g. `5m` always shows the last 5 minutes | +| **Time shift** | Shifts the whole query range back by N, e.g. `1d` to compare with the same time yesterday | +| **Compare** | Period-over-period comparison, see [Period-over-period comparison](#period-over-period-comparison) | + +Durations are always written as a number plus a unit (`s` / `m` / `h` / `d` / `w`), such as `5m`, `1h`, `1d`; an invalid value turns the input red with "Use a duration like 5m, 1h or 1d". A panel with a relative time or a time shift is marked next to its title in blue with the range it actually queries (e.g. "Last 5 minutes · timeshift -1d"), so viewers can tell it does not follow the dashboard time range. + +Previewing happens live inside the panel editor: editing the query itself runs it on Enter (or `⌘/Ctrl + Enter`), while changing the datasource, visualization or time re-runs it automatically; display settings (unit, thresholds, alias and so on) apply immediately without re-querying. **Saving does not require a successful preview.** On a new dashboard with no folder selected yet, the preview area shows "Select a folder before previewing". + +## Template variables + +The variable bar sits above the canvas and uses the same filter control as the rest of the product: each variable is a permanent filter field, single- or multi-select according to its configuration. In edit mode the bar has a **Manage variables** button at the end, opening a drawer where every variable can be added, edited or deleted. + +There are three **variable kinds**: + +| Kind | Where values come from | Settings | +|------|------------------------|----------| +| **Datasource** | One concrete data source | Datasource type (only prometheus / mysql / loki) and default datasource | +| **Custom** | A hand-written candidate list | Options (one per line, `text=value` or a bare value) | +| **Query** | Candidates fetched by querying a data source | Datasource (fixed or a datasource variable) + query definition + when to refresh candidates | + +A **Query variable's candidate query** has three flavours by data source type: Prometheus needs `label` (required) and `metric` (optional) plus any number of **label filters** using `= / != / =~ / !~`; SQL data sources take an expression and a value field; Loki takes an expression and a field. **Preview candidates** in the drawer fetches candidates once with the current configuration to confirm the datasource and query are right, and shows the failure reason next to the variable when they are not. + +**Names and references**: a variable name must match `^[A-Za-z_][A-Za-z0-9_]{0,63}$`, and a name already in use is rejected. Renaming is an atomic frontend refactor — every `${oldName}` reference (query expressions, query args, datasource variable references and the variable's own candidate query) is rewritten, and the editor warns "N references will be rewritten" before doing it. A variable that is still referenced cannot be deleted: "Variable x is referenced in N places; remove the references first." A dashboard holds at most 20 variables. + +**Selection mode and the 「All」 option**: + +- **Single**: must hold one concrete value, defaulting to the first candidate when the dashboard opens. +- **Multi**: may be left empty, and **empty means everything**; the control then shows the placeholder "All". "All" is not a candidate — it is the state of having no concrete selection, so candidates added later are not implied by it, and there is no "select all" button. +- **Clearing means All**: a variable that allows "All" has its own clear affordance (the × on the tag, or "clear" in the dropdown), and clearing writes an explicit All rather than falling back to the default. A variable that does not allow "All" has no clear affordance and must always keep a concrete value. +- When a dashboard opens, a variable with no value in the URL first takes its default; with no default it falls back to the first candidate (or to All for a variable that allows it), and that selection is written back to the URL. +- **Values outside the candidate list** (carried in by a URL or by an alert entry point) still run normally: the control shows them as "value (not in candidates)" with a warning, and does not block the query. + +The URL is the single source of truth for variable selections: a single value is written as `var-=value`, several values as repeated parameters, and All as `var-=$__all` — the same parameters a dashboard URL uses, so a link can be shared with its variable selections attached. + +## Time range and auto-refresh + +- The **time range** comes from the URL's `from` / `to`, either absolute milliseconds or a `now-*` relative expression; with no URL parameters the stored **default time range** applies (the last hour for a new dashboard, and one of eight presets — 15m / 30m / 1h / 3h / 6h / 12h / 24h / 7d — when saved, always ending at "now"). +- **Auto-refresh**: the interval stored on the dashboard is one of Off / 30s / 1m / 5m; the viewer's refresh picker offers finer steps (Off / 10s / 30s / 1m / 5m / 15m / 30m / 1h). Picking one writes the `refresh` URL parameter and refreshes immediately rather than waiting a full interval. Relative ranges roll forward with "now" on each refresh, and the refresh button on the left runs a manual refresh at any time, spinning while queries are still running. + +## Period-over-period comparison + +The **Compare** entry in a panel's **query options** makes the same query run a second time over the period one cycle earlier — "1d before" or "1w before" — and merges both results into the same panel. + +- **Supported panels**: only **time series** and **stat** panels have this option; every other visualization has neither the setting nor an extra request. +- **Available periods**: only "1d before" and "1w before", plus "No comparison"; arbitrary durations are not offered. +- **Time series**: the comparison run is drawn as a **dashed line in the same color**, and the legend spells out the period, e.g. `series name (1d ago)`. +- **Stat**: shows the percentage change against the comparison period, e.g. "▲ 12.3% vs 1d ago" (flat values get no arrow, so 0% is not read as a rise); no percentage is shown when the comparison value is 0 or missing. +- **Failure handling**: if the comparison query fails you only lose the comparison line — the current results still render, and the panel's overall state still reflects the current run. + +## Cross-panel cursor linking + +Every **time series** panel in a dashboard shares one cursor synchronisation group: moving the mouse over any of them draws the same **vertical line and points** on the others, which makes it easy to line up several metrics at the same instant. + +- Only mouse move and mouse leave are synchronised, not press and release (otherwise a drag-zoom would zoom every panel), and the **Y axis is not synchronised** — only the vertical line is drawn. +- The tooltip stays on the panel under the mouse; a linked cursor does not raise one. +- **Panels with a relative time or a time shift do not take part** — their time axis differs from the dashboard's, so linking by timestamp would point at the wrong instant. +- The editor's preview canvas and the panel fullscreen view do not link; only the time series in the dashboard grid do. + +## Click-to-filter and drill-down links + +**Click-to-filter**: clicking data in a chart (a point on a time series, a stat, a numeric or label cell in a table) opens an overlay. If the clicked data carries a **label — or table column — whose name matches a dashboard variable**, the overlay offers "Filter by `k = v`", which sets that variable to that value and re-queries the whole dashboard. + +- The variables that can be set this way are all variables **except datasource variables** (a datasource variable is a single-choice datasource selector and does not take part). +- When a time series point carries a timestamp, the overlay header shows the series name (with a copy button), the point's time and its value formatted with the panel's unit. +- Label cells in tables only offer filtering, never drill-down: a drill-down link expands the labels of the whole row or series, so handing it a single label would build a broken URL. + +**Drill-down links (data links)**: with data links configured, clicking data can open an `http(s)://` URL or a site-relative `/` URL, carrying the clicked value, labels and time. The rules are: + +- A time series panel can enable **One click** on one link (clicking data opens it straight away, with no menu; at most one link per panel). A stat or table panel opens the only available link directly and pops a menu when there are several. +- Links are expanded **at click time**: dashboard variables and the time range come from the current view context, while point-related placeholders come from the point that was clicked. Inserted values are URL-encoded, and `${xxx:raw}` splices a value in verbatim when it belongs inside a path. +- Available placeholders: `${__value.raw}` (the point's value), `${__value.time}` (the point's time in ms), `${__series.name}` (series name), `${__field.labels.