From 08203a060e94de08220bdbc9edb1fff6abb75b92 Mon Sep 17 00:00:00 2001 From: Darren Janeczek <38694490+darrenjaneczek@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:13:17 -0400 Subject: [PATCH] feat: NavTree menu entry for adaptive telemetry grafana cloud apps (#109561) * feat: NavTree menu entry for adaptive telemetry grafana cloud apps * feat: 'adaptive-telemetry' icon added --- packages/grafana-data/src/types/icon.ts | 1 + pkg/services/navtree/models.go | 1 + pkg/services/navtree/navtreeimpl/applinks.go | 31 +++++++++++++++++-- public/app/routes/routes.tsx | 4 +++ .../img/icons/unicons/adaptive-telemetry.svg | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 public/img/icons/unicons/adaptive-telemetry.svg diff --git a/packages/grafana-data/src/types/icon.ts b/packages/grafana-data/src/types/icon.ts index 1f7cf51c2ee..b59fdeca75a 100644 --- a/packages/grafana-data/src/types/icon.ts +++ b/packages/grafana-data/src/types/icon.ts @@ -98,6 +98,7 @@ export const availableIconsIndex = { 'download-alt': true, draggabledots: true, drilldown: true, + 'adaptive-telemetry': true, edit: true, 'ellipsis-v': true, enter: true, diff --git a/pkg/services/navtree/models.go b/pkg/services/navtree/models.go index 250b3bf8717..51bbdf261b1 100644 --- a/pkg/services/navtree/models.go +++ b/pkg/services/navtree/models.go @@ -41,6 +41,7 @@ const ( NavIDDashboards = "dashboards/browse" NavIDExplore = "explore" NavIDDrilldown = "drilldown" + NavIDAdaptiveTelemetry = "adaptive-telemetry" NavIDCfg = "cfg" // NavIDCfg is the id for org configuration navigation node NavIDAlertsAndIncidents = "alerts-and-incidents" NavIDTestingAndSynthetics = "testing-and-synthetics" diff --git a/pkg/services/navtree/navtreeimpl/applinks.go b/pkg/services/navtree/navtreeimpl/applinks.go index b54e679de9c..0cc24694b96 100644 --- a/pkg/services/navtree/navtreeimpl/applinks.go +++ b/pkg/services/navtree/navtreeimpl/applinks.go @@ -37,6 +37,8 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel return false } + enabledAccessibleAppPluginMap := make(map[string]*pluginstore.Plugin) + for _, plugin := range s.pluginStore.Plugins(c.Req.Context(), plugins.TypeApp) { if !isPluginEnabled(plugin) { continue @@ -46,11 +48,20 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel continue } + enabledAccessibleAppPluginMap[plugin.ID] = &plugin if appNode := s.processAppPlugin(plugin, c, treeRoot); appNode != nil { appLinks = append(appLinks, appNode) } } + if adaptiveTelemetryPlugin := enabledAccessibleAppPluginMap["grafana-adaptivetelemetry-app"]; adaptiveTelemetryPlugin != nil { + if adaptiveTelemetrySection := treeRoot.FindById(navtree.NavIDAdaptiveTelemetry); adaptiveTelemetrySection != nil { + // If the adaptivetelemetry app is enabled, and the adaptiveTelemetrySection exists, then update the section to point to the plugin + adaptiveTelemetrySection.Url = s.cfg.AppSubURL + "/a/" + adaptiveTelemetryPlugin.ID + adaptiveTelemetrySection.PluginID = adaptiveTelemetryPlugin.ID + } + } + if len(appLinks) > 0 { sort.SliceStable(appLinks, func(i, j int) bool { return appLinks[i].Text < appLinks[j].Text @@ -291,6 +302,19 @@ func (s *ServiceImpl) addPluginToSection(c *contextmodel.ReqContext, treeRoot *n Children: []*navtree.NavLink{appLink}, Url: s.cfg.AppSubURL + "/testing-and-synthetics", }) + case navtree.NavIDAdaptiveTelemetry: + treeRoot.AddSection(&navtree.NavLink{ + Text: "Adaptive Telemetry", + Id: navtree.NavIDAdaptiveTelemetry, + SubTitle: "Reduce noise, cut costs, and accelerate troubleshooting by intelligently ingesting only the telemetry data that matters most.", + Icon: "adaptive-telemetry", + SortWeight: navtree.WeightAIAndML + 1, // Place under "AI & Machine Learning" + Children: []*navtree.NavLink{appLink}, + Url: "adaptive-telemetry", + // Use the icon URL from the first "Adaptive Telemetry" plugin in the list (they will all be the same) + Img: s.cfg.AppSubURL + plugin.Info.Logos.Large, + IsNew: true, + }) default: s.log.Error("Plugin app nav id not found", "pluginId", plugin.ID, "navId", sectionID) } @@ -333,9 +357,10 @@ func (s *ServiceImpl) readNavigationSettings() { "grafana-slo-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 7}, "grafana-cloud-link-app": {SectionID: navtree.NavIDCfgPlugins, SortWeight: 3}, "grafana-costmanagementui-app": {SectionID: navtree.NavIDCfg, Text: "Cost management"}, - "grafana-adaptive-metrics-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Metrics"}, - "grafana-adaptivelogs-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Logs"}, - "grafana-adaptivetraces-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Traces"}, + "grafana-adaptive-metrics-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 1, Text: "Adaptive Metrics", SubTitle: "Analyzes and reduces unused metrics and cardinality to help you focus on your most valuable performance data."}, + "grafana-adaptivelogs-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 2, Text: "Adaptive Logs", SubTitle: "Analyzes log patterns to drop repetitive lines and accelerate troubleshooting."}, + "grafana-adaptivetraces-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 3, Text: "Adaptive Traces", SubTitle: "Analyzes and retains the most valuable traces, providing the performance insights needed to resolve issues faster."}, + "grafana-adaptiveprofiles-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 4, Text: "Adaptive Profiles", SubTitle: "Analyzes application profiles to pinpoint the root cause of performance issues and accelerate resolution."}, "grafana-attributions-app": {SectionID: navtree.NavIDCfg, Text: "Attributions"}, "grafana-logvolumeexplorer-app": {SectionID: navtree.NavIDCfg, Text: "Log Volume Explorer"}, "grafana-easystart-app": {SectionID: navtree.NavIDRoot, SortWeight: navtree.WeightApps + 1, Text: "Connections", Icon: "adjust-circle"}, diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index 334087cfbed..3767ed90322 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -187,6 +187,10 @@ export function getAppRoutes(): RouteDescriptor[] { path: '/testing-and-synthetics', component: () => , }, + { + path: '/adaptive-telemetry', + component: () => , + }, { path: '/monitoring', component: () => , diff --git a/public/img/icons/unicons/adaptive-telemetry.svg b/public/img/icons/unicons/adaptive-telemetry.svg new file mode 100644 index 00000000000..557d011c86c --- /dev/null +++ b/public/img/icons/unicons/adaptive-telemetry.svg @@ -0,0 +1 @@ + \ No newline at end of file