diff --git a/' b/'
deleted file mode 100644
index b179a2b8b5a..00000000000
--- a/'
+++ /dev/null
@@ -1,36 +0,0 @@
-define([
- 'angular',
- 'lodash'
-],
-function (angular) {
- 'use strict';
-
- angular
- .module('grafana.directives')
- .directive('annotationTooltip', function($sanitize, dashboardSrv) {
- return {
- scope: { tagColorFromName: "=" },
- link: function (scope, element) {
- var title = $sanitize(scope.annoation.title);
- var dashboard = dashboardSrv.getCurrent();
- var time = '' + dashboard.formatDate(scope.annotation.time) + '';
-
- var tooltip = '
'+ title + ' ' + time + '
' ;
-
- if (options.tags) {
- var tags = $sanitize(options.tags);
- tooltip += '
' + (tags || '') + '';
- }
-
- if (options.text) {
- var text = $sanitize(options.text);
- tooltip += text.replace(/\n/g, '
');
- }
-
- tooltip += "";
- }
- };
- });
-
-});
-
diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go
index b439bd67ac7..00ae26744d9 100644
--- a/pkg/api/dashboard.go
+++ b/pkg/api/dashboard.go
@@ -55,6 +55,7 @@ func GetDashboard(c *middleware.Context) {
Type: m.DashTypeDB,
CanStar: c.IsSignedIn,
CanSave: c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR,
+ CanEdit: c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR,
},
}
diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go
index d5e294cc983..3e1826f56fb 100644
--- a/pkg/api/dtos/models.go
+++ b/pkg/api/dtos/models.go
@@ -34,6 +34,7 @@ type DashboardMeta struct {
IsSnapshot bool `json:"isSnapshot,omitempty"`
Type string `json:"type,omitempty"`
CanSave bool `json:"canSave"`
+ CanEdit bool `json:"canEdit"`
CanStar bool `json:"canStar"`
Slug string `json:"slug"`
Expires time.Time `json:"expires"`
diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go
index ea154320608..4dd6ba06819 100644
--- a/pkg/api/frontendsettings.go
+++ b/pkg/api/frontendsettings.go
@@ -99,6 +99,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
"defaultDatasource": defaultDatasource,
"datasources": datasources,
"appSubUrl": setting.AppSubUrl,
+ "viewerRoleMode": setting.ViewerRoleMode,
"buildInfo": map[string]interface{}{
"version": setting.BuildVersion,
"commit": setting.BuildCommit,
diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go
index 77445dd6c4c..6768f9aabd9 100644
--- a/pkg/setting/setting.go
+++ b/pkg/setting/setting.go
@@ -79,6 +79,7 @@ var (
AllowUserOrgCreate bool
AutoAssignOrg bool
AutoAssignOrgRole string
+ ViewerRoleMode string
// Http auth
AdminUser string
@@ -383,6 +384,7 @@ func NewConfigContext(args *CommandLineArgs) {
AllowUserOrgCreate = users.Key("allow_org_create").MustBool(true)
AutoAssignOrg = users.Key("auto_assign_org").MustBool(true)
AutoAssignOrgRole = users.Key("auto_assign_org_role").In("Editor", []string{"Editor", "Admin", "Viewer"})
+ ViewerRoleMode = users.Key("viewer_role_mode").In("default", []string{"default", "strinct"})
// anonymous access
AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false)
diff --git a/public/app/components/panelmeta.js b/public/app/components/panelmeta.js
index 4ee4a9b9b55..013919c174a 100644
--- a/public/app/components/panelmeta.js
+++ b/public/app/components/panelmeta.js
@@ -16,8 +16,8 @@ function () {
this.addMenuItem('view', 'icon-eye-open', 'toggleFullscreen(false); dismiss();');
}
- this.addMenuItem('edit', 'icon-cog', 'editPanel(); dismiss();');
- this.addMenuItem('duplicate', 'icon-copy', 'duplicatePanel()');
+ this.addMenuItem('edit', 'icon-cog', 'editPanel(); dismiss();', 'Editor');
+ this.addMenuItem('duplicate', 'icon-copy', 'duplicatePanel()', 'Editor');
this.addMenuItem('share', 'icon-share', 'sharePanel(); dismiss();');
this.addEditorTab('General', 'app/partials/panelgeneral.html');
@@ -29,12 +29,12 @@ function () {
this.addExtendedMenuItem('Panel JSON', '', 'editPanelJson(); dismiss();');
}
- PanelMeta.prototype.addMenuItem = function(text, icon, click) {
- this.menu.push({text: text, icon: icon, click: click});
+ PanelMeta.prototype.addMenuItem = function(text, icon, click, role) {
+ this.menu.push({text: text, icon: icon, click: click, role: role});
};
- PanelMeta.prototype.addExtendedMenuItem = function(text, icon, click) {
- this.extendedMenu.push({text: text, icon: icon, click: click});
+ PanelMeta.prototype.addExtendedMenuItem = function(text, icon, click, role) {
+ this.extendedMenu.push({text: text, icon: icon, click: click, role: role});
};
PanelMeta.prototype.addEditorTab = function(title, src) {
diff --git a/public/app/features/panel/panelMenu.js b/public/app/features/panel/panelMenu.js
index 27152ef2b94..03ee78491ab 100644
--- a/public/app/features/panel/panelMenu.js
+++ b/public/app/features/panel/panelMenu.js
@@ -8,7 +8,7 @@ function (angular, $, _) {
angular
.module('grafana.directives')
- .directive('panelMenu', function($compile, linkSrv) {
+ .directive('panelMenu', function($compile, linkSrv, contextSrv) {
var linkTemplate =
'
' +
'{{panel.title | interpolateTemplateVars:this}}' +
@@ -18,18 +18,26 @@ function (angular, $, _) {
function createMenuTemplate($scope) {
var template = '