Bladeren bron

more work on dashboard links, this feature is taking forever, dam angular, and dam complexity

Torkel Ödegaard 10 jaren geleden
bovenliggende
commit
4b4f398e83

+ 10 - 0
public/app/features/dashlinks/editor.html

@@ -27,6 +27,16 @@
 				<li ng-show="link.type === 'dashboards'">
 					<input type="text" ng-model="link.tag" class="input-small tight-form-input" style="width: 151px" ng-model-onblur ng-change="updated()">
 				</li>
+				<li class="tight-form-item" ng-show="link.type === 'dashboards'">
+					<editor-checkbox text="As dropdown" model="link.asDropdown" change="updated()"></editor-checkbox>
+				</li>
+				<li class="tight-form-item" ng-show="link.type === 'dashboards' && link.asDropdown">
+					Title
+				</li>
+				<li ng-show="link.type === 'dashboards' && link.asDropdown">
+					<input type="text" ng-model="link.title" class="input-medium tight-form-input" ng-model-onblur ng-change="updated()">
+				</li>
+
 
 				<li class="tight-form-item" ng-show="link.type === 'link'" style="width: 51px">Url</li>
 				<li ng-show="link.type === 'link'">

+ 0 - 6
public/app/features/dashlinks/module.html

@@ -1,6 +0,0 @@
-<div class="submenu-item">
-	<a class="pointer dash-nav-link" href="/asd" data-placement="bottom">
-		<i class="fa fa-th-large"></i>
-		<span></span>
-	</a>
-</div>

+ 51 - 17
public/app/features/dashlinks/module.js

@@ -42,21 +42,33 @@ function (angular, _) {
     };
   });
 
