diff --git a/web/src/composables/dashboard/usePanelDrilldown.bar-gauge.spec.ts b/web/src/composables/dashboard/usePanelDrilldown.bar-gauge.spec.ts index 199c081602..789d6c798e 100644 --- a/web/src/composables/dashboard/usePanelDrilldown.bar-gauge.spec.ts +++ b/web/src/composables/dashboard/usePanelDrilldown.bar-gauge.spec.ts @@ -48,7 +48,13 @@ const store = { }, dispatch: vi.fn(), }; -const drilldown = [{ name: "Logs", type: "byUrl", data: { url: "https://example.com" } }]; +const drilldown = [ + { + name: "Logs", + type: "byUrl", + data: { url: "https://example.com/?name=${series.__name}&value=${series.__value}" }, + }, +]; const field = (alias: string, column: string, functionName: string | null = null) => ({ label: column, @@ -211,11 +217,21 @@ describe("drilldown on the new chart types", () => { expect(params.componentType).toBe("series"); expect(params.dataIndex).not.toBeUndefined(); - const clickedRow = grouped.find((row) => row.x_axis_1 === params.name); - expect(params.data.rawValue).toBe(clickedRow?.y_axis_1); expect(popup.style.display).toBe("block"); expect(api.drilldownArray.value.map((item: any) => item.name)).toEqual(["Logs"]); expect(hideChartTooltip).toHaveBeenCalledTimes(1); + + // The bar is drawn at its 0..1 fill; the resolved URL must carry the row's real value. + const open = vi.spyOn(window, "open").mockReturnValue(null); + await api.openDrilldown(0); + expect(open).toHaveBeenCalledTimes(1); + const url = new URL(String(open.mock.calls[0][0])); + expect(url.searchParams.get("name")).toBe(params.name); + const rowValues = grouped + .filter((row) => row.x_axis_1 === params.name) + .map((row) => row.y_axis_1); + expect(rowValues).toContain(Number(url.searchParams.get("value"))); + open.mockRestore(); }, ); }); diff --git a/web/src/composables/dashboard/usePanelDrilldown.spec.ts b/web/src/composables/dashboard/usePanelDrilldown.spec.ts index d45f9468a7..1d90c3cba0 100644 --- a/web/src/composables/dashboard/usePanelDrilldown.spec.ts +++ b/web/src/composables/dashboard/usePanelDrilldown.spec.ts @@ -508,6 +508,33 @@ describe("usePanelDrilldown", () => { ); }); + it("a gauge dial standing in for a blank label drills down with the blank, not (empty)", async () => { + const deps = makeDeps(); + deps.panelSchema.value.type = "gauge"; + deps.panelSchema.value.config.drilldown = [ + { + name: "Dial", + type: "byUrl", + data: { url: "https://example.com/?axis=${series.__axisValue}&v=${series.__value}" }, + }, + ]; + const openSpy = vi.spyOn(window, "open").mockImplementation(() => null); + const api = usePanelDrilldown(deps as any); + await api.onChartClick({ + componentType: "series", + event: { offsetX: 1, offsetY: 1 }, + seriesName: "series", + name: "(empty)", + value: 88, + data: { name: "(empty)", rawName: "", value: 88 }, + }); + await api.openDrilldown(0); + const url = new URL(String(openSpy.mock.calls[0]?.[0])); + openSpy.mockRestore(); + expect(url.searchParams.get("axis")).toBe(""); + expect(url.searchParams.get("v")).toBe("88"); + }); + describe("heatmap drilldown", () => { const heatmapDeps = (options: any, extras: any = {}) => { const deps = makeDeps(); diff --git a/web/src/composables/dashboard/usePanelDrilldown.ts b/web/src/composables/dashboard/usePanelDrilldown.ts index 18cef8a7f9..d0e9ec47e9 100644 --- a/web/src/composables/dashboard/usePanelDrilldown.ts +++ b/web/src/composables/dashboard/usePanelDrilldown.ts @@ -273,7 +273,8 @@ export function usePanelDrilldown({ return { __name: NAMED_ITEM_TYPES.includes(panelSchema.value.type) ? params?.name : params?.seriesName, __value: value, - __axisValue: params?.value?.[0] ?? params?.name, + // A gauge dial named "(empty)" stands in for a blank label; drilldowns filter on the blank. + __axisValue: params?.value?.[0] ?? params?.data?.rawName ?? params?.name, }; };