Sfoglia il codice sorgente

Merge branch 'develop-settings-links' into develop

Torkel Ödegaard 8 anni fa
parent
commit
2765c2ecc7

+ 1 - 1
public/app/features/dashboard/settings/settings.html

@@ -76,7 +76,7 @@
 </div>
 
 <div class="dashboard-settings__content" ng-if="ctrl.viewId === 'links'" >
-	<dash-links-editor></dash-links-editor>
+	<dash-links-editor dashboard="ctrl.dashboard"></dash-links-editor>
 </div>
 
 <div class="dashboard-settings__content" ng-if="ctrl.viewId === 'versions'" >

+ 126 - 68
public/app/features/dashlinks/editor.html

@@ -1,77 +1,135 @@
 <h3 class="dashboard-settings__header">
-	Dashboard Links
+  <a ng-click="ctrl.backToList()">Dashboard Links</a>
+  <span ng-show="ctrl.mode === 'new'">&gt; New</span>
+  <span ng-show="ctrl.mode === 'edit'">&gt; Edit</span>
 </h3>
 
-<div ng-repeat="link in dashboard.links">
-	<div class="gf-form-group gf-form-inline">
-		<div class="section">
-			<div class="gf-form">
-				<span class="gf-form-label width-8">Type</span>
-				<div class="gf-form-select-wrapper width-10">
-					<select class="gf-form-input" ng-model="link.type" ng-options="f for f in ['dashboards','link']" ng-change="updated()"></select>
-				</div>
-			</div>
-			<div class="gf-form" ng-show="link.type === 'dashboards'">
-				<span class="gf-form-label width-8">With tags</span>
-				<bootstrap-tagsinput ng-model="link.tags" tagclass="label label-tag" placeholder="add tags" style="margin-right: .25rem"></bootstrap-tagsinput>
-			</div>
-			<gf-form-switch ng-show="link.type === 'dashboards'" class="gf-form" label="As dropdown" checked="link.asDropdown" switch-class="max-width-4" label-class="width-8" on-change="updated()"></gf-form-switch>
-			<div class="gf-form" ng-show="link.type === 'dashboards' && link.asDropdown">
-				<span class="gf-form-label width-8">Title</span>
-				<input type="text" ng-model="link.title" class="gf-form-input max-width-10" ng-model-onblur ng-change="updated()">
-			</div>
-			<div ng-show="link.type === 'link'">
-				<div class="gf-form">
-					<li class="gf-form-label width-8">Url</li>
-					<input type="text" ng-model="link.url" class="gf-form-input width-20" ng-model-onblur ng-change="updated()">
-				</div>
+<div ng-if="ctrl.mode == 'list'">
+  <div ng-if="ctrl.dashboard.links.length === 0">
+    <div class="empty-list-cta">
+      <div class="empty-list-cta__title">
+        There are no dashboard links added yet
+      </div>
+      <a ng-click="ctrl.setupNew()" class="empty-list-cta__button btn btn-xlarge btn-success">
+        <i class="gicon gicon-dashboard-new"></i>
+        Add Dashboard Link
+      </a>
+      <div class="grafana-info-box">
+        <h5>What are Dashboard Links?</h5>
+        <p>
+					Dashboad Links allow you to place links to other dashboards and web sites directly in below the dashboard header.
+        </p>
+      </div>
+    </div>
+  </div>
 
