You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by rb...@apache.org on 2015/01/29 13:37:59 UTC

tez git commit: TEZ-1946. Tez UI: add source & sink views, add counters to vertices/all task views (Sreenath Somarajapuram via rbalamohan)

Repository: tez
Updated Branches:
  refs/heads/master e84c1aa7a -> 3a45508b9


TEZ-1946. Tez UI: add source & sink views, add counters to vertices/all task views (Sreenath Somarajapuram via rbalamohan)


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

Branch: refs/heads/master
Commit: 3a45508b92f4863a9b53a329d8522b9900e397f0
Parents: e84c1aa
Author: Rajesh Balamohan <rb...@hortonworks.com>
Authored: Thu Jan 29 18:07:11 2015 +0530
Committer: Rajesh Balamohan <rb...@hortonworks.com>
Committed: Thu Jan 29 18:07:11 2015 +0530

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 tez-ui/src/main/webapp/app/scripts/app.js       |   9 +
 tez-ui/src/main/webapp/app/scripts/configs.js   |  15 +-
 .../app/scripts/controllers/dag_vertices.js     |  27 +-
 .../vertex-additionals-controller.js            | 108 ++++++++
 .../scripts/controllers/vertex_controller.js    |   2 +-
 .../main/webapp/app/scripts/default-configs.js  | 275 ++++++++++++++++---
 .../main/webapp/app/scripts/helpers/dialogs.js  |   2 +-
 .../src/main/webapp/app/scripts/helpers/misc.js |  19 +-
 .../app/scripts/models/TimelineRestAdapter.js   |  68 ++++-
 .../src/main/webapp/app/scripts/models/dag.js   |  14 +-
 tez-ui/src/main/webapp/app/scripts/router.js    |  31 ++-
 tez-ui/src/main/webapp/app/styles/colors.less   |  36 +++
 tez-ui/src/main/webapp/app/styles/main.less     |  30 +-
 tez-ui/src/main/webapp/app/styles/shared.less   |  42 +++
 .../webapp/app/templates/common/configs.hbs     |  29 +-
 .../main/webapp/app/templates/input/configs.hbs |  42 +++
 .../webapp/app/templates/output/configs.hbs     |  39 +++
 .../webapp/app/templates/partials/configs.hbs   |  27 ++
 .../webapp/app/templates/vertex/additionals.hbs |  45 +++
 .../main/webapp/app/templates/vertex/inputs.hbs |  36 ---
 21 files changed, 733 insertions(+), 164 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9e64a0b..cae1af9 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -54,6 +54,7 @@ Release 0.6.1: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-1946. Tez UI: add source & sink views, add counters to vertices/all task views.
   TEZ-1987. Tez UI non-standalone mode uses invalid protocol.
   TEZ-1983. Tez UI swimlane task attempt link is broken
 

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/app.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/app.js b/tez-ui/src/main/webapp/app/scripts/app.js
index fe2ea4d..5beb815 100644
--- a/tez-ui/src/main/webapp/app/scripts/app.js
+++ b/tez-ui/src/main/webapp/app/scripts/app.js
@@ -31,6 +31,11 @@ var App = window.App = Em.Application.createWithMixins(Bootstrap, {
 
   env: {
     isStandalone: true // Can ne set false in the wrapper initializer
+  },
+
+  setConfigs: function (configs) {
+    App.Helpers.misc.merge(App.Configs, configs);
+    App.advanceReadiness();
   }
 });
 App.deferReadiness();
@@ -72,6 +77,9 @@ App.ready = function () {
             if(vertexData && vertexData.additionalInputs) {
               data.inputs = vertexData.additionalInputs;
             }
+            if(vertexData && vertexData.additionalOutputs) {
+              data.outputs = vertexData.additionalOutputs;
+            }
           }
           return data;
         });
@@ -115,4 +123,5 @@ require('scripts/models/**/*');
 require('scripts/controllers/**/*');
 
 require('scripts/components/*');
