tez-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject [30/31] tez git commit: TEZ-3227. Tez UI: Replace UI1 with UI2 (sree)
Date Tue, 26 Apr 2016 10:19:01 GMT
http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/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
deleted file mode 100644
index dc92bb2..0000000
--- a/tez-ui/src/main/webapp/Gruntfile.js
+++ /dev/null
@@ -1,482 +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.
- */
-// 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/app.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/ember-table/dist/ember-table.css',
-            '<%= yeoman.app %>/bower_components/font-awesome/css/font-awesome.css',
-            '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/jquery-ui.css',
-            '<%= yeoman.app %>/bower_components/codemirror/lib/codemirror.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/**/*'
-            ]
-          },
-          {
-            src: '<%= yeoman.app %>/scripts/configs.js',
-            dest: '<%= yeoman.dist %>/scripts/configs.js'
-          },
-          {
-            expand: true,
-            flatten: true,
-            cwd: '<%= yeoman.app %>',
-            dest: '<%= yeoman.dist %>/scripts/zip.js',
-            src: [
-              'bower_components/zip.js/WebContent/z-worker.js',
-              'bower_components/zip.js/WebContent/inflate.js',
-              'bower_components/zip.js/WebContent/deflate.js',
-            ]
-          },
-          {
-            expand: true,
-            flatten: true,
-            src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/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/**/*'
-            ]
-          },
-          {
-            src: '<%= yeoman.app %>/scripts/configs.js',
-            dest: '<%= yeoman.dist %>/scripts/configs.js'
-          },
-          {
-            expand: true,
-            flatten: true,
-            src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/images/*',
-            dest: '.tmp/styles/images/'
-          },
-          {
-            expand: true,
-            flatten: true,
-            src: '<%= yeoman.app %>/bower_components/font-awesome/fonts/*',
-            dest: '.tmp/fonts/'
-          },
-          {
-            expand: true,
-            flatten: true,
-            cwd: '<%= yeoman.app %>',
-            dest: '.tmp/scripts/zip.js',
-            src: [
-              'bower_components/zip.js/WebContent/z-worker.js',
-              'bower_components/zip.js/WebContent/inflate.js',
-              'bower_components/zip.js/WebContent/deflate.js',
-            ]
-          },
-          {
-            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/app.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/13132ec7/tez-ui/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/README.md b/tez-ui/src/main/webapp/README.md
index 85b7fb2..997752c 100644
--- a/tez-ui/src/main/webapp/README.md
+++ b/tez-ui/src/main/webapp/README.md
@@ -1,21 +1,57 @@
 <!--
-  Licensed 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
+   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
+       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. See accompanying LICENSE file.
+   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.
 -->
 
-Tez UI
-=========
+# Tez-ui
 
-The Tez UI is an ember based web application that provides visualization of Tez applications
-running on the Apache Hadoop YARN framework.
+The Tez UI is an ember based web-app that provides visualization of Tez applications running on the Apache Hadoop YARN framework.
 
-For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+For more information on Tez and the Tez UI - Check the [Tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Configurations
+
+* By default timeline is expected at localhost:8188 & RM at localhost:8088
+* You can point the UI to custom locations by setting the environment variables in `src/main/webapp/config/configs.env`
+
+## Development
+
+All the following commands must be run inside `src/main/webapp`.
+
+### Prerequisites
+
+You will need the following things properly installed on your computer.
+
+* Install [Node.js](http://nodejs.org/) (with NPM)
+* Install [Bower](http://bower.io/)
+* Install all dependencies by running `npm install` & `bower install`
+
+### Running UI
+
+* `npm start`
+* Visit your app at [http://localhost:4200](http://localhost:4200).
+
+### Running Tests
+
+* `npm test`
+
+### Building
+
+* `npm run build` (production)
+* Files would be stored in "dist/"
+
+### Adding new routes (pages), controllers, components etc.
+
+* Use ember-cli blueprint generator - [Ember CLI](http://ember-cli.com/extending/#generators-and-blueprints)

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/WEB-INF/wro.xml
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/WEB-INF/wro.xml b/tez-ui/src/main/webapp/WEB-INF/wro.xml
new file mode 100644
index 0000000..2709c6f
--- /dev/null
+++ b/tez-ui/src/main/webapp/WEB-INF/wro.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<groups xmlns="http://www.isdc.ro/wro">
+  <group name='vendor'>
+    <js>/vendor.js</js>
+  </group>
+  <group name='tez-ui'>
+    <js>/tez-ui.js</js>
+  </group>
+</groups>

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/abstract.js b/tez-ui/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..121d4ee
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/abstract.js
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import LoaderAdapter from './loader';
+
+export default LoaderAdapter.extend({
+  serverName: null, //Must be set by inheriting classes
+
+  host: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName");
+    return this.get(`hosts.${serverName}`);
+  }),
+  namespace: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName");
+    return this.get(`env.app.namespaces.webService.${serverName}`);
+  }),
+  pathTypeHash: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName");
+    return this.get(`env.app.paths.${serverName}`);
+  }),
+
+  ajaxOptions: function(url, method, options) {
+    options = options || {};
+    options.crossDomain = true;
+    options.xhrFields = {
+      withCredentials: true
+    };
+    options.targetServer = this.get('serverName');
+    return this._super(url, method, options);
+  },
+
+  pathForType: function(type) {
+    var serverName = this.get("serverName"),
+        path = this.get("pathTypeHash")[type];
+    Ember.assert(`Path not found for type:${type} to server:${serverName}`, path);
+    return path;
+  },
+
+  normalizeErrorResponse: function(status, headers, payload) {
+    var response;
+
+    if(payload && payload.exception && !payload.errors) {
+      payload = `${payload.exception}\n${payload.message}\n${payload.javaClassName}`;
+      response = this._super(status, headers, payload);
+    }
+    else {
+      response = this._super(status, headers, payload);
+      Ember.set(response, '0.title', this.get("outOfReachMessage"));
+    }
+
+    return response;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/ahs-app.js b/tez-ui/src/main/webapp/app/adapters/ahs-app.js
new file mode 100644
index 0000000..0e7556a
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/ahs-app.js
@@ -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.
+ */
+
+import Ember from 'ember';
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+  namespace: Ember.computed.alias("env.app.namespaces.webService.appHistory"),
+  pathForType: function() {
+    return "apps";
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/am.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/am.js b/tez-ui/src/main/webapp/app/adapters/am.js
new file mode 100644
index 0000000..c4cb75d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/am.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "am",
+  outOfReachMessage: "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager.",
+
+  queryRecord: function(store, type, query) {
+    return this.query(store, type, query);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/app-rm.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/app-rm.js b/tez-ui/src/main/webapp/app/adapters/app-rm.js
new file mode 100644
index 0000000..b61e391
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/app-rm.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import RMAdapter from './rm';
+
+export default RMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/app.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/app.js b/tez-ui/src/main/webapp/app/adapters/app.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/app.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/attempt-am.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/attempt-am.js b/tez-ui/src/main/webapp/app/adapters/attempt-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/attempt-am.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/attempt.js b/tez-ui/src/main/webapp/app/adapters/attempt.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/attempt.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/dag-am.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/dag-am.js b/tez-ui/src/main/webapp/app/adapters/dag-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/dag-am.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/dag.js b/tez-ui/src/main/webapp/app/adapters/dag.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/dag.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/loader.js b/tez-ui/src/main/webapp/app/adapters/loader.js
new file mode 100644
index 0000000..f63bd07
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/loader.js
@@ -0,0 +1,58 @@
+/*global more*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+
+var MoreString = more.String;
+
+export default DS.RESTAdapter.extend({
+  _isLoader: true,
+
+  buildURL: function(modelName, id, snapshot, requestType, query, params) {
+    var url = this._super(modelName, id, snapshot, requestType, query);
+    return params ? MoreString.fmt(url, params) : url;
+  },
+
+  _loaderAjax: function (url, queryParams, nameSpace) {
+    if (this.sortQueryParams && queryParams) {
+      queryParams = this.sortQueryParams(queryParams);
+    }
+
+    // Inject nameSpace
+    return this.ajax(url, 'GET', { data: queryParams }).then(function (data) {
+      return {
+        nameSpace: nameSpace,
+        data: data
+      };
+    });
+  },
+
+  queryRecord: function(store, type, query) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, query.id, null, null, queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/rm.js b/tez-ui/src/main/webapp/app/adapters/rm.js
new file mode 100644
index 0000000..252affb
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/rm.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "rm",
+  outOfReachMessage: "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled.",
+
+  // Any rm specific adapter changes must be added here
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/task-am.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/task-am.js b/tez-ui/src/main/webapp/app/adapters/task-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/task-am.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/task.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/task.js b/tez-ui/src/main/webapp/app/adapters/task.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/task.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/timeline.js b/tez-ui/src/main/webapp/app/adapters/timeline.js
new file mode 100644
index 0000000..1a341f7
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/timeline.js
@@ -0,0 +1,106 @@
+/*global more*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+var MoreObject = more.Object;
+
+export default AbstractAdapter.extend({
+  serverName: "timeline",
+  outOfReachMessage: "Timeline server (ATS) is out of reach. Either it's down, or CORS is not enabled.",
+
+  filters: {
+    dagID: 'TEZ_DAG_ID',
+    vertexID: 'TEZ_VERTEX_ID',
+    taskID: 'TEZ_TASK_ID',
+    attemptID: 'TEZ_TASK_ATTEMPT_ID',
+    hiveQueryID: 'HIVE_QUERY_ID',
+    appID: 'applicationId',
+
+    dagName: 'dagName',
+    user: "user",
+    status: "status",
+    callerID: "callerId"
+  },
+
+  stringifyFilters: function (filters) {
+    var filterStrs = [];
+
+    MoreObject.forEach(filters, function (key, value) {
+      filterStrs.push(`${key}:${value}`);
+    });
+
+    return filterStrs.join(",");
+  },
+
+  normalizeQuery: function(query) {
+    var primaryFilter = null, // Primary must have just one single filter
+        secondaryFilters = {},
+        normalQuery = {},
+        filterStr;
+
+    MoreObject.forEach(query, function (key, value) {
+      var filter = this.get(`filters.${key}`);
+
+      if(filter) {
+        if(!primaryFilter) {
+          primaryFilter = {};
+          primaryFilter[filter] = value;
+        }
+        else {
+          secondaryFilters[filter] = value;
+        }
+      }
+      else {
+        normalQuery[key] = value;
+      }
+    }, this);
+
+    // primaryFilter
+    if(primaryFilter) {
+      filterStr = this.stringifyFilters(primaryFilter);
+    }
+    if(filterStr) {
+      normalQuery.primaryFilter = filterStr;
+    }
+
+    // secondaryFilters
+    filterStr = this.stringifyFilters(secondaryFilters);
+    if(filterStr) {
+      normalQuery.secondaryFilter = filterStr;
+    }
+
+    // Limit
+    normalQuery.limit = normalQuery.limit || this.get("env.app.rowLoadLimit");
+
+    return normalQuery;
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+
+    if(query) {
+      queryParams = this.normalizeQuery(queryParams);
+    }
+
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/vertex-am.js b/tez-ui/src/main/webapp/app/adapters/vertex-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/vertex-am.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/adapters/vertex.js b/tez-ui/src/main/webapp/app/adapters/vertex.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/adapters/vertex.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/app.js b/tez-ui/src/main/webapp/app/app.js
new file mode 100644
index 0000000..fb4695c
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/app.js
@@ -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.
+ */
+
+import Ember from 'ember';
+import Resolver from 'ember-resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+
+let App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix,
+  Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+
+export default App;

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/caller-info.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/caller-info.js b/tez-ui/src/main/webapp/app/components/caller-info.js
new file mode 100644
index 0000000..ece33ac
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/caller-info.js
@@ -0,0 +1,78 @@
+/*global CodeMirror*/
+/**
+ * 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.
+ */
+
+// Must be convert into an ember addon
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  type: null,
+  info: null,
+
+  codeMirror: null,
+
+  classNames: ['caller-info'],
+
+  mode: Ember.computed("type", function () {
+    switch(this.get("type")) {
+      case 'Hive':
+        return 'text/x-hive';
+      case 'Pig':
+        return 'text/x-pig';
+      default:
+        return 'text/x-sql';
+    }
+  }),
+
+  _init:  Ember.on('didInsertElement', function() {
+    var element  = Ember.$(this.get('element')).find('textarea')[0],
+        codeMirror = CodeMirror.fromTextArea(element, {
+          theme: 'default',
+          indentUnit: 2,
+          smartIndent: true,
+          tabSize: 4,
+          electricChars: true,
+          lineWrapping: true,
+          lineNumbers: true,
+          readOnly: true,
+          autofocus: false,
+          dragDrop: false,
+        });
+
+    this.set('codeMirror', codeMirror);
+
+    this._modeChanged();
+    this._infoChanged();
+  }),
+
+  _modeChanged: Ember.observer("mode", function() {
+    this.get('codeMirror').setOption("mode", this.get("mode"));
+  }),
+
+  _infoChanged: Ember.observer("info", function() {
+    var codeMirror = this.get('codeMirror'),
+        info = this.get('info') || '';
+
+    if (this.get('codeMirror').getValue() !== info) {
+      codeMirror.setValue(info);
+    }
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/column-selector.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/column-selector.js b/tez-ui/src/main/webapp/app/components/column-selector.js
new file mode 100644
index 0000000..8f9ac13
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/column-selector.js
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import isIOCounter from '../utils/misc';
+
+export default Ember.Component.extend({
+
+  classNames: ['column-selector'],
+
+  searchText: "",
+  selectAll: false,
+
+  content: null,
+
+  options: Ember.computed("content.columns", "content.visibleColumnIDs", function () {
+    var group,
+        highlight = false,
+        visibleColumnIDs = this.get('content.visibleColumnIDs') || {};
+
+    return this.get('content.columns').map(function (definition) {
+      var css = '';
+
+      highlight = highlight ^ (Ember.get(definition, "counterGroupName") !== group);
+      group = Ember.get(definition, "counterGroupName");
+
+      if(highlight) {
+        css += ' highlight';
+      }
+      if(group && isIOCounter(group)) {
+        css += ' per-io';
+      }
+
+      return Ember.Object.create({
+        id: Ember.get(definition, "id"),
+        displayText: Ember.get(definition, "headerTitle"),
+        css: css,
+        selected: visibleColumnIDs[Ember.get(definition, "id")]
+      });
+    });
+  }),
+
+  filteredOptions: Ember.computed("options", "searchText", function () {
+    var options = this.get('options'),
+        searchText = this.get('searchText');
+
+    if (!searchText) {
+      return options;
+    }
+
+    return options.filter(function (option) {
+      return option.get('displayText').match(searchText);
+    });
+  }),
+
+  selectedColumnIDs: Ember.computed("options", function () {
+    var columnIds = {};
+    this.get('options').forEach(function (option) {
+      columnIds[option.get("id")] = option.get('selected');
+    });
+
+    return columnIds;
+  }),
+
+  _selectObserver: Ember.observer('filteredOptions.@each.selected', function () {
+    var selectedCount = 0;
+    this.get('filteredOptions').forEach(function (option) {
+      if(Ember.get(option, 'selected')) {
+        selectedCount++;
+      }
+    });
+    this.set('selectAll', selectedCount > 0 && selectedCount === this.get('filteredOptions.length'));
+  }),
+
+  actions: {
+    selectAll: function (checked) {
+      this.get('filteredOptions').forEach(function (option) {
+        Ember.set(option, 'selected', checked);
+      });
+    },
+    closeModal: function () {
+      this.get("targetObject").send("closeModal");
+    },
+    ok: function () {
+      this.get("targetObject").send("columnsSelected", this.get("selectedColumnIDs"));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/dags-page-search.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/dags-page-search.js b/tez-ui/src/main/webapp/app/components/dags-page-search.js
new file mode 100644
index 0000000..f1cc71b
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/dags-page-search.js
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  classNames: ['dags-page-search'],
+
+  dagName: Ember.computed.oneWay("tableDefinition.dagName"),
+  dagID: Ember.computed.oneWay("tableDefinition.dagID"),
+  submitter: Ember.computed.oneWay("tableDefinition.submitter"),
+  status: Ember.computed.oneWay("tableDefinition.status"),
+  appID: Ember.computed.oneWay("tableDefinition.appID"),
+  callerID: Ember.computed.oneWay("tableDefinition.callerID"),
+
+  sendSearch: function () {
+    this.get('parentView').sendAction('search', {
+      dagName: this.get("dagName"),
+      dagID: this.get("dagID"),
+      submitter: this.get("submitter"),
+      status: this.get("status"),
+      appID: this.get("appID"),
+      callerID: this.get("callerID"),
+    });
+  },
+
+  actions: {
+    statusChanged: function (value) {
+      this.set("status", value);
+    },
+    statusKeyPress: function () {
+      this.sendSearch();
+    },
+    search: function () {
+      this.sendSearch();
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js b/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js
new file mode 100644
index 0000000..8d88b45
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  tableDefinition: null,
+  dataProcessor: null,
+
+  classNames: ['pagination-ui'],
+  isVisible: Ember.computed.alias('tableDefinition.enablePagination'),
+
+  atFirst: Ember.computed('tableDefinition.pageNum', function () {
+    return this.get('tableDefinition.pageNum') === 1;
+  }),
+
+  rowCountOptions: Ember.computed('tableDefinition.rowCountOptions', 'tableDefinition.rowCount', function () {
+    var options = this.get('tableDefinition.rowCountOptions'),
+        rowCount = this.get('tableDefinition.rowCount');
+
+    return options.map(function (option) {
+      return {
+        value: option,
+        selected: option === rowCount
+      };
+    });
+  }),
+
+  _possiblePages: Ember.computed('tableDefinition.pageNum',
+      'tableDefinition.moreAvailable',
+      'dataProcessor.totalPages', function () {
+    var pageNum = this.get('tableDefinition.pageNum'),
+        totalPages = this.get('dataProcessor.totalPages'),
+        possiblePages = [],
+        startPage = 1,
+        endPage = totalPages,
+        delta = 0;
+
+    if(this.get('tableDefinition.moreAvailable')) {
+      totalPages++;
+    }
+
+    if(totalPages > 1) {
+      startPage = pageNum - 1;
+      endPage = pageNum + 1;
+
+      if(startPage < 1) {
+        delta = 1 - startPage;
+      }
+      else if(endPage > totalPages) {
+        delta = totalPages - endPage;
+      }
+
+      startPage += delta;
+      endPage += delta;
+    }
+
+    startPage = Math.max(startPage, 1);
+    endPage = Math.min(endPage, totalPages);
+
+    while(startPage <= endPage) {
+      possiblePages.push({
+        isCurrent: startPage === pageNum,
+        isLoadPage: startPage === totalPages,
+        pageNum: startPage++,
+      });
+    }
+
+    return possiblePages;
+  }),
+
+  actions: {
+    rowSelected: function (value) {
+      value = parseInt(value);
+      if(this.get('tableDefinition.rowCount') !== value) {
+        this.get('parentView').send('rowChanged', value);
+      }
+    },
+    changePage: function (value) {
+      if(value === 1) {
+        this.get('parentView').sendAction('reload');
+      }
+      else if(this.get('dataProcessor.totalPages') < value) {
+        this.get('parentView').sendAction('loadPage', value);
+      }
+      else {
+        this.get('parentView').send('pageChanged', value);
+      }
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/date-formatter.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/date-formatter.js b/tez-ui/src/main/webapp/app/components/date-formatter.js
new file mode 100644
index 0000000..da21383
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/date-formatter.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  classNames: ["date-formatter"],
+
+  content: null,
+
+  env: Ember.inject.service('env'),
+  timeZone: Ember.computed.oneWay('env.app.timeZone'),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js b/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js
new file mode 100644
index 0000000..a487699
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  process: null,
+  blocking: null,
+
+  processor: null,
+
+  classNames: ["em-swimlane-blocking-event"],
+
+  blockingEvent: Ember.computed("process.blockingEventName",
+      "process.events.@each.name", function () {
+    var events = this.get("process.events"),
+        blockingEventName = this.get("process.blockingEventName");
+
+    return events.find(function (event) {
+      return event.name === blockingEventName;
+    });
+  }),
+
+  didInsertElement: Ember.observer("blockingEvent.time", "processor.timeWindow", function () {
+    var blockTime = this.get("blockingEvent.time"),
+        blockerEventHeight;
+
+    if(blockTime && this.get("blocking.endEvent.time") >= blockTime) {
+      blockerEventHeight = (this.get("blocking.index") - this.get("process.index")) * 30;
+
+      Ember.run.later(this, function () {
+        this.$().css({
+          "left": this.get("processor").timeToPositionPercent(blockTime) + "%"
+        });
+        this.$(".event-line").css({
+          "height": `${blockerEventHeight}px`,
+          "border-color": this.get("process").getColor()
+        });
+      });
+    }
+  }),
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "blocking-event", this.get("process"), {
+      mouseEvent: mouseEvent,
+      blocking: this.get("blocking"),
+      blockingEvent: this.get("blockingEvent")
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js b/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js
new file mode 100644
index 0000000..67186dd
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  process: null,
+  processor: null,
+  focusedProcess: null,
+
+  classNames: ["em-swimlane-consolidated-process"],
+  classNameBindings: ['focused'],
+
+  focused: Ember.computed("process", "focusedProcess", function () {
+    return this.get("process") === this.get("focusedProcess");
+  }),
+
+  fromPos: Ember.computed("process.consolidateStartTime", "processor.timeWindow", function () {
+    var time = this.get("process.consolidateStartTime");
+    if(time) {
+      return this.get("processor").timeToPositionPercent(time);
+    }
+  }),
+
+  toPos: Ember.computed("process.consolidateEndTime", "processor.timeWindow", function () {
+    var time = this.get("process.consolidateEndTime");
+    if(time) {
+      return this.get("processor").timeToPositionPercent(time);
+    }
+  }),
+
+  didInsertElement: Ember.observer("fromPos", "toPos", function () {
+    var fromPos = this.get("fromPos"),
+        toPos = this.get("toPos"),
+        thisElement = this.$();
+
+    if(fromPos && toPos) {
+      thisElement.show();
+      thisElement.css({
+        left: fromPos + "%",
+        right: (100 - toPos) + "%",
+        "background-color": this.get("process").getConsolidateColor(),
+        "z-index": parseInt(toPos - fromPos)
+      });
+    }
+    else {
+      thisElement.hide();
+    }
+  }),
+
+  sendMouseAction: function (name, mouseEvent) {
+    var fromPos = this.get("fromPos") || 0,
+        toPos = this.get("toPos") || 0;
+
+    this.sendAction(name, "consolidated-process", this.get("process"), {
+      mouseEvent: mouseEvent,
+      contribution: parseInt(toPos - fromPos)
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js b/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js
new file mode 100644
index 0000000..224489b
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  bar: null,
+  barIndex: 0,
+
+  process: null,
+  processor: null,
+
+  classNames: ["em-swimlane-event-bar"],
+
+  fromEvent: Ember.computed("process.events.@each.name", "bar.fromEvent", function () {
+    var events = this.get("process.events"),
+        fromEventName = this.get("bar.fromEvent");
+    return events.find(function (event) {
+      return event.name === fromEventName;
+    });
+  }),
+  toEvent: Ember.computed("process.events.@each.name", "bar.toEvent", function () {
+    var events = this.get("process.events"),
+        toEventName = this.get("bar.toEvent");
+    return events.find(function (event) {
+      return event.name === toEventName;
+    });
+  }),
+
+  didInsertElement: Ember.observer("fromEvent.time", "toEvent.time",
+      "barIndex", "processor.timeWindow", function () {
+
+    var processor = this.get("processor"),
+        fromEventPos = processor.timeToPositionPercent(this.get("fromEvent.time")),
+        toEventPos = processor.timeToPositionPercent(this.get("toEvent.time")),
+        color = this.get("bar.color") || this.get("process").getBarColor(this.get("barIndex"));
+
+    if(fromEventPos && toEventPos) {
+      Ember.run.later(this, function () {
+        this.$().show();
+        this.$(".event-bar").css({
+          left: fromEventPos + "%",
+          right: (100 - toEventPos) + "%",
+          "background-color": color,
+          "border-color": this.get("process").getColor()
+        });
+      });
+    }
+    else {
+      this.$().hide();
+    }
+  }),
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "event-bar", this.get("process"), {
+      mouseEvent: mouseEvent,
+      bar: this.get("bar"),
+      fromEvent: this.get("fromEvent"),
+      toEvent: this.get("toEvent")
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-event.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-event.js b/tez-ui/src/main/webapp/app/components/em-swimlane-event.js
new file mode 100644
index 0000000..4eef7f0
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-event.js
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  process: null,
+  event: null,
+
+  processor: null,
+
+  classNames: ["em-swimlane-event"],
+
+  didInsertElement: Ember.observer("event.time", "processor.timeWindow", function () {
+    var color = this.get("process").getColor();
+
+    this.$(".event-line").css("border-color", color);
+    this.$(".event-bubble").css("border-color", color);
+
+    Ember.run.later(this, function () {
+      this.$().css({
+        "left": this.get("processor").timeToPositionPercent(this.get("event.time")) + "%"
+      });
+    });
+  }),
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "event", this.get("process"), {
+      mouseEvent: mouseEvent,
+      events: [this.get("event")]
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js
new file mode 100644
index 0000000..2d6e2b6
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  process: null,
+  processor: null,
+
+  didInsertElement: Ember.observer("process.startEvent.time",
+      "process.endEvent.time", "processor.timeWindow", function () {
+    var processor = this.get("processor"),
+        startPos = processor.timeToPositionPercent(this.get("process.startEvent.time")),
+        endPos = processor.timeToPositionPercent(this.get("process.endEvent.time"));
+
+    Ember.run.later(this, function () {
+      this.$(".process-line").css({
+        left: startPos + "%",
+        right: (100 - endPos) + "%",
+        "background-color": this.get("process").getColor()
+      });
+    });
+  }),
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "process-line", this.get("process"), {
+      mouseEvent: mouseEvent,
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js
new file mode 100644
index 0000000..eea897d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js
@@ -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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  process: null,
+
+  classNames: ["em-swimlane-process-name"],
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "process-name", this.get("process"), {
+      mouseEvent: mouseEvent,
+    });
+  },
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js
new file mode 100644
index 0000000..aa555cd
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+const BUBBLE_DIA = 10; // Same as that in css
+
+export default Ember.Component.extend({
+
+  process: null,
+  processor: null,
+  focusedProcess: null,
+
+  classNames: ["em-swimlane-process-visual"],
+
+  actions: {
+    showTooltip: function(type, process, options) {
+
+      if(type === "event") {
+        let clientX = options.mouseEvent.clientX,
+            events = process.get("events"),
+            eventsUnderMouse = [];
+
+        this.$(".em-swimlane-event").each(function (index) {
+          var offsetLeft = Ember.$(this).offset().left;
+
+          if(clientX >= offsetLeft - BUBBLE_DIA && clientX <= offsetLeft + BUBBLE_DIA) {
+            eventsUnderMouse.push(events[index]);
+          }
+        });
+
+        if(events.length) {
+          eventsUnderMouse.sort(function (eventA, eventB) {
+            return eventA.time - eventB.time;
+          });
+          options.events = eventsUnderMouse;
+        }
+      }
+
+      this.sendAction("showTooltip", type, process, options);
+    },
+
+    hideTooltip: function(type, process, options) {
+      this.sendAction("hideTooltip", type, process, options);
+    },
+    click: function (type, process, options) {
+      this.sendAction("click", type, process, options);
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js b/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js
new file mode 100644
index 0000000..4d1b933
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import moment from 'moment';
+
+const DEFAULT_MARK_COUNT = 10;
+
+export default Ember.Component.extend({
+
+  zoom: null,
+  processor: null,
+  scroll: 0,
+
+  classNames: ["em-swimlane-ruler"],
+
+  markDef: Ember.computed("processor.timeWindow", "zoom", function () {
+    var markCount = parseInt(DEFAULT_MARK_COUNT * this.get("zoom") / 100),
+        timeWindow = this.get("processor.timeWindow"),
+        duration = moment.duration(parseInt(timeWindow / markCount)),
+
+        markUnit = "Milliseconds",
+        markBaseValue = 0,
+        markWindow = 0,
+        styleWidth = 0;
+
+    if(markBaseValue = duration.years()) {
+      markUnit = "Years";
+    }
+    else if(markBaseValue = duration.months()) {
+      markUnit = "Months";
+    }
+    else if(markBaseValue = duration.days()) {
+      markUnit = "Days";
+    }
+    else if(markBaseValue = duration.hours()) {
+      markUnit = "Hours";
+    }
+    else if(markBaseValue = duration.minutes()) {
+      markUnit = "Minutes";
+    }
+    else if(markBaseValue = duration.seconds()) {
+      markUnit = "Seconds";
+    }
+    else {
+      markBaseValue = duration.milliseconds();
+    }
+
+    if(markBaseValue > 10) {
+      markBaseValue = Math.floor(markBaseValue / 10) * 10;
+    }
+
+    markWindow = moment.duration(markBaseValue, markUnit.toLowerCase()).asMilliseconds();
+    styleWidth = markWindow / timeWindow * 100;
+
+    return {
+      unit: markUnit,
+      baseValue: markBaseValue,
+      style: Ember.String.htmlSafe(`width: ${styleWidth}%;`),
+      count: parseInt(100 / styleWidth * 1.1)
+    };
+  }),
+
+  unitTextStyle: Ember.computed("scroll", function () {
+    var scroll = this.get("scroll");
+    return Ember.String.htmlSafe(`left: ${scroll}px;`);
+  }),
+
+  marks: Ember.computed("processor.timeWindow", "markDef", function () {
+    var def = this.get("markDef"),
+        baseValue = def.baseValue,
+        marks = [];
+
+    for(var i=0, count = def.count; i < count; i++) {
+      marks.push({
+        duration: parseInt(baseValue * i)
+      });
+    }
+
+    return marks;
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js b/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js
new file mode 100644
index 0000000..36a7bbc
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js
@@ -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.
+ */
+
+import Ember from 'ember';
+
+const MAX_TEXT_LENGTH = 10;
+
+export default Ember.Component.extend({
+
+  process: null,
+
+  classNames: ["em-swimlane-vertex-name"],
+
+  sendMouseAction: function (name, mouseEvent) {
+    this.sendAction(name, "process-name", this.get("process"), {
+      mouseEvent: mouseEvent,
+    });
+  },
+
+  progressText: Ember.computed("process.vertex.finalStatus", "process.vertex.progress", function () {
+    if(this.get("process.vertex.finalStatus") === "RUNNING") {
+      let progress = this.get("process.vertex.progress");
+      if(!isNaN(progress)) {
+        let percent = parseInt(progress * 100);
+        return `${percent}%`;
+      }
+    }
+  }),
+
+  useEllipsis: Ember.computed("process.name", "progressText", function () {
+    var name = this.get("process.name") || "",
+        progressLength = this.get("progressText.length");
+    progressLength = progressLength ? progressLength + 1 : 0;
+    return  name.length + progressLength - 1 > MAX_TEXT_LENGTH;
+  }),
+
+  processName: Ember.computed("process.name", "progressText", function () {
+    var name = this.get("process.name") || "",
+        progressLength = this.get("progressText.length");
+    progressLength = progressLength ? progressLength + 1 : 0;
+    return name.substr(Math.max(name.length - MAX_TEXT_LENGTH - progressLength, 0));
+  }),
+
+  mouseEnter: function (mouseEvent) {
+    this.sendMouseAction("showTooltip", mouseEvent);
+  },
+
+  mouseLeave: function (mouseEvent) {
+    this.sendMouseAction("hideTooltip", mouseEvent);
+  },
+
+  mouseUp: function (mouseEvent) {
+    this.sendMouseAction("click", mouseEvent);
+  }
+
+});


Mime
View raw message