Chore: Move ml app to root (#105677)
* move ml app to root * update translation * translate subtitle as well * fix casing
This commit is contained in:
@@ -317,7 +317,7 @@ func (s *ServiceImpl) readNavigationSettings() {
|
|||||||
"grafana-irm-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 3, Text: "IRM"},
|
"grafana-irm-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 3, Text: "IRM"},
|
||||||
"grafana-oncall-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 4, Text: "OnCall"},
|
"grafana-oncall-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 4, Text: "OnCall"},
|
||||||
"grafana-incident-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 5, Text: "Incident"},
|
"grafana-incident-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 5, Text: "Incident"},
|
||||||
"grafana-ml-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 6, Text: "Machine Learning"},
|
"grafana-ml-app": {SectionID: navtree.NavIDRoot, SortWeight: navtree.WeightAIAndML, Text: "AI & machine learning", SubTitle: "Explore AI and machine learning features", Icon: "gf-ml-alt"},
|
||||||
"grafana-slo-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 7},
|
"grafana-slo-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 7},
|
||||||
"grafana-cloud-link-app": {SectionID: navtree.NavIDCfgPlugins, SortWeight: 3},
|
"grafana-cloud-link-app": {SectionID: navtree.NavIDCfgPlugins, SortWeight: 3},
|
||||||
"grafana-costmanagementui-app": {SectionID: navtree.NavIDCfg, Text: "Cost management"},
|
"grafana-costmanagementui-app": {SectionID: navtree.NavIDCfg, Text: "Cost management"},
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
|
||||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey"
|
"github.com/grafana/grafana/pkg/services/apikey"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
@@ -18,7 +17,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
"github.com/grafana/grafana/pkg/services/licensing"
|
||||||
"github.com/grafana/grafana/pkg/services/navtree"
|
"github.com/grafana/grafana/pkg/services/navtree"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
pc "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||||
@@ -163,10 +161,6 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Prefere
|
|||||||
if alertingSection := s.buildAlertNavLinks(c); alertingSection != nil {
|
if alertingSection := s.buildAlertNavLinks(c); alertingSection != nil {
|
||||||
treeRoot.AddSection(alertingSection)
|
treeRoot.AddSection(alertingSection)
|
||||||
}
|
}
|
||||||
|
|
||||||
if aimlSection := s.buildAIMLNavLinks(c); aimlSection != nil {
|
|
||||||
treeRoot.AddSection(aimlSection)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if connectionsSection := s.buildDataConnectionsNavLink(c); connectionsSection != nil {
|
if connectionsSection := s.buildDataConnectionsNavLink(c); connectionsSection != nil {
|
||||||
@@ -422,80 +416,6 @@ func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext) []*navt
|
|||||||
return dashboardChildNavs
|
return dashboardChildNavs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) buildAIMLNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
|
||||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
|
||||||
|
|
||||||
pss, err := s.pluginSettings.GetPluginSettings(c.Req.Context(), &pluginsettings.GetArgs{OrgID: c.GetOrgID()})
|
|
||||||
if err != nil {
|
|
||||||
s.log.Error("Failed to get plugin settings", "error", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if ML plugin is enabled
|
|
||||||
isMLPluginEnabled := false
|
|
||||||
for _, plugin := range s.pluginStore.Plugins(c.Req.Context(), plugins.TypeApp) {
|
|
||||||
if plugin.ID == "grafana-ml-app" {
|
|
||||||
// Check if plugin is enabled in settings
|
|
||||||
if plugin.AutoEnabled {
|
|
||||||
isMLPluginEnabled = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for _, ps := range pss {
|
|
||||||
if ps.PluginID == plugin.ID && ps.Enabled {
|
|
||||||
isMLPluginEnabled = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return nil if plugin is not enabled
|
|
||||||
if !isMLPluginEnabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if user has access to the plugin
|
|
||||||
if !hasAccess(ac.EvalPermission(pc.ActionAppAccess, "grafana-ml-app")) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var aimlChildNavs []*navtree.NavLink
|
|
||||||
|
|
||||||
aimlChildNavs = append(aimlChildNavs, &navtree.NavLink{
|
|
||||||
Text: "Metric forecasting",
|
|
||||||
SubTitle: "Create a forecast",
|
|
||||||
Id: "ai-ml-metric-forecast",
|
|
||||||
Url: s.cfg.AppSubURL + "/a/grafana-ml-app/metric-forecast",
|
|
||||||
})
|
|
||||||
|
|
||||||
aimlChildNavs = append(aimlChildNavs, &navtree.NavLink{
|
|
||||||
Text: "Outlier detection",
|
|
||||||
SubTitle: "Create an outlier detector",
|
|
||||||
Id: "ai-ml-outlier-detection",
|
|
||||||
Url: s.cfg.AppSubURL + "/a/grafana-ml-app/outlier-detector",
|
|
||||||
})
|
|
||||||
|
|
||||||
aimlChildNavs = append(aimlChildNavs, &navtree.NavLink{
|
|
||||||
Text: "Sift investigations",
|
|
||||||
SubTitle: "View and create investigations",
|
|
||||||
Id: "ai-ml-sift-investigations",
|
|
||||||
Url: s.cfg.AppSubURL + "/a/grafana-ml-app/investigations",
|
|
||||||
})
|
|
||||||
|
|
||||||
var aimlNav = navtree.NavLink{
|
|
||||||
Text: "AI & Machine Learning",
|
|
||||||
SubTitle: "Explore AI and machine learning features",
|
|
||||||
Id: "ai-ml-home",
|
|
||||||
Icon: "gf-ml-alt",
|
|
||||||
Children: aimlChildNavs,
|
|
||||||
SortWeight: navtree.WeightAIAndML,
|
|
||||||
Url: s.cfg.AppSubURL + "/a/grafana-ml-app/home",
|
|
||||||
}
|
|
||||||
|
|
||||||
return &aimlNav
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
||||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||||
var alertChildNavs []*navtree.NavLink
|
var alertChildNavs []*navtree.NavLink
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export function getNavTitle(navId: string | undefined) {
|
|||||||
case 'plugin-page-grafana-incident-app':
|
case 'plugin-page-grafana-incident-app':
|
||||||
return t('nav.incidents.title', 'Incident');
|
return t('nav.incidents.title', 'Incident');
|
||||||
case 'plugin-page-grafana-ml-app':
|
case 'plugin-page-grafana-ml-app':
|
||||||
return t('nav.machine-learning.title', 'Machine learning');
|
return t('nav.machine-learning.title', 'AI & machine learning');
|
||||||
case 'plugin-page-grafana-slo-app':
|
case 'plugin-page-grafana-slo-app':
|
||||||
return t('nav.slo.title', 'SLO');
|
return t('nav.slo.title', 'SLO');
|
||||||
case 'plugin-page-k6-app':
|
case 'plugin-page-k6-app':
|
||||||
@@ -319,6 +319,8 @@ export function getNavSubTitle(navId: string | undefined) {
|
|||||||
'nav.private-data-source-connections.subtitle',
|
'nav.private-data-source-connections.subtitle',
|
||||||
'Query data that lives within a secured network without opening the network to inbound traffic from Grafana Cloud. Learn more in our docs.'
|
'Query data that lives within a secured network without opening the network to inbound traffic from Grafana Cloud. Learn more in our docs.'
|
||||||
);
|
);
|
||||||
|
case 'plugin-page-grafana-ml-app':
|
||||||
|
return t('nav.machine-learning.subtitle', 'Explore AI and machine learning features');
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6776,7 +6776,8 @@
|
|||||||
"title": "Library panels"
|
"title": "Library panels"
|
||||||
},
|
},
|
||||||
"machine-learning": {
|
"machine-learning": {
|
||||||
"title": "Machine learning"
|
"subtitle": "Explore AI and machine learning features",
|
||||||
|
"title": "AI & machine learning"
|
||||||
},
|
},
|
||||||
"manage-folder": {
|
"manage-folder": {
|
||||||
"subtitle": "Manage folder dashboards and permissions"
|
"subtitle": "Manage folder dashboards and permissions"
|
||||||
|
|||||||
Reference in New Issue
Block a user