http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/router.js 
b/tez-ui/src/main/webapp/app/router.js
new file mode 100644
index 0000000..98a456a
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/router.js
@@ -0,0 +1,59 @@
+/**
+ * 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 config from './config/environment';
+
+const Router = Ember.Router.extend({
+  location: config.locationType
+});
+
+Router.map(function() {
+  this.route('dags', { path: '/' });
+  this.route('dag', {path: '/dag/:dag_id'}, function() {
+    this.route('vertices');
+    this.route('tasks');
+    this.route('attempts');
+    this.route('counters');
+    this.route('index', {path: '/'}, function() {});
+    this.route('graphical');
+    this.route('swimlane');
+  });
+  this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
+    this.route('tasks');
+    this.route('attempts');
+    this.route('counters');
+  });
+  this.route('task', {path: '/task/:task_id'}, function() {
+    this.route('attempts');
+    this.route('counters');
+  });
+  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {
+    this.route('counters');
+  });
+  // Alias for backward compatibility with Tez UI V1
+  this.route('app', {path: '/tez-app/:app_id'}, function () {});
+  this.route('app', {path: '/app/:app_id'}, function () {
+    this.route('dags');
+    this.route('configs');
+  });
+  this.route('multi-am-pollster');
+  this.route('single-am-pollster');
+});
+
+export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/abstract.js 
b/tez-ui/src/main/webapp/app/routes/abstract.js
new file mode 100644
index 0000000..39b8314
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/abstract.js
@@ -0,0 +1,189 @@
+/*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 Ember from 'ember';
+import DS from 'ember-data';
+
+import LoaderService from '../services/loader';
+import UnlinkedPromise from '../errors/unlinked-promise';
+import NameMixin from '../mixins/name';
+
+var MoreObject = more.Object;
+
+export default Ember.Route.extend(NameMixin, {
+  title: null, // Must be set by inheriting class
+
+  loaderNamespace: null,
+  isLoading: false,
+  currentPromiseId: null,
+  loadedValue: null,
+
+  isLeafRoute: false,
+  breadcrumbs: null,
+  childCrumbs: null,
+
+  currentQuery: {},
+
+  loaderQueryParams: {},
+
+  init: function () {
+    var namespace = this.get("loaderNamespace");
+    if(namespace) {
+      this.setLoader(namespace);
+    }
+  },
+
+  model: function(params/*, transition*/) {
+    this.set("currentQuery", this.queryFromParams(params));
+    Ember.run.later(this, "loadData");
+  },
+
+  queryFromParams: function (params) {
+    var query = {};
+
+    MoreObject.forEach(this.get("loaderQueryParams"), function (name, 
paramKey) {
+      var value = Ember.get(params, paramKey);
+      if(value) {
+        query[name] = value;
+      }
+    });
+
+    return query;
+  },
+
+  setDocTitle: function () {
+    Ember.$(document).attr('title', "Tez UI : " + this.get('title'));
+  },
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    this.setDocTitle();
+  },
+
+  checkAndCall: function (id, functionName, query, options, value) {
+    if(id === this.get("currentPromiseId")) {
+      return this[functionName](value, query, options);
+    }
+    else {
+      throw new UnlinkedPromise();
+    }
+  },
+
+  loadData: function (options) {
+    var promiseId = Math.random(),
+        query = this.get("currentQuery");
+
+    options = options || {};
+
+    this.set('currentPromiseId', promiseId);
+
+    return Ember.RSVP.resolve().
+      then(this.checkAndCall.bind(this, promiseId, "setLoading", query, 
options)).
+      then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query, 
options)).
+      then(this.checkAndCall.bind(this, promiseId, "load", query, options)).
+      then(this.checkAndCall.bind(this, promiseId, "afterLoad", query, 
options)).
+      then(this.checkAndCall.bind(this, promiseId, "setValue", query, 
options)).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  setLoading: function (/*query, options*/) {
+    this.set('isLoading', true);
+    this.set('controller.isLoading', true);
+  },
+  beforeLoad: function (value/*, query, options*/) {
+    return value;
+  },
+  load: function (value/*, query, options*/) {
+    return value;
+  },
+  afterLoad: function (value/*, query, options*/) {
+    return value;
+  },
+  setValue: function (value/*, query, options*/) {
+    this.set('loadedValue', value);
+
+    this.set('isLoading', false);
+    this.set('controller.isLoading', false);
+
+    this.send("setLoadTime", this.getLoadTime(value));
+
+    return value;
+  },
+  onLoadFailure: function (error) {
+    if(error instanceof UnlinkedPromise) {
+      Ember.Logger.warn("Slow down, you are refreshing too fast!");
+    }
+    else {
+      this.send("error", error);
+      throw(error);
+    }
+  },
+
+  getLoadTime: function (value) {
+    if(value instanceof DS.RecordArray) {
+      value = value.get("content.0.record");
+    }
+    else if(Array.isArray(value)) {
+      value = value[0];
+    }
+
+    if(value) {
+      return Ember.get(value, "loadTime");
+    }
+  },
+
+  _setControllerModel: Ember.observer("loadedValue", function () {
+    var controller = this.get("controller");
+    if(controller) {
+      controller.set("model", this.get("loadedValue"));
+    }
+  }),
+
+  setLoader: function (nameSpace) {
+    this.set("loader", LoaderService.create({
+      nameSpace: nameSpace,
+      store: this.get("store"),
+      container: this.get("container")
+    }));
+  },
+
+  startCrumbBubble: function () {
+    this.send("bubbleBreadcrumbs", []);
+  },
+
+  actions: {
+    setBreadcrumbs: function (crumbs) {
+      var name = this.get("name");
+      if(crumbs && crumbs[name]) {
+        this.set("breadcrumbs", crumbs[name]);
+      }
+      return true;
+    },
+    bubbleBreadcrumbs: function (crumbs) {
+      crumbs.unshift.apply(crumbs, this.get("breadcrumbs"));
+      return true;
+    },
+    reload: function () {
+      Ember.run.later(this, "loadData", {reload: true});
+    },
+    willTransition: function () {
+      this.set("loadedValue", null);
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/am-pollster.js 
b/tez-ui/src/main/webapp/app/routes/am-pollster.js
new file mode 100644
index 0000000..e26c0aa
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/am-pollster.js
@@ -0,0 +1,93 @@
+/*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 Ember from 'ember';
+
+import PollsterRoute from './pollster';
+
+var MoreObject = more.Object;
+
+export default PollsterRoute.extend({
+
+  countersToPoll: null,
+
+  onRecordPoll: function (record) {
+    var query = {},
+        countersToPoll = this.get("countersToPoll");
+
+    if(countersToPoll !== null) {
+      query.counters = countersToPoll;
+    }
+
+    return this.get("loader").loadNeed(record, "am", {reload: true}, query);
+  },
+
+  onPollFailure: function (error) {
+    var that = this,
+        record = this.get("polledRecords.0");
+
+    this.get("loader").queryRecord("appRm", record.get("appID"), {reload: 
true}).then(function (appRm) {
+      if(appRm.get('isComplete')) {
+        that.scheduleReload();
+      }
+      else {
+        that.send("error", error);
+      }
+    }, function (error) {
+      that.send("error", error);
+      that.scheduleReload();
+    });
+  },
+
+  scheduleReload: function () {
+    this.set("polledRecords", null);
+    Ember.run.debounce(this, "reload", this.get("polling.interval") * 2);
+  },
+
+  reload: function () {
+    this.set("polledRecords", null);
+    this.send("reload");
+  },
+
+  actions: {
+    countersToPollChanged: function (counterColumnDefinitions) {
+      var counterGroupHash = {},
+          counterGroups = [];
+
+      if(counterColumnDefinitions){
+        counterColumnDefinitions.forEach(function (definition) {
+          var counterGroupName = definition.get("counterGroupName"),
+              counterNames = counterGroupHash[counterGroupName];
+          if(!counterNames) {
+            counterNames = counterGroupHash[counterGroupName] = [];
+          }
+          counterNames.push(definition.get("counterName"));
+        });
+
+        MoreObject.forEach(counterGroupHash, function (groupName, counters) {
+          counters = counters.join(",");
+          counterGroups.push(`${groupName}/${counters}`);
+        });
+      }
+
+      this.set("countersToPoll", counterGroups.join(";"));
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/app.js 
b/tez-ui/src/main/webapp/app/routes/app.js
new file mode 100644
index 0000000..395a9be
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/app.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Application",
+
+  loaderQueryParams: {
+    id: "app_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('app', "tez_" + 
this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/app/configs.js 
b/tez-ui/src/main/webapp/app/routes/app/configs.js
new file mode 100644
index 0000000..bdd53ae
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/app/configs.js
@@ -0,0 +1,37 @@
+/**
+ * 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 SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "Application Details",
+
+  loaderNamespace: "app",
+
+  canPoll: false,
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('app', 
this.modelFor("app").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/app/dags.js 
b/tez-ui/src/main/webapp/app/routes/app/dags.js
new file mode 100644
index 0000000..8264299
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/app/dags.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "DAGs",
+
+  loaderNamespace: "app",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('dag', {
+      appID: this.modelFor("app").get("appID")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/app/index.js 
b/tez-ui/src/main/webapp/app/routes/app/index.js
new file mode 100644
index 0000000..7df42e5
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/app/index.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "Application Details",
+
+  loaderNamespace: "app",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  onRecordPoll: function () {
+    this.reload();
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('app', 
this.modelFor("app").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/application.js 
b/tez-ui/src/main/webapp/app/routes/application.js
new file mode 100644
index 0000000..5ae68b8
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/application.js
@@ -0,0 +1,84 @@
+/**
+ * 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.Route.extend({
+  title: "Application",
+
+  pageReset: function () {
+    this.send("resetTooltip");
+  },
+
+  actions: {
+    didTransition: function(/* transition */) {
+      this.pageReset();
+    },
+    bubbleBreadcrumbs: function (breadcrumbs) {
+      this.set("controller.breadcrumbs", breadcrumbs);
+    },
+
+    error: function (error) {
+      this.set("controller.appError", error);
+      Ember.Logger.error(error);
+    },
+
+    resetTooltip: function () {
+      Ember.$(document).tooltip("destroy");
+      Ember.$(document).tooltip({
+        delay: 20,
+        tooltipClass: 'generic-tooltip'
+      });
+    },
+
+    // Modal window actions
+    openModal: function (componentName, options) {
+      options = options || {};
+
+      if(typeof componentName === "object") {
+        options = componentName;
+        componentName = null;
+      }
+
+      this.render(options.modalName || "simple-modal", {
+        into: 'application',
+        outlet: 'modal',
+        model: {
+          title: options.title,
+          componentName: componentName,
+          content: options.content,
+          targetObject: options.targetObject
+        }
+      });
+      Ember.run.later(function () {
+        Ember.$(".simple-modal").modal();
+      });
+    },
+    closeModal: function () {
+      Ember.$(".simple-modal").modal("hide");
+    },
+    destroyModal: function () {
+      Ember.run.later(this, function () {
+        this.disconnectOutlet({
+          outlet: 'modal',
+          parentView: 'application'
+        });
+      });
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/attempt.js 
b/tez-ui/src/main/webapp/app/routes/attempt.js
new file mode 100644
index 0000000..3d0224f
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/attempt.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Attempt",
+
+  loaderQueryParams: {
+    id: "attempt_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('attempt', 
this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/attempt/counters.js 
b/tez-ui/src/main/webapp/app/routes/attempt/counters.js
new file mode 100644
index 0000000..add4ce5
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/attempt/counters.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.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "attempt",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('attempt', 
this.modelFor("attempt").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/attempt/index.js 
b/tez-ui/src/main/webapp/app/routes/attempt/index.js
new file mode 100644
index 0000000..add4ce5
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/attempt/index.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.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "attempt",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('attempt', 
this.modelFor("attempt").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag.js 
b/tez-ui/src/main/webapp/app/routes/dag.js
new file mode 100644
index 0000000..13f1bc0
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG",
+
+  loaderQueryParams: {
+    id: "dag_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('dag', 
this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/attempts.js 
b/tez-ui/src/main/webapp/app/routes/dag/attempts.js
new file mode 100644
index 0000000..167c10e
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/attempts.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "All Task Attempts",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('attempt', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/counters.js 
b/tez-ui/src/main/webapp/app/routes/dag/counters.js
new file mode 100644
index 0000000..be60c1d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/counters.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 SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('dag', 
this.modelFor("dag").get("id"), options);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/graphical.js 
b/tez-ui/src/main/webapp/app/routes/dag/graphical.js
new file mode 100644
index 0000000..69d2de4
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/graphical.js
@@ -0,0 +1,81 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "Graphical View",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  },
+
+  _loadedValueObserver: Ember.observer("loadedValue", function () {
+    var loadedValue = this.get("loadedValue"),
+        records = [];
+
+    if(loadedValue) {
+      loadedValue.forEach(function (record) {
+        records.push(record);
+      });
+
+      this.set("polledRecords", records);
+    }
+    Ember.run.later(this, "setViewHeight", 100);
+  }),
+
+  setViewHeight: function () {
+    var container = Ember.$('#graphical-view-component-container'),
+        offset;
+
+    if(container) {
+      offset = container.offset();
+      container.height(
+        Math.max(
+          // 50 pixel is left at the bottom
+          offset ? Ember.$(window).height() - offset.top - 70 : 0,
+          500 // Minimum dag view component container height
+        )
+      );
+    }
+  },
+
+  actions: {
+    didTransition: function () {
+      Ember.$(window).on('resize', this.setViewHeight);
+      this._super();
+      return true;
+    },
+    willTransition: function () {
+      Ember.$(window).off('resize', this.setViewHeight);
+      this._super();
+      return true;
+    },
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/index.js 
b/tez-ui/src/main/webapp/app/routes/dag/index.js
new file mode 100644
index 0000000..acabc58
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/index.js
@@ -0,0 +1,58 @@
+/**
+ * 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 SingleAmPollsterRoute from '../single-am-pollster';
+
+import downloadDAGZip from '../../utils/download-dag-zip';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('dag', 
this.modelFor("dag").get("id"), options);
+  },
+
+  actions: {
+    downloadDagJson: function () {
+      var dag = this.get("loadedValue"),
+          downloader = downloadDAGZip(dag, {
+            batchSize: 500,
+            timelineHost: this.get("hosts.timeline"),
+            timelineNamespace: 
this.get("env.app.namespaces.webService.timeline")
+          }),
+          modalContent = Ember.Object.create({
+            dag: dag,
+            downloader: downloader
+          });
+
+      this.send("openModal", "zip-download-modal", {
+        title: "Download data",
+        content: modalContent
+      });
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/index/index.js 
b/tez-ui/src/main/webapp/app/routes/dag/index/index.js
new file mode 100644
index 0000000..72d8686
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/index/index.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';
+import MultiAmPollsterRoute from '../../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  },
+
+  _canPollObserver: Ember.observer("canPoll", function () {
+    if(this.get("canPoll")) {
+      this.get("polling").setPoll(this.pollData, this, "dag.index.index");
+    }
+    else {
+      this.get("polling").resetPoll("dag.index.index");
+    }
+  }),
+
+  updateLoadTime: function (value) {
+    return value;
+  },
+
+  actions: {
+    reload: function () {
+      this._super();
+      return true;
+    },
+    willTransition: function () {
+      this.set("loadedValue", null);
+      return true;
+    },
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/swimlane.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/swimlane.js 
b/tez-ui/src/main/webapp/app/routes/dag/swimlane.js
new file mode 100644
index 0000000..c79b00c
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/swimlane.js
@@ -0,0 +1,51 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "Vertex Swimlane",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  },
+
+  _loadedValueObserver: Ember.observer("loadedValue", function () {
+    var loadedValue = this.get("loadedValue"),
+        records = [];
+
+    if(loadedValue) {
+      loadedValue.forEach(function (record) {
+        records.push(record);
+      });
+
+      this.set("polledRecords", records);
+    }
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/tasks.js 
b/tez-ui/src/main/webapp/app/routes/dag/tasks.js
new file mode 100644
index 0000000..744913d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/tasks.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "All Tasks",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('task', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dag/vertices.js 
b/tez-ui/src/main/webapp/app/routes/dag/vertices.js
new file mode 100644
index 0000000..0b7d63b
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dag/vertices.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "All Vertices",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/dags.js 
b/tez-ui/src/main/webapp/app/routes/dags.js
new file mode 100644
index 0000000..33366c8
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/dags.js
@@ -0,0 +1,167 @@
+/**
+ * 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 AbstractRoute from './abstract';
+
+const REFRESH = {refreshModel: true};
+
+export default AbstractRoute.extend({
+  title: "All DAGs",
+
+  queryParams: {
+    dagName: REFRESH,
+    dagID: REFRESH,
+    submitter: REFRESH,
+    status: REFRESH,
+    appID: REFRESH,
+    callerID: REFRESH,
+
+    rowCount: REFRESH
+  },
+
+  loaderQueryParams: {
+    dagName: "dagName",
+    dagID: "dagID",
+    user: "submitter",
+    status: "status",
+    appID: "appID",
+    callerID: "callerID",
+
+    limit: "rowCount",
+  },
+
+  loaderNamespace: "dags",
+
+  fromId: null,
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  // Client side filtering to ensure that records are relevant after status 
correction
+  filterRecords: function (records, query) {
+    query = {
+      name: query.dagName,
+      entityID: query.dagID,
+      submitter: query.submitter,
+      status: query.status,
+      appID: query.appID,
+      callerID: query.callerID
+    };
+
+    return records.filter(function (record) {
+      for(var propName in query) {
+        if(query[propName] && query[propName] !== record.get(propName)) {
+          return false;
+        }
+      }
+      return true;
+    });
+  },
+
+  load: function (value, query/*, options*/) {
+    var loader,
+        that = this,
+        limit = this.get("controller.rowCount") || query.limit;
+
+    if(query.dagID) {
+      that.set("loadedRecords", []);
+      loader = this.get("loader").queryRecord('dag', query.dagID, {reload: 
true}).then(function (record) {
+        return [record];
+      });
+    }
+    else {
+      query = Ember.$.extend({}, query, {
+        limit: limit + 1
+      });
+      loader = this.get("loader").query('dag', query, {reload: true});
+    }
+
+    return loader.then(function (records) {
+
+      if(records.get("length") > limit) {
+        let lastRecord = records.popObject();
+        that.set("controller.moreAvailable", true);
+        that.set("fromId", lastRecord.get("entityID"));
+      }
+      else {
+        that.set("controller.moreAvailable", false);
+      }
+
+      records = that.filterRecords(records, query);
+      records.forEach(function (record) {
+        if(record.get("status") === "RUNNING") {
+          that.get("loader").loadNeed(record, "am", {reload: 
true}).catch(function () {
+            record.set("am", null);
+          });
+        }
+      });
+      return records;
+    });
+  },
+
+  loadNewPage: function () {
+    var query = this.get("currentQuery"),
+        that = this;
+
+    query = Ember.$.extend({}, query, {
+      fromId: this.get("fromId")
+    });
+
+    this.set("controller.loadingMore", true);
+    return this.load(null, query).then(function (data) {
+      if(that.get("controller.loadingMore")) {
+        that.set("controller.loadingMore", false);
+        that.get("loadedValue").pushObjects(data);
+        return data;
+      }
+    });
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    },
+    loadPage: function (page) {
+      var that = this;
+      if(this.get("controller.moreAvailable") && 
!this.get("controller.loadingMore")) {
+        this.send("resetTooltip");
+        this.loadNewPage().then(function (data) {
+          if(data) {
+            that.set("controller.pageNum", page);
+          }
+          return data;
+        });
+      }
+    },
+    reload: function () {
+      this.set("controller.loadingMore", false);
+      this.set("controller.pageNum", 1);
+      this._super();
+    },
+    willTransition: function () {
+      var loader = this.get("loader");
+      loader.unloadAll("dag");
+      loader.unloadAll("ahs-app");
+      this._super();
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/multi-am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/multi-am-pollster.js 
b/tez-ui/src/main/webapp/app/routes/multi-am-pollster.js
new file mode 100644
index 0000000..c3260a6
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/multi-am-pollster.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.
+ */
+
+import Ember from 'ember';
+import AmPollsterRoute from './am-pollster';
+
+export default AmPollsterRoute.extend({
+
+  canPoll: Ember.computed("polledRecords.0.app.isComplete", "loadedValue", 
function () {
+    var isComplete = this.get("polledRecords.0.app.isComplete");
+    return isComplete === false && this._super();
+  }),
+
+  actions: {
+    setPollingRecords: function (records) {
+      this.set("polledRecords", records);
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/pollster.js 
b/tez-ui/src/main/webapp/app/routes/pollster.js
new file mode 100644
index 0000000..9e1e40d
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/pollster.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  polling: Ember.inject.service("pollster"),
+
+  // Todo - Change name to recordsToPoll
+  polledRecords: null,
+
+  // Must be implemented by inheriting classes
+  onRecordPoll: function (val) {return val;},
+  onPollSuccess: function (val) {return val;},
+  onPollFailure: function (err) {throw(err);},
+
+  pollData: function () {
+    var polledRecords = this.get("polledRecords");
+
+    if(!this.get("isLoading") && polledRecords) {
+      polledRecords = polledRecords.map(this.onRecordPoll.bind(this));
+      return Ember.RSVP.all(polledRecords).
+      then(this.updateLoadTime.bind(this)).
+      then(this.onPollSuccess.bind(this), this.onPollFailure.bind(this));
+    }
+    return Ember.RSVP.reject();
+  },
+
+  canPoll: Ember.computed("polledRecords", "loadedValue", function () {
+    return this.get("polledRecords") && this.get("loadedValue");
+  }),
+
+  updateLoadTime: function (value) {
+    this.send("setLoadTime", this.getLoadTime(value));
+    return value;
+  },
+
+  _canPollInit: Ember.on("init", function () {
+    // This sets a flag that ensures that the _canPollObserver is called 
whenever
+    // canPoll changes. By default observers on un-used computed properties
+    // are not called.
+    this.get("canPoll");
+  }),
+
+  _canPollObserver: Ember.observer("canPoll", function () {
+    if(this.get("canPoll")) {
+      this.get("polling").setPoll(this.pollData, this);
+    }
+    else {
+      this.get("polling").resetPoll();
+    }
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/single-am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/single-am-pollster.js 
b/tez-ui/src/main/webapp/app/routes/single-am-pollster.js
new file mode 100644
index 0000000..4a0d507
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/single-am-pollster.js
@@ -0,0 +1,34 @@
+/**
+ * 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 AmPollsterRoute from './am-pollster';
+
+export default AmPollsterRoute.extend({
+
+  canPoll: Ember.computed("polledRecords", "loadedValue.app.isComplete", 
function () {
+    var isComplete = this.get("loadedValue.app.isComplete");
+    return isComplete === false && this._super();
+  }),
+
+  _loadedValueObserver: Ember.observer("loadedValue", function () {
+    var loadedValue = this.get("loadedValue");
+    this.set("polledRecords", loadedValue ? [this.get("loadedValue")] : null);
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/task.js 
b/tez-ui/src/main/webapp/app/routes/task.js
new file mode 100644
index 0000000..54d29f1
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/task.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Task",
+
+  loaderQueryParams: {
+    id: "task_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('task', 
this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/task/attempts.js 
b/tez-ui/src/main/webapp/app/routes/task/attempts.js
new file mode 100644
index 0000000..536d085
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/task/attempts.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "Task Attempts",
+
+  loaderNamespace: "task",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('attempt', {
+      taskID: this.modelFor("task").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/task/counters.js 
b/tez-ui/src/main/webapp/app/routes/task/counters.js
new file mode 100644
index 0000000..086e0cc
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/task/counters.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.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "task",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('task', 
this.modelFor("task").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/task/index.js 
b/tez-ui/src/main/webapp/app/routes/task/index.js
new file mode 100644
index 0000000..f012796
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/task/index.js
@@ -0,0 +1,47 @@
+/**
+ * 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 SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "task",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  loadAttempts: function (taskID, options) {
+    var that = this;
+
+    this.get("loader").query('attempt', {
+      taskID: taskID
+    }, options).then(function (attempts) {
+      that.set("controller.attempts", attempts);
+    });
+  },
+
+  load: function (value, query, options) {
+    var taskID = this.modelFor("task").get("id");
+    this.loadAttempts(taskID, options);
+    return this.get("loader").queryRecord('task', taskID, options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/vertex.js 
b/tez-ui/src/main/webapp/app/routes/vertex.js
new file mode 100644
index 0000000..6e99fd1
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/vertex.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "vertex_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('vertex', 
this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/vertex/attempts.js 
b/tez-ui/src/main/webapp/app/routes/vertex/attempts.js
new file mode 100644
index 0000000..b0b33b2
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/vertex/attempts.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "Task Attempts",
+
+  loaderNamespace: "vertex",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('attempt', {
+      vertexID: this.modelFor("vertex").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/vertex/counters.js 
b/tez-ui/src/main/webapp/app/routes/vertex/counters.js
new file mode 100644
index 0000000..d7cae37
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/vertex/counters.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.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "vertex",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('vertex', 
this.modelFor("vertex").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/vertex/index.js 
b/tez-ui/src/main/webapp/app/routes/vertex/index.js
new file mode 100644
index 0000000..d7cae37
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/vertex/index.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.
+ */
+
+import Ember from 'ember';
+import SingleAmPollsterRoute from '../single-am-pollster';
+
+export default SingleAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "vertex",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('vertex', 
this.modelFor("vertex").get("id"), options);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/routes/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/routes/vertex/tasks.js 
b/tez-ui/src/main/webapp/app/routes/vertex/tasks.js
new file mode 100644
index 0000000..25e0f4b
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/routes/vertex/tasks.js
@@ -0,0 +1,37 @@
+/**
+ * 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 MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "All Tasks",
+
+  loaderNamespace: "vertex",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('task', {
+      vertexID: this.modelFor("vertex").get("id")
+    }, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/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
deleted file mode 100644
index 22b4151..0000000
--- a/tez-ui/src/main/webapp/app/scripts/app.js
+++ /dev/null
@@ -1,309 +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.
- */
-
-Ember.FEATURES.I18N_TRANSLATE_HELPER_SPAN = false;
-Ember.ENV.I18N_COMPILE_WITHOUT_HANDLEBARS = true;
-
-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,
-
-  env: {
-    isStandalone: true, // Can ne set false in the wrapper initializer
-    isIE: navigator.userAgent.indexOf('MSIE') !== -1 || 
navigator.appVersion.indexOf('Trident/') > 0
-  },
-
-  setConfigs: function (configs) {
-    if(configs.envDefaults.version == "${version}") {
-      delete configs.envDefaults.version;
-    }
-    App.Helpers.misc.merge(App.Configs, configs);
-    $.extend(App.env, {
-      timelineBaseUrl: App.Helpers.misc.normalizePath(App.env.timelineBaseUrl),
-      RMWebUrl: App.Helpers.misc.normalizePath(App.env.RMWebUrl)
-    });
-    App.advanceReadiness();
-  }
-});
-
-Em.Application.initializer({
-  name: "objectTransforms",
-
-  initialize: function(container, application) {
-    application.register('transform:object', DS.Transform.extend({
-      deserialize: function(serialized) {
-        return Em.none(serialized) ? {} : serialized;
-      },
-
-      serialized: function(deserialized) {
-        return Em.none(deserialized) ? {} : deserialized;
-      }
-    }));
-  }
-});
-
-App.deferReadiness();
-
-App.Helpers = Em.Namespace.create(),
-App.Mappers = Em.Namespace.create(),
-App.Configs = Em.Namespace.create();
-
-App.ready = function () {
-  $.extend(App.env, App.Configs.envDefaults);
-
-  $(document).tooltip({
-    delay: 20,
-    tooltipClass: 'generic-tooltip'
-  });
-
-  ["timelineBaseUrl", "RMWebUrl"].forEach(function(item) {
-    if (!!App.env[item]) {
-      App.env[item] = App.Helpers.misc.normalizePath(App.env[item]);
-    }
-  })
-
-  App.ApplicationAdapter = App.TimelineRESTAdapter.extend({
-    host: App.env.timelineBaseUrl
-  });
-  App.ApplicationSerializer = App.TimelineSerializer.extend();
-
-  App.AppDetailAdapter = DS.RESTAdapter.extend({
-    ajax: function(url, method, hash) {
-      hash = hash || {}; // hash may be undefined
-      hash.crossDomain = true;
-      hash.xhrFields = {withCredentials: true};
-      hash.targetServer = "Timeline Server";
-      return this._super(url, method, hash);
-    },
-    namespace: App.Configs.restNamespace.applicationHistory,
-    host: App.env.timelineBaseUrl,
-    pathForType: function() {
-      return "apps";
-    },
-  });
-
-  App.DagVertexAdapter =
-  App.VertexAdapter = App.ApplicationAdapter.extend({
-    _setInputs: function (store, data) {
-      var dagId = Ember.get(data, 'primaryfilters.TEZ_DAG_ID.0'),
-          vertexName = Ember.get(data, 'otherinfo.vertexName');
-      if(dagId) {
-        return store.find('dag', dagId).then(function (dag) {
-          if(dag.get('vertices') instanceof Array) {
-            var vertexData = dag.get('vertices').findBy('vertexName', 
vertexName);
-            if(vertexData && vertexData.additionalInputs) {
-              data.inputs = vertexData.additionalInputs;
-            }
-            if(vertexData && vertexData.additionalOutputs) {
-              data.outputs = vertexData.additionalOutputs;
-            }
-          }
-          return data;
-        });
-      }
-      else {
-        return Em.RSVP.Promise(data);
-      }
-    },
-    find: function(store, type, id) {
-      var that = this;
-      return this._super(store, type, id).then(function (data) {
-        return that._setInputs(store, data);
-      });
-    },
-    findQuery: function(store, type, queryObj, records) {
-      var that = this;
-      return that._super(store, type, queryObj, records ).then(function (data) 
{
-        var fetchers = [];
-        data.entities.forEach(function (datum) {
-          fetchers.push(that._setInputs(store, datum));
-        });
-        return Em.RSVP.allSettled(fetchers).then(function () {
-          return data;
-        });
-      });
-    }
-  });
-
-  App.AMInfoAdapter = DS.RESTAdapter.extend({
-    ajax: function(url, method, hash) {
-      hash = hash || {}; // hash may be undefined
-      if (hash && hash.data && hash.data.__app_id__) {
-        url = url.replace('__app_id__', hash.data.__app_id__);
-        delete hash.data['__app_id__'];
-      }
-      hash.crossDomain = true;
-      hash.xhrFields = {withCredentials: true};
-      hash.targetServer = "Resource Manager";
-      return this._super(url, method, hash);
-    },
-    host: App.env.RMWebUrl,
-    namespace: App.Configs.restNamespace.aminfo,
-  });
-
-  App.DagProgressAdapter = App.AMInfoAdapter.extend({
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appId'))
-        .fmt(record.get('dagIdx'));
-    },
-    pathForType: function() {
-      return 'dagProgress?dagID=%@';
-    }
-  });
-
-  App.VertexProgressAdapter = App.AMInfoAdapter.extend({
-    findQuery: function(store, type, query) {
-      var record = query.metadata;
-      delete query.metadata;
-      return this.ajax(
-        this.buildURL(Ember.String.pluralize(type.typeKey),
-          record.vertexIds, Em.Object.create(record)), 'GET', { data: query});
-    },
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appId'))
-        .fmt(record.get('dagIdx'), id);
-    },
-    pathForType: function(typeName) {
-      return typeName + '?dagID=%@&vertexID=%@';
-    }
-  });
-
-  // v2 version of am web services
-  App.DagInfoAdapter = App.AMInfoAdapter.extend({
-    namespace: App.Configs.restNamespace.aminfoV2,
-    findQuery: function(store, type, query) {
-      var record = query.metadata;
-      delete query.metadata;
-      return this.ajax(
-        this.buildURL(Ember.String.pluralize(type.typeKey),
-          record.dagID, Em.Object.create(record)), 'GET', { data: query});
-    },
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appID'))
-        .fmt(id, record.get('counters'));
-    },
-    pathForType: function(typeName) {
-      return 'dagInfo?dagID=%@&counters=%@';
-    }
-  });
-
-
-  App.VertexInfoAdapter = App.AMInfoAdapter.extend({
-    namespace: App.Configs.restNamespace.aminfoV2,
-    findQuery: function(store, type, query) {
-      var record = query.metadata;
-      delete query.metadata;
-      return this.ajax(
-        this.buildURL(Ember.String.pluralize(type.typeKey),
-          record.vertexID, Em.Object.create(record)), 'GET', { data: query});
-    },
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appID'))
-        .fmt(record.get('dagID'), id, record.get('counters'));
-    },
-    pathForType: function(typeName) {
-      return 'verticesInfo?dagID=%@&vertexID=%@&counters=%@';
-    }
-  });
-
-  App.TaskInfoAdapter = App.AMInfoAdapter.extend({
-    namespace: App.Configs.restNamespace.aminfoV2,
-    findQuery: function(store, type, query) {
-      var record = query.metadata;
-      delete query.metadata;
-      return this.ajax(
-        this.buildURL(Ember.String.pluralize(type.typeKey),
-          record.taskID, Em.Object.create(record)), 'GET', { data: query});
-    },
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appID'))
-        .fmt(record.get('dagID'), id, record.get('counters'));
-    },
-    pathForType: function(typeName) {
-      return 'tasksInfo?dagID=%@&taskID=%@&counters=%@';
-    }
-  });
-
-  App.AttemptInfoAdapter = App.AMInfoAdapter.extend({
-    namespace: App.Configs.restNamespace.aminfoV2,
-    findQuery: function(store, type, query) {
-      var record = query.metadata;
-      delete query.metadata;
-      return this.ajax(
-        this.buildURL(Ember.String.pluralize(type.typeKey),
-          record.attemptID, Em.Object.create(record)), 'GET', { data: query});
-    },
-    buildURL: function(type, id, record) {
-      var url = this._super(type, undefined, record);
-      return url.replace('__app_id__', record.get('appID'))
-        .fmt(record.get('dagID'), record.get('taskID'), id, 
record.get('counters'));
-    },
-    pathForType: function(typeName) {
-      return 'attemptsInfo?dagID=%@&taskID=%@&attemptID=%@&counters=%@';
-    }
-  });
-
-  App.ClusterAppAdapter = DS.RESTAdapter.extend({
-    host: App.env.RMWebUrl,
-    namespace: App.Configs.restNamespace.cluster,
-    pathForType: function() {
-      return 'apps';
-    }
-  });
-
-};
-
-$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
-  jqXHR.requestOptions = originalOptions;
-});
-
-$.ajaxSetup({
-  cache: false
-});
-
-/* Order and include */
-require('scripts/default-configs');
-
-require('scripts/translations');
-require('scripts/helpers/pollster');
-require('scripts/helpers/*');
-require('scripts/mixins/*');
-
-require('scripts/router');
-require('scripts/views/**/*');
-require('scripts/models/**/*');
-
-require('scripts/controllers/base-controller');
-require('scripts/controllers/polling-controller');
-require('scripts/controllers/table-page-controller');
-require('scripts/controllers/**/*');
-
-require('scripts/components/basic-table/basic-table-component');
-require('scripts/components/**/*');
-require('scripts/adapters/*');

Reply via email to