{% extends "/base.html" %}
{% block html_attr %} ng-app="App"{% endblock %}
{% block title_text %}Rally Task Report{% endblock %}
{% block libs %}
  {% if include_libs %}
  
  
  {% else %}
  
  
  
  
  {% endif %}
{% endblock %}
{% block js_before %}
    "use strict";
    {{ include_raw_file("/task/directive_widget.js") }}
    var controllerFunction = function($scope, $location) {
        $scope.source = {{ source }};
        $scope.scenarios = {{ data }};
{% raw %}
      $scope.location = {
        /* #/path/hash/sub/div */
        normalize: function(str) {
          /* Remove unwanted characters from string */
          if (typeof str !== "string") { return "" }
          return str.replace(/[^\w\-\.]/g, "")
        },
        uri: function(obj) {
          /* Getter/Setter */
          if (! obj) {
            var uri = {path: "", hash: "", sub: "", div: ""};
            var arr = ["div", "sub", "hash", "path"];
            angular.forEach($location.url().split("/"), function(value){
              var v = $scope.location.normalize(value);
              if (v) { var k = arr.pop(); if (k) { this[k] = v }}
            }, uri);
            return uri
          }
          var arr = [obj.path, obj.hash, obj.sub, obj.div], res = [];
          for (var i in arr) { if (! arr[i]) { break }; res.push(arr[i]) }
          return $location.url("/" + res.join("/"))
        },
        path: function(path, hash) {
          /* Getter/Setter */
          if (path === "") { return this.uri({}) }
          path = this.normalize(path);
          var uri = this.uri();
          if (! path) { return uri.path }
          uri.path = path;
          var _hash = this.normalize(hash);
          if (_hash || hash === "") { uri.hash = _hash }
          return this.uri(uri)
        },
        hash: function(hash) {
          /* Getter/Setter */
          if (hash) { this.uri({path:this.uri().path, hash:hash}) }
          return this.uri().hash
        }
      }
      /* Dispatch */
      $scope.route = function(uri) {
        if (! $scope.scenarios_map) { return }
        // Expand menu if there is only one menu group
        if ($scope.nav.length === 1) {
          $scope.nav_idx = $scope.nav[0].idx;
        }
        if (uri.path in $scope.scenarios_map) {
          $scope.view = {is_scenario:true};
          $scope.scenario = $scope.scenarios_map[uri.path];
          $scope.nav_idx = $scope.nav_map[uri.path];
          if ($scope.scenario.iterations.histogram.views.length) {
            $scope.mainHistogram = $scope.scenario.iterations.histogram.views[0]
          }
          if ($scope.scenario.atomic.histogram.views.length) {
            $scope.atomicHistogram = $scope.scenario.atomic.histogram.views[0]
          }
          $scope.outputIteration = 0;
          $scope.showTab(uri);
        } else {
          $scope.scenario = null;
          if (uri.path === "source") {
            $scope.view = {is_source:true}
          } else {
            $scope.view = {is_main:true}
          }
        }
      }
      $scope.$on("$locationChangeSuccess", function (event, newUrl, oldUrl) {
        $scope.route($scope.location.uri())
      });
      $scope.showNav = function(nav_idx) { $scope.nav_idx = nav_idx }
      /* Tabs */
      $scope.tabs = [
        {
          id: "overview",
          name: "Overview",
          visible: function(){ return !! $scope.scenario.iterations.pie.length }
        },{
          id: "details",
          name: "Details",
          visible: function(){ return !! $scope.scenario.atomic.pie.length }
        },{
          id: "output",
          name: "Scenario Data",
          visible: function(){ return $scope.scenario.has_output }
        },{
          id: "hooks",
          name: "Hooks",
          visible: function(){ return $scope.scenario.hooks.length }
        },{
          id: "failures",
          name: "Failures",
          visible: function(){ return !! $scope.scenario.errors.length }
        },{
          id: "task",
          name: "Input task",
          visible: function(){ return !! $scope.scenario.config }
        }
      ];
      $scope.tabs_map = {};
      angular.forEach($scope.tabs,
                      function(tab){ this[tab.id] = tab }, $scope.tabs_map);
      $scope.showTab = function(uri) {
        $scope.tab = uri.hash in $scope.tabs_map ? uri.hash : "overview";
        if (uri.hash === "output") {
          if (typeof $scope.scenario.output === "undefined") {
            var has_additive = !! $scope.scenario.additive_output.length;
            var has_complete = !! ($scope.scenario.complete_output.length
                                   && $scope.scenario.complete_output[0].length);
            $scope.scenario.output = {
              has_additive: has_additive,
              has_complete: has_complete,
              length: has_additive + has_complete,
              active: has_additive ? "additive" : (has_complete ? "complete" : "")
            }
          }
          if (uri.sub && $scope.scenario.output["has_" + uri.sub]) {
            $scope.scenario.output.active = uri.sub
          }
        }
        else if (uri.hash === "hooks") {
          if ($scope.scenario.hooks.length) {
            var hook_idx = parseInt(uri.sub);
            if (isNaN(hook_idx) || ($scope.scenario.hooks.length - hook_idx) <= 0) {
              hook_idx = 0
            }
            if ($scope.scenario.hook_idx === hook_idx) {
              return
            }
            $scope.scenario.hooks.cur = $scope.scenario.hooks[hook_idx];
            $scope.scenario.hook_idx = hook_idx;
            if (typeof $scope.scenario.hooks.cur.active === "undefined") {
              if ($scope.scenario.hooks.cur.additive.length) {
                $scope.scenario.hooks.cur.active = "additive"
              }
              if ($scope.scenario.hooks.cur.complete.length) {
                if (typeof $scope.scenario.hooks.cur.active === "undefined") {
                  $scope.scenario.hooks.cur.active = "complete"
                }
                $scope.set_hook_run()
              }
            }
          }
        }
      }
      for (var i in $scope.tabs) {
        if ($scope.tabs[i].id === $scope.location.hash()) {
          $scope.tab = $scope.tabs[i].id
        }
        $scope.tabs[i].isVisible = function() {
          if ($scope.scenario) {
            if (this.visible()) { return true }
            /* If tab should be hidden but is selected - show another one */
            if (this.id === $scope.location.hash()) {
              for (var i in $scope.tabs) {
                var tab = $scope.tabs[i];
                if (tab.id != this.id && tab.visible()) {
                  $scope.tab = tab.id;
                  return false
                }
              }
            }
          }
          return false
        }
      }
      $scope.set_hook_run = function(idx) {
        if (typeof idx !== "undefined") {
          $scope.scenario.hooks.cur.run_idx = idx
        }
        else if (typeof $scope.scenario.hooks.cur.run_idx === "undefined") {
          $scope.scenario.hooks.cur.run_idx = 0
        }
        idx = $scope.scenario.hooks.cur.run_idx;
        if (($scope.scenario.hooks.cur.complete.length - idx) > 0) {
          $scope.scenario.hooks.cur.run = $scope.scenario.hooks.cur.complete[idx]
        }
      }
      $scope.complete_hooks_as_dropdown = function() {
        return $scope.scenario.hooks.cur.complete.length > 10
      }
      /* Other helpers */
      $scope.showError = function(message) {
          return (function (e) {
            e.style.display = "block";
            e.textContent = message
          })(document.getElementById("page-error"))
      }
      $scope.compact_atomics = function() {
        return ($scope.scenario && $scope.scenario.atomic.iter.length < 9)
      }
      /* Initialization */
      angular.element(document).ready(function(){
        if (! $scope.scenarios.length) {
          return $scope.showError("No data...")
        }
        /* Compose data mapping */
        $scope.nav = [];
        $scope.nav_map = {};
        $scope.scenarios_map = {};
        var met = [], itr = 0, cls_idx = 0;
        var prev_cls, prev_met;
        for (var idx in $scope.scenarios) {
          var sc = $scope.scenarios[idx];
          if (! prev_cls) {
            prev_cls = sc.cls
          }
          else if (prev_cls !== sc.cls) {
            $scope.nav.push({cls:prev_cls, met:met, idx:cls_idx});
            prev_cls = sc.cls;
            met = [];
            itr = 1;
            cls_idx += 1
          }
          if (prev_met !== sc.met) { itr = 1 };
          sc.ref = $scope.location.normalize(sc.cls+"."+sc.met+(itr > 1 ? "-"+itr : ""));
          $scope.scenarios_map[sc.ref] = sc;
          $scope.nav_map[sc.ref] = cls_idx;
          met.push({name:sc.name, itr:itr, idx:idx, ref:sc.ref});
          prev_met = sc.met;
          itr += 1;
        }
        if (met.length) {
          $scope.nav.push({cls:prev_cls, met:met, idx:cls_idx})
        }
        /* Start */
        var uri = $scope.location.uri();
        uri.path = $scope.location.path();
        $scope.route(uri);
        $scope.$digest()
      })
    };
    if (typeof angular === "object") {
      angular.module("App", [])
        .controller("Controller", ["$scope", "$location", controllerFunction])
        .directive("widget", widgetDirective)
    }
{% endraw %}
{% endblock %}
{% block css %}
    .aside { margin:0 20px 0 0; display:block; width:255px; float:left }
    .aside > div { margin-bottom: 15px }
    .aside > div div:first-child { border-top-left-radius:4px; border-top-right-radius:4px }
    .aside > div div:last-child { border-bottom-left-radius:4px; border-bottom-right-radius:4px }
    .navcls { color:#678; background:#eee; border:1px solid #ddd; margin-bottom:-1px; display:block; padding:8px 9px; font-weight:bold; text-align:left; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; cursor:pointer }
    .navcls.expanded { color:#469 }
    .navcls.active { background:#428bca; background-image:linear-gradient(to bottom, #428bca 0px, #3278b3 100%); border-color:#3278b3; color:#fff }
    .navmet { color:#555; background:#fff; border:1px solid #ddd; font-size:12px; display:block; margin-bottom:-1px; padding:8px 10px; text-align:left; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; cursor:pointer }
    .navmet:hover { background:#f8f8f8 }
    .navmet.active, .navmet.active:hover { background:#428bca; background-image:linear-gradient(to bottom, #428bca 0px, #3278b3 100%); border-color:#3278b3; color:#fff }
    .buttn { color:#555; background:#fff; border:1px solid #ddd; border-radius:5px; font-size:12px; margin-bottom:-1px; padding:5px 7px; text-align:left; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; cursor:pointer }
    .buttn:hover { background:#f8f8f8 }
    .buttn.active, .bttn.active:hover { background:#428bca; background-image:linear-gradient(to bottom, #428bca 0px, #3278b3 100%); border-color:#3278b3; color:#fff; cursor:default }
    .tabs { list-style:outside none none; margin:0 0 5px; padding:0; border-bottom:1px solid #ddd }
    .tabs:after { clear:both }
    .tabs li { float:left; margin-bottom:-1px; display:block; position:relative }
    .tabs li div { border:1px solid transparent; border-radius:4px 4px 0 0; line-height:20px; margin-right:2px; padding:10px 15px; color:#428bca }
    .tabs li div:hover { border-color:#eee #eee #ddd; background:#eee; cursor:pointer; }
    .tabs li.active div { background:#fff; border-color:#ddd #ddd transparent; border-style:solid; border-width:1px; color:#555; cursor:default }
    .failure-mesg { color:#900 }
    .failure-trace { color:#333; white-space:pre; overflow:auto }
    .link { color:#428BCA; padding:5px 15px 5px 5px; text-decoration:underline; cursor:pointer }
    .link.active { color:#333; text-decoration:none; cursor:default }
    .chart { padding:0; margin:0; width:890px }
    .chart svg { height:300px; padding:0; margin:0; overflow:visible; float:right }
    .chart.lower svg { height:180px }
    .chart-label-y { font-size:12px; position:relative; top:5px; padding:0; margin:0 }
    .expandable { cursor:pointer }
    .clearfix { clear:both }
    .sortable > .arrow { display:inline-block; width:12px; height:inherit; color:#c90 }
    .content-main { margin:0 5px; display:block; float:left }
{% endblock %}
{% block media_queries %}
    @media only screen and (min-width: 320px)  { .content-wrap { width:900px  } .content-main { width:600px } }
    @media only screen and (min-width: 900px)  { .content-wrap { width:880px  } .content-main { width:590px } }
    @media only screen and (min-width: 1000px) { .content-wrap { width:980px  } .content-main { width:690px } }
    @media only screen and (min-width: 1100px) { .content-wrap { width:1080px } .content-main { width:790px } }
    @media only screen and (min-width: 1200px) { .content-wrap { width:1180px } .content-main { width:890px } }
{% endblock %}
{% block body_attr %} ng-controller="Controller"{% endblock %}
{% block header_text %}task results{% endblock %}
{% block content %}
{% raw %}
    
    
    
      
        Task overview
        
          
            
              | Scenario
                
                  ▴
                  ▾ | Load duration (s)
                
                  ▴
                  ▾ | Full duration (s)
                
                  ▴
                  ▾ | Iterations
                
                  ▴
                  ▾ | Runner
                
                  ▴
                  ▾ | Errors
                
                  ▴
                  ▾ | Hooks
                
                  ▴
                  ▾ | Success (SLA)
                
                  ▴
                  ▾ | 
          
          
            
              | {{sc.ref}} | {{sc.load_duration | number:3}} | {{sc.full_duration | number:3}} | {{sc.iterations_count}} | {{sc.runner}} | {{sc.errors.length}} | {{sc.hooks.length}} | ✔
                ✖ | 
          
        
       
      
      
        {{scenario.cls}}.{{scenario.name}} ({{scenario.full_duration | number:3}}s)
        
            {{scenario.description}}
        
        
        
        
        
        
        
        
        
       
     
    
{% endraw %}
{% endblock %}
{% block js_after %}
    if (! window.angular) {(function(f){
      f(document.getElementById("content-nav"), "none");
      f(document.getElementById("content-main"), "none");
      f(document.getElementById("page-error"), "block").textContent = "Failed to load AngularJS framework"
    })(function(e, s){e.style.display = s; return e})}
{% endblock %}