-				<div class="gf-form">
-					<span class="gf-form-label width-8">Title</span>
-					<input type="text" ng-model="link.title" class="gf-form-input width-20" ng-model-onblur ng-change="updated()">
-				</div>
+  <div ng-if="ctrl.dashboard.links.length > 0">
+    <div class="page-action-bar">
+      <div class="page-action-bar__spacer"></div>
+      <a type="button" class="btn btn-success" ng-click="ctrl.setupNew()">
+        <i class="fa fa-plus"></i> New</a>
+    </div>
+    <table class="filter-table filter-table--hover">
+      <thead>
+        <tr>
+          <th>Type</th>
+          <th>Info</th>
+          <th colspan="3"></th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr ng-repeat="link in ctrl.dashboard.links">
+          <td class="pointer" ng-click="ctrl.editLink(link)">
+            <i class="fa fa-fw fa-external-link"></i>
+            {{link.type}}
+          </td>
+          <td>
+            <div ng-if="link.title">
+              {{link.title}}
+            </div>
+            <div ng-if="!link.title && link.url">
+              {{link.url}}
+            </div>
+            <span ng-if="!link.title && link.tags" ng-repeat="tag in link.tags" tag-color-from-name="tag" class="label label-tag" style="margin-right: 6px">
+              {{tag}}
+            </span>
+          </td>
+          <td style="width: 1%">
+            <i ng-click="ctrl.moveLink($index, -1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i>
+          </td>
+          <td style="width: 1%">
+            <i ng-click="ctrl.moveLink($index, 1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i>
+          </td>
+          <td style="width: 1%">
+            <a ng-click="ctrl.deleteLink($index)" class="btn btn-danger btn-mini" ng-hide="annotation.builtIn">
+              <i class="fa fa-remove"></i>
+            </a>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+  </div>
+</div>
 
-				<div class="gf-form">
-					<span class="gf-form-label width-8">Tooltip</span>
-					<input type="text" ng-model="link.tooltip" class="gf-form-input width-20" placeholder="Open dashboard" ng-model-onblur ng-change="updated()">
-				</div>
+<div ng-if="ctrl.mode == 'edit' || ctrl.mode == 'new'">
+  <div class="gf-form-group">
+    <div class="gf-form-group">
+      <div class="gf-form">
+        <span class="gf-form-label width-8">Type</span>
+        <div class="gf-form-select-wrapper width-10">
+          <select class="gf-form-input" ng-model="ctrl.link.type" ng-options="f for f in ['dashboards','link']"></select>
+        </div>
+      </div>
 
-				<div class="gf-form">
-					<span class="gf-form-label width-8">Icon</span>
-					<div class="gf-form-select-wrapper width-20">
-						<select class="gf-form-input" ng-model="link.icon" ng-options="k as k for (k, v) in iconMap" ng-change="updated()"></select>
-					</div>
-				</div>
-			</div>
-		</div>
+      <div class="gf-form" ng-show="ctrl.link.type === 'dashboards'">
+        <span class="gf-form-label width-8">With tags</span>
+        <bootstrap-tagsinput ng-model="ctrl.link.tags" tagclass="label label-tag" placeholder="add tags" style="margin-right: .25rem"></bootstrap-tagsinput>
+      </div>
 
-		<div class="section gf-form-inline"  style="display: flex">
-			<div>
-				<div class="gf-form">
-					<span class="gf-form-label width-6">Include</span>
-				</div>
-			</div>
-			<div>
-				<gf-form-switch class="gf-form" label="Time range" checked="link.keepTime" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
-				<gf-form-switch class="gf-form" label="Variable values" checked="link.includeVars" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
-				<gf-form-switch class="gf-form" label="Open in new tab" checked="link.targetBlank" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
-			</div>
-		</div>
+      <gf-form-switch ng-show="ctrl.link.type === 'dashboards'" class="gf-form" label="As dropdown" checked="ctrl.link.asDropdown"
+        switch-class="max-width-4" label-class="width-8"></gf-form-switch>
+      <div class="gf-form" ng-show="ctrl.link.type === 'dashboards' && ctrl.link.asDropdown">
+        <span class="gf-form-label width-8">Title</span>
+        <input type="text" ng-model="ctrl.link.title" class="gf-form-input max-width-10" ng-model-onblur>
+      </div>
+      <div ng-show="ctrl.link.type === 'link'">
+        <div class="gf-form">
+          <li class="gf-form-label width-8">Url</li>
+          <input type="text" ng-model="ctrl.link.url" class="gf-form-input width-20" ng-model-onblur>
+        </div>
 
