You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by sr...@apache.org on 2016/02/04 17:26:42 UTC

tez git commit: TEZ-3095. Tez UI 2: Tuneups & Improvements (sree)

Repository: tez
Updated Branches:
  refs/heads/TEZ-2980 46d181bfd -> 1f5f1b6f0


TEZ-3095. Tez UI 2: Tuneups & Improvements (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1f5f1b6f
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1f5f1b6f
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1f5f1b6f

Branch: refs/heads/TEZ-2980
Commit: 1f5f1b6f087785901e48fbd8bdf9078817eb161a
Parents: 46d181b
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Feb 4 21:54:53 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 4 21:54:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../webapp/app/components/date-formatter.js     | 30 +++++++
 .../main/webapp/app/components/stats-link.js    | 33 ++++++++
 .../src/main/webapp/app/controllers/app/dags.js |  8 +-
 .../main/webapp/app/controllers/dag/attempts.js |  8 +-
 .../webapp/app/controllers/dag/graphical.js     | 12 +--
 .../webapp/app/controllers/dag/index/index.js   | 58 ++++++++++++-
 .../main/webapp/app/controllers/dag/tasks.js    |  8 +-
 .../main/webapp/app/controllers/dag/vertices.js | 12 +--
 tez-ui2/src/main/webapp/app/controllers/dags.js |  8 +-
 .../src/main/webapp/app/controllers/table.js    | 32 ++++++-
 .../webapp/app/controllers/task/attempts.js     |  8 +-
 .../webapp/app/controllers/vertex/attempts.js   |  8 +-
 .../main/webapp/app/controllers/vertex/tasks.js |  8 +-
 tez-ui2/src/main/webapp/app/entities/entity.js  |  4 +-
 tez-ui2/src/main/webapp/app/index.html          |  2 +-
 tez-ui2/src/main/webapp/app/models/task.js      |  2 +
 tez-ui2/src/main/webapp/app/models/vertex-am.js |  2 +-
 tez-ui2/src/main/webapp/app/models/vertex.js    | 10 +--
 .../src/main/webapp/app/routes/am-pollster.js   |  2 +-
 .../src/main/webapp/app/routes/application.js   |  6 ++
 tez-ui2/src/main/webapp/app/serializers/task.js |  2 +
 .../main/webapp/app/serializers/vertex-am.js    |  2 +-
 .../src/main/webapp/app/serializers/vertex.js   |  2 +-
 tez-ui2/src/main/webapp/app/styles/app.less     |  1 +
 .../main/webapp/app/styles/column-selector.less |  2 +-
 .../main/webapp/app/styles/date-formatter.less  | 21 +++++
 .../main/webapp/app/styles/details-page.less    |  1 +
 .../src/main/webapp/app/templates/app/index.hbs |  7 +-
 .../main/webapp/app/templates/attempt/index.hbs |  4 +-
 .../app/templates/components/date-formatter.hbs | 19 +++++
 .../app/templates/components/stats-link.hbs     | 25 ++++++
 .../app/templates/components/tab-n-refresh.hbs  |  2 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  8 +-
 .../webapp/app/templates/dag/index/index.hbs    | 42 +++++++++
 .../main/webapp/app/templates/simple-modal.hbs  |  2 +
 .../main/webapp/app/templates/task/index.hbs    | 17 +++-
 .../main/webapp/app/templates/vertex/index.hbs  | 89 ++++++--------------
 tez-ui2/src/main/webapp/package.json            |  2 +-
 .../components/date-formatter-test.js           | 40 +++++++++
 .../integration/components/stats-link-test.js   | 38 +++++++++
 .../tests/unit/controllers/app/dags-test.js     |  1 +
 .../tests/unit/controllers/dag/attempts-test.js |  1 +
 .../unit/controllers/dag/graphical-test.js      |  1 +
 .../unit/controllers/dag/index/index-test.js    |  1 +
 .../tests/unit/controllers/dag/tasks-test.js    |  1 +
 .../tests/unit/controllers/dag/vertices-test.js |  1 +
 .../webapp/tests/unit/controllers/dags-test.js  |  1 +
 .../tests/unit/controllers/multi-table-test.js  |  1 +
 .../webapp/tests/unit/controllers/table-test.js |  1 +
 .../unit/controllers/task/attempts-test.js      |  1 +
 .../unit/controllers/vertex/attempts-test.js    |  1 +
 .../tests/unit/controllers/vertex/tasks-test.js |  1 +
 .../webapp/tests/unit/models/vertex-test.js     |  2 +-
 54 files changed, 449 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index bc74ffd..ec8bc05 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -34,3 +34,4 @@ ALL CHANGES:
   TEZ-3084. Tez UI 2: Display caller type and info
   TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
   TEZ-3092. Tez UI 2: Tuneups & Improvements
+  TEZ-3095. Tez UI 2: Tuneups & Improvements

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/components/date-formatter.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/date-formatter.js b/tez-ui2/src/main/webapp/app/components/date-formatter.js
new file mode 100644
index 0000000..da21383
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/date-formatter.js
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  classNames: ["date-formatter"],
+
+  content: null,
+
+  env: Ember.inject.service('env'),
+  timeZone: Ember.computed.oneWay('env.app.timeZone'),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/components/stats-link.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/stats-link.js b/tez-ui2/src/main/webapp/app/components/stats-link.js
new file mode 100644
index 0000000..0fb56df
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/stats-link.js
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  value: null,
+  routeName: null,
+  statsType: null,
+
+  searchText: Ember.computed.oneWay("statsType"),
+  _statsType: Ember.computed("statsType", function () {
+    var type = this.get("statsType");
+    if(type) {
+      return Ember.String.capitalize(type.toLowerCase());
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index 6510e93..e0c5e68 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -61,16 +61,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index 94bca3e..71559f8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -77,16 +77,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
index a6e42c3..86d534a 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
@@ -62,16 +62,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',
@@ -83,9 +79,7 @@ export default MultiTableController.extend({
     id: 'firstTaskStartTime',
     headerTitle: 'First Task Start Time',
     contentPath: 'firstTaskStartTime',
-    cellDefinition: {
-     type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'totalTasks',
     headerTitle: 'Tasks',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
index 8dc27a5..2937a2b 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import MultiTableController from '../../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
@@ -50,9 +52,9 @@ export default MultiTableController.extend({
     contentPath: 'totalTasks',
     observePath: true
   },{
-    id: 'successfulTasks',
-    headerTitle: 'Successful Tasks',
-    contentPath: 'successfulTasks',
+    id: 'succeededTasks',
+    headerTitle: 'Succeeded Tasks',
+    contentPath: 'succeededTasks',
     observePath: true
   },{
     id: 'runningTasks',
@@ -74,6 +76,54 @@ export default MultiTableController.extend({
     headerTitle: 'Killed Task Attempts',
     contentPath: 'killedTaskAttempts',
     observePath: true
-  }])
+  }]),
+
+  stats: Ember.computed("model.@each.loadTime", function () {
+    var vertices = this.get("model");
+
+    if(vertices) {
+      let succeededVertices = 0,
+          succeededTasks = 0,
+          totalTasks =0,
+
+          failedTasks = 0,
+          killedTasks = 0,
+          failedTaskAttempts = 0,
+          killedTaskAttempts = 0;
+
+      vertices.forEach(function (vertex) {
+        if(vertex.get("status") === "SUCCEEDED") {
+          succeededVertices++;
+        }
+
+        succeededTasks += vertex.get("succeededTasks");
+        totalTasks += vertex.get("totalTasks");
+
+        failedTasks += vertex.get("failedTasks");
+        killedTasks += vertex.get("killedTasks");
+
+        failedTaskAttempts += vertex.get("failedTaskAttempts");
+        killedTaskAttempts += vertex.get("killedTaskAttempts");
+      });
+
+      return {
+        succeededVertices: succeededVertices,
+        totalVertices: vertices.get("length"),
+
+        succeededTasks: succeededTasks,
+        totalTasks: totalTasks,
+
+        failedTasks: failedTasks,
+        killedTasks: killedTasks,
+
+        failedTaskAttempts: failedTaskAttempts,
+        killedTaskAttempts: killedTaskAttempts
+      };
+    }
+  }),
+
+  beforeSort: function () {
+    return true;
+  }
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 58e0163..113d37e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -65,16 +65,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index 1b9f136..f42a667 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -57,16 +57,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',
@@ -78,9 +74,7 @@ export default MultiTableController.extend({
     id: 'firstTaskStartTime',
     headerTitle: 'First Task Start Time',
     contentPath: 'firstTaskStartTime',
-    cellDefinition: {
-     type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'totalTasks',
     headerTitle: 'Tasks',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 1a760d1..0365987 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -87,16 +87,12 @@ export default TableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table.js b/tez-ui2/src/main/webapp/app/controllers/table.js
index 0891e8d..ca2bae8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table.js
@@ -43,6 +43,8 @@ export default AbstractController.extend({
   columnSelectorTitle: 'Column Selector',
   columnSelectorMessage: "",
 
+  polling: Ember.inject.service("pollster"),
+
   definition: Ember.computed(function () {
     return TableDefinition.create({
       rowCount: this.get("rowCount"),
@@ -69,11 +71,37 @@ export default AbstractController.extend({
     this.set('visibleColumnIDs', visibleColumnIDs);
   })),
 
+  beforeSort: function (columnDefinition) {
+    if(this.get("polling.isReady")) {
+      let columnName = columnDefinition.get("headerTitle");
+      switch(columnDefinition.get("contentPath")) {
+        case "counterGroupsHash":
+          columnName = "Counters";
+          /* falls through */
+        case "status":
+        case "progress":
+          this.send("openModal", {
+            title: "Cannot sort!",
+            content: `Sorting on ${columnName} is disabled for running DAGs!`
+          });
+          return false;
+      }
+    }
+    return true;
+  },
+
   allColumns: Ember.computed("columns", function () {
     var columns = this.get("columns"),
-        counters = this.getCounterColumns();
+        counters = this.getCounterColumns(),
+        beforeSort = this.get("beforeSort").bind(this);
+
+    columns = columns.concat(CounterColumnDefinition.make(counters));
+
+    columns.forEach(function (column) {
+      column.set("beforeSort", beforeSort);
+    });
 
-    return columns.concat(CounterColumnDefinition.make(counters));
+    return columns;
   }),
 
   visibleColumns: Ember.computed('visibleColumnIDs', 'allColumns', function() {

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
index 472d04f..696b09d 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
@@ -55,16 +55,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
index 34a067f..9806458 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -67,16 +67,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
index ea02d61..ed26173 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -55,16 +55,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index f763dcf..8280558 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -98,15 +98,15 @@ var Entity = Ember.Object.extend(NameMixin, {
     );
 
     needLoader.then(function (model) {
-      parentModel.refreshLoadTime();
       parentModel.set(needOptions.name, model);
+      parentModel.refreshLoadTime();
       return model;
     });
 
     if(needOptions.silent) {
       needLoader = needLoader.catch(function () {
-        parentModel.refreshLoadTime();
         parentModel.set(needOptions.name, null);
+        parentModel.refreshLoadTime();
       });
     }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
index 3f82152..757d663 100644
--- a/tez-ui2/src/main/webapp/app/index.html
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -37,7 +37,7 @@
   <body>
     {{content-for 'body'}}
 
-    <script src="config/configs.env"></script>
+    <script src="config/configs.env" integrity=""></script>
 
     <script src="assets/vendor.js"></script>
     <script src="assets/tez-ui.js"></script>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/models/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task.js b/tez-ui2/src/main/webapp/app/models/task.js
index 4db732e..b2e7f71 100644
--- a/tez-ui2/src/main/webapp/app/models/task.js
+++ b/tez-ui2/src/main/webapp/app/models/task.js
@@ -61,4 +61,6 @@ export default AMTimelineModel.extend({
 
   dagID: DS.attr('string'),
   dag: DS.attr('object'), // Auto-loaded by need
+
+  failedTaskAttempts: DS.attr('number'),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/models/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex-am.js b/tez-ui2/src/main/webapp/app/models/vertex-am.js
index 54339b2..69d2346 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex-am.js
@@ -23,7 +23,7 @@ import AMModel from './am';
 export default AMModel.extend({
 
   totalTasks: DS.attr("number"),
-  successfulTasks: DS.attr("number"),
+  succeededTasks: DS.attr("number"),
   runningTasks: DS.attr("number"),
   pendingTasks: DS.attr("number"),
   failedTaskAttempts: DS.attr("number"),

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index 1f4365b..647241f 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -64,13 +64,13 @@ export default AMTimelineModel.extend({
 
   totalTasks: DS.attr('number'),
   _failedTasks: DS.attr('number'),
-  _successfulTasks: DS.attr('number'),
+  _succeededTasks: DS.attr('number'),
   _killedTasks: DS.attr('number'),
   failedTasks: Ember.computed("am.failedTasks", "_failedTasks",
     valueComputerFactory("am.failedTasks", "_failedTasks")
   ),
-  successfulTasks: Ember.computed("am.successfulTasks", "_successfulTasks",
-    valueComputerFactory("am.successfulTasks", "_successfulTasks")
+  succeededTasks: Ember.computed("am.succeededTasks", "_succeededTasks",
+    valueComputerFactory("am.succeededTasks", "_succeededTasks")
   ),
   killedTasks: Ember.computed("am.killedTasks", "_killedTasks",
     valueComputerFactory("am.killedTasks", "_killedTasks")
@@ -83,12 +83,12 @@ export default AMTimelineModel.extend({
     }
     return  runningTasks;
   }),
-  pendingTasks: Ember.computed("totalTasks", "successfulTasks", "runningTasks", function () {
+  pendingTasks: Ember.computed("totalTasks", "succeededTasks", "runningTasks", function () {
     var pendingTasks = null,
         runningTasks = this.get("runningTasks"),
         totalTasks = this.get("totalTasks");
     if(totalTasks!== null && runningTasks !== null) {
-      pendingTasks = totalTasks - this.get("successfulTasks") - runningTasks;
+      pendingTasks = totalTasks - this.get("succeededTasks") - runningTasks;
     }
     return pendingTasks;
   }),

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
index 6752ffd..35d6611 100644
--- a/tez-ui2/src/main/webapp/app/routes/am-pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
@@ -51,7 +51,7 @@ export default PollsterRoute.extend({
       }
     }, function (error) {
       that.send("error", error);
-      Ember.run.later(that, "reload", this.get("polling.interval") * 3);
+      Ember.run.later(that, "reload", that.get("polling.interval") * 3);
     });
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 99bed25..039e329 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -45,6 +45,12 @@ export default Ember.Route.extend({
     // Modal window actions
     openModal: function (componentName, options) {
       options = options || {};
+
+      if(typeof componentName === "object") {
+        options = componentName;
+        componentName = null;
+      }
+
       this.render(options.modalName || "simple-modal", {
         into: 'application',
         outlet: 'modal',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/serializers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/task.js b/tez-ui2/src/main/webapp/app/serializers/task.js
index 7918e89..3c57be2 100644
--- a/tez-ui2/src/main/webapp/app/serializers/task.js
+++ b/tez-ui2/src/main/webapp/app/serializers/task.js
@@ -22,5 +22,7 @@ export default TimelineSerializer.extend({
   maps: {
     vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
     dagID: 'primaryfilters.TEZ_DAG_ID.0',
+
+    failedTaskAttempts: 'otherinfo.numFailedTaskAttempts'
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
index e3b7eaf..ba160d2 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
@@ -22,7 +22,7 @@ export default AMSerializer.extend({
   payloadNamespace: "vertices",
 
   maps: {
-    successfulTasks: "succeededTasks",
+    succeededTasks: "succeededTasks",
     runningTasks: "runningTasks",
     failedTaskAttempts: "failedTaskAttempts",
     killedTaskAttempts: "killedTaskAttempts",

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index bf074f1..eac6808 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -34,7 +34,7 @@ export default TimelineSerializer.extend({
 
     totalTasks: 'otherinfo.numTasks',
     _failedTasks: 'otherinfo.numFailedTasks',
-    _successfulTasks: 'otherinfo.numSucceededTasks',
+    _succeededTasks: 'otherinfo.numSucceededTasks',
     _killedTasks: 'otherinfo.numKilledTasks',
 
     _failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index a832446..88dc47a 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -28,6 +28,7 @@
 @import "table-controls";
 @import "error-bar";
 @import "caller-info";
+@import "date-formatter";
 
 // Modals
 @import "column-selector";

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
index c83bdde..eb61128 100644
--- a/tez-ui2/src/main/webapp/app/styles/column-selector.less
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -40,7 +40,7 @@
     .options {
       .force-scrollbar;
 
-      max-height: 500px;
+      max-height: 450px;
       overflow: auto;
     }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/styles/date-formatter.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/date-formatter.less b/tez-ui2/src/main/webapp/app/styles/date-formatter.less
new file mode 100644
index 0000000..a817bec
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/date-formatter.less
@@ -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.
+ */
+
+.date-formatter {
+  display: inline;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
index b3b1a16..dccec06 100644
--- a/tez-ui2/src/main/webapp/app/styles/details-page.less
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -20,6 +20,7 @@
 
 .detail-list {
   display: inline-block;
+  vertical-align: top;
 
   margin: 0 10px 10px 0;
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
index feaee3a..bf77bf1 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -35,11 +35,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.app.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.app.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
@@ -47,6 +47,7 @@
       </tr>
       </tbody>
     </table>
+
     <table class='detail-list'>
       <thead>
       <tr>
@@ -76,8 +77,8 @@
       </tr>
       </tbody>
     </table>
-    <br/>
   {{/if}}
+
   <table class='detail-list'>
     <thead>
       <tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
index a8be79f..e652cde 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -50,11 +50,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs b/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs
new file mode 100644
index 0000000..0f740cb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs
@@ -0,0 +1,19 @@
+{{!
+ * 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.
+}}
+
+{{txt content type="date" timeZone=timeZone}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs b/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
new file mode 100644
index 0000000..0d91ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
@@ -0,0 +1,25 @@
+{{!
+ * 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.
+}}
+
+{{#if value}}
+  {{#link-to routeName (query-params searchText=searchText)}}
+    {{txt value type="number"}} {{_statsType}}
+  {{/link-to}}
+{{else}}
+  {{txt value type="number"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
index 9d80c6a..e489f00 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -32,7 +32,7 @@
         <br/>
       </span>
       {{#if loadTime}}
-        Last refreshed at <b>{{txt loadTime type="date"}}</b>
+        Last refreshed at <b>{{date-formatter content=loadTime}}</b>
       {{else}}
         Load time not available!
       {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 0003a64..9bc6a80 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -42,6 +42,10 @@
         <td>{{model.entityID}}</td>
       </tr>
       <tr>
+        <td>Name</td>
+        <td>{{model.name}}</td>
+      </tr>
+      <tr>
         <td>Submitter</td>
         <td>{{model.submitter}}</td>
       </tr>
@@ -55,11 +59,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
index 1321b9f..02c88da 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
@@ -17,6 +17,48 @@
 }}
 
 {{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+    <tr>
+      <th colspan=2>Stats</th>
+    </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Succeeded Vertices</td>
+        <td>{{stats-link value=stats.succeededVertices routeName="dag.vertices" statsType="SUCCEEDED"}}</td>
+      </tr>
+      <tr>
+        <td>Total Vertices</td>
+        <td>{{stats.totalVertices}}</td>
+      </tr>
+      <tr>
+        <td>Succeeded Tasks</td>
+        <td>{{stats-link value=stats.succeededTasks routeName="dag.tasks" statsType="SUCCEEDED"}}</td>
+      </tr>
+      <tr>
+        <td>Total Tasks</td>
+        <td>{{stats.totalTasks}}</td>
+      </tr>
+      <tr>
+        <td>Failed Tasks</td>
+        <td>{{stats-link value=stats.failedTasks routeName="dag.tasks" statsType="FAILED"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Tasks</td>
+        <td>{{stats-link value=stats.killedTasks routeName="dag.tasks" statsType="KILLED"}}</td>
+      </tr>
+      <tr>
+        <td>Failed Task Attempts</td>
+        <td>{{stats-link value=stats.failedTaskAttempts routeName="dag.attempts" statsType="FAILED"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Task Attempts</td>
+        <td>{{stats-link value=stats.killedTaskAttempts routeName="dag.attempts" statsType="KILLED"}}</td>
+      </tr>
+    </tbody>
+  </table>
+
   {{em-table
   columns=visibleColumns
   rows=model

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
index 59b3aaa..71fdb90 100644
--- a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
@@ -27,6 +27,8 @@
       </div>
       {{#if model.componentName}}
         {{component model.componentName content=model.content targetObject=model.targetObject}}
+      {{else}}
+        <div class="modal-body">{{model.content}}</div>
       {{/if}}
     </div>
   </div>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
index c4b0a5a..3bcecad 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -42,11 +42,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
@@ -54,6 +54,19 @@
       </tr>
     </tbody>
   </table>
+  <table class='detail-list'>
+    <thead>
+    <tr>
+      <th colspan=2>Stats</th>
+    </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Failed Task Attempts</td>
+        <td>{{stats-link value=model.failedTaskAttempts routeName="vertex.attempts" statsType="FAILED"}}</td>
+      </tr>
+    </tbody>
+  </table>
 
   {{#if model.diagnostics}}
     <div class="panel panel-danger">

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
index cac5c92..2955882 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -20,7 +20,7 @@
   <table class='detail-list'>
     <thead>
       <tr>
-        <th colspan=2>Description</th>
+        <th colspan=2>Details</th>
       </tr>
     </thead>
     <tbody>
@@ -36,18 +36,6 @@
         <td>Processor Class</td>
         <td>{{model.processorClassName}}</td>
       </tr>
-    </tbody>
-  </table>
-
-  <br/>
-
-  <table class='detail-list'>
-    <thead>
-      <tr>
-        <th colspan=2>Details</th>
-      </tr>
-    </thead>
-    <tbody>
       <tr>
         <td>Status</td>
         <td>{{em-table-status-cell content=model.status}}</td>
@@ -58,82 +46,59 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
         <td>{{txt model.duration type="duration"}}</td>
       </tr>
-      <tr>
-        <td>First Task Start Time</td>
-        <td>
-          {{txt model.firstTaskStartTime type="date"}}
-          {{#if firstTasksToStart}}
-            [{{em-table-linked-cell content=firstTasksToStart}}]
-          {{/if}}
-        </td>
-      </tr>
-      <tr>
-        <td>Last Task Finish Time</td>
-        <td>
-          {{txt model.lastTaskFinishTime type="date"}}
-          {{#if lastTasksToFinish}}
-            [{{em-table-linked-cell content=lastTasksToFinish}}]
-          {{/if}}
-        </td>
-      </tr>
     </tbody>
   </table>
 
-  <br/>
-
   <table class='detail-list'>
     <thead>
       <tr>
-        <th colspan=2>Tasks of this Vertex</th>
+        <th colspan=2>Stats</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>Total Tasks</td>
-          <td>
-            <a href="{{pathname}}/tasks">{{txt model.totalTasks type="number"}} Tasks</a>
-          </td>
+        <td>{{txt model.totalTasks type="number"}}</td>
       </tr>
       <tr>
-        <td>Successful Tasks</td>
-        {{#if model.successfulTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=SUCCEEDED">{{txt model.successfulTasks type="number"}} Succeeded</a>
-          </td>
-        {{else}}
-          <td>{{txt model.successfulTasks type="number"}}</td>
-        {{/if}}
+        <td>Succeeded Tasks</td>
+        <td>{{stats-link value=model.succeededTasks routeName="vertex.tasks" statsType="SUCCEEDED"}}</td>
       </tr>
       <tr>
         <td>Failed Tasks</td>
-        {{#if model.failedTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=FAILED">{{txt model.failedTasks type="number"}} Failed</a>
-          </td>
-        {{else}}
-          <td>{{txt model.failedTasks type="number"}}</td>
-        {{/if}}
+        <td>{{stats-link value=model.failedTasks routeName="vertex.tasks" statsType="FAILED"}}</td>
       </tr>
       <tr>
         <td>Killed Tasks</td>
-        {{#if model.killedTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=KILLED">{{txt model.killedTasks type="number"}} Killed</a>
-          </td>
-        {{else}}
-          <td>{{txt model.killedTasks type="number"}}</td>
-        {{/if}}
-
+        <td>{{stats-link value=model.killedTasks routeName="vertex.tasks" statsType="KILLED"}}</td>
+      </tr>
+      <tr>
+        <td>First Task Start Time</td>
+        <td>
+          {{date-formatter content=model.firstTaskStartTime}}
+          {{#if firstTasksToStart}}
+            [{{em-table-linked-cell content=firstTasksToStart}}]
+          {{/if}}
+        </td>
+      </tr>
+      <tr>
+        <td>Last Task Finish Time</td>
+        <td>
+          {{date-formatter content=model.lastTaskFinishTime}}
+          {{#if lastTasksToFinish}}
+            [{{em-table-linked-cell content=lastTasksToFinish}}]
+          {{/if}}
+        </td>
       </tr>
       <tr>
         <td>Average Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 8fde220..db2cc77 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -53,7 +53,7 @@
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
     "em-helpers": "0.5.8",
-    "em-table": "0.3.9",
+    "em-table": "0.3.10",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0",
     "phantomjs": "^1.9.19"

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js b/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js
new file mode 100644
index 0000000..dad41f9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('date-formatter', 'Integration | Component | em table date-formatter cell', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  this.render(hbs`{{date-formatter}}`);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#date-formatter}}
+      template block text
+    {{/date-formatter}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js b/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js
new file mode 100644
index 0000000..ad2dc7b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('stats-link', 'Integration | Component | stats link', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  this.render(hbs`{{stats-link}}`);
+  assert.equal(this.$().text().trim(), 'Not Available!');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#stats-link}}
+      template block text
+    {{/stats-link}}
+  `);
+  assert.equal(this.$().text().trim(), 'Not Available!');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index 402b629..53cf7f2 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:app/dags', 'Unit | Controller | app/dags', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: Ember.K
   });

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index f0aeeb9..f1d3d01 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
index cb9ab66..6b7ecb6 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/graphical', 'Unit | Controller | dag/graphical', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
index 956eee3..166ee6b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/index/index', 'Unit | Controller | dag/index/index', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index 474c61a..a288244 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index d0b32f3..fa7bec0 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index 996dd39..98f2815 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -30,6 +30,7 @@ test('Basic creation test', function(assert) {
 
   let controller = this.subject({
     initVisibleColumns: Ember.K,
+    beforeSort: {bind: Ember.K},
     send: function (name, query) {
       assert.equal(name, "setBreadcrumbs");
       assert.ok(query);

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
index d4ab10f..27e32fc 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
@@ -27,6 +27,7 @@ moduleFor('controller:multi-table', 'Unit | Controller | multi table', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     localStorage: Ember.Object.create(),
     getCounterColumns: function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
index 360b6a9..110fec2 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
@@ -48,6 +48,7 @@ test('Basic creation test', function(assert) {
   assert.ok(controller.storageID);
   assert.ok(controller.initVisibleColumns);
 
+  assert.ok(controller.beforeSort);
   assert.ok(controller.columns);
   assert.ok(controller.allColumns);
   assert.ok(controller.visibleColumns);

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
index b2006de..4db8dac 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:task/attempts', 'Unit | Controller | task/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
index eb68055..142fa58 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
index 9aae299..6949ba5 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/1f5f1b6f/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
index 9ca049a..86cd472 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
@@ -54,7 +54,7 @@ test('pendingTasks test', function(assert) {
     model.set("totalTasks", null);
     assert.equal(model.get("pendingTasks"), null);
     model.set("totalTasks", 2);
-    model.set("_successfulTasks", 1);
+    model.set("_succeededTasks", 1);
     model.set("status", "SUCCEEDED");
     assert.equal(model.get("pendingTasks"), 1);
   });