github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/public/static/js/directives/directives.visualization.js (about)

     1  var directives = directives || {};
     2  
     3  directives.visualization = angular.module('directives.visualization', ['md5']);
     4  
     5  directives.visualization.directive('progressBar', function($filter) {
     6    return function(scope, element, attrs) {
     7      var lastVal = 0;
     8      var lastClass = "progress-bar-success";
     9      var lastMax = 1;
    10  
    11      element.html('<div class="progress-bar progress-bar-success" role="progressbar" style="width: 0%"></div>');
    12  
    13      scope.$watch(attrs.progressBar, function(val) {
    14        if (isNaN(val)) {} else {
    15          lastVal = val;
    16          element.children('.progress-bar').css('width', (val / lastMax * 100) + '%');
    17          if (attrs.progressBarTitle) {
    18            $(element).children('.progress-bar').tooltip({
    19              title: scope.$eval(attrs.progressBarTitle),
    20              animation: false
    21            });
    22          }
    23        }
    24      });
    25  
    26      scope.$watch(attrs.progressBarMax, function(val) {
    27        if (isNaN(val)) {} else {
    28          lastMax = val || 1; // don't allow val = 0;
    29          element.children('.progress-bar').css('width', (lastVal / lastMax * 100) + '%');
    30          if (attrs.progressBarTitle) {
    31            $(element).children('.progress-bar').tooltip({
    32              title: scope.$eval(attrs.progressBarTitle),
    33              animation: false
    34            });
    35          }
    36        }
    37      });
    38  
    39      if (attrs.progressBarClass) {
    40        scope.$watch(attrs.progressBarClass, function(val) {
    41          element.children('.progress-bar').removeClass(lastClass);
    42          lastClass = $filter('statusFilter')(val);
    43          element.children('.progress-bar').addClass(lastClass);
    44        });
    45      }
    46    }
    47  }).directive('resultsBar', function() {
    48    return {
    49      scope: true,
    50      restrict: 'A',
    51      link: function(scope, element, attrs) {
    52        scope.results = [];
    53        scope.widthPerSlice = 100 + '%';
    54  
    55        scope.$parent.$watch(attrs.resultsBar, function(v) {
    56          if (!v) {
    57            return;
    58          }
    59  
    60          scope.results = v;
    61          scope.widthPerSlice = (100 / (v.length || 1)) + "%";
    62  
    63          setTimeout(function() {
    64            // Need to do setTimeout so template has a chance to catch up
    65            $(element).children('.result-slice').each(function(i, el) {
    66              if (i < scope.results.length) {
    67                if (scope.results[i].tooltip) {
    68                  $(el).tooltip({
    69                    title: scope.results[i].tooltip,
    70                    animation: false
    71                  });
    72                }
    73  
    74                if (scope.results[i].link) {
    75                  $(el).attr('href', scope.results[i].link);
    76                }
    77              }
    78            });
    79          }, 0);
    80        });
    81      },
    82      template: '<a ng-repeat="result in results" ng-style="{ display : \'block\', width : widthPerSlice }" ' +
    83        ' ng-class="result.class" class="result-slice"></div>'
    84    };
    85  })
    86   //buildGrid creates a group of task boxes in react. It serves as a shim between
    87  //our angularjs and the React code used to create and manage the boxes.
    88    .directive('buildGrid', function gridDirective() {
    89      return ({
    90          link: link,
    91          scope: {
    92            collapsed: "=",
    93            onClose: "&",
    94            build: "="
    95          }
    96      });
    97     function link(scope, element, attributes) {
    98       //project out the tasks from the uiTask struct to what the react code expects.
    99       var tasks = _.map(scope.build.Tasks, function (task) {
   100          var t = task.Task;
   101          t.failed_test_names = task.failed_test_names;
   102          return t;
   103       });
   104       // bind the angular $destroy to a function that removes the react element
   105       // from the DOM.
   106       scope.$on("$destroy", unmountReactElement);
   107  
   108       // bind angular's changes in the 'collapsed' variable to re-render the React
   109       // element.
   110       scope.$watch("collapsed", renderReactElement);
   111  
   112       // renderReactElement packages the props and renders the React element into the DOM.
   113       function renderReactElement() {
   114       var props = {
   115         onClose: function() {
   116           scope.$apply(scope.onClose);
   117         },
   118         build: {
   119           id: scope.build.Build._id,
   120           taskStatusCount: scope.build.taskStatusCount,
   121           tasks: tasks
   122         },
   123         rolledUp: false,
   124         collapseInfo: {
   125           collapsed: scope.collapsed,
   126           activeTaskStatuses : ['failed','system-failed']
   127         }
   128       }
   129       ReactDOM.render(
   130         React.createElement(Build, props),
   131         element[0]
   132       );
   133     }
   134    function unmountReactElement() {
   135      React.unmountComponentAtNode(element[0]);
   136    }
   137     }
   138  }).directive('ngBindHtmlUnsafe', function() {
   139    // Because ng-bind-html prevents you from entering text with left angle
   140    // bracket (<) we can't use it for logs
   141    return function(scope, element, attr) {
   142      scope.$watch(attr.ngBindHtmlUnsafe, function(v) {
   143        element.html(v);
   144      });
   145    };
   146  });