You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by je...@apache.org on 2014/12/10 04:33:44 UTC

[21/53] tez git commit: TEZ-1708. Make UI part of TEZ build process. (Sreenath Somarajapuram via hitesh)

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/login.html
----------------------------------------------------------------------
diff --git a/tez-ui/original/login.html b/tez-ui/original/login.html
deleted file mode 100644
index dc0a89d..0000000
--- a/tez-ui/original/login.html
+++ /dev/null
@@ -1,51 +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.
- */ -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-    <title>TEZ UI</title>
-    <script src="lib/jquery.js"></script>
-    <script src="/jquery-cookie/jquery.cookie.js"></script>
-    <script src="login.js"></script>
-    <link rel="stylesheet" type="text/css" href="css/jquery.dataTables.min.css">
-    <script type="text/javascript" charset="utf8" src="lib/jquery.dataTables.min.js"></script>
-    <script>
-      function f(){
-        var hostname=document.getElementById('sid').value;
-        var port=document.getElementById('port_id').value;
-        if(hostname.length==0)
-        alert("hostname can't be blank");
-        else if(port.length==0)
-        alert("port number can't be blank");
-        else{
-          window.sessionStorage.setItem('hostname',hostname);
-          window.sessionStorage.setItem('port',port);
-          window.open("application_page.html");
-        }
-      }
-    </script>
-  </head>
-
-  <body>
-    SERVER HOSTNAME: <input type="text" id="sid">
-    <br/>
-    SERVER PORT: <input type="text" id="port_id">
-    <br/>
-    <input type = "button" onclick="f()" value="Log in">
-  </body>

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/task_attempt_page.html
----------------------------------------------------------------------
diff --git a/tez-ui/original/task_attempt_page.html b/tez-ui/original/task_attempt_page.html
deleted file mode 100644
index e827588..0000000
--- a/tez-ui/original/task_attempt_page.html
+++ /dev/null
@@ -1,60 +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.
- */ -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-    <title>TEZ UI</title>
-    <script src="lib/jquery.js"></script>
-    <script src="task_attempt_page.js"></script>
-    <link rel="stylesheet" type="text/css" href="css/jquery.dataTables.min.css">
-    <script type="text/javascript" charset="utf8" src="lib/jquery.dataTables.min.js"></script>
-  </head>
-
-  <body>
-    <div>
-      <center><h2 id=taskattemptid>Task Attempt Id</h2></center>
-      <table id='task_attempt_overview' class='display'>
-        <caption>Task Attempt Overview</caption>
-        <thead>
-          <tr>
-            <th>Task Attempt Id</th>	
-            <th>Start Time</th>
-            <th>End Time</th>
-            <th>Time Taken</th>
-            <th>Status</th>
-            <th>Progress Logs</th>
-            <th>Completed Logs</th>
-          </tr>
-        </thead>
-      </table>
-    </div>
-    <div id="counters">
-      <table id='counter' class='display'>
-        <thead>
-          <tr>
-            <th>Counter Group</th>
-            <th>Counters</th>
-          </tr>
-        </thead>
-        <tbody id="counterbody">
-        </tbody>
-      </table>
-    </div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/task_attempt_page.js
----------------------------------------------------------------------
diff --git a/tez-ui/original/task_attempt_page.js b/tez-ui/original/task_attempt_page.js
deleted file mode 100644
index 160f6c0..0000000
--- a/tez-ui/original/task_attempt_page.js
+++ /dev/null
@@ -1,59 +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.
- */
-$(document).ready( function () {
-  var task_attempt_id=window.sessionStorage.getItem('taskattemptid');
-  var hostname=window.sessionStorage.getItem('hostname');
-  var port=window.sessionStorage.getItem('port');
-  var taurl="http://"+hostname+":"+port+"/ws/v1/timeline/TEZ_TASK_ATTEMPT_ID/"+task_attempt_id;
-
-  $.getJSON(taurl, function(task_attempt) {
-    $('#taskattemptid').text("Task Attempt Id - " + task_attempt_id);
-    var task_attempt_table=$('#task_attempt_overview').DataTable({
-      "paging": false,
-      "searching": false,
-      "ordering": false,
-      "info": false,
-      });
-    var taskAttemptStartEpoch=task_attempt.otherinfo.startTime;
-    var taskAttemptStartTime=new Date(taskAttemptStartEpoch);
-    var taskAttemptEndEpoch=task_attempt.otherinfo.endTime;
-    var taskAttemptEndTime=new Date(taskAttemptEndEpoch);
-    var inProgressLogs='<a href=http://'+task_attempt.otherinfo.inProgressLogsURL+'> inProgressLog</a>';
-    var completedLogs='<a href='+task_attempt.otherinfo.completedLogsURL+'> completeLog</a>';
-    task_attempt_table.row.add([task_attempt.entity, taskAttemptStartTime.toGMTString(), taskAttemptEndTime.toGMTString(), task_attempt.otherinfo.timeTaken, task_attempt.otherinfo.status, inProgressLogs, completedLogs]);
-    task_attempt_table.draw();
-
-    var counterGroupNum = 0;
-    $.each(task_attempt.otherinfo.counters.counterGroups, function(i, counterGroup){
-      $("<th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th>");
-      $("<tr><th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th><td class='table'><table id='countergroup" + counterGroupNum + "'><thead><tr><th>Name</th><th>Value</th></tr></thead></table></td></tr>").appendTo('#counterbody');
-      var counterGroupDT = $('#countergroup' + counterGroupNum).DataTable();
-      counterGroupNum++;
-      $.each(counterGroup.counters, function(i, counter) {
-        counterGroupDT.row.add([counter.counterDisplayName, counter.counterValue]);
-      });
-      counterGroupDT.draw();
-    });
-    counters_table=$('#counter').DataTable(
-        { "paging": false,
-          "searching": false,
-          "ordering": false,
-          "info": false,
-        });
-  });
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/task_page.html
----------------------------------------------------------------------
diff --git a/tez-ui/original/task_page.html b/tez-ui/original/task_page.html
deleted file mode 100644
index f6751ab..0000000
--- a/tez-ui/original/task_page.html
+++ /dev/null
@@ -1,72 +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.
- */ -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-    <title>TEZ UI</title>
-    <script src="lib/jquery.js"></script>
-    <script src="task_page.js"></script>
-    <link rel="stylesheet" type="text/css" href="css/jquery.dataTables.min.css">
-    <script type="text/javascript" charset="utf8" src="lib/jquery.dataTables.min.js"></script>
-  </head>
-
-  <body>
-    <div>
-      <center><h2 id=taskid>Task Id</h2></center>
-      <table id='task_overview' class='display'>
-        <caption>Task Overview</caption>
-        <thead>
-          <tr>
-            <th>Task Id</th>	
-            <th>Start Time</th>
-            <th>End Time</th>
-            <th>Time Taken</th>
-            <th>Status</th>
-          </tr>
-        </thead>
-      </table>
-    </div>
-    <div>
-      <table id='task_attempts' class='display'>
-        <caption>Task Attempts</caption>
-        <thead>
-          <tr>
-            <th>Task Attempt Id</th>	
-            <th>Start Time</th>
-            <th>End Time</th>
-            <th>Time Taken</th>
-            <th>Status</th>
-          </tr>
-        </thead>
-      </table>
-    </div>
-    <div id="counters">
-      <table id='counter' class='display'>
-        <thead>
-          <tr>
-            <th>Counter Group</th>
-            <th>Counters</th>
-          </tr>
-        </thead>
-        <tbody id="counterbody">
-        </tbody>
-      </table>
-    </div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/task_page.js
----------------------------------------------------------------------
diff --git a/tez-ui/original/task_page.js b/tez-ui/original/task_page.js
deleted file mode 100644
index 400ce66..0000000
--- a/tez-ui/original/task_page.js
+++ /dev/null
@@ -1,76 +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.
- */
-$(document).ready( function () {
-  var task_id=window.sessionStorage.getItem('taskid');
-  var hostname=window.sessionStorage.getItem('hostname');
-  var port=window.sessionStorage.getItem('port');
-  var turl="http://"+hostname+":"+port+"/ws/v1/timeline/TEZ_TASK_ID/"+task_id;
-
-  $.getJSON(turl, function(task) {
-    $('#taskid').text("Task Id - " + task_id);
-    var task_table=$('#task_overview').DataTable({
-      "paging": false,
-      "searching": false,
-      "ordering": false,
-      "info": false,
-      });
-    var taskStartEpoch=task.otherinfo.startTime;
-    var taskStartTime=new Date(taskStartEpoch);
-    var taskEndEpoch=task.otherinfo.endTime;
-    var taskEndTime=new Date(taskEndEpoch);
-    var startTime, status, scheduledTime, endTime, diagnostics;
-    task_table.row.add([task.entity, taskStartTime.toGMTString(), taskEndTime.toGMTString(), task.otherinfo.timeTaken, task.otherinfo.status]);
-    task_table.draw();
-
-    var task_attempts_table=$('#task_attempts').DataTable();
-    var turl='http://'+hostname+':'+port+'/ws/v1/timeline/TEZ_TASK_ATTEMPT_ID?primaryFilter=TEZ_TASK_ID:' + task_id;
-    $.getJSON(turl, function(task_attempts) {
-      $.each(task_attempts.entities, function(i, task_attempt) {
-        var callback='tcallback("'+ task_attempt.entity+'");>';			
-        var task_attempt_id_cell='<a href="task_attempt_page.html" onclick='+ callback + task_attempt.entity +" </a>";
-        var taskAttemptStartEpoch=task_attempt.otherinfo.startTime;
-        var taskAttemptStartTime=new Date(taskAttemptStartEpoch);
-        var taskAttemptEndEpoch=task_attempt.otherinfo.endTime;
-        var taskAttemptEndTime=new Date(taskAttemptEndEpoch);
-        task_attempts_table.row.add([task_attempt_id_cell, taskAttemptStartTime.toGMTString(), taskAttemptEndTime.toGMTString(), task_attempt.otherinfo.timeTaken, task_attempt.otherinfo.status]);
-      });
-      task_attempts_table.draw();
-    });
-
-    var counterGroupNum = 0;
-    $.each(task.otherinfo.counters.counterGroups, function(i, counterGroup){
-      $("<th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th>");
-      $("<tr><th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th><td class='table'><table id='countergroup" + counterGroupNum + "'><thead><tr><th>Name</th><th>Value</th></tr></thead></table></td></tr>").appendTo('#counterbody');
-      var counterGroupDT = $('#countergroup' + counterGroupNum).DataTable();
-      counterGroupNum++;
-      $.each(counterGroup.counters, function(i, counter) {
-        counterGroupDT.row.add([counter.counterDisplayName, counter.counterValue]);
-      });
-      counterGroupDT.draw();
-    });
-    counters_table=$('#counter').DataTable(
-        { "paging": false,
-          "searching": false,
-          "ordering": false,
-          "info": false,
-        });
-  });
-});
-function tcallback(id) {
-	window.sessionStorage.setItem('taskattemptid',id);
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/user_guide.txt
----------------------------------------------------------------------
diff --git a/tez-ui/original/user_guide.txt b/tez-ui/original/user_guide.txt
deleted file mode 100644
index e0f41f3..0000000
--- a/tez-ui/original/user_guide.txt
+++ /dev/null
@@ -1,18 +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.
- */
-Please open the TEZ_UI_LOGIN.html as the first page, and enter the server hostname and server port(usually is 8188).

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/vertex_page.html
----------------------------------------------------------------------
diff --git a/tez-ui/original/vertex_page.html b/tez-ui/original/vertex_page.html
deleted file mode 100644
index 8e703a0..0000000
--- a/tez-ui/original/vertex_page.html
+++ /dev/null
@@ -1,73 +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.
- */ -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-    <title>TEZ UI</title>
-    <script src="lib/jquery.js"></script>
-    <script src="vertex_page.js"></script>
-    <link rel="stylesheet" type="text/css" href="css/jquery.dataTables.min.css">
-    <script type="text/javascript" charset="utf8" src="lib/jquery.dataTables.min.js"></script>
-  </head>
-
-  <body>
-    <div>
-      <center><h2 id=vertexid>Vertex Id</h2></center>
-      <table id="vertex_overview" class="display">
-        <caption>Vertex Overview</caption>
-        <thead>
-          <tr>
-            <th>Vertex Id</th>
-            <th>Name</th>
-            <th>Start Time</th>
-            <th>End Time</th>
-            <th>Time Taken</th>
-            <th>Task Count</th>
-            <th>Status</th>
-          </tr>
-        </thead>
-      </table>
-    </div>
-    <div>
-      <table id="tasks" class="display">
-        <thead>
-          <tr>
-            <th>Task Id</th>	
-            <th>Start Time</th>
-            <th>End Time</th>
-            <th>Time Taken</th>
-            <th>Status</th>
-          </tr>
-        </thead>
-      </table>
-    </div>
-    <div id="counters">
-      <table id='counter' class='display'>
-        <thead>
-          <tr>
-            <th>Counter Group</th>
-            <th>Counters</th>
-          </tr>
-        </thead>
-        <tbody id="counterbody">
-        </tbody>
-      </table>
-    </div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/original/vertex_page.js
----------------------------------------------------------------------
diff --git a/tez-ui/original/vertex_page.js b/tez-ui/original/vertex_page.js
deleted file mode 100644
index 0da3018..0000000
--- a/tez-ui/original/vertex_page.js
+++ /dev/null
@@ -1,76 +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.
- */
-$(document).ready( function () {
-	var vertex_id=window.sessionStorage.getItem('vertid');
-	var hostname=window.sessionStorage.getItem('hostname');
-	var port=window.sessionStorage.getItem('port');
-	var vurl='http://'+hostname+':'+port+'/ws/v1/timeline/TEZ_VERTEX_ID/'+vertex_id;
-
-  $.getJSON(vurl, function(vertex) {
-    $('#vertexid').text("Vertex Id - " + vertex_id);
-
-    var vertex_table=$('#vertex_overview').DataTable(
-      { "paging": false,
-        "searching": false,
-        "ordering": false,
-        "info": false,
-      });
-    vertexStartEpoch=vertex.otherinfo.startTime;
-    vertexStartTime=new Date(vertexStartEpoch);
-    vertexEndEpoch=vertex.otherinfo.endTime;
-    vertexEndTime=new Date(vertexEndEpoch);
-    vertex_table.row.add([vertex.entity, vertex.otherinfo.vertexName, vertexStartTime.toGMTString(), vertexEndTime.toGMTString(), vertex.otherinfo.timeTaken, vertex.otherinfo.numTasks, vertex.otherinfo.status]);
-    vertex_table.draw();
-
-    var task_table=$('#tasks').DataTable();
-    var turl='http://'+hostname+':'+port+'/ws/v1/timeline/TEZ_TASK_ID?primaryFilter=TEZ_VERTEX_ID:' + vertex_id;
-    $.getJSON(turl, function(tasks) {
-      $.each(tasks.entities, function(i, task) {
-        var callback='tcallback("'+ task.entity+'");>';			
-        var task_id_cell='<a href="task_page.html" onclick='+ callback + task.entity +" </a>";
-        var taskStartEpoch=task.otherinfo.startTime;
-        var taskStartTime=new Date(taskStartEpoch);
-        var taskEndEpoch=task.otherinfo.endTime;
-        var taskEndTime=new Date(taskEndEpoch);
-        task_table.row.add([task_id_cell, taskStartTime.toGMTString(), taskEndTime.toGMTString(), task.otherinfo.timeTaken, task.otherinfo.status]);
-      });
-      task_table.draw();
-    });
-
-    var counterGroupNum = 0;
-    $.each(vertex.otherinfo.counters.counterGroups, function(i, counterGroup){
-      $("<th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th>");
-      $("<tr><th>Counters</th></tr></thead><tbody><th>" + counterGroup.counterGroupDisplayName + "</th><td class='table'><table id='countergroup" + counterGroupNum + "'><thead><tr><th>Name</th><th>Value</th></tr></thead></table></td></tr>").appendTo('#counterbody');
-      var counterGroupDT = $('#countergroup' + counterGroupNum).DataTable();
-      counterGroupNum++;
-      $.each(counterGroup.counters, function(i, counter) {
-        counterGroupDT.row.add([counter.counterDisplayName, counter.counterValue]);
-      });
-      counterGroupDT.draw();
-    });
-    counters_table=$('#counter').DataTable(
-        { "paging": false,
-          "searching": false,
-          "ordering": false,
-          "info": false,
-        });
-  });
-});
-function tcallback(id) {
-	window.sessionStorage.setItem('taskid',id);
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/package.json
----------------------------------------------------------------------
diff --git a/tez-ui/package.json b/tez-ui/package.json
deleted file mode 100644
index ef46e7a..0000000
--- a/tez-ui/package.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "name": "tez-ui",
-  "version": "0.0.1",
-  "dependencies": {},
-  "devDependencies": {
-    "bower": "1.3.8",
-    "grunt": "~0.4.1",
-    "grunt-cli": "~0.1.13",
-    "grunt-contrib-copy": "~0.4.1",
-    "grunt-contrib-concat": "~0.3.0",
-    "grunt-contrib-uglify": "~0.2.0",
-    "grunt-contrib-jshint": "~0.6.3",
-    "grunt-contrib-cssmin": "~0.6.0",
-    "grunt-contrib-connect": "~0.3.0",
-    "grunt-contrib-clean": "~0.5.0",
-    "grunt-contrib-htmlmin": "~0.1.3",
-    "grunt-contrib-watch": "~0.5.2",
-    "grunt-rev": "~0.1.0",
-    "grunt-usemin": "~0.1.12",
-    "grunt-mocha": "~0.4.1",
-    "grunt-open": "~0.2.0",
-    "grunt-svgmin": "~0.2.0",
-    "grunt-concurrent": "~0.3.0",
-    "load-grunt-tasks": "~0.1.0",
-    "connect-livereload": "~0.2.0",
-    "grunt-ember-templates": "0.4.14",
-    "time-grunt": "~0.1.1",
-    "grunt-replace": "~0.4.4",
-    "jshint-stylish": "~0.1.3",
-    "grunt-neuter": "~0.6.0",
-    "grunt-contrib-less": "~0.11"
-  },
-  "engines": {
-    "node": ">=0.8.0"
-  }
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui/pom.xml b/tez-ui/pom.xml
new file mode 100644
index 0000000..87e46b9
--- /dev/null
+++ b/tez-ui/pom.xml
@@ -0,0 +1,146 @@
+<!--
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.tez</groupId>
+    <artifactId>tez</artifactId>
+    <version>0.6.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>tez-ui</artifactId>
+  <packaging>war</packaging>
+
+  <properties>
+    <webappDir>src/main/webapp</webappDir>
+    <nodeBinDir>node_modules/.bin</nodeBinDir>
+    <fileName>${artifactId}-${parent.version}</fileName>
+
+    <nodeVersion>v0.10.18</nodeVersion>
+    <npmVersion>1.3.8</npmVersion>
+  </properties>
+
+  <build>
+    <finalName>${fileName}</finalName>
+    <plugins>
+
+      <!-- Apache RAT -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+      </plugin>
+
+      <!-- NPM Install -->
+      <plugin>
+        <groupId>com.github.eirslett</groupId>
+        <artifactId>frontend-maven-plugin</artifactId>
+        <configuration>
+          <workingDirectory>${webappDir}</workingDirectory>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>install node and npm</id>
+            <goals>
+              <goal>install-node-and-npm</goal>
+            </goals>
+            <configuration>
+              <nodeVersion>${nodeVersion}</nodeVersion>
+              <npmVersion>${npmVersion}</npmVersion>
+            </configuration>
+          </execution>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>npm install</id>
+            <goals>
+              <goal>npm</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Bower install & grunt build-->
+      <plugin>
+        <artifactId>exec-maven-plugin</artifactId>
+        <groupId>org.codehaus.mojo</groupId>
+        <executions>
+          <execution>
+            <id>Bower install</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>node/node</executable>
+              <arguments>
+                <argument>${nodeBinDir}/bower</argument>
+                <argument>install</argument>
+                <argument>--allow-root</argument>
+              </arguments>
+            </configuration>
+          </execution>
+          <execution>
+            <id>grunt build</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>node/node</executable>
+              <arguments>
+                <argument>${nodeBinDir}/grunt</argument>
+                <argument>build</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Maven assembly plugin for creating the web tar ball-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <finalName>${fileName}</finalName>
+          <descriptor>${basedir}/src/assembly/bin.xml</descriptor>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Package into war -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <webXml>${basedir}/src/main/resources/WEB-INF/web.xml</webXml>
+          <warSourceDirectory>${webappDir}/dist</warSourceDirectory>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/assembly/bin.xml
----------------------------------------------------------------------
diff --git a/tez-ui/src/assembly/bin.xml b/tez-ui/src/assembly/bin.xml
new file mode 100644
index 0000000..2b5dd18
--- /dev/null
+++ b/tez-ui/src/assembly/bin.xml
@@ -0,0 +1,31 @@
+<!--
+   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.
+-->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+  <id>web</id>
+  <formats>
+    <format>tar.gz</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>${basedir}/src/main/webapp/dist</directory>
+      <outputDirectory>/</outputDirectory>
+    </fileSet>
+  </fileSets>
+</assembly>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/resources/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/resources/WEB-INF/web.xml b/tez-ui/src/main/resources/WEB-INF/web.xml
new file mode 100644
index 0000000..62bfe31
--- /dev/null
+++ b/tez-ui/src/main/resources/WEB-INF/web.xml
@@ -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.
+-->
+
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>TEZ UI</display-name>
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/.bowerrc
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/.bowerrc b/tez-ui/src/main/webapp/.bowerrc
new file mode 100644
index 0000000..ba0accc
--- /dev/null
+++ b/tez-ui/src/main/webapp/.bowerrc
@@ -0,0 +1,3 @@
+{
+    "directory": "app/bower_components"
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/.gitattributes
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/.gitattributes b/tez-ui/src/main/webapp/.gitattributes
new file mode 100644
index 0000000..2125666
--- /dev/null
+++ b/tez-ui/src/main/webapp/.gitattributes
@@ -0,0 +1 @@
+* text=auto
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/.gitignore
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/.gitignore b/tez-ui/src/main/webapp/.gitignore
new file mode 100644
index 0000000..ee72141
--- /dev/null
+++ b/tez-ui/src/main/webapp/.gitignore
@@ -0,0 +1,9 @@
+node
+node_modules
+temp
+dist
+.sass-cache
+.tmp
+app/bower_components
+test/bower_components
+.editorconfig

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/.jshintrc b/tez-ui/src/main/webapp/.jshintrc
new file mode 100644
index 0000000..780790d
--- /dev/null
+++ b/tez-ui/src/main/webapp/.jshintrc
@@ -0,0 +1,24 @@
+{
+    "node": true,
+    "browser": true,
+    "esnext": true,
+    "bitwise": false,
+    "curly": false,
+    "eqeqeq": true,
+    "eqnull": true,
+    "immed": true,
+    "latedef": true,
+    "newcap": true,
+    "noarg": true,
+    "undef": true,
+    "strict": false,
+    "trailing": false,
+    "smarttabs": true,
+    "globals": {
+        "App": true,
+        "jQuery": true,
+        "Ember": true,
+        "Handlebars": true,
+        "DS": true
+    }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/Gruntfile.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/Gruntfile.js b/tez-ui/src/main/webapp/Gruntfile.js
new file mode 100644
index 0000000..3d3b96f
--- /dev/null
+++ b/tez-ui/src/main/webapp/Gruntfile.js
@@ -0,0 +1,451 @@
+/**
+ * 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.
+ */
+// Generated on 2014-06-24 using generator-ember 0.8.4
+'use strict';
+var LIVERELOAD_PORT = 35729;
+var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
+var mountFolder = function (connect, dir) {
+  return connect.static(require('path').resolve(dir));
+};
+
+// # Globbing
+// for performance reasons we're only matching one level down:
+// 'test/spec/{,*/}*.js'
+// use this if you want to match all subfolders:
+// 'test/spec/**/*.js'
+
+module.exports = function (grunt) {
+  // show elapsed time at the end
+  require('time-grunt')(grunt);
+  // load all grunt tasks
+  require('load-grunt-tasks')(grunt);
+
+  // configurable paths
+  var yeomanConfig = {
+    app: 'app',
+    dist: 'dist'
+  };
+
+  grunt.initConfig({
+    yeoman: yeomanConfig,
+    watch: {
+      emberTemplates: {
+        files: '<%= yeoman.app %>/templates/**/*.hbs',
+        tasks: ['emberTemplates']
+      },
+      neuter: {
+        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
+        tasks: ['neuter']
+      },
+      less: {
+        files: '<%= yeoman.app %>/styles/**/*.less',
+        tasks: ['less:development']
+      },
+      livereload: {
+        options: {
+          livereload: LIVERELOAD_PORT
+        },
+        files: [
+          '.tmp/scripts/**/*.js',
+          '<%= yeoman.app %>/*.html',
+          '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
+          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
+        ]
+      },
+      css: {
+        files: '<%= yeoman.app %>/styles/*.css',
+        tasks: ['copy:development']
+      }
+    },
+    connect: {
+      options: {
+        port: 9001,
+        // change this to '0.0.0.0' to access the server from outside
+        hostname: 'localhost'
+      },
+      livereload: {
+        options: {
+          middleware: function (connect) {
+            return [
+              lrSnippet,
+              mountFolder(connect, '.tmp'),
+              mountFolder(connect, yeomanConfig.app)
+            ];
+          }
+        }
+      },
+      test: {
+        options: {
+          middleware: function (connect) {
+            return [
+              mountFolder(connect, 'test'),
+              mountFolder(connect, '.tmp')
+            ];
+          }
+        }
+      },
+      dist: {
+        options: {
+          middleware: function (connect) {
+            return [
+              mountFolder(connect, yeomanConfig.dist)
+            ];
+          }
+        }
+      }
+    },
+    open: {
+      server: {
+        path: 'http://localhost:<%= connect.options.port %>'
+      }
+    },
+    clean: {
+      dist: {
+        files: [
+          {
+            dot: true,
+            src: [
+              '.tmp',
+              '<%= yeoman.dist %>/*',
+              '!<%= yeoman.dist %>/.git*'
+            ]
+          }
+        ]
+      },
+      server: '.tmp'
+    },
+    jshint: {
+      options: {
+        jshintrc: '.jshintrc',
+        reporter: require('jshint-stylish')
+      },
+      all: [
+        'Gruntfile.js',
+        '<%= yeoman.app %>/scripts/{,*/}*.js',
+        '!<%= yeoman.app %>/scripts/vendor/*',
+        'test/spec/{,*/}*.js'
+      ]
+    },
+    mocha: {
+      all: {
+        options: {
+          run: true,
+          urls: ['http://localhost:<%= connect.options.port %>/index.html']
+        }
+      }
+    },
+    // not used since Uglify task does concat,
+    // but still available if needed
+    /*concat: {
+     dist: {}
+     },*/
+    // not enabled since usemin task does concat and uglify
+    // check index.html to edit your build targets
+    // enable this task if you prefer defining your build targets here
+    /*uglify: {
+     dist: {}
+     },*/
+    rev: {
+      dist: {
+        files: {
+          src: [
+            '<%= yeoman.dist %>/scripts/{,*/}*.js',
+            '<%= yeoman.dist %>/styles/{,*/}*.css',
+            '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
+            '<%= yeoman.dist %>/styles/fonts/*'
+          ]
+        }
+      }
+    },
+    useminPrepare: {
+      html: '.tmp/index.html',
+      options: {
+        dest: '<%= yeoman.dist %>'
+      }
+    },
+    usemin: {
+      html: ['<%= yeoman.dist %>/{,*/}*.html'],
+      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
+      options: {
+        dirs: ['<%= yeoman.dist %>']
+      }
+    },
+    svgmin: {
+      dist: {
+        files: [
+          {
+            expand: true,
+            cwd: '<%= yeoman.app %>/images',
+            src: '{,*/}*.svg',
+            dest: '<%= yeoman.dist %>/images'
+          }
+        ]
+      }
+    },
+    cssmin: {
+      dist: {
+        files: {
+          '<%= yeoman.dist %>/styles/main.css': [
+            '.tmp/styles/{,*/}*.css',
+            '<%= yeoman.app %>/styles/{,*/}*.css',
+            '<%= yeoman.app %>/bower_components/bootstrap/dist/css/bootstrap.css',
+            '<%= yeoman.app %>/bower_components/ember-table/dist/ember-table.css',
+            '<%= yeoman.app %>/bower_components/font-awesome/css/font-awesome.css'
+          ]
+        }
+      }
+    },
+    htmlmin: {
+      dist: {
+        options: {
+          /*removeCommentsFromCDATA: true,
+           // https://github.com/yeoman/grunt-usemin/issues/44
+           //collapseWhitespace: true,
+           collapseBooleanAttributes: true,
+           removeAttributeQuotes: true,
+           removeRedundantAttributes: true,
+           useShortDoctype: true,
+           removeEmptyAttributes: true,
+           removeOptionalTags: true*/
+        },
+        files: [
+          {
+            expand: true,
+            cwd: '<%= yeoman.app %>',
+            src: '*.html',
+            dest: '<%= yeoman.dist %>'
+          }
+        ]
+      }
+    },
+    replace: {
+      app: {
+        options: {
+          variables: {
+            ember: 'bower_components/ember/ember.js',
+            ember_data: 'bower_components/ember-data/ember-data.js'
+          }
+        },
+        files: [
+          {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'}
+        ]
+      },
+      dist: {
+        options: {
+          variables: {
+            ember: 'bower_components/ember/ember.prod.js',
+            ember_data: 'bower_components/ember-data/ember-data.prod.js'
+          }
+        },
+        files: [
+          {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'}
+        ]
+      }
+    },
+    // Put files not handled in other tasks here
+    copy: {
+      dist: {
+        files: [
+          {
+            expand: true,
+            dot: true,
+            cwd: '<%= yeoman.app %>',
+            dest: '<%= yeoman.dist %>',
+            src: [
+              '*.{ico,txt}',
+              '.htaccess',
+              'img/*',
+              'styles/fonts/*',
+              'scripts/assets/**/*'
+            ]
+          },
+          {
+            expand: true,
+            flatten: true,
+            src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/base/images/*',
+            dest: '<%= yeoman.dist %>/styles/images/'
+          },
+          {
+            expand: true,
+            flatten: true,
+            src: '<%= yeoman.app %>/bower_components/font-awesome/fonts/*',
+            dest: '<%= yeoman.dist %>/fonts/'
+          }
+        ]
+      },
+      development: {
+        files: [
+          {
+            expand: true,
+            dot: true,
+            cwd: '<%= yeoman.app %>',
+            dest: '.tmp',
+            src: [
+              '*.{ico,txt}',
+              '.htaccess',
+              'img/*',
+              'styles/*.css',
+              'styles/fonts/*',
+              'scripts/assets/**/*'
+            ]
+          },
+          {
+            expand: true,
+            flatten: true,
+            src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/base/images/*',
+            dest: '.tmp/styles/images/'
+          },
+          {
+            expand: true,
+            flatten: true,
+            src: '<%= yeoman.app %>/bower_components/font-awesome/fonts/*',
+            dest: '.tmp/fonts/'
+          },
+          {
+            expand: true,
+            flatten: false,
+            cwd: '<%= yeoman.app %>',
+            src: 'bower_components/**',
+            dest: '.tmp/'
+          }
+        ]
+      }
+    },
+    concurrent: {
+      server: [
+        'emberTemplates'
+      ],
+      test: [
+        'emberTemplates'
+      ],
+      dist: [
+        'emberTemplates',
+        'svgmin',
+        'htmlmin'
+      ]
+    },
+    emberTemplates: {
+      options: {
+        templateName: function (sourceFile) {
+          var templatePath = yeomanConfig.app + '/templates/';
+          return sourceFile.replace(templatePath, '');
+        }
+      },
+      dist: {
+        files: {
+          '.tmp/scripts/compiled-templates.js': '<%= yeoman.app %>/templates/**/*.hbs'
+        }
+      },
+      development: {
+        files: {
+          '.tmp/scripts/compiled-templates.js': '<%= yeoman.app %>/templates/**/*.hbs'
+        }
+      }
+    },
+
+    less: {
+      development: {
+        options: {
+          paths: ["<%= yeoman.app %>/styles"],
+          sourceMap: true,
+        },
+        files: [{
+          expand: true,
+          cwd: "<%= yeoman.app %>/styles",
+          src: ['styles/*.less', '**/*.less'],
+          dest: ".tmp/styles",
+          ext: ".css"
+        }]
+      },
+      production: {
+        options: {
+          paths: ["<%= yeoman.app %>/styles"],
+          cleancss: true
+        },
+        files: {
+          ".tmp/styles/styles.css": "<%= yeoman.app %>/styles/**/*.less"
+        }
+      }
+    },
+
+    neuter: {
+      app: {
+        options: {
+          filepathTransform: function (filepath) {
+            return yeomanConfig.app + '/' + filepath;
+          }
+        },
+        src: '<%= yeoman.app %>/scripts/**/*.js',
+        dest: '.tmp/scripts/combined-scripts.js'
+      }
+    }
+  });
+
+  grunt.registerTask('server', function (target) {
+    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
+    grunt.task.run(['serve:' + target]);
+  });
+
+  grunt.registerTask('serve', function (target) {
+    if (target === 'dist') {
+      return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
+    }
+
+    grunt.task.run([
+      'clean:server',
+      'replace:app',
+      'concurrent:server',
+      'neuter:app',
+      'less:development',
+      'connect:livereload',
+      'open',
+      'copy:development',
+      'watch'
+    ]);
+  });
+
+  grunt.registerTask('test', [
+    'clean:server',
+    'replace:app',
+    'concurrent:test',
+    'connect:test',
+    'neuter:app',
+    'mocha'
+  ]);
+
+  grunt.registerTask('build', [
+    'clean:dist',
+    'replace:app',
+    'useminPrepare',
+    'concurrent:dist',
+    'neuter:app',
+    'less:production',
+    'concat',
+    'cssmin',
+    //'uglify',
+    'copy:dist',
+    //'rev',
+    'usemin'
+  ]);
+
+  grunt.registerTask('default', [
+    'jshint',
+    'test',
+    'build'
+  ]);
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/img/apache_tez_logo_lowres.png
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/img/apache_tez_logo_lowres.png b/tez-ui/src/main/webapp/app/img/apache_tez_logo_lowres.png
new file mode 100644
index 0000000..45fd701
Binary files /dev/null and b/tez-ui/src/main/webapp/app/img/apache_tez_logo_lowres.png differ

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/img/glyphicons-halflings.png
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/img/glyphicons-halflings.png b/tez-ui/src/main/webapp/app/img/glyphicons-halflings.png
new file mode 100644
index 0000000..79bc568
Binary files /dev/null and b/tez-ui/src/main/webapp/app/img/glyphicons-halflings.png differ

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/index.html b/tez-ui/src/main/webapp/app/index.html
new file mode 100644
index 0000000..1653e94
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/index.html
@@ -0,0 +1,71 @@
+<!--
+* 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.
+-->
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Tez UI</title>
+
+    <!-- build:css styles/main.css -->
+    <link rel="stylesheet" href="styles/main.css">
+    <link rel="stylesheet" href="styles/swimlanes.css">
+    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
+    <link rel="stylesheet" href="bower_components/ember-table/dist/ember-table.css">
+    <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css">
+    <!-- endbuild -->
+
+  </head>
+
+  <body>
+    <!-- build:js(app) scripts/components.js -->
+    <script src="bower_components/cldr/plurals.js"></script>
+    <script src="bower_components/jquery/jquery.js"></script>
+    <script src="bower_components/jquery-ui/jquery-ui.js"></script>
+    <script src="bower_components/bootstrap/js/dropdown.js"></script>
+    <script src="bower_components/bootstrap/js/button.js"></script>
+    <script src="bower_components/bootstrap/js/tooltip.js"></script>
+    <script src="bower_components/jquery-ui/ui/datepicker.js"></script>
+    <script src="bower_components/moment/moment.js"></script>
+    <script src="bower_components/handlebars/handlebars.js"></script>
+    <script src="@@ember"></script>
+    <script src="@@ember_data"></script>
+    <script src="bower_components/ember-json-mapper/ember-json-mapper.js"></script>
+    <script src="bower_components/ember-i18n/lib/i18n.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-core.min.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-basic.min.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-button.min.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-modal.min.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-nav.min.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-items-action-bar.min.js"></script>
+    <script src="bower_components/antiscroll/antiscroll.js"></script>
+    <script src="bower_components/jquery-mousewheel/jquery.mousewheel.js"></script>
+    <script src="bower_components/ember-table/dist/ember-table.js"></script>
+    <script src="bower_components/ember-addons.bs_for_ember/dist/js/bs-nav.min.js"></script>
+    <script src="bower_components/d3/d3.js"></script>
+    <!-- endbuild -->
+
+    <!-- build:js(.tmp) scripts/templates.js -->
+    <script src="scripts/compiled-templates.js"></script>
+    <!-- endbuild -->
+
+    <!-- build:js(.tmp) scripts/main.js -->
+    <script src="scripts/combined-scripts.js"></script>
+    <!-- endbuild -->
+  </body>
+</html>
+    

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/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
new file mode 100644
index 0000000..c06678e
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/app.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+var App = window.App = Em.Application.createWithMixins(Bootstrap, {
+	// Basic logging, e.g. "Transitioned into 'post'"
+  LOG_TRANSITIONS: true,
+
+  // Extremely detailed logging, highlighting every internal
+  // step made while transitioning into a route, including
+  // `beforeModel`, `model`, and `afterModel` hooks, and
+  // information about redirects and aborted transitions
+  LOG_TRANSITIONS_INTERNAL: true
+});
+
+App.AtsBaseUrl = "http://localhost:8188";
+
+require('scripts/router');
+require('scripts/store');
+
+App.Helpers = Em.Namespace.create();
+App.Mappers = Em.Namespace.create();
+
+//TODO: initializer.
+
+/* Order and include */
+/* TODO: cleanup */
+require('scripts/translations');
+require('scripts/mixins/*');
+require('scripts/helpers/*');
+require('scripts/views/**/*');
+require('scripts/models/**/*');
+require('scripts/mappers/server_data_mapper.js');
+require('scripts/mappers/**/*');
+require('scripts/controllers/**/*');
+require('scripts/components/*');
+require('scripts/adapters/*');
+
+App.ApplicationAdapter = App.TimelineRESTAdapter.extend();
+App.ApplicationSerializer = App.TimelineSerializer.extend();

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/components/counter-table.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/components/counter-table.js b/tez-ui/src/main/webapp/app/scripts/components/counter-table.js
new file mode 100644
index 0000000..2ee6b76
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/components/counter-table.js
@@ -0,0 +1,83 @@
+/**
+ * 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.CounterTableComponent = Ember.Table.EmberTableComponent.extend({
+	hasFooter: false,
+	hasHeader: true,
+	forceFillColumns: true,
+	data: null,
+
+	columns: function() {
+		var groupColumn = Em.Table.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Group',
+      getCellContent: function(row) {
+      	return row.get('counterGroup');
+      }
+    });
+
+		var nameColumn = Em.Table.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Counter Name',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span {{bind-attr class=":ember-table-content view.cellContent.isCG:countertable-group-header:countertable-row"}}>\
+          	{{view.cellContent.name}}\
+           </span>')
+      }),
+      getCellContent: function(row) {
+      	return {
+      		isCG: row.get('counters') != undefined,
+      		name: row.get('name')
+      	};
+      }
+    });
+
+		var valueColumn = Em.Table.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Value',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span {{bind-attr class=":ember-table-content view.cellContent.isCG:countertable-group-header"}}>\
+          	{{view.cellContent.value}}\
+           </span>')
+      }),
+      getCellContent: function(row) {
+      	return {
+      		isCG: row.get('counters') != undefined,
+      		value: row.get('value')
+      	};
+      }
+    });
+
+    return [nameColumn, valueColumn];
+	}.property(),
+
+	content: function() {
+		var allCounters = [];
+		if (!!this.data) {
+			this.data.forEach(function(cg){
+				allCounters.push(cg);
+				[].push.apply(allCounters, cg.get('counters').content);
+			});
+		}
+		return allCounters;
+	}.property('data'),
+});
+
+Em.Handlebars.helper('counter-table-component', App.CounterTableComponent);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/components/extended-table.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/components/extended-table.js b/tez-ui/src/main/webapp/app/scripts/components/extended-table.js
new file mode 100644
index 0000000..5047af9
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/components/extended-table.js
@@ -0,0 +1,190 @@
+/**
+ * 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.ExTable = Ember.Namespace.create();
+
+App.ExTable.FilterField = Em.TextField.extend({
+	classNames: ['filter'],
+  classNameBindings: ['isPopulated','isInputDirty:input-dirty'],
+  type: 'search',
+  results: 1,
+  attributeBindings: ['autofocus', 'results'],
+  valueBinding: Em.Binding.oneWay('filterValue'),
+  isPopulated: function() {
+  	return !Em.isEmpty(this.get('value'));
+  }.property('value'),
+  insertNewline: function(event) {
+    if (this.get('isInputDirty')) {
+      this.set('filterValue', this.get('value'));
+      this.get('parentView.controller').send('filterUpdated', 
+        this.get('parentView.content'), this.get('value'));
+    }
+  },
+  cancel: function() {
+    // cancel is ignored. user needs to press enter. This is done in order to avoid 
+    // two requests when user wants to clear the current input and enter new value.
+  },
+  isInputDirty: function() {
+  	return $.trim(this.get('value')) != $.trim(this.get('filterValue'));
+  }.property('value', 'filterValue')
+});
+
+App.ExTable.FilterRow = Ember.View.extend(Ember.AddeparMixins.StyleBindingsMixin, {
+  templateName: 'components/extended-table/filter-row',
+  classNames: ['ember-table-table-row', 'ember-table-header-row'],
+  styleBindings: ['width'],
+  columns: Ember.computed.alias('content'),
+  width: Ember.computed.alias('controller._rowWidth'),
+  scrollLeft: Ember.computed.alias('controller._tableScrollLeft'),
+  onScrollLeftDidChange: function() {
+    return this.$().scrollLeft(this.get('scrollLeft'));
+  }.observes('scrollLeft'),
+  onScroll: function(event) {
+    this.set('scrollLeft', event.target.scrollLeft);
+    return event.preventDefault();
+  }
+});
+
+App.ExTable.FilterBlock = Ember.Table.TableBlock.extend({
+  classNames: ['ember-table-header-block'],
+  itemViewClass: 'App.ExTable.FilterRow',
+  content: function() {
+    return [this.get('columns')];
+  }.property('columns')
+});
+
+App.ExTable.FilterTableContainer = Ember.Table.TableContainer.extend(Ember.Table.ShowHorizontalScrollMixin, {
+  templateName: 'components/extended-table/filter-container',
+  classNames: ['ember-table-table-container', 'ember-table-fixed-table-container', 'ember-table-header-container'],
+  height: Ember.computed.alias('controller._filterHeight'),
+  width: Ember.computed.alias('controller._tableContainerWidth')
+});
+
+App.ExTable.FilterCell = Ember.View.extend(Ember.AddeparMixins.StyleBindingsMixin, {
+  templateName: 'components/extended-table/filter-cell',
+  classNames: ['ember-table-cell', 'ember-table-header-cell'],
+  classNameBindings: ['column.textAlign'],
+  styleBindings: ['width', 'height'],
+ 	column: Ember.computed.alias('content'),
+  width: Ember.computed.alias('column.columnWidth'),
+  height: function() {
+  	return this.get('controller._filterHeight');
+  }.property('controller._filterHeight'),
+  // Currently resizing is not handled automatically. if required will need to do here.
+});
+
+App.ExTable.ColumnDefinition = Ember.Table.ColumnDefinition.extend({
+  init: function() {
+    if (!!this.filterID) {
+      var columnFilterValueBinding = Em.Binding
+        .oneWay('controller._parentView.context.' + this.filterID)
+        .to('columnFilterValue');
+      columnFilterValueBinding.connect(this);
+    }
+  },
+  textAlign: 'text-align-left',
+  filterCellView: 'App.ExTable.FilterCell',
+  filterCellViewClass: Ember.computed.alias('filterCellView'),
+  filterID: null,
+});
+
+App.ExTable.TableComponent = Ember.Table.EmberTableComponent.extend({
+	layoutName: 'components/extended-table/extable',
+	filters: {},
+
+	hasFilter: true,
+	minFilterHeight: 30, //TODO: less changes
+
+  actions: {
+    filterUpdated: function(columnDef, value) {
+      var filterID = columnDef.get('filterID');
+      filterID = filterID || columnDef.get('headerCellName').underscore();
+      if (this.get('onFilterUpdated')) {
+      	this.sendAction('onFilterUpdated', filterID, value);
+      }
+    }
+  },
+
+	// private variables
+	// Dynamic filter height that adjusts according to the filter content height
+	_contentFilterHeight: null,
+  _filterHeight: function() {
+    var minHeight = this.get('minFilterHeight');
+    var contentFilterHeight = this.get('_contentFilterHeight');
+    if (contentFilterHeight < minHeight) {
+      return minHeight;
+    } else {
+      return contentFilterHeight;
+    }
+  }.property('_contentFilterHeight', 'minFilterHeight'),
+
+	// some of these below are private functions extend. however to add the filterrow we need them.
+	// tables-container height adjusts to the content height
+	_tablesContainerHeight: function() {
+    var contentHeight, height;
+    height = this.get('_height');
+    contentHeight = this.get('_tableContentHeight') + this.get('_headerHeight') + this.get('_footerHeight') 
+    	+ this.get('_filterHeight');
+    if (contentHeight < height) {
+      return contentHeight;
+    } else {
+      return height;
+    }
+  }.property('_height', '_tableContentHeight', '_headerHeight', '_footerHeight', '_filterHeight'),
+
+  _bodyHeight: function() {
+    var bodyHeight;
+    bodyHeight = this.get('_tablesContainerHeight');
+    if (this.get('hasHeader')) {
+      bodyHeight -= this.get('_headerHeight');
+    }
+    if (this.get('hasFilter')) { 
+      bodyHeight -= this.get('_filterHeight');
+    }
+    if (this.get('hasFooter')) {
+      bodyHeight -= this.get('footerHeight');
+    }
+    return bodyHeight;
+  }.property('_tablesContainerHeight', '_hasHorizontalScrollbar', '_headerHeight', 'footerHeight', '_filterHeight',
+  	'hasHeader', 'hasFooter', 'hasFilter'), 
+
+  _hasVerticalScrollbar: function() {
+    var contentHeight, height;
+    height = this.get('_height');
+    contentHeight = this.get('_tableContentHeight') + this.get('_headerHeight') + this.get('_footerHeight') 
+    	+ this.get('_filterHeight');
+    if (height < contentHeight) {
+      return true;
+    } else {
+      return false;
+    }
+  }.property('_height', '_tableContentHeight', '_headerHeight', '_footerHeight', '_filterHeight'),
+
+  _tableContentHeight: function() {
+    return this.get('rowHeight') * this.get('bodyContent.length');
+  }.property('rowHeight', 'bodyContent.length')
+});
+
+App.ExTable.FilterColumnMixin = Ember.Mixin.create({
+		isFilterable: true,
+		filterPresent: function() {
+			return !Em.isEmpty(this.get('columnFilterValue'));
+		}.property('columnFilterValue'),
+});
+
+Ember.Handlebars.helper('extended-table-component', App.ExTable.TableComponent);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/components/page-nav.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/components/page-nav.js b/tez-ui/src/main/webapp/app/scripts/components/page-nav.js
new file mode 100644
index 0000000..a6c0f68
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/components/page-nav.js
@@ -0,0 +1,35 @@
+/**
+ * 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.PageNavComponent = Em.Component.extend({
+	layoutName: 'components/page-nav',
+	
+	actions: {
+		gotoNext: function() {
+			this.sendAction('navNext');
+		},
+		gotoPrev: function() {
+			this.sendAction('navPrev');
+		},
+		gotoFirst: function() {
+			this.sendAction('navFirst');
+		}
+	}
+});
+
+Em.Handlebars.helper('page-nav-component', App.PageNavComponent);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/controllers/dag_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_controller.js
new file mode 100644
index 0000000..bbf8e12
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_controller.js
@@ -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.
+ */
+
+App.DagController = Em.ObjectController.extend(App.Helpers.DisplayHelper, {
+	controllerName: 'DagController',
+
+	pageTitle: 'Dag',
+
+	loading: true,
+
+	updateLoading: function() {
+    this.set('loading', false);
+  }.observes('content'),
+
+	pageSubTitle: function() {
+		return this.get('name');
+	}.property('name'),
+
+	childDisplayViews: [
+		Ember.Object.create({title: 'Details', linkTo: 'dag.index'}),
+		Ember.Object.create({title: 'Vertices', linkTo: 'dag.vertices'}),
+		Ember.Object.create({title: 'Tasks', linkTo: 'dag.tasks'}),
+		Ember.Object.create({title: 'Counters', linkTo: 'dag.counters'}),
+		Ember.Object.create({title: 'Swimlane', linkTo: 'dag.swimlane'})
+	],
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
new file mode 100644
index 0000000..14a54ea
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
@@ -0,0 +1,61 @@
+/**
+ * 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.
+ */
+
+ //TODO: watch individual counters.
+App.DagIndexController = Em.ObjectController.extend({
+	controllerName: 'DagIndexController',
+
+	taskIconStatus: function() {
+		return App.Helpers.misc.getStatusClassForEntity(this.get('model'));
+	}.property('id', 'status', 'counterGroups'),
+
+	totalTasks: function() {
+		return App.Helpers.misc.getCounterValueForDag(this.get('counterGroups'), 
+			this.get('id'), 'org.apache.tez.common.counters.DAGCounter', 'TOTAL_LAUNCHED_TASKS')
+	}.property('id', 'counterGroups'),
+
+	sucessfulTasks: function() {
+		return App.Helpers.misc.getCounterValueForDag(this.get('counterGroups'), this.get('id'),
+			'org.apache.tez.common.counters.DAGCounter', 'NUM_SUCCEEDED_TASKS')
+	}.property('id', 'counterGroups'),
+
+	failedTasks: function() {
+		return App.Helpers.misc.getCounterValueForDag(this.get('counterGroups'), this.get('id'),
+			'org.apache.tez.common.counters.DAGCounter', 'NUM_FAILED_TASKS')
+	}.property('id', 'counterGroups'),
+
+	killedTasks: function() {
+		return App.Helpers.misc.getCounterValueForDag(this.get('counterGroups'), this.get('id'),
+			'org.apache.tez.common.counters.DAGCounter', 'NUM_KILLED_TASKS')
+	}.property('id', 'counterGroups'),
+
+	hasFailedTasks: function() {
+		return this.get('failedTasks') > 0;
+	}.property('id', 'counterGroups'),
+
+  failedTasksLink: function() {
+    return '/#tasks?status=FAILED&parentType=TEZ_DAG_ID&parentID=' + this.get('id');
+  }.property(),
+
+	actions: {
+		showFailedTasks: function() {
+			alert('not implemented');
+		}
+	},
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/controllers/dag_swimlane_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_swimlane_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_swimlane_controller.js
new file mode 100644
index 0000000..a49d54d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_swimlane_controller.js
@@ -0,0 +1,35 @@
+/**
+ * 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.DagSwimlaneController = Em.ArrayController.extend({
+  needs: "dag",
+  controllerName: "DagSwimlaneController",
+  pageTitle: "Task Attempts",
+  pageSubTitle: "All Task Attempts",
+  dag_id: Em.computed.alias('controllers.dag.id'),
+
+  getFilterParams: function(params) {
+    var dag_id = this.get('dag_id');
+    var filterParams = {};
+    if (dag_id) {
+      filterParams['primaryFilter'] = 'TEZ_DAG_ID:' + dag_id;
+    }
+
+    return filterParams;
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
new file mode 100644
index 0000000..43e6809
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
@@ -0,0 +1,123 @@
+/**
+ * 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.DagTasksController = Em.ObjectController.extend(App.PaginatedContentMixin, {
+  needs: "dag",
+
+  // required by the PaginatedContentMixin
+  childEntityType: 'task',
+
+  queryParams: {
+    status_filter: 'status',
+    vertex_id_filter: 'vertex_id',
+  },
+  status_filter: null,
+  vertex_id_filter: null,
+
+  loadData: function() {
+    var filters = {
+      primary: {
+        TEZ_DAG_ID: this.get('controllers.dag.id'),
+        TEZ_VERTEX_ID: this.vertex_id_filter,
+      },
+      secondary: {
+        status: this.status_filter
+      }
+    }
+    this.setFiltersAndLoadEntities(filters);
+  },
+
+  actions : {
+    filterUpdated: function(filterID, value) {
+      // any validations required goes here.
+      if (!!value) {
+        this.set(filterID, value);
+      } else {
+        this.set(filterID, null);
+      }
+      this.loadData();
+    }
+  },
+
+	columns: function() {
+		var idCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Task ID',
+      tableCellViewClass: Em.Table.TableCell.extend({
+      	template: Em.Handlebars.compile(
+      		"{{#link-to 'task' view.cellContent class='ember-table-content'}}{{view.cellContent}}{{/link-to}}")
+      }),
+      contentPath: 'id',
+    });
+
+    var vertexCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin,{
+      headerCellName: 'Vertex ID',
+      filterID: 'vertex_id_filter',
+      contentPath: 'vertexID'
+    });
+
+    var startTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Start Time',
+      getCellContent: function(row) {
+      	return App.Helpers.date.dateFormat(row.get('startTime'));
+      }
+    });
+
+    var runTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Run Time',
+      getCellContent: function(row) {
+        var st = row.get('startTime');
+        var et = row.get('endTime');
+        if (st && et) {
+          return App.Helpers.date.durationSummary(st, et);
+        }
+      }
+    });
+
+    var statusCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin,{
+      headerCellName: 'Status',
+      filterID: 'status_filter',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">&nbsp;\
+          <i {{bind-attr class=":task-status view.cellContent.statusIcon"}}></i>\
+          &nbsp;&nbsp;{{view.cellContent.status}}</span>')
+      }),
+      getCellContent: function(row) {
+      	return { 
+          status: row.get('status'),
+          statusIcon: App.Helpers.misc.getStatusClassForEntity(row)
+        };
+      }
+    });
+
+    var actionsCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Actions',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">\
+          {{#link-to "task.counters" view.cellContent}}counters{{/link-to}}&nbsp;\
+          {{#link-to "task.attempts" view.cellContent}}attempts{{/link-to}}\
+          </span>'
+          )
+      }),
+      contentPath: 'id'
+    });
+
+		return [idCol, vertexCol, startTimeCol, runTimeCol, statusCol, actionsCol];
+	}.property(),
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/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
new file mode 100644
index 0000000..5751de7
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
@@ -0,0 +1,117 @@
+/**
+ * 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.DagVerticesController = Em.ObjectController.extend(App.PaginatedContentMixin, {
+  needs: "dag",
+
+  // required by the PaginatedContentMixin
+  childEntityType: 'vertex',
+
+  queryParams: {
+    status_filter: 'status'
+  },
+
+  status_filter: null,
+
+  loadData: function() {
+    var filters = {
+      primary: {
+        TEZ_DAG_ID: this.get('controllers.dag.id')
+      },
+      secondary: {
+        status: this.status_filter
+      }
+    }
+    this.setFiltersAndLoadEntities(filters);
+  },
+
+  actions : {
+    filterUpdated: function(filterID, value) {
+      // any validations required goes here.
+      if (!!value) {
+        this.set(filterID, value);
+      } else {
+        this.set(filterID, null);
+      }
+      this.loadData();
+    }
+  },
+
+  columns: function() {
+    var idCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Vertex Name',
+      tableCellViewClass: Em.Table.TableCell.extend({
+      	template: Em.Handlebars.compile(
+      		"{{#link-to 'vertex' view.cellContent.id class='ember-table-content'}}{{view.cellContent.name}}{{/link-to}}")
+      }),
+      getCellContent: function(row) {
+        return {
+          id: row.get('id'),
+          name: row.get('name')
+        };
+      }
+    });
+
+    var nameCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Vertex ID',
+      contentPath: 'id',
+    });
+
+    var startTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Submission Time',
+      getCellContent: function(row) {
+      	return App.Helpers.date.dateFormat(row.get('startTime'));
+      }
+    });
+
+    var runTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Run Time',
+      getCellContent: function(row) {
+        var st = row.get('startTime');
+        var et = row.get('endTime');
+        if (st && et) {
+          return App.Helpers.date.durationSummary(st, et);
+        }
+      }
+    });
+
+    var numTasksCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Tasks',
+      contentPath: 'numTasks'
+    });
+
+    var statusCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin,{
+      headerCellName: 'Status',
+      filterID: 'status_filter',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">&nbsp;\
+          <i {{bind-attr class=":task-status view.cellContent.statusIcon"}}></i>\
+          &nbsp;&nbsp;{{view.cellContent.status}}</span>')
+      }),
+      getCellContent: function(row) {
+      	return { 
+          status: row.get('status'),
+          statusIcon: App.Helpers.misc.getStatusClassForEntity(row)
+        };
+      }
+    });
+
+		return [idCol, nameCol, startTimeCol, runTimeCol, numTasksCol, statusCol];
+	}.property(),
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e18a1fa7/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
new file mode 100644
index 0000000..896db7f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
@@ -0,0 +1,152 @@
+/**
+ * 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.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin, {
+  childEntityType: 'dag',
+
+	controllerName: 'DagsController',
+
+	pageTitle: 'Dags',
+
+	pageSubTitle: 'All Dags',
+
+  // query parameters supported through url. The same named variables in this controller get
+  // bound automatically to the ones defined in the route.
+  queryParams: {
+    count: true,
+    fromID: true,
+    status_filter: 'status',
+    user_filter: 'user'
+  },
+
+  // paging related values. These are bound automatically to the values in url. via the queryParams
+  // defined in the route. 
+  count: 10,
+
+  fromID: null,
+
+  status_filter: null,
+
+  user_filter: null,
+
+  fields: 'events,primaryfilters,otherinfo',
+
+  // The dropdown contents for number of items to show.
+  countOptions: [5, 10, 25, 50, 100],
+
+  loadData: function() {
+    var filters = {
+      primary: {
+        user: this.user_filter
+      },
+      secondary: {
+        status: this.status_filter
+      }
+    }
+    this.setFiltersAndLoadEntities(filters);
+  },
+
+  countUpdated: function() {
+    this.loadData();
+  }.observes('count'),
+
+  actions : {
+    filterUpdated: function(filterID, value) {
+      // any validations required goes here.
+      if (!!value) {
+        this.set(filterID, value);
+      } else {
+        this.set(filterID, null);
+      }
+      this.loadData();
+    },
+  },
+
+	/* table view for dags */
+  columns: function() {
+    var store = this.get('store');
+    var columnHelper = function(columnName, valName) {
+      return App.ExTable.ColumnDefinition.create({
+        textAlign: 'text-align-left',
+        headerCellName: columnName,
+        contentPath: valName
+      });
+    }
+
+    var nameCol = App.ExTable.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Dag Name',
+      tableCellViewClass: Em.Table.TableCell.extend({
+      	template: Em.Handlebars.compile(
+          "{{#link-to 'dag' view.cellContent.id class='ember-table-content'}}{{view.cellContent.name}}{{/link-to}}")
+      }),
+      getCellContent: function(row) {
+      	return {
+          id: row.get('id'),
+          name: row.get('name')
+        };
+      }
+    });
+    var idCol = columnHelper('Dag ID', 'id');
+    var userCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin, {
+      textAlign: 'text-align-left',
+      headerCellName: 'Submitter',
+      filterID: 'user_filter',
+      contentPath: 'user'
+    }); 
+    var statusCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin,{
+      textAlign: 'text-align-left',
+      headerCellName: 'Status',
+      filterID: 'status_filter',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">&nbsp;\
+          <i {{bind-attr class=":task-status view.cellContent.statusIcon"}}></i>\
+          &nbsp;&nbsp;{{view.cellContent.status}}</span>')
+      }),
+      getCellContent: function(row) {
+      	return { 
+          status: row.get('status'),
+          statusIcon: App.Helpers.misc.getStatusClassForEntity(row)
+        };
+      }
+    });
+    var submittedTimeCol = App.ExTable.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Submitted Time',
+      getCellContent: function(row) {
+        return App.Helpers.date.dateFormat(row.get('submittedTime'));
+      }
+    });
+    var runTimeCol = App.ExTable.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Run Time',
+      getCellContent: function(row) {
+        var st = row.get('startTime');
+        var et = row.get('endTime');
+        if (st && et) {
+          return App.Helpers.date.durationSummary(st, et);
+        }
+      }
+    });
+    var appIdCol = columnHelper('Application ID', 'applicationId');
+    return [nameCol, idCol, userCol, statusCol, submittedTimeCol, runTimeCol, appIdCol];
+  }.property(),
+
+
+});
\ No newline at end of file