Просмотр исходного кода

Began work on dashboard: editable flag, that actually stops users from changing anything, #1834

Torkel Ödegaard 10 лет назад
Родитель
Сommit
236c4e65f8

+ 3 - 3
pkg/api/dtos/models.go

@@ -28,9 +28,9 @@ type CurrentUser struct {
 }
 
 type DashboardMeta struct {
-	IsStarred  bool      `json:"isStarred"`
-	IsHome     bool      `json:"isHome"`
-	IsSnapshot bool      `json:"isSnapshot"`
+	IsStarred  bool      `json:"isStarred,omitempty"`
+	IsHome     bool      `json:"isHome,omitempty"`
+	IsSnapshot bool      `json:"isSnapshot,omitempty"`
 	Slug       string    `json:"slug"`
 	Expires    time.Time `json:"expires"`
 	Created    time.Time `json:"created"`

+ 8 - 12
public/app/features/dashboard/dashboardSrv.js

@@ -52,24 +52,20 @@ function (angular, $, kbn, _, moment) {
 
     p._initMeta = function(meta) {
       meta = meta || {};
-      meta.canShare = true;
-      meta.canSave = true;
-      meta.canEdit = true;
-      meta.canStar = true;
 
-      if (contextSrv.hasRole('Viewer')) {
-        meta.canSave = false;
-      }
+      meta.canShare = meta.canShare === false ? false : true;
+      meta.canSave = meta.canSave === false ? false : true;
+      meta.canEdit = meta.canEdit === false ? false : true;
+      meta.canStar = meta.canStar === false ? false : true;
+      meta.canDelete = meta.canDelete === false ? false : true;
 
-      if (meta.isSnapshot) {
+      if (contextSrv.hasRole('Viewer')) {
         meta.canSave = false;
       }
 
-      if (meta.isHome) {
-        meta.canShare = false;
-        meta.canStar = false;
-        meta.canSave = false;
+      if (!this.editable) {
         meta.canEdit = false;
+        meta.canDelete = false;
       }
 
       this.meta = meta;

+ 6 - 6
public/app/features/dashboard/partials/dashboardTopNav.html

@@ -27,19 +27,19 @@
 				<li ng-show="dashboardMeta.canShare">
 					<a class="pointer" ng-click="shareDashboard()" bs-tooltip="'Share dashboard'" data-placement="bottom"><i class="fa fa-share-square-o"></i></a>
 				</li>
-				<li ng-show="dashboardMeta.canSave">
+				<li ng-show="dashboardMeta.canEdit">
 					<a ng-click="saveDashboard()" bs-tooltip="'Save dashboard'" data-placement="bottom"><i class="fa fa-save"></i></a>
 				</li>
-				<li class="dropdown" ng-if="dashboardMeta.canEdit">
+				<li class="dropdown">
 					<a class="pointer" data-toggle="dropdown"><i class="fa fa-cog"></i></a>
 					<ul class="dropdown-menu">
-						<li><a class="pointer" ng-click="openEditView('settings');">Settings</a></li>
-						<li><a class="pointer" ng-click="openEditView('annotations');">Annotations</a></li>
-						<li><a class="pointer" ng-click="openEditView('templating');">Templating</a></li>
+						<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('settings');">Settings</a></li>
+						<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('annotations');">Annotations</a></li>
+						<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('templating');">Templating</a></li>
 						<li><a class="pointer" ng-click="exportDashboard();">Export</a></li>
 						<li><a class="pointer" ng-click="editJson();">View JSON</a></li>
 						<li ng-if="dashboardMeta.canSave"><a class="pointer" ng-click="saveDashboardAs();">Save As...</a></li>
-						<li ng-if="dashboardMeta.canSave"><a class="pointer" ng-click="deleteDashboard();">Delete dashboard</a></li>
+						<li ng-if="dashboardMeta.canDelete"><a class="pointer" ng-click="deleteDashboard();">Delete dashboard</a></li>
 					</ul>
 				</li>
 			</ul>

+ 100 - 45
public/app/partials/dasheditor.html

@@ -17,63 +17,118 @@
 
 </div>
 
-<div class="gf-box-body">
-
-		<div ng-if="editor.index == 0">
-			<div class="editor-row">
-				<div class="section">
-					<div class="editor-option">
-						<label class="small">Title</label><input type="text" class="input-large" ng-model='dashboard.title'></input>
-					</div>
-					<div class="editor-option">
-						<label class="small">Time correction</label>
-						<select ng-model="dashboard.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
-					</div>
-					<editor-opt-bool text="Hide controls (CTRL+H)" model="dashboard.hideControls"></editor-opt-bool>
-          <editor-opt-bool text="Shared Crosshair (CTRL+O)" model="dashboard.sharedCrosshair"></editor-opt-bool>
+<div class="gf-box-body" style="padding-bottom: 50px;">
+	<div ng-if="editor.index == 0">
+		<div class="editor-row">
+			<div class="section">
+				<h5>Dashboard info</h5>
+				<div class="tight-form">
+					<ul class="tight-form-list">
+						<li class="tight-form-item" style="width: 90px">
+							Title
+						</li>
+						<li>
+							<input type="text" class="input-xlarge tight-form-input" ng-model='dashboard.title'></input>
+						</li>
+						<li class="tight-form-item">
+							Tags
+							<tip>Press enter to a add tag</tip>
+						</li>
+						<li>
+							<bootstrap-tagsinput ng-model="dashboard.tags" tagclass="label label-tag" placeholder="add tags">
+							</bootstrap-tagsinput>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
 				</div>
-			</div>
-			<div class="editor-row">
-				<div class="section">
-					<div class="editor-option">
-						<label class="small">Tags</label>
-						<bootstrap-tagsinput ng-model="dashboard.tags" tagclass="label label-tag" placeholder="add tags">
-						</bootstrap-tagsinput>
-						<tip>Press enter to a add tag</tip>
-					</div>
+				<div class="tight-form">
+					<ul class="tight-form-list">
+						<li class="tight-form-item" style="width: 90px">
+							Timezone
+						</li>
+						<li>
+							<select ng-model="dashboard.timezone" class='input-small tight-form-input' ng-options="f for f in ['browser','utc']"></select>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
 				</div>
+
 			</div>
-		</div>
 
-		<div ng-if="editor.index == 1">
-			<div class="editor-row">
-				<div class="span6">
-					<table class="grafana-options-table">
-						<tr ng-repeat="row in dashboard.rows">
-							<td style="width: 97%">
-								{{row.title}}
-							</td>
-							<td><i ng-click="_.move(dashboard.rows,$index,$index-1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i></td>
-							<td><i ng-click="_.move(dashboard.rows,$index,$index+1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i></td>
-							<td>
-								<a ng-click="dashboard.rows = _.without(dashboard.rows,row)" class="btn btn-danger btn-small">
-									<i class="fa fa-remove"></i>
-								</a>
-							</td>
-						</tr>
-					</table>
+			<div class="section">
+				<h5>Toggles</h5>
+				<div class="tight-form">
+					<ul class="tight-form-list">
+						<li class="tight-form-item" style="width: 181px">
+							<label class="checkbox-label" for="dashboard.editable">Editable</label>
+						</li>
+						<li>
+							<li class="tight-form-item last">
+								<input class="cr1" id="dashboard.editable" type="checkbox" ng-model="dashboard.editable" ng-checked="dashboard.editable">
+								<label for="dashboard.editable" class="cr1"></label>
+							</li>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
+				</div>
+				<div class="tight-form">
+					<ul class="tight-form-list">
+						<li class="tight-form-item" style="width: 181px">
+							<label class="checkbox-label" for="dashboard.hideControls">Hide Controls (CTRL+H)</label>
+						</li>
+						<li class="tight-form-item last">
+							<input class="cr1" id="dashboard.hideControls" type="checkbox" ng-model="dashboard.hideControls" ng-checked="dashboard.hideControls">
+							<label for="dashboard.hideControls" class="cr1"></label>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
+				</div>
+				<div class="tight-form">
+					<ul class="tight-form-list">
+						<li class="tight-form-item" style="width: 181px">
+							<label class="checkbox-label" for="dashboard.sharedCrosshair">Shared Crosshair (CTRL+H)</label>
+						</li>
+						<li class="tight-form-item last">
+							<input class="cr1" id="dashboard.sharedCrosshair" type="checkbox" ng-model="dashboard.sharedCrosshair" ng-checked="dashboard.sharedCrosshair">
+							<label for="dashboard.sharedCrosshair" class="cr1"></label>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
 				</div>
 			</div>
 		</div>
+	</div>
 
-		<div ng-repeat="pulldown in dashboard.nav" ng-controller="SubmenuCtrl" ng-show="editor.index == 2+$index">
-			<ng-include ng-show="pulldown.enable" src="pulldownEditorPath(pulldown.type)"></ng-include>
-			<button ng-hide="pulldown.enable" class="btn" ng-click="pulldown.enable = true">Enable the {{pulldown.type}}</button>
+	<div ng-if="editor.index == 1">
+		<div class="editor-row">
+			<div class="span6">
+				<table class="grafana-options-table">
+					<tr ng-repeat="row in dashboard.rows">
+						<td style="width: 97%">
+							{{row.title}}
+						</td>
+						<td><i ng-click="_.move(dashboard.rows,$index,$index-1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i></td>
+						<td><i ng-click="_.move(dashboard.rows,$index,$index+1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i></td>
+						<td>
+							<a ng-click="dashboard.rows = _.without(dashboard.rows,row)" class="btn btn-danger btn-small">
+								<i class="fa fa-remove"></i>
+							</a>
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="clearfix"></div>
 		</div>
+	</div>
 
+	<div ng-repeat="pulldown in dashboard.nav" ng-controller="SubmenuCtrl" ng-show="editor.index == 2+$index">
+		<ng-include ng-show="pulldown.enable" src="pulldownEditorPath(pulldown.type)"></ng-include>
+		<button ng-hide="pulldown.enable" class="btn" ng-click="pulldown.enable = true">Enable the {{pulldown.type}}</button>
 	</div>
 
-	<div class="clearfix"></div>
+</div>
+
+<div class="clearfix"></div>
 </div>
 
 <div class="gf-box-footer">

+ 26 - 15
public/app/routes/dashLoadControllers.js

@@ -18,6 +18,8 @@ function (angular, _, kbn, moment, $) {
 
     if (!$routeParams.slug) {
       backendSrv.get('/api/dashboards/home').then(function(result) {
+        var meta = result.meta;
+        meta.canSave = meta.canShare = meta.canEdit = meta.canStar = false;
         $scope.initDashboard(result, $scope);
       },function() {
         dashboardLoadFailed('Not found');
@@ -38,7 +40,16 @@ function (angular, _, kbn, moment, $) {
     backendSrv.get('/api/snapshots/' + $routeParams.key).then(function(result) {
       $scope.initDashboard(result, $scope);
     }, function() {
-      $scope.initDashboard({meta: {isSnapshot: true}, model: {title: 'Snapshot not found'}}, $scope);
+      $scope.initDashboard({
+        meta: {
+          isSnapshot: true,
+          canSave: false,
+          canEdit: false,
+        },
+        model: {
+          title: 'Snapshot not found'
+        }
+      }, $scope);
     });
   });
 
@@ -56,7 +67,7 @@ function (angular, _, kbn, moment, $) {
       meta: {},
       model: {
         title: "New dashboard",
-      rows: [{ height: '250px', panels:[] }]
+        rows: [{ height: '250px', panels:[] }]
       },
     }, $scope);
   });
@@ -66,10 +77,10 @@ function (angular, _, kbn, moment, $) {
     var file_load = function(file) {
       return $http({
         url: "public/dashboards/"+file.replace(/\.(?!json)/,"/")+'?' + new Date().getTime(),
-             method: "GET",
-             transformResponse: function(response) {
-               return angular.fromJson(response);
-             }
+        method: "GET",
+        transformResponse: function(response) {
+          return angular.fromJson(response);
+        }
       }).then(function(result) {
         if(!result) {
           return false;
@@ -92,8 +103,8 @@ function (angular, _, kbn, moment, $) {
     var execute_script = function(result) {
       var services = {
         dashboardSrv: dashboardSrv,
-    datasourceSrv: datasourceSrv,
-    $q: $q,
+        datasourceSrv: datasourceSrv,
+        $q: $q,
       };
 
       /*jshint -W054 */
@@ -118,16 +129,16 @@ function (angular, _, kbn, moment, $) {
       var url = 'public/dashboards/'+file.replace(/\.(?!js)/,"/") + '?' + new Date().getTime();
 
       return $http({ url: url, method: "GET" })
-        .then(execute_script)
-        .then(null,function(err) {
-          console.log('Script dashboard error '+ err);
-          $scope.appEvent('alert-error', ["Script Error", "Please make sure it exists and returns a valid dashboard"]);
-          return false;
-        });
+      .then(execute_script)
+      .then(null,function(err) {
+        console.log('Script dashboard error '+ err);
+        $scope.appEvent('alert-error', ["Script Error", "Please make sure it exists and returns a valid dashboard"]);
+        return false;
+      });
     };
 
     script_load($routeParams.jsFile).then(function(result) {
-      $scope.initDashboard({meta: {fromScript: true}, model: result.data}, $scope);
+      $scope.initDashboard({meta: {fromScript: true, canDelete: false}, model: result.data}, $scope);
     });
 
   });

+ 8 - 22
public/css/less/bootstrap-tagsinput.less

@@ -1,33 +1,19 @@
 .bootstrap-tagsinput {
   display: inline-block;
-  padding: 4px 6px;
-  margin-bottom: 10px;
-  color: #555;
+  padding: 0 0 0 6px;
   vertical-align: middle;
-  border-radius: 4px;
   max-width: 100%;
   line-height: 22px;
-
   background-color: @inputBackground;
-  border: 1px solid @inputBorder;
-  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
-  .transition(~"border linear .2s, box-shadow linear .2s");
 
   input {
     border: none;
-    box-shadow: none;
-    outline: none;
-    background-color: transparent;
-    padding: 0;
-    padding-left: 5px;
-    margin: 0;
-    width: auto !important;
-    max-width: inherit;
-
-    &:focus {
-      border: none;
-      box-shadow: none;
-    }
+    border-right: 1px solid @grafanaTargetSegmentBorder;
+    margin: 0px;
+    border-radius: 0;
+    padding: 8px 6px;
+    height: 100%;
+    box-sizing: border-box;
   }
 
   .tag {
@@ -49,4 +35,4 @@
       }
     }
   }
-}
+}

+ 1 - 1
public/vendor/tagsinput/bootstrap-tagsinput.js

@@ -500,4 +500,4 @@
   $(function() {
     $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput();
   });
-})(window.jQuery);
+})(window.jQuery);