-		<div style="display:flex; flex-direction:column; justify-content:flex-start">
-			<div class="gf-form">
-				<button class="btn btn-inverse gf-form-btn width-4" ng-click="deleteLink($index)">
-					<i class="fa fa-trash"></i>
-				</button>
-			</div>
-			<div class="gf-form">
-				<button class="btn btn-inverse gf-form-btn width-4" ng-click="moveLink($index, -1)" ng-hide="$first"><i class="fa fa-arrow-up"></i></button>
-			</div>
-			<div class="gf-form">
-				<button class="btn btn-inverse gf-form-btn width-4" ng-click="moveLink($index, 1)" ng-hide="$last"><i class="fa fa-arrow-down"></i></button>
-			</div>
-		</div>
-	</div>
-</div>
+        <div class="gf-form">
+          <span class="gf-form-label width-8">Title</span>
+          <input type="text" ng-model="ctrl.link.title" class="gf-form-input width-20" ng-model-onblur>
+        </div>
+
+        <div class="gf-form">
+          <span class="gf-form-label width-8">Tooltip</span>
+          <input type="text" ng-model="ctrl.link.tooltip" class="gf-form-input width-20" placeholder="Open dashboard" ng-model-onblur>
+        </div>
 
-<button class="btn btn-inverse" ng-click="addLink()"><i class="fa fa-plus"></i> Add link</button>
+        <div class="gf-form">
+          <span class="gf-form-label width-8">Icon</span>
+          <div class="gf-form-select-wrapper width-20">
+            <select class="gf-form-input" ng-model="ctrl.link.icon" ng-options="k as k for (k, v) in ctrl.iconMap"></select>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="gf-form-group">
+      <h5 class="section-heading">Include</h5>
+      <div>
+        <gf-form-switch class="gf-form" label="Time range" checked="ctrl.link.keepTime" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
+        <gf-form-switch class="gf-form" label="Variable values" checked="ctrl.link.includeVars" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
+        <gf-form-switch class="gf-form" label="Open in new tab" checked="ctrl.link.targetBlank" switch-class="max-width-6" label-class="width-9"></gf-form-switch>
+      </div>
+    </div>
+  </div>
+  <button class="btn btn-success" ng-if="ctrl.mode == 'new'" ng-click="ctrl.addLink()">
+    Add
+  </button>
+  <button class="btn btn-success" ng-if="ctrl.mode == 'edit'" ng-click="ctrl.saveLink()">
+    Update
+  </button>
+</div>

+ 80 - 0
public/app/features/dashlinks/editor.ts

@@ -0,0 +1,80 @@
+import angular from "angular";
+import _ from "lodash";
+
+export var iconMap = {
+  "external link": "fa-external-link",
+  dashboard: "fa-th-large",
+  question: "fa-question",
+  info: "fa-info",
+  bolt: "fa-bolt",
+  doc: "fa-file-text-o",
+  cloud: "fa-cloud"
+};
+
+export class DashLinkEditorCtrl {
+  dashboard: any;
+  iconMap: any;
+  mode: any;
+  link: any;
+
+  /** @ngInject */
+  constructor($scope, $rootScope) {
+    this.iconMap = iconMap;
+    this.dashboard.links = this.dashboard.links || [];
+    this.mode = "list";
+
+    $scope.$on("$destroy", () => {
+      $rootScope.appEvent("dash-links-updated");
+    });
+  }
+
+  backToList() {
+    this.mode = "list";
+  }
+
+  setupNew() {
+    this.mode = "new";
+    this.link = { type: "dashboards", icon: "external link" };
+  }
+
+  addLink() {
+    this.dashboard.links.push(this.link);
+    this.mode = "list";
+  }
+
+  editLink(link) {
+    this.link = link;
+    this.mode = "edit";
+    console.log(this.link);
+  }
+
+  saveLink() {
+    this.backToList();
+  }
+
+  moveLink(index, dir) {
+    _.move(this.dashboard.links, index, index + dir);
+  }
+
+  deleteLink(index) {
+    this.dashboard.links.splice(index, 1);
+    this.dashboard.updateSubmenuVisibility();
+  }
+}
+
+function dashLinksEditor() {
+  return {
+    restrict: "E",
+    controller: DashLinkEditorCtrl,
+    templateUrl: "public/app/features/dashlinks/editor.html",
+    bindToController: true,
+    controllerAs: "ctrl",
+    scope: {
+      dashboard: "="
+    }
+  };
+}
+
+angular
+  .module("grafana.directives")
+  .directive("dashLinksEditor", dashLinksEditor);

+ 83 - 111
public/app/features/dashlinks/module.ts

