//
  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.

nav.navbar.navbar-default.navbar-fixed-top.navbar-main
  #fold-button.btn.btn-default.navbar-btn.pull-left(ng-click='showSidebar()')
    i.fa.fa-navicon

  .navbar-title
    | Overview

  .navbar-info.last.first
    | Version: {{overview['flink-version']}}

  .navbar-info.last.first(ng-if="overview['flink-commit']")
    | Commit: {{overview['flink-commit']}}

#content-inner
  .row
    .col-md-6
      .panel.panel-default.panel-dashboard
        .panel-heading
          .row
            .col-xs-3
              i.fa.fa-tasks.fa-3x
            .col-xs-9.text-right
              .huge {{overview.taskmanagers}}
              div Task Managers

        .panel-heading
          .row
            .col-xs-3
              i.fa.fa-folder.fa-3x
            .col-xs-9.text-right
              .huge {{overview["slots-total"]}}
              div Task Slots

        .panel-heading
          .row
            .col-xs-3
              i.fa.fa-folder-o.fa-3x
            .col-xs-9.text-right
              .huge {{overview["slots-available"]}}
              div Available Task Slots

    .col-md-6
      .panel.panel-default.panel-lg
        .panel-heading
          | Total Jobs
        .list-group
          .list-group-item
            .badge.badge-primary {{overview["jobs-running"]}}
            | Running
          .list-group-item
            .badge.badge-success {{overview["jobs-finished"]}}
            | Finished
          .list-group-item
            .badge.badge-info {{overview["jobs-cancelled"]}}
            | Canceled
          .list-group-item
            .badge.badge-danger {{overview["jobs-failed"]}}
            | Failed

  //- .row
  //-   .col-sm-12
  //-     .progress
  //-       .progress-bar.progress-bar-success(style='width: 35%')
  //-         span.sr-only 35% Complete (success)
  //-       .progress-bar.progress-bar-warning.progress-bar-striped(style='width: 20%')
  //-         span.sr-only 20% Complete (warning)
  //-       .progress-bar.progress-bar-danger(style='width: 10%')
  //-         span.sr-only 10% Complete (danger)

  .panel.panel-default
    .panel-heading
      h3.panel-title Running Jobs
    .panel-body

      table.table.table-hover.table-clickable
        thead
          tr
            th Start Time
            th End Time
            th Duration
            th Job Name
            th Job ID
            th Tasks
            th Status

        tbody
          tr(ng-repeat="job in runningJobs|orderBy:\"'start-time'\"" ui-sref="single-job.plan.subtasks({ jobid: job.jid })")
            td {{job['start-time'] | amDateFormat:'YYYY-MM-DD, H:mm:ss'}}
            td {{job['end-time'] | amDateFormat:'YYYY-MM-DD, H:mm:ss'}}
            td(title="{{job.duration | humanizeDuration:false}}") {{job.duration | humanizeDuration:true}}
            td {{job.name}}
            td {{job.jid}}
            td.label-group
              bs-label(status="{{status}}" ng-repeat="(status, value) in job.tasks") {{value}}
            td 
              bs-label(status="{{job.state}}") {{job.state}}

  .panel.panel-default
    .panel-heading
      h3.panel-title Completed Jobs
    .panel-body

      table.table.table-hover.table-clickable
        thead
          tr
            th Start Time
            th End Time
            th Duration
            th Job Name
            th Job ID
            th Tasks
            th Status

        tbody
          tr(ng-repeat="job in finishedJobs|orderBy:\"'end-time'\":true" ui-sref="single-job.plan.subtasks({ jobid: job.jid })")
            td {{job['start-time'] | amDateFormat:'YYYY-MM-DD, H:mm:ss'}}
            td {{job['end-time'] | amDateFormat:'YYYY-MM-DD, H:mm:ss'}}
            td(title="{{job.duration | humanizeDuration:false}}") {{job.duration | humanizeDuration:true}}
            td {{job.name}}
            td {{job.jid}}
            td.label-group
              bs-label(status="{{status}}" ng-repeat="(status, value) in job.tasks") {{value}}
            td 
              bs-label(status="{{job.state}}") {{job.state}}
