From 336aa06966a618e94475f4098b5f50bca81ffb9a Mon Sep 17 00:00:00 2001 From: Victor Marin Date: Fri, 21 Nov 2025 18:03:27 +0200 Subject: [PATCH] Dashboards: Add non-applicable filter pills per panel (#112507) * wip non-applicable pills * refactor * fix * tests * locales * canary version * mods * fix query fetching * fix * fix * Add VizPanelSubHeader component * lint * extra check * refactor * wip * refactor wipp * refactor * refactor * use canary scenes * prettier * canary scenes * interpolate ds uid for ds var case * refactor * refactor * memoize values + tests + rename component * refactor * refactor * refactor * refactor * canary scenes + fixes * Fix infinite loop casused by unstable useEffect dependency * lint * helper functions * bump scenes * reduce applicability calls to only when filters or groupBy keys change, not any var state change * refactor * fix * fix * fixes --------- Co-authored-by: Dominik Prokop --- package.json | 4 +- packages/grafana-data/src/types/datasource.ts | 2 +- .../src/types/featureToggles.gen.ts | 4 + .../src/selectors/components.ts | 3 + .../components/PanelChrome/PanelChrome.mdx | 64 ++ .../PanelChrome/PanelChrome.test.tsx | 27 + .../components/PanelChrome/PanelChrome.tsx | 84 ++- pkg/services/featuremgmt/registry.go | 7 + pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.json | 553 +++++++++--------- .../PanelNonApplicableDrilldownsSubHeader.tsx | 189 ++++++ .../scene/VizPanelSubHeader.test.tsx | 184 ++++++ .../scene/VizPanelSubHeader.tsx | 193 ++++++ .../serialization/layoutSerializers/utils.ts | 7 + .../transformSaveModelToScene.ts | 4 + .../utils/drilldownUtils.test.ts | 236 ++++++++ .../dashboard-scene/utils/drilldownUtils.ts | 75 +++ .../features/dashboard-scene/utils/utils.ts | 4 + yarn.lock | 232 +++++--- 19 files changed, 1486 insertions(+), 387 deletions(-) create mode 100644 public/app/features/dashboard-scene/scene/PanelNonApplicableDrilldownsSubHeader.tsx create mode 100644 public/app/features/dashboard-scene/scene/VizPanelSubHeader.test.tsx create mode 100644 public/app/features/dashboard-scene/scene/VizPanelSubHeader.tsx create mode 100644 public/app/features/dashboard-scene/utils/drilldownUtils.test.ts create mode 100644 public/app/features/dashboard-scene/utils/drilldownUtils.ts diff --git a/package.json b/package.json index a41dee5cd15..1ab0dc7a811 100644 --- a/package.json +++ b/package.json @@ -296,8 +296,8 @@ "@grafana/plugin-ui": "^0.11.1", "@grafana/prometheus": "workspace:*", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "^6.46.0", - "@grafana/scenes-react": "^6.46.0", + "@grafana/scenes": "6.47.1", + "@grafana/scenes-react": "6.47.1", "@grafana/schema": "workspace:*", "@grafana/sql": "workspace:*", "@grafana/ui": "workspace:*", diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 25e39084acc..e5bf0e10a21 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -646,7 +646,7 @@ export interface MetricFindValue { } export interface DataSourceGetDrilldownsApplicabilityOptions { - filters: AdHocVariableFilter[]; + filters?: AdHocVariableFilter[]; groupByKeys?: string[]; timeRange?: TimeRange; queries?: TQuery[]; diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 09c123d527a..b215e95220f 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -365,6 +365,10 @@ export interface FeatureToggles { */ unlimitedLayoutsNesting?: boolean; /** + * Enables viewing non-applicable drilldowns on a panel level + */ + perPanelNonApplicableDrilldowns?: boolean; + /** * Enables use of the `systemPanelFilterVar` variable to filter panels in a dashboard */ panelFilterVariable?: boolean; diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index c8cfb1d47cb..e56318477c0 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -426,6 +426,9 @@ export const versionedComponents = { loadingBar: { '10.0.0': () => `Panel loading bar`, }, + PanelNonApplicableDrilldownsSubHeader: { + '12.4.0': 'Panel non-applicable drilldowns subheader', + }, HoverWidget: { container: { '10.1.0': 'data-testid hover-header-container', diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.mdx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.mdx index c00acacda20..a1fbb1dbbd4 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.mdx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.mdx @@ -421,6 +421,70 @@ Component used for rendering content wrapped in the same style as grafana panels +### Sub-header content + +The panel supports displaying additional content below the main header using the `subHeaderContent` prop. This can be used to show context-specific information. + +```tsx + + Additional info + + } + width={400} + height={200} +> + {(innerwidth, innerheight) => { + return ( +
+ Content +
+ ); + }} +
+``` + + + + Additional info + + } + width={400} + height={200} + > + {(innerwidth, innerheight) => { + return ( +
+ Content +
+ ); + }} +
+
+ ### Collapsible The panel can be collapsed/expanded by clicking on the chevron or the title. diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx index 3032099a069..7576138f533 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx @@ -196,3 +196,30 @@ it('collapses the uncontrolled panel when user clicks on the chevron or the titl expect(button).not.toHaveAttribute('aria-controlls'); expect(screen.queryByTestId(selectors.components.Panels.Panel.content)?.id).toBe(undefined); }); + +it('renders panel with a header if prop subHeaderContent', () => { + setup({ + subHeaderContent:
This should be a sub-header node
, + }); + + expect(screen.getByTestId(selectors.components.Panels.Panel.headerContainer)).toBeInTheDocument(); +}); + +it('renders panel with sub-header content in place if prop subHeaderContent', () => { + setup({ + subHeaderContent:
This should be a sub-header node
, + }); + + expect(screen.getByText('This should be a sub-header node')).toBeInTheDocument(); +}); + +it('does not render sub-header content when panel is collapsed', () => { + setup({ + title: 'Test Panel', + collapsible: true, + collapsed: true, + subHeaderContent:
This should be a sub-header node
, + }); + + expect(screen.queryByText('This should be a sub-header node')).not.toBeInTheDocument(); +}); diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index a10057a5cc3..a632f6ddca4 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -76,6 +76,11 @@ interface BaseProps { * If true, the VizPanelMenu will always be visible in the panel header. Defaults to false. */ showMenuAlways?: boolean; + /** + * Content to display in the sub-header area below the main header. + * Can contain text, pills, links, buttons, or any other React elements. + */ + subHeaderContent?: ReactNode; } interface FixedDimensions extends BaseProps { @@ -157,6 +162,7 @@ export function PanelChrome({ onMouseEnter, onDragStart, showMenuAlways = false, + subHeaderContent, }: PanelChromeProps) { const theme = useTheme2(); const styles = useStyles2(getStyles); @@ -164,6 +170,7 @@ export function PanelChrome({ const panelTitleId = useId().replace(/:/g, '_'); const { isSelected, onSelect, isSelectable } = useElementSelection(selectionId); const pointerDistance = usePointerDistance(); + const [subHeaderRef, { height: measuredSubHeaderHeight }] = useMeasure(); const hasHeader = !hoverHeader; @@ -184,11 +191,13 @@ export function PanelChrome({ const isPanelTransparent = displayMode === 'transparent'; const headerHeight = getHeaderHeight(theme, hasHeader); + const subHeaderHeight = Math.min(measuredSubHeaderHeight, headerHeight); const { contentStyle, innerWidth, innerHeight } = getContentStyle( padding, theme, headerHeight, collapsed, + subHeaderHeight, height, width ); @@ -395,37 +404,44 @@ export function PanelChrome({ )} {hasHeader && ( -
- {statusMessage && ( -
- +
+ {statusMessage && ( +
+ +
+ )} + + {headerContent} + + {menu && ( + + )} +
+ {!collapsed && subHeaderContent && ( +
+ {subHeaderContent}
)} - - {headerContent} - - {menu && ( - - )} -
+ )} {!collapsed && ( @@ -466,6 +482,7 @@ const getContentStyle = ( theme: GrafanaTheme2, headerHeight: number, collapsed: boolean, + subHeaderHeight: number, height?: number, width?: number ) => { @@ -481,7 +498,7 @@ const getContentStyle = ( let innerHeight = 0; if (height) { - innerHeight = height - headerHeight - panelPadding - panelBorder; + innerHeight = height - headerHeight - panelPadding - panelBorder - subHeaderHeight; } if (collapsed) { @@ -579,6 +596,15 @@ const getStyles = (theme: GrafanaTheme2) => { padding: newPanelPadding ? theme.spacing(0, 1, 0, 1.5) : theme.spacing(0, 0.5, 0, 1), gap: theme.spacing(1), }), + subHeader: css({ + label: 'panel-sub-header', + display: 'flex', + alignItems: 'center', + maxHeight: theme.spacing.gridSize * theme.components.panel.headerHeight, + padding: newPanelPadding ? theme.spacing(0, 1, 0, 1.5) : theme.spacing(0, 0.5, 0, 1), + overflow: 'hidden', + gap: theme.spacing(1), + }), pointer: css({ cursor: 'pointer', }), diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 26690f92481..e4afd8e5c11 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -586,6 +586,13 @@ var ( FrontendOnly: true, Owner: grafanaDashboardsSquad, }, + { + Name: "perPanelNonApplicableDrilldowns", + Description: "Enables viewing non-applicable drilldowns on a panel level", + Stage: FeatureStageExperimental, + FrontendOnly: true, + Owner: grafanaDashboardsSquad, + }, { Name: "panelFilterVariable", Description: "Enables use of the `systemPanelFilterVar` variable to filter panels in a dashboard", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index d0a2674aa55..25e97404857 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -81,6 +81,7 @@ dashboardScene,GA,@grafana/dashboards-squad,false,false,true dashboardNewLayouts,experimental,@grafana/dashboards-squad,false,false,false dashboardUndoRedo,experimental,@grafana/dashboards-squad,false,false,true unlimitedLayoutsNesting,experimental,@grafana/dashboards-squad,false,false,true +perPanelNonApplicableDrilldowns,experimental,@grafana/dashboards-squad,false,false,true panelFilterVariable,experimental,@grafana/dashboards-squad,false,false,true pdfTables,preview,@grafana/grafana-operator-experience-squad,false,false,false canvasPanelPanZoom,preview,@grafana/dataviz-squad,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 1f9315705ce..e791d3bd89b 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -6,7 +6,7 @@ { "metadata": { "name": "aiGeneratedDashboardChanges", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-03-05T12:01:31Z" }, "spec": { @@ -19,7 +19,7 @@ { "metadata": { "name": "alertEnrichment", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-06T12:16:07Z" }, "spec": { @@ -33,7 +33,7 @@ { "metadata": { "name": "alertEnrichmentConditional", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -48,7 +48,7 @@ { "metadata": { "name": "alertEnrichmentMultiStep", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -63,7 +63,7 @@ { "metadata": { "name": "alertRuleRestore", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-05T14:15:26Z" }, "spec": { @@ -76,7 +76,7 @@ { "metadata": { "name": "alertRuleUseFiredAtForStartsAt", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-22T11:16:38Z" }, "spec": { @@ -89,7 +89,7 @@ { "metadata": { "name": "alertingAIAnalyzeCentralStateHistory", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-16T16:42:42Z" }, "spec": { @@ -103,7 +103,7 @@ { "metadata": { "name": "alertingAIFeedback", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-23T12:38:09Z" }, "spec": { @@ -117,7 +117,7 @@ { "metadata": { "name": "alertingAIGenAlertRules", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-16T16:42:42Z" }, "spec": { @@ -131,7 +131,7 @@ { "metadata": { "name": "alertingAIGenTemplates", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-16T16:42:42Z" }, "spec": { @@ -145,7 +145,7 @@ { "metadata": { "name": "alertingAIImproveAlertRules", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-16T16:42:42Z" }, "spec": { @@ -159,7 +159,7 @@ { "metadata": { "name": "alertingBacktesting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-12-14T14:44:14Z" }, "spec": { @@ -171,7 +171,7 @@ { "metadata": { "name": "alertingBulkActionsInUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-24T14:49:59Z" }, "spec": { @@ -186,7 +186,7 @@ { "metadata": { "name": "alertingCentralAlertHistory", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-29T15:01:38Z" }, "spec": { @@ -198,7 +198,7 @@ { "metadata": { "name": "alertingDisableSendAlertsExternal", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-23T12:29:19Z" }, "spec": { @@ -211,7 +211,7 @@ { "metadata": { "name": "alertingEnrichmentAssistantInvestigations", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -226,7 +226,7 @@ { "metadata": { "name": "alertingEnrichmentPerRule", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -241,7 +241,7 @@ { "metadata": { "name": "alertingFilterV2", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-11T11:29:26Z" }, "spec": { @@ -254,7 +254,7 @@ { "metadata": { "name": "alertingImportAlertmanagerAPI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-10T08:32:50Z" }, "spec": { @@ -268,7 +268,7 @@ { "metadata": { "name": "alertingImportAlertmanagerUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -283,7 +283,7 @@ { "metadata": { "name": "alertingImportYAMLUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-05-21T15:59:41Z" }, "spec": { @@ -297,7 +297,7 @@ { "metadata": { "name": "alertingJiraIntegration", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-14T12:22:04Z" }, "spec": { @@ -311,7 +311,7 @@ { "metadata": { "name": "alertingListViewV2", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-24T14:40:49Z" }, "spec": { @@ -324,7 +324,7 @@ { "metadata": { "name": "alertingListViewV2PreviewToggle", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-22T08:50:34Z" }, "spec": { @@ -337,7 +337,7 @@ { "metadata": { "name": "alertingMigrationUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-14T16:40:05Z" }, "spec": { @@ -351,7 +351,7 @@ { "metadata": { "name": "alertingNotificationHistory", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-17T13:26:26Z" }, "spec": { @@ -365,7 +365,7 @@ { "metadata": { "name": "alertingNotificationsStepMode", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-22T11:07:45Z" }, "spec": { @@ -379,7 +379,7 @@ { "metadata": { "name": "alertingPrometheusRulesPrimary", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-27T12:27:16Z" }, "spec": { @@ -392,7 +392,7 @@ { "metadata": { "name": "alertingProvenanceLockWrites", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-23T18:16:06Z" }, "spec": { @@ -405,7 +405,7 @@ { "metadata": { "name": "alertingQueryAndExpressionsStepMode", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-26T06:33:14Z" }, "spec": { @@ -419,7 +419,7 @@ { "metadata": { "name": "alertingQueryOptimization", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-10T20:52:58Z" }, "spec": { @@ -432,7 +432,7 @@ { "metadata": { "name": "alertingRulePermanentlyDelete", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-03T11:18:25Z" }, "spec": { @@ -447,7 +447,7 @@ { "metadata": { "name": "alertingRuleRecoverDeleted", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-27T14:39:26Z" }, "spec": { @@ -461,7 +461,7 @@ { "metadata": { "name": "alertingRuleVersionHistoryRestore", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-17T12:25:32Z" }, "spec": { @@ -476,7 +476,7 @@ { "metadata": { "name": "alertingSaveStateCompressed", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-27T17:47:33Z" }, "spec": { @@ -489,7 +489,7 @@ { "metadata": { "name": "alertingSaveStatePeriodic", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-23T16:03:30Z" }, "spec": { @@ -501,7 +501,7 @@ { "metadata": { "name": "alertingTriage", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -516,7 +516,7 @@ { "metadata": { "name": "alertingUIOptimizeReducer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-18T10:59:00Z" }, "spec": { @@ -530,7 +530,7 @@ { "metadata": { "name": "alertingUIUseBackendFilters", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-13T14:52:14Z" }, "spec": { @@ -543,7 +543,7 @@ { "metadata": { "name": "alertingUseNewSimplifiedRoutingHashAlgorithm", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -559,7 +559,7 @@ { "metadata": { "name": "alertmanagerRemotePrimary", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-30T16:27:08Z" }, "spec": { @@ -571,7 +571,7 @@ { "metadata": { "name": "alertmanagerRemoteSecondary", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-30T16:27:08Z" }, "spec": { @@ -583,7 +583,7 @@ { "metadata": { "name": "alertmanagerRemoteSecondaryWithRemoteState", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-25T15:06:59Z" }, "spec": { @@ -596,7 +596,7 @@ { "metadata": { "name": "annotationPermissionUpdate", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-31T13:30:13Z" }, "spec": { @@ -609,7 +609,7 @@ { "metadata": { "name": "appPlatformGrpcClientAuth", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-14T10:47:18Z" }, "spec": { @@ -622,7 +622,7 @@ { "metadata": { "name": "assetSriChecks", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-04T10:56:35Z" }, "spec": { @@ -635,7 +635,7 @@ { "metadata": { "name": "authZGRPCServer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-13T09:41:35Z" }, "spec": { @@ -648,7 +648,7 @@ { "metadata": { "name": "awsAsyncQueryCaching", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-21T15:34:07Z" }, "spec": { @@ -661,7 +661,7 @@ { "metadata": { "name": "awsDatasourcesHttpProxy", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-12T18:51:23Z" }, "spec": { @@ -674,7 +674,7 @@ { "metadata": { "name": "awsDatasourcesTempCredentials", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-06T15:06:11Z" }, "spec": { @@ -687,7 +687,7 @@ { "metadata": { "name": "azureMonitorDisableLogLimit", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-24T13:32:09Z" }, "spec": { @@ -700,7 +700,7 @@ { "metadata": { "name": "azureMonitorEnableUserAuth", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-27T14:01:54Z" }, "spec": { @@ -713,7 +713,7 @@ { "metadata": { "name": "azureMonitorLogsBuilderEditor", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-02T14:15:25Z" }, "spec": { @@ -726,7 +726,7 @@ { "metadata": { "name": "azureMonitorPrometheusExemplars", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-06T16:53:17Z" }, "spec": { @@ -739,7 +739,7 @@ { "metadata": { "name": "azureResourcePickerUpdates", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -754,7 +754,7 @@ { "metadata": { "name": "cachingOptimizeSerializationMemoryUsage", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-12T16:56:49Z" }, "spec": { @@ -766,7 +766,7 @@ { "metadata": { "name": "canvasPanelNesting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-05-31T19:03:34Z" }, "spec": { @@ -779,7 +779,7 @@ { "metadata": { "name": "canvasPanelPanZoom", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-02T19:52:21Z" }, "spec": { @@ -792,7 +792,7 @@ { "metadata": { "name": "cdnPluginsLoadFirst", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -806,7 +806,7 @@ { "metadata": { "name": "cdnPluginsUrls", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -820,7 +820,7 @@ { "metadata": { "name": "cloudRBACRoles", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-10T13:19:01Z" }, "spec": { @@ -834,7 +834,7 @@ { "metadata": { "name": "cloudWatchBatchQueries", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-20T19:09:41Z" }, "spec": { @@ -846,7 +846,7 @@ { "metadata": { "name": "cloudWatchCrossAccountQuerying", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-11-28T11:39:12Z" }, "spec": { @@ -859,7 +859,7 @@ { "metadata": { "name": "cloudWatchNewLabelParsing", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-05T15:57:56Z" }, "spec": { @@ -872,7 +872,7 @@ { "metadata": { "name": "cloudWatchRoundUpEndTime", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-27T15:10:28Z" }, "spec": { @@ -885,7 +885,7 @@ { "metadata": { "name": "configurableSchedulerTick", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-26T16:44:12Z" }, "spec": { @@ -899,7 +899,7 @@ { "metadata": { "name": "crashDetection", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-12T15:07:27Z" }, "spec": { @@ -912,7 +912,7 @@ { "metadata": { "name": "dashboardDisableSchemaValidationV1", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -924,7 +924,7 @@ { "metadata": { "name": "dashboardDisableSchemaValidationV2", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -936,7 +936,7 @@ { "metadata": { "name": "dashboardLevelTimeMacros", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T09:49:07Z" }, "spec": { @@ -949,7 +949,7 @@ { "metadata": { "name": "dashboardLibrary", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -962,7 +962,7 @@ { "metadata": { "name": "dashboardNewLayouts", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-23T08:55:45Z" }, "spec": { @@ -974,7 +974,7 @@ { "metadata": { "name": "dashboardScene", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-11-13T08:51:21Z" }, "spec": { @@ -988,7 +988,7 @@ { "metadata": { "name": "dashboardSceneForViewers", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-11-02T19:02:25Z" }, "spec": { @@ -1002,7 +1002,7 @@ { "metadata": { "name": "dashboardSceneSolo", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-02-11T08:08:47Z" }, "spec": { @@ -1016,7 +1016,7 @@ { "metadata": { "name": "dashboardSchemaValidationLogging", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -1028,7 +1028,7 @@ { "metadata": { "name": "dashboardTemplates", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-28T20:05:32Z" }, "spec": { @@ -1040,7 +1040,7 @@ { "metadata": { "name": "dashboardUndoRedo", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -1054,7 +1054,7 @@ { "metadata": { "name": "dashgpt", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-08-30T20:22:05Z" }, "spec": { @@ -1068,7 +1068,7 @@ { "metadata": { "name": "dataplaneAggregator", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-08-09T08:41:07Z" }, "spec": { @@ -1081,7 +1081,7 @@ { "metadata": { "name": "datasourceAPIServers", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-19T08:28:27Z" }, "spec": { @@ -1094,7 +1094,7 @@ { "metadata": { "name": "datasourceConnectionsTab", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-21T17:39:48Z" }, "spec": { @@ -1107,7 +1107,7 @@ { "metadata": { "name": "datasourceQueryTypes", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-23T16:46:28Z" }, "spec": { @@ -1120,7 +1120,7 @@ { "metadata": { "name": "disableClassicHTTPHistogram", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-18T19:37:44Z" }, "spec": { @@ -1133,7 +1133,7 @@ { "metadata": { "name": "disableEnvelopeEncryption", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-05-24T08:34:47Z" }, "spec": { @@ -1146,7 +1146,7 @@ { "metadata": { "name": "disableNumericMetricsSortingInExpressions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-16T14:52:47Z" }, "spec": { @@ -1159,7 +1159,7 @@ { "metadata": { "name": "disableSSEDataplane", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-04-12T16:24:34Z" }, "spec": { @@ -1171,7 +1171,7 @@ { "metadata": { "name": "elasticsearchCrossClusterSearch", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-12T22:20:04Z" }, "spec": { @@ -1184,7 +1184,7 @@ { "metadata": { "name": "elasticsearchImprovedParsing", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-15T17:05:54Z" }, "spec": { @@ -1196,7 +1196,7 @@ { "metadata": { "name": "enableAppChromeExtensions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-30T04:32:08Z" }, "spec": { @@ -1211,7 +1211,7 @@ { "metadata": { "name": "enableDashboardEmptyExtensions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-13T07:03:13Z" }, "spec": { @@ -1226,7 +1226,7 @@ { "metadata": { "name": "enableDatagridEditing", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-04-24T14:46:31Z" }, "spec": { @@ -1238,7 +1238,7 @@ { "metadata": { "name": "enableExtensionsAdminPage", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-05T15:55:10Z" }, "spec": { @@ -1251,7 +1251,7 @@ { "metadata": { "name": "enableNativeHTTPHistogram", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-03T18:23:55Z" }, "spec": { @@ -1264,7 +1264,7 @@ { "metadata": { "name": "enableSCIM", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-07T14:38:46Z" }, "spec": { @@ -1276,7 +1276,7 @@ { "metadata": { "name": "enableScopesInMetricsExplore", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-06T13:11:33Z" }, "spec": { @@ -1289,7 +1289,7 @@ { "metadata": { "name": "exploreLogsAggregatedMetrics", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1302,7 +1302,7 @@ { "metadata": { "name": "exploreLogsLimitedTimeRange", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1315,7 +1315,7 @@ { "metadata": { "name": "exploreLogsShardSplitting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1328,7 +1328,7 @@ { "metadata": { "name": "exploreMetricsRelatedLogs", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-05T16:28:43Z" }, "spec": { @@ -1341,7 +1341,7 @@ { "metadata": { "name": "externalServiceAccounts", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-09-28T07:26:37Z" }, "spec": { @@ -1353,7 +1353,7 @@ { "metadata": { "name": "extraThemes", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-05-10T13:37:04Z", "deletionTimestamp": "2025-05-20T08:18:08Z" }, @@ -1367,7 +1367,7 @@ { "metadata": { "name": "faroDatasourceSelector", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-05-05T00:35:10Z" }, "spec": { @@ -1380,7 +1380,7 @@ { "metadata": { "name": "favoriteDatasources", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1394,7 +1394,7 @@ { "metadata": { "name": "featureHighlights", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-02-03T11:53:23Z" }, "spec": { @@ -1407,7 +1407,7 @@ { "metadata": { "name": "fetchRulesUsingPost", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-29T12:17:44Z" }, "spec": { @@ -1420,7 +1420,7 @@ { "metadata": { "name": "foldersAppPlatformAPI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-03T14:15:23Z" }, "spec": { @@ -1435,7 +1435,7 @@ { "metadata": { "name": "grafanaAPIServerEnsureKubectlAccess", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-12-06T20:21:21Z" }, "spec": { @@ -1449,7 +1449,7 @@ { "metadata": { "name": "grafanaAPIServerWithExperimentalAPIs", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-10-06T18:55:22Z" }, "spec": { @@ -1463,7 +1463,7 @@ { "metadata": { "name": "grafanaAdvisor", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-20T10:08:00Z" }, "spec": { @@ -1475,7 +1475,7 @@ { "metadata": { "name": "grafanaAssistantInProfilesDrilldown", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1490,7 +1490,7 @@ { "metadata": { "name": "grafanaManagedRecordingRules", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-22T17:53:16Z", "deletionTimestamp": "2025-05-19T10:15:49Z" }, @@ -1504,7 +1504,7 @@ { "metadata": { "name": "grafanaconThemes", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-06T11:08:04Z" }, "spec": { @@ -1519,7 +1519,7 @@ { "metadata": { "name": "graphiteBackendMode", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1533,7 +1533,7 @@ { "metadata": { "name": "groupAttributeSync", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-09T15:29:43Z" }, "spec": { @@ -1546,7 +1546,7 @@ { "metadata": { "name": "groupByVariable", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-02-14T17:18:04Z" }, "spec": { @@ -1559,7 +1559,7 @@ { "metadata": { "name": "grpcServer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-09-26T20:25:34Z" }, "spec": { @@ -1571,7 +1571,7 @@ { "metadata": { "name": "improvedExternalSessionHandling", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-17T10:54:39Z" }, "spec": { @@ -1584,7 +1584,7 @@ { "metadata": { "name": "improvedExternalSessionHandlingSAML", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-01-09T17:02:49Z" }, "spec": { @@ -1597,7 +1597,7 @@ { "metadata": { "name": "individualCookiePreferences", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-02-21T10:19:07Z" }, "spec": { @@ -1609,7 +1609,7 @@ { "metadata": { "name": "infinityRunQueriesInParallel", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-14T12:54:04Z" }, "spec": { @@ -1621,7 +1621,7 @@ { "metadata": { "name": "influxdbBackendMigration", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-02-09T18:26:16Z", "deletionTimestamp": "2023-01-17T14:11:26Z" }, @@ -1636,7 +1636,7 @@ { "metadata": { "name": "influxdbRunQueriesInParallel", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-02-01T10:58:24Z" }, "spec": { @@ -1648,7 +1648,7 @@ { "metadata": { "name": "influxqlStreamingParser", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-11-29T17:29:35Z" }, "spec": { @@ -1660,7 +1660,7 @@ { "metadata": { "name": "interactiveLearning", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-22T08:06:21Z" }, "spec": { @@ -1672,7 +1672,7 @@ { "metadata": { "name": "investigationsBackend", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-18T08:31:03Z" }, "spec": { @@ -1685,7 +1685,7 @@ { "metadata": { "name": "jaegerEnableGrpcEndpoint", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-31T18:19:16Z" }, "spec": { @@ -1697,7 +1697,7 @@ { "metadata": { "name": "jitterAlertRulesWithinGroups", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-18T18:48:11Z" }, "spec": { @@ -1711,7 +1711,7 @@ { "metadata": { "name": "k8SFolderCounts", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-27T17:10:44Z" }, "spec": { @@ -1724,7 +1724,7 @@ { "metadata": { "name": "k8SFolderMove", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-27T17:10:44Z" }, "spec": { @@ -1737,7 +1737,7 @@ { "metadata": { "name": "kubernetesAggregator", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-02-12T20:59:35Z" }, "spec": { @@ -1750,7 +1750,7 @@ { "metadata": { "name": "kubernetesAggregatorCapTokenAuth", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-05-15T18:14:23Z" }, "spec": { @@ -1763,7 +1763,7 @@ { "metadata": { "name": "kubernetesAlertingRules", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1777,7 +1777,7 @@ { "metadata": { "name": "kubernetesAnnotations", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-06T18:22:20Z" }, "spec": { @@ -1790,7 +1790,7 @@ { "metadata": { "name": "kubernetesAuthZHandlerRedirect", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -1804,7 +1804,7 @@ { "metadata": { "name": "kubernetesAuthnMutation", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-25T15:05:32Z" }, "spec": { @@ -1817,7 +1817,7 @@ { "metadata": { "name": "kubernetesAuthzApis", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-18T07:43:01Z" }, "spec": { @@ -1830,7 +1830,7 @@ { "metadata": { "name": "kubernetesAuthzResourcePermissionApis", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1844,7 +1844,7 @@ { "metadata": { "name": "kubernetesAuthzZanzanaSync", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-13T19:37:13Z" }, "spec": { @@ -1857,7 +1857,7 @@ { "metadata": { "name": "kubernetesCorrelations", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -1871,7 +1871,7 @@ { "metadata": { "name": "kubernetesDashboards", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-05T14:34:23Z" }, "spec": { @@ -1884,7 +1884,7 @@ { "metadata": { "name": "kubernetesFeatureToggles", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-18T05:32:44Z" }, "spec": { @@ -1897,7 +1897,7 @@ { "metadata": { "name": "kubernetesLibraryPanels", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-25T22:21:56Z" }, "spec": { @@ -1910,7 +1910,7 @@ { "metadata": { "name": "kubernetesLogsDrilldown", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-16T21:31:42Z" }, "spec": { @@ -1923,7 +1923,7 @@ { "metadata": { "name": "kubernetesQueryCaching", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-20T16:11:25Z" }, "spec": { @@ -1936,7 +1936,7 @@ { "metadata": { "name": "kubernetesShortURLs", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -1950,7 +1950,7 @@ { "metadata": { "name": "kubernetesSnapshots", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-12-05T22:31:49Z" }, "spec": { @@ -1963,7 +1963,7 @@ { "metadata": { "name": "kubernetesStars", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -1977,7 +1977,7 @@ { "metadata": { "name": "localeFormatPreference", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-31T13:59:07Z" }, "spec": { @@ -1989,7 +1989,7 @@ { "metadata": { "name": "logQLScope", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-11T11:53:24Z" }, "spec": { @@ -2003,7 +2003,7 @@ { "metadata": { "name": "logRequestsInstrumentedAsUnknown", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-06-10T08:56:55Z" }, "spec": { @@ -2015,7 +2015,7 @@ { "metadata": { "name": "logsContextDatasourceUi", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-01-27T14:12:01Z" }, "spec": { @@ -2029,7 +2029,7 @@ { "metadata": { "name": "logsExploreTableDefaultVisualization", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-02T15:28:15Z" }, "spec": { @@ -2042,7 +2042,7 @@ { "metadata": { "name": "logsExploreTableVisualisation", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-12T13:52:42Z" }, "spec": { @@ -2056,7 +2056,7 @@ { "metadata": { "name": "logsPanelControls", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-07T14:38:55Z" }, "spec": { @@ -2070,7 +2070,7 @@ { "metadata": { "name": "lokiExperimentalStreaming", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-06-19T10:03:51Z" }, "spec": { @@ -2082,7 +2082,7 @@ { "metadata": { "name": "lokiLabelNamesQueryApi", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-13T14:31:41Z" }, "spec": { @@ -2095,7 +2095,7 @@ { "metadata": { "name": "lokiLogsDataplane", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-13T07:58:00Z" }, "spec": { @@ -2107,8 +2107,8 @@ { "metadata": { "name": "lokiQueryLimitsContext", - "resourceVersion": "1763727063618", - "creationTimestamp": "2025-11-21T12:11:03Z" + "resourceVersion": "1763734583253", + "creationTimestamp": "2025-11-21T14:16:23Z" }, "spec": { "description": "Send X-Loki-Query-Limits-Context header to Loki on first split request", @@ -2120,7 +2120,7 @@ { "metadata": { "name": "lokiQuerySplitting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-02-09T17:27:02Z" }, "spec": { @@ -2134,7 +2134,7 @@ { "metadata": { "name": "lokiRunQueriesInParallel", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-09-19T09:34:01Z" }, "spec": { @@ -2146,7 +2146,7 @@ { "metadata": { "name": "lokiShardSplitting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-23T11:21:03Z" }, "spec": { @@ -2159,7 +2159,7 @@ { "metadata": { "name": "managedDualWriter", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-19T14:50:39Z" }, "spec": { @@ -2172,7 +2172,7 @@ { "metadata": { "name": "metricsFromProfiles", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-09T10:55:28Z" }, "spec": { @@ -2185,7 +2185,7 @@ { "metadata": { "name": "mlExpressions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-07-13T17:37:50Z" }, "spec": { @@ -2197,7 +2197,7 @@ { "metadata": { "name": "multiTenantTempCredentials", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-02T20:25:50Z" }, "spec": { @@ -2210,7 +2210,7 @@ { "metadata": { "name": "mysqlAnsiQuotes", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-10-12T11:43:35Z" }, "spec": { @@ -2222,7 +2222,7 @@ { "metadata": { "name": "newClickhouseConfigPageDesign", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -2236,7 +2236,7 @@ { "metadata": { "name": "newDashboardWithFiltersAndGroupBy", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-04T11:25:21Z" }, "spec": { @@ -2249,7 +2249,7 @@ { "metadata": { "name": "newFiltersUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-08-30T12:48:13Z" }, "spec": { @@ -2262,7 +2262,7 @@ { "metadata": { "name": "newGauge", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-20T16:33:19Z" }, "spec": { @@ -2276,7 +2276,7 @@ { "metadata": { "name": "newInfluxDSConfigPageDesign", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-25T16:39:54Z" }, "spec": { @@ -2289,7 +2289,7 @@ { "metadata": { "name": "newLogContext", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z" }, "spec": { @@ -2302,7 +2302,7 @@ { "metadata": { "name": "newLogsPanel", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-04T17:40:17Z" }, "spec": { @@ -2316,7 +2316,7 @@ { "metadata": { "name": "newPanelPadding", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-12T15:40:46Z" }, "spec": { @@ -2329,7 +2329,7 @@ { "metadata": { "name": "newShareReportDrawer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-17T19:05:46Z" }, "spec": { @@ -2342,8 +2342,8 @@ { "metadata": { "name": "newTimeRangeZoomShortcuts", - "resourceVersion": "1763727063618", - "creationTimestamp": "2025-11-21T12:11:03Z" + "resourceVersion": "1763734583253", + "creationTimestamp": "2025-11-21T14:16:23Z" }, "spec": { "description": "Enables new keyboard shortcuts for time range zoom operations", @@ -2355,7 +2355,7 @@ { "metadata": { "name": "newVizSuggestions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-12T19:26:29Z" }, "spec": { @@ -2369,7 +2369,7 @@ { "metadata": { "name": "oauthRequireSubClaim", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-03-25T13:22:24Z" }, "spec": { @@ -2382,7 +2382,7 @@ { "metadata": { "name": "onPremToCloudMigrations", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-01-22T16:09:08Z" }, "spec": { @@ -2395,7 +2395,7 @@ { "metadata": { "name": "onlyStoreActionSets", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-20T15:02:56Z" }, "spec": { @@ -2409,7 +2409,7 @@ { "metadata": { "name": "otelLogsFormatting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-16T15:42:14Z" }, "spec": { @@ -2422,7 +2422,7 @@ { "metadata": { "name": "panelFilterVariable", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-11-03T12:15:54Z" }, "spec": { @@ -2436,7 +2436,7 @@ { "metadata": { "name": "panelTimeSettings", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-29T08:06:23Z" }, "spec": { @@ -2448,7 +2448,7 @@ { "metadata": { "name": "panelTitleSearch", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-02-15T18:26:03Z" }, "spec": { @@ -2460,7 +2460,7 @@ { "metadata": { "name": "passwordlessMagicLinkAuthentication", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-14T13:50:55Z" }, "spec": { @@ -2473,7 +2473,7 @@ { "metadata": { "name": "pdfTables", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-11-06T13:39:22Z" }, "spec": { @@ -2482,10 +2482,23 @@ "codeowner": "@grafana/grafana-operator-experience-squad" } }, + { + "metadata": { + "name": "perPanelNonApplicableDrilldowns", + "resourceVersion": "1763734583253", + "creationTimestamp": "2025-11-21T14:16:23Z" + }, + "spec": { + "description": "Enables viewing non-applicable drilldowns on a panel level", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", + "frontend": true + } + }, { "metadata": { "name": "permissionsFilterRemoveSubquery", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-08-02T07:39:25Z" }, "spec": { @@ -2497,7 +2510,7 @@ { "metadata": { "name": "playlistsReconciler", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-20T03:09:31Z" }, "spec": { @@ -2510,7 +2523,7 @@ { "metadata": { "name": "pluginContainers", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -2525,7 +2538,7 @@ { "metadata": { "name": "pluginInstallAPISync", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-24T12:09:26Z" }, "spec": { @@ -2538,7 +2551,7 @@ { "metadata": { "name": "pluginProxyPreserveTrailingSlash", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-05T11:36:14Z" }, "spec": { @@ -2551,7 +2564,7 @@ { "metadata": { "name": "pluginStoreServiceLoading", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-17T20:01:43Z" }, "spec": { @@ -2564,7 +2577,7 @@ { "metadata": { "name": "pluginsAutoUpdate", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-16T11:44:39Z" }, "spec": { @@ -2576,7 +2589,7 @@ { "metadata": { "name": "pluginsSriChecks", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-04T12:55:09Z" }, "spec": { @@ -2589,7 +2602,7 @@ { "metadata": { "name": "postgresDSUsePGX", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-05-26T06:54:18Z", "deletionTimestamp": "2025-06-03T12:45:07Z" }, @@ -2602,7 +2615,7 @@ { "metadata": { "name": "preferLibraryPanelTitle", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-17T11:21:21Z" }, "spec": { @@ -2615,7 +2628,7 @@ { "metadata": { "name": "preserveDashboardStateWhenNavigating", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-05-27T12:28:06Z" }, "spec": { @@ -2628,7 +2641,7 @@ { "metadata": { "name": "preventPanelChromeOverflow", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-17T14:40:08Z" }, "spec": { @@ -2642,7 +2655,7 @@ { "metadata": { "name": "prometheusAzureOverrideAudience", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-05-30T15:43:32Z", "deletionTimestamp": "2023-07-16T21:30:14Z" }, @@ -2656,7 +2669,7 @@ { "metadata": { "name": "prometheusSpecialCharsInLabelValues", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-18T21:31:08Z" }, "spec": { @@ -2669,7 +2682,7 @@ { "metadata": { "name": "prometheusTypeMigration", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -2684,7 +2697,7 @@ { "metadata": { "name": "provisioning", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-22T09:03:50Z" }, "spec": { @@ -2697,7 +2710,7 @@ { "metadata": { "name": "publicDashboardsEmailSharing", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-01-03T19:45:15Z" }, "spec": { @@ -2710,7 +2723,7 @@ { "metadata": { "name": "publicDashboardsScene", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-03-22T14:48:21Z" }, "spec": { @@ -2724,7 +2737,7 @@ { "metadata": { "name": "queryCacheRequestDeduplication", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -2738,7 +2751,7 @@ { "metadata": { "name": "queryLibrary", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-10-07T18:31:45Z", "deletionTimestamp": "2023-03-20T16:00:14Z" }, @@ -2751,7 +2764,7 @@ { "metadata": { "name": "queryService", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2764,7 +2777,7 @@ { "metadata": { "name": "queryServiceFromExplore", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-02T10:00:33Z" }, "spec": { @@ -2777,7 +2790,7 @@ { "metadata": { "name": "queryServiceFromUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2790,7 +2803,7 @@ { "metadata": { "name": "queryServiceRewrite", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2803,7 +2816,7 @@ { "metadata": { "name": "queryServiceWithConnections", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-28T19:28:26Z", "deletionTimestamp": "2025-08-29T12:49:57Z" }, @@ -2817,7 +2830,7 @@ { "metadata": { "name": "refactorVariablesTimeRange", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-06-06T13:12:09Z" }, "spec": { @@ -2829,8 +2842,8 @@ { "metadata": { "name": "refreshTokenRequired", - "resourceVersion": "1763727063618", - "creationTimestamp": "2025-11-21T12:11:03Z" + "resourceVersion": "1763734583253", + "creationTimestamp": "2025-11-21T14:16:23Z" }, "spec": { "description": "Require that refresh tokens are present in oauth tokens.", @@ -2842,7 +2855,7 @@ { "metadata": { "name": "reloadDashboardsOnParamsChange", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-25T12:56:54Z" }, "spec": { @@ -2855,7 +2868,7 @@ { "metadata": { "name": "renderAuthJWT", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-04-03T16:53:38Z" }, "spec": { @@ -2867,7 +2880,7 @@ { "metadata": { "name": "rendererDisableAppPluginsPreload", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-02-24T14:43:06Z" }, "spec": { @@ -2881,7 +2894,7 @@ { "metadata": { "name": "reportingRetries", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-08-31T07:47:47Z" }, "spec": { @@ -2894,7 +2907,7 @@ { "metadata": { "name": "restoreDashboards", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-05-23T14:35:54Z" }, "spec": { @@ -2907,7 +2920,7 @@ { "metadata": { "name": "restrictedPluginApis", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -2923,7 +2936,7 @@ { "metadata": { "name": "rolePickerDrawer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-26T12:51:38Z" }, "spec": { @@ -2935,8 +2948,8 @@ { "metadata": { "name": "rudderstackUpgrade", - "resourceVersion": "1763727063618", - "creationTimestamp": "2025-11-21T12:11:03Z" + "resourceVersion": "1763734583253", + "creationTimestamp": "2025-11-21T14:16:23Z" }, "spec": { "description": "Enables the new version of rudderstack", @@ -2949,7 +2962,7 @@ { "metadata": { "name": "scanRowInvalidDashboardParseFallbackEnabled", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-30T14:18:38Z" }, "spec": { @@ -2961,7 +2974,7 @@ { "metadata": { "name": "scopeApi", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-11-27T07:58:25Z" }, "spec": { @@ -2974,7 +2987,7 @@ { "metadata": { "name": "scopeFilters", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-03-05T15:41:19Z" }, "spec": { @@ -2987,7 +3000,7 @@ { "metadata": { "name": "scopeSearchAllLevels", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-14T07:42:16Z" }, "spec": { @@ -3000,7 +3013,7 @@ { "metadata": { "name": "secretsManagementAppPlatform", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-19T09:25:14Z" }, "spec": { @@ -3012,7 +3025,7 @@ { "metadata": { "name": "secretsManagementAppPlatformUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -3025,7 +3038,7 @@ { "metadata": { "name": "sharingDashboardImage", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-15T21:07:39Z" }, "spec": { @@ -3039,7 +3052,7 @@ { "metadata": { "name": "showDashboardValidationWarnings", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-10-14T13:51:05Z" }, "spec": { @@ -3051,7 +3064,7 @@ { "metadata": { "name": "sqlExpressions", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-02-27T21:16:00Z" }, "spec": { @@ -3063,7 +3076,7 @@ { "metadata": { "name": "sqlExpressionsColumnAutoComplete", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-23T21:49:58Z" }, "spec": { @@ -3076,7 +3089,7 @@ { "metadata": { "name": "sseGroupByDatasource", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-09-07T20:02:07Z" }, "spec": { @@ -3088,7 +3101,7 @@ { "metadata": { "name": "ssoSettingsLDAP", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-18T11:31:27Z" }, "spec": { @@ -3102,7 +3115,7 @@ { "metadata": { "name": "starsFromAPIServer", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -3117,7 +3130,7 @@ { "metadata": { "name": "storage", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2022-03-17T17:19:23Z" }, "spec": { @@ -3129,7 +3142,7 @@ { "metadata": { "name": "suggestedDashboards", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-07T13:38:59Z" }, "spec": { @@ -3141,7 +3154,7 @@ { "metadata": { "name": "tableSharedCrosshair", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-12-13T09:33:14Z" }, "spec": { @@ -3154,7 +3167,7 @@ { "metadata": { "name": "tabularNumbers", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-06-24T11:52:03Z" }, "spec": { @@ -3167,7 +3180,7 @@ { "metadata": { "name": "teamFolders", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -3181,7 +3194,7 @@ { "metadata": { "name": "teamHttpHeadersTempo", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-05-22T19:13:31Z" }, "spec": { @@ -3193,7 +3206,7 @@ { "metadata": { "name": "tempoAlerting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-15T13:36:36Z" }, "spec": { @@ -3205,7 +3218,7 @@ { "metadata": { "name": "tempoSearchBackendMigration", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -3220,7 +3233,7 @@ { "metadata": { "name": "timeComparison", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-24T20:07:28Z" }, "spec": { @@ -3233,7 +3246,7 @@ { "metadata": { "name": "timeRangePan", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-05T01:39:46Z" }, "spec": { @@ -3246,7 +3259,7 @@ { "metadata": { "name": "timeRangeProvider", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-22T10:52:33Z" }, "spec": { @@ -3258,7 +3271,7 @@ { "metadata": { "name": "transformationsEmptyPlaceholder", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-17T13:57:05Z" }, "spec": { @@ -3271,7 +3284,7 @@ { "metadata": { "name": "ttlPluginInstanceManager", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-11-18T11:17:23Z" }, "spec": { @@ -3284,7 +3297,7 @@ { "metadata": { "name": "unifiedHistory", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-13T10:41:18Z" }, "spec": { @@ -3297,7 +3310,7 @@ { "metadata": { "name": "unifiedNavbars", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-04-09T12:51:22Z" }, "spec": { @@ -3311,7 +3324,7 @@ { "metadata": { "name": "unifiedRequestLog", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2023-03-31T13:38:09Z" }, "spec": { @@ -3324,7 +3337,7 @@ { "metadata": { "name": "unifiedStorageBigObjectsSupport", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-10-17T10:18:29Z" }, "spec": { @@ -3336,7 +3349,7 @@ { "metadata": { "name": "unifiedStorageGrpcConnectionPool", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-21T13:24:54Z" }, "spec": { @@ -3349,7 +3362,7 @@ { "metadata": { "name": "unifiedStorageSearch", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-30T19:46:14Z" }, "spec": { @@ -3362,7 +3375,7 @@ { "metadata": { "name": "unifiedStorageSearchDualReaderEnabled", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-18T12:43:56Z" }, "spec": { @@ -3375,7 +3388,7 @@ { "metadata": { "name": "unifiedStorageSearchSprinkles", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-18T17:00:54Z" }, "spec": { @@ -3388,7 +3401,7 @@ { "metadata": { "name": "unifiedStorageSearchUI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-12-19T18:21:48Z" }, "spec": { @@ -3401,7 +3414,7 @@ { "metadata": { "name": "unlimitedLayoutsNesting", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-10T12:15:54Z" }, "spec": { @@ -3414,7 +3427,7 @@ { "metadata": { "name": "useKubernetesShortURLsAPI", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -3428,7 +3441,7 @@ { "metadata": { "name": "useMultipleScopeNodesEndpoint", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-08-29T14:46:39Z", "deletionTimestamp": "2025-09-01T09:33:33Z" }, @@ -3444,7 +3457,7 @@ { "metadata": { "name": "useScopeSingleNodeEndpoint", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T14:32:41Z" }, "spec": { @@ -3459,7 +3472,7 @@ { "metadata": { "name": "useScopesNavigationEndpoint", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-03-31T15:20:00Z" }, "spec": { @@ -3473,7 +3486,7 @@ { "metadata": { "name": "useSessionStorageForRedirection", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-09-23T09:31:23Z" }, "spec": { @@ -3486,7 +3499,7 @@ { "metadata": { "name": "vizActionsAuth", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-07-31T22:56:50Z", "deletionTimestamp": "2025-08-01T11:30:17Z" }, @@ -3501,7 +3514,7 @@ { "metadata": { "name": "zanzana", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2024-06-19T13:59:47Z" }, "spec": { @@ -3514,7 +3527,7 @@ { "metadata": { "name": "zanzanaNoLegacyClient", - "resourceVersion": "1763727063618", + "resourceVersion": "1763734583253", "creationTimestamp": "2025-10-21T14:03:17Z" }, "spec": { diff --git a/public/app/features/dashboard-scene/scene/PanelNonApplicableDrilldownsSubHeader.tsx b/public/app/features/dashboard-scene/scene/PanelNonApplicableDrilldownsSubHeader.tsx new file mode 100644 index 00000000000..fe8437f9dc5 --- /dev/null +++ b/public/app/features/dashboard-scene/scene/PanelNonApplicableDrilldownsSubHeader.tsx @@ -0,0 +1,189 @@ +import { css, cx } from '@emotion/css'; +import { useEffect, useLayoutEffect, useMemo, useState } from 'react'; +import { useMeasure } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { AdHocFiltersVariable, GroupByVariable, SceneQueryRunner } from '@grafana/scenes'; +import { Tooltip, measureText, useStyles2, useTheme2 } from '@grafana/ui'; + +import { getDrilldownApplicability } from '../utils/drilldownUtils'; + +const GAP_SIZE = 8; +const FONT_SIZE = 12; + +interface Props { + filtersVar?: AdHocFiltersVariable; + groupByVar?: GroupByVariable; + queryRunner: SceneQueryRunner; +} + +export function PanelNonApplicableDrilldownsSubHeader({ filtersVar, groupByVar, queryRunner }: Props) { + const styles = useStyles2(getStyles); + const theme = useTheme2(); + const [sizeRef, { width: containerWidth }] = useMeasure(); + + // Subscribe to state changes (this triggers re-renders when state changes) + const filtersState = filtersVar?.useState(); + const groupByState = groupByVar?.useState(); + + const [nonApplicable, setNonApplicable] = useState([]); + const [visibleCount, setVisibleCount] = useState(0); + + // Create stable string representations to detect actual changes + const filterKey = useMemo(() => { + const filters = filtersState?.filters ?? []; + const originFilters = filtersState?.originFilters ?? []; + const filterValues = [...filters, ...originFilters]; + return JSON.stringify(filterValues.map((f) => `${f.key}${f.operator}${f.value}${f.origin ?? ''}`)); + }, [filtersState?.filters, filtersState?.originFilters]); + + const groupByKey = useMemo(() => { + const value = groupByState?.value ?? []; + const groupByValues = Array.isArray(value) ? value : value ? [value] : []; + return JSON.stringify(groupByValues); + }, [groupByState?.value]); + + useEffect(() => { + const fetchApplicability = async () => { + const filters = filtersState?.filters ?? []; + const originFilters = filtersState?.originFilters ?? []; + const value = groupByState?.value ?? []; + + const filterValues = [...filters, ...originFilters]; + const groupByValues = Array.isArray(value) ? value : value ? [value] : []; + + const labels: string[] = []; + + const applicability = await getDrilldownApplicability(queryRunner, filtersVar, groupByVar); + if (filterValues.length) { + const nonApplicableFilters = filterValues.filter((filter) => { + const result = applicability?.find((entry) => entry.key === filter.key && entry.origin === filter.origin); + return result && !result.applicable; + }); + labels.push(...nonApplicableFilters.map((filter) => `${filter.key} ${filter.operator} ${filter.value}`)); + } + + if (groupByValues.length) { + const nonApplicableKeys = groupByValues + .filter((groupByKey) => { + const result = applicability?.find((entry) => entry.key === groupByKey); + return result && !result.applicable; + }) + .map((key) => String(key)); + + labels.push(...nonApplicableKeys); + } + + setNonApplicable(labels); + }; + + fetchApplicability(); + }, [ + filterKey, + groupByKey, + filtersVar, + groupByVar, + queryRunner, + filtersState?.filters, + groupByState?.value, + filtersState?.originFilters, + ]); + + useLayoutEffect(() => { + if (!nonApplicable.length) { + setVisibleCount(0); + return; + } + + setVisibleCount(calculateVisibleCount(nonApplicable, containerWidth, theme)); + }, [containerWidth, nonApplicable, theme]); + + if (nonApplicable.length === 0) { + return null; + } + + const visibleFilters = nonApplicable.slice(0, visibleCount); + const remainingCount = nonApplicable.length - visibleCount; + const hasOverflow = remainingCount > 0; + const remainingFilters = nonApplicable.slice(visibleCount); + + return ( +
+ {visibleFilters.map((filter, index) => ( +
+ {filter} +
+ ))} + {hasOverflow && ( + +
+{remainingCount}
+
+ )} +
+ ); +} + +function getPillWidth(label: string) { + return Math.ceil(measureText(label, FONT_SIZE).width) + GAP_SIZE; +} + +function calculateVisibleCount(labels: string[], containerWidth: number, theme: GrafanaTheme2) { + let usedWidth = 0; + let visible = 0; + + for (let i = 0; i < labels.length; i++) { + const pillWidth = getPillWidth(labels[i]); + const gapBefore = visible > 0 ? GAP_SIZE : 0; + const nextWidth = usedWidth + gapBefore + pillWidth; + const remaining = labels.length - (i + 1); + + if (remaining > 0) { + const overflowWidth = getPillWidth(`+${remaining}`); + if (nextWidth + GAP_SIZE + overflowWidth > containerWidth) { + break; + } + } else if (nextWidth > containerWidth) { + break; + } + + usedWidth = nextWidth; + visible++; + } + + return visible; +} + +function getStyles(theme: GrafanaTheme2) { + return { + container: css({ + display: 'flex', + flexWrap: 'nowrap', + gap: theme.spacing(1), + width: '100%', + overflow: 'hidden', + }), + pill: css({ + padding: theme.spacing(0.2, 0.4), + borderRadius: theme.shape.radius.default, + whiteSpace: 'nowrap', + flexShrink: 0, + fontSize: theme.typography.bodySmall.fontSize, + }), + disabledPill: css({ + background: theme.colors.action.selected, + color: theme.colors.text.disabled, + border: 0, + '&:hover': { + background: theme.colors.action.selected, + }, + }), + strikethrough: css({ + textDecoration: 'line-through', + }), + }; +} diff --git a/public/app/features/dashboard-scene/scene/VizPanelSubHeader.test.tsx b/public/app/features/dashboard-scene/scene/VizPanelSubHeader.test.tsx new file mode 100644 index 00000000000..e05e9b20da4 --- /dev/null +++ b/public/app/features/dashboard-scene/scene/VizPanelSubHeader.test.tsx @@ -0,0 +1,184 @@ +import { of } from 'rxjs'; + +import { DataQueryRequest, DataSourceApi, LoadingState } from '@grafana/data'; +import { getPanelPlugin } from '@grafana/data/test'; +import { setPluginImportUtils } from '@grafana/runtime'; +import { + AdHocFiltersVariable, + GroupByVariable, + SceneDataTransformer, + SceneQueryRunner, + SceneVariableSet, + VizPanel, + VizPanelState, +} from '@grafana/scenes'; + +import { activateFullSceneTree } from '../utils/test-utils'; + +import { DashboardScene } from './DashboardScene'; +import { VizPanelSubHeader } from './VizPanelSubHeader'; +import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager'; + +const runRequestMock = jest.fn().mockImplementation((ds: DataSourceApi, request: DataQueryRequest) => { + return of({ + state: LoadingState.Loading, + series: [], + timeRange: request.range, + }); +}); + +jest.mock('@grafana/runtime', () => ({ + ...jest.requireActual('@grafana/runtime'), + getRunRequest: () => (ds: DataSourceApi, request: DataQueryRequest) => { + return runRequestMock(ds, request); + }, + getDataSourceSrv: () => ({ + get: jest.fn().mockResolvedValue({ + getRef: () => ({ uid: 'ds-1', type: 'test' }), + }), + getInstanceSettings: jest.fn().mockResolvedValue({ uid: 'ds-1', type: 'test' }), + }), + getPluginImportUtils: () => ({ + getPanelPluginFromCache: jest.fn(() => undefined), + }), +})); + +setPluginImportUtils({ + importPanelPlugin: () => Promise.resolve(getPanelPlugin({})), + getPanelPluginFromCache: () => undefined, +}); + +describe('VizPanelSubHeader', () => { + it('renders when the drilldown variables apply to the panel', async () => { + const { subHeader } = await buildScene(); + + expect(subHeader.state.supportsApplicability).toBe(true); + }); + + it('renders only one drilldown var is set', async () => { + const { subHeader } = await buildScene({ noGroupBy: true }); + + expect(subHeader.state.supportsApplicability).toBe(true); + }); + + it('does not render when applicability is disabled', async () => { + const { subHeader } = await buildScene({ applicabilityEnabled: false }); + + expect(subHeader.state.supportsApplicability).toBe(false); + }); + + it('does not render when the datasource uid does not match', async () => { + const { subHeader } = await buildScene({ + variableDatasourceUid: 'other-ds', + }); + + expect(subHeader.state.supportsApplicability).toBe(false); + }); + + it('no longer renders if variable ds changes to a different type', async () => { + const { subHeader, adhocFiltersVariable } = await buildScene({ + noGroupBy: true, + }); + + expect(subHeader.state.supportsApplicability).toBe(true); + + adhocFiltersVariable.setState({ datasource: { uid: 'ds-2' } }); + + expect(subHeader.state.supportsApplicability).toBe(false); + }); + + it('no longers renders if variable applicability becomes disabled', async () => { + const { subHeader, adhocFiltersVariable } = await buildScene({ + noGroupBy: true, + }); + + expect(subHeader.state.supportsApplicability).toBe(true); + + adhocFiltersVariable.setState({ applicabilityEnabled: false }); + + expect(subHeader.state.supportsApplicability).toBe(false); + }); + + it('continues to render if one adhoc is disabled, but groupby remains active', async () => { + const { subHeader, adhocFiltersVariable } = await buildScene(); + + expect(subHeader.state.supportsApplicability).toBe(true); + + adhocFiltersVariable.setState({ applicabilityEnabled: false }); + + expect(subHeader.state.supportsApplicability).toBe(true); + }); + + it('stops rendering if queryRunner changes datasource to different one than vars', async () => { + const { subHeader, queryRunner } = await buildScene(); + + expect(subHeader.state.supportsApplicability).toBe(true); + + queryRunner.setState({ datasource: { uid: 'ds-2' } }); + + expect(subHeader.state.supportsApplicability).toBe(false); + }); +}); + +interface BuildSceneOptions { + applicabilityEnabled?: boolean; + variableDatasourceUid?: string; + noGroupBy?: boolean; +} + +async function buildScene(options?: BuildSceneOptions) { + const subHeader = new VizPanelSubHeader({}); + + const queryRunner = new SceneQueryRunner({ + datasource: { uid: 'ds-1' }, + queries: [{ refId: 'A', datasource: { uid: 'ds-1' } }], + }); + + const adhocFiltersVariable = new AdHocFiltersVariable({ + name: 'adhoc', + label: 'adhoc', + filters: [{ key: 'filter-1', operator: '=', value: 'value-1' }], + datasource: { uid: options?.variableDatasourceUid ?? 'ds-1' }, + applicabilityEnabled: options?.applicabilityEnabled ?? true, + }); + + const groupByVariable = new GroupByVariable({ + name: 'group', + label: 'group', + value: ['groupBy'], + text: ['groupBy'], + options: [], + applicabilityEnabled: options?.applicabilityEnabled ?? true, + datasource: { uid: options?.variableDatasourceUid ?? 'ds-1' }, + }); + + const dataProvider = new SceneDataTransformer({ + $data: queryRunner, + transformations: [], + }); + + const panelState: VizPanelState = { + key: 'panel-1', + title: 'Panel A', + pluginId: 'timeseries', + subHeader, + $data: dataProvider, + options: {}, + fieldConfig: { defaults: {}, overrides: [] }, + }; + + const panel = new VizPanel(panelState); + + const scene = new DashboardScene({ + $variables: new SceneVariableSet({ + variables: options?.noGroupBy ? [adhocFiltersVariable] : [groupByVariable, adhocFiltersVariable], + }), + body: DefaultGridLayoutManager.fromVizPanels([panel]), + }); + + activateFullSceneTree(scene); + + await new Promise((r) => setTimeout(r, 1)); + + return { subHeader, groupByVariable, adhocFiltersVariable, queryRunner }; +} diff --git a/public/app/features/dashboard-scene/scene/VizPanelSubHeader.tsx b/public/app/features/dashboard-scene/scene/VizPanelSubHeader.tsx new file mode 100644 index 00000000000..f2247661e04 --- /dev/null +++ b/public/app/features/dashboard-scene/scene/VizPanelSubHeader.tsx @@ -0,0 +1,193 @@ +import { Unsubscribable } from 'rxjs'; + +import { + SceneComponentProps, + SceneObjectState, + SceneObjectBase, + sceneGraph, + AdHocFiltersVariable, + GroupByVariable, + SceneQueryRunner, + VizPanel, +} from '@grafana/scenes'; +import { DataSourceRef } from '@grafana/schema'; + +import { verifyDrilldownApplicability } from '../utils/drilldownUtils'; + +import { PanelNonApplicableDrilldownsSubHeader } from './PanelNonApplicableDrilldownsSubHeader'; + +interface ApplicabilitySupportHelperState { + datasource: DataSourceRef | null; + applicabilityEnabled?: boolean; +} + +export interface VizPanelSubHeaderState extends SceneObjectState { + hideNonApplicableDrilldowns?: boolean; + supportsApplicability?: boolean; +} + +export class VizPanelSubHeader extends SceneObjectBase { + static Component = VizPanelSubHeaderRenderer; + + private _adHocVar?: AdHocFiltersVariable; + private _groupByVar?: GroupByVariable; + + private _adHocSub?: Unsubscribable; + private _groupBySub?: Unsubscribable; + + private _queryRunnerDatasource?: DataSourceRef; + + constructor(state: Partial) { + super({ + hideNonApplicableDrilldowns: state.hideNonApplicableDrilldowns ?? false, + ...state, + }); + + this.addActivationHandler(this._onActivate); + } + + private _onActivate = () => { + if (!this.parent || !(this.parent instanceof VizPanel)) { + throw new Error('VizPanelSubHeader can be used only with VizPanel'); + } + + if (!this.state.hideNonApplicableDrilldowns) { + this.subscribeToDrilldownVariableChanges(); + } + + return () => { + this._groupBySub?.unsubscribe(); + this._adHocSub?.unsubscribe(); + }; + }; + + private subscribeToDrilldownVariableChanges() { + const vars = sceneGraph.getVariables(this); + const queryRunner = this.getQueryRunner(); + + this._adHocVar = vars.state.variables.find((variable) => variable instanceof AdHocFiltersVariable); + this._groupByVar = vars.state.variables.find((variable) => variable instanceof GroupByVariable); + this._queryRunnerDatasource = queryRunner?.state.datasource; + + this.setDrilldownApplicabilitySupportHelper(); + + // keep track of queryRunner datasource updates andupdate rendering + this._subs.add( + queryRunner?.subscribeToState((n, p) => { + if (n.datasource !== p.datasource) { + this._queryRunnerDatasource = n.datasource; + + this.setDrilldownApplicabilitySupportHelper(); + } + }) + ); + + // check when var set updates and search for drilldown vars + this._subs.add( + vars.subscribeToState((n) => { + this._adHocVar = n.variables.find((variable) => variable instanceof AdHocFiltersVariable); + this._groupByVar = n.variables.find((variable) => variable instanceof GroupByVariable); + + this.refreshDrilldownVarsSubscriptions(); + }) + ); + + // adhoc sub so if that changes, we potentially update rendering + this._adHocSub = this._adHocVar?.subscribeToState((n, p) => { + if (n.datasource !== p.datasource || n.applicabilityEnabled !== p.applicabilityEnabled) { + this.setDrilldownApplicabilitySupportHelper({ + datasource: n.datasource, + applicabilityEnabled: n.applicabilityEnabled, + }); + } + }); + + // same for groupBy + this._groupBySub = this._groupByVar?.subscribeToState((n, p) => { + if (n.datasource !== p.datasource || n.applicabilityEnabled !== p.applicabilityEnabled) { + this.setDrilldownApplicabilitySupportHelper(undefined, { + datasource: n.datasource, + applicabilityEnabled: n.applicabilityEnabled, + }); + } + }); + } + + private refreshDrilldownVarsSubscriptions() { + if (this._groupByVar) { + this._groupBySub?.unsubscribe(); + this._groupByVar?.subscribeToState((n, p) => { + if (n.datasource !== p.datasource || n.applicabilityEnabled !== p.applicabilityEnabled) { + this.setDrilldownApplicabilitySupportHelper(undefined, { + datasource: n.datasource, + applicabilityEnabled: n.applicabilityEnabled, + }); + } + }); + } + + if (this._adHocVar) { + this._adHocVar?.subscribeToState((n, p) => { + if (n.datasource !== p.datasource || n.applicabilityEnabled !== p.applicabilityEnabled) { + this.setDrilldownApplicabilitySupportHelper({ + datasource: n.datasource, + applicabilityEnabled: n.applicabilityEnabled, + }); + } + }); + } + } + + private setDrilldownApplicabilitySupportHelper( + adHocData?: ApplicabilitySupportHelperState, + groupByData?: ApplicabilitySupportHelperState + ) { + this.setState({ + supportsApplicability: + verifyDrilldownApplicability( + this, + this._queryRunnerDatasource, + adHocData?.datasource ?? this._adHocVar?.state.datasource ?? null, + adHocData?.applicabilityEnabled ?? this._adHocVar?.state.applicabilityEnabled ?? false + ) || + verifyDrilldownApplicability( + this, + this._queryRunnerDatasource, + groupByData?.datasource ?? this._groupByVar?.state.datasource ?? null, + groupByData?.applicabilityEnabled ?? this._groupByVar?.state.applicabilityEnabled ?? false + ), + }); + } + + public getQueryRunner() { + const panel = this.parent; + const dataObject = panel ? sceneGraph.getData(panel) : undefined; + const queryRunner = dataObject?.state.$data; + + if (!queryRunner || !(queryRunner instanceof SceneQueryRunner)) { + return null; + } + + return queryRunner; + } +} + +export function VizPanelSubHeaderRenderer({ model }: SceneComponentProps) { + const { supportsApplicability, hideNonApplicableDrilldowns } = model.useState(); + const variables = sceneGraph.getVariables(model); + const adhocFiltersVar = variables.state.variables.find((variable) => variable instanceof AdHocFiltersVariable); + const groupByVar = variables.state.variables.find((variable) => variable instanceof GroupByVariable); + const queryRunner = model.getQueryRunner(); + + if (!queryRunner || hideNonApplicableDrilldowns || !supportsApplicability) { + return null; + } + + return ( + + ); +} diff --git a/public/app/features/dashboard-scene/serialization/layoutSerializers/utils.ts b/public/app/features/dashboard-scene/serialization/layoutSerializers/utils.ts index 566bb7c367a..512631961d3 100644 --- a/public/app/features/dashboard-scene/serialization/layoutSerializers/utils.ts +++ b/public/app/features/dashboard-scene/serialization/layoutSerializers/utils.ts @@ -31,6 +31,7 @@ import { LibraryPanelBehavior } from '../../scene/LibraryPanelBehavior'; import { VizPanelLinks, VizPanelLinksMenu } from '../../scene/PanelLinks'; import { panelLinksBehavior, panelMenuBehavior } from '../../scene/PanelMenuBehavior'; import { PanelNotices } from '../../scene/PanelNotices'; +import { VizPanelSubHeader } from '../../scene/VizPanelSubHeader'; import { AutoGridItem } from '../../scene/layout-auto-grid/AutoGridItem'; import { DashboardGridItem } from '../../scene/layout-default/DashboardGridItem'; import { PanelTimeRange } from '../../scene/panel-timerange/PanelTimeRange'; @@ -70,6 +71,9 @@ export function buildVizPanel(panel: PanelKind, id?: number): VizPanel { seriesLimit: config.panelSeriesLimit, $data: createPanelDataProvider(panel), titleItems, + subHeader: new VizPanelSubHeader({ + hideNonApplicableDrilldowns: !config.featureToggles.perPanelNonApplicableDrilldowns, + }), $behaviors: [], extendPanelContext: setDashboardPanelContext, }; @@ -106,6 +110,9 @@ export function buildLibraryPanel(panel: LibraryPanelKind, id?: number): VizPane const vizPanelState: VizPanelState = { key: getVizPanelKeyForPanelId(id ?? panel.spec.id), titleItems, + subHeader: new VizPanelSubHeader({ + hideNonApplicableDrilldowns: !config.featureToggles.perPanelNonApplicableDrilldowns, + }), seriesLimit: config.panelSeriesLimit, $behaviors: [ new LibraryPanelBehavior({ diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index 25cb5d55e44..41dcc938222 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -45,6 +45,7 @@ import { LibraryPanelBehavior } from '../scene/LibraryPanelBehavior'; import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks'; import { panelLinksBehavior, panelMenuBehavior } from '../scene/PanelMenuBehavior'; import { PanelNotices } from '../scene/PanelNotices'; +import { VizPanelSubHeader } from '../scene/VizPanelSubHeader'; import { DashboardGridItem, RepeatDirection } from '../scene/layout-default/DashboardGridItem'; import { DefaultGridLayoutManager } from '../scene/layout-default/DefaultGridLayoutManager'; import { RowRepeaterBehavior } from '../scene/layout-default/RowRepeaterBehavior'; @@ -440,6 +441,9 @@ export function buildGridItemForPanel(panel: PanelModel): DashboardGridItem { hoverHeaderOffset: 0, $data: createPanelDataProvider(panel), titleItems, + subHeader: new VizPanelSubHeader({ + hideNonApplicableDrilldowns: !config.featureToggles.perPanelNonApplicableDrilldowns, + }), $behaviors: [], extendPanelContext: setDashboardPanelContext, _UNSAFE_customMigrationHandler: getAngularPanelMigrationHandler(panel), diff --git a/public/app/features/dashboard-scene/utils/drilldownUtils.test.ts b/public/app/features/dashboard-scene/utils/drilldownUtils.test.ts new file mode 100644 index 00000000000..eb8a30baea3 --- /dev/null +++ b/public/app/features/dashboard-scene/utils/drilldownUtils.test.ts @@ -0,0 +1,236 @@ +import type { DrilldownsApplicability } from '@grafana/data'; +import { DataSourceSrv, getDataSourceSrv } from '@grafana/runtime'; +import { + AdHocFiltersVariable, + GroupByVariable, + SceneQueryRunner, + SceneDataTransformer, + SceneVariableSet, + VizPanel, + VizPanelState, +} from '@grafana/scenes'; +import { DataSourceRef } from '@grafana/schema'; + +import { DashboardScene } from '../scene/DashboardScene'; +import { VizPanelSubHeader } from '../scene/VizPanelSubHeader'; +import { DefaultGridLayoutManager } from '../scene/layout-default/DefaultGridLayoutManager'; + +import { getDrilldownApplicability, verifyDrilldownApplicability } from './drilldownUtils'; + +jest.mock('@grafana/runtime', () => { + const actual = jest.requireActual('@grafana/runtime'); + return { + ...actual, + getDataSourceSrv: jest.fn(), + }; +}); + +const getDataSourceSrvMock = getDataSourceSrv as jest.MockedFunction; + +// Helper to create partial DataSourceSrv mock +const createMockDataSourceSrv = (overrides: Partial = {}): DataSourceSrv => ({ + get: jest.fn(), + getList: jest.fn(), + getInstanceSettings: jest.fn(), + reload: jest.fn(), + registerRuntimeDataSource: jest.fn(), + ...overrides, +}); + +describe('verifyDrilldownApplicability', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('returns true when applicability is enabled and datasources match', () => { + const subHeader = new VizPanelSubHeader({}); + + const result = verifyDrilldownApplicability( + subHeader, + { uid: 'ds-1' } as DataSourceRef, + { uid: 'ds-1' } as DataSourceRef, + true + ); + + expect(result).toBe(true); + }); + + it('returns false when datasources differ or applicability disabled', () => { + const subHeader = new VizPanelSubHeader({}); + + const mismatch = verifyDrilldownApplicability( + subHeader, + { uid: 'ds-1' } as DataSourceRef, + { uid: 'ds-2' } as DataSourceRef, + true + ); + + expect(mismatch).toBe(false); + + const disabled = verifyDrilldownApplicability( + subHeader, + { uid: 'ds-1' } as DataSourceRef, + { uid: 'ds-1' } as DataSourceRef, + false + ); + + expect(disabled).toBe(false); + }); +}); + +describe('getDrilldownApplicability', () => { + beforeEach(() => { + const applicabilityFn = jest.fn().mockResolvedValue([]); + getDataSourceSrvMock.mockReturnValue( + createMockDataSourceSrv({ + get: jest.fn().mockResolvedValue({ getDrilldownsApplicability: applicabilityFn }), + getInstanceSettings: jest.fn(), + }) + ); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('returns undefined when no drilldown variables are provided', async () => { + const queryRunner = new SceneQueryRunner({ + datasource: { uid: 'ds-1' }, + queries: [{ refId: 'A' }], + }); + + const result = await getDrilldownApplicability(queryRunner); + + expect(result).toBeUndefined(); + expect(getDataSourceSrvMock).not.toHaveBeenCalled(); + }); + + it('returns undefined when datasource lacks getDrilldownsApplicability', async () => { + getDataSourceSrvMock.mockReturnValue( + createMockDataSourceSrv({ + get: jest.fn().mockResolvedValue({}), + getInstanceSettings: jest.fn(), + }) + ); + + const { queryRunner, groupByVariable } = buildScene(); + + const result = await getDrilldownApplicability(queryRunner, undefined, groupByVariable); + + expect(result).toBeUndefined(); + }); + + it('returns undefined when drilldown variables use a different datasource', async () => { + const applicabilityFn = jest.fn().mockResolvedValue([]); + getDataSourceSrvMock.mockReturnValue( + createMockDataSourceSrv({ + get: jest.fn().mockResolvedValue({ getDrilldownsApplicability: applicabilityFn }), + getInstanceSettings: jest.fn(), + }) + ); + + const { queryRunner, adhocFiltersVariable, groupByVariable } = buildScene({ + datasourceUid: 'ds-query', + filtersDatasourceUid: 'ds-other', + groupByDatasourceUid: 'ds-other', + }); + + const result = await getDrilldownApplicability(queryRunner, adhocFiltersVariable, groupByVariable); + + expect(result).toBeUndefined(); + expect(applicabilityFn).not.toHaveBeenCalled(); + }); + + it('returns applicability data when datasource and variables align', async () => { + const applicability: DrilldownsApplicability[] = [{ key: 'region', applicable: true }]; + const getApplicability = jest.fn().mockResolvedValue(applicability); + getDataSourceSrvMock.mockReturnValue( + createMockDataSourceSrv({ + get: jest.fn().mockResolvedValue({ getDrilldownsApplicability: getApplicability }), + getInstanceSettings: jest.fn(), + }) + ); + + const { queryRunner, adhocFiltersVariable, groupByVariable } = buildScene({ + datasourceUid: 'ds-apply', + filtersDatasourceUid: 'ds-apply', + groupByDatasourceUid: 'ds-apply', + groupValues: ['region', 'instance'], + }); + + const result = await getDrilldownApplicability(queryRunner, adhocFiltersVariable, groupByVariable); + + expect(getApplicability).toHaveBeenCalledTimes(1); + const payload = getApplicability.mock.calls[0][0]; + expect(payload.groupByKeys).toEqual(['region', 'instance']); + expect(payload.filters).toEqual([]); + expect(payload.queries).toBe(queryRunner.state.data?.request?.targets); + expect(payload.timeRange).toBeDefined(); + expect(result).toBe(applicability); + }); +}); + +interface BuildSceneOptions { + datasourceUid?: string; + groupByDatasourceUid?: string; + filtersDatasourceUid?: string; + groupValues?: Array; +} + +function buildScene({ + datasourceUid = 'ds-1', + groupByDatasourceUid = datasourceUid, + filtersDatasourceUid = datasourceUid, + groupValues = ['groupBy'], +}: BuildSceneOptions = {}) { + const subHeader = new VizPanelSubHeader({}); + + const queryRunner = new SceneQueryRunner({ + datasource: { uid: datasourceUid }, + queries: [{ refId: 'A', datasource: { uid: datasourceUid } }], + }); + + const adhocFiltersVariable = new AdHocFiltersVariable({ + name: 'adhoc', + label: 'adhoc', + filters: [], + datasource: { uid: filtersDatasourceUid }, + applicabilityEnabled: true, + }); + + const groupByVariable = new GroupByVariable({ + name: 'group', + label: 'group', + value: groupValues, + text: groupValues.map((val) => String(val)), + options: [], + applicabilityEnabled: true, + datasource: { uid: groupByDatasourceUid }, + }); + + const dataProvider = new SceneDataTransformer({ + $data: queryRunner, + transformations: [], + }); + + const panelState: VizPanelState = { + key: 'panel-1', + title: 'Panel A', + pluginId: 'timeseries', + subHeader, + $data: dataProvider, + options: {}, + fieldConfig: { defaults: {}, overrides: [] }, + }; + + const panel = new VizPanel(panelState); + + new DashboardScene({ + $variables: new SceneVariableSet({ + variables: [groupByVariable, adhocFiltersVariable], + }), + body: DefaultGridLayoutManager.fromVizPanels([panel]), + }); + + return { queryRunner, adhocFiltersVariable, groupByVariable }; +} diff --git a/public/app/features/dashboard-scene/utils/drilldownUtils.ts b/public/app/features/dashboard-scene/utils/drilldownUtils.ts new file mode 100644 index 00000000000..2ff0ecf7c6e --- /dev/null +++ b/public/app/features/dashboard-scene/utils/drilldownUtils.ts @@ -0,0 +1,75 @@ +import { DrilldownsApplicability } from '@grafana/data'; +import { getDataSourceSrv } from '@grafana/runtime'; +import { AdHocFiltersVariable, GroupByVariable, sceneGraph, SceneObject, SceneQueryRunner } from '@grafana/scenes'; +import { DataSourceRef } from '@grafana/schema'; + +export function verifyDrilldownApplicability( + sourceObject: SceneObject, + queriesDataSource: DataSourceRef | undefined, + drilldownDatasource: DataSourceRef | null, + isApplicabilityEnabled?: boolean +): boolean { + const datasourceUid = sceneGraph.interpolate(sourceObject, queriesDataSource?.uid); + + return Boolean( + isApplicabilityEnabled && datasourceUid === sceneGraph.interpolate(sourceObject, drilldownDatasource?.uid) + ); +} + +export async function getDrilldownApplicability( + queryRunner: SceneQueryRunner, + filtersVar?: AdHocFiltersVariable, + groupByVar?: GroupByVariable +): Promise { + //if no drilldown vars return + if (!filtersVar && !groupByVar) { + return; + } + + const datasource = queryRunner.state.datasource; + const queries = queryRunner.state.data?.request?.targets; + + const ds = await getDataSourceSrv().get(datasource?.uid); + + // return if method not implemented + if (!ds.getDrilldownsApplicability) { + return; + } + + const dsUid = sceneGraph.interpolate(queryRunner, datasource?.uid); + const timeRange = sceneGraph.getTimeRange(queryRunner).state.value; + const groupByKeys = []; + const filters = []; + + const hasGroupByApplicability = + groupByVar && dsUid === sceneGraph.interpolate(groupByVar, groupByVar?.state.datasource?.uid); + const hasFiltersApplicability = + filtersVar && dsUid === sceneGraph.interpolate(filtersVar, filtersVar.state?.datasource?.uid); + + // if neither vars use the ds from the queries, return + if (!hasGroupByApplicability && !hasFiltersApplicability) { + return; + } + + if (hasGroupByApplicability) { + groupByKeys.push( + ...(Array.isArray(groupByVar.state.value) + ? groupByVar.state.value.map((v) => String(v)) + : groupByVar.state.value + ? [String(groupByVar.state.value)] + : []) + ); + } + + if (hasFiltersApplicability) { + filters.push(...filtersVar.state.filters, ...(filtersVar.state.originFilters ?? [])); + } + + return await ds.getDrilldownsApplicability({ + groupByKeys, + filters, + queries, + timeRange, + scopes: sceneGraph.getScopes(queryRunner), + }); +} diff --git a/public/app/features/dashboard-scene/utils/utils.ts b/public/app/features/dashboard-scene/utils/utils.ts index 36ccabdca23..7691b52f3b8 100644 --- a/public/app/features/dashboard-scene/utils/utils.ts +++ b/public/app/features/dashboard-scene/utils/utils.ts @@ -24,6 +24,7 @@ import { LibraryPanelBehavior } from '../scene/LibraryPanelBehavior'; import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks'; import { panelMenuBehavior } from '../scene/PanelMenuBehavior'; import { UNCONFIGURED_PANEL_PLUGIN_ID } from '../scene/UnconfiguredPanel'; +import { VizPanelSubHeader } from '../scene/VizPanelSubHeader'; import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem'; import { setDashboardPanelContext } from '../scene/setDashboardPanelContext'; import { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types/DashboardLayoutManager'; @@ -267,6 +268,9 @@ export function getDefaultVizPanel(): VizPanel { titleItems: [new VizPanelLinks({ menu: new VizPanelLinksMenu({}) })], hoverHeaderOffset: 0, $behaviors: [], + subHeader: new VizPanelSubHeader({ + hideNonApplicableDrilldowns: !config.featureToggles.perPanelNonApplicableDrilldowns, + }), extendPanelContext: setDashboardPanelContext, menu: new VizPanelMenu({ $behaviors: [panelMenuBehavior], diff --git a/yarn.lock b/yarn.lock index 1e810d79f5c..778173eec14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1473,7 +1473,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.24.7, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.10, @babel/runtime@npm:^7.26.7, @babel/runtime@npm:^7.27.0, @babel/runtime@npm:^7.27.6, @babel/runtime@npm:^7.28.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.24.7, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.7, @babel/runtime@npm:^7.27.0, @babel/runtime@npm:^7.27.6, @babel/runtime@npm:^7.28.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": version: 7.28.4 resolution: "@babel/runtime@npm:7.28.4" checksum: 10/6c9a70452322ea80b3c9b2a412bcf60771819213a67576c8cec41e88a95bb7bf01fc983754cda35dc19603eef52df22203ccbf7777b9d6316932f9fb77c25163 @@ -2324,15 +2324,15 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:2.3.6": - version: 2.3.6 - resolution: "@formatjs/ecma402-abstract@npm:2.3.6" +"@formatjs/ecma402-abstract@npm:2.3.4": + version: 2.3.4 + resolution: "@formatjs/ecma402-abstract@npm:2.3.4" dependencies: "@formatjs/fast-memoize": "npm:2.2.7" - "@formatjs/intl-localematcher": "npm:0.6.2" + "@formatjs/intl-localematcher": "npm:0.6.1" decimal.js: "npm:^10.4.3" tslib: "npm:^2.8.0" - checksum: 10/30b1b5cd6b62ba46245f934429936592df5500bc1b089dc92dd49c826757b873dd92c305dcfe370701e4df6b057bf007782113abb9b65db550d73be4961718bc + checksum: 10/573971ffc291096a4b9fcc80b4708124e89bf2e3ac50e0f78b41eb797e9aa1b842f4dc3665e4467a853c738386821769d9e40408a1d25bc73323a1f057a16cf2 languageName: node linkType: hard @@ -2376,13 +2376,13 @@ __metadata: linkType: hard "@formatjs/intl-durationformat@npm:^0.7.0": - version: 0.7.6 - resolution: "@formatjs/intl-durationformat@npm:0.7.6" + version: 0.7.4 + resolution: "@formatjs/intl-durationformat@npm:0.7.4" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.6" - "@formatjs/intl-localematcher": "npm:0.6.2" + "@formatjs/ecma402-abstract": "npm:2.3.4" + "@formatjs/intl-localematcher": "npm:0.6.1" tslib: "npm:^2.8.0" - checksum: 10/442236ba85bcd9cb7296c43a708271fa09f110b1ca9d5899066d00812fc2965eaeaec6b5240be421b80daba62860352131088449ba0fcd2061f671cec6240f0b + checksum: 10/d62273ecd635475ca91e9b501301f3f396403fa91b584c550734b19b2d194ba1316b27303fed985c1d42ae933d54eb220da6540edfdf376b0d9371ecfd0d4e15 languageName: node linkType: hard @@ -2395,12 +2395,12 @@ __metadata: languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.6.2": - version: 0.6.2 - resolution: "@formatjs/intl-localematcher@npm:0.6.2" +"@formatjs/intl-localematcher@npm:0.6.1": + version: 0.6.1 + resolution: "@formatjs/intl-localematcher@npm:0.6.1" dependencies: tslib: "npm:^2.8.0" - checksum: 10/eb12a7f5367bbecdfafc20d7f005559ce840f420e970f425c5213d35e94e86dfe75bde03464971a26494bf8427d4961269db22ecad2834f2a19d888b5d9cc064 + checksum: 10/c7b3bc8395d18670677f207b2fd107561fff5d6394a9b4273c29e0bea920300ec3a2eefead600ebb7761c04a770cada28f78ac059f84d00520bfb57a9db36998 languageName: node linkType: hard @@ -3596,11 +3596,11 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes-react@npm:^6.46.0": - version: 6.46.1 - resolution: "@grafana/scenes-react@npm:6.46.1" +"@grafana/scenes-react@npm:6.47.1": + version: 6.47.1 + resolution: "@grafana/scenes-react@npm:6.47.1" dependencies: - "@grafana/scenes": "npm:6.46.1" + "@grafana/scenes": "npm:6.47.1" lru-cache: "npm:^10.2.2" react-use: "npm:^17.4.0" peerDependencies: @@ -3612,7 +3612,7 @@ __metadata: react: ^18.0.0 react-dom: ^18.0.0 react-router-dom: ^6.28.0 - checksum: 10/47007ae998dd52c774f1b53cc1cbd62cbff6c077886ba36381f371454918bd7fbe9ea9373e021a38ba0144e507c8c51a435a2be1aa8250a36c37d7bbfa72fb9d + checksum: 10/dc20f9ee80eaf648665f7449e3ccb3b640a931f8f4a1be89599dce17eb0f52e763e3a603a4d491d9886b3e6cdf2ad3634124252c223315917206200f7cd6da16 languageName: node linkType: hard @@ -3642,9 +3642,9 @@ __metadata: languageName: node linkType: hard -"@grafana/scenes@npm:6.46.1, @grafana/scenes@npm:^6.46.0": - version: 6.46.1 - resolution: "@grafana/scenes@npm:6.46.1" +"@grafana/scenes@npm:6.47.1": + version: 6.47.1 + resolution: "@grafana/scenes@npm:6.47.1" dependencies: "@floating-ui/react": "npm:^0.26.16" "@leeoniya/ufuzzy": "npm:^1.0.16" @@ -3664,7 +3664,7 @@ __metadata: react: ^18.0.0 react-dom: ^18.0.0 react-router-dom: ^6.28.0 - checksum: 10/e72a90833a94307c6a4633d9f637e407f681d2be9fa27938158b0bdbb9520e31a3ff804eaab3f5e146673af5a21822b6a8279b4b8fd2ead79b94e2593e366144 + checksum: 10/bc0c76258955058e7493b04e7cdd5d59dcc4159adf06da0837e992716ea15700b54f8403614df04326350363dc3344fb2602a2e8f7807724571659b4bd95aded languageName: node linkType: hard @@ -4118,13 +4118,20 @@ __metadata: languageName: node linkType: hard -"@inquirer/figures@npm:^1.0.14, @inquirer/figures@npm:^1.0.3": +"@inquirer/figures@npm:^1.0.14": version: 1.0.14 resolution: "@inquirer/figures@npm:1.0.14" checksum: 10/39df361eb607cea5a020d457e25f9c6aee3a1de8975c6295a4b3bfe86ba7e7f7bfbefa6a52b145b1790f2690e5c8f10eb822e5bc764aff7ba00a6cd24eec5a25 languageName: node linkType: hard +"@inquirer/figures@npm:^1.0.3": + version: 1.0.11 + resolution: "@inquirer/figures@npm:1.0.11" + checksum: 10/357ddd2e83718bc3c9189d518b93fd69099af9c860354df9a5ac0ec024cb5df1228ae4608d2de7625624d2adcd047db813f29426a610eaae7b9e449f8c753c6b + languageName: node + linkType: hard + "@inquirer/input@npm:^4.2.5": version: 4.2.5 resolution: "@inquirer/input@npm:4.2.5" @@ -6096,9 +6103,9 @@ __metadata: linkType: hard "@openfeature/core@npm:^1.9.0": - version: 1.9.1 - resolution: "@openfeature/core@npm:1.9.1" - checksum: 10/6099e16b1b4cd6e3c45c05ab4acd44c9cb4ab501b676ab6f3e77f0be1b56abc7506c5629187381333a02975d315d831e0905582435b356d9676255e72a465899 + version: 1.9.0 + resolution: "@openfeature/core@npm:1.9.0" + checksum: 10/c6d20edc09053afd99752fe46d8328158680950bca4b86679f67f79249d7226eea127b31fffdc38e26ecb729f2bab5a4a5a7c1db708ae76b7fbbac68cd56f094 languageName: node linkType: hard @@ -6123,11 +6130,11 @@ __metadata: linkType: hard "@openfeature/web-sdk@npm:^1.6.1": - version: 1.7.1 - resolution: "@openfeature/web-sdk@npm:1.7.1" + version: 1.6.1 + resolution: "@openfeature/web-sdk@npm:1.6.1" peerDependencies: "@openfeature/core": ^1.9.0 - checksum: 10/358cabfddda8bf67a9bd96ce28f0f84a3218416907f8df4f2a58750ee840d164d86a1c859e8c9aa92d132fa28fcf72a0f17ceece798ff8af297d3e1c1e30cdab + checksum: 10/8bd7d1ea386e21cdd7492cab2fd1d2b138b4e6a376a4c0a40244633e5955f6452039bc2633fc5230bd7b494506a4137ba7210d40850634f9618f77a0ee435f9d languageName: node linkType: hard @@ -7107,7 +7114,7 @@ __metadata: languageName: node linkType: hard -"@reduxjs/toolkit@npm:2.10.1, @reduxjs/toolkit@npm:^2.9.0": +"@reduxjs/toolkit@npm:2.10.1": version: 2.10.1 resolution: "@reduxjs/toolkit@npm:2.10.1" dependencies: @@ -7129,6 +7136,28 @@ __metadata: languageName: node linkType: hard +"@reduxjs/toolkit@npm:^2.9.0": + version: 2.9.2 + resolution: "@reduxjs/toolkit@npm:2.9.2" + dependencies: + "@standard-schema/spec": "npm:^1.0.0" + "@standard-schema/utils": "npm:^0.3.0" + immer: "npm:^10.0.3" + redux: "npm:^5.0.1" + redux-thunk: "npm:^3.1.0" + reselect: "npm:^5.1.0" + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 || ^19 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + checksum: 10/7a8fa57086bc44dafe2f04428d6557edad46ee6eb46b2fe80468ebf934a441a7d4d750b50a6d41bc360d9ab61baadb1dddb5a8f556cfac68977f56e832f509a2 + languageName: node + linkType: hard + "@remix-run/router@npm:1.19.1": version: 1.19.1 resolution: "@remix-run/router@npm:1.19.1" @@ -9007,7 +9036,7 @@ __metadata: languageName: node linkType: hard -"@swc/core@npm:1.13.19, @swc/core@npm:^1.10.8, @swc/core@npm:^1.5.22": +"@swc/core@npm:1.13.19": version: 1.13.19 resolution: "@swc/core@npm:1.13.19" dependencies: @@ -9053,7 +9082,7 @@ __metadata: languageName: node linkType: hard -"@swc/core@npm:1.13.3": +"@swc/core@npm:1.13.3, @swc/core@npm:^1.10.8, @swc/core@npm:^1.5.22": version: 1.13.3 resolution: "@swc/core@npm:1.13.3" dependencies: @@ -12287,7 +12316,18 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1, axios@npm:^1.10.0, axios@npm:^1.12.2, axios@npm:^1.6.1, axios@npm:^1.8.3": +"axios@npm:^1, axios@npm:^1.10.0, axios@npm:^1.6.1, axios@npm:^1.8.3": + version: 1.12.2 + resolution: "axios@npm:1.12.2" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.4" + proxy-from-env: "npm:^1.1.0" + checksum: 10/886a79770594eaad76493fecf90344b567bd956240609b5dcd09bd0afe8d3e6f1ad6d3257a93a483b6192b409d4b673d9515a34619e3e3ed1b2c0ec2a83b20ba + languageName: node + linkType: hard + +"axios@npm:^1.12.2": version: 1.13.2 resolution: "axios@npm:1.13.2" dependencies: @@ -13211,7 +13251,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:5.6.2, chalk@npm:^5.2.0, chalk@npm:^5.3.0, chalk@npm:^5.4.1, chalk@npm:^5.6.2": +"chalk@npm:5.6.2, chalk@npm:^5.6.2": version: 5.6.2 resolution: "chalk@npm:5.6.2" checksum: 10/1b2f48f6fba1370670d5610f9cd54c391d6ede28f4b7062dd38244ea5768777af72e5be6b74fb6c6d54cb84c4a2dff3f3afa9b7cb5948f7f022cfd3d087989e0 @@ -13249,6 +13289,13 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^5.2.0, chalk@npm:^5.3.0, chalk@npm:^5.4.1": + version: 5.4.1 + resolution: "chalk@npm:5.4.1" + checksum: 10/29df3ffcdf25656fed6e95962e2ef86d14dfe03cd50e7074b06bad9ffbbf6089adbb40f75c00744d843685c8d008adaf3aed31476780312553caf07fa86e5bc7 + languageName: node + linkType: hard + "chance@npm:^1.1.13": version: 1.1.13 resolution: "chance@npm:1.1.13" @@ -13852,7 +13899,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:14.0.1, commander@npm:~14.0.0": +"commander@npm:14.0.1": version: 14.0.1 resolution: "commander@npm:14.0.1" checksum: 10/783115e9403caeca29c0fcbd4e0358f70c67760e4e4933f3453fcdd5ddba2ec44173c8da5213d7ce5e404f51c7e71203a42c548164dbe27b668b32a8981577f1 @@ -13929,6 +13976,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:~14.0.0": + version: 14.0.0 + resolution: "commander@npm:14.0.0" + checksum: 10/c05418bfc35a3e8b5c67bd9f75f5b773f386f9b85f83e70e7c926047f270929cb06cf13cd68f387dd6e7e23c6157de8171b28ba606abd3e6256028f1f789becf + languageName: node + linkType: hard + "comment-parser@npm:1.4.1": version: 1.4.1 resolution: "comment-parser@npm:1.4.1" @@ -16176,7 +16230,16 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.6, enquirer@npm:^2.4.1": +"enquirer@npm:^2.3.6, enquirer@npm:~2.3.6": + version: 2.3.6 + resolution: "enquirer@npm:2.3.6" + dependencies: + ansi-colors: "npm:^4.1.1" + checksum: 10/751d14f037eb7683997e696fb8d5fe2675e0b0cde91182c128cf598acf3f5bd9005f35f7c2a9109e291140af496ebec237b6dac86067d59a9b44f3688107f426 + languageName: node + linkType: hard + +"enquirer@npm:^2.4.1": version: 2.4.1 resolution: "enquirer@npm:2.4.1" dependencies: @@ -16186,15 +16249,6 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:~2.3.6": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: "npm:^4.1.1" - checksum: 10/751d14f037eb7683997e696fb8d5fe2675e0b0cde91182c128cf598acf3f5bd9005f35f7c2a9109e291140af496ebec237b6dac86067d59a9b44f3688107f426 - languageName: node - linkType: hard - "ensure-posix-path@npm:^1.1.0": version: 1.1.1 resolution: "ensure-posix-path@npm:1.1.1" @@ -18604,19 +18658,19 @@ __metadata: languageName: node linkType: hard -"glob@npm:*": - version: 12.0.0 - resolution: "glob@npm:12.0.0" +"glob@npm:*, glob@npm:11.0.3": + version: 11.0.3 + resolution: "glob@npm:11.0.3" dependencies: foreground-child: "npm:^3.3.1" jackspeak: "npm:^4.1.1" - minimatch: "npm:^10.1.1" + minimatch: "npm:^10.0.3" minipass: "npm:^7.1.2" package-json-from-dist: "npm:^1.0.0" path-scurry: "npm:^2.0.0" bin: glob: dist/esm/bin.mjs - checksum: 10/6e21b3f1f1fa635836d45e54bbe50704884cc3e310e0cc011cfb5429db65a030e12936d99b07e66236370efe45dc8c8b26fa5334dbf555d6f8709e0315c77c30 + checksum: 10/2ae536c1360c0266b523b2bfa6aadc10144a8b7e08869b088e37ac3c27cd30774f82e4bfb291cde796776e878f9e13200c7ff44010eb7054e00f46f649397893 languageName: node linkType: hard @@ -18651,22 +18705,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:11.0.3": - version: 11.0.3 - resolution: "glob@npm:11.0.3" - dependencies: - foreground-child: "npm:^3.3.1" - jackspeak: "npm:^4.1.1" - minimatch: "npm:^10.0.3" - minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^2.0.0" - bin: - glob: dist/esm/bin.mjs - checksum: 10/2ae536c1360c0266b523b2bfa6aadc10144a8b7e08869b088e37ac3c27cd30774f82e4bfb291cde796776e878f9e13200c7ff44010eb7054e00f46f649397893 - languageName: node - linkType: hard - "glob@npm:11.1.0, glob@npm:^11.0.0": version: 11.1.0 resolution: "glob@npm:11.1.0" @@ -18926,8 +18964,8 @@ __metadata: "@grafana/plugin-ui": "npm:^0.11.1" "@grafana/prometheus": "workspace:*" "@grafana/runtime": "workspace:*" - "@grafana/scenes": "npm:^6.46.0" - "@grafana/scenes-react": "npm:^6.46.0" + "@grafana/scenes": "npm:6.47.1" + "@grafana/scenes-react": "npm:6.47.1" "@grafana/schema": "workspace:*" "@grafana/sql": "workspace:*" "@grafana/test-utils": "workspace:*" @@ -20051,22 +20089,22 @@ __metadata: linkType: hard "i18next@npm:^23.5.1 || ^24.2.0": - version: 24.2.3 - resolution: "i18next@npm:24.2.3" + version: 24.2.2 + resolution: "i18next@npm:24.2.2" dependencies: - "@babel/runtime": "npm:^7.26.10" + "@babel/runtime": "npm:^7.23.2" peerDependencies: typescript: ^5 peerDependenciesMeta: typescript: optional: true - checksum: 10/6c73d964f2a98b1aa2c2717fe6da66fc265bcbbc5fcd52b2bfff51ff013d30d4f7d7449c4eb7f464d27af43e2e73f2e7f1d46a144d731bd3bdb1385d4c199e4c + checksum: 10/f66ed9e56d9412e59502f5df39163631daf9f1264774732fb21edbd66a528ca7a6b67dc2e2aec95683c6c7956e42c651587a54bd8ee082bd12008880ce6cd326 languageName: node linkType: hard "i18next@npm:^25.0.0, i18next@npm:^25.5.2": - version: 25.6.2 - resolution: "i18next@npm:25.6.2" + version: 25.5.2 + resolution: "i18next@npm:25.5.2" dependencies: "@babel/runtime": "npm:^7.27.6" peerDependencies: @@ -20074,7 +20112,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/bb7f3e200caac72bacaead766287dbad5ed5945430bd9f2be1c14fbccd49cf78ab751f78cf53cd0be3ec063bc4c40837d7d771f7b14d50fcb9022e1ed5d6e72f + checksum: 10/8d52e82386722a228f4465aa5cf39d82bd9861ea9cc8b31d7cc4d22d5e70b2740ee006068b09f486d5273cabd227a2ac14f37d68fab26344524200083f679bcd languageName: node linkType: hard @@ -20169,7 +20207,7 @@ __metadata: languageName: node linkType: hard -"immer@npm:10.2.0, immer@npm:^10.2.0": +"immer@npm:10.2.0, immer@npm:^10.0.3, immer@npm:^10.2.0": version: 10.2.0 resolution: "immer@npm:10.2.0" checksum: 10/d73e218c8f8ffbb39f9290dfafa478b94af73403dcf26b5672eef35233bb30f09ffe231f8a78a6c9cb442968510edd89e851776ec90a5ddfa82cee6db6b35137 @@ -23175,9 +23213,9 @@ __metadata: linkType: hard "lossless-json@npm:^4.1.1": - version: 4.3.0 - resolution: "lossless-json@npm:4.3.0" - checksum: 10/a984a882c79b6e62a917d0202518472c17587bdee002f1427d7ec61115f9fbdeb5f0baa9f0e9fff8d9dbacd17da6b6c910012b2dcab69dd33d151cb7c13d5a37 + version: 4.2.0 + resolution: "lossless-json@npm:4.2.0" + checksum: 10/b29cbf9a90b8f3108219ff410223a90a3a6ad14cf902eed4038571d9421c69ade7077fb59737e1ca20f3f404ddd68fad69be11365b0d79b4b61421b054759551 languageName: node linkType: hard @@ -23652,9 +23690,9 @@ __metadata: linkType: hard "micro-memoize@npm:^4.1.2": - version: 4.2.0 - resolution: "micro-memoize@npm:4.2.0" - checksum: 10/260e27a5c15809f7dc435a89a424d93e49ccca62b743fa96ee72f254264df58c95edacbd847a2899a6d7f8ad0daef188548a8b12add5ccff83e88869a50a762c + version: 4.1.3 + resolution: "micro-memoize@npm:4.1.3" + checksum: 10/4e9c7767911cc76ae9c9779584ec87844437af9446b295a01774640a732c2c7f91944794027f44625031f7330ab7f9147740d0a9fb612680d1d2d858dad43402 languageName: node linkType: hard @@ -26460,6 +26498,15 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.54.1": + version: 1.54.1 + resolution: "playwright-core@npm:1.54.1" + bin: + playwright-core: cli.js + checksum: 10/c0acfb7ecb48e9fb6c22f71298b966244bd4f8659093a798cc7f9a509deee22109560e44f2d507124e7718779640e0b4cb05a05c068b034405418d8740ec31ff + languageName: node + linkType: hard + "playwright-core@npm:1.56.1, playwright-core@npm:>=1.2.0": version: 1.56.1 resolution: "playwright-core@npm:1.56.1" @@ -26469,7 +26516,7 @@ __metadata: languageName: node linkType: hard -"playwright@npm:1.56.1, playwright@npm:^1.14.0": +"playwright@npm:1.56.1": version: 1.56.1 resolution: "playwright@npm:1.56.1" dependencies: @@ -26484,6 +26531,21 @@ __metadata: languageName: node linkType: hard +"playwright@npm:^1.14.0": + version: 1.54.1 + resolution: "playwright@npm:1.54.1" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.54.1" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10/ebad2924b589a4cfedf48288e67b4afc81047222e607321c9452a37610025e6e249bdfeff010c1c70cf9a9d35c0b9e5cb7934a58986f67928dd469d9fde1a035 + languageName: node + linkType: hard + "plop@npm:^4.0.1": version: 4.0.1 resolution: "plop@npm:4.0.1"