@@ -1,63 +1,50 @@
-import angular from 'angular';
-import _ from 'lodash';
-
-var iconMap = {
-  "external link": "fa-external-link",
-  "dashboard": "fa-th-large",
-  "question": "fa-question",
-  "info": "fa-info",
-  "bolt": "fa-bolt",
-  "doc": "fa-file-text-o",
-  "cloud": "fa-cloud",
-};
-
-function dashLinksEditor() {
-  return {
-    restrict: 'E',
-    controller: 'DashLinkEditorCtrl',
-    templateUrl: 'public/app/features/dashlinks/editor.html',
-    link: function() {
-    }
-  };
-}
+import angular from "angular";
+import _ from "lodash";
+import { iconMap } from "./editor";
 
 function dashLinksContainer() {
   return {
     scope: {
       links: "="
     },
-    restrict: 'E',
-    controller: 'DashLinksContainerCtrl',
-    template: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
-    link: function() { }
+    restrict: "E",
+    controller: "DashLinksContainerCtrl",
+    template:
+      '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
+    link: function() {}
   };
 }
 
 /** @ngInject */
 function dashLink($compile, linkSrv) {
   return {
-    restrict: 'E',
+    restrict: "E",
     link: function(scope, elem) {
       var link = scope.link;
-      var template = '<div class="gf-form">' +
+      var template =
+        '<div class="gf-form">' +
         '<a class="pointer gf-form-label" data-placement="bottom"' +
-        (link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"'  : "") + '>' +
-        '<i></i> <span></span></a>';
+        (link.asDropdown
+          ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"'
+          : "") +
+        ">" +
+        "<i></i> <span></span></a>";
 
       if (link.asDropdown) {
-        template += '<ul class="dropdown-menu" role="menu">' +
+        template +=
+          '<ul class="dropdown-menu" role="menu">' +
           '<li ng-repeat="dash in link.searchHits"><a href="{{dash.url}}">{{dash.title}}</a></li>' +
-          '</ul>';
+          "</ul>";
       }
 
-      template += '</div>';
+      template += "</div>";
 
       elem.html(template);
       $compile(elem.contents())(scope);
 
-      var anchor = elem.find('a');
-      var icon = elem.find('i');
-      var span = elem.find('span');
+      var anchor = elem.find("a");
+      var icon = elem.find("i");
+      var span = elem.find("span");
 
       function update() {
         var linkInfo = linkSrv.getAnchorInfo(link);
@@ -66,17 +53,19 @@ function dashLink($compile, linkSrv) {
       }
 
       // tooltip
-      elem.find('a').tooltip({ title: scope.link.tooltip, html: true, container: 'body' });
-      icon.attr('class', 'fa fa-fw ' + scope.link.icon);
-      anchor.attr('target', scope.link.target);
+      elem
+        .find("a")
+        .tooltip({ title: scope.link.tooltip, html: true, container: "body" });
+      icon.attr("class", "fa fa-fw " + scope.link.icon);
+      anchor.attr("target", scope.link.target);
 
       // fix for menus on the far right
       if (link.asDropdown && scope.$last) {
-        elem.find('.dropdown-menu').addClass('pull-right');
+        elem.find(".dropdown-menu").addClass("pull-right");
       }
 
       update();
-      scope.$on('refresh', update);
+      scope.$on("refresh", update);
     }
   };
 }
@@ -87,36 +76,40 @@ export class DashLinksContainerCtrl {
     var currentDashId = dashboardSrv.getCurrent().id;
 
     function buildLinks(linkDef) {
-      if (linkDef.type === 'dashboards') {
+      if (linkDef.type === "dashboards") {
         if (!linkDef.tags) {
-          console.log('Dashboard link missing tag');
+          console.log("Dashboard link missing tag");
           return $q.when([]);
         }
 
         if (linkDef.asDropdown) {
-          return $q.when([{
-            title: linkDef.title,
-            tags: linkDef.tags,
-            keepTime: linkDef.keepTime,
-            includeVars: linkDef.includeVars,
-            icon: "fa fa-bars",
-            asDropdown: true
-          }]);
+          return $q.when([
+            {
+              title: linkDef.title,
+              tags: linkDef.tags,
+              keepTime: linkDef.keepTime,
+              includeVars: linkDef.includeVars,
+              icon: "fa fa-bars",
+              asDropdown: true
+            }
+          ]);
         }
 
         return $scope.searchDashboards(linkDef, 7);
       }
 
-      if (linkDef.type === 'link') {
-        return $q.when([{
-          url: linkDef.url,
-          title: linkDef.title,
-          icon: iconMap[linkDef.icon],
-          tooltip: linkDef.tooltip,
-          target: linkDef.targetBlank ? "_blank" : "_self",
-          keepTime: linkDef.keepTime,
-          includeVars: linkDef.includeVars,
-        }]);
+      if (linkDef.type === "link") {
+        return $q.when([
+          {
+            url: linkDef.url,
+            title: linkDef.title,
+            icon: iconMap[linkDef.icon],
+            tooltip: linkDef.tooltip,
+            target: linkDef.targetBlank ? "_blank" : "_self",
+            keepTime: linkDef.keepTime,
+            includeVars: linkDef.includeVars
+          }
+        ]);
       }
 
       return $q.when([]);
@@ -131,21 +124,27 @@ export class DashLinksContainerCtrl {
     }
 
     $scope.searchDashboards = function(link, limit) {
-      return backendSrv.search({tag: link.tags, limit: limit}).then(function(results) {
-        return _.reduce(results, function(memo, dash) {
-          // do not add current dashboard
-          if (dash.id !== currentDashId) {
-            memo.push({
-              title: dash.title,
-              url: 'dashboard/' + dash.uri,
-              icon: 'fa fa-th-large',
-              keepTime: link.keepTime,
-              includeVars: link.includeVars
-            });
-          }
-          return memo;
-        }, []);
-      });
+      return backendSrv
+        .search({ tag: link.tags, limit: limit })
+        .then(function(results) {
+          return _.reduce(
+            results,
+            function(memo, dash) {
+              // do not add current dashboard
+              if (dash.id !== currentDashId) {
+                memo.push({
+                  title: dash.title,
+                  url: "dashboard/" + dash.uri,
+                  icon: "fa fa-th-large",
+                  keepTime: link.keepTime,
+                  includeVars: link.includeVars
+                });
+              }
+              return memo;
+            },
+            []
+          );
+        });
     };
 
     $scope.fillDropdown = function(link) {
@@ -158,41 +157,14 @@ export class DashLinksContainerCtrl {
     };
 
     updateDashLinks();
-    $rootScope.onAppEvent('dash-links-updated', updateDashLinks, $scope);
-  }
-}
-
-export class DashLinkEditorCtrl {
-  /** @ngInject */
-  constructor($scope, $rootScope) {
-    $scope.iconMap = iconMap;
-    $scope.dashboard.links = $scope.dashboard.links || [];
-
-    $scope.addLink = function() {
-      $scope.dashboard.links.push({ type: 'dashboards', icon: 'external link' });
-      $scope.dashboard.updateSubmenuVisibility();
-      $scope.updated();
-    };
-
-    $scope.moveLink = function(index, dir) {
-      _.move($scope.dashboard.links, index, index+dir);
-      $scope.updated();
-    };
-
-    $scope.updated = function() {
-      $rootScope.appEvent('dash-links-updated');
-    };
-
-    $scope.deleteLink = function(index) {
-      $scope.dashboard.links.splice(index, 1);
-      $scope.dashboard.updateSubmenuVisibility();
-      $scope.updated();
-    };
+    $rootScope.onAppEvent("dash-links-updated", updateDashLinks, $scope);
   }
 }
 
-angular.module('grafana.directives').directive('dashLinksEditor', dashLinksEditor);
-angular.module('grafana.directives').directive('dashLinksContainer', dashLinksContainer);
-angular.module('grafana.directives').directive('dashLink', dashLink);
-angular.module('grafana.directives').controller("DashLinksContainerCtrl", DashLinksContainerCtrl);
-angular.module('grafana.directives').controller('DashLinkEditorCtrl', DashLinkEditorCtrl);
+angular
+  .module("grafana.directives")
+  .directive("dashLinksContainer", dashLinksContainer);
+angular.module("grafana.directives").directive("dashLink", dashLink);
+angular
+  .module("grafana.directives")
+  .controller("DashLinksContainerCtrl", DashLinksContainerCtrl);