mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Navigation: Remove ApplyAdminIA
logic (#89113)
make admin IA more normal
This commit is contained in:
parent
5bb10d84e0
commit
822644714a
@ -158,7 +158,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
|
||||
hs.HooksService.RunIndexDataHooks(&data, c)
|
||||
|
||||
data.NavTree.ApplyAdminIA()
|
||||
data.NavTree.ApplyCostManagementIA()
|
||||
data.NavTree.ApplyHelpVersion(data.Settings.BuildInfo.VersionString) // RunIndexDataHooks can modify the version string
|
||||
data.NavTree.Sort()
|
||||
|
||||
|
@ -59,12 +59,13 @@ func ProvideService(cfg *setting.Cfg, hooksService *hooks.HooksService) *OSSLice
|
||||
return
|
||||
}
|
||||
|
||||
if adminNode := indexData.NavTree.FindById(navtree.NavIDCfg); adminNode != nil {
|
||||
if adminNode := indexData.NavTree.FindById(navtree.NavIDCfgGeneral); adminNode != nil {
|
||||
adminNode.Children = append(adminNode.Children, &navtree.NavLink{
|
||||
Text: "Stats and license",
|
||||
Id: "upgrading",
|
||||
Url: l.LicenseURL(req.IsGrafanaAdmin),
|
||||
Icon: "unlock",
|
||||
Text: "Stats and license",
|
||||
Id: "upgrading",
|
||||
Url: l.LicenseURL(req.IsGrafanaAdmin),
|
||||
Icon: "unlock",
|
||||
SortWeight: -1,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -136,113 +136,50 @@ func (root *NavTreeRoot) ApplyHelpVersion(version string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (root *NavTreeRoot) ApplyAdminIA() {
|
||||
func (root *NavTreeRoot) ApplyCostManagementIA() {
|
||||
orgAdminNode := root.FindById(NavIDCfg)
|
||||
var costManagementApp *NavLink
|
||||
var adaptiveMetricsApp *NavLink
|
||||
var attributionsApp *NavLink
|
||||
var logVolumeExplorerApp *NavLink
|
||||
|
||||
if orgAdminNode != nil {
|
||||
adminNodeLinks := []*NavLink{}
|
||||
|
||||
generalNodeLinks := []*NavLink{}
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("upgrading")) // TODO does this even exist
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("licensing"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("org-settings"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("server-settings"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("global-orgs"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("feature-toggles"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("storage"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("migrate-to-cloud"))
|
||||
generalNodeLinks = AppendIfNotNil(generalNodeLinks, root.FindById("banner-settings"))
|
||||
|
||||
generalNode := &NavLink{
|
||||
Text: "General",
|
||||
SubTitle: "Manage default preferences and settings across Grafana",
|
||||
Id: NavIDCfgGeneral,
|
||||
Url: "/admin/general",
|
||||
Icon: "shield",
|
||||
Children: generalNodeLinks,
|
||||
for _, element := range orgAdminNode.Children {
|
||||
switch navId := element.Id; navId {
|
||||
case "plugin-page-grafana-costmanagementui-app":
|
||||
costManagementApp = element
|
||||
case "plugin-page-grafana-adaptive-metrics-app":
|
||||
adaptiveMetricsApp = element
|
||||
case "plugin-page-grafana-attributions-app":
|
||||
attributionsApp = element
|
||||
case "plugin-page-grafana-logvolumeexplorer-app":
|
||||
logVolumeExplorerApp = element
|
||||
default:
|
||||
adminNodeLinks = append(adminNodeLinks, element)
|
||||
}
|
||||
}
|
||||
|
||||
pluginsNodeLinks := []*NavLink{}
|
||||
pluginsNodeLinks = AppendIfNotNil(pluginsNodeLinks, root.FindById("plugins"))
|
||||
pluginsNodeLinks = AppendIfNotNil(pluginsNodeLinks, root.FindById("datasources"))
|
||||
pluginsNodeLinks = AppendIfNotNil(pluginsNodeLinks, root.FindById("recordedQueries"))
|
||||
pluginsNodeLinks = AppendIfNotNil(pluginsNodeLinks, root.FindById("correlations"))
|
||||
pluginsNodeLinks = AppendIfNotNil(pluginsNodeLinks, root.FindById("plugin-page-grafana-cloud-link-app"))
|
||||
if costManagementApp != nil {
|
||||
costManagementMetricsNode := FindByURL(costManagementApp.Children, "/a/grafana-costmanagementui-app/metrics")
|
||||
if costManagementMetricsNode != nil {
|
||||
if adaptiveMetricsApp != nil {
|
||||
costManagementMetricsNode.Children = append(costManagementMetricsNode.Children, adaptiveMetricsApp)
|
||||
}
|
||||
if attributionsApp != nil {
|
||||
costManagementMetricsNode.Children = append(costManagementMetricsNode.Children, attributionsApp)
|
||||
}
|
||||
}
|
||||
|
||||
pluginsNode := &NavLink{
|
||||
Text: "Plugins and data",
|
||||
SubTitle: "Install plugins and define the relationships between data",
|
||||
Id: NavIDCfgPlugins,
|
||||
Url: "/admin/plugins",
|
||||
Icon: "shield",
|
||||
Children: pluginsNodeLinks,
|
||||
}
|
||||
|
||||
accessNodeLinks := []*NavLink{}
|
||||
accessNodeLinks = AppendIfNotNil(accessNodeLinks, root.FindById("global-users"))
|
||||
accessNodeLinks = AppendIfNotNil(accessNodeLinks, root.FindById("teams"))
|
||||
accessNodeLinks = AppendIfNotNil(accessNodeLinks, root.FindById("standalone-plugin-page-/a/grafana-auth-app"))
|
||||
accessNodeLinks = AppendIfNotNil(accessNodeLinks, root.FindById("serviceaccounts"))
|
||||
accessNodeLinks = AppendIfNotNil(accessNodeLinks, root.FindById("apikeys"))
|
||||
|
||||
usersNode := &NavLink{
|
||||
Text: "Users and access",
|
||||
SubTitle: "Configure access for individual users, teams, and service accounts",
|
||||
Id: NavIDCfgAccess,
|
||||
Url: "/admin/access",
|
||||
Icon: "shield",
|
||||
Children: accessNodeLinks,
|
||||
}
|
||||
|
||||
if len(generalNode.Children) > 0 {
|
||||
adminNodeLinks = append(adminNodeLinks, generalNode)
|
||||
}
|
||||
|
||||
if len(pluginsNode.Children) > 0 {
|
||||
adminNodeLinks = append(adminNodeLinks, pluginsNode)
|
||||
}
|
||||
|
||||
if len(usersNode.Children) > 0 {
|
||||
adminNodeLinks = append(adminNodeLinks, usersNode)
|
||||
}
|
||||
|
||||
authenticationNode := root.FindById("authentication")
|
||||
if authenticationNode != nil {
|
||||
authenticationNode.IsSection = true
|
||||
adminNodeLinks = append(adminNodeLinks, authenticationNode)
|
||||
}
|
||||
|
||||
costManagementNode := root.FindById("plugin-page-grafana-costmanagementui-app")
|
||||
|
||||
if costManagementNode != nil {
|
||||
adminNodeLinks = append(adminNodeLinks, costManagementNode)
|
||||
}
|
||||
|
||||
costManagementMetricsNode := root.FindByURL("/a/grafana-costmanagementui-app/metrics")
|
||||
adaptiveMetricsNode := root.FindById("plugin-page-grafana-adaptive-metrics-app")
|
||||
|
||||
if costManagementMetricsNode != nil && adaptiveMetricsNode != nil {
|
||||
costManagementMetricsNode.Children = append(costManagementMetricsNode.Children, adaptiveMetricsNode)
|
||||
}
|
||||
|
||||
attributionsNode := root.FindById("plugin-page-grafana-attributions-app")
|
||||
|
||||
if costManagementMetricsNode != nil && attributionsNode != nil {
|
||||
costManagementMetricsNode.Children = append(costManagementMetricsNode.Children, attributionsNode)
|
||||
}
|
||||
|
||||
costManagementLogsNode := root.FindByURL("/a/grafana-costmanagementui-app/logs")
|
||||
logVolumeExplorerNode := root.FindById("plugin-page-grafana-logvolumeexplorer-app")
|
||||
|
||||
if costManagementLogsNode != nil && logVolumeExplorerNode != nil {
|
||||
costManagementLogsNode.Children = append(costManagementLogsNode.Children, logVolumeExplorerNode)
|
||||
}
|
||||
|
||||
if len(adminNodeLinks) > 0 {
|
||||
orgAdminNode.Children = adminNodeLinks
|
||||
} else {
|
||||
root.RemoveSection(orgAdminNode)
|
||||
costManagementLogsNode := FindByURL(costManagementApp.Children, "/a/grafana-costmanagementui-app/logs")
|
||||
if costManagementLogsNode != nil {
|
||||
if logVolumeExplorerApp != nil {
|
||||
costManagementLogsNode.Children = append(costManagementLogsNode.Children, logVolumeExplorerApp)
|
||||
}
|
||||
}
|
||||
adminNodeLinks = append(adminNodeLinks, costManagementApp)
|
||||
}
|
||||
orgAdminNode.Children = adminNodeLinks
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,60 +21,9 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
orgsAccessEvaluator := ac.EvalPermission(ac.ActionOrgsRead)
|
||||
authConfigUIAvailable := s.license.FeatureEnabled(social.SAMLProviderName) || s.cfg.LDAPAuthEnabled
|
||||
|
||||
// FIXME: If plugin admin is disabled or externally managed, server admins still need to access the page, this is why
|
||||
// while we don't have a permissions for listing plugins the legacy check has to stay as a default
|
||||
if pluginaccesscontrol.ReqCanAdminPlugins(s.cfg)(c) || hasAccess(pluginaccesscontrol.AdminAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Plugins",
|
||||
Id: "plugins",
|
||||
SubTitle: "Extend the Grafana experience with plugins",
|
||||
Icon: "plug",
|
||||
Url: s.cfg.AppSubURL + "/plugins",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionOrgUsersRead), ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll))) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Users", SubTitle: "Manage users in Grafana", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.TeamsAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Teams",
|
||||
Id: "teams",
|
||||
SubTitle: "Groups of users that have common dashboard and permission needs",
|
||||
Icon: "users-alt",
|
||||
Url: s.cfg.AppSubURL + "/org/teams",
|
||||
})
|
||||
}
|
||||
|
||||
if enableServiceAccount(s, c) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Service accounts",
|
||||
Id: "serviceaccounts",
|
||||
SubTitle: "Use service accounts to run automated workloads in Grafana",
|
||||
Icon: "gf-service-account",
|
||||
Url: s.cfg.AppSubURL + "/org/serviceaccounts",
|
||||
})
|
||||
}
|
||||
|
||||
disabled, err := s.apiKeyService.IsDisabled(ctx, c.SignedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasAccess(ac.ApiKeyAccessEvaluator) && !disabled {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "API keys",
|
||||
Id: "apikeys",
|
||||
SubTitle: "Manage and create API keys that are used to interact with Grafana HTTP APIs",
|
||||
Icon: "key-skeleton-alt",
|
||||
Url: s.cfg.AppSubURL + "/org/apikeys",
|
||||
})
|
||||
}
|
||||
|
||||
generalNodeLinks := []*navtree.NavLink{}
|
||||
if hasAccess(ac.OrgPreferencesAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Default preferences",
|
||||
Id: "org-settings",
|
||||
SubTitle: "Manage preferences across an organization",
|
||||
@ -82,32 +31,18 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
Url: s.cfg.AppSubURL + "/org",
|
||||
})
|
||||
}
|
||||
|
||||
if authConfigUIAvailable && hasAccess(ssoutils.EvalAuthenticationSettings(s.cfg)) ||
|
||||
(hasAccess(ssoutils.OauthSettingsEvaluator(s.cfg)) && s.features.IsEnabled(ctx, featuremgmt.FlagSsoSettingsApi)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Authentication",
|
||||
Id: "authentication",
|
||||
SubTitle: "Manage your auth settings and configure single sign-on",
|
||||
Icon: "signin",
|
||||
Url: s.cfg.AppSubURL + "/admin/authentication",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Settings", SubTitle: "View the settings defined in your Grafana config", Id: "server-settings", Url: s.cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt",
|
||||
})
|
||||
}
|
||||
|
||||
if hasGlobalAccess(orgsAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Organizations", SubTitle: "Isolated instances of Grafana running on the same server", Id: "global-orgs", Url: s.cfg.AppSubURL + "/admin/orgs", Icon: "building",
|
||||
})
|
||||
}
|
||||
|
||||
if s.features.IsEnabled(ctx, featuremgmt.FlagFeatureToggleAdminPage) && hasAccess(ac.EvalPermission(ac.ActionFeatureManagementRead)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Feature Toggles",
|
||||
SubTitle: "View and edit feature toggles",
|
||||
Id: "feature-toggles",
|
||||
@ -115,9 +50,51 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
Icon: "toggle-on",
|
||||
})
|
||||
}
|
||||
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) && s.features.IsEnabled(ctx, featuremgmt.FlagStorage) {
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Storage",
|
||||
Id: "storage",
|
||||
SubTitle: "Manage file storage",
|
||||
Icon: "cube",
|
||||
Url: s.cfg.AppSubURL + "/admin/storage",
|
||||
})
|
||||
}
|
||||
if s.features.IsEnabled(ctx, featuremgmt.FlagOnPremToCloudMigrations) && c.SignedInUser.HasRole(org.RoleAdmin) {
|
||||
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
||||
Text: "Migrate to Grafana Cloud",
|
||||
Id: "migrate-to-cloud",
|
||||
SubTitle: "Copy configuration from your self-managed installation to a cloud stack",
|
||||
Url: s.cfg.AppSubURL + "/admin/migrate-to-cloud",
|
||||
})
|
||||
}
|
||||
|
||||
generalNode := &navtree.NavLink{
|
||||
Text: "General",
|
||||
SubTitle: "Manage default preferences and settings across Grafana",
|
||||
Id: navtree.NavIDCfgGeneral,
|
||||
Url: "/admin/general",
|
||||
Icon: "shield",
|
||||
Children: generalNodeLinks,
|
||||
}
|
||||
|
||||
if len(generalNode.Children) > 0 {
|
||||
configNodes = append(configNodes, generalNode)
|
||||
}
|
||||
|
||||
pluginsNodeLinks := []*navtree.NavLink{}
|
||||
// FIXME: If plugin admin is disabled or externally managed, server admins still need to access the page, this is why
|
||||
// while we don't have a permissions for listing plugins the legacy check has to stay as a default
|
||||
if pluginaccesscontrol.ReqCanAdminPlugins(s.cfg)(c) || hasAccess(pluginaccesscontrol.AdminAccessEvaluator) {
|
||||
pluginsNodeLinks = append(pluginsNodeLinks, &navtree.NavLink{
|
||||
Text: "Plugins",
|
||||
Id: "plugins",
|
||||
SubTitle: "Extend the Grafana experience with plugins",
|
||||
Icon: "plug",
|
||||
Url: s.cfg.AppSubURL + "/plugins",
|
||||
})
|
||||
}
|
||||
if s.features.IsEnabled(ctx, featuremgmt.FlagCorrelations) && hasAccess(correlations.ConfigurationPageAccess) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
pluginsNodeLinks = append(pluginsNodeLinks, &navtree.NavLink{
|
||||
Text: "Correlations",
|
||||
Icon: "gf-glue",
|
||||
SubTitle: "Add and configure correlations",
|
||||
@ -126,25 +103,80 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) && s.features.IsEnabled(ctx, featuremgmt.FlagStorage) {
|
||||
storage := &navtree.NavLink{
|
||||
Text: "Storage",
|
||||
Id: "storage",
|
||||
SubTitle: "Manage file storage",
|
||||
Icon: "cube",
|
||||
Url: s.cfg.AppSubURL + "/admin/storage",
|
||||
}
|
||||
configNodes = append(configNodes, storage)
|
||||
pluginsNode := &navtree.NavLink{
|
||||
Text: "Plugins and data",
|
||||
SubTitle: "Install plugins and define the relationships between data",
|
||||
Id: navtree.NavIDCfgPlugins,
|
||||
Url: "/admin/plugins",
|
||||
Icon: "shield",
|
||||
Children: pluginsNodeLinks,
|
||||
}
|
||||
|
||||
if s.features.IsEnabled(ctx, featuremgmt.FlagOnPremToCloudMigrations) && c.SignedInUser.HasRole(org.RoleAdmin) {
|
||||
migrateToCloud := &navtree.NavLink{
|
||||
Text: "Migrate to Grafana Cloud",
|
||||
Id: "migrate-to-cloud",
|
||||
SubTitle: "Copy configuration from your self-managed installation to a cloud stack",
|
||||
Url: s.cfg.AppSubURL + "/admin/migrate-to-cloud",
|
||||
}
|
||||
configNodes = append(configNodes, migrateToCloud)
|
||||
if len(pluginsNode.Children) > 0 {
|
||||
configNodes = append(configNodes, pluginsNode)
|
||||
}
|
||||
|
||||
accessNodeLinks := []*navtree.NavLink{}
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionOrgUsersRead), ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll))) {
|
||||
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
||||
Text: "Users", SubTitle: "Manage users in Grafana", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
|
||||
})
|
||||
}
|
||||
if hasAccess(ac.TeamsAccessEvaluator) {
|
||||
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
||||
Text: "Teams",
|
||||
Id: "teams",
|
||||
SubTitle: "Groups of users that have common dashboard and permission needs",
|
||||
Icon: "users-alt",
|
||||
Url: s.cfg.AppSubURL + "/org/teams",
|
||||
})
|
||||
}
|
||||
if enableServiceAccount(s, c) {
|
||||
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
||||
Text: "Service accounts",
|
||||
Id: "serviceaccounts",
|
||||
SubTitle: "Use service accounts to run automated workloads in Grafana",
|
||||
Icon: "gf-service-account",
|
||||
Url: s.cfg.AppSubURL + "/org/serviceaccounts",
|
||||
})
|
||||
}
|
||||
disabled, err := s.apiKeyService.IsDisabled(ctx, c.SignedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasAccess(ac.ApiKeyAccessEvaluator) && !disabled {
|
||||
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
||||
Text: "API keys",
|
||||
Id: "apikeys",
|
||||
SubTitle: "Manage and create API keys that are used to interact with Grafana HTTP APIs",
|
||||
Icon: "key-skeleton-alt",
|
||||
Url: s.cfg.AppSubURL + "/org/apikeys",
|
||||
})
|
||||
}
|
||||
|
||||
usersNode := &navtree.NavLink{
|
||||
Text: "Users and access",
|
||||
SubTitle: "Configure access for individual users, teams, and service accounts",
|
||||
Id: navtree.NavIDCfgAccess,
|
||||
Url: "/admin/access",
|
||||
Icon: "shield",
|
||||
Children: accessNodeLinks,
|
||||
}
|
||||
|
||||
if len(usersNode.Children) > 0 {
|
||||
configNodes = append(configNodes, usersNode)
|
||||
}
|
||||
|
||||
if authConfigUIAvailable && hasAccess(ssoutils.EvalAuthenticationSettings(s.cfg)) ||
|
||||
(hasAccess(ssoutils.OauthSettingsEvaluator(s.cfg)) && s.features.IsEnabled(ctx, featuremgmt.FlagSsoSettingsApi)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Authentication",
|
||||
Id: "authentication",
|
||||
SubTitle: "Manage your auth settings and configure single sign-on",
|
||||
Icon: "signin",
|
||||
IsSection: true,
|
||||
Url: s.cfg.AppSubURL + "/admin/authentication",
|
||||
})
|
||||
}
|
||||
|
||||
configNode := &navtree.NavLink{
|
||||
|
@ -295,7 +295,7 @@ func (s *ServiceImpl) readNavigationSettings() {
|
||||
"grafana-incident-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 2, Text: "Incidents"},
|
||||
"grafana-ml-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 3, Text: "Machine Learning"},
|
||||
"grafana-slo-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 4},
|
||||
"grafana-cloud-link-app": {SectionID: navtree.NavIDCfg},
|
||||
"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-attributions-app": {SectionID: navtree.NavIDCfg, Text: "Attributions"},
|
||||
@ -307,7 +307,7 @@ func (s *ServiceImpl) readNavigationSettings() {
|
||||
}
|
||||
|
||||
s.navigationAppPathConfig = map[string]NavigationAppConfig{
|
||||
"/a/grafana-auth-app": {SectionID: navtree.NavIDCfg, SortWeight: 7},
|
||||
"/a/grafana-auth-app": {SectionID: navtree.NavIDCfgAccess, SortWeight: 2},
|
||||
}
|
||||
|
||||
appSections := s.cfg.Raw.Section("navigation.app_sections")
|
||||
|
@ -151,7 +151,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Prefere
|
||||
|
||||
orgAdminNode, err := s.getAdminNode(c)
|
||||
|
||||
if orgAdminNode != nil {
|
||||
if orgAdminNode != nil && len(orgAdminNode.Children) > 0 {
|
||||
treeRoot.AddSection(orgAdminNode)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
|
Loading…
Reference in New Issue
Block a user