diff --git a/pkg/api/app_plugin.go b/pkg/api/app_plugin.go index 6ef078961d7..c39acb4dba4 100644 --- a/pkg/api/app_plugin.go +++ b/pkg/api/app_plugin.go @@ -18,10 +18,11 @@ func GetAppPlugins(c *middleware.Context) Response { installedAppsMap := make(map[string]*dtos.AppPlugin) for t, a := range plugins.Apps { installedAppsMap[t] = &dtos.AppPlugin{ - Type: a.Type, - Enabled: a.Enabled, - Module: a.Module, - JsonData: make(map[string]interface{}), + Type: a.Type, + Enabled: a.Enabled, + PinNavLinks: a.PinNavLinks, + Module: a.Module, + JsonData: make(map[string]interface{}), } } @@ -31,10 +32,11 @@ func GetAppPlugins(c *middleware.Context) Response { for _, b := range query.Result { if def, ok := installedAppsMap[b.Type]; ok { result = append(result, &dtos.AppPlugin{ - Type: b.Type, - Enabled: b.Enabled, - Module: def.Module, - JsonData: b.JsonData, + Type: b.Type, + Enabled: b.Enabled, + PinNavLinks: b.PinNavLinks, + Module: def.Module, + JsonData: b.JsonData, }) seenApps[b.Type] = true } diff --git a/pkg/api/dtos/app_plugin.go b/pkg/api/dtos/app_plugin.go index 1da1b8acd4e..d7eaf8f4140 100644 --- a/pkg/api/dtos/app_plugin.go +++ b/pkg/api/dtos/app_plugin.go @@ -1,8 +1,9 @@ package dtos type AppPlugin struct { - Type string `json:"type"` - Enabled bool `json:"enabled"` - Module string `json:"module"` - JsonData map[string]interface{} `json:"jsonData"` + Type string `json:"type"` + Enabled bool `json:"enabled"` + PinNavLinks bool `json:"pin_nav_links"` + Module string `json:"module"` + JsonData map[string]interface{} `json:"jsonData"` } diff --git a/pkg/api/index.go b/pkg/api/index.go index 8caa709b0be..1346a45a7ac 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -69,28 +69,31 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { for _, css := range plugin.Css { data.PluginCss = append(data.PluginCss, &dtos.PluginCss{Light: css.Light, Dark: css.Dark}) } - for _, item := range plugin.MainNavLinks { - // only show menu items for the specified roles. - var validRoles []m.RoleType - if string(item.ReqRole) == "" || item.ReqRole == m.ROLE_VIEWER { - validRoles = []m.RoleType{m.ROLE_ADMIN, m.ROLE_EDITOR, m.ROLE_VIEWER} - } else if item.ReqRole == m.ROLE_EDITOR { - validRoles = []m.RoleType{m.ROLE_ADMIN, m.ROLE_EDITOR} - } else if item.ReqRole == m.ROLE_ADMIN { - validRoles = []m.RoleType{m.ROLE_ADMIN} - } - ok := true - if len(validRoles) > 0 { - ok = false - for _, role := range validRoles { - if role == c.OrgRole { - ok = true - break + + if plugin.PinNavLinks { + for _, item := range plugin.MainNavLinks { + // only show menu items for the specified roles. + var validRoles []m.RoleType + if string(item.ReqRole) == "" || item.ReqRole == m.ROLE_VIEWER { + validRoles = []m.RoleType{m.ROLE_ADMIN, m.ROLE_EDITOR, m.ROLE_VIEWER} + } else if item.ReqRole == m.ROLE_EDITOR { + validRoles = []m.RoleType{m.ROLE_ADMIN, m.ROLE_EDITOR} + } else if item.ReqRole == m.ROLE_ADMIN { + validRoles = []m.RoleType{m.ROLE_ADMIN} + } + ok := true + if len(validRoles) > 0 { + ok = false + for _, role := range validRoles { + if role == c.OrgRole { + ok = true + break + } } } - } - if ok { - data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: item.Text, Href: item.Href, Icon: item.Icon}) + if ok { + data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: item.Text, Href: item.Href, Icon: item.Icon}) + } } } } diff --git a/pkg/models/app_plugin.go b/pkg/models/app_plugin.go index 605e69f623c..fc155035f84 100644 --- a/pkg/models/app_plugin.go +++ b/pkg/models/app_plugin.go @@ -3,11 +3,12 @@ package models import "time" type AppPlugin struct { - Id int64 - Type string - OrgId int64 - Enabled bool - JsonData map[string]interface{} + Id int64 + Type string + OrgId int64 + Enabled bool + PinNavLinks bool + JsonData map[string]interface{} Created time.Time Updated time.Time @@ -18,9 +19,10 @@ type AppPlugin struct { // Also acts as api DTO type UpdateAppPluginCmd struct { - Type string `json:"type" binding:"Required"` - Enabled bool `json:"enabled"` - JsonData map[string]interface{} `json:"jsonData"` + Type string `json:"type" binding:"Required"` + Enabled bool `json:"enabled"` + PinNavLinks bool `json:"pin_nav_links"` + JsonData map[string]interface{} `json:"jsonData"` Id int64 `json:"-"` OrgId int64 `json:"-"` diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index e0eecd35bfe..1e040a37748 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -71,6 +71,7 @@ type AppPlugin struct { Js []*AppPluginJs `json:"js"` Css []*AppPluginCss `json:"css"` MainNavLinks []*AppPluginNavLink `json:"mainNavLinks"` + PinNavLinks bool `json:"pinNavLinks"` StaticRootConfig *StaticRootConfig `json:"staticRoot"` } diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 5363c13c129..01feace9d44 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -203,17 +203,18 @@ func GetEnabledPlugins(orgApps []*models.AppPlugin) EnabledPlugins { seenPanels := make(map[string]bool) seenApi := make(map[string]bool) - for appType, app := range Apps { - // start with enabled set to the default state listed in the json config. - enabled := app.Enabled + for appType, installedApp := range Apps { + var app AppPlugin + app = *installedApp // check if the app is stored in the DB for this org and if so, use the - // enabled state stored there. + // state stored there. if b, ok := orgAppsMap[appType]; ok { - enabled = b.Enabled + app.Enabled = b.Enabled + app.PinNavLinks = b.PinNavLinks } - if enabled { + if app.Enabled { for _, d := range app.DatasourcePlugins { if ds, ok := DataSources[d]; ok { enabledPlugins.DataSourcePlugins[d] = ds @@ -235,7 +236,7 @@ func GetEnabledPlugins(orgApps []*models.AppPlugin) EnabledPlugins { } } } - enabledPlugins.AppPlugins = append(enabledPlugins.AppPlugins, app) + enabledPlugins.AppPlugins = append(enabledPlugins.AppPlugins, &app) } } diff --git a/pkg/services/sqlstore/app_plugin.go b/pkg/services/sqlstore/app_plugin.go index fca6031cac5..63fdcac0d8c 100644 --- a/pkg/services/sqlstore/app_plugin.go +++ b/pkg/services/sqlstore/app_plugin.go @@ -25,20 +25,23 @@ func UpdateAppPlugin(cmd *m.UpdateAppPluginCmd) error { exists, err := sess.Where("org_id=? and type=?", cmd.OrgId, cmd.Type).Get(&app) sess.UseBool("enabled") + sess.UseBool("pin_nav_links") if !exists { app = m.AppPlugin{ - Type: cmd.Type, - OrgId: cmd.OrgId, - Enabled: cmd.Enabled, - JsonData: cmd.JsonData, - Created: time.Now(), - Updated: time.Now(), + Type: cmd.Type, + OrgId: cmd.OrgId, + Enabled: cmd.Enabled, + PinNavLinks: cmd.PinNavLinks, + JsonData: cmd.JsonData, + Created: time.Now(), + Updated: time.Now(), } _, err = sess.Insert(&app) return err } else { app.Enabled = cmd.Enabled app.JsonData = cmd.JsonData + app.PinNavLinks = cmd.PinNavLinks _, err = sess.Id(app.Id).Update(&app) return err } diff --git a/pkg/services/sqlstore/migrations/app_plugin.go b/pkg/services/sqlstore/migrations/app_plugin.go index 3fbadcd2a11..a0208f0eac5 100644 --- a/pkg/services/sqlstore/migrations/app_plugin.go +++ b/pkg/services/sqlstore/migrations/app_plugin.go @@ -11,6 +11,7 @@ func addAppPluginMigration(mg *Migrator) { {Name: "org_id", Type: DB_BigInt, Nullable: true}, {Name: "type", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "enabled", Type: DB_Bool, Nullable: false}, + {Name: "pin_nav_links", Type: DB_Bool, Nullable: false}, {Name: "json_data", Type: DB_Text, Nullable: true}, {Name: "created", Type: DB_DateTime, Nullable: false}, {Name: "updated", Type: DB_DateTime, Nullable: false}, diff --git a/public/app/features/org/appEditCtrl.js b/public/app/features/org/appEditCtrl.js index 8d4bb80dea9..63f638a72fd 100644 --- a/public/app/features/org/appEditCtrl.js +++ b/public/app/features/org/appEditCtrl.js @@ -26,7 +26,7 @@ function (angular, _, config) { $scope._update = function() { appSrv.update($scope.current).then(function() { - window.location.href = config.appSubUrl + "plugins"; + window.location.href = config.appSubUrl + "org/apps"; }); }; diff --git a/public/app/features/org/partials/appEdit.html b/public/app/features/org/partials/appEdit.html index 1af3af51182..1926751f96a 100644 --- a/public/app/features/org/partials/appEdit.html +++ b/public/app/features/org/partials/appEdit.html @@ -26,6 +26,11 @@ +