+require('scripts/components/dag-view/*');
 require('scripts/adapters/*');

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/configs.js b/tez-ui/src/main/webapp/app/scripts/configs.js
index d07965d..b0397d8 100644
--- a/tez-ui/src/main/webapp/app/scripts/configs.js
+++ b/tez-ui/src/main/webapp/app/scripts/configs.js
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-$.extend(true, App.Configs, {
+App.setConfigs({
 
   /* Environment configurations */
   envDefaults: {
@@ -39,10 +39,11 @@ $.extend(true, App.Configs, {
    * as columns edit the following 'tables' object. Counters must be added as configuration objects
    * of the following format.
    *    {
-   *      counterId: '<Counter ID>',
-   *      groupId: '<Group ID>',
-   *      headerText: '<Display text>'
+   *      counterName: '<Counter ID>',
+   *      counterGroupName: '<Group ID>',
    *    }
+   *
+   * Note: Till 0.6.0 the properties were counterId and groupId, their use is deprecated now.
    */
   tables: {
     /*
@@ -51,9 +52,8 @@ $.extend(true, App.Configs, {
     entity: {
       dag: [
         // { // Following is a sample configuration object.
-        //   counterId: 'FILE_BYTES_READ',
-        //   groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-        //   headerText: 'File Bytes Read'
+        //   counterName: 'FILE_BYTES_READ',
+        //   counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
         // }
       ],
       vertex: [],
@@ -69,4 +69,3 @@ $.extend(true, App.Configs, {
 
 });
 
-App.advanceReadiness();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
index 8e3a2d4..c50280e 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
@@ -127,23 +127,28 @@ App.DagVerticesController = Em.ObjectController.extend(App.PaginatedContentMixin
       },
       {
         id: 'configurations',
-        headerCellName: 'Input Configurations',
+        headerCellName: 'Source/Sink Configs',
         tableCellViewClass: Em.Table.TableCell.extend({
           template: Em.Handlebars.compile(
-            " {{#if view.cellContent.inputId}}\
-                {{#if view.cellContent.showConfigs}}\
-                 {{#link-to 'vertexInput.configs' view.cellContent.vertexId view.cellContent.inputId class='ember-table-content'}}View configurations{{/link-to}}\
-                {{else}}\
-                 {{#link-to 'vertex.inputs' view.cellContent.vertexId class='ember-table-content'}}View Inputs{{/link-to}}\
-                {{/if}}\
+            " {{#if view.cellContent.linkToAdditionals}}\
+                {{#link-to 'vertex.additionals' view.cellContent.vertexId class='ember-table-content'}}View sources & sinks{{/link-to}}\
+              {{else}}{{#if view.cellContent.inputId}}\
+                {{#link-to 'input.configs' view.cellContent.vertexId view.cellContent.inputId class='ember-table-content'}}View source configs{{/link-to}}\
+              {{else}}{{#if view.cellContent.outputId}}\
+                {{#link-to 'output.configs' view.cellContent.vertexId view.cellContent.outputId class='ember-table-content'}}View sink configs{{/link-to}}\
               {{else}}\
-                <span class='ember-table-content'>No Inputs</span>\
-              {{/if}}")
+                <span class='ember-table-content'>No source or sink</span>\
+              {{/if}}{{/if}}{{/if}}")
         }),
         getCellContent: function(row) {
+          var firstInputId = row.get('inputs.content.0.id'),
+              firstOutputId = row.get('outputs.content.0.id');
           return {
-            showConfigs: row.get('inputs.content.length') == 1 && row.get('inputs.content.0.configs.length') > 0,
-            inputId: row.get('inputs.content.0.id'),
+            linkToAdditionals: row.get('inputs.content.length') > 1 ||
+                row.get('outputs.content.length') > 1 ||
+                (firstInputId != undefined && firstOutputId != undefined),
+            inputId: firstInputId,
+            outputId: firstOutputId,
             vertexId: row.get('id')
           };
         }

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js
new file mode 100644
index 0000000..61c2616
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ */
+
+App.VertexAdditionalsController = Em.ObjectController.extend({
+  needs: 'vertex',
+
+  controllerName: 'VertexAdditionalsController',
+
+  loadEntities: function() {
+    var inputs = this.get('inputs.content'),
+        outputs = this.get('outputs.content');
+
+    this.set('inputContent', inputs);
+    this.set('inputsAvailable', inputs.length > 0);
+
+    this.set('outputContent', outputs);
+    this.set('outputsAvailable', outputs.length > 0);
+
+    this.set('loading', false);
+  },
+
+  inputColumns: function() {
+    return App.Helpers.misc.createColumnsFromConfigs([
+      {
+        id: 'inputId',
+        headerCellName: 'Name',
+        contentPath: 'inputName',
+      },
+      {
+        id: 'inputClass',
+        headerCellName: 'Class',
+        contentPath: 'inputClass',
+      },
+      {
+        id: 'inputInitializer',
+        headerCellName: 'Initializer',
+        contentPath: 'inputInitializer',
+      },
+      {
+        id: 'configurations',
+        headerCellName: 'Configurations',
+        tableCellViewClass: Em.Table.TableCell.extend({
+          template: Em.Handlebars.compile(
+            "{{#if view.cellContent.count}}\
+              {{#link-to 'input.configs' view.cellContent.id class='ember-table-content'}}View Configurations{{/link-to}}\
+            {{else}}\
+              <span class='ember-table-content'>Not Available</span>\
+            {{/if}}")
+        }),
+        getCellContent: function(row) {
+          return {
+            count: row.get('configs.content.length'),
+            id: row.get('id')
+          };
+        }
+      }
+    ]);
+  }.property(),
+
+  outputColumns: function() {
+    return App.Helpers.misc.createColumnsFromConfigs([
+      {
+        id: 'outputId',
+        headerCellName: 'Name',
+        contentPath: 'outputName',
+      },
+      {
+        id: 'outputClass',
+        headerCellName: 'Class',
+        contentPath: 'outputClass',
+      },
+      {
+        id: 'configurations',
+        headerCellName: 'Configurations',
+        tableCellViewClass: Em.Table.TableCell.extend({
+          template: Em.Handlebars.compile(
+            "{{#if view.cellContent.count}}\
+              {{#link-to 'output.configs' view.cellContent.id class='ember-table-content'}}View Configurations{{/link-to}}\
+            {{else}}\
+              <span class='ember-table-content'>Not Available</span>\
+            {{/if}}")
+        }),
+        getCellContent: function(row) {
+          return {
+            count: row.get('configs.content.length'),
+            id: row.get('id')
+          };
+        }
+      }
+    ]);
+  }.property(),
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
index 7e05eba..1c20b3e 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
@@ -33,6 +33,6 @@ App.VertexController = Em.ObjectController.extend(App.Helpers.DisplayHelper, {
     Ember.Object.create({title: 'Task Attempts', linkTo: 'vertex.taskAttempts'}),
     Ember.Object.create({title: 'Counters', linkTo: 'vertex.counters'}),
     Ember.Object.create({title: 'Swimlane', linkTo: 'vertex.swimlane'}),
-    Ember.Object.create({title: 'Inputs', linkTo: 'vertex.inputs'}),
+    Ember.Object.create({title: 'Sources & Sinks', linkTo: 'vertex.additionals'}),
   ],
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/default-configs.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/default-configs.js b/tez-ui/src/main/webapp/app/scripts/default-configs.js
index 48da014..eba6a7e 100644
--- a/tez-ui/src/main/webapp/app/scripts/default-configs.js
+++ b/tez-ui/src/main/webapp/app/scripts/default-configs.js
@@ -43,57 +43,270 @@ $.extend(true, App.Configs, {
     applicationHistory: 'ws/v1/applicationhistory'
   },
 
+  tables: {
+    entity: {
+      dag: [
+        // DAG Counters
+        {
+          counterName :"NUM_FAILED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_KILLED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_SUCCEEDED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"TOTAL_LAUNCHED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"OTHER_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"DATA_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"RACK_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"SLOTS_MILLIS_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"FALLOW_SLOTS_MILLIS_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"TOTAL_LAUNCHED_UBERTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_UBER_SUBTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_FAILED_UBERTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+
+        {
+          counterName: "REDUCE_OUTPUT_RECORDS",
+          counterGroupName: "REDUCE_OUTPUT_RECORDS",
+        },
+        {
+          counterName: "REDUCE_SKIPPED_GROUPS",
+          counterGroupName: "REDUCE_SKIPPED_GROUPS",
+        },
+        {
+          counterName: "REDUCE_SKIPPED_RECORDS",
+          counterGroupName: "REDUCE_SKIPPED_RECORDS",
+        },
+        {
+          counterName: "COMBINE_OUTPUT_RECORDS",
+          counterGroupName: "COMBINE_OUTPUT_RECORDS",
+        },
+        {
+          counterName: "SKIPPED_RECORDS",
+          counterGroupName: "SKIPPED_RECORDS",
+        },
+        {
+          counterName: "INPUT_GROUPS",
+          counterGroupName: "INPUT_GROUPS",
+        }
+      ]
+    }
+  },
+
   defaultCounters: [
     // File System Counters
     {
-      counterId: 'FILE_BYTES_READ',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'File Bytes Read'
+      counterName: 'FILE_BYTES_READ',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'FILE_BYTES_WRITTEN',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'File Bytes Written'
+      counterName: 'FILE_BYTES_WRITTEN',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'FILE_READ_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'File Read Ops'
+      counterName: 'FILE_READ_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'FILE_LARGE_READ_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'File Large Read Ops'
+      counterName: 'FILE_LARGE_READ_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'FILE_WRITE_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'File Write Ops'
+      counterName: 'FILE_WRITE_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'HDFS_BYTES_READ',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'HDFS Bytes Read'
+      counterName: 'HDFS_BYTES_READ',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'HDFS_BYTES_WRITTEN',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'HDFS Bytes Written'
+      counterName: 'HDFS_BYTES_WRITTEN',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'HDFS_READ_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'HDFS Read Ops'
+      counterName: 'HDFS_READ_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'HDFS_LARGE_READ_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'HDFS Large Read Ops'
+      counterName: 'HDFS_LARGE_READ_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
     },
     {
-      counterId: 'HDFS_WRITE_OPS',
-      groupId: 'org.apache.tez.common.counters.FileSystemCounter',
-      headerText: 'HDFS Write Ops'
-    }
+      counterName: 'HDFS_WRITE_OPS',
+      counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+    },
+
+    // Task Counters
+    {
+      counterName: "NUM_SPECULATIONS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "REDUCE_INPUT_GROUPS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "REDUCE_INPUT_RECORDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SPLIT_RAW_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "COMBINE_INPUT_RECORDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SPILLED_RECORDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "NUM_SHUFFLED_INPUTS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "NUM_SKIPPED_INPUTS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "NUM_FAILED_SHUFFLE_INPUTS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "MERGED_MAP_OUTPUTS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "GC_TIME_MILLIS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "CPU_MILLISECONDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "PHYSICAL_MEMORY_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "VIRTUAL_MEMORY_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "COMMITTED_HEAP_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "INPUT_RECORDS_PROCESSED",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "OUTPUT_RECORDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "OUTPUT_LARGE_RECORDS",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "OUTPUT_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "OUTPUT_BYTES_WITH_OVERHEAD",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "OUTPUT_BYTES_PHYSICAL",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "ADDITIONAL_SPILLS_BYTES_WRITTEN",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "ADDITIONAL_SPILLS_BYTES_READ",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "ADDITIONAL_SPILL_COUNT",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_BYTES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_BYTES_DECOMPRESSED",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_BYTES_TO_MEM",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_BYTES_TO_DISK",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_BYTES_DISK_DIRECT",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "NUM_MEM_TO_DISK_MERGES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "NUM_DISK_TO_DISK_MERGES",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "SHUFFLE_PHASE_TIME",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "MERGE_PHASE_TIME",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "FIRST_EVENT_RECEIVED",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
+    {
+      counterName: "LAST_EVENT_RECEIVED",
+      counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+    },
   ]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js
index 253c8ab..4acd082 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js
@@ -41,7 +41,7 @@ App.Dialogs = Em.Namespace.create({
       var id = getProperty(item, 'id'),
           displayText = getProperty(item, 'displayText');
 
-      listHTML += '<li><input id=%@ type="checkbox" %@ /> %@</li>'.fmt(
+      listHTML += '<li class="no-wrap"><input id=%@ type="checkbox" %@ /> %@</li>'.fmt(
         id,
         selectedItems[id] ? 'checked' : '',
         displayText

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
index 07de80a..69f0037 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
@@ -81,8 +81,9 @@ App.Helpers.misc = {
    */
   normalizeCounterConfigs: function (counterConfigs) {
     return counterConfigs.map(function (configuration) {
-      configuration.headerCellName = configuration.headerCellName || configuration.counterId;
-      configuration.id = '%@/%@'.fmt(configuration.groupId, configuration.counterId),
+      configuration.headerCellName = configuration.counterName || configuration.counterId;
+      configuration.id = '%@/%@'.fmt(configuration.counterGroupName || configuration.groupId,
+          configuration.counterName || configuration.counterId),
       configuration.getCellContent = App.Helpers.misc.getCounterCellContent;
       return configuration;
     });
@@ -153,6 +154,20 @@ App.Helpers.misc = {
     };
   },
 
+  merge: function objectMerge(obj1, obj2) {
+    $.each(obj2, function (key, val) {
+      if(Array.isArray(obj1[key]) && Array.isArray(val)) {
+        $.merge(obj1[key], val);
+      }
+      else if($.isPlainObject(obj1[key]) && $.isPlainObject(val)) {
+        objectMerge(obj1[key], val);
+      }
+      else {
+        obj1[key] = val;
+      }
+    });
+  },
+
   dagStatusUIOptions: [
     { label: 'All', id: null },
     { label: 'Submitted', id: 'SUBMITTED' },

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
index d5d5858..6794e7d 100644
--- a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
+++ b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
@@ -75,7 +75,7 @@ App.TimelineSerializer = DS.RESTSerializer.extend({
         var c = {
           id: cg.id + '/' + counter.counterName,
           name: counter.counterName,
-          displayName: counter.counterDisplayName,
+          displayName: counter.counterName,
           value: counter.counterValue,
           parentID: cg.id
         };
@@ -281,6 +281,7 @@ var timelineJsonToVertexMap = {
   processorClassName: 'processorClassName',
   counterGroups: 'counterGroups',
   inputs: 'inputs',
+  outputs: 'outputs',
 
   startTime: 'otherinfo.startTime',
   endTime: 'otherinfo.endTime',
@@ -312,8 +313,10 @@ App.VertexSerializer = App.TimelineSerializer.extend({
     var normalizedCounterGroupData = this.normalizeCounterGroupsHelper('vertex', vertex.entity,
         vertex),
     processorClassName = Ember.get(vertex, 'otherinfo.processorClassName'),
-    vertexInputs = [],
-    inputIds = [];
+    inputs = [],
+    inputIds = [],
+    outputs = [],
+    outputIds = [];
 
     vertex.processorClassName = processorClassName.substr(processorClassName.lastIndexOf('.') + 1),
     vertex.counterGroups = normalizedCounterGroupData.counterGroupsIDs;
@@ -324,15 +327,25 @@ App.VertexSerializer = App.TimelineSerializer.extend({
       vertex.inputs.forEach(function (input, index) {
         input.entity = vertex.entity + '-input' + index;
         inputIds.push(input.entity);
-        vertexInputs.push(input);
+        inputs.push(input);
       });
       vertex.inputs = inputIds;
     }
 
+    if(vertex.outputs) {
+      vertex.outputs.forEach(function (output, index) {
+        output.entity = vertex.entity + '-output' + index;
+        outputIds.push(output.entity);
+        outputs.push(output);
+      });
+      vertex.outputs = outputIds;
+    }
+
     return {
       vertex: vertex,
       counterGroups: normalizedCounterGroupData.counterGroups,
-      vertexInputs: vertexInputs,
+      inputs: inputs,
+      outputs: outputs,
       counters: normalizedCounterGroupData.counters
     };
   },
@@ -342,7 +355,8 @@ App.VertexSerializer = App.TimelineSerializer.extend({
       var normalizedPayload = {
         vertices: [],
         counterGroups: [],
-        vertexInputs: [],
+        inputs: [],
+        outputs: [],
         counters: []
       };
       rawPayload.vertices.forEach(function(vertex){
@@ -350,7 +364,8 @@ App.VertexSerializer = App.TimelineSerializer.extend({
         normalizedPayload.vertices.push(n.vertex);
         [].push.apply(normalizedPayload.counterGroups, n.counterGroups);
         [].push.apply(normalizedPayload.counters, n.counters);
-        [].push.apply(normalizedPayload.vertexInputs, n.vertexInputs);
+        [].push.apply(normalizedPayload.inputs, n.inputs);
+        [].push.apply(normalizedPayload.outputs, n.outputs);
       }, this);
       
       // delete so that we dont hang on to the json data.
@@ -367,7 +382,7 @@ App.VertexSerializer = App.TimelineSerializer.extend({
   },
 });
 
-App.VertexInputSerializer = App.TimelineSerializer.extend({
+App.InputSerializer = App.TimelineSerializer.extend({
   _map: {
     id: 'entity',
     inputName: 'name',
@@ -405,6 +420,43 @@ App.VertexInputSerializer = App.TimelineSerializer.extend({
   }
 });
 
+App.OutputSerializer = App.TimelineSerializer.extend({
+  _map: {
+    id: 'entity',
+    outputName: 'name',
+    outputClass: 'class',
+    configs: 'configs'
+  },
+  _normalizeData: function(data) {
+    var userPayload = JSON.parse(data.userPayloadAsText || null),
+        store = this.get('store'),
+        configs,
+        configKey,
+        configIndex = 0,
+        id;
+
+    data.configs = [];
+
+    if(userPayload) {
+      configs = userPayload.config || userPayload.dist;
+      for(configKey in configs) {
+        id = data.entity + configIndex++;
+        data.configs.push(id);
+        store.push('KVDatum', {
+          id: id,
+          key: configKey,
+          value: configs[configKey]
+        });
+      }
+    }
+
+    return data;
+  },
+  normalize: function(type, hash, prop) {
+    return Em.JsonMapper.map(this._normalizeData(hash), this._map);
+  }
+});
+
 var timelineJsonToAppDetailMap = {
   id: 'appId',
   attemptId: 'currentAppAttemptId',

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/models/dag.js b/tez-ui/src/main/webapp/app/scripts/models/dag.js
index e677478..c729712 100644
--- a/tez-ui/src/main/webapp/app/scripts/models/dag.js
+++ b/tez-ui/src/main/webapp/app/scripts/models/dag.js
@@ -221,7 +221,8 @@ App.Vertex = DS.Model.extend({
 
   recordWriteCount: DS.attr('number'),
 
-  inputs: DS.hasMany('vertexInput'),
+  inputs: DS.hasMany('input'),
+  outputs: DS.hasMany('output'),
 
   totalReadBytes: function () {
     return this.get('fileReadBytes') + this.get('hdfsReadBytes');
@@ -244,7 +245,7 @@ App.Vertex = DS.Model.extend({
   }.property('duration')
 });
 
-App.VertexInput = DS.Model.extend({
+App.Input = DS.Model.extend({
   entity: DS.attr('string'),
 
   inputName: DS.attr('string'),
@@ -254,6 +255,15 @@ App.VertexInput = DS.Model.extend({
   configs: DS.hasMany('kVData', { async: false })
 });
 
+App.Output = DS.Model.extend({
+  entity: DS.attr('string'),
+
+  outputName: DS.attr('string'),
+  outputClass: DS.attr('string'),
+
+  configs: DS.hasMany('kVData', { async: false })
+});
+
 App.AppDetail = DS.Model.extend({
   attemptId: DS.attr('string'),
 

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/router.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/router.js b/tez-ui/src/main/webapp/app/scripts/router.js
index f33bcca..ddc8365 100644
--- a/tez-ui/src/main/webapp/app/scripts/router.js
+++ b/tez-ui/src/main/webapp/app/scripts/router.js
@@ -33,8 +33,11 @@ App.Router.map(function() {
 
   this.resource('vertex', {path: '/vertex/:vertex_id'}, function(){
     this.route('tasks');
-    this.route('inputs');
-    this.resource('vertexInput', {path: '/input/:input_id'}, function(){
+    this.route('additionals');
+    this.resource('input', {path: '/input/:input_id'}, function(){
+      this.route('configs');
+    });
+    this.resource('output', {path: '/output/:input_id'}, function(){
       this.route('configs');
     });
     this.route('taskAttempts');
@@ -48,9 +51,11 @@ App.Router.map(function() {
     this.route('attempts');
     this.route('counters');
   });
+
   this.resource('taskAttempt', {path: '/task_attempt/:task_attempt_id'}, function() {
     this.route('counters');
   });
+
   this.resource('error', {path: '/error'});
 });
 
@@ -138,6 +143,10 @@ App.DagRoute = Em.Route.extend({
   setupController: setupControllerFactory('Dag: %@ (%@)', 'name', 'id')
 });
 
+App.DagViewRoute = Em.Route.extend({
+  setupController: setupControllerFactory()
+});
+
 App.DagSwimlaneRoute = Em.Route.extend({
   renderTemplate: renderSwimlanes,
   model: function(params) {
@@ -177,25 +186,25 @@ App.VertexRoute = Em.Route.extend({
   setupController: setupControllerFactory('Vertex: %@ (%@)', 'name', 'id')
 });
 
-App.VertexInputsRoute = Em.Route.extend({
+App.VertexAdditionalsRoute = Em.Route.extend({
   setupController: function(controller, model) {
     this._super(controller, model);
     controller.loadEntities();
   }
 });
 
-App.VertexInputConfigsRoute = Em.Route.extend({
-  renderTemplate: renderConfigs,
-  setupController: function(controller, model) {
-    this._super(controller, model)
-    controller.set('needToShowInputDetails', true);
-  }
+App.InputRoute = Em.Route.extend({
+  model: function (params) {
+    var model = this.modelFor('vertex');
+    return model.get('inputs').findBy('id', params.input_id);
+  },
+  setupController: setupControllerFactory()
 });
 
-App.VertexInputRoute = Em.Route.extend({
+App.OutputRoute = Em.Route.extend({
   model: function (params) {
     var model = this.modelFor('vertex');
-    return model.get('inputs').findBy('id', params.input_id);
+    return model.get('outputs').findBy('id', params.input_id);
   },
   setupController: setupControllerFactory()
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/colors.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/colors.less b/tez-ui/src/main/webapp/app/styles/colors.less
new file mode 100644
index 0000000..b8e3b6e
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/styles/colors.less
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+// Colors
+@logo-orange: #D27A22;
+@bg-lite: #f5f5f5;
+@bg-liter: #f5f5f5;
+@border-lite: #e5e5e5;
+@bg-red-light: #FFE6E6;
+
+@white: #fff;
+
+@text-color: #666666;
+@text-red: red;
+
+@top-nav-bg-color-from: #d5d5d5;
+@top-nav-bg-color-to: #f0f0f0;
+
+@success-color: limegreen;
+@error-color: crimson;
+@warning-color: orange;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/main.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/main.less b/tez-ui/src/main/webapp/app/styles/main.less
index 0f95485..57fa437 100644
--- a/tez-ui/src/main/webapp/app/styles/main.less
+++ b/tez-ui/src/main/webapp/app/styles/main.less
@@ -16,29 +16,14 @@
  * limitations under the License.
  */
 
-
-// Colors
-@logo-orange: #D27A22;
-@bg-lite: #f5f5f5;
-@border-lite: #e5e5e5;
-@bg-red-light: #FFE6E6;
-
-@white: #fff;
-
-@text-color: #666666;
-@text-red: red;
-
-@top-nav-bg-color-from: #d5d5d5;
-@top-nav-bg-color-to: #f0f0f0;
-
-@success-color: limegreen;
-@error-color: crimson;
-@warning-color: orange;
-
 // Imports
 @import "../bower_components/font-awesome/less/font-awesome";
 @import "../bower_components/bootstrap/less/bootstrap"; //UI theme
 
+// Colors
+@import "app/styles/colors";
+@import "app/styles/shared";
+
 // Base style
 body, html, body > .ember-view {
   height: 100%;
@@ -205,11 +190,6 @@ body, html, body > .ember-view {
   }
 }
 
-.fa-icon(@name) {
-    @content: "fa-var-@{name}";
-    &:before {content: @@content}
-}
-
 /* misc helpers */
 .inline-block {
   display: inline-block;
@@ -441,4 +421,4 @@ div.indent {
 .align-close-button {
   margin-left: -1px;
   margin-top: -1px;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/shared.less b/tez-ui/src/main/webapp/app/styles/shared.less
new file mode 100644
index 0000000..341bb10
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/styles/shared.less
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+.fa-icon(@name) {
+  @content: "fa-var-@{name}";
+  &:before {content: @@content}
+}
+
+.no-select {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+
+  cursor: default;
+}
+
+.no-display {
+  display: none !important;
+}
+
+.no-pointer {
+  pointer-events: none;
+}
+
+.no-wrap {
+  white-space: nowrap;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/common/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/common/configs.hbs b/tez-ui/src/main/webapp/app/templates/common/configs.hbs
index 8abf055..000a645 100644
--- a/tez-ui/src/main/webapp/app/templates/common/configs.hbs
+++ b/tez-ui/src/main/webapp/app/templates/common/configs.hbs
@@ -16,31 +16,4 @@
 * limitations under the License.
 }}
 
-{{#if needToShowInputDetails}}
-  <div class='align-left margin-small-horizontal' style="margin-bottom:10px;">
-    <table class='detail-list'>
-      <thead>
-        <tr>
-          <th>Input Details</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>Name</td>
-          <td>{{inputName}}</td>
-        </tr>
-        <tr>
-          <td>Class</td>
-          <td>{{inputClass}}</td>
-        </tr>
-        <tr>
-          <td>Initializer</td>
-          <td>{{inputInitializer}}</td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-{{/if}}
-<div class='table-container'>
-  {{kv-table-component data=configs}}
-</div>
+{{partial 'partials/configs'}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/input/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/input/configs.hbs b/tez-ui/src/main/webapp/app/templates/input/configs.hbs
new file mode 100644
index 0000000..83c6ed9
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/templates/input/configs.hbs
@@ -0,0 +1,42 @@
+{{!
+* 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='margin-small-horizontal' style="margin-bottom:10px;">
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th>Source Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Name</td>
+        <td>{{inputName}}</td>
+      </tr>
+      <tr>
+        <td>Class</td>
+        <td>{{inputClass}}</td>
+      </tr>
+      <tr>
+        <td>Initializer</td>
+        <td>{{inputInitializer}}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+{{partial 'partials/configs'}}

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/output/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/output/configs.hbs b/tez-ui/src/main/webapp/app/templates/output/configs.hbs
new file mode 100644
index 0000000..3c5dd59
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/templates/output/configs.hbs
@@ -0,0 +1,39 @@
+{{!
+* 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='margin-small-horizontal' style="margin-bottom:10px;">
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th>Sink Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Name</td>
+        <td>{{outputName}}</td>
+      </tr>
+      <tr>
+        <td>Class</td>
+        <td>{{outputClass}}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+{{partial 'partials/configs'}}
+

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/partials/configs.hbs b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs
new file mode 100644
index 0000000..a639352
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs
@@ -0,0 +1,27 @@
+{{!
+* 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 configs}}
+  <div class='table-container'>
+    {{kv-table-component data=configs}}
+  </div>
+{{else}}
+  <div class='margin-small-horizontal'>
+    <h4>No configurations available!</h4>
+  </div>
+{{/if}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs
new file mode 100644
index 0000000..bb85eb3
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs
@@ -0,0 +1,45 @@
+{{!
+* 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.
+}}
+
+{{#unless loading}}
+  <h3>Sources</h3>
+  {{#if inputsAvailable}}
+    {{extended-table-component
+      hasFooter=false
+      columnsBinding="inputColumns"
+      contentBinding="inputContent"
+      forceFillColumns=true
+    }}
+  {{else}}
+    <h4>Not available!</h4>
+  {{/if}}
+
+  <h3>Sinks</h3>
+  {{#if outputsAvailable}}
+    {{extended-table-component
+      hasFooter=false
+      columnsBinding="outputColumns"
+      contentBinding="outputContent"
+      forceFillColumns=true
+    }}
+  {{else}}
+    <h4>Not available!</h4>
+  {{/if}}
+{{else}}
+  {{partial 'partials/loading-spinner'}}
+{{/unless}}

http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs b/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs
deleted file mode 100644
index 972951d..0000000
--- a/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs
+++ /dev/null
@@ -1,36 +0,0 @@
-{{!
-* 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.
-}}
-
-{{#unless loading}}
-  {{#if inputsAvailable}}
-    <div class='margin-small align-children-right'>
-      {{page-nav-component
-        hasPrev=hasPrev
-        hasNext=hasNext
-        navNext='navigateNext'
-        navPrev='navigatePrev'
-        navFirst='navigateFirst'
-      }}
-    </div>
-    {{partial 'partials/table'}}
-  {{else}}
-    <h1>Inputs are not available!</h1>
-  {{/if}}
-{{else}}
-  {{partial 'utils/loading-spinner'}}
-{{/unless}}