Browse Source

add validation of uid when importing dashboards

Marcus Efraimsson 7 năm trước cách đây
mục cha
commit
7c3e8afd82

+ 31 - 0
public/app/features/dashboard/dashboard_import_ctrl.ts

@@ -7,6 +7,7 @@ export class DashboardImportCtrl {
   jsonText: string;
   parseError: string;
   nameExists: boolean;
+  uidExists: boolean;
   dash: any;
   inputs: any[];
   inputsValid: boolean;
@@ -16,6 +17,10 @@ export class DashboardImportCtrl {
   titleTouched: boolean;
   hasNameValidationError: boolean;
   nameValidationError: any;
+  hasUidValidationError: boolean;
+  uidValidationError: any;
+  autoGenerateUid: boolean;
+  autoGenerateUidValue: string;
 
   /** @ngInject */
   constructor(private backendSrv, private validationSrv, navModelSrv, private $location, $routeParams) {
@@ -23,6 +28,9 @@ export class DashboardImportCtrl {
 
     this.step = 1;
     this.nameExists = false;
+    this.uidExists = false;
+    this.autoGenerateUid = true;
+    this.autoGenerateUidValue = 'auto-generated';
 
     // check gnetId in url
     if ($routeParams.gnetId) {
@@ -61,6 +69,7 @@ export class DashboardImportCtrl {
 
     this.inputsValid = this.inputs.length === 0;
     this.titleChanged();
+    this.uidChanged(true);
   }
 
   setDatasourceOptions(input, inputModel) {
@@ -107,6 +116,28 @@ export class DashboardImportCtrl {
       });
   }
 
+  uidChanged(initial) {
+    this.uidExists = false;
+    this.hasUidValidationError = false;
+
+    if (initial === true && this.dash.uid) {
+      this.autoGenerateUidValue = 'value set';
+    }
+
+    this.backendSrv
+      .getDashboardByUid(this.dash.uid)
+      .then(res => {
+        this.uidExists = true;
+        this.hasUidValidationError = true;
+        this.uidValidationError = `Dashboard named '${res.dashboard.title}' in folder '${
+          res.meta.folderTitle
+        }' has the same uid`;
+      })
+      .catch(err => {
+        err.isHandled = true;
+      });
+  }
+
   saveDashboard() {
     var inputs = this.inputs.map(input => {
       return {

+ 30 - 2
public/app/features/dashboard/partials/dashboard_import.html

@@ -80,6 +80,34 @@
         </div>
       </div>
 
+      <div class="gf-form-inline">
+        <div class="gf-form gf-form--grow">
+          <span class="gf-form-label width-15">
+            Unique identifier (uid)
+            <info-popover mode="right-normal">
+                The unique identifier (uid) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs.
+                The uid allows having consistent URL’s for accessing dashboards so changing the title of a dashboard will not break any
+                bookmarked links to that dashboard.
+            </info-popover>
+          </span>
+          <input type="text" class="gf-form-input" disabled="disabled" ng-model="ctrl.autoGenerateUidValue" ng-if="ctrl.autoGenerateUid">
+          <a class="btn btn-secondary gf-form-btn" href="#" ng-click="ctrl.autoGenerateUid = false" ng-if="ctrl.autoGenerateUid">change</a>
+          <input type="text" class="gf-form-input" maxlength="40" placeholder="optional, will be auto-generated if empty" ng-model="ctrl.dash.uid" ng-change="ctrl.uidChanged()" ng-if="!ctrl.autoGenerateUid">
+          <label class="gf-form-label text-success" ng-if="!ctrl.autoGenerateUid && !ctrl.hasUidValidationError">
+            <i class="fa fa-check"></i>
+          </label>
+        </div>
+      </div>
+
+      <div class="gf-form-inline" ng-if="ctrl.hasUidValidationError">
+        <div class="gf-form offset-width-15 gf-form--grow">
+          <label class="gf-form-label text-warning gf-form-label--grow">
+            <i class="fa fa-warning"></i>
+            {{ctrl.uidValidationError}}
+          </label>
+        </div>
+      </div>
+
       <div ng-repeat="input in ctrl.inputs">
         <div class="gf-form">
           <label class="gf-form-label width-15">
@@ -104,10 +132,10 @@
     </div>
 
     <div class="gf-form-button-row">
-      <button type="button" class="btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
+      <button type="button" class="btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists || ctrl.uidExists" ng-disabled="!ctrl.inputsValid">
         <i class="fa fa-save"></i> Import
       </button>
-      <button type="button" class="btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
+      <button type="button" class="btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists || ctrl.uidExists" ng-disabled="!ctrl.inputsValid">
         <i class="fa fa-save"></i> Import (Overwrite)
       </button>
       <a class="btn btn-link" ng-click="ctrl.back()">Cancel</a>

+ 1 - 0
public/app/features/dashboard/specs/dashboard_import_ctrl.jest.ts

@@ -15,6 +15,7 @@ describe('DashboardImportCtrl', function() {
 
     backendSrv = {
       search: jest.fn().mockReturnValue(Promise.resolve([])),
+      getDashboardByUid: jest.fn().mockReturnValue(Promise.resolve([])),
       get: jest.fn(),
     };