You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2017/03/13 15:48:01 UTC

[1/4] qpid-dispatch git commit: DISPATCH-725 Use patternfly styles for stand-alone console

Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 1a59f1fca -> 615d7b65f


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/stand-alone/bower_components/angular-patternfly/dist/styles/angular-patternfly.min.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/bower_components/angular-patternfly/dist/styles/angular-patternfly.min.css b/console/stand-alone/bower_components/angular-patternfly/dist/styles/angular-patternfly.min.css
new file mode 100644
index 0000000..41c78b0
--- /dev/null
+++ b/console/stand-alone/bower_components/angular-patternfly/dist/styles/angular-patternfly.min.css
@@ -0,0 +1 @@
+.card-pf-aggregate-status-alt .card-pf-body{padding-bottom:20px}.card-pf-aggregate-status-alt .card-pf-title{line-height:22px;margin:20px 0 10px;font-weight:300}.card-pf-aggregate-status-alt .card-pf-aggregate-status-count{font-size:24px}.card-pf-aggregate-status-alt .card-pf-aggregate-status-title{display:block;font-size:12px}.card-pf-aggregate-status-alt .card-pf-aggregate-status-notifications .card-pf-aggregate-status-notification{border-left:none}.card-pf-aggregate-status-alt .card-pf-aggregate-status-notifications .fa,.card-pf-aggregate-status-alt .card-pf-aggregate-status-notifications .pficon{position:relative;top:-1px}.card-pf-heading-no-bottom{margin:0 -20px 0;padding:0 20px}.card-pf-icon-image{height:18px;margin:0 5px 5px}.empty-chart-content{text-align:center}.empty-chart-content .pficon{font-size:24px}.empty-chart-content span{vertical-align:middle;width:100%}.utilization-trend-chart-pf .donut-chart-pf{width:100%;float:left;padding-top:15px}.utilization-trend-chart-pf h3
 {font-weight:400}.utilization-trend-chart-pf .current-values{border-bottom:1px solid #d1d1d1;float:left;padding:0 5px 10px 0;width:100%}.utilization-trend-chart-pf .available-count{margin:3px 0;padding-left:0;padding-right:5px}.utilization-trend-chart-pf .available-text{font-size:12px;font-weight:400;line-height:14px;margin:2px 0;padding:0 5px}.utilization-trend-chart-pf .radial-chart{float:left;padding-top:10px;width:100%}.utilization-trend-chart-pf .sparkline-chart{float:left;margin-left:-5px;margin-right:-5px;width:100%}.utilization-trend-chart-pf .legend-text{color:inherit;display:block;font-size:12px;font-weight:400;margin-left:0}.utilization-trend-chart-pf.data-unavailable-pf .current-values{color:transparent}.card-view-pf{overflow:auto;padding-top:20px;padding-left:2px}.card-view-pf .card{-webkit-box-shadow:0 1px 1px rgba(0,0,0,.175);background:#fff;border-top:2px solid transparent;box-shadow:0 1px 1px rgba(0,0,0,.175);display:block;float:left;height:290px;margin-right:20px;m
 argin-bottom:20px;padding:10px;position:relative;text-align:center;width:260px}.card-view-pf .card .card-check-box{left:10px;position:absolute;top:8px;width:20px;z-index:3;visibility:hidden}.card-view-pf .card-content{height:100%;margin:2px 0 10px;overflow:auto;width:100%}.card-view-pf .card-title{color:#1186C1;font-weight:500;font-size:16px;line-height:1.1;margin-top:0}.card-view-pf .card.active,.card-view-pf .card.active:focus,.card-view-pf .card.active:hover{border:solid 3px #00a8e1}.card-view-pf .card:focus,.card-view-pf .card:hover{-webkit-box-shadow:0 3px 10px -2px rgba(0,0,0,.24);-moz-box-shadow:0 3px 10px -2px rgba(0,0,0,.24);box-shadow:0 3px 10px -2px rgba(0,0,0,.24);border:1px solid #d1d1d1}.card-view-pf .card.active .pficon,.card-view-pf .card.active:focus .pficon,.card-view-pf .card.active:hover .pficon{color:#fff}.card-view-pf .card.active .card-check-box,.card-view-pf .card:hover .card-check-box{visibility:visible}.card-view-pf .card.disabled,.card.disabled:focus,.card
 .disabled:hover{border:1px solid #eee;color:#999;cursor:not-allowed;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.trend-card-large-pf .trend-header-pf{font-size:16px;font-weight:400;display:block;margin-left:10px}.trend-card-small-pf .trend-header-pf{font-size:12px;font-weight:400;display:block;margin-left:10px}.trend-card-large-pf .trend-title-big-pf{font-size:26px;font-weight:300;margin-left:10px}.trend-card-small-pf .trend-title-big-pf{font-size:17px;font-weight:400;margin-left:10px}.trend-card-large-pf .trend-title-small-pf{font-size:12px;font-weight:400}.trend-card-small-pf .trend-title-small-pf{font-size:10px;font-weight:400}.trend-flat-details{display:table;margin-top:5px}@media (min-width:768px){.trend-flat-details{margin-top:25px}}.trend-flat-details-cell{display:table-cell;vertical-align:bottom;min-width:70px}.trend-header-compact-pf{display:block;font-size:12px;font-weight:400}.trend-title-compact-big-pf{font-size:36px;font-weight:300;line-height:1}.trend-
 title-compact-small-pf{font-size:12px;font-weight:400}.trend-title-flat-big-pf{font-size:26px;font-weight:300;line-height:1;margin-right:15px}.trend-label-flat-pf{font-size:12px;font-weight:400;line-height:1}.trend-label-flat-strong-pf{display:block;font-size:12px;font-weight:700;line-height:1}.trend-footer-pf{font-size:10px;font-weight:400;color:#333;margin-left:10px}.data-unavailable-pf .trend-footer-pf,.data-unavailable-pf [class*=trend-label-],.data-unavailable-pf [class*=trend-title-]{color:transparent}.filter-pf a{cursor:pointer}.filter-pf.filter-fields .form-group{padding-left:0;width:275px}.filter-select .btn-default{font-size:12px;font-style:italic;font-weight:400;background-color:#fff;background-image:none;color:#999}.sort-pf .btn-link{color:#252525;font-size:16px;line-height:1;padding:4px 0;margin-left:10px}.sort-pf .btn-link:hover{color:#0099d3}.input-group .input-group-btn .dropdown-menu>.selected>a{background-color:#0099d3!important;border-color:#0076b7!important;color
 :#fff!important}@media (min-width:768px){.toolbar-pf-actions .toolbar-apf-filter{padding-left:0}}.toolbar-pf-actions .dropdown-menu a,.toolbar-pf-actions .toolbar-pf-view-selector a{cursor:pointer}.toolbar-pf-actions .dropdown-kebab-pf{float:right}.toolbar-pf-include-actions{display:inline-block;margin:0 5px}.dropdown-kebab-pf.invisible{opacity:0;pointer-events:none}.utilization-bar-chart-pf .progress-bar{-webkit-transition:width .75s ease-in-out;-moz-transition:width .75s ease-in-out;-o-transition:width .75s ease-in-out;transition:width .75s ease-in-out}.utilization-bar-chart-pf .progress-bar.animate{width:0!important}.heatmap-pf-container{position:relative}.heatmap-pf-container-pf .loading{position:absolute;top:100px;right:50%;z-index:10}.heatmap-pf-container .heatmap-container{margin-left:-1px}.heatmap-pf-svg{width:100%;height:100%}.heatmap-pf-legend-container{list-style-type:none;margin-top:5px;padding:0;overflow:auto}.heatmap-pf-legend-items{float:left}.legend-pf-color-box{widt
 h:11px;height:11px;margin-left:5px;margin-right:5px;display:inline-block}.legend-pf-color-box:first-of-type{margin-left:0}.legend-pf-text{font-size:11px;font-weight:400;line-height:11px;padding-right:5px}.toolbar-pf-actions.no-filter-results{margin-bottom:10px}accordion>.panel-group .panel-default .panel-title>a:before{content:"\f105"}accordion>.panel-group .panel-open .panel-title>a:before{content:"\f107"}.navbar-brand-txt{line-height:34px}.toast-pf .dropdown-menu>li>a,.toast-pf-action>a{cursor:pointer}.wizard-pf-footer .tooltip-wrapper{border:none;box-shadow:none;display:inline-block;margin-left:5px;padding:0;text-align:center}.wizard-pf-footer .tooltip-wrapper .btn[disabled]{pointer-events:none}.wizard-pf-singlestep{margin-left:0}.wizard-pf-position-override{position:relative}.wizard-pf-footer-inline{text-align:left}.wizard-pf-cancel-inline{margin-left:25px}.pf-expand-placeholder{margin-right:15px}

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/stand-alone/plugin/css/dispatchpf.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatchpf.css b/console/stand-alone/plugin/css/dispatchpf.css
new file mode 100644
index 0000000..23ae0e5
--- /dev/null
+++ b/console/stand-alone/plugin/css/dispatchpf.css
@@ -0,0 +1,144 @@
+/* The following are for matching Patternfly styles */
+span.logo {
+  letter-spacing: 4px;
+}
+
+.navbar-pf .navbar-brand {
+  padding: 2px 0 2px;
+}
+/* using dynatree instead of treeview */
+#overtree ul.dynatree-container,
+#entityTree ul.dynatree-container,
+#schema ul.dynatree-container {
+    background-color: transparent;
+    border: 0px;
+}
+
+span.dynatree-folder a {
+    font-weight: normal;
+    font-size: 12px;
+}
+
+ul.dynatree-container li,
+span.dynatree-icon {
+  background-image: none;
+}
+
+.dynatree-exp-c span.fa-angle, .dynatree-exp-e span.fa-angle,
+.dynatree-exp-cl span.fa-angle, .dynatree-exp-el span.fa-angle {
+  margin-right: 5px;
+}
+.dynatree-exp-c span.fa-angle:before, .dynatree-exp-cl span.fa-angle:before {
+  content: "\f105";
+}
+.dynatree-exp-e span.fa-angle:before, .dynatree-exp-el span.fa-angle:before {
+  content: "\f107";
+}
+
+.dynatree-ico-ef span.dynatree-icon, .dynatree-ico-cf span.dynatree-icon {
+  background-image: initial;
+  font-family: FontAwsome;
+}
+
+.dynatree-ico-cf span.dynatree-icon:before {
+  content: "\f07b";
+}
+.dynatree-ico-ef span.dynatree-icon:before {
+  content: "\f07c";
+}
+
+ul.dynatree-container a {
+    color: #363636;
+}
+
+/* override left and right pane styles */
+#overview-controller .col-sm-3,
+#list-controller .col-sm-3,
+#schema .col-sm-3,
+.qdr-topology-form.col-sm-3 {
+  padding-left: 0px;
+}
+
+.qdr-topology-form.col-sm-3 {
+  padding-right: 0px;
+}
+
+#overview-controller .ngViewport {
+  height: auto !important;
+}
+
+.pane-wrapper {
+  padding-top: 0.5em;
+}
+
+div#list-controller {
+  padding-left: 0px;
+}
+
+.pane-viewport {
+    position: relative;
+}
+
+#list-controller select,
+#list-controller .tree-header {
+    width: 100%;
+}
+
+[class^="icon-"],
+[class*=" icon-"] {
+  display: inline;
+  width: auto;
+  height: auto;
+  line-height: normal;
+  vertical-align: baseline;
+  background-image: none;
+  background-position: 0% 0%;
+  background-repeat: repeat;
+  margin-top: 0;
+}
+[class^="icon-"],
+[class*=" icon-"] {
+  font-family: FontAwesome;
+  font-weight: normal;
+  font-style: normal;
+  text-decoration: inherit;
+  -webkit-font-smoothing: antialiased;
+  *margin-right: .3em;
+}
+
+[class^="icon-"]:before,
+[class*=" icon-"]:before {
+  text-decoration: inherit;
+  display: inline-block;
+  speak: none;
+}
+
+.icon-bar-chart:before {
+    content: "\f080";
+}
+
+.icon-step-forward:before {
+  content: "\f051";
+}
+.icon-step-backward:before {
+  content: "\f048";
+}
+
+[class^="icon-"]:before, [class*=" icon-"]:before {
+    text-decoration: inherit;
+    display: inline-block;
+    speak: none;
+}
+
+#svg_legend {
+  top: 10px;
+}
+
+#topologyForm > div {
+  width: auto;
+}
+
+div.chartContainer {
+  width: auto;
+  margin-top: 1em;
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[4/4] qpid-dispatch git commit: DISPATCH-725 Use patternfly styles for stand-alone console

Posted by ea...@apache.org.
DISPATCH-725 Use patternfly styles for stand-alone console


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/615d7b65
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/615d7b65
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/615d7b65

Branch: refs/heads/master
Commit: 615d7b65f446ff762b7b3a59c586fea57ea0bf53
Parents: 38c02ed
Author: Ernest Allen <ea...@redhat.com>
Authored: Mon Mar 13 11:47:23 2017 -0400
Committer: Ernest Allen <ea...@redhat.com>
Committed: Mon Mar 13 11:47:23 2017 -0400

----------------------------------------------------------------------
 console/stand-alone/plugin/js/navbar.js         | 43 ++++++----
 console/stand-alone/plugin/js/qdrList.js        | 13 ++-
 console/stand-alone/plugin/js/qdrListChart.js   | 12 +--
 console/stand-alone/plugin/js/qdrNewNode.js     | 10 +--
 console/stand-alone/plugin/js/qdrOverview.js    | 75 +++++++++++------
 .../plugin/js/qdrOverviewLogsController.js      |  4 +-
 console/stand-alone/plugin/js/qdrSchema.js      |  7 +-
 console/stand-alone/plugin/js/qdrTopology.js    | 88 +++++++++++---------
 8 files changed, 154 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/navbar.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/navbar.js b/console/stand-alone/plugin/js/navbar.js
index 5125748..0d7baf9 100644
--- a/console/stand-alone/plugin/js/navbar.js
+++ b/console/stand-alone/plugin/js/navbar.js
@@ -34,38 +34,44 @@ var QDR = (function (QDR) {
         content: '<i class="icon-cogs"></i> Connect',
         title: "Connect to a router",
         isValid: function () { return true; },
-        href: "#" + QDR.pluginRoot + "/connect"
+        href: "#!" + QDR.pluginRoot + "/connect",
+        name: "Connect"
     },
     {
-        content: '<i class="icon-home"></i> Overview',
+        content: '<i class="pficon-home"></i> Overview',
         title: "View router overview",
         isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/overview"
+        href: "#!" + QDR.pluginRoot + "/overview",
+        name: "Overview"
       },
     {
         content: '<i class="icon-list "></i> Entities',
         title: "View the attributes of the router entities",
         isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/list"
+        href: "#!" + QDR.pluginRoot + "/list",
+        name: "Entities"
       },
     {
         content: '<i class="icon-star-empty"></i> Topology',
         title: "View router network topology",
         isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/topology"
+        href: "#!" + QDR.pluginRoot + "/topology",
+        name: "Topology"
       },
     {
         content: '<i class="icon-bar-chart"></i> Charts',
         title: "View charts",
         isValid: function (QDRService, $location) { return QDRService.isConnected() && QDR.isStandalone; },
-        href: "#/charts"
+        href: "#!/charts",
+        name: "Charts"
     },
     {
         content: '<i class="icon-align-left"></i> Schema',
         title: "View dispatch schema",
         isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/schema",
-        right: true
+        href: "#!" + QDR.pluginRoot + "/schema",
+        right: true,
+        name: "Schema"
       }
   ];
   /**
@@ -77,17 +83,22 @@ var QDR = (function (QDR) {
    * The controller for this plugin's navigation bar
    *
    */
-  QDR.module.controller("QDR.NavBarController", ['$scope', 'QDRService', 'QDRChartService', '$routeParams', '$location', function($scope, QDRService, QDRChartService, $routeParams, $location) {
+  QDR.module.controller("QDR.NavBarController", ['$rootScope', '$scope', 'QDRService', 'QDRChartService', '$routeParams', '$location', function($rootScope, $scope, QDRService, QDRChartService, $routeParams, $location) {
     $scope.breadcrumbs = QDR.breadcrumbs;
     $scope.isValid = function(link) {
+      if ($scope.isActive(link.href))
+        $rootScope.$broadcast("setCrumb", {name: link.name, title: link.content})
       return link.isValid(QDRService, $location);
     };
 
     $scope.isActive = function(href) {
-    // highlight the connect tab if we are on the root page
-    if (($location.path() === QDR.pluginRoot) && (href.split("#")[1] === QDR.pluginRoot + "/connect"))
-      return true
-        return href.split("#")[1] == $location.path();
+//QDR.log.info("isActive(" + href + ") location.path() is " + $location.path())
+      // highlight the connect tab if we are on the root page
+      if (($location.path() === QDR.pluginRoot) && (href.split("#")[1] === QDR.pluginRoot + "/connect")) {
+//QDR.log.info("isActive is returning true for connect page")
+        return true
+      }
+      return href.split("#")[1] === '!' + $location.path();
     };
 
     $scope.isRight = function (link) {
@@ -123,7 +134,7 @@ var QDR = (function (QDR) {
   }]);
 
   // controller for the edit/configure chart dialog
-  QDR.module.controller("QDR.ChartDialogController", function($scope, QDRChartService, $location, dialog, chart, updateTick, dashboard, adding) {
+  QDR.module.controller("QDR.ChartDialogController", function($scope, QDRChartService, $location, $uibModalInstance, chart, updateTick, dashboard, adding) {
     var dialogSvgChart = null;
     $scope.svgDivId = "dialogEditChart";    // the div id for the svg chart
 
@@ -166,7 +177,7 @@ var QDR = (function (QDR) {
 
     $scope.showChartsPage = function () {
       cleanup();
-      dialog.close(true);
+      $uibModalInstance.close(true);
       $location.path(QDR.pluginRoot + "/charts");
     };
 
@@ -180,7 +191,7 @@ var QDR = (function (QDR) {
     }
     $scope.okClick = function () {
       cleanup();
-      dialog.close(true);
+      $uibModalInstance.close(true);
     };
 
     var initRateSlider = function () {

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrList.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrList.js b/console/stand-alone/plugin/js/qdrList.js
index ec2efb2..0e5ee8f 100644
--- a/console/stand-alone/plugin/js/qdrList.js
+++ b/console/stand-alone/plugin/js/qdrList.js
@@ -28,8 +28,8 @@ var QDR = (function(QDR) {
    *
    * Controller for the main interface
    */
-  QDR.module.controller("QDR.ListController", ['$scope', '$location', '$dialog', '$filter', '$timeout', 'QDRService', 'QDRChartService',
-    function ($scope, $location, $dialog, $filter, $timeout, QDRService, QDRChartService) {
+  QDR.module.controller("QDR.ListController", ['$scope', '$location', '$uibModal', '$filter', '$timeout', 'QDRService', 'QDRChartService',
+    function ($scope, $location, $uibModal, $filter, $timeout, QDRService, QDRChartService) {
 
     var updateIntervalHandle = undefined;
     var updateInterval = 5000;
@@ -675,7 +675,7 @@ var QDR = (function(QDR) {
     }
 
     function doDialog(tmpl, chart) {
-        var d = $dialog.dialog({
+        var d = $uibModal.open({
           backdrop: true,
           keyboard: true,
           backdropClick: true,
@@ -691,7 +691,7 @@ var QDR = (function(QDR) {
               }
         });
 
-        d.open().then(function(result) { console.log("d.open().then"); });
+        d.result.then(function(result) { console.log("d.open().then"); });
 
     };
 
@@ -744,6 +744,7 @@ var QDR = (function(QDR) {
           var e = new Folder(entity)
           e.typeName = "entity"
           e.key = entity
+          e.isFolder = true
           e.expand = (expandedList.indexOf(entity) > -1)
           var placeHolder = new Folder("loading...")
           placeHolder.addClass = "loading"
@@ -769,6 +770,10 @@ var QDR = (function(QDR) {
         autoCollapse: $scope.largeNetwork,
         activeVisible: !$scope.largeNetwork,
         debugLevel: 0,
+        classNames: {
+          expander: 'fa-angle',
+          connector: 'dynatree-no-connector'
+          },
         children: entityTreeChildren
       })
       restartUpdate()

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrListChart.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrListChart.js b/console/stand-alone/plugin/js/qdrListChart.js
index 93391f1..3c14ebf 100644
--- a/console/stand-alone/plugin/js/qdrListChart.js
+++ b/console/stand-alone/plugin/js/qdrListChart.js
@@ -21,7 +21,7 @@ under the License.
  */
 var QDR = (function(QDR) {
 
-  QDR.module.controller('QDR.ListChartController', function ($scope, dialog, $dialog, $location, QDRChartService, chart, nodeName) {
+  QDR.module.controller('QDR.ListChartController', function ($scope, $uibModalInstance, $uibModal, $location, QDRChartService, chart, nodeName) {
     $scope.chart = chart;
     $scope.dialogSvgChart = null;
     var updateTimer = null;
@@ -29,14 +29,14 @@ var QDR = (function(QDR) {
 
     $scope.showChartsPage = function () {
       cleanup();
-      dialog.close(true);
+      $uibModalInstance.close(true);
       $location.path(QDR.pluginRoot + "/charts");
     };
 
     $scope.addHChart = function () {
       QDRChartService.addHDash($scope.chart);
       cleanup();
-      dialog.close(true);
+      $uibModalInstance.close(true);
     }
 
     $scope.addToDashboardLink = function () {
@@ -100,7 +100,7 @@ var QDR = (function(QDR) {
     }
     $scope.ok = function () {
       cleanup();
-      dialog.close(true);
+      $uibModalInstance.close(true);
       };
 
     $scope.editChart = function () {
@@ -109,7 +109,7 @@ var QDR = (function(QDR) {
 
     function doDialog(template, chart) {
 
-      $dialog.dialog({
+      var d = $uibModal.open({
       backdrop: true,
       keyboard: true,
       backdropClick: true,
@@ -129,7 +129,7 @@ var QDR = (function(QDR) {
           return true
         }
       }
-      }).open().then(function(result) {
+      }).result.then(function(result) {
         $scope.ok()
       });
     };

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrNewNode.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrNewNode.js b/console/stand-alone/plugin/js/qdrNewNode.js
index f6d035a..48af70f 100644
--- a/console/stand-alone/plugin/js/qdrNewNode.js
+++ b/console/stand-alone/plugin/js/qdrNewNode.js
@@ -21,7 +21,7 @@ under the License.
  */
 var QDR = (function(QDR) {
 
-  QDR.module.controller("QDR.NodeDialogController", function($scope, QDRService, dialog, newname) {
+  QDR.module.controller("QDR.NodeDialogController", function($scope, QDRService, $uibModalInstance, newname) {
     var schema = QDRService.schema;
     var myEntities = ['router', 'log', 'listener'];
     var typeMap = {
@@ -298,13 +298,13 @@ var QDR = (function(QDR) {
       // handle the download button click
       // copy the dialog's values to the original node
     $scope.download = function() {
-      dialog.close({
+      $uibModalInstance.close({
         entities: $scope.entities,
         annotations: annotations
       });
     }
     $scope.cancel = function() {
-      dialog.close()
+      $uibModalInstance.close()
     };
 
     $scope.selectAnnotationTab = function(tabName) {
@@ -327,7 +327,7 @@ var QDR = (function(QDR) {
 
   });
 
-  QDR.module.controller("QDR.DownloadDialogController", function($scope, QDRService, $templateCache, $window, dialog, results) {
+  QDR.module.controller("QDR.DownloadDialogController", function($scope, QDRService, $templateCache, $window, $uibModalInstance, results) {
     var result = results.entities;
     var annotations = results.annotations;
     var annotationKeys = Object.keys(annotations);
@@ -437,7 +437,7 @@ var QDR = (function(QDR) {
     }
 
     $scope.done = function() {
-      dialog.close();
+      $uibModalInstance.close();
     }
   });
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrOverview.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrOverview.js b/console/stand-alone/plugin/js/qdrOverview.js
index f612847..303a91d 100644
--- a/console/stand-alone/plugin/js/qdrOverview.js
+++ b/console/stand-alone/plugin/js/qdrOverview.js
@@ -34,7 +34,7 @@ var QDR = (function (QDR) {
    *
    * Controller that handles the QDR overview page
    */
-  QDR.module.controller("QDR.OverviewController", ['$scope', 'QDRService', '$location', '$timeout', '$dialog', function($scope, QDRService, $location, $timeout, $dialog) {
+  QDR.module.controller("QDR.OverviewController", ['$scope', 'QDRService', '$location', '$timeout', '$uibModal', function($scope, QDRService, $location, $timeout, $uibModal) {
 
     console.log("QDR.OverviewControll started with location of " + $location.path() + " and connection of  " + QDRService.connected);
     var COLUMNSTATEKEY = 'QDRColumnKey.';
@@ -515,6 +515,16 @@ var QDR = (function (QDR) {
     $scope.totalLinks = 0;
     $scope.pagedLinkData = []
     $scope.selectedLinks = []
+
+    var linkRowTmpl = `
+      <div ng-class="{linkDirIn: row.getProperty('linkDir') == 'in', linkDirOut: row.getProperty('linkDir') == 'out'}">
+        <div ng-style="{ 'cursor': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}}">
+          <div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }">&nbsp;</div>
+          <div ng-cell></div>
+        </div>
+      </div>
+    `;
+
     $scope.linksGrid = {
       saveKey: 'linksGrid',
       data: 'pagedLinkData',
@@ -591,8 +601,7 @@ var QDR = (function (QDR) {
       enableColumnResize: true,
       enableColumnReordering: true,
       showColumnMenu: true,
-      rowTemplate: 'linkRowTemplate.html',
-      // aggregateTemplate: "linkAggTemplate.html",
+      rowTemplate: linkRowTmpl,
       multiSelect: false,
       selectedItems: $scope.selectedLinks,
       plugins: [new ngGridFlexibleHeightPlugin()],
@@ -616,6 +625,7 @@ var QDR = (function (QDR) {
         })
 
     var loadColState = function (grid) {
+return;
       if (!grid)
         return;
       var columns = localStorage.getItem(COLUMNSTATEKEY+grid.saveKey);
@@ -1236,29 +1246,32 @@ QDR.log.debug("setting linkFields to [] in selectMode")
     }
 
     function logDialog(row, col) {
-        var d = $dialog.dialog({
-          backdrop: false,
-          keyboard: true,
-          backdropClick: false,
-          templateUrl: 'viewLogs.html',
-          controller: "QDR.OverviewLogsController",
-          resolve: {
-            nodeName: function () {
-              return row.entity.nodeName
-            },
-            module: function () {
-              return row.entity.name
-            },
-            level: function () {
-              return col.displayName
-            },
-            nodeId: function () {
-              return row.entity.nodeId
-            },
-          }
-        });
-        d.open().then(function(result) { console.log("d.open().then"); });
-    };
+      var d = $uibModal.open({
+      animation: true,
+      templateUrl: 'viewLogs.html',
+      controller: 'QDR.OverviewLogsController',
+      resolve: {
+        nodeName: function () {
+          return row.entity.nodeName
+        },
+        module: function () {
+          return row.entity.name
+        },
+        level: function () {
+          return col.displayName
+        },
+        nodeId: function () {
+          return row.entity.nodeId
+        },
+      }
+    });
+
+    d.result.then(function (result) {
+      console.log("d.open().then");
+    }, function () {
+      console.log('Modal dismissed at: ' + new Date());
+    });
+  };
 
     var numberTemplate = '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD | pretty}}</span></div>'
     $scope.allLogFields = []
@@ -1524,6 +1537,7 @@ QDR.log.debug("setting linkFields to [] in selectMode")
       })
       $scope.template = template[0];
     }
+    $scope.template = $scope.templates[0]
     // activated is called each time a tree node is clicked
     // based on which node is clicked, load the correct data grid template and start getting the data
     var activated = function (node) {
@@ -1608,6 +1622,7 @@ QDR.log.debug("newly created node needs to be activated")
     routers.key = "Routers"
     routers.parent = "Routers"
     routers.addClass = "routers"
+    routers.isFolder = true
     topLevelChildren.push(routers)
     // called when the list of routers changes
     var updateRouterTree = function (nodes) {
@@ -1636,6 +1651,7 @@ QDR.log.debug("newly created node needs to be activated")
     addresses.key = "Addresses"
     addresses.parent = "Addresses"
     addresses.addClass = "addresses"
+    addresses.isFolder = true
     topLevelChildren.push(addresses)
     var updateAddressTree = function (addressFields) {
       var worker = function (address) {
@@ -1677,6 +1693,7 @@ QDR.log.debug("newly created node needs to be activated")
     links.key = "Links"
     links.parent = "Links"
     links.addClass = "links"
+    links.isFolder = true
     topLevelChildren.push(links)
 
     // called both before the tree is created and whenever a background update is done
@@ -1709,6 +1726,7 @@ QDR.log.debug("newly created node needs to be activated")
     connections.key = "Connections"
     connections.parent = "Connections"
     connections.addClass = "connections"
+    connections.isFolder = true
     topLevelChildren.push(connections)
 
     updateConnectionTree = function (connectionFields) {
@@ -1756,6 +1774,7 @@ QDR.log.debug("newly created node needs to be activated")
     logs.clickFolderMode = 1
     logs.key = "Logs"
     logs.parent = "Logs"
+    logs.isFolder = true
     if (QDRService.versionCheck('0.8.0'))
       topLevelChildren.push(logs)
     var initTreeAndGrid = function () {
@@ -1773,6 +1792,10 @@ QDR.log.debug("newly created node needs to be activated")
         activeVisible: !$scope.largeNetwork,
         selectMode: 1,
         debugLevel: 0,
+        classNames: {
+          expander: 'fa-angle',
+          connector: 'dynatree-no-connector'
+          },
         children: topLevelChildren
       })
       treeRoot = $("#overtree").dynatree("getRoot");

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrOverviewLogsController.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrOverviewLogsController.js b/console/stand-alone/plugin/js/qdrOverviewLogsController.js
index fed1e3d..832d8aa 100644
--- a/console/stand-alone/plugin/js/qdrOverviewLogsController.js
+++ b/console/stand-alone/plugin/js/qdrOverviewLogsController.js
@@ -21,7 +21,7 @@ under the License.
  */
 var QDR = (function(QDR) {
 
-  QDR.module.controller('QDR.OverviewLogsController', function ($scope, dialog, QDRService, $timeout, nodeName, nodeId, module, level) {
+  QDR.module.controller('QDR.OverviewLogsController', function ($scope, $uibModalInstance, QDRService, $timeout, nodeName, nodeId, module, level) {
 
       var gotLogInfo = function (nodeId, entity, response, context) {
         var statusCode = context.message.application_properties.statusCode;
@@ -58,7 +58,7 @@ var QDR = (function(QDR) {
     $scope.nodeName = nodeName
     $scope.logFields = []
     $scope.ok = function () {
-      dialog.close(true);
+      $uibModalInstance.close(true);
     };
 
   });

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrSchema.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrSchema.js b/console/stand-alone/plugin/js/qdrSchema.js
index 656b159..d73e265 100644
--- a/console/stand-alone/plugin/js/qdrSchema.js
+++ b/console/stand-alone/plugin/js/qdrSchema.js
@@ -52,6 +52,7 @@ var QDR = (function (QDR) {
 		var tree = []
 		for (var key in QDRService.schema) {
 			var kid = {title: key}
+      kid.isFolder = true
 			var val = QDRService.schema[key]
 			if (val === Object(val))
 				keys2kids(kid, val)
@@ -62,7 +63,11 @@ var QDR = (function (QDR) {
 		}
         $('#schema').dynatree({
 			minExpandLevel: 2,
-            children: tree
+      classNames: {
+        expander: 'fa-angle',
+        connector: 'dynatree-no-connector'
+        },
+      children: tree
         })
 
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/615d7b65/console/stand-alone/plugin/js/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrTopology.js b/console/stand-alone/plugin/js/qdrTopology.js
index 9899393..23da1bb 100644
--- a/console/stand-alone/plugin/js/qdrTopology.js
+++ b/console/stand-alone/plugin/js/qdrTopology.js
@@ -21,8 +21,9 @@ under the License.
  */
 var QDR = (function(QDR) {
 
-  QDR.module.controller('QDR.TopologyFormController', function($scope, QDRService) {
+  QDR.module.controller('QDR.TopologyFormController', function($scope, $rootScope, $timeout, QDRService) {
 
+    $scope.panelVisible = true  // show/hide the panel on the left
     $scope.attributes = []
     var nameTemplate = '<div title="{{row.entity.description}}" class="ngCellText {{row.entity.cls}}"><span>{{row.entity.attributeName}}</span></div>';
     var valueTemplate = '<div title="{{row.entity.attributeValue}}" class="ngCellText {{row.entity.cls}}"><span>{{row.entity.attributeValue}}</span></div>';
@@ -40,18 +41,18 @@ var QDR = (function(QDR) {
         cellTemplate: valueTemplate
       }]
     };
-    $scope.form = ''
+    $scope.form = 'router'
     $scope.$on('showEntityForm', function(event, args) {
       var attributes = args.attributes;
       var entityTypes = QDRService.schema.entityTypes[args.entity].attributes;
       attributes.forEach(function(attr) {
         attr.cls = ''
-QDR.log.debug("attr.description " + attr.description)
         if (attr.attributeName === 'Listening on')
           attr.cls = 'listening-on'
         if (entityTypes[attr.attributeName] && entityTypes[attr.attributeName].description) {
           attr.description = entityTypes[attr.attributeName].description
         }
+        //QDR.log.debug("attr.description " + attr.description)
       })
       $scope.attributes = attributes;
       $scope.form = args.entity;
@@ -59,6 +60,41 @@ QDR.log.debug("attr.description " + attr.description)
     $scope.$on('showAddForm', function(event) {
       $scope.form = 'add';
     })
+
+    $scope.hideLeftPane = function () {
+      d3.select(".qdr-topology-form")
+        .transition().duration(300).ease("sin-in")
+        .style("left" , "-309px")
+        .each("end", function () {
+          $timeout(function () {
+            QDR.log.debug("done with transition. setting scope ");
+            $scope.panelVisible = false
+            $rootScope.$broadcast('panel-resized')
+        })
+/*
+      d3.select(".qdr-topology-svg")
+        .transition().duration(300).ease("sin-in")
+        .style("margin-left", "30px")
+        .each("end", function () {
+          resize()
+          $timeout(function () {QDR.log.debug("done with transition. setting scope ");$scope.panelVisible = false})
+        })
+*/
+    })}
+
+    $scope.showLeftPane = function () {
+      d3.select(".qdr-topology-form")
+        .transition().duration(300).ease("sin-out")
+        .style("left" , "0px")
+
+      d3.select(".qdr-topology-svg")
+        .transition().duration(300).ease("sin-out")
+        .style("margin-left", "430px")
+        .each("end", function () {
+          resize()
+          $timeout(function () {QDR.log.debug("done with transition. setting scope ");$scope.panelVisible = true})
+        })
+    }
   })
 
   /**
@@ -66,41 +102,14 @@ QDR.log.debug("attr.description " + attr.description)
    *
    * Controller that handles the QDR topology page
    */
-  QDR.module.controller("QDR.TopologyController", ['$scope', '$rootScope', 'QDRService', '$location', '$timeout', '$dialog',
-    function($scope, $rootScope, QDRService, $location, $timeout, $dialog) {
+  QDR.module.controller("QDR.TopologyController", ['$scope', '$rootScope', 'QDRService', '$location', '$timeout', '$uibModal',
+    function($scope, $rootScope, QDRService, $location, $timeout, $uibModal) {
 
-      $scope.panelVisible = true  // show/hide the panel on the left
       $scope.multiData = []
       $scope.selectedClient = [];
       $scope.quiesceState = {}
       var dontHide = false;
 
-      $scope.hideLeftPane = function () {
-        d3.select(".qdr-topology.pane.left")
-          .transition().duration(300).ease("sin-in")
-          .style("left" , "-380px")
-
-        d3.select(".panel-adjacent")
-          .transition().duration(300).ease("sin-in")
-          .style("margin-left", "30px")
-          .each("end", function () {
-            resize()
-            $timeout(function () {QDR.log.debug("done with transition. setting scope ");$scope.panelVisible = false})
-          })
-      }
-      $scope.showLeftPane = function () {
-        d3.select(".qdr-topology.pane.left")
-          .transition().duration(300).ease("sin-out")
-          .style("left" , "0px")
-
-        d3.select(".panel-adjacent")
-          .transition().duration(300).ease("sin-out")
-          .style("margin-left", "430px")
-          .each("end", function () {
-            resize()
-            $timeout(function () {QDR.log.debug("done with transition. setting scope ");$scope.panelVisible = true})
-          })
-      }
       $scope.quiesceConnection = function(row) {
         var entity = row.entity;
         var state = $scope.quiesceState[entity.connectionId].state;
@@ -335,7 +344,6 @@ QDR.log.debug("attr.description " + attr.description)
       ];
       $scope.mode = "Diagram";
       $scope.contextNode = null; // node that is associated with the current context menu
-
       $scope.isModeActive = function(name) {
         if ((name == 'Add Router' || name == 'Diagram') && $scope.addingNode.step > 0)
           return true;
@@ -547,6 +555,10 @@ QDR.log.debug("attr.description " + attr.description)
           force.size(sizes).resume();
         }
       }
+
+      $scope.$on('panel-resized', function () {
+        resize()
+      })
       window.addEventListener('resize', resize);
       var sizes = getSizes()
       width = sizes[0]
@@ -990,7 +1002,7 @@ QDR.log.debug("attr.description " + attr.description)
                 });
               }
             }
-            $scope.$broadcast('showEntityForm', {
+            $rootScope.$broadcast('showEntityForm', {
               entity: entity,
               attributes: attributes
             })
@@ -2113,7 +2125,7 @@ QDR.log.debug("attr.description " + attr.description)
 
       function doAddDialog(NewRouterName) {
         QDRService.ensureAllEntities({entity: ".listener"}, function () {
-          var d = $dialog.dialog({
+          var d = $uibModal.open({
             dialogClass: "modal dlg-large",
             backdrop: true,
             keyboard: true,
@@ -2127,7 +2139,7 @@ QDR.log.debug("attr.description " + attr.description)
             }
           });
           $timeout(function () {
-            d.open().then(function(result) {
+            d.result.then(function(result) {
               if (result)
                 doDownloadDialog(result);
             });
@@ -2136,7 +2148,7 @@ QDR.log.debug("attr.description " + attr.description)
       };
 
       function doDownloadDialog(result) {
-        d = $dialog.dialog({
+        d = $uibModal.open({
           backdrop: true,
           keyboard: true,
           backdropClick: true,
@@ -2148,7 +2160,7 @@ QDR.log.debug("attr.description " + attr.description)
             }
           }
         });
-        d.open().then(function(result) {
+        d.result.then(function(result) {
           //QDR.log.debug("download dialog done")
         })
         if (!$scope.$$phase) $scope.$apply()


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[3/4] qpid-dispatch git commit: DISPATCH-725 Use patternfly styles for stand-alone console

Posted by ea...@apache.org.
DISPATCH-725 Use patternfly styles for stand-alone console


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/38c02edf
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/38c02edf
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/38c02edf

Branch: refs/heads/master
Commit: 38c02edfd381db70ae545c94be1352aa24da36b6
Parents: 1a59f1f
Author: Ernest Allen <ea...@redhat.com>
Authored: Mon Mar 13 11:45:23 2017 -0400
Committer: Ernest Allen <ea...@redhat.com>
Committed: Mon Mar 13 11:45:23 2017 -0400

----------------------------------------------------------------------
 .../src/main/webapp/plugin/html/qdrConnect.html |  75 ++++++-
 .../src/main/webapp/plugin/html/qdrLayout.html  |  27 ++-
 .../src/main/webapp/plugin/html/qdrList.html    |  93 +++++++-
 .../main/webapp/plugin/html/qdrOverview.html    | 211 ++++++++++++++++++-
 .../src/main/webapp/plugin/html/qdrSchema.html  |  22 +-
 .../main/webapp/plugin/html/qdrTopology.html    | 201 +++++++++++++++++-
 .../main/webapp/plugin/html/tmplListTree.html   |  22 +-
 .../angular-patternfly/LICENSE.txt              | 205 ++++++++++++++++++
 .../dist/angular-patternfly.min.js              |   4 +
 .../dist/styles/angular-patternfly.min.css      |   1 +
 console/stand-alone/plugin/css/dispatchpf.css   | 144 +++++++++++++
 11 files changed, 998 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html b/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
deleted file mode 120000
index 2eb3530..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrConnect.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html b/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
new file mode 100644
index 0000000..8a73177
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
@@ -0,0 +1,74 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div class="row-fluid" ng-controller="QDR.SettingsController">
+      <div class="login container" ng-hide="connecting">
+          <div class="row" id="dispatch-login-container">
+              <div class="connect-column">
+                  <div class="alert alert-success">
+                      <p>
+                          Enter the address and a HTML-enabled port of a <strong><a href="http://qpid.apache.org/components/dispatch-router/" target="_blank">Qpid Dispatch Router</a></strong> to connect..
+                      </p>
+                      <p>
+                          If Autostart is checked, you will be automatically logged in to the router the next time you start the console.
+                      </p>
+
+                  </div>
+              </div>
+              <div class="connect-column connect-form">
+                  <form class="hawtio-form form-horizontal no-bottom-margin" novalidate ng-submit="connect()" name="settings">
+                      <fieldset>
+                          <div class="control-group">
+                              <label class="strong control-label">Address: </label>
+                              <div class="controls">
+                                  <input tabindex="1" type="text" ng-model="formEntity.address" placeholder="localhost" name="address" autofocus="autofocus" class="ng-pristine ng-valid ng-valid-required"></div>
+                          </div>
+                          <div class="control-group">
+                              <label tabindex="-1" class="control-label" title="Ports to connect to, by default 5673">Port: </label>
+                              <div class="controls">
+                                  <input tabindex="2" posint type="number" placeholder="5673" tooltip="Ports to connect to, by default 5673" ng-model="formEntity.port" name="port" title="Ports to connect to, by default 5673">
+                                  <span ng-show="settings.port.$error.range">Must be 1 through 65535</span>
+                              </div>
+                          </div>
+                          <div class="control-group">
+                              <label tabindex="-1" class="control-label" title="Whether or not the connection should be started as soon as you log into hawtio">Autostart: </label>
+                              <div class="controls">
+                                  <input tabindex="3" type="checkbox" tooltip="Whether or not the connection should be started as soon as you log into hawtio" ng-model="formEntity.autostart" name="autostart" title="Whether or not the connection should be started as soon as you log into hawtio"
+                                         class="ng-scope ng-pristine ng-valid"></div>
+                          </div>
+                          <input tabindex="-1" type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;">
+                          <p></p>
+                          <div>
+                              <button type="submit" tabindex="4" class="btn btn-primary pull-right" ng-disabled="settings.$invalid">{{buttonText()}}</button>
+                              <!-- <button tabindex="-1" class="btn btn-secondary pull-right" ng-click="connect1()">Debug</button> -->
+                          </div>
+                      </fieldset>
+                  </form>
+              </div>
+          </div>
+      </div>
+
+      <div class="centered" ng-show="connecting">
+        <i class="icon-spin icon-spinner icon-4x"></i>
+        <p>Please wait, connecting now...</p>
+      </div>
+      <div class="centered" ng-show="connectionError">
+        <p>There was a connection error: {{connectionErrorText}}</p>
+      </div>
+
+</div>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html b/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
deleted file mode 120000
index f4caaf6..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrLayout.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html b/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
new file mode 100644
index 0000000..208e390
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<ul class="nav nav-tabs connected dispatch-view" ng-controller="QDR.NavBarController">
+  <li ng-repeat="link in breadcrumbs" title="{{link.title}}" ng-show="isValid(link)" ng-class='{active : isActive(link.href), "pull-right" : isRight(link), haschart: hasChart(link)}'>
+    <a ng-href="{{link.href}}{{hash}}" ng-bind-html-unsafe="link.content"></a>
+  </li>
+</ul>
+<div class="row-fluid dispatch-router">
+  <div ng-view></div>
+</div>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrList.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrList.html b/console/hawtio/src/main/webapp/plugin/html/qdrList.html
deleted file mode 120000
index 843a1ef..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrList.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrList.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrList.html b/console/hawtio/src/main/webapp/plugin/html/qdrList.html
new file mode 100644
index 0000000..e6f0d3c
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrList.html
@@ -0,0 +1,92 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div id="list-controller" ng-controller="QDR.ListController"  ng-include="tmplListTree"></div>
+
+<script type="text/ng-template" id="listGrid.html">
+    <div class="row-fluid qdrListActions">
+        <ul class="nav nav-tabs">
+            <li ng-repeat="mode in modes" ng-show="isValid(mode)" ng-click="selectMode(mode)" ng-class="{active : isModeSelected(mode)}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
+        </ul>
+        <h4>{{selectedRecordName}}</h4>
+        <div ng-show="currentMode.id === 'attributes'" class="selectedItems">
+            <div ng-show="selectedRecordName === selectedEntity" class="no-content">There are no {{selectedEntity | safePlural}}</div>
+            <div ng-hide="selectedRecordName === selectedEntity" ng-grid="details"></div>
+        </div>
+        <div ng-show="currentMode.id === 'delete'">
+            <div class="delete" ng-show="selectedRecordName !== selectedEntity">
+                <button class="btn btn-primary" ng-click="remove()">Delete</button> {{selectedRecordName}}
+            </div>
+            <div ng-hide="selectedRecordName !== selectedEntity">
+                There are no {{selectedEntity | safePlural}}
+            </div>
+        </div>
+        <div class="operations" ng-show="currentMode.id === 'operations'">
+            <fieldset ng-show="operation != ''">
+                <table>
+                    <tr>
+                        <th>Attribute</th>
+                        <th>Value</th>
+                    </tr>
+                <tr title="{{attribute.title}}" ng-repeat="attribute in detailFields">
+                    <td><label for="{{attribute.name}}">{{attribute.name | humanify}}</label></td>
+                    <!-- we can't do <input type="{angular expression}"> because... jquery throws an exception because... -->
+                    <td>
+                    <div ng-if="attribute.input == 'input'">
+                        <!-- ng-pattern="testPattern(attribute)" -->
+                        <input ng-if="attribute.type == 'number'" type="number" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.rawValue" ng-required="attribute.required" class="ui-widget-content ui-corner-all"/>
+                        <input ng-if="attribute.type == 'text'" type="text" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.attributeValue" ng-required="attribute.required" class="ui-widget-content ui-corner-all"/>
+                        <textarea ng-if="attribute.type == 'textarea'" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.attributeValue" ng-required="attribute.required" class="ui-widget-content ui-corner-all"></textarea>
+                        <span ng-if="attribute.type == 'disabled'" >{{getAttributeValue(attribute)}}</span>
+                    </div>
+                    <div ng-if="attribute.input == 'select'">
+                        <select id="{{attribute.name}}" ng-model="attribute.selected" ng-options="item for item in attribute.rawtype track by item"></select>
+                    </div>
+                    <div ng-if="attribute.input == 'boolean'" class="boolean">
+                        <label><input type="radio" ng-model="attribute.rawValue" ng-value="true"> True</label>
+                        <label><input type="radio" ng-model="attribute.rawValue" ng-value="false"> False</label>
+                    </div>
+                    </td>
+                </tr>
+                <tr><td></td><td><button class="btn btn-primary" type="button" ng-click="ok()">{{operation | Pascalcase}}</button></td></tr>
+                </table>
+            </fieldset>
+        </div>
+        <div ng-show="currentMode.id === 'log'">
+            <div ng-if="logResults.length > 0">
+                <table class="log-entry" ng-repeat="entry in logResults track by $index">
+                    <tr>
+                        <td align="left" colspan="2">{{entry.time}}</td>
+                    </tr>
+                    <tr>
+                        <td>Type</td><td>{{entry.type}}</td>
+                    </tr>
+                    <tr>
+                        <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
+                    </tr>
+                    <tr>
+                        <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
+                    </tr>
+                </table>
+            </div>
+            <div ng-if="logResults.length == 0 && !fetchingLog">No log entries for {{selectedRecordName}}</div>
+            <div ng-if="fetchingLog">Fetching logs for {{selectedRecordName}}</div>
+        </div>
+    </div>
+</script>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html b/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
deleted file mode 120000
index 3c33d8a..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrOverview.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html b/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
new file mode 100644
index 0000000..812fc45
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
@@ -0,0 +1,210 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div id="overview-controller" ng-controller="QDR.OverviewController" ng-include="tmplOverviewTree"></div>
+<script type="text/ng-template" id="overviewGrid.html">
+    <div class="gridDetails" ng-include="template.url"></div>
+</script>
+
+
+<!-- the following scripts are content that gets loaded into the above div that has the temple.url -->
+<script type="text/ng-template" id="routers.html">
+    <div class="row-fluid">
+        <h3>Routers</h3>
+        <div class="overview">
+            <div class="gridStyle" ng-grid="allRouters"></div>
+        </div>
+    </div>
+</script>
+<script type="text/ng-template" id="router.html">
+    <div class="row-fluid">
+        <h3>Router {{router.data.title}} attributes</h3>
+        <div class="gridStyle noHighlight" ng-grid="routerGrid"></div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="addresses.html">
+    <div class="row-fluid">
+        <h3>Addresses</h3>
+        <div class="overview">
+            <div class="gridStyle" ng-grid="addressesGrid"></div>
+        </div>
+    </div>
+</script>
+<script type="text/ng-template" id="address.html">
+    <div class="row-fluid">
+        <ul class="nav nav-tabs">
+            <li ng-repeat="mode in gridModes" ng-click="selectMode(mode,'Address')" ng-class="{active : isModeSelected(mode,'Address')}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
+        </ul>
+        <div ng-if="isModeVisible('Address','attributes')" class="selectedItems">
+            <h3>Address {{address.data.title}}</h3>
+            <div class="gridStyle noHighlight" ng-grid="addressGrid"></div>
+        </div>
+        <div ng-if="isModeVisible('Address','links')" class="selectedItems">
+            <h3>Links for address {{address.data.title}}</h3>
+            <div class="gridStyle" ng-grid="linksGrid"></div>
+        </div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="links.html">
+    <div class="row-fluid">
+        <h3>Links <button type='button' ng-click="filterToggle()" class='btn btn-secondary btn-filter'>Filter</button></h3>
+        <div id="linkFilter">
+            <div class="filter-title">
+                <h6>Filter links</h6>
+                <button ng-click="filterToggle()" type="button" class="btn btn-primary filter-close">x</button>
+            </div>
+            <div class="formLine"><label for="hideConsoles">Hide console links</label><input name="hideConsoles" id="hideConsoles" type="checkbox" ng-model="filter.hideConsoles"/></div>
+            <div class="formLine"><label for="endpointOnly">Endpoints only</label><input name="linkTypes" id="endpointOnly" type="radio" ng-model="filter.endpointsOnly" value="true"/>
+                <label for="allLinks">All link types</label><input name="linkTypes" id="allLinks" type="radio" ng-model="filter.endpointsOnly" value="false"/></div>
+        </div>
+        <div class="gridStyle" ng-grid="linksGrid"></div>
+    </div>
+</script>
+<script type="text/ng-template" id="link.html">
+    <div class="row-fluid">
+        <h3>Link {{link.data.title}}</h3>
+        <div class="gridStyle noHighlight" ng-grid="linkGrid"></div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="connections.html">
+    <div class="row-fluid">
+        <h3>Connections</h3>
+        <div class="overview">
+            <div class="gridStyle" ng-grid="allConnectionGrid"></div>
+        </div>
+    </div>
+</script>
+<script type="text/ng-template" id="connection.html">
+    <div class="row-fluid">
+        <ul class="nav nav-tabs">
+            <li ng-repeat="mode in gridModes" ng-click="selectMode(mode,'Connection')" ng-class="{active : isModeSelected(mode,'Connection')}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
+        </ul>
+        <div ng-if="isModeVisible('Connection','attributes')" class="selectedItems">
+            <h3>Connection {{connection.data.title}}</h3>
+            <div class="gridStyle noHighlight" ng-grid="connectionGrid"></div>
+        </div>
+        <div ng-if="isModeVisible('Connection','links')" class="selectedItems">
+            <h3>Links for connection {{connection.data.title}}</h3>
+            <div class="gridStyle" ng-grid="linksGrid"></div>
+        </div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="titleHeaderCellTemplate.html">
+    <div title="{{col.displayName}}" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{'cursor': col.cursor}" ng-class="{ 'ngSorted': !noSortVisible }">
+        <div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText">{{col.displayName}}</div>
+        <div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>
+        <div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>
+        <div class="ngSortPriority">{{col.sortPriority}}</div>
+    </div>
+</script>
+<script type="text/ng-template" id="titleCellTemplate.html">
+    <div title="{{row.entity[col.field]}}" class="ngCellText">{{row.entity[col.field]}}</div>
+</script>
+<script type="text/ng-template" id="logs.html">
+    <div class="row-fluid">
+        <h3>Recent log events</h3>
+        <div class="overview">
+            <div class="gridStyle" ng-grid="allLogGrid"></div>
+        </div>
+    </div>
+</script>
+<script type="text/ng-template" id="logModule.html">
+    <div class="row-fluid">
+        <h3>{{logModule.module}} events</h3>
+        <div class="overview-cell">
+            <div class="gridStyle" ng-grid="logModuleGrid"></div>
+        </div>
+    </div>
+</script>
+<script type="text/ng-template" id="log.html">
+    <div class="row-fluid">
+        <h3>{{log.data.title}}</h3>
+        <div ng-if="logFields.length > 0">
+            <table class="log-entry" ng-repeat="entry in logFields track by $index">
+                <tr>
+                    <td>Router</td><td>{{entry.nodeId}}</td>
+                </tr>
+                <tr>
+                    <td align="left" colspan="2">{{entry.time}}</td>
+                </tr>
+                <tr>
+                    <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
+                </tr>
+                <tr>
+                    <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
+                </tr>
+            </table>
+        </div>
+        <div ng-if="logFields.length == 0">No log entries for {{log.data.title}}</div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="linkRowTemplate.html">
+    <div ng-class="{linkDirIn: row.getProperty('linkDir') == 'in', linkDirOut: row.getProperty('linkDir') == 'out'}">
+        <div ng-style="{ 'cursor': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}}">
+            <div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }">&nbsp;</div>
+            <div ng-cell></div>
+        </div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="linkAggTemplate.html">
+    <div ng-click='row.toggleExpand(); saveGroupState()' ng-style='rowStyle(row)' class='ngAggregate ng-scope' style='top: 0px; height: 48px; left: 0px;'>
+    <span class='ngAggregateText ng-binding'>
+            {{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})
+        </span>
+    <div ng-class="{true: 'ngAggArrowCollapsed', false: 'ngAggArrowExpanded'}[row.collapsed]"></div>
+    </div>
+</script>
+
+<script type="text/ng-template" id="viewLogs.html">
+    <div class="modal-header">
+        <h3 class="modal-title">Logs for {{nodeName}} {{module}}:{{level | humanify}}</h3>
+    </div>
+    <div class="modal-body">
+        <div ng-if="loading == false">
+            <div class="log-details" ng-if="logFields.length > 0">
+                <table class="log-entry" ng-repeat="entry in logFields track by $index">
+                    <tr>
+                        <td>Router</td><td>{{entry.nodeId}}</td>
+                    </tr>
+                    <tr>
+                        <td align="left" colspan="2">{{entry.time}}</td>
+                    </tr>
+                    <tr>
+                        <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
+                    </tr>
+                    <tr>
+                        <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
+                    </tr>
+                </table>
+            </div>
+            <div ng-if="logFields.length == 0">No log entries</div>
+        </div>
+        <div ng-if="loading == true">
+            Loading...
+        </div>
+    </div>
+    <div class="modal-footer">
+        <button class="btn btn-primary" type="button" ng-click="ok()">Close</button>
+    </div>
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html b/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
deleted file mode 120000
index 7f9422e..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrSchema.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html b/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
new file mode 100644
index 0000000..33f6951
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
@@ -0,0 +1,21 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div class="main-display row-fluid" ng-controller="QDR.SchemaController">
+    <div id="schema"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html b/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
deleted file mode 120000
index 9dc2f21..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/qdrTopology.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html b/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
new file mode 100644
index 0000000..31afe1f
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
@@ -0,0 +1,200 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div class="qdrTopology row-fluid" ng-controller="QDR.TopologyController">
+    <div class="qdr-topology pane left" ng-controller="QDR.TopologyFormController">
+        <div id="topologyForm" ng-class="{selected : isSelected()}">
+            <!-- <div ng-repeat="form in forms" ng-show="isVisible(form)" ng-class='{selected : isSelected(form)}'> -->
+            <div ng-show="form == 'router'">
+                <h4>Router Info</h4>
+                <div class="gridStyle" ng-grid="topoGridOptions"></div>
+            </div>
+            <div ng-show="form == 'connection'">
+                <h4>Connection Info</h4>
+                <div class="gridStyle" ng-grid="topoGridOptions"></div>
+            </div>
+            <div id="addNodeForm" ng-show="form == 'add'">
+                <h4>Add a new router</h4>
+                <ul>
+                    <li>Click on an existing router to create a connection to the new router</li>
+                    <li>Double-click on the new router to <button ng-click="editNewRouter()">edit</button> its properties</li>
+                    <li ng-show="addingNode.hasLink" >Right-click on a new connection to edit its properties</li>
+                </ul>
+                <button ng-click="cancel()">Cancel</button>
+            </div>
+        </div>
+        <button ng-if="panelVisible" ng-click="hideLeftPane()" class="hideLeft" title="Hide"><i class="icon-step-backward"></i></button>
+        <button ng-if="!panelVisible" ng-click="showLeftPane()" class="hideLeft" title="Show"><i class="icon-step-forward"></i></button>
+    </div>
+    <div class="panel-adjacent">
+
+<!--
+        <ul class="nav nav-tabs ng-scope qdrTopoModes">
+            <li ng-repeat="mode in modes" ng-class="{active : isModeActive(mode.name), 'pull-right' : isRight(mode)}" ng-click="selectMode('{{mode.name}}')" >
+                <a data-placement="bottom" class="ng-binding"> {{mode.name}} </a></li>
+        </ul>
+-->
+        <div id="topology" ng-show="mode == 'Diagram'"><!-- d3 toplogy here --></div>
+        <div id="geology" ng-show="mode == 'Globe'"><!-- d3 globe here --></div>
+        <div id="crosssection"><!-- d3 pack here --></div>
+        <!-- <div id="addRouter" ng-show="mode == 'Add Node'"></div> -->
+        <div id="node_context_menu" class="contextMenu">
+            <ul>
+                <li class="na" ng-class="{new: contextNode.cls == 'temp'}" ng-click="addingNode.trigger = 'editNode'">Edit...</li>
+                <li class="na" ng-class="{adding: addingNode.step > 0}" ng-click="addingNode.step = 0">Cancel add</li>
+                <li class="context-separator"></li>
+                <li class="na" ng-class="{'force-display': !isFixed()}" ng-click="setFixed(true)">Freeze in place</li>
+                <li class="na" ng-class="{'force-display': isFixed()}" ng-click="setFixed(false)">Unfreeze</li>
+            </ul>
+        </div>
+        <div id="svg_context_menu" class="contextMenu">
+            <ul>
+                <li ng-click="addingNode.step = 2">Add a new router</li>
+            </ul>
+        </div>
+        <div id="link_context_menu" class="contextMenu">
+            <ul>
+                <li ng-click="reverseLink()">Reverse connection direction</li>
+                <li ng-click="removeLink()">Remove connection</li>
+            </ul>
+        </div>
+        <div id="svg_legend"></div>
+        <div id="multiple_details">
+            <h4 class="grid-title">Connections</h4>
+            <div class="gridStyle" ng-grid="multiDetails"></div>
+         </div>
+        <div id="link_details">
+            <h4 class="grid-title">Links</h4>
+            <div class="gridStyle" ng-grid="linkDetails"></div>
+        </div>
+    </div>
+</div>
+
+
+<script type="text/ng-template" id="titleHeaderCellTemplate.html">
+    <div title="{{col.displayName}}" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{'cursor': col.cursor}" ng-class="{ 'ngSorted': !noSortVisible }">
+        <div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText">{{col.displayName}}</div>
+        <div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>
+        <div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>
+        <div class="ngSortPriority">{{col.sortPriority}}</div>
+    </div>
+</script>
+<script type="text/ng-template" id="titleCellTemplate.html">
+    <div title="{{row.entity[col.field]}}" class="ngCellText">{{row.entity[col.field]}}</div>
+</script>
+
+<!--
+    This is the template for the node edit dialog that is displayed.
+-->
+<script type="text/ng-template" id="node-config-template.html">
+    <div class="modal-header">
+        <h3 class="modal-title">Configure new router</h3>
+    </div>
+    <div class="modal-body">
+        <form novalidate name="editForm">
+
+            <tabset vertical="true" class="tabs-left">
+                <tab ng-repeat="entity in entities"> <!-- ng-class="{separated: entity.tabName == 'listener0'}" -->
+                    <tab-heading>
+                        <i ng-if="entity.icon !== ''" ng-class="entity.icon ? 'ui-icon-arrowthick-1-w' : 'ui-icon-arrowthick-1-e'" class="ui-icon"></i>{{entity.humanName}}
+                    </tab-heading>
+                    <div class="entity-description">{{entity.description}}</div>
+                    <fieldset>
+                        <div ng-mouseenter="showDescription(attribute, $event)" ng-repeat="attribute in entity.attributes">
+                            <label for="{{attribute.name}}">{{attribute.humanName}}</label>
+<!-- we can't do <input type="{angular expression}"> because... jquery throws an exception because... -->
+                            <div ng-if="attribute.input == 'input'">
+                                <!-- ng-pattern="testPattern(attribute)" -->
+                                <input ng-if="attribute.type == 'number'" type="number" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.value" ng-required="attribute.required" class="ui-widget-content ui-corner-all"/>
+                                <input ng-if="attribute.type == 'text'" type="text" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.value" ng-required="attribute.required" class="ui-widget-content ui-corner-all"/>
+                            </div>
+                            <div ng-if="attribute.input == 'select'">
+                                <select id="{{attribute.name}}" ng-model="attribute.selected" ng-options="item for item in attribute.rawtype"></select>
+                            </div>
+                            <div ng-if="attribute.input == 'boolean'" class="boolean">
+                                <label><input type="radio" ng-model="attribute.value" value="true"> True</label>
+                                <label><input type="radio" ng-model="attribute.value" value="false"> False</label>
+                            </div>
+                        </div>
+                    </fieldset>
+                    <div class="attr-description">{{attributeDescription}}
+                        <div class="attr-type">{{attributeType}}</div>
+                        <div class="attr-required">{{attributeRequired}}</div>
+                        <div class="attr-unique">{{attributeUnique}}</div>
+                    </div>
+                    <div class="attr-annotations" ng-repeat="annotation in entity.annotatedBy">
+                        <span>You can also enter the <button ng-click="selectAnnotationTab(annotation)">{{annotation}}</button> values.</span>
+                    </div>
+                </tab>
+            </tabset>
+
+
+        </form>
+    </div>
+    <div class="modal-footer">
+        <button class="btn btn-primary" type="button" ng-click="download()">Download</button>
+        <button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
+    </div>
+</script>
+
+<script type="text/ng-template" id="config-file-header.html">##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##   http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License
+##
+</script>
+
+<script type="text/ng-template" id="download-dialog-template.html">
+    <div class="modal-header">
+        <h3 class="modal-title">Configure new router</h3>
+    </div>
+    <div class="modal-body">
+
+        <label title="Show descriptions and default values in confile files"><input type="checkbox" ng-model="verbose"> Verbose output</label>
+        <div>
+            <button ng-click="download()">Download</button>
+            <button class="btn" zero-clipboard data-clipboard-text="{{output}}" title="Copy to clipboard">
+                <i class="icon-copy"></i>
+            </button> configuration file for {{newRouterName}}
+        </div>
+        <div ng-repeat="part in parts">
+            <button ng-click="downloadPart(part)">Download</button>
+            <button class="btn" zero-clipboard data-clipboard-text="{{part.output}}" title="Copy to clipboard">
+                <i class="icon-copy"></i>
+            </button> connector section for {{part.name}}
+        </div>
+
+    </div>
+    <div class="modal-footer">
+        <button class="btn btn-primary" type="button" ng-click="done()">Done</button>
+    </div>
+</script>
+

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html b/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
deleted file mode 120000
index 618221c..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../stand-alone/plugin/html/tmplListTree.html
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html b/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
new file mode 100644
index 0000000..75d4940
--- /dev/null
+++ b/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
@@ -0,0 +1,21 @@
+<div class="qdr-attributes pane left" position="left" width="300">
+    <div class="pane-wrapper">
+        <div class="pane-header-wrapper">
+            <div class="tree-header"><select ng-options="node as node.name for node in nodes" ng-model="currentNode" ng-change="selectNode(currentNode)"></select></div>
+            <div ng-hide="largeNetwork" class="expand-collapse">
+                <i class="icon-chevron-down clickable" title="Expand all nodes" ng-click="expandAll()"></i>
+                <i class="icon-chevron-up clickable" title="Unexpand all nodes" ng-click="contractAll()"></i>
+            </div>
+        </div>
+        <div class="pane-viewport">
+            <div class="pane-content">
+                <div class="treeContainer">
+                    <div id="entityTree" onSelect="onTreeSelected" onRoot="onRootReady" hideRoot="true"></div>
+                    <div ng-init="treeReady()"></div>
+                </div>
+            </div>
+        </div>
+        <div class="pane-bar"></div>
+    </div>
+</div>
+<div class="list-grid" ng-include="'listGrid.html'"></div>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/stand-alone/bower_components/angular-patternfly/LICENSE.txt
----------------------------------------------------------------------
diff --git a/console/stand-alone/bower_components/angular-patternfly/LICENSE.txt b/console/stand-alone/bower_components/angular-patternfly/LICENSE.txt
new file mode 100644
index 0000000..cc698cd
--- /dev/null
+++ b/console/stand-alone/bower_components/angular-patternfly/LICENSE.txt
@@ -0,0 +1,205 @@
+Modifications to Bootstrap are copyright 2013 Red Hat, Inc. and licensed
+under the Apache License 2.0.
+
+
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[2/4] qpid-dispatch git commit: DISPATCH-725 Use patternfly styles for stand-alone console

Posted by ea...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/38c02edf/console/stand-alone/bower_components/angular-patternfly/dist/angular-patternfly.min.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/bower_components/angular-patternfly/dist/angular-patternfly.min.js b/console/stand-alone/bower_components/angular-patternfly/dist/angular-patternfly.min.js
new file mode 100644
index 0000000..ca26809
--- /dev/null
+++ b/console/stand-alone/bower_components/angular-patternfly/dist/angular-patternfly.min.js
@@ -0,0 +1,4 @@
+function mergeDeep(dst){"use strict";return angular.forEach(arguments,function(obj){obj!==dst&&angular.forEach(obj,function(value,key){dst[key]&&dst[key].constructor&&dst[key].constructor===Object?mergeDeep(dst[key],value):dst[key]=value})}),dst}angular.module("patternfly.card",[]),angular.module("patternfly.charts",["patternfly.utils","ui.bootstrap","ngSanitize"]),angular.module("patternfly.filters",["patternfly.select","ui.bootstrap"]),angular.module("patternfly.form",[]),angular.module("patternfly.modals",["ui.bootstrap.modal","ui.bootstrap.tpls"]),angular.module("patternfly.navigation",["ui.bootstrap"]),angular.module("patternfly.notification",["patternfly.utils"]),angular.module("patternfly",["patternfly.autofocus","patternfly.card","patternfly.filters","patternfly.form","patternfly.modals","patternfly.navigation","patternfly.notification","patternfly.select","patternfly.sort","patternfly.toolbars","patternfly.utils","patternfly.validation","patternfly.views","patternfly.wizard
 "]),angular.module("patternfly.sort",["ui.bootstrap"]),angular.module("patternfly.toolbars",["patternfly.utils","patternfly.filters","patternfly.sort","patternfly.views"]),angular.module("patternfly.utils",["ui.bootstrap"]),angular.module("patternfly.views",["patternfly.utils","patternfly.filters","patternfly.sort","patternfly.charts","dndLists"]),angular.module("patternfly.wizard",["ui.bootstrap.modal","ui.bootstrap.tpls","patternfly.form"]),angular.module("patternfly.autofocus",[]).directive("pfFocused",["$timeout",function($timeout){"use strict";return{restrict:"A",link:function(scope,element,attrs){scope.$watch(attrs.pfFocused,function(newValue){$timeout(function(){newValue&&(element[0].focus(),element[0].select&&element[0].select())})})}}}]),angular.module("patternfly.card").directive("pfAggregateStatusCard",function(){"use strict";return{restrict:"A",scope:{status:"=",showTopBorder:"@?",altLayout:"@?",layout:"@?"},templateUrl:"card/aggregate-status/aggregate-status-card.html",
 link:function(scope){scope.shouldShowTopBorder="true"===scope.showTopBorder,scope.isAltLayout="true"===scope.altLayout||"tall"===scope.layout,scope.isMiniLayout="mini"===scope.layout}}}),angular.module("patternfly.card").directive("pfCard",function(){"use strict";return{restrict:"A",transclude:!0,templateUrl:"card/basic/card.html",scope:{headTitle:"@",subTitle:"@?",showTopBorder:"@?",showTitlesSeparator:"@?",footer:"=?",filter:"=?"},controller:["$scope",function($scope){$scope.filter&&!$scope.currentFilter&&($scope.filter.defaultFilter?$scope.currentFilter=$scope.filter.filters[$scope.filter.defaultFilter]:$scope.currentFilter=$scope.filter.filters[0]),$scope.footerCallBackFn=function(){$scope.footerCallBackResult=$scope.footer.callBackFn()},$scope.filterCallBackFn=function(f){$scope.currentFilter=f,$scope.filter.callBackFn&&($scope.filterCallBackResult=$scope.filter.callBackFn(f))},$scope.showHeader=function(){return $scope.headTitle||$scope.showFilterInHeader()},$scope.showFilterI
 nHeader=function(){return $scope.filter&&$scope.filter.filters&&$scope.filter.position&&"header"===$scope.filter.position},$scope.showFilterInFooter=function(){return $scope.filter&&$scope.filter.filters&&(!$scope.filter.position||"footer"===$scope.filter.position)}}],link:function(scope){scope.shouldShowTitlesSeparator=!scope.showTitlesSeparator||"true"===scope.showTitlesSeparator}}}),function(patternfly){"use strict";var patternflyDefaults=patternfly.c3ChartDefaults();angular.module("patternfly.charts").constant("c3ChartDefaults",{getDefaultColors:patternflyDefaults.getDefaultColors,getDefaultDonut:patternflyDefaults.getDefaultDonut,getDefaultDonutSize:patternflyDefaults.getDefaultDonutSize,getDefaultDonutColor:patternflyDefaults.getDefaultDonutColors,getDefaultDonutLegend:patternflyDefaults.getDefaultDonutLegend,getDefaultDonutConfig:patternflyDefaults.getDefaultDonutConfig,getDefaultSparklineArea:patternflyDefaults.getDefaultSparklineArea,getDefaultSparklineSize:patternflyDefaul
 ts.getDefaultSparklineSize,getDefaultSparklineAxis:patternflyDefaults.getDefaultSparklineAxis,getDefaultSparklineColor:patternflyDefaults.getDefaultColors,getDefaultSparklineLegend:patternflyDefaults.getDefaultSparklineLegend,getDefaultSparklinePoint:patternflyDefaults.getDefaultSparklinePoint,getDefaultSparklineTooltip:patternflyDefaults.getDefaultSparklineTooltip,getDefaultSparklineConfig:patternflyDefaults.getDefaultSparklineConfig,getDefaultLineConfig:patternflyDefaults.getDefaultLineConfig})}(patternfly),function(patternfly){"use strict";angular.module("patternfly.charts").directive("pfC3Chart",["$timeout",function($timeout){return{restrict:"A",scope:{config:"=",getChartCallback:"="},template:'<div id=""></div>',replace:!0,link:function(scope,element,attrs){scope.$watch("config",function(){$timeout(function(){var chart,chartData=scope.config;chartData&&(chartData.bindto="#"+attrs.id,chart=c3.generate(chartData),scope.getChartCallback&&scope.getChartCallback(chart))})},!0)}}}])}
 (patternfly),function(patternfly){"use strict";angular.module("patternfly.charts").directive("pfDonutPctChart",["pfUtils","$timeout",function(pfUtils,$timeout){return{restrict:"A",scope:{config:"=",data:"=",chartHeight:"=?",centerLabel:"=?"},replace:!0,templateUrl:"charts/donut/donut-pct-chart.html",controller:["$scope",function($scope){var donutTooltip;$scope.donutChartId="donutChart",$scope.config.chartId&&($scope.donutChartId=$scope.config.chartId+$scope.donutChartId),$scope.updateAvailable=function(){$scope.data.available=$scope.data.total-$scope.data.used},void 0===$scope.data.available&&$scope.updateAvailable(),$scope.getStatusColor=function(used,thresholds){var color=pfUtils.colorPalette.blue;return thresholds&&(color=pfUtils.colorPalette.green,used>=thresholds.error?color=pfUtils.colorPalette.red:used>=thresholds.warning&&(color=pfUtils.colorPalette.orange)),color},$scope.statusDonutColor=function(scope){var color,percentUsed;return color={pattern:[]},percentUsed=scope.data.
 used/scope.data.total*100,color.pattern[0]=$scope.getStatusColor(percentUsed,scope.config.thresholds),color.pattern[1]=pfUtils.colorPalette.black300,color},donutTooltip=function(scope){return{contents:function(d){var tooltipHtml;return tooltipHtml=scope.config.tooltipFn?'<span class="donut-tooltip-pf" style="white-space: nowrap;">'+scope.config.tooltipFn(d)+"</span>":'<span class="donut-tooltip-pf" style="white-space: nowrap;">'+Math.round(100*d[0].ratio)+"% "+$scope.config.units+" "+d[0].name+"</span>"}}},$scope.getDonutData=function(scope){return{columns:[["Used",scope.data.used],["Available",scope.data.available]],type:"donut",donut:{label:{show:!1}},groups:[["used","available"]],order:null}},$scope.getCenterLabelText=function(){var centerLabelText;return centerLabelText={bigText:$scope.data.used,smText:$scope.config.units+" Used"},$scope.config.centerLabelFn?(centerLabelText.bigText=$scope.config.centerLabelFn(),centerLabelText.smText=""):"none"===$scope.centerLabel?(centerLabel
 Text.bigText="",centerLabelText.smText=""):"available"===$scope.centerLabel?(centerLabelText.bigText=$scope.data.available,centerLabelText.smText=$scope.config.units+" Available"):"percent"===$scope.centerLabel&&(centerLabelText.bigText=Math.round($scope.data.used/$scope.data.total*100)+"%",centerLabelText.smText="of "+$scope.data.total+" "+$scope.config.units),centerLabelText},$scope.updateAll=function(scope){$scope.updateAvailable(),$scope.config.data=pfUtils.merge($scope.config.data,$scope.getDonutData($scope)),$scope.config.color=$scope.statusDonutColor($scope),$scope.config.tooltip=donutTooltip(scope),$scope.config.data.onclick=$scope.config.onClickFn},$scope.config=pfUtils.merge(patternfly.c3ChartDefaults().getDefaultDonutConfig(),$scope.config),$scope.updateAll($scope)}],link:function(scope,element){var setupDonutChartTitle=function(){$timeout(function(){var donutChartTitle,centerLabelText;donutChartTitle=d3.select(element[0]).select("text.c3-chart-arcs-title"),donutChartTitl
 e&&(centerLabelText=scope.getCenterLabelText(),donutChartTitle.selectAll("*").remove(),centerLabelText.bigText&&!centerLabelText.smText?donutChartTitle.text(centerLabelText.bigText):(donutChartTitle.insert("tspan").text(centerLabelText.bigText).classed("donut-title-big-pf",!0).attr("dy",0).attr("x",0),donutChartTitle.insert("tspan").text(centerLabelText.smText).classed("donut-title-small-pf",!0).attr("dy",20).attr("x",0)))},300)};scope.$watch("config",function(){scope.updateAll(scope),setupDonutChartTitle()},!0),scope.$watch("chartHeight",function(){scope.chartHeight&&(scope.config.size.height=scope.chartHeight)}),scope.$watch("data",function(){scope.updateAll(scope),setupDonutChartTitle()},!0),scope.$watch("centerLabel",function(){setupDonutChartTitle()})}}}])}(patternfly),angular.module("patternfly.charts").directive("pfEmptyChart",function(){"use strict";return{restrict:"A",scope:{chartHeight:"=?"},replace:!0,templateUrl:"charts/empty-chart.html",controller:["$scope",function($sc
 ope){$scope.setSizeStyles=function(){var height=$scope.chartHeight||40,topPadding=Math.min(Math.round((height-40)/2),20);$scope.sizeStyles={height:height+"px","padding-top":topPadding+"px"}},$scope.setSizeStyles()}],link:function(scope){scope.$watch("chartHeight",function(){scope.setSizeStyles()})}}}),angular.module("patternfly.charts").directive("pfHeatmapLegend",function(){"use strict";return{restrict:"A",scope:{legend:"=?",legendColors:"=?"},templateUrl:"charts/heatmap/heatmap-legend.html",controller:["$scope",function($scope){var heatmapColorPatternDefaults=["#d4f0fa","#F9D67A","#EC7A08","#CE0000"],legendLabelDefaults=["< 70%","70-80%","80-90%","> 90%"];$scope.legendColors||($scope.legendColors=heatmapColorPatternDefaults),$scope.legend||($scope.legend=legendLabelDefaults)}],link:function($scope){var index,items=[];for(index=$scope.legend.length-1;index>=0;index--)items.push({text:$scope.legend[index],color:$scope.legendColors[index]});$scope.legendItems=items}}}),angular.module
 ("patternfly.charts").directive("pfHeatmap",["$compile","$window",function($compile,$window){"use strict";return{restrict:"A",scope:{data:"=",chartDataAvailable:"=?",height:"=?",chartTitle:"=?",showLegend:"=?",legendLabels:"=?",maxBlockSize:"@",minBlockSize:"@",blockPadding:"@",thresholds:"=?",heatmapColorPattern:"=?",clickAction:"=?",rangeOnHover:"=?",rangeHoverSize:"@",rangeTooltips:"=?"},templateUrl:"charts/heatmap/heatmap.html",controller:["$scope",function($scope){var thresholdDefaults=[.7,.8,.9],heatmapColorPatternDefaults=["#d4f0fa","#F9D67A","#EC7A08","#CE0000"],legendLabelDefaults=["< 70%","70-80%","80-90%","> 90%"],rangeTooltipDefaults=["< 70%","70-80%","80-90%","> 90%"],heightDefault=200;void 0===$scope.maxBlockSize||isNaN($scope.maxBlockSize)?$scope.maxSize=64:($scope.maxSize=parseInt($scope.maxBlockSize),$scope.maxSize<5?$scope.maxSize=5:$scope.maxSize>50&&($scope.maxSize=50)),void 0===$scope.minBlockSize||isNaN($scope.minBlockSize)?$scope.minSize=2:$scope.minSize=parse
 Int($scope.minBlockSize),void 0===$scope.blockPadding||isNaN($scope.blockPadding)?$scope.padding=2:$scope.padding=parseInt($scope.blockPadding),void 0===$scope.rangeHoverSize||isNaN($scope.rangeHoverSize)?$scope.rangeHoverSize=15:$scope.rangeHoverSize=parseInt($scope.rangeHoverSize),$scope.rangeOnHover=void 0===$scope.rangeOnHover||$scope.rangeOnHover?!0:!1,$scope.rangeTooltips||($scope.rangeTooltips=rangeTooltipDefaults),$scope.thresholds||($scope.thresholds=thresholdDefaults),$scope.heatmapColorPattern||($scope.heatmapColorPattern=heatmapColorPatternDefaults),$scope.legendLabels||($scope.legendLabels=legendLabelDefaults),$scope.height=$scope.height||heightDefault,$scope.showLegend=$scope.showLegend||void 0===$scope.showLegend,$scope.loadingDone=!1}],link:function(scope,element,attrs){var containerWidth,containerHeight,blockSize,numberOfRows,thisComponent=element[0].querySelector(".heatmap-pf-svg"),setStyles=function(){scope.containerStyles={height:scope.height+"px",display:scope.c
 hartDataAvailable===!1?"none":"block"}},setSizes=function(){var parentContainer=element[0].querySelector(".heatmap-container");containerWidth=parentContainer.clientWidth,containerHeight=parentContainer.clientHeight,blockSize=determineBlockSize(),blockSize-scope.padding>scope.maxSize?(blockSize=scope.padding+scope.maxSize,numberOfRows=Math.ceil(Math.sqrt(scope.data.length)),(blockSize*numberOfRows>containerWidth||blockSize*numberOfRows>containerHeight)&&(numberOfRows=0===blockSize?0:Math.floor(containerHeight/blockSize))):blockSize-scope.padding<scope.minSize?(blockSize=scope.padding+scope.minSize,numberOfRows=Math.ceil(Math.sqrt(scope.data.length)),(blockSize*numberOfRows>containerWidth||blockSize*numberOfRows>containerHeight)&&(numberOfRows=0===blockSize?0:Math.floor(containerHeight/blockSize))):numberOfRows=0===blockSize?0:Math.floor(containerHeight/blockSize)},determineBlockSize=function(){var sx,sy,x=containerWidth,y=containerHeight,n=scope.data?scope.data.length:0,px=Math.ceil(
 Math.sqrt(n*x/y)),py=Math.ceil(Math.sqrt(n*y/x));return sx=Math.floor(px*y/x)*px<n?y/Math.ceil(px*y/x):x/px,sy=Math.floor(py*x/y)*py<n?x/Math.ceil(x*py/y):y/py,Math.max(sx,sy)},redraw=function(){var blocks,data=scope.data,color=d3.scale.threshold().domain(scope.thresholds).range(scope.heatmapColorPattern),rangeTooltip=d3.scale.threshold().domain(scope.thresholds).range(scope.rangeTooltips),fillSize=blockSize-scope.padding,highlightBlock=function(block,active){block.style("fill-opacity",active?1:.4)},highlightBlockColor=function(block,fillColor){var blockColor=color(block.map(function(d){return d[0].__data__.value}));blockColor===fillColor&&block.style("fill-opacity",1)},svg=window.d3.select(thisComponent);svg.selectAll("*").remove(),blocks=svg.selectAll("rect").data(data).enter().append("rect"),blocks.attr("x",function(d,i){return Math.floor(i/numberOfRows)*blockSize}).attr("y",function(d,i){return i%numberOfRows*blockSize}).attr("width",fillSize).attr("height",fillSize).style("fill
 ",function(d){return color(d.value)}).attr("uib-tooltip-html",function(d,i){return scope.rangeOnHover&&fillSize<=scope.rangeHoverSize?'"'+rangeTooltip(d.value)+'"':"'"+d.tooltip+"'"}).attr("tooltip-append-to-body",function(d,i){return!0}).attr("tooltip-animation",function(d,i){return!1}),blocks.on("mouseover",function(){var fillColor;blocks.call(highlightBlock,!1),scope.rangeOnHover&&fillSize<=scope.rangeHoverSize?(fillColor=color(d3.select(this).map(function(d){return d[0].__data__.value})),blocks[0].forEach(function(block){highlightBlockColor(d3.select(block),fillColor)})):d3.select(this).call(highlightBlock,!0)}),blocks.on("click",function(d){scope.clickAction&&scope.clickAction(d)}),angular.forEach(angular.element(blocks),function(block){var el=angular.element(block);$compile(el)(scope)}),svg.on("mouseleave",function(){blocks.call(highlightBlock,!0)})};scope.$watch("data",function(newVal,oldVal){"undefined"!=typeof newVal&&(scope.loadingDone=!0,setStyles(),scope.chartDataAvailab
 le!==!1&&(setSizes(),redraw()))}),scope.$watch("chartDataAvailable",function(){scope.chartDataAvailable===!1&&(scope.loadingDone=!0),setStyles()}),angular.element($window).bind("resize",function(){setSizes(),redraw()}),scope.$watch(function(){return[element[0].offsetWidth,element[0].offsetHeight].join("x")},function(value){setSizes(),redraw()})}}}]),function(patternfly){"use strict";angular.module("patternfly.charts").directive("pfLineChart",["pfUtils",function(pfUtils){return{restrict:"A",scope:{config:"=",chartData:"=",showXAxis:"=?",showYAxis:"=?",setAreaChart:"=?"},replace:!0,templateUrl:"charts/line/line-chart.html",controller:["$scope",function($scope){$scope.lineChartId="lineChart",$scope.config.chartId&&($scope.lineChartId=$scope.config.chartId+$scope.lineChartId),$scope.getLineData=function(chartData){var lineData={type:$scope.setAreaChart?"area":"line"};return chartData&&chartData.dataAvailable!==!1&&chartData.xData&&(lineData.x=chartData.xData[0],lineData.columns=Object.k
 eys(chartData).map(function(key){return chartData[key]})),lineData},void 0===$scope.showXAxis&&($scope.showXAxis=void 0!==$scope.config.showAxis&&$scope.config.showAxis),void 0===$scope.showYAxis&&($scope.showYAxis=void 0!==$scope.config.showAxis&&$scope.config.showAxis),$scope.defaultConfig=patternfly.c3ChartDefaults().getDefaultLineConfig(),$scope.defaultConfig.axis={x:{show:$scope.showXAxis===!0,type:"timeseries",tick:{format:function(){return""}}},y:{show:$scope.showYAxis===!0,tick:{format:function(){return""}}}},void 0===$scope.setAreaChart&&($scope.setAreaChart=void 0!==$scope.config.setAreaChart&&$scope.config.setAreaChart),$scope.config.data=pfUtils.merge($scope.config.data,$scope.getLineData($scope.chartData)),$scope.defaultConfig=pfUtils.merge($scope.defaultConfig,$scope.config)}],link:function(scope){scope.$watch("config",function(){scope.config.data=pfUtils.merge(scope.config.data,scope.getLineData(scope.chartData)),scope.chartConfig=pfUtils.merge(scope.defaultConfig,sco
 pe.config)},!0),scope.$watch("showXAxis",function(){scope.chartConfig.axis.x.show=scope.showXAxis===!0}),scope.$watch("showYAxis",function(){scope.chartConfig.axis.y.show=scope.showYAxis===!0}),scope.$watch("setAreaChart",function(){scope.chartConfig.data.type=scope.setAreaChart?"area":"line"}),scope.$watch("chartData",function(){scope.chartConfig.data=scope.getLineData(scope.chartData)},!0)}}}])}(patternfly),function(patternfly){"use strict";angular.module("patternfly.charts").directive("pfSparklineChart",["pfUtils",function(pfUtils){return{restrict:"A",scope:{config:"=",chartData:"=",chartHeight:"=?",showXAxis:"=?",showYAxis:"=?"},replace:!0,templateUrl:"charts/sparkline/sparkline-chart.html",controller:["$scope",function($scope){$scope.sparklineChartId="sparklineChart",$scope.config.chartId&&($scope.sparklineChartId=$scope.config.chartId+$scope.sparklineChartId),$scope.getSparklineData=function(chartData){var sparklineData={type:"area"};return chartData&&chartData.dataAvailable!=
 =!1&&chartData.xData&&chartData.yData&&(sparklineData.x=chartData.xData[0],sparklineData.columns=[chartData.xData,chartData.yData]),sparklineData},$scope.getTooltipTableHTML=function(tipRows){return'<div class="module-triangle-bottom">  <table class="c3-tooltip">    <tbody>'+tipRows+"    </tbody>  </table></div>"},$scope.sparklineTooltip=function(){return{contents:function(d){var tipRows,percentUsed=0;if($scope.config.tooltipFn)tipRows=$scope.config.tooltipFn(d);else switch($scope.config.tooltipType){case"usagePerDay":$scope.chartData.dataAvailable!==!1&&$scope.chartData.total>0&&(percentUsed=Math.round(d[0].value/$scope.chartData.total*100)),tipRows='<tr>  <th colspan="2">'+d[0].x.toLocaleDateString()+'</th></tr><tr>  <td class="name">'+percentUsed+'%:</td>  <td class="value text-nowrap">'+d[0].value+" "+($scope.config.units?$scope.config.units+" ":"")+d[0].name+"</td></tr>";break;case"valuePerDay":tipRows='<tr>  <td class="value">'+d[0].x.toLocaleDateString()+'</td>  <td class="va
 lue text-nowrap">'+d[0].value+" "+d[0].name+"</td></tr>";break;case"percentage":percentUsed=Math.round(d[0].value/$scope.chartData.total*100),tipRows='<tr>  <td class="name">'+percentUsed+"%</td></tr>";break;default:tipRows=patternfly.c3ChartDefaults().getDefaultSparklineTooltip().contents(d)}return $scope.getTooltipTableHTML(tipRows)},position:function(data,width,height,element){var center,top,chartBox,graphOffsetX,x;try{return center=parseInt(element.getAttribute("x")),top=parseInt(element.getAttribute("y")),chartBox=document.querySelector("#"+$scope.sparklineChartId).getBoundingClientRect(),graphOffsetX=document.querySelector("#"+$scope.sparklineChartId+" g.c3-axis-y").getBoundingClientRect().right,x=Math.max(0,center+graphOffsetX-chartBox.left-Math.floor(width/2)),{top:top-height,left:Math.min(x,chartBox.width-width)}}catch(e){}}}},void 0===$scope.showXAxis&&($scope.showXAxis=void 0!==$scope.config.showAxis&&$scope.config.showAxis),void 0===$scope.showYAxis&&($scope.showYAxis=vo
 id 0!==$scope.config.showAxis&&$scope.config.showAxis),$scope.defaultConfig=patternfly.c3ChartDefaults().getDefaultSparklineConfig(),$scope.defaultConfig.axis={x:{show:$scope.showXAxis===!0,type:"timeseries",tick:{format:function(){return""}}},y:{show:$scope.showYAxis===!0,tick:{format:function(){return""}}}},$scope.defaultConfig.tooltip=$scope.sparklineTooltip(),$scope.chartHeight&&($scope.defaultConfig.size.height=$scope.chartHeight),$scope.defaultConfig.units="",$scope.config.data=pfUtils.merge($scope.config.data,$scope.getSparklineData($scope.chartData)),$scope.chartConfig=pfUtils.merge($scope.defaultConfig,$scope.config)}],link:function(scope){scope.$watch("config",function(){scope.config.data=pfUtils.merge(scope.config.data,scope.getSparklineData(scope.chartData)),scope.chartConfig=pfUtils.merge(scope.defaultConfig,scope.config)},!0),scope.$watch("chartHeight",function(){scope.chartHeight&&(scope.chartConfig.size.height=scope.chartHeight)}),scope.$watch("showXAxis",function(){
 scope.chartConfig.axis.x.show=scope.showXAxis===!0}),scope.$watch("showYAxis",function(){scope.chartConfig.axis.y.show=scope.showYAxis===!0}),scope.$watch("chartData",function(){scope.chartConfig.data=pfUtils.merge(scope.chartConfig.data,scope.getSparklineData(scope.chartData))},!0)}}}])}(patternfly),angular.module("patternfly.charts").directive("pfTrendsChart",function(){"use strict";return{restrict:"A",scope:{config:"=",chartData:"=",chartHeight:"=?",showXAxis:"=?",showYAxis:"=?"},replace:!0,templateUrl:"charts/trends/trends-chart.html",controller:["$scope",function($scope){var SMALL=30,LARGE=60;$scope.getPercentageValue=function(){var pctValue=0;return $scope.chartData.dataAvailable!==!1&&$scope.chartData.total>0&&(pctValue=Math.round($scope.getLatestValue()/$scope.chartData.total*100)),pctValue},$scope.getLatestValue=function(){var latestValue=0;return $scope.chartData.yData&&$scope.chartData.yData.length>0&&(latestValue=$scope.chartData.yData[$scope.chartData.yData.length-1]),l
 atestValue},$scope.getChartHeight=function(){var retValue=LARGE;return $scope.chartHeight?retValue=$scope.chartHeight:"small"===$scope.config.layout&&(retValue=SMALL),retValue}}],link:function(scope){scope.$watch("config",function(){scope.showLargeCardLayout=!scope.config.layout||"large"===scope.config.layout,scope.showSmallCardLayout="small"===scope.config.layout,scope.showActualValue=!scope.config.valueType||"actual"===scope.config.valueType,scope.showPercentageValue="percentage"===scope.config.valueType},!0)}}}),angular.module("patternfly.charts").directive("pfUtilizationBarChart",["$timeout",function($timeout){"use strict";return{restrict:"A",scope:{chartData:"=",chartTitle:"=",chartFooter:"=",units:"=",thresholdError:"=?",thresholdWarning:"=?",footerLabelFormat:"@?",layout:"=?"},templateUrl:"charts/utilization-bar/utilization-bar-chart.html",link:function(scope){scope.$watch("chartData",function(newVal,oldVal){"undefined"!=typeof newVal&&(scope.chartData.percentageUsed=Math.rou
 nd(100*(scope.chartData.used/scope.chartData.total)),(scope.thresholdError||scope.thresholdWarning)&&(scope.isError=scope.chartData.percentageUsed>=scope.thresholdError,scope.isWarn=scope.chartData.percentageUsed>=scope.thresholdWarning&&scope.chartData.percentageUsed<scope.thresholdError,scope.isOk=scope.chartData.percentageUsed<scope.thresholdWarning),scope.animate=!0,$timeout(function(){scope.animate=!1},0))})}}}]),angular.module("patternfly.charts").directive("pfUtilizationTrendChart",function(){"use strict";return{restrict:"A",scope:{chartData:"=",config:"=",centerLabel:"=?",donutConfig:"=",sparklineConfig:"=",sparklineChartHeight:"=?",showSparklineXAxis:"=?",showSparklineYAxis:"=?"},replace:!0,templateUrl:"charts/utilization-trend/utilization-trend-chart.html",controller:["$scope",function($scope){void 0===$scope.centerLabel&&($scope.centerLabel="used"),void 0===$scope.donutConfig.units&&($scope.donutConfig.units=$scope.config.units),void 0===$scope.chartData.available&&($scop
 e.chartData.available=$scope.chartData.total-$scope.chartData.used),$scope.config.units=$scope.config.units||$scope.units}],link:function(scope,element){var setupCurrentValues=function(){"available"===scope.centerLabel?(scope.currentValue=scope.chartData.used,scope.currentText="Used"):(scope.currentValue=scope.chartData.total-scope.chartData.used,scope.currentText="Available")};scope.$watchGroup(["centerLabel","chartData.used","chartData.available","chartData.total"],function(){setupCurrentValues()})}}}),angular.module("patternfly.filters").directive("pfFilter",function(){"use strict";return{restrict:"A",scope:{config:"="},templateUrl:"filters/filter.html",controller:["$scope",function($scope){$scope.filterExists=function(filter){var foundFilter=_.findWhere($scope.config.appliedFilters,{title:filter.title,value:filter.value});return void 0!==foundFilter},$scope.enforceSingleSelect=function(filter){_.remove($scope.config.appliedFilters,{title:filter.title})},$scope.addFilter=function
 (field,value){var newFilter={id:field.id,title:field.title,type:field.filterType,value:value};$scope.filterExists(newFilter)||("select"===newFilter.type&&$scope.enforceSingleSelect(newFilter),$scope.config.appliedFilters.push(newFilter),$scope.config.onFilterChange&&$scope.config.onFilterChange($scope.config.appliedFilters))}}]}}),angular.module("patternfly.filters").directive("pfFilterFields",function(){"use strict";return{restrict:"A",scope:{config:"=",addFilterFn:"="},templateUrl:"filters/filter-fields.html",controller:["$scope",function($scope){$scope.setupConfig=function(){void 0===$scope.fields&&($scope.fields=[]),$scope.currentField||($scope.currentField=$scope.config.fields[0],$scope.config.currentValue=null),void 0===$scope.config.currentValue&&($scope.config.currentValue=null)},$scope.$watch("config",function(){$scope.setupConfig()},!0)}],link:function(scope,element,attrs){scope.selectField=function(item){scope.currentField=item,scope.config.currentValue=null},scope.select
 Value=function(filterValue){scope.addFilterFn(scope.currentField,filterValue),scope.config.currentValue=null},scope.onValueKeyPress=function(keyEvent){13===keyEvent.which&&(scope.addFilterFn(scope.currentField,scope.config.currentValue),scope.config.currentValue=void 0)}}}}),angular.module("patternfly.filters").directive("pfFilterResults",function(){"use strict";return{restrict:"A",scope:{config:"="},templateUrl:"filters/filter-results.html",controller:["$scope",function($scope){$scope.setupConfig=function(){$scope.config.appliedFilters||($scope.config.appliedFilters=[]),void 0===$scope.config.resultsCount&&($scope.config.resultsCount=0)},$scope.$watch("config",function(){$scope.setupConfig()},!0)}],link:function(scope,element,attrs){scope.clearFilter=function(item){var newFilters=[];scope.config.appliedFilters.forEach(function(filter){(item.title!==filter.title||item.value!==filter.value)&&newFilters.push(filter)}),scope.config.appliedFilters=newFilters,scope.config.onFilterChange&
 &scope.config.onFilterChange(scope.config.appliedFilters)},scope.clearAllFilters=function(){scope.config.appliedFilters=[],scope.config.onFilterChange&&scope.config.onFilterChange(scope.config.appliedFilters)}}}}),angular.module("patternfly.form").directive("pfDatepicker",function(){"use strict";return{replace:!0,restrict:"A",require:"^form",templateUrl:"form/datepicker/datepicker.html",scope:{options:"=",date:"="},link:function($scope,element){element.datepicker($scope.options),element.datepicker("update",$scope.date),element.datepicker($scope.date).on("changeDate clearDate",function(elem){$scope.$apply(function(){$scope.date=elem.date})}),$scope.$watch("date",function(newValue,oldValue){var elemDate;oldValue!==newValue&&(elemDate=element.datepicker("getDate"),elemDate&&newValue&&elemDate.getTime()===newValue.getTime()||element.datepicker("update",newValue))})}}}),angular.module("patternfly.form").directive("pfDateTimepicker",function(){"use strict";return{replace:!0,restrict:"A",r
 equire:"^form",templateUrl:"form/datetimepicker/datetimepicker.html",scope:{options:"=",date:"="},link:function($scope,element){element.datetimepicker($scope.options),element.datetimepicker("date",$scope.date||null),element.on("dp.change",function(elem){$scope.$apply(function(){$scope.date=elem.date})})}}}),angular.module("patternfly.form").directive("pfFormButtons",function(){"use strict";return{replace:!0,require:"^form",templateUrl:"form/form-buttons/form-buttons.html",scope:{pfHandleCancel:"&pfOnCancel",pfHandleSave:"&pfOnSave",pfWorking:"=",pfButtonContainerClass:"@"},link:function(scope,iElement,iAttrs,controller){void 0===scope.pfWorking&&(scope.pfWorking=!1),scope.isInvalid=function(){var invalid=controller.$invalid;return angular.forEach(controller,function(value){value&&value.$error&&value.$error.server&&(invalid=!1)}),invalid}}}}),angular.module("patternfly.form").directive("pfFormGroup",function(){"use strict";function getInput(element){var input=element.find("table");re
 turn 0===input.length&&(input=element.find("input"),0===input.length&&(input=element.find("select"),0===input.length&&(input=element.find("textarea")))),input}return{transclude:!0,replace:!0,require:"^form",templateUrl:"form/form-group/form-group.html",scope:{pfLabel:"@",pfField:"@",pfLabelClass:"@",pfInputClass:"@"},link:function(scope,iElement,iAttrs,controller){var field,input=getInput(iElement),type=input.attr("type");iAttrs.pfLabelClass||(iAttrs.pfLabelClass="col-sm-2"),iAttrs.pfInputClass||(iAttrs.pfInputClass="col-sm-5"),scope.pfField||(scope.pfField=input.attr("id")),field=scope.pfField,-1===["checkbox","radio","time"].indexOf(type)&&input.addClass("form-control"),input.attr("required")&&iElement.addClass("required"),controller[field]&&(scope.error=controller[field].$error),scope.hasErrors=function(){return controller[field]&&controller[field].$invalid&&controller[field].$dirty}}}}),angular.module("patternfly.form").directive("pfRemainingCharsCount",["$timeout",function($tim
 eout){"use strict";return{restrict:"A",require:"ngModel",scope:{ngModel:"="},link:function($scope,$element,$attributes){var charsMaxLimit=$attributes.charsMaxLimit,charsWarnRemaining=$attributes.charsWarnRemaining,countRemainingFld=angular.element(document.getElementById($attributes.countFld)),blockInputAtMaxLimit="true"===$attributes.blockInputAtMaxLimit,checkCharactersRemaining=function(){var charsLength=$scope.ngModel.length,remainingChars=charsMaxLimit-charsLength;blockInputAtMaxLimit&&charsLength>charsMaxLimit&&($scope.ngModel=$scope.ngModel.substring(0,charsMaxLimit),charsLength=$scope.ngModel.length,remainingChars=charsMaxLimit-charsLength),$scope.remainingChars=remainingChars,$scope.remainingCharsWarning=charsWarnRemaining>=remainingChars?!0:!1,countRemainingFld.text(remainingChars),countRemainingFld.toggleClass("chars-warn-remaining-pf",charsWarnRemaining>=remainingChars),0>remainingChars?$scope.$emit("overCharsMaxLimit",$attributes.id):$scope.$emit("underCharsMaxLimit",$at
 tributes.id)};$scope.$watch("ngModel",function(){checkCharactersRemaining()}),$element.bind("keypress",function(event){blockInputAtMaxLimit&&$element.val().length>=charsMaxLimit&&8!==event.keyCode&&event.preventDefault()})}}}]),angular.module("patternfly.modals").directive("pfAboutModalTransclude",["$parse",function($parse){"use strict";return{link:function(scope,element,attrs){element.append($parse(attrs.pfAboutModalTransclude)(scope))}}}]).directive("pfAboutModal",function(){"use strict";return{restrict:"A",scope:{additionalInfo:"=?",copyright:"=?",close:"&onClose",imgAlt:"=?",imgSrc:"=?",isOpen:"=?",productInfo:"=",title:"=?"},templateUrl:"modals/about-modal.html",transclude:!0,controller:["$scope","$uibModal","$transclude",function($scope,$uibModal,$transclude){void 0===$scope.isOpen&&($scope.isOpen=!1),$scope.openModal=function(){$uibModal.open({controller:["$scope","$uibModalInstance","content",function($scope,$uibModalInstance,content){$scope.template=content,$scope.close=fun
 ction(){$uibModalInstance.close()},$scope.$watch(function(){return $scope.isOpen},function(newValue){
+newValue===!1&&$uibModalInstance.close()})}],resolve:{content:function(){var transcludedContent;return $transclude(function(clone){transcludedContent=clone}),transcludedContent}},scope:$scope,templateUrl:"about-modal-template.html"}).result.then(function(){$scope.close()},function(){$scope.close()})}}],link:function(scope,element,attrs){var isOpenListener=scope.$watch("isOpen",function(newVal,oldVal){newVal===!0&&scope.openModal()});scope.$on("$destroy",isOpenListener)}}}),angular.module("patternfly.navigation").directive("pfVerticalNavigation",["$location","$rootScope","$window","$document","$timeout","$injector",function(location,rootScope,$window,$document,$timeout,$injector){"use strict";var $state;return $injector.has("$state")&&($state=$injector.get("$state")),{restrict:"A",scope:{brandSrc:"@",brandAlt:"@",showBadges:"@",persistentSecondary:"@",pinnableMenus:"@",hiddenIcons:"@",items:"=",navigateCallback:"=?",itemClickCallback:"=?",updateActiveItemsOnClick:"@",ignoreMobile:"@"
 },replace:!0,templateUrl:"navigation/vertical-navigation.html",transclude:!0,controller:["$scope",function($scope){var routeChangeListener;$scope.showBadges="true"===$scope.showBadges,$scope.persistentSecondary="true"===$scope.persistentSecondary,$scope.pinnableMenus="true"===$scope.pinnableMenus,$scope.hiddenIcons="true"===$scope.hiddenIcons,$scope.updateActiveItemsOnClick="true"===$scope.updateActiveItemsOnClick,$scope.ignoreMobile="true"===$scope.ignoreMobile,$scope.activeSecondary=!1,$scope.clearActiveItems=function(){$scope.items.forEach(function(item){item.isActive=!1,item.children&&item.children.forEach(function(secondary){secondary.isActive=!1,secondary.children&&secondary.children.forEach(function(tertiary){tertiary.isActive=!1})})})},$scope.setActiveItems=function(){var updatedRoute="#"+location.path();$scope.items.forEach(function(topLevel){updatedRoute.indexOf(topLevel.href)>-1&&(topLevel.isActive=!0),topLevel.children&&topLevel.children.forEach(function(secondLevel){upd
 atedRoute.indexOf(secondLevel.href)>-1&&(secondLevel.isActive=!0,topLevel.isActive=!0),secondLevel.children&&secondLevel.children.forEach(function(thirdLevel){updatedRoute.indexOf(thirdLevel.href)>-1&&(thirdLevel.isActive=!0,secondLevel.isActive=!0,topLevel.isActive=!0)})})})},$scope.updateActiveItemsOnClick||(routeChangeListener=rootScope.$on("$routeChangeSuccess",function(event,next,current){$scope.clearActiveItems(),$scope.setActiveItems()}),$scope.$on("$destroy",routeChangeListener))}],link:function($scope){var breakpoints={tablet:768,desktop:1200},getBodyContentElement=function(){return angular.element(document.querySelector(".container-pf-nav-pf-vertical"))},explicitCollapse=!1,hoverDelay=500,hideDelay=hoverDelay+200,initBodyElement=function(){var bodyContentElement=getBodyContentElement();$scope.showBadges&&bodyContentElement.addClass("nav-pf-vertical-with-badges"),$scope.persistentSecondary&&bodyContentElement.addClass("nav-pf-persistent-secondary"),$scope.hiddenIcons&&bodyC
 ontentElement.addClass("hidden-icons-pf")},updateMobileMenu=function(selected,secondaryItem){$scope.items.forEach(function(item){item.isMobileItem=!1,item.children&&item.children.forEach(function(nextSecondary){nextSecondary.isMobileItem=!1})}),selected?(selected.isMobileItem=!0,secondaryItem?(secondaryItem.isMobileItem=!0,$scope.showMobileSecondary=!1,$scope.showMobileTertiary=!0):($scope.showMobileSecondary=!0,$scope.showMobileTertiary=!1)):($scope.showMobileSecondary=!1,$scope.showMobileTertiary=!1)},checkNavState=function(){var width=$window.innerWidth,bodyContentElement=getBodyContentElement();!$scope.ignoreMobile&&width<breakpoints.tablet?$scope.inMobileState||($scope.inMobileState=!0,bodyContentElement.removeClass("collapsed-nav"),bodyContentElement.addClass("hidden-nav"),updateSecondaryCollapsedState(!1),updateTertiaryCollapsedState(!1),explicitCollapse=!1):($scope.inMobileState=!1,$scope.showMobileNav=!1,bodyContentElement.removeClass("hidden-nav")),explicitCollapse?($scope
 .navCollapsed=!0,bodyContentElement.addClass("collapsed-nav")):($scope.navCollapsed=!1,bodyContentElement.removeClass("collapsed-nav"))},collapseMenu=function(){var bodyContentElement=getBodyContentElement();$scope.navCollapsed=!0,bodyContentElement.addClass("collapsed-nav"),explicitCollapse=!0},expandMenu=function(){var bodyContentElement=getBodyContentElement();$scope.navCollapsed=!1,bodyContentElement.removeClass("collapsed-nav"),explicitCollapse=!1,angular.element($window).triggerHandler("resize")},forceHideSecondaryMenu=function(){$scope.forceHidden=!0,$timeout(function(){$scope.forceHidden=!1},500)},setParentActive=function(item){$scope.items.forEach(function(topLevel){topLevel.children&&topLevel.children.forEach(function(secondLevel){secondLevel===item&&(topLevel.isActive=!0),secondLevel.children&&secondLevel.children.forEach(function(thirdLevel){thirdLevel===item&&(topLevel.isActive=!0,secondLevel.isActive=!0)})})})},getFirstNavigateChild=function(item){var firstChild;return
  firstChild=!item.children||item.children.length<1?item:getFirstNavigateChild(item.children[0])},setSecondaryItemVisible=function(){var bodyContentElement=getBodyContentElement();$scope.activeSecondary=!1,$scope.persistentSecondary&&!$scope.inMobileState&&($scope.items.forEach(function(topLevel){topLevel.children&&topLevel.children.forEach(function(secondLevel){secondLevel.isActive&&($scope.activeSecondary=!0)})}),$scope.activeSecondary?bodyContentElement.addClass("secondary-visible-pf"):bodyContentElement.removeClass("secondary-visible-pf"))},navigateToItem=function(item){var navTo,navItem=getFirstNavigateChild(item);if(navItem){if($scope.showMobileNav=!1,navItem.uiSref&&navItem.href)throw new Error("Using both uiSref and href on an item is not supported.");if(navItem.uiSref){if(void 0===$state)throw new Error('uiSref is defined on item, but no $state has been injected. Did you declare a dependency on "ui.router" module in your app?');$state.go(navItem.uiSref,navItem.uiSrefOptions)
 }else navTo=navItem.href,navTo&&(navTo.startsWith("#/")&&(navTo=navTo.substring(2)),location.path(navTo));$scope.navigateCallback&&$scope.navigateCallback(navItem)}$scope.itemClickCallback&&$scope.itemClickCallback(item),$scope.updateActiveItemsOnClick&&($scope.clearActiveItems(),navItem.isActive=!0,setParentActive(navItem),setSecondaryItemVisible()),setSecondaryItemVisible()},primaryHover=function(){var hover=!1;return $scope.items.forEach(function(item){item.isHover&&(hover=!0)}),hover},secondaryHover=function(){var hover=!1;return $scope.items.forEach(function(item){item.children&&item.children.length>0&&item.children.forEach(function(secondaryItem){secondaryItem.isHover&&(hover=!0)})}),hover},updateSecondaryCollapsedState=function(setCollapsed,collapsedItem){var bodyContentElement=getBodyContentElement();collapsedItem&&(collapsedItem.secondaryCollapsed=setCollapsed),setCollapsed?($scope.collapsedSecondaryNav=!0,bodyContentElement.addClass("collapsed-secondary-nav-pf")):($scope.i
 tems&&$scope.items.forEach(function(item){item.secondaryCollasped=!1}),$scope.collapsedSecondaryNav=!1,bodyContentElement.removeClass("collapsed-secondary-nav-pf"))},updateTertiaryCollapsedState=function(setCollapsed,collapsedItem){var bodyContentElement=getBodyContentElement();collapsedItem&&(collapsedItem.tertiaryCollapsed=setCollapsed),setCollapsed?($scope.collapsedTertiaryNav=!0,bodyContentElement.addClass("collapsed-tertiary-nav-pf"),updateSecondaryCollapsedState(!1)):($scope.items&&$scope.items.forEach(function(item){item.children&&item.children.length>0&&item.children.forEach(function(secondaryItem){secondaryItem.tertiaryCollasped=!1})}),$scope.collapsedTertiaryNav=!1,bodyContentElement.removeClass("collapsed-tertiary-nav-pf"))};$scope.showMobileNav=!1,$scope.showMobileSecondary=!1,$scope.showMobileTertiary=!1,$scope.hoverSecondaryNav=!1,$scope.hoverTertiaryNav=!1,$scope.collapsedSecondaryNav=!1,$scope.collapsedTertiaryNav=!1,$scope.navCollapsed=!1,$scope.forceHidden=!1,$scop
 e.handleNavBarToggleClick=function(){$scope.inMobileState?$scope.showMobileNav?$scope.showMobileNav=!1:(updateMobileMenu(),$scope.showMobileNav=!0):$scope.navCollapsed?expandMenu():collapseMenu()},$scope.handlePrimaryClick=function(item,event){$scope.inMobileState?item.children&&item.children.length>0?updateMobileMenu(item):(updateMobileMenu(),navigateToItem(item)):navigateToItem(item)},$scope.handleSecondaryClick=function(primary,secondary,event){$scope.inMobileState?secondary.children&&secondary.children.length>0?updateMobileMenu(primary,secondary):(updateMobileMenu(),navigateToItem(secondary)):navigateToItem(secondary)},$scope.handleTertiaryClick=function(primary,secondary,tertiary,event){$scope.inMobileState&&updateMobileMenu(),navigateToItem(tertiary)},$scope.handlePrimaryHover=function(item){item.children&&item.children.length>0&&($scope.inMobileState||(void 0!==item.navUnHoverTimeout?($timeout.cancel(item.navUnHoverTimeout),item.navUnHoverTimeout=void 0):void 0!==$scope.navHo
 verTimeout||item.isHover||(item.navHoverTimeout=$timeout(function(){$scope.hoverSecondaryNav=!0,item.isHover=!0,item.navHoverTimeout=void 0},hoverDelay))))},$scope.handlePrimaryUnHover=function(item){item.children&&item.children.length>0&&(void 0!==item.navHoverTimeout?($timeout.cancel(item.navHoverTimeout),item.navHoverTimeout=void 0):void 0===item.navUnHoverTimeout&&item.isHover&&(item.navUnHoverTimeout=$timeout(function(){item.isHover=!1,primaryHover()||($scope.hoverSecondaryNav=!1),item.navUnHoverTimeout=void 0},hideDelay)))},$scope.handleSecondaryHover=function(item){item.children&&item.children.length>0&&($scope.inMobileState||(void 0!==item.navUnHoverTimeout?($timeout.cancel(item.navUnHoverTimeout),item.navUnHoverTimeout=void 0):void 0===$scope.navHoverTimeout&&(item.navHoverTimeout=$timeout(function(){$scope.hoverTertiaryNav=!0,item.isHover=!0,item.navHoverTimeout=void 0},hoverDelay))))},$scope.handleSecondaryUnHover=function(item){item.children&&item.children.length>0&&(voi
 d 0!==item.navHoverTimeout?($timeout.cancel(item.navHoverTimeout),item.navHoverTimeout=void 0):void 0===item.navUnHoverTimeout&&(item.navUnHoverTimeout=$timeout(function(){item.isHover=!1,secondaryHover()||($scope.hoverTertiaryNav=!1),item.navUnHoverTimeout=void 0},hideDelay)))},$scope.collapseSecondaryNav=function(item,event){$scope.inMobileState?updateMobileMenu():item.secondaryCollapsed?(updateSecondaryCollapsedState(!1,item),forceHideSecondaryMenu()):updateSecondaryCollapsedState(!0,item),$scope.hoverSecondaryNav=!1,event.stopImmediatePropagation()},$scope.collapseTertiaryNav=function(item,event){$scope.inMobileState?$scope.items.forEach(function(primaryItem){primaryItem.children&&primaryItem.children.forEach(function(secondaryItem){secondaryItem===item&&updateMobileMenu(primaryItem)})}):item.tertiaryCollapsed?(updateTertiaryCollapsedState(!1,item),forceHideSecondaryMenu()):updateTertiaryCollapsedState(!0,item),$scope.hoverSecondaryNav=!1,$scope.hoverTertiaryNav=!1,event.stopImm
 ediatePropagation()},initBodyElement(),checkNavState(),angular.element($window).bind("resize",function(){checkNavState(),$timeout(function(){try{$scope.$apply()}catch(e){}})})}}}]),angular.module("patternfly.notification").directive("pfInlineNotification",function(){"use strict";return{scope:{pfNotificationType:"=",pfNotificationMessage:"=",pfNotificationHeader:"=",pfNotificationPersistent:"=",pfNotificationIndex:"="},restrict:"E",templateUrl:"notification/inline-notification.html"}}),angular.module("patternfly.notification").directive("pfNotificationDrawer",["$window","$timeout",function($window,$timeout){"use strict";return{restrict:"A",scope:{drawerHidden:"=?",allowExpand:"=?",drawerExpanded:"=?",drawerTitle:"@",notificationGroups:"=",actionButtonTitle:"@",actionButtonCallback:"=?",titleInclude:"@",headingInclude:"@",subheadingInclude:"@",notificationBodyInclude:"@",notificationFooterInclude:"@",customScope:"=?"},templateUrl:"notification/notification-drawer.html",controller:["$s
 cope",function($scope){(!$scope.allowExpand||angular.isUndefined($scope.drawerExpanded))&&($scope.drawerExpanded=!1)}],link:function(scope,element){scope.$watch("notificationGroups",function(){var openFound=!1;scope.notificationGroups.forEach(function(group){group.open&&(openFound?group.open=!1:openFound=!0)})}),scope.$watch("drawerHidden",function(){$timeout(function(){angular.element($window).triggerHandler("resize")},100)}),scope.toggleCollapse=function(selectedGroup){selectedGroup.open?selectedGroup.open=!1:(scope.notificationGroups.forEach(function(group){group.open=!1}),selectedGroup.open=!0)},scope.toggleExpandDrawer=function(){scope.drawerExpanded=!scope.drawerExpanded},scope.groupHeight&&element.find(".panel-group").css("height",scope.groupHeight),scope.groupClass&&element.find(".panel-group").addClass(scope.groupClass)}}}]),angular.module("patternfly.notification").provider("Notifications",function(){"use strict";this.delay=8e3,this.verbose=!0,this.notifications={},this.pe
 rsist={error:!0,httpError:!0},this.setDelay=function(delay){return this.delay=delay,this},this.setVerbose=function(verbose){return this.verbose=verbose,this},this.setPersist=function(persist){this.persist=persist},this.$get=["$rootScope","$timeout","$log",function($rootScope,$timeout,$log){function createNotifyMethod(mode){return function(message,header,persistent,closeCallback,actionTitle,actionCallback,menuActions){angular.isUndefined(header)&&(header=modes[mode].header),angular.isUndefined(persistent)&&(persistent=persist[mode]),notifications.message(modes[mode].type,header,message,persistent,closeCallback,actionTitle,actionCallback,menuActions),verbose&&$log[modes[mode].log](message)}}var delay=this.delay,notifications=this.notifications,verbose=this.verbose,persist=this.persist,modes={info:{type:"info",header:"Info!",log:"info"},success:{type:"success",header:"Success!",log:"info"},error:{type:"danger",header:"Error!",log:"error"},warn:{type:"warning",header:"Warning!",log:"war
 n"}};return $rootScope.notifications={},$rootScope.notifications.data=[],$rootScope.notifications.remove=function(index){$rootScope.notifications.data.splice(index,1)},$rootScope.notifications||($rootScope.notifications.data=[]),notifications.message=function(type,header,message,isPersistent,closeCallback,actionTitle,actionCallback,menuActions){var notification={type:type,header:header,message:message,isPersistent:isPersistent,closeCallback:closeCallback,actionTitle:actionTitle,actionCallback:actionCallback,menuActions:menuActions};notification.show=!0,$rootScope.notifications.data.push(notification),notification.isPersistent||(notification.viewing=!1,$timeout(function(){notification.show=!1,notification.viewing||notifications.remove(notification)},delay))},angular.forEach(modes,function(mode,index){notifications[index]=createNotifyMethod(index)}),notifications.httpError=function(message,httpResponse){message+=" ("+(httpResponse.data.message||httpResponse.data.cause||httpResponse.da
 ta.cause||httpResponse.data.errorMessage)+")",notifications.message("danger","Error!",message,persist.httpError),verbose&&$log.error(message)},notifications.remove=function(notification){var index=$rootScope.notifications.data.indexOf(notification);-1!==index&&notifications.removeIndex(index)},notifications.removeIndex=function(index){$rootScope.notifications.remove(index)},notifications.setViewing=function(notification,viewing){notification.viewing=viewing,viewing||notification.show||notifications.remove(notification)},notifications.data=$rootScope.notifications.data,notifications}]}),angular.module("patternfly.notification").directive("pfNotificationList",function(){"use strict";function NotificationListController($scope,$rootScope){$scope.notifications=$rootScope.notifications}return NotificationListController.$inject=["$scope","$rootScope"],{restrict:"E",controller:NotificationListController,templateUrl:"notification/notification-list.html"}}),angular.module("patternfly.notifica
 tion").directive("pfToastNotificationList",function(){"use strict";return{restrict:"A",scope:{notifications:"=",showClose:"=?",closeCallback:"=?",updateViewing:"=?"},templateUrl:"notification/toast-notification-list.html",controller:["$scope",function($scope){$scope.handleClose=function(notification){angular.isFunction($scope.closeCallback)&&$scope.closeCallback(notification)},$scope.handleViewingChange=function(isViewing,notification){angular.isFunction($scope.updateViewing)&&$scope.updateViewing(isViewing,notification)}}]}}),angular.module("patternfly.notification").directive("pfToastNotification",function(){"use strict";return{scope:{notificationType:"@",message:"@",header:"@",showClose:"@",closeCallback:"=?",actionTitle:"@",actionCallback:"=?",menuActions:"=?",updateViewing:"=?",data:"=?"},restrict:"A",templateUrl:"notification/toast-notification.html",controller:["$scope",function($scope){$scope.notificationType=$scope.notificationType||"info",$scope.updateShowClose=function(){
 $scope.showCloseButton="true"===$scope.showClose&&(angular.isUndefined($scope.menuActions)||$scope.menuActions.length<1)},$scope.handleClose=function(){angular.isFunction($scope.closeCallback)&&$scope.closeCallback($scope.data)},$scope.handleAction=function(){angular.isFunction($scope.actionCallback)&&$scope.actionCallback($scope.data)},$scope.handleMenuAction=function(menuAction){menuAction&&angular.isFunction(menuAction.actionFn)&&menuAction.isDisabled!==!0&&menuAction.actionFn(menuAction,$scope.data)},$scope.handleEnter=function(){angular.isFunction($scope.updateViewing)&&$scope.updateViewing(!0,$scope.data)},$scope.handleLeave=function(){angular.isFunction($scope.updateViewing)&&$scope.updateViewing(!1,$scope.data)},$scope.updateShowClose()}],link:function(scope){scope.$watch("showClose",function(){scope.updateShowClose()}),scope.$watch("menuActions",function(){scope.updateShowClose()})}}}),angular.module("patternfly.select",[]).directive("pfSelect",["$timeout",function($timeout
 ){"use strict";return{restrict:"A",require:"?ngModel",scope:{selectPickerOptions:"=pfSelect"},link:function(scope,element,attrs,ngModel){var optionCollectionList,optionCollectionExpr,optionCollection,$render=ngModel.$render,selectpickerRefresh=function(argument){scope.$applyAsync(function(){element.selectpicker("refresh")})},selectpickerDestroy=function(){element.selectpicker("destroy")};element.selectpicker(scope.selectPickerOptions),ngModel.$render=function(){$render.apply(this,arguments),selectpickerRefresh()},attrs.ngOptions&&(optionCollectionList=attrs.ngOptions.split("in "),optionCollectionExpr=optionCollectionList[optionCollectionList.length-1].split(/track by|\|/),optionCollection=optionCollectionExpr[0],scope.$parent.$watchCollection(optionCollection,selectpickerRefresh)),attrs.ngModel&&scope.$parent.$watch(attrs.ngModel,selectpickerRefresh),attrs.$observe("disabled",selectpickerRefresh),scope.$on("$destroy",selectpickerDestroy)}}}]),angular.module("patternfly.sort").direct
 ive("pfSort",function(){"use strict";return{restrict:"A",scope:{config:"="},templateUrl:"sort/sort.html",controller:["$scope",function($scope){$scope.setupConfig=function(){var updated=!1;void 0===$scope.config.fields&&($scope.config.fields=[]),$scope.config.fields.length>0&&(void 0===$scope.config.currentField&&($scope.config.currentField=$scope.config.fields[0],updated=!0),void 0===$scope.config.isAscending&&($scope.config.isAscending=!0,updated=!0)),updated===!0&&$scope.config.onSortChange&&$scope.config.onSortChange($scope.config.currentField,$scope.config.isAscending)},$scope.selectField=function(field){$scope.config.currentField=field,$scope.config.onSortChange&&$scope.config.onSortChange($scope.config.currentField,$scope.config.isAscending)},$scope.changeDirection=function(){$scope.config.isAscending=!$scope.config.isAscending,$scope.config.onSortChange&&$scope.config.onSortChange($scope.config.currentField,$scope.config.isAscending)},$scope.getSortIconClass=function(){var ic
 onClass;return iconClass="numeric"===$scope.config.currentField.sortType?$scope.config.isAscending?"fa fa-sort-numeric-asc":"fa fa-sort-numeric-desc":$scope.config.isAscending?"fa fa-sort-alpha-asc":"fa fa-sort-alpha-desc"},$scope.setupConfig()}],link:function(scope,element,attrs){scope.$watch("config",function(){scope.setupConfig()},!0)}}}),angular.module("patternfly.toolbars").directive("pfToolbar",function(){"use strict";return{restrict:"A",scope:{config:"="},replace:!0,transclude:{actions:"?"},templateUrl:"toolbars/toolbar.html",controller:["$scope",function($scope){$scope.viewSelected=function(viewId){$scope.config.viewsConfig.currentView=viewId,$scope.config.viewsConfig.onViewSelect&&!$scope.checkViewDisabled(viewId)&&$scope.config.viewsConfig.onViewSelect(viewId)},$scope.isViewSelected=function(viewId){return $scope.config.viewsConfig&&$scope.config.viewsConfig.currentView===viewId},$scope.checkViewDisabled=function(view){return $scope.config.viewsConfig.checkViewDisabled&&$s
 cope.config.viewsConfig.checkViewDisabled(view)},$scope.filterExists=function(filter){var foundFilter=_.findWhere($scope.config.filterConfig.appliedFilters,{title:filter.title,value:filter.value});return void 0!==foundFilter},$scope.addFilter=function(field,value){var newFilter={id:field.id,title:field.title,value:value};$scope.filterExists(newFilter)||($scope.config.filterConfig.appliedFilters.push(newFilter),$scope.config.filterConfig.onFilterChange&&$scope.config.filterConfig.onFilterChange($scope.config.filterConfig.appliedFilters))},$scope.handleAction=function(action){action&&action.actionFn&&action.isDisabled!==!0&&action.actionFn(action)}}],link:function(scope,element,attrs){scope.$watch("config",function(){scope.config&&scope.config.viewsConfig&&scope.config.viewsConfig.views&&(scope.config.viewsConfig.viewsList=angular.copy(scope.config.viewsConfig.views),scope.config.viewsConfig.currentView||(scope.config.viewsConfig.currentView=scope.config.viewsConfig.viewsList[0]))},!0
 )}}}),angular.module("patternfly.utils").directive("pfFixedAccordion",["$window","$timeout",function($window,$timeout){"use strict";return{restrict:"A",scope:{scrollSelector:"@",groupHeight:"@",groupClass:"@"},link:function($scope,$element,$attrs){var setCollapseHeights=function(){var height,openPanel,contentHeight,bodyHeight,overflowY="hidden",parentElement=$element.find(".panel-group");height=parentElement.height(),openPanel=parentElement.find(".collapse.in"),openPanel&&openPanel.length>0&&openPanel.removeClass("in"),contentHeight=0,parentElement.children().each(function(index,groupHeading){var headingElement=angular.element(groupHeading);contentHeight+=headingElement.prop("offsetHeight"),contentHeight+=parseInt(headingElement.css("margin-top")),contentHeight+=parseInt(headingElement.css("margin-bottom"))}),bodyHeight=height-contentHeight,25>bodyHeight&&(bodyHeight=25,overflowY="auto"),openPanel&&openPanel.length>0&&openPanel.addClass("in"),$timeout(function(){parentElement.find("
 .panel-collapse").each(function(index,collapsePanel){var selected,$sibling,$panel=angular.element(collapsePanel),scrollElement=$panel,innerHeight=0;angular.isDefined($scope.scrollSelector)&&(selected=angular.element($panel.find($scope.scrollSelector)),1===selected.length&&(scrollElement=angular.element(selected[0]),$panel.children().each(function(j,sibling){sibling!==scrollElement[0]&&($sibling=angular.element(sibling),innerHeight+=$sibling.prop("offsetHeight"),innerHeight+=parseInt($sibling.css("margin-top")),innerHeight+=parseInt($sibling.css("margin-bottom")))}))),angular.element(scrollElement).css("max-height",bodyHeight-innerHeight+"px"),angular.element(scrollElement).css("overflow-y","auto")})}),angular.element(parentElement).css("overflow-y",overflowY)};$scope.groupHeight&&$element.find(".panel-group").css("height",$scope.groupHeight),$scope.groupClass&&$element.find(".panel-group").addClass($scope.groupClass),$timeout(function(){setCollapseHeights()},100),angular.element($wi
 ndow).bind("resize",function(){setCollapseHeights()})}}}]),angular.module("patternfly.utils").directive("pfTransclude",function(){"use strict";return{restrict:"A",link:function($scope,$element,$attrs,controller,$transclude){var iChildScope,iScopeType;if(!$transclude)throw new Error("pfTransclude - Illegal use of pfTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}");switch(iScopeType=$attrs.pfTransclude||"sibling"){case"sibling":$transclude(function(clone){$element.empty(),$element.append(clone)});break;case"parent":$transclude($scope,function(clone){$element.empty(),$element.append(clone)});break;case"child":iChildScope=$scope.$new(),$transclude(iChildScope,function(clone){$element.empty(),$element.append(clone),$element.on("$destroy",function(){iChildScope.$destroy()})})}}}}),function(){"use strict";angular.module("patternfly.utils").constant("pfUtils",{merge:function(source1,source2){var retValue;return retValue="function"==
 typeof angular.merge?this.angularMerge(source1,source2):"function"==typeof _.merge?this._merge(source1,source2):"function"==typeof $.extend?this.$extend(source1,source2):this.mergeDeep(source1,source2)},angularMerge:function(source1,source2){return angular.merge({},source1,source2)},_merge:function(source1,source2){return _.merge({},source1,source2)},$extend:function(source1,source2){return $.extend(!0,angular.copy(source1),source2)},mergeDeep:function(source1,source2){return mergeDeep({},angular.copy(source1),angular.copy(source2))},colorPalette:$.pfPaletteColors})}(),angular.module("patternfly.validation",[]).directive("pfValidation",["$timeout",function($timeout){"use strict";return{restrict:"A",require:"ngModel",scope:{pfValidation:"&",pfValidationDisabled:"="},link:function(scope,element,attrs,ctrl){function validate(){var valid,val=scope.inputCtrl.$modelValue,valFunc=scope.pfValidation({input:val});attrs.pfValidation||(valFunc=!0),valid=!val||valFunc||""===val,toggleErrorClass
 (scope.valEnabled&&!valid?!0:!1)}function toggleErrorClass(add){var messageElement=element.next(),parentElement=element.parent(),hasErrorM=parentElement.hasClass("has-error"),wasHidden=messageElement.hasClass("ng-hide");scope.inputCtrl.$setValidity("pf-validation",!add),add&&(hasErrorM||parentElement.addClass("has-error"),wasHidden&&messageElement.removeClass("ng-hide")),add||(hasErrorM&&parentElement.removeClass("has-error"),wasHidden||messageElement.addClass("ng-hide"))}scope.inputCtrl=ctrl,scope.valEnabled=!attrs.pfValidationDisabled,scope.$watch("pfValidationDisabled",function(newVal){scope.valEnabled=!newVal,newVal?(scope.inputCtrl.$setValidity("pfValidation",!0),toggleErrorClass(!1)):validate()}),attrs.pfValidation?$timeout(function(){validate()},0):!scope.inputCtrl.$valid&&scope.inputCtrl.$dirty&&toggleErrorClass(!0),scope.$watch("inputCtrl.$valid",function(isValid){toggleErrorClass(isValid?!1:!0)}),scope.$watch("inputCtrl.$modelValue",function(){validate()})}}}]),angular.mod
 ule("patternfly.views").directive("pfCardView",["pfUtils",function(pfUtils){"use strict";return{restrict:"A",scope:{config:"=?",items:"=",eventId:"@id"},transclude:!0,templateUrl:"views/cardview/card-view.html",controller:["$scope",function($scope){if($scope.defaultConfig={selectItems:!1,multiSelect:!1,dblClick:!1,selectionMatchProp:"uuid",selectedItems:[],checkDisabled:!1,showSelectBox:!0,onSelect:null,onSelectionChange:null,onCheckBoxChange:null,onClick:null,onDblClick:null},$scope.config=pfUtils.merge($scope.defaultConfig,$scope.config),$scope.config.selectItems&&$scope.config.showSelectBox)throw new Error("pfCardView - Illegal use of pfCardView directive! Cannot allow both select box and click selection in the same card view.")}],link:function(scope,element,attrs){attrs.$observe("config",function(){scope.config=pfUtils.merge(scope.defaultConfig,scope.config),scope.config.selectItems||(scope.config.selectedItems=[]),!scope.config.multiSelect&&scope.config.selectedItems&&scope.con
 fig.selectedItems.length>0&&(scope.config.selectedItems=[scope.config.selectedItems[0]])}),scope.itemClick=function(e,item){var alreadySelected,selectionChanged=!1,continueEvent=!0;return scope.checkDisabled(item)?continueEvent:(scope.config&&scope.config.selectItems&&item&&(scope.config.multiSelect&&!scope.config.dblClick?(alreadySelected=_.find(scope.config.selectedItems,function(itemObj){return itemObj===item}),alreadySelected?scope.config.selectedItems=_.without(scope.config.selectedItems,item):(scope.config.selectedItems.push(item),selectionChanged=!0)):scope.config.selectedItems[0]===item?(scope.config.dblClick||(scope.config.selectedItems=[],selectionChanged=!0),continueEvent=!1):(scope.config.selectedItems=[item],selectionChanged=!0),selectionChanged&&scope.config.onSelect&&scope.config.onSelect(item,e),selectionChanged&&scope.config.onSelectionChange&&scope.config.onSelectionChange(scope.config.selectedItems,e)),scope.config.onClick&&scope.config.onClick(item,e),continueEve
 nt)},scope.dblClick=function(e,item){scope.config.onDblClick&&scope.config.onDblClick(item,e)},scope.checkBoxChange=function(item){scope.config.onCheckBoxChange&&scope.config.onCheckBoxChange(item)},scope.isSelected=function(item){var matchProp=scope.config.selectionMatchProp,selected=!1;if(scope.config.showSelectBox)selected=item.selected;else if(scope.config.selectedItems.length)return _.find(scope.config.selectedItems,function(itemObj){return itemObj[matchProp]===item[matchProp]});return selected},scope.checkDisabled=function(item){return scope.config.checkDisabled&&scope.config.checkDisabled(item)}}}}]),angular.module("patternfly.views").directive("pfListView",["$window","pfUtils",function($window,pfUtils){"use strict";return{restrict:"A",scope:{config:"=?",items:"=",actionButtons:"=?",enableButtonForItemFn:"=?",menuActions:"=?",hideMenuForItemFn:"=?",menuClassForItemFn:"=?",updateMenuActionForItemFn:"=?",actions:"=?",updateActionForItemFn:"=?",customScope:"=?"},transclude:{expa
 ndedContent:"?listExpandedContent"},templateUrl:"views/listview/list-view.html",controller:["$scope","$element",function($scope,$element){var setDropMenuLocation=function(parentDiv){var dropButton=parentDiv.querySelector(".dropdown-toggle"),dropMenu=parentDiv.querySelector(".dropdown-menu"),parentRect=$element[0].getBoundingClientRect(),buttonRect=dropButton.getBoundingClientRect(),menuRect=dropMenu.getBoundingClientRect(),menuTop=buttonRect.top-menuRect.height,menuBottom=buttonRect.top+buttonRect.height+menuRect.height;menuBottom<=parentRect.top+parentRect.height||menuTop<parentRect.top?$scope.dropdownClass="dropdown":$scope.dropdownClass="dropup"};if($scope.defaultConfig={selectItems:!1,multiSelect:!1,dblClick:!1,dragEnabled:!1,dragEnd:null,dragMoved:null,dragStart:null,selectionMatchProp:"uuid",selectedItems:[],checkDisabled:!1,useExpandingRows:!1,showSelectBox:!0,onSelect:null,onSelectionChange:null,onCheckBoxChange:null,onClick:null,onDblClick:null},$scope.config=pfUtils.merge(
 $scope.defaultConfig,$scope.config),$scope.config.selectItems&&$scope.config.showSelectBox)throw new Error("pfListView - Illegal use of pListView directive! Cannot allow both select box and click selection in the same list view.");$scope.dropdownClass="dropdown",$scope.handleButtonAction=function(action,item){!$scope.checkDisabled(item)&&action&&action.actionFn&&$scope.enableButtonForItem(action,item)&&action.actionFn(action,item)},$scope.handleMenuAction=function(action,item){!$scope.checkDisabled(item)&&action&&action.actionFn&&action.isDisabled!==!0&&action.actionFn(action,item)},$scope.enableButtonForItem=function(action,item){var enable=!0;return"function"==typeof $scope.enableButtonForItemFn?$scope.enableButtonForItemFn(action,item):enable},$scope.updateActions=function(item){"function"==typeof $scope.updateMenuActionForItemFn&&$scope.menuActions.forEach(function(action){$scope.updateMenuActionForItemFn(action,item)})},$scope.getMenuClassForItem=function(item){var menuClass=""
 ;return angular.isFunction($scope.menuClassForItemFn)&&(menuClass=$scope.menuClassForItemFn(item)),
+menuClass},$scope.hideMenuForItem=function(item){var hideMenu=!1;return angular.isFunction($scope.hideMenuForItemFn)&&(hideMenu=$scope.hideMenuForItemFn(item)),hideMenu},$scope.toggleItemExpansion=function(item){item.isExpanded=!item.isExpanded},$scope.setupActions=function(item,event){$scope.checkDisabled(item)||($scope.updateActions(item),$window.requestAnimationFrame(function(){var nextElement,parentDiv=void 0;for(nextElement=event.target;nextElement&&!parentDiv;)-1!==nextElement.className.indexOf("dropdown-kebab-pf")&&(parentDiv=nextElement,-1!==nextElement.className.indexOf("open")&&setDropMenuLocation(parentDiv)),nextElement=nextElement.parentElement}))}}],link:function(scope,element,attrs){attrs.$observe("config",function(){scope.config=pfUtils.merge(scope.defaultConfig,scope.config),scope.config.selectItems||(scope.config.selectedItems=[]),!scope.config.multiSelect&&scope.config.selectedItems&&scope.config.selectedItems.length>0&&(scope.config.selectedItems=[scope.config.sel
 ectedItems[0]])}),scope.itemClick=function(e,item){var alreadySelected,selectionChanged=!1,continueEvent=!0,enableRowExpansion=scope.config&&scope.config.useExpandingRows&&item&&!item.disableRowExpansion;return scope.checkDisabled(item)?continueEvent:(scope.config&&scope.config.selectItems&&item&&(scope.config.multiSelect&&!scope.config.dblClick?(alreadySelected=_.find(scope.config.selectedItems,function(itemObj){return itemObj===item}),alreadySelected?scope.config.selectedItems=_.without(scope.config.selectedItems,item):(scope.config.selectedItems.push(item),selectionChanged=!0)):scope.config.selectedItems[0]===item?(scope.config.dblClick||(scope.config.selectedItems=[],selectionChanged=!0),continueEvent=!1):(scope.config.selectedItems=[item],selectionChanged=!0),selectionChanged&&scope.config.onSelect&&scope.config.onSelect(item,e),selectionChanged&&scope.config.onSelectionChange&&scope.config.onSelectionChange(scope.config.selectedItems,e)),scope.config.onClick?scope.config.onCli
 ck(item,e)!==!1&&enableRowExpansion&&scope.toggleItemExpansion(item):enableRowExpansion&&scope.toggleItemExpansion(item),continueEvent)},scope.dblClick=function(e,item){return scope.checkDisabled(item)?continueEvent:void(scope.config.onDblClick&&scope.config.onDblClick(item,e))},scope.checkBoxChange=function(item){scope.config.onCheckBoxChange&&scope.config.onCheckBoxChange(item)},scope.isSelected=function(item){var matchProp=scope.config.selectionMatchProp,selected=!1;return scope.config.showSelectBox?selected=item.selected:scope.config.selectItems&&scope.config.selectedItems.length&&(selected=_.find(scope.config.selectedItems,function(itemObj){return itemObj[matchProp]===item[matchProp]})),selected},scope.checkDisabled=function(item){return scope.config.checkDisabled&&scope.config.checkDisabled(item)},scope.dragEnd=function(){angular.isFunction(scope.config.dragEnd)&&scope.config.dragEnd()},scope.dragMoved=function(){angular.isFunction(scope.config.dragMoved)&&scope.config.dragMov
 ed()},scope.isDragOriginal=function(item){return item===scope.dragItem},scope.dragStart=function(item){scope.dragItem=item,angular.isFunction(scope.config.dragStart)&&scope.config.dragStart(item)}}}}]),function(){"use strict";angular.module("patternfly.views").constant("pfViewUtils",{getDashboardView:function(title){return{id:"dashboardView",title:title||"Dashboard View",iconClass:"fa fa-dashboard"}},getCardView:function(title){return{id:"cardView",title:title||"Card View",iconClass:"fa fa-th"}},getListView:function(title){return{id:"listView",title:title||"List View",iconClass:"fa fa-th-list"}},getTableView:function(title){return{id:"tableView",title:title||"Table View",iconClass:"fa fa-table"}},getTopologyView:function(title){return{id:"topologyView",title:title||"Topology View",iconClass:"fa fa-sitemap"}}})}(),function(){"use strict";function pfWizardButtonDirective(action){angular.module("patternfly.wizard").directive(action,function(){return{restrict:"A",require:"^pf-wizard",sc
 ope:{callback:"=?"},link:function($scope,$element,$attrs,wizard){$element.on("click",function(e){e.preventDefault(),$scope.$apply(function(){$scope.$eval($attrs[action]),wizard[action.replace("pfWiz","").toLowerCase()]($scope.callback)})})}}})}pfWizardButtonDirective("pfWizNext"),pfWizardButtonDirective("pfWizPrevious"),pfWizardButtonDirective("pfWizFinish"),pfWizardButtonDirective("pfWizCancel"),pfWizardButtonDirective("pfWizReset")}(),angular.module("patternfly.wizard").directive("pfWizard",["$window",function($window){"use strict";return{restrict:"A",transclude:!0,scope:{title:"@",hideIndicators:"=?",currentStep:"=?",cancelTitle:"=?",backTitle:"=?",nextTitle:"=?",backCallback:"=?",nextCallback:"=?",onFinish:"&",onCancel:"&",wizardReady:"=?",wizardDone:"=?",loadingWizardTitle:"=?",loadingSecondaryInformation:"=?",contentHeight:"=?",embedInPage:"=?"},templateUrl:"wizard/wizard.html",controller:["$scope","$timeout",function($scope,$timeout){var firstRun=!0,stepIdx=function(step){var
  idx=0,res=-1;return angular.forEach($scope.getEnabledSteps(),function(currStep){currStep===step&&(res=idx),idx++}),res},unselectAll=function(){angular.forEach($scope.getEnabledSteps(),function(step){step.selected=!1}),$scope.selectedStep=null},watchSelectedStep=function(){$scope.nextStepEnabledWatcher&&$scope.nextStepEnabledWatcher(),$scope.nextStepTooltipWatcher&&$scope.nextStepTooltipWatcher(),$scope.prevStepEnabledWatcher&&$scope.prevStepEnabledWatcher(),$scope.prevStepTooltipWatcher&&$scope.prevStepTooltipWatcher(),$scope.nextStepEnabledWatcher=$scope.$watch("selectedStep.nextEnabled",function(value){$scope.nextEnabled=value}),$scope.nextStepTooltipWatcher=$scope.$watch("selectedStep.nextTooltip",function(value){$scope.nextTooltip=value}),$scope.prevStepEnabledWatcher=$scope.$watch("selectedStep.prevEnabled",function(value){$scope.prevEnabled=value}),$scope.prevStepTooltipWatcher=$scope.$watch("selectedStep.prevTooltip",function(value){$scope.prevTooltip=value})},stepByTitle=fu
 nction(titleToFind){var foundStep=null;return angular.forEach($scope.getEnabledSteps(),function(step){step.title===titleToFind&&(foundStep=step)}),foundStep};$scope.steps=[],$scope.context={},this.context=$scope.context,angular.isUndefined($scope.wizardReady)&&($scope.wizardReady=!0),angular.isUndefined($scope.contentHeight)&&($scope.contentHeight="300px"),this.contentHeight=$scope.contentHeight,$scope.contentStyle={height:$scope.contentHeight,"max-height":$scope.contentHeight,"overflow-y":"auto"},this.contentStyle=$scope.contentStyle,$scope.nextEnabled=!1,$scope.prevEnabled=!1,$scope.cancelTitle||($scope.cancelTitle="Cancel"),$scope.backTitle||($scope.backTitle="< Back"),$scope.nextTitle||($scope.nextTitle="Next >"),$scope.getEnabledSteps=function(){return $scope.steps.filter(function(step){return"true"!==step.disabled})},this.getReviewSteps=function(){return $scope.steps.filter(function(step){return!step.disabled&&(!angular.isUndefined(step.reviewTemplate)||step.getReviewSteps().l
 ength>0)})},$scope.currentStepNumber=function(){return stepIdx($scope.selectedStep)+1},$scope.getStepNumber=function(step){return stepIdx(step)+1},$scope.$watch("currentStep",function(step){step&&$scope.selectedStep&&$scope.selectedStep.title!==$scope.currentStep&&$scope.goTo(stepByTitle($scope.currentStep))}),$scope.$watch("[editMode, steps.length]",function(){var editMode=$scope.editMode;angular.isUndefined(editMode)||null===editMode||(editMode?angular.forEach($scope.getEnabledSteps(),function(step){step.completed=!0}):angular.forEach($scope.getEnabledSteps(),function(step,stepIndex){stepIndex>=$scope.currentStepNumber()-1&&(step.completed=!1)}))},!0),$scope.goTo=function(step,resetStepNav){$scope.wizardDone||$scope.selectedStep&&!$scope.selectedStep.okToNavAway||step===$scope.selectedStep||((firstRun||$scope.getStepNumber(step)<$scope.currentStepNumber()&&$scope.selectedStep.isPrevEnabled()||$scope.selectedStep.isNextEnabled())&&(unselectAll(),!firstRun&&resetStepNav&&step.subste
 ps&&step.resetNav(),$scope.selectedStep=step,step.selected=!0,$timeout(function(){angular.isFunction(step.onShow)&&step.onShow()},100),watchSelectedStep(),$scope.currentStep=step.title,step.substeps||$scope.$emit("wizard:stepChanged",{step:step,index:stepIdx(step)}),firstRun=!1),$scope.selectedStep.substeps?$scope.firstStep=0===stepIdx($scope.selectedStep)&&1===$scope.selectedStep.currentStepNumber():$scope.firstStep=0===stepIdx($scope.selectedStep))},$scope.stepClick=function(step){step.allowClickNav&&$scope.goTo(step,!0)},this.addStep=function(step){var insertBefore=_.find($scope.steps,function(nextStep){return nextStep.stepPriority>step.stepPriority});insertBefore?$scope.steps.splice($scope.steps.indexOf(insertBefore),0,step):$scope.steps.push(step),$scope.wizardReady&&$scope.getEnabledSteps().length>0&&step===$scope.getEnabledSteps()[0]&&$scope.goTo($scope.getEnabledSteps()[0])},this.isWizardDone=function(){return $scope.wizardDone},this.updateSubStepNumber=function(value){$scop
 e.firstStep=0===stepIdx($scope.selectedStep)&&0===value},this.currentStepTitle=function(){return $scope.selectedStep.title},this.currentStepDescription=function(){return $scope.selectedStep.description},this.currentStep=function(){return $scope.selectedStep},this.totalStepCount=function(){return $scope.getEnabledSteps().length},this.getEnabledSteps=function(){return $scope.getEnabledSteps()},this.currentStepNumber=function(){return $scope.currentStepNumber()},this.getStepNumber=function(step){return $scope.getStepNumber(step)},this.goTo=function(step,resetStepNav){var stepTo,enabledSteps=$scope.getEnabledSteps();stepTo=angular.isNumber(step)?enabledSteps[step]:stepByTitle(step),$scope.goTo(stepTo,resetStepNav)},this.next=function(callback){var enabledSteps=$scope.getEnabledSteps(),index=stepIdx($scope.selectedStep);if(!$scope.selectedStep.substeps||!$scope.selectedStep.next(callback)){if(angular.isFunction(callback)){if(!callback($scope.selectedStep))return;index===enabledSteps.leng
 th-1?this.finish():enabledSteps[index+1].substeps&&enabledSteps[index+1].resetNav()}$scope.selectedStep.completed=!0,index===enabledSteps.length-1?this.finish():$scope.goTo(enabledSteps[index+1])}},this.previous=function(callback){var index=stepIdx($scope.selectedStep);if((!$scope.selectedStep.substeps||!$scope.selectedStep.previous(callback))&&angular.isFunction(callback)&&callback($scope.selectedStep)){if(0===index)throw new Error("Can't go back. It's already in step 0");$scope.goTo($scope.getEnabledSteps()[index-1])}},this.finish=function(){$scope.onFinish&&$scope.onFinish()!==!1&&this.reset()},this.cancel=function(){$scope.onCancel&&$scope.onCancel()!==!1&&this.reset()},this.reset=function(){angular.forEach($scope.getEnabledSteps(),function(step){step.completed=!1}),this.goTo(0)}}],link:function($scope){$scope.$watch("wizardReady",function(){$scope.wizardReady&&$scope.goTo($scope.getEnabledSteps()[0])})}}}]),angular.module("patternfly.wizard").directive("pfWizardReviewPage",func
 tion(){"use strict";return{restrict:"A",scope:{shown:"=",wizardData:"="},require:"^pf-wizard",templateUrl:"wizard/wizard-review-page.html",controller:["$scope",function($scope){$scope.toggleShowReviewDetails=function(step){step.showReviewDetails===!0?step.showReviewDetails=!1:step.showReviewDetails=!0},$scope.getSubStepNumber=function(step,substep){return step.getStepDisplayNumber(substep)},$scope.getReviewSubSteps=function(reviewStep){return reviewStep.getReviewSteps()},$scope.reviewSteps=[],$scope.updateReviewSteps=function(wizard){$scope.reviewSteps=wizard.getReviewSteps()}}],link:function($scope,$element,$attrs,wizard){$scope.$watch("shown",function(value){value&&$scope.updateReviewSteps(wizard)})}}}),angular.module("patternfly.wizard").directive("pfWizardStep",function(){"use strict";return{restrict:"A",transclude:!0,scope:{stepTitle:"@",stepId:"@",stepPriority:"@",substeps:"=?",nextEnabled:"=?",prevEnabled:"=?",nextTooltip:"=?",prevTooltip:"=?",disabled:"@?wzDisabled",okToNavA
 way:"=?",allowClickNav:"=?",description:"@",wizardData:"=",onShow:"=?",showReview:"@?",showReviewDetails:"@?",reviewTemplate:"@?"},require:"^pf-wizard",templateUrl:"wizard/wizard-step.html",controller:["$scope","$timeout",function($scope,$timeout){var firstRun=!0,stepIdx=function(step){var idx=0,res=-1;return angular.forEach($scope.getEnabledSteps(),function(currStep){currStep===step&&(res=idx),idx++}),res},unselectAll=function(){angular.forEach($scope.getEnabledSteps(),function(step){step.selected=!1}),$scope.selectedStep=null},watchSelectedStep=function(){$scope.nextStepEnabledWatcher&&$scope.nextStepEnabledWatcher(),$scope.nextStepTooltipWatcher&&$scope.nextStepTooltipWatcher(),$scope.prevStepEnabledWatcher&&$scope.prevStepEnabledWatcher(),$scope.prevStepTooltipWatcher&&$scope.prevStepTooltipWatcher(),$scope.nextStepEnabledWatcher=$scope.$watch("selectedStep.nextEnabled",function(value){$scope.nextEnabled=value}),$scope.nextStepTooltipWatcher=$scope.$watch("selectedStep.nextToolt
 ip",function(value){$scope.nextTooltip=value}),$scope.prevStepEnabledWatcher=$scope.$watch("selectedStep.prevEnabled",function(value){$scope.prevEnabled=value}),$scope.prevStepTooltipWatcher=$scope.$watch("selectedStep.prevTooltip",function(value){$scope.prevTooltip=value})},stepByTitle=function(titleToFind){var foundStep=null;return angular.forEach($scope.getEnabledSteps(),function(step){step.stepTitle===titleToFind&&(foundStep=step)}),foundStep};$scope.steps=[],$scope.context={},this.context=$scope.context,angular.isUndefined($scope.nextEnabled)&&($scope.nextEnabled=!0),angular.isUndefined($scope.prevEnabled)&&($scope.prevEnabled=!0),angular.isUndefined($scope.showReview)&&($scope.showReview=!1),angular.isUndefined($scope.showReviewDetails)&&($scope.showReviewDetails=!1),angular.isUndefined($scope.stepPriority)?$scope.stepPriority=999:$scope.stepPriority=parseInt($scope.stepPriority),angular.isUndefined($scope.okToNavAway)&&($scope.okToNavAway=!0),angular.isUndefined($scope.allowC
 lickNav)&&($scope.allowClickNav=!0),$scope.getEnabledSteps=function(){return $scope.steps.filter(function(step){return"true"!==step.disabled})},$scope.getReviewSteps=function(){var reviewSteps=$scope.getEnabledSteps().filter(function(step){return!angular.isUndefined(step.reviewTemplate)});return reviewSteps},$scope.resetNav=function(){$scope.goTo($scope.getEnabledSteps()[0])},$scope.currentStepNumber=function(){return stepIdx($scope.selectedStep)+1},$scope.getStepNumber=function(step){return stepIdx(step)+1},$scope.isNextEnabled=function(){var enabled=angular.isUndefined($scope.nextEnabled)||$scope.nextEnabled;return $scope.substeps&&angular.forEach($scope.getEnabledSteps(),function(step){enabled=enabled&&step.nextEnabled}),enabled},$scope.isPrevEnabled=function(){var enabled=angular.isUndefined($scope.prevEnabled)||$scope.prevEnabled;return $scope.substeps&&angular.forEach($scope.getEnabledSteps(),function(step){enabled=enabled&&step.prevEnabled}),enabled},$scope.getStepDisplayNumb
 er=function(step){return $scope.pageNumber+String.fromCharCode(65+stepIdx(step))+"."},$scope.$watch("currentStep",function(step){step&&$scope.selectedStep&&$scope.selectedStep.stepTitle!==$scope.currentStep&&$scope.goTo(stepByTitle($scope.currentStep))}),$scope.$watch("[editMode, steps.length]",function(){var editMode=$scope.editMode;angular.isUndefined(editMode)||null===editMode||(editMode?angular.forEach($scope.getEnabledSteps(),function(step){step.completed=!0}):angular.forEach($scope.getEnabledSteps(),function(step,stepIndex){stepIndex>=$scope.currentStepNumber()-1&&(step.completed=!1)}))},!0),$scope.prevStepsComplete=function(nextStep){var nextIdx=stepIdx(nextStep),complete=!0;return angular.forEach($scope.getEnabledSteps(),function(step,stepIndex){nextIdx>stepIndex&&(complete=complete&&step.nextEnabled)}),complete},$scope.goTo=function(step){!$scope.wizard.isWizardDone()&&step.okToNavAway&&step!==$scope.selectedStep&&(firstRun||$scope.getStepNumber(step)<$scope.currentStepNumb
 er()&&$scope.selectedStep.prevEnabled||$scope.prevStepsComplete(step))&&(unselectAll(),$scope.selectedStep=step,step&&(step.selected=!0,angular.isFunction($scope.selectedStep.onShow)&&$scope.selectedStep.onShow(),watchSelectedStep(),$scope.currentStep=step.stepTitle,$scope.selected&&($scope.$emit("wizard:stepChanged",{step:step,index:stepIdx(step)}),firstRun=!1)),$scope.wizard.updateSubStepNumber(stepIdx($scope.selectedStep)))},$scope.stepClick=function(step){step.allowClickNav&&$scope.goTo(step)},$scope.$watch("selected",function(){$scope.selected&&$scope.selectedStep&&$scope.$emit("wizard:stepChanged",{step:$scope.selectedStep,index:stepIdx($scope.selectedStep)})}),this.addStep=function(step){var insertBefore=_.find($scope.steps,function(nextStep){return nextStep.stepPriority>step.stepPriority});insertBefore?$scope.steps.splice($scope.steps.indexOf(insertBefore),0,step):$scope.steps.push(step)},this.currentStepTitle=function(){return $scope.selectedStep.stepTitle},this.currentStep
 Description=function(){return $scope.selectedStep.description},this.currentStep=function(){return $scope.selectedStep},this.totalStepCount=function(){return $scope.getEnabledSteps().length},this.getEnabledSteps=function(){return $scope.getEnabledSteps()},this.currentStepNumber=function(){return $scope.currentStepNumber()},this.goTo=function(step){var stepTo,enabledSteps=$scope.getEnabledSteps();stepTo=angular.isNumber(step)?enabledSteps[step]:stepByTitle(step),$scope.goTo(stepTo)},$scope.next=function(callback){var enabledSteps=$scope.getEnabledSteps(),index=stepIdx($scope.selectedStep);return angular.isFunction(callback)?callback($scope.selectedStep)?index===enabledSteps.length-1?!1:($scope.goTo(enabledSteps[index+1]),!0):!0:($scope.selectedStep.completed=!0,index===enabledSteps.length-1?!1:($scope.goTo(enabledSteps[index+1]),!0))},$scope.previous=function(callback){var index=stepIdx($scope.selectedStep),goPrev=!1;return angular.isFunction(callback)&&callback($scope.selectedStep)&&
 0!==index&&($scope.goTo($scope.getEnabledSteps()[index-1]),goPrev=!0),goPrev},$scope.substeps&&!$scope.onShow&&($scope.onShow=function(){$timeout(function(){$scope.selectedStep||$scope.goTo($scope.getEnabledSteps()[0])},10)})}],link:function($scope,$element,$attrs,wizard){$scope.$watch($attrs.ngShow,function(value){$scope.pageNumber=wizard.getStepNumber($scope)}),$scope.title=$scope.stepTitle,$scope.contentStyle=wizard.contentStyle,wizard.addStep($scope),$scope.wizard=wizard}}}),angular.module("patternfly.wizard").directive("pfWizardSubstep",function(){"use strict";return{restrict:"A",transclude:!0,scope:{stepTitle:"@",stepId:"@",stepPriority:"@",nextEnabled:"=?",prevEnabled:"=?",okToNavAway:"=?",allowClickNav:"=?",disabled:"@?wzDisabled",description:"@",wizardData:"=",onShow:"=?",showReviewDetails:"@?",reviewTemplate:"@?"},require:"^pf-wizard-step",templateUrl:"wizard/wizard-substep.html",controller:["$scope",function($scope){angular.isUndefined($scope.nextEnabled)&&($scope.nextEna
 bled=!0),angular.isUndefined($scope.prevEnabled)&&($scope.prevEnabled=!0),angular.isUndefined($scope.showReviewDetails)&&($scope.showReviewDetails=!1),angular.isUndefined($scope.stepPriority)?$scope.stepPriority=999:$scope.stepPriority=parseInt($scope.stepPriority),angular.isUndefined($scope.okToNavAway)&&($scope.okToNavAway=!0),angular.isUndefined($scope.allowClickNav)&&($scope.allowClickNav=!0),$scope.isPrevEnabled=function(){var enabled=angular.isUndefined($scope.prevEnabled)||$scope.prevEnabled;return $scope.substeps&&angular.forEach($scope.getEnabledSteps(),function(step){enabled=enabled&&step.prevEnabled}),enabled}}],link:function($scope,$element,$attrs,step){$scope.title=$scope.stepTitle,step.addStep($scope)}}}),angular.module("patternfly.card").run(["$templateCache",function($templateCache){"use strict";$templateCache.put("card/aggregate-status/aggregate-status-card.html",'<div ng-if=!isMiniLayout class="card-pf card-pf-aggregate-status" ng-class="{\'card-pf-accented\': shou
 ldShowTopBorder, \'card-pf-aggregate-status-alt\': isAltLayout}"><h2 class=card-pf-title><a href={{status.href}} ng-if=status.href><image ng-if=status.iconImage ng-src={{status.iconImage}} alt="" class=card-pf-icon-image></image><span class={{status.iconClass}}></span> <span class=card-pf-aggregate-status-count>{{status.count}}</span> <span class=card-pf-aggregate-status-title>{{status.title}}</span></a> <span ng-if=!status.href><image ng-if=status.iconImage ng-src={{status.iconImage}} alt="" class=card-pf-icon-image></image><span class={{status.iconClass}}></span> <span class=card-pf-aggregate-status-count>{{status.count}}</span> <span class=card-pf-aggregate-status-title>{{status.title}}</span></span></h2><div class=card-pf-body><p class=card-pf-aggregate-status-notifications><span class=card-pf-aggregate-status-notification ng-repeat="notification in status.notifications"><a href={{notification.href}} ng-if=notification.href><image ng-if=notification.iconImage ng-src={{notificati
 on.iconImage}} alt="" class=card-pf-icon-image></image><span class={{notification.iconClass}}></span>{{ notification.count }}</a> <span ng-if=!notification.href><image ng-if=notification.iconImage ng-src={{notification.iconImage}} alt="" class=card-pf-icon-image></image><span class={{notification.iconClass}}></span>{{ notification.count }}</span></span></p></div></div><div ng-if=isMiniLayout class="card-pf card-pf-aggregate-status card-pf-aggregate-status-mini" ng-class="{\'card-pf-accented\': shouldShowTopBorder}"><h2 class=card-pf-title><a ng-if=status.href href={{status.href}}><image ng-if=status.iconImage ng-src={{status.iconImage}} alt="" class=card-pf-icon-image></image><span ng-if=status.iconClass class={{status.iconClass}}></span> <span class=card-pf-aggregate-status-count>{{status.count}}</span> {{status.title}}</a> <span ng-if=!status.href><span class=card-pf-aggregate-status-count>{{status.count}}</span> {{status.title}}</span></h2><div class=card-pf-body><p ng-if="status
 .notification.iconImage || status.notification.iconClass || status.notification.count" class=card-pf-aggregate-status-notifications><span class=card-pf-aggregate-status-notification><a ng-if=status.notification.href href={{status.notification.href}}><image ng-if=status.notification.iconImage ng-src={{status.notification.iconImage}} alt="" class=card-pf-icon-image></image><span ng-if=status.notification.iconClass class={{status.notification.iconClass}}></span><span ng-if=status.notification.count>{{status.notification.count}}</span></a> <span ng-if=!status.notification.href><image ng-if=status.notification.iconImage ng-src={{status.notification.iconImage}} alt="" class=card-pf-icon-image></image><span ng-if=status.notification.iconClass class={{status.notification.iconClass}}></span><span ng-if=status.notification.count>{{status.notification.count}}</span></span></span></p></div></div>'),$templateCache.put("card/basic/card-filter.html",'<div uib-dropdown class=card-pf-time-frame-filt
 er><button type=button uib-dropdown-toggle class="btn btn-default">{{currentFilter.label}} <span class=caret></span></button><ul uib-dropdown-menu class=dropdown-menu-right role=menu><li ng-repeat="item in filter.filters" ng-class="{\'selected\': item === currentFilter}"><a role=menuitem tabindex=-1 ng-click=filterCallBackFn(item)>{{item.label}}</a></li></ul></div>'),$templateCache.put("card/basic/card.html","<div ng-class=\"showTopBorder === 'true' ? 'card-pf card-pf-accented' : 'card-pf'\"><div ng-if=showHeader() ng-class=\"shouldShowTitlesSeparator ? 'card-pf-heading' : 'card-pf-heading-no-bottom'\"><div ng-if=showFilterInHeader() ng-include=\"'card/basic/card-filter.html'\"></div><h2 class=card-pf-title>{{headTitle}}</h2></div><span ng-if=subTitle class=card-pf-subtitle>{{subTitle}}</span><div class=card-pf-body><div ng-transclude></div></div><div ng-if=footer class=card-pf-footer><div ng-if=showFilterInFooter() ng-include=\"'card/basic/card-filter.html'\"></div><p><a ng-if=foot
 er.href href={{footer.href}} ng-class=\"{'card-pf-link-with-icon':footer.iconClass,'card-pf-link':!footer.iconClass}\"><span ng-if=footer.iconClass class=\"{{footer.iconClass}} card-pf-footer-text\"></span> <span ng-if=footer.text class=card-pf-footer-text>{{footer.text}}</span></a> <a ng-if=\"footer.callBackFn && !footer.href\" ng-click=footerCallBackFn() ng-class=\"{'card-pf-link-with-icon':footer.iconClass,'card-pf-link':!footer.iconClass}\"><span class=\"{{footer.iconClass}} card-pf-footer-text\" ng-if=footer.iconClass></span> <span class=card-pf-footer-text ng-if=footer.text>{{footer.text}}</span></a> <span ng-if=\"!footer.href && !footer.callBackFn\"><span ng-if=footer.iconClass class=\"{{footer.iconClass}} card-pf-footer-text\" ng-class=\"{'card-pf-link-with-icon':footer.iconClass,'card-pf-link':!footer.iconClass}\"></span> <span ng-if=footer.text class=card-pf-footer-text>{{footer.text}}</span></span></p></div></div>")}]),angular.module("patter

<TRUNCATED>

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org