mirror of
https://github.com/grafana/grafana.git
synced 2025-07-28 23:25:58 +08:00
Navigation: Moving Machine-Learning out of IRM and into the top-level of the Navigation (#103822)
* adding ml items to main navigation if plugin is installed * undoing testing change * updating based on feedback and fixing role to be specific to access to ml plugin * cleanup unneeded constants * cleanup diff * updateing GetOrgID call * adding greyscale ml logo and using that for consistency * use currentColor --------- Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
This commit is contained in:
@ -139,6 +139,7 @@ export const availableIconsIndex = {
|
|||||||
'gf-layout-simple': true,
|
'gf-layout-simple': true,
|
||||||
'gf-logs': true,
|
'gf-logs': true,
|
||||||
'gf-ml': true,
|
'gf-ml': true,
|
||||||
|
'gf-ml-alt': true,
|
||||||
'gf-movepane-left': true,
|
'gf-movepane-left': true,
|
||||||
'gf-movepane-right': true,
|
'gf-movepane-right': true,
|
||||||
'gf-portrait': true,
|
'gf-portrait': true,
|
||||||
|
@ -19,6 +19,7 @@ const (
|
|||||||
WeightDrilldown
|
WeightDrilldown
|
||||||
WeightAlerting
|
WeightAlerting
|
||||||
WeightAlertsAndIncidents
|
WeightAlertsAndIncidents
|
||||||
|
WeightAIAndML
|
||||||
WeightTestingAndSynthetics
|
WeightTestingAndSynthetics
|
||||||
WeightMonitoring
|
WeightMonitoring
|
||||||
WeightCloudServiceProviders
|
WeightCloudServiceProviders
|
||||||
|
@ -7,6 +7,7 @@ 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"
|
||||||
@ -17,6 +18,7 @@ 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"
|
||||||
@ -161,6 +163,10 @@ 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 {
|
||||||
@ -416,6 +422,80 @@ 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
|
||||||
|
1
public/img/icons/custom/gf-ml-alt.svg
Normal file
1
public/img/icons/custom/gf-ml-alt.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 135.46 118.24"><defs><style>.cls-1{fill: currentColor;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M135.37,64.86l-5.6-26.43a4.05,4.05,0,0,0-.9-1.82L113.19,18.24a4.11,4.11,0,0,0-1-.87L83.71.57A4.18,4.18,0,0,0,81.62,0H58.54a4.19,4.19,0,0,0-1,.12L26,8a4.16,4.16,0,0,0-2,1.17L1.12,33.32A4.1,4.1,0,0,0,0,36.14v24.2A4.1,4.1,0,0,0,2.46,64.1l22.85,10L39,95.07a4.13,4.13,0,0,0,3.45,1.86H68.66L81.59,116.4A4.09,4.09,0,0,0,85,118.24h0l6,0a4.11,4.11,0,0,0,4.09-4.11V90.21H117a4.09,4.09,0,0,0,3.36-1.75l14.34-20.38A4.1,4.1,0,0,0,135.37,64.86ZM86.12,34.1a3.29,3.29,0,0,0-.67.77l0,.05H59.83L57,30.53A3.38,3.38,0,0,0,54.24,29a3.45,3.45,0,0,0-2.86,1.45l-3.15,4.51H10.92L21.64,23.58H98.3Zm-3,4.52L72.77,55.23,62.19,38.62ZM37.75,50H8.22V38.62H45.66ZM29.12,15.65,59.05,8.22H80.49l19.74,11.66H25.13Zm-20.9,38h27L26.73,65.78,8.22,57.65ZM114.87,82h-4V46.21a2.3,2.3,0,0,0-2.3-2.3h-1.39a2.3,2.3,0,0,0-2.3,2.3V82h-12V63.92a2.31,2.31,0,0,0-2.3-2.31H89.21a2.31,2.31,0,0,0-2.3,2.31v45.64L74.48,90.84V78.36a2.3,2.3,0,0,0-2.3-2.3H70.79a2.3,2.3,0,0,0-2.3,2.3V88.71H56.23V58.54a2.32,2.32,0,0,0-2.31-2.31H52.54a2.32,2.32,0,0,0-2.31,2.31V88.71H44.64l-12.39-19L53.93,38.62h.21l15.8,24.81A3.32,3.32,0,0,0,72.82,65a3.39,3.39,0,0,0,2.87-1.6L91,38.9l16.73-14.45,14.26,16.7,5,23.66Z"/></g></g></svg>
|
After Width: | Height: | Size: 1.4 KiB |
Reference in New Issue
Block a user