-  module.directive('dashLink', function(templateSrv) {
+  module.directive('dashLink', function($compile, linkSrv) {
     return {
-      scope: {
-        link: "="
-      },
       restrict: 'E',
-      templateUrl: 'app/features/dashlinks/module.html',
       link: function(scope, elem) {
+        var link = scope.link;
+        var template = '<div class="submenu-item dropdown">' +
+          '<a class="pointer dash-nav-link" data-placement="bottom"' +
+          (link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"'  : "") + '>' +
+          '<i></i> <span></span></a>';
+
+        if (link.asDropdown) {
+          template += '<ul class="dropdown-menu" role="menu">' +
+            '<li ng-repeat="dash in link.searchHits"><a href="{{dash.url}}"><i class="fa fa-th-large"></i> {{dash.title}}</a></li>' +
+            '</ul';
+        }
+
+        elem.html(template);
+        $compile(elem.contents())(scope);
+
         var anchor = elem.find('a');
         var icon = elem.find('i');
         var span = elem.find('span');
 
         function update() {
-          span.text(templateSrv.replace(scope.link.title));
-          anchor.attr("href", templateSrv.replace(scope.link.url));
+          var linkInfo = linkSrv.getAnchorInfo(link);
+          span.text(linkInfo.title);
+          anchor.attr("href", linkInfo.href);
         }
 
         // tooltip
@@ -70,7 +82,7 @@ function (angular, _) {
     };
   });
 
-  module.controller("DashLinksContainerCtrl", function($scope, $rootScope, $q, backendSrv, dashboardSrv) {
+  module.controller("DashLinksContainerCtrl", function($scope, $rootScope, $q, backendSrv, dashboardSrv, linkSrv) {
     var currentDashId = dashboardSrv.getCurrent().id;
 
     function buildLinks(linkDef) {
@@ -80,15 +92,16 @@ function (angular, _) {
           return $q.when([]);
         }
 
-        return backendSrv.search({tag: linkDef.tag}).then(function(results) {
-          return _.reduce(results.dashboards, function(memo, dash) {
-            // do not add current dashboard
-            if (dash.id !== currentDashId) {
-              memo.push({ title: dash.title, url: 'dashboard/db/'+ dash.slug, icon: 'fa fa-th-large' });
-            }
-            return memo;
-          }, []);
-        });
+        if (linkDef.asDropdown) {
+          return $q.when([{
+            title: linkDef.title,
+            tag: linkDef.tag,
+            icon: "fa fa-bars",
+            asDropdown: true
+          }]);
+        }
+
+        return $scope.searchDashboards(linkDef.tag);
       }
 
       if (linkDef.type === 'link') {
@@ -112,6 +125,27 @@ function (angular, _) {
       });
     }
 
+    $scope.searchDashboards = function(tag) {
+      return backendSrv.search({tag: tag}).then(function(results) {
+        return _.reduce(results.dashboards, function(memo, dash) {
+          // do not add current dashboard
+          if (dash.id !== currentDashId) {
+            memo.push({ title: dash.title, url: 'dashboard/db/'+ dash.slug, icon: 'fa fa-th-large', addTime: true });
+          }
+          return memo;
+        }, []);
+      });
+    };
+
+    $scope.fillDropdown = function(link) {
+      $scope.searchDashboards(link.tag).then(function(results) {
+        _.each(results, function(hit) {
+          hit.url = linkSrv.getLinkUrl(hit);
+        });
+        link.searchHits = results;
+      });
+    };
+
     updateDashLinks();
     $rootScope.onAppEvent('dash-links-updated', updateDashLinks);
   });

+ 58 - 0
public/app/features/panellinks/linkSrv.js

@@ -9,6 +9,64 @@ function (angular, kbn) {
     .module('grafana.services')
     .service('linkSrv', function(templateSrv, timeSrv) {
 
+      // parseUri 1.2.2
+      // (c) Steven Levithan <stevenlevithan.com>
+      // MIT License
+
+      function parseUri (str) {
+        var	o   = parseUri.options,
+          m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+          uri = {},
+          i   = 14;
+
+        while (i--) {
+          uri[o.key[i]] = m[i] || "";
+        }
+
+        uri[o.q.name] = {};
+        uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+          if ($1) {
+            uri[o.q.name][$1] = $2;
+          }
+        });
+
+        return uri;
+      }
+
+      parseUri.options = {
+        strictMode: false,
+        key: ["source","protocol","authority","userInfo","user","password","host",
+              "port","relative","path","directory","file","query","anchor"],
+        q:   {
+          name:   "queryKey",
+          parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+        },
+        /* jshint ignore:start */
+        parser: {
+          strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+          loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+        }
+        /* jshint ignore:end */
+      };
+
+      this.getLinkUrl = function(link) {
+        var href = templateSrv.replace(link.url || '');
+        if (link.addTime) {
+          var range = timeSrv.timeRangeForUrl();
+          href += (href.indexOf('?') !== -1 ? '&' : '?');
+          href += 'from=' + range.from;
+          href += '&to=' + range.to;
+        }
+        return href;
+      };
+
+      this.getAnchorInfo = function(link) {
+        var info = {};
+        info.href = this.getLinkUrl(link);
+        info.title = templateSrv.replace(link.title || '');
+        return info;
+      };
+
       this.getPanelLinkAnchorInfo = function(link) {
         var info = {};
         if (link.type === 'absolute') {

+ 9 - 13
public/css/less/overrides.less

@@ -558,18 +558,6 @@ div.flot-text {
   background-color: darken(@purple, 10%);
 }
 
-// Top menu
-.save-dashboard-dropdown {
-  padding: 10px;
-  li>a {
-    padding-left: 5px;
-  }
-}
-
-.save-dashboard-dropdown-save-form {
-  margin-bottom: 5px;
-}
-
 
 // inspector
 .inspector-request-table {
@@ -592,4 +580,12 @@ code, pre {
   color: @textColor;
 }
 
-
+.dropdown-menu {
+  > li > a {
+    padding: 3px 10px;
+    i {
+      padding-right: 5px;
+      color: @linkColorDisabled;
+    }
+  }
+}

+ 1 - 1
public/css/less/submenu.less

@@ -1,6 +1,6 @@
 .submenu-controls-visible {
   .panel-fullscreen {
-    top: 88px;
+    top: 105px;
   }
 }