http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml
new file mode 100644
index 0000000..8ba1f6d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml
@@ -0,0 +1,213 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <parent>
+    <artifactId>hadoop-yarn</artifactId>
+    <groupId>org.apache.hadoop</groupId>
+    <version>3.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.hadoop</groupId>
+  <artifactId>hadoop-yarn-ui</artifactId>
+  <version>3.0.0-SNAPSHOT</version>
+  <name>Apache Hadoop YARN UI</name>
+  <packaging>${packaging.type}</packaging>
+
+  <properties>
+    <packaging.type>jar</packaging.type>
+    <webappDir>src/main/webapp</webappDir>
+    <node.executable>node</node.executable>
+    <nodeVersion>v0.12.2</nodeVersion>
+    <npmVersion>2.10.0</npmVersion>
+    <skipTests>false</skipTests>
+  </properties>
+
+  <build>
+    <plugins>
+      <!-- Apache RAT -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>src/main/webapp/node_modules/**/*</exclude>
+            <exclude>src/main/webapp/bower_components/**/*</exclude>
+            <exclude>src/main/webapp/jsconfig.json</exclude>
+            <exclude>src/main/webapp/bower.json</exclude>
+            <exclude>src/main/webapp/package.json</exclude>
+            <exclude>src/main/webapp/testem.json</exclude>
+            <exclude>src/main/webapp/public/assets/images/**/*</exclude>
+            <exclude>src/main/webapp/public/robots.txt</exclude>
+            <exclude>public/crossdomain.xml</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <plugin>
+         <artifactId>maven-clean-plugin</artifactId>
+         <version>3.0.0</version>
+         <configuration>
+            <followSymLinks>false</followSymLinks>
+            <filesets>
+               <fileset>
+                  
<directory>${basedir}/src/main/webapp/bower_components</directory>
+               </fileset>
+               <fileset>
+                  
<directory>${basedir}/src/main/webapp/node_modules</directory>
+               </fileset>
+            </filesets>
+         </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>yarn-ui</id>
+
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+
+      <properties>
+        <packaging.type>war</packaging.type>
+      </properties>
+
+      <build>
+        <plugins>
+          <!-- Bower install & grunt build-->
+          <plugin>
+            <artifactId>exec-maven-plugin</artifactId>
+            <groupId>org.codehaus.mojo</groupId>
+            <executions>
+              <execution>
+                <phase>generate-sources</phase>
+                <id>npm install</id>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>npm</executable>
+                  <arguments>
+                    <argument>install</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <phase>generate-sources</phase>
+                <id>bower install</id>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>bower</executable>
+                  <arguments>
+                    <argument>--allow-root</argument>
+                    <argument>install</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <phase>generate-sources</phase>
+                <id>bower --allow-root install</id>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>bower</executable>
+                  <arguments>
+                    <argument>--allow-root</argument>
+                    <argument>install</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <id>ember build</id>
+                <phase>generate-sources</phase>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>ember</executable>
+                  <arguments>
+                    <argument>build</argument>
+                    <argument>-prod</argument>
+                    <argument>--output-path</argument>
+                    <argument>${basedir}/target/dist</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <id>ember test</id>
+                <phase>generate-resources</phase>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <skip>${skipTests}</skip>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>ember</executable>
+                  <arguments>
+                    <argument>test</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+              <execution>
+                <id>cleanup tmp</id>
+                <phase>generate-sources</phase>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <workingDirectory>${webappDir}</workingDirectory>
+                  <executable>rm</executable>
+                  <arguments>
+                    <argument>-rf</argument>
+                    <argument>tmp</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+
+          <!-- Package into war -->
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <configuration>
+              <webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
+              <warSourceDirectory>${basedir}/target/dist</warSourceDirectory>
+              <webResources>
+                <resource>
+                  <filtering>false</filtering>
+                  <directory>${basedir}/src/main/resources/</directory>
+                </resource>
+              </webResources>
+            </configuration>
+          </plugin>
+
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/robots.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/robots.txt 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/robots.txt
deleted file mode 100644
index f591645..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# http://www.robotstxt.org
-User-agent: *
-Disallow:

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ddb8532
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd"; >
+
+<web-app>
+  <display-name>YARN UI</display-name>
+</web-app>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js
new file mode 100644
index 0000000..7dcbe61
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.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 DS from 'ember-data';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT, // 
configurable
+  namespace: 'ws/v1/cluster', // common const
+  pathForType(modelName) {
+    return ''; // move to some common place, return path by modelname.
+  },
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js
new file mode 100644
index 0000000..ad5ae0e
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.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 DS from 'ember-data';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT, // 
configurable
+  namespace: 'ws/v1/cluster/metrics', // common const
+  pathForType(modelName) {
+    return ''; // move to some common place, return path by modelname.
+  },
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
new file mode 100644
index 0000000..7b233bc
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
@@ -0,0 +1,50 @@
+/**
+ * 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';
+import Converter from 'yarn-ui/utils/converter';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT, // 
configurable
+  namespace: 'ws/v1/cluster', // common const
+
+  urlForQuery(query, modelName) {
+    var url = this._buildURL();
+    return url + '/apps/' + query.appId + "/appattempts";
+  },
+
+  urlForFindRecord(id, modelName, snapshot) {
+    var url = this._buildURL();
+    var url = url + '/apps/' + 
+           Converter.attemptIdToAppId(id) + "/appattempts/" + id;
+    console.log(url);
+    return url;
+  },
+
+  ajax(url, method, hash) {
+    hash = {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
new file mode 100644
index 0000000..5cd888c
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
@@ -0,0 +1,44 @@
+/**
+ * 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';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT, // 
configurable
+  namespace: 'ws/v1/cluster', // common const
+  pathForType(modelName) {
+    return 'apps'; // move to some common place, return path by modelname.
+  },
+  /*
+  urlForQuery(query, modelName) {
+    var url = this._buildURL();
+    return url + '/apps/' + query.appId + "/appattempts";
+  },
+  */
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
new file mode 100644
index 0000000..7838c98
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
@@ -0,0 +1,74 @@
+/**
+ * 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';
+import Ember from 'ember';
+import Converter from 'yarn-ui/utils/converter';
+
+/**
+ * REST URL's response when fetching container logs will be
+ * in plain text format and not JSON.
+ */
+export default DS.RESTAdapter.extend({
+  headers: {
+    Accept: 'text/plain'
+  },
+  host: 'http://localhost:1337/',
+  namespace: 'ws/v1/node',
+
+  urlForFindRecord(id, modelName, snapshot) {
+    var splits = Converter.splitForContainerLogs(id);
+    var nodeHttpAddr = splits[0];
+    var containerId = splits[1];
+    var filename = splits[2];
+    this.host = this.host + nodeHttpAddr;
+    var url = this._buildURL();
+    url = url + "/containerlogs/" + containerId + "/" + filename;
+    return url;
+  },
+
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "NM";
+    return this._super(url, method, hash);
+  },
+
+  /**
+   * Override options so that result is not expected to be JSON
+   */
+  ajaxOptions: function (url, type, options) {
+    var hash = options || {};
+    hash.url = url;
+    hash.type = type;
+    // Make sure jQuery does not try to convert response to JSON.
+    hash.dataType = 'text';
+    hash.context = this;
+
+    var headers = Ember.get(this, 'headers');
+    if (headers != undefined) {
+      hash.beforeSend = function (xhr) {
+        Object.keys(headers).forEach(function (key) {
+          return xhr.setRequestHeader(key, headers[key]);
+        });
+      };
+    }
+    return hash;
+  },
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
new file mode 100644
index 0000000..67a37f7
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  rmHost: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT,
+  tsHost: 'http://localhost:1337/' + Config.TS_HOST + ':' + Config.TS_PORT,
+  host: function() {
+    return undefined
+  }.property(),
+  rmNamespace: 'ws/v1/cluster',
+  tsNamespace: 'ws/v1/applicationhistory',
+  namespace: function() {
+    return undefined
+  }.property(),
+
+  urlForQuery(query, modelName) {
+    if (query.is_rm) {
+      this.set("host", this.rmHost);
+      this.set("namespace", this.rmNamespace);
+    } else {
+      this.set("host", this.tsHost);
+      this.set("namespace", this.tsNamespace);
+    }
+
+    var url = this._buildURL();
+    url = url + '/apps/' + Converter.attemptIdToAppId(query.app_attempt_id) 
+               + "/appattempts/" + query.app_attempt_id + "/containers";
+    console.log(url);
+    return url;
+  },
+
+  ajax(url, method, hash) {
+    hash = {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
new file mode 100644
index 0000000..0c60d1f
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
@@ -0,0 +1,63 @@
+/**
+ * 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';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/',
+  namespace: 'ws/v1/node',
+
+  urlForQuery(query) {
+    this.host = this.host + query.nodeAddr;
+    var url = this._buildURL();
+    url = url + "/apps";
+    return url;
+  },
+
+  urlForQueryRecord: function (query) {
+    this.host = this.host + query.nodeAddr;
+    var url = this._buildURL();
+    url = url + "/apps/" + query.appId;
+    return url;
+  },
+
+  query: function (store, type, query) {
+    var url = this.urlForQuery(query);
+    // Query params not required.
+    query = null;
+    return this.ajax(url, 'GET', { data: query });
+  },
+
+  queryRecord: function (store, type, query) {
+    var url = this.urlForQueryRecord(query);
+    // Query params not required.
+    query = null;
+    return this.ajax(url, 'GET', { data: query });
+  },
+
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "NM";
+    return this._super(url, method, hash);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
new file mode 100644
index 0000000..e8bf7b7
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
@@ -0,0 +1,64 @@
+/**
+ * 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';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/',
+  namespace: 'ws/v1/node',
+
+  urlForQuery(query) {
+    this.host = this.host + query.nodeHttpAddr;
+    var url = this._buildURL();
+    url = url + "/containers";
+    return url;
+  },
+
+  urlForQueryRecord(query) {
+    this.host = this.host + query.nodeHttpAddr;
+    var url = this._buildURL();
+    url = url + "/containers/" + query.containerId;
+    return url;
+  },
+
+  query: function (store, type, query) {
+    var url = this.urlForQuery(query);
+    // Query params not required.
+    query = null;
+    return this.ajax(url, 'GET', { data: query });
+  },
+
+  queryRecord: function (store, type, query) {
+    var url = this.urlForQueryRecord(query);
+    // Query params not required.
+    query = null;
+    console.log(url);
+    return this.ajax(url, 'GET', { data: query });
+  },
+
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "NM";
+    return this._super(url, method, hash);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
new file mode 100644
index 0000000..64f524a
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/',
+  namespace: 'ws/v1/node',
+
+  urlForFindRecord(id, modelName, snapshot) {
+    this.host = this.host + id;
+    var url = this._buildURL();
+    return url;
+  },
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "NM";
+    return this._super(url, method, hash);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js
new file mode 100644
index 0000000..ebe7b39
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.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 DS from 'ember-data';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT, // 
configurable
+  namespace: 'ws/v1/cluster', // common const
+  pathForType(modelName) {
+    return 'scheduler'; // move to some common place, return path by modelname.
+  },
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash); 
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js
new file mode 100644
index 0000000..c6ad6f3
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.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 DS from 'ember-data';
+import Config from 'yarn-ui/config';
+
+export default DS.JSONAPIAdapter.extend({
+  headers: {
+    Accept: 'application/json'
+  },
+  host: 'http://localhost:1337/' + Config.RM_HOST + ':' + Config.RM_PORT,
+  namespace: 'ws/v1/cluster',
+  pathForType(modelName) {
+    return 'nodes';
+  },
+
+  urlForFindRecord(id, modelName, snapshot) {
+    var url = this._buildURL();
+    url = url + "/nodes/" + id;
+    return url;
+  },
+
+  ajax(url, method, hash) {
+    hash = hash || {};
+    hash.crossDomain = true;
+    hash.xhrFields = {withCredentials: true};
+    hash.targetServer = "RM";
+    return this._super(url, method, hash);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js
new file mode 100644
index 0000000..5617953
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/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 Ember from 'ember';
+import Resolver from 'ember/resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+import Sorter from 'yarn-ui/utils/sorter';
+
+var App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix,
+  Resolver: Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+Sorter.initDataTableSorter();
+
+export default App;

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.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 Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.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 Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
new file mode 100644
index 0000000..8e48279
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
@@ -0,0 +1,122 @@
+/**
+ * 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 BaseChartComponent from 'yarn-ui/components/base-chart-component';
+
+export default BaseChartComponent.extend({
+  // data: 
+  //    [{label=label1, value=value1}, ...]
+  //    ...
+  renderBarChart: function(data, title, textWidth = 50) {
+    var g = this.chart.g;
+    var layout = this.getLayout();
+    this.renderTitleAndBG(g, title, layout);
+
+    var maxValue = -1;
+    for (var i = 0; i < data.length; i++) {
+      if (data[i] instanceof Array) {
+        if (data[i][0].value > maxValue) {
+          maxValue = data[i][0].value;
+        }
+      } else {
+        if (data[i].value > maxValue) {
+          maxValue = data[i].value;
+        }
+      }
+    }
+
+    var singleBarHeight = 30;
+
+    // 50 is for text
+    var maxBarWidth = layout.x2 - layout.x1 - 2 * layout.margin - textWidth - 
50;
+
+    // 30 is for title
+    var maxBarsHeight = layout.y2 - layout.y1 - 2 * layout.margin - 30;
+    var gap = (maxBarsHeight - data.length * singleBarHeight) / (data.length -
+      1);
+
+    var xScaler = d3.scale.linear()
+      .domain([0, maxValue])
+      .range([0, maxBarWidth]);
+
+    // show bar text
+    for (var i = 0; i < data.length; i++) {
+      g.append("text")
+        .text(
+          function() {
+            return data[i].label;
+          })
+        .attr("y", function() {
+          return layout.y1 + singleBarHeight / 2 + layout.margin + (gap +
+            singleBarHeight) * i + 30;
+        })
+        .attr("x", layout.x1 + layout.margin);
+    }
+
+    // show bar
+    var bar = g.selectAll("bars")
+      .data(data)
+      .enter()
+      .append("rect")
+      .attr("y", function(d, i) {
+        return layout.y1 + 30 + layout.margin + (gap + singleBarHeight) * i;
+      })
+      .attr("x", layout.x1 + layout.margin + textWidth)
+      .attr("height", singleBarHeight)
+      .attr("fill", function(d, i) {
+        return this.colors[i];
+      }.bind(this))
+      .attr("width", 0);
+
+    this.bindTooltip(bar);
+
+    bar.transition()
+      .duration(500)
+      .attr("width", function(d) {
+        var w;
+        w = xScaler(d.value);
+        // At least each item has 3 px
+        w = Math.max(w, 3);
+        return w;
+      });
+
+    // show bar value
+    for (var i = 0; i < data.length; i++) {
+      g.append("text")
+        .text(
+          function() {
+            return data[i].value;
+          })
+        .attr("y", function() {
+          return layout.y1 + singleBarHeight / 2 + layout.margin + (gap +
+            singleBarHeight) * i + 30;
+        })
+        .attr("x", layout.x1 + layout.margin + textWidth + 15 + 
xScaler(data[i].value));
+    }
+  },
+
+  draw: function() {
+    this.initChart();
+    this.renderBarChart(this.get("data"), this.get("title"), 
this.get("textWidth"));
+  },
+
+  didInsertElement: function() {
+    this.draw();
+  },
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
new file mode 100644
index 0000000..b85b6ab
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
@@ -0,0 +1,127 @@
+/**
+ * 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({
+  chart: undefined,
+  tooltip : undefined,
+  colors: d3.scale.category10().range(),
+
+  initChart: function() {
+    this.chart = {
+      svg: undefined,
+      g: undefined,
+      h: 0,
+      w: 0,
+      tooltip: undefined
+    };
+
+    // Init tooltip if it is not initialized
+    this.tooltip = d3.select("#chart-tooltip");
+    if (!this.tooltip) {
+      this.tooltip = d3.select("body")
+        .append("div")
+        .attr("class", "tooltip")
+        .attr("id", "chart-tooltip")
+        .style("opacity", 0);
+    }
+
+    // Init svg
+    var svg = this.chart.svg;
+    if (svg) {
+      svg.remove();
+    }
+
+    var parentId = this.get("parentId");
+    var parent = d3.select("#" + parentId);
+    var bbox = parent.node().getBoundingClientRect();
+    this.chart.w = bbox.width - 30;
+
+    var ratio = 0.75; // 4:3 by default
+    if (this.get("ratio")) {
+      ratio = this.get("ratio");
+    }
+    this.chart.h = bbox.width * ratio;
+
+    if (this.get("maxHeight")) {
+      this.chart.h = Math.min(this.get("maxHeight"), this.chart.h);
+    }
+
+    this.chart.svg = parent.append("svg")
+      .attr("width", this.chart.w)
+      .attr("height", this.chart.h);
+
+    this.chart.g = this.chart.svg.append("g");
+  },
+
+  renderTitleAndBG: function(g, title, layout) {
+    var bg = g.append("g");
+    bg.append("text")
+      .text(title)
+      .attr("x", (layout.x1 + layout.x2) / 2)
+      .attr("y", layout.y1 + layout.margin + 20)
+      .attr("class", "chart-title");
+
+    bg.append("rect")
+      .attr("x", layout.x1)
+      .attr("y", layout.y1)
+      .attr("width", layout.x2 - layout.x1)
+      .attr("height", layout.y2 - layout.y1)
+      .attr("class", "chart-frame");
+  },
+
+  bindTooltip: function(d) {
+    d.on("mouseover", function(d) {
+        this.tooltip
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mousemove", function(d) {
+        // Handle pie chart case
+        var data = d;
+        if (d.data) {
+          data = d.data;
+        }
+
+        this.tooltip.style("opacity", .9);
+        this.tooltip.html(data.label + " = " + data.value)
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mouseout", function(d) {
+        this.tooltip.style("opacity", 0);
+      }.bind(this));
+  },
+
+  getLayout: function() {
+    var x1 = 0;
+    var y1 = 0;
+    var x2 = this.chart.w;
+    var y2 = this.chart.h;
+
+    var layout = {
+      x1: x1,
+      y1: y1,
+      x2: x2 - 10,
+      y2: y2 - 10,
+      margin: 10
+    };
+    return layout;
+  },
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.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 Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
new file mode 100644
index 0000000..e6dcb12
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
@@ -0,0 +1,166 @@
+/**
+ * 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 BaseChartComponent from 'yarn-ui/components/base-chart-component';
+
+export default BaseChartComponent.extend({
+  /*
+   * data = [{label="xx", value=},{...}]
+   */
+  renderDonutChart: function(data, title, showLabels = false, 
+    middleLabel = "Total", middleValue = undefined) {
+    var g = this.chart.g;
+    var layout = this.getLayout();
+    this.renderTitleAndBG(g, title, layout);
+
+    var total = 0;
+    var allZero = true;
+    for (var i = 0; i < data.length; i++) {
+      total += data[i].value;
+      if (data[i].value > 1e-6) {
+        allZero = false;
+      }
+    }
+
+    if (!middleValue) {
+      middleValue = total;
+    }
+
+    //Width and height
+    var h = layout.y2 - layout.y1;
+
+    // 50 is for title
+    var outerRadius = (h - 50 - 2 * layout.margin) / 2;
+    var innerRadius = outerRadius * 0.618;
+    var arc = d3.svg.arc()
+      .innerRadius(innerRadius)
+      .outerRadius(outerRadius);
+
+    var cx;
+    var cy = layout.y1 + 50 + layout.margin + outerRadius;
+    if (showLabels) {
+      cx = layout.x1 + layout.margin + outerRadius;
+    } else {
+      cx = (layout.x1 + layout.x2) / 2;
+    }
+
+    var pie = d3.layout.pie();
+    pie.sort(null);
+    pie.value(function(d) {
+      var v = d.value;
+      // make sure it > 0
+      v = Math.max(v, 1e-6);
+      return v;
+    });
+
+    //Set up groups
+    var arcs = g
+      .selectAll("g.arc")
+      .data(pie(data))
+      .enter()
+      .append("g")
+      .attr("class", "arc")
+      .attr("transform", "translate(" + cx + "," + cy + ")");
+
+    function tweenPie(finish) {
+      var start = {
+        startAngle: 0,
+        endAngle: 0
+      };
+      var i = d3.interpolate(start, finish);
+      return function(d) {
+        return arc(i(d));
+      };
+    }
+
+    //Draw arc paths
+    var path = arcs.append("path")
+      .attr("fill", function(d, i) {
+        if (d.value > 1e-6) {
+          return this.colors[i];
+        } else {
+          return "white";
+        }
+      }.bind(this))
+      .attr("d", arc)
+      .attr("stroke", function(d, i) {
+        if (allZero) {
+          return this.colors[i];
+        }
+      }.bind(this))
+      .attr("stroke-dasharray", function(d, i) {
+        if (d.value <= 1e-6) {
+          return "10,10";
+        }
+      }.bind(this));
+    this.bindTooltip(path);
+
+    // Show labels
+    if (showLabels) {
+      var lx = layout.x1 + layout.margin + outerRadius * 2 + 30;
+      var squareW = 15;
+      var margin = 10;
+
+      var select = g.selectAll(".rect")
+        .data(data)
+        .enter();
+      select.append("rect")
+        .attr("fill", function(d, i) {
+          return this.colors[i];
+        }.bind(this))
+        .attr("x", lx)
+        .attr("y", function(d, i) {
+          return layout.y1 + 50 + (squareW + margin) * i + layout.margin;
+        })
+        .attr("width", squareW)
+        .attr("height", squareW);
+      select.append("text")
+        .attr("x", lx + squareW + margin)
+        .attr("y", function(d, i) {
+          return layout.y1 + 50 + (squareW + margin) * i + layout.margin + 
squareW / 2;
+        })
+        .text(function(d) {
+          return d.label + ' = ' + d.value;
+        });
+    }
+
+    if (middleLabel) {
+      var highLightColor = this.colors[0];
+      g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10).
+        attr("class", "donut-highlight-text").attr("fill", highLightColor);
+      g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 20).
+        attr("class", "donut-highlight-text").attr("fill", highLightColor).
+        style("font-size", "30px");
+    }
+
+    path.transition()
+      .duration(500)
+      .attrTween('d', tweenPie);
+  },
+
+  draw: function() {
+    this.initChart();
+    this.renderDonutChart(this.get("data"), this.get("title"), 
this.get("showLabels"), 
+                          this.get("middleLabel"), this.get("middleValue"));
+  },
+
+  didInsertElement: function() {
+    this.draw();
+  },
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js
new file mode 100644
index 0000000..235e438
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.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';
+
+export default Ember.Component.extend({
+  didInsertElement: function() {
+    $(".js-example-basic-single").select2(
+      {
+        width: '100%',
+        placeholder: "Select a queue"
+      });
+    var elementId = this.get("element-id");
+    var prefix = this.get("prefix");
+
+    var element = d3.select("#" + elementId);
+
+    if (element) {
+      this.get("model").forEach(function(o) {
+        element.append("option").attr("value", o.get("name")).text(prefix + 
o.get("name"));
+      });
+    }
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.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 Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.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 Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
new file mode 100644
index 0000000..2a90771
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
@@ -0,0 +1,290 @@
+/**
+ * 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 ChartUtilsMixin from 'yarn-ui/mixins/charts-utils';
+
+export default Ember.Component.extend(ChartUtilsMixin, {
+  queues: {
+    data: undefined,
+    foldedQueues: {},
+    selectedQueueCircle: undefined,
+    maxDepth: -1,
+  },
+
+  queueColors: d3.scale.category20().range(),
+
+  renderQueue: function (now, depth, sequence) {
+    if (depth > this.queues.maxDepth) {
+      this.queues.maxDepth = depth;
+    }
+
+    var cx = 20 + depth * 30;
+    var cy = 20 + sequence * 30;
+    var name = now.get("name");
+
+    var g = this.queues.dataGroup.append("g")
+      .attr("id", "queue-" + name + "-g");
+
+    var folded = this.queues.foldedQueues[name];
+    var isParentQueue = false;
+
+    // render its children
+    var children = [];
+    var childrenNames = now.get("children");
+    if (childrenNames) {
+      childrenNames.forEach(function (name) {
+        isParentQueue = true;
+        var child = this.queues.data[name];
+        if (child) {
+          children.push(child);
+        }
+      }.bind(this));
+    }
+    if (folded) {
+      children = [];
+    }
+    var linefunction = d3.svg.line()
+      .interpolate("basis")
+      .x(function (d) {
+        return d.x;
+      })
+      .y(function (d) {
+        return d.y;
+      });
+
+    for (var i = 0; i < children.length; i++) {
+      sequence = sequence + 1;
+      // Get center of children queue
+      var cc = this.renderQueue(children[i],
+        depth + 1, sequence);
+      g.append("path")
+        .attr("class", "queue")
+        .attr("d", linefunction([{
+          x: cx,
+          y: cy
+        }, {
+          x: cc.x - 20,
+          y: cc.y
+        }, cc]));
+    }
+
+    var circle = g.append("circle")
+      .attr("cx", cx)
+      .attr("cy", cy)
+      .attr("class", "queue");
+
+    circle.on('mouseover', function () {
+      circle.style("fill", this.queueColors[1]);
+    }.bind(this));
+    circle.on('mouseout', function () {
+      if (circle != this.queues.selectedQueueCircle) {
+        circle.style("fill", this.queueColors[0]);
+      }
+    }.bind(this));
+    circle.on('click', function () {
+      circle.style("fill", this.queueColors[2]);
+      var pre = this.queues.selectedQueueCircle;
+      this.queues.selectedQueueCircle = circle;
+      if (pre) {
+        pre.on('mouseout')();
+      }
+      this.renderCharts(name);
+    }.bind(this));
+    circle.on('dblclick', function () {
+      if (!isParentQueue) {
+        return;
+      }
+
+      if (this.queues.foldedQueues[name]) {
+        delete this.queues.foldedQueues[name];
+      } else {
+        this.queues.foldedQueues[name] = now;
+      }
+      this.renderQueues();
+    }.bind(this));
+
+    var text = name;
+    if (folded) {
+      text = name + " (+)";
+    }
+
+    // print queue's name
+    g.append("text")
+      .attr("x", cx + 30)
+      .attr("y", cy + 5)
+      .text(text)
+      .attr("class", "queue");
+
+    return {
+      x: cx,
+      y: cy
+    };
+  },
+
+  renderQueues: function () {
+    if (this.queues.dataGroup) {
+      this.queues.dataGroup.remove();
+    }
+    // render queues
+    this.queues.dataGroup = this.canvas.svg.append("g")
+      .attr("id", "queues-g");
+    var rootQueue = undefined;
+
+    if (this.queues.data) {
+      this.renderQueue(this.queues.data['root'], 0, 0);
+
+    }
+  },
+
+  draw: function () {
+    this.queues.data = {};
+    this.get("model")
+      .forEach(function (o) {
+        this.queues.data[o.id] = o;
+      }.bind(this));
+
+    // get w/h of the svg
+    var bbox = d3.select("#main-container")
+      .node()
+      .getBoundingClientRect();
+    this.canvas.w = bbox.width;
+    this.canvas.h = Math.max(Object.keys(this.queues.data)
+        .length * 35, 1500);
+
+    this.canvas.svg = d3.select("#main-container")
+      .append("svg")
+      .attr("width", this.canvas.w)
+      .attr("height", this.canvas.h)
+      .attr("id", "main-svg");
+
+    this.renderBackground();
+
+    this.renderQueues();
+    this.renderCharts("root");
+  },
+
+  didInsertElement: function () {
+    this.draw();
+  },
+
+  /*
+   * data = [{label="xx", value=},{...}]
+   */
+  renderTable: function (data, title, layout) {
+    d3.select("#main-svg")
+      .append('table')
+      .selectAll('tr')
+      .data(data)
+      .enter()
+      .append('tr')
+      .selectAll('td')
+      .data(function (d) {
+        return d;
+      })
+      .enter()
+      .append('td')
+      .text(function (d) {
+        return d;
+      });
+  },
+
+  renderQueueCapacities: function (queue, layout) {
+    // Render bar chart
+    this.renderBarChart(this.charts.g, [{
+      label: "Cap",
+      value: queue.get("capacity")
+    }, {
+      label: "MaxCap",
+      value: queue.get("maxCapacity")
+    }, {
+      label: "UsedCap",
+      value: queue.get("usedCapacity")
+    }], "Queue Capacities", layout, 60);
+  },
+
+  renderChildrenCapacities: function (queue, layout) {
+    var data = [];
+    var children = queue.get("children");
+    if (children) {
+      for (var i = 0; i < children.length; i++) {
+        var child = this.queues.data[children[i]];
+        data.push({
+          label: child.get("name"),
+          value: child.get("capacity")
+        });
+      }
+    }
+
+    this.renderDonutChart(this.charts.g, data, "Children Capacities", layout, 
true);
+  },
+
+  renderChildrenUsedCapacities: function (queue, layout) {
+    var data = [];
+    var children = queue.get("children");
+    if (children) {
+      for (var i = 0; i < children.length; i++) {
+        var child = this.queues.data[children[i]];
+        data.push({
+          label: child.get("name"),
+          value: child.get("usedCapacity")
+        });
+      }
+    }
+
+    this.renderDonutChart(this.charts.g, data, "Children Used Capacities", 
layout, true);
+  },
+
+  renderLeafQueueUsedCapacities: function (layout) {
+    var leafQueueUsedCaps = [];
+    for (var queueName in this.queues.data) {
+      var q = this.queues.data[queueName];
+      if ((!q.get("children")) || q.get("children")
+          .length == 0) {
+        // it's a leafqueue
+        leafQueueUsedCaps.push({
+          label: q.get("name"),
+          value: q.get("usedCapacity")
+        });
+      }
+    }
+
+    this.renderDonutChart(this.charts.g, leafQueueUsedCaps, "LeafQueues Used 
Capacities",
+      layout, true);
+  },
+
+  renderCharts: function (queueName) {
+    this.charts.leftBannerLen = this.queues.maxDepth * 30 + 100;
+    this.initCharts();
+
+    var queue = this.queues.data[queueName];
+    var idx = 0;
+
+    if (queue.get("name") == "root") {
+      this.renderLeafQueueUsedCapacities(this.getLayout(idx++));
+    }
+    if (queue.get("name") != "root") {
+      this.renderQueueCapacities(queue, this.getLayout(idx++));
+    }
+    if (queue.get("children") && queue.get("children")
+        .length > 0) {
+      this.renderChildrenCapacities(queue, this.getLayout(idx++));
+      this.renderChildrenUsedCapacities(queue, this.getLayout(idx++));
+    }
+  },
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
new file mode 100644
index 0000000..e5da81a
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
@@ -0,0 +1,76 @@
+/**
+ * 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({
+  didInsertElement: function() {
+    var paging = this.get("paging") ? true : this.get("paging");
+    var ordering = this.get("ordering") ? true : this.get("ordering");
+    var info = this.get("info") ? true : this.get("info");
+    var bFilter = this.get("bFilter") ? true : this.get("bFilter");
+
+    // Defines sorter for the columns if not default.
+    // Can also specify a custom sorter.
+    var i;
+    var colDefs = [];
+    if (this.get("colTypes")) {
+      var typesArr = this.get("colTypes").split(' ');
+      var targetsArr = this.get("colTargets").split(' ');
+      for (i = 0; i < typesArr.length; i++) {
+        console.log(typesArr[i] + " " + targetsArr[i]);
+        colDefs.push({
+          type: typesArr[i],
+          targets: parseInt(targetsArr[i])
+        });
+      }
+    }
+    // Defines initial column and sort order.
+    var orderArr = [];
+    if (this.get("colsOrder")) {
+      var cols = this.get("colsOrder").split(' ');
+      for (i = 0; i < cols.length; i++) {
+        var col = cols[i].split(',');
+        if (col.length != 2) {
+          continue;
+        }
+        var order = col[1].trim();
+        if (order != 'asc' && order != 'desc') {
+          continue;
+        }
+        var colOrder = [];
+        colOrder.push(parseInt(col[0]));
+        colOrder.push(order);
+        orderArr.push(colOrder);
+      }
+    }
+    if (orderArr.length == 0) {
+      var defaultOrder = [0, 'asc'];
+      orderArr.push(defaultOrder);
+    }
+    console.log(orderArr[0]);
+    Ember.$('#' + this.get('table-id')).DataTable({
+      "paging":   paging,
+      "ordering": ordering, 
+      "info":     info,
+      "bFilter": bFilter,
+      "order": orderArr,
+      "columnDefs": colDefs
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/4bf84af8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
new file mode 100644
index 0000000..b92f4bf
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
@@ -0,0 +1,268 @@
+/**
+ * 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 Converter from 'yarn-ui/utils/converter';
+
+export default Ember.Component.extend({
+  canvas: {
+    svg: undefined,
+    h: 0,
+    w: 0,
+    tooltip: undefined
+  },
+
+  clusterMetrics: undefined,
+  modelArr: [],
+  colors: d3.scale.category10().range(),
+  _selected: undefined,
+
+  selected: function() {
+    return this._selected;
+  }.property(),
+
+  tableComponentName: function() {
+    return "app-attempt-table";
+  }.property(),
+
+  setSelected: function(d) {
+    if (this._selected == d) {
+      return;
+    }
+
+    // restore color
+    if (this._selected) {
+      var dom = d3.select("#timeline-bar-" + this._selected.get("id"));
+      dom.attr("fill", this.colors[0]);
+    }
+
+    this._selected = d;
+    this.set("selected", d);
+    dom = d3.select("#timeline-bar-" + d.get("id"));
+    dom.attr("fill", this.colors[1]);
+  },
+
+  getPerItemHeight: function() {
+    var arrSize = this.modelArr.length;
+
+    if (arrSize < 20) {
+      return 30;
+    } else if (arrSize < 100) {
+      return 10;
+    } else {
+      return 2;
+    }
+  },
+
+  getPerItemGap: function() {
+    var arrSize = this.modelArr.length;
+
+    if (arrSize < 20) {
+      return 5;
+    } else if (arrSize < 100) {
+      return 1;
+    } else {
+      return 1;
+    }
+  },
+
+  getCanvasHeight: function() {
+    return (this.getPerItemHeight() + this.getPerItemGap()) * 
this.modelArr.length + 200;
+  },
+
+  draw: function(start, end) {
+    // get w/h of the svg
+    var bbox = d3.select("#" + this.get("parent-id"))
+      .node()
+      .getBoundingClientRect();
+    this.canvas.w = bbox.width;
+    this.canvas.h = this.getCanvasHeight();
+
+    this.canvas.svg = d3.select("#" + this.get("parent-id"))
+      .append("svg")
+      .attr("width", this.canvas.w)
+      .attr("height", this.canvas.h)
+      .attr("id", this.get("my-id"));
+    this.renderTimeline(start, end);
+  },
+
+  renderTimeline: function(start, end) {
+    var border = 30;
+    var singleBarHeight = this.getPerItemHeight();
+    var gap = this.getPerItemGap();
+    var textWidth = 50;
+    /*
+     start-time                              end-time
+      |--------------------------------------|
+         ==============
+                ==============
+                        ==============
+                              ===============
+     */
+    var xScaler = d3.scale.linear()
+      .domain([start, end])
+      .range([0, this.canvas.w - 2 * border - textWidth]);
+
+    /*
+     * Render frame of timeline view
+     */
+    this.canvas.svg.append("line")
+      .attr("x1", border + textWidth)
+      .attr("y1", border - 5)
+      .attr("x2", this.canvas.w - border)
+      .attr("y2", border - 5)
+      .attr("class", "chart");
+
+    this.canvas.svg.append("line")
+      .attr("x1", border + textWidth)
+      .attr("y1", border - 10)
+      .attr("x2", border + textWidth)
+      .attr("y2", border - 5)
+      .attr("class", "chart");
+
+    this.canvas.svg.append("line")
+      .attr("x1", this.canvas.w - border)
+      .attr("y1", border - 10)
+      .attr("x2", this.canvas.w - border)
+      .attr("y2", border - 5)
+      .attr("class", "chart");
+
+    this.canvas.svg.append("text")
+        .text(Converter.timeStampToDate(start))
+        .attr("y", border - 15)
+        .attr("x", border + textWidth)
+        .attr("class", "bar-chart-text")
+        .attr("text-anchor", "left");
+
+    this.canvas.svg.append("text")
+        .text(Converter.timeStampToDate(end))
+        .attr("y", border - 15)
+        .attr("x", this.canvas.w - border)
+        .attr("class", "bar-chart-text")
+        .attr("text-anchor", "end");
+
+    // show bar
+    var bar = this.canvas.svg.selectAll("bars")
+      .data(this.modelArr)
+      .enter()
+      .append("rect")
+      .attr("y", function(d, i) {
+        return border + (gap + singleBarHeight) * i;
+      })
+      .attr("x", function(d, i) {
+        return border + textWidth + xScaler(d.get("startTs"));
+      })
+      .attr("height", singleBarHeight)
+      .attr("fill", function(d, i) {
+        return this.colors[0];
+      }.bind(this))
+      .attr("width", function(d, i) {
+        var finishedTs = xScaler(d.get("finishedTs"));
+        finishedTs = finishedTs > 0 ? finishedTs : xScaler(end);
+        return finishedTs - xScaler(d.get("startTs"));
+      })
+      .attr("id", function(d, i) {
+        return "timeline-bar-" + d.get("id");
+      });
+    bar.on("click", function(d) {
+      this.setSelected(d);
+    }.bind(this));
+
+    this.bindTooltip(bar);
+
+    if (this.modelArr.length <= 20) {
+      // show bar texts
+      for (var i = 0; i < this.modelArr.length; i++) {
+        this.canvas.svg.append("text")
+          .text(this.modelArr[i].get(this.get("label")))
+          .attr("y", border + (gap + singleBarHeight) * i + singleBarHeight / 
2)
+          .attr("x", border)
+          .attr("class", "bar-chart-text");
+      }
+    }
+  },
+
+  bindTooltip: function(d) {
+    d.on("mouseover", function(d) {
+        this.tooltip
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mousemove", function(d) {
+        this.tooltip.style("opacity", .9);
+        this.tooltip.html(d.get("tooltipLabel"))
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mouseout", function(d) {
+        this.tooltip.style("opacity", 0);
+      }.bind(this));
+  },
+
+  initTooltip: function() {
+    this.tooltip = d3.select("body")
+      .append("div")
+      .attr("class", "tooltip")
+      .attr("id", "chart-tooltip")
+      .style("opacity", 0);
+  },
+
+  didInsertElement: function() {
+    // init tooltip
+    this.initTooltip();
+
+    // init model
+    if (this.get("rmModel")) {
+      this.get("rmModel").forEach(function(o) {
+        this.modelArr.push(o);
+      }.bind(this));
+    }
+
+    if (this.get("tsModel")) {
+     this.get("tsModel").forEach(function(o) {
+        this.modelArr.push(o);
+      }.bind(this)); 
+    }
+
+    this.modelArr.sort(function(a, b) {
+      var tsA = a.get("startTs");
+      var tsB = b.get("startTs");
+
+      return tsA - tsB;
+    });
+    if (this.modelArr.length > 0) {
+      var begin = this.modelArr[0].get("startTs");
+    }
+    var end = 0;
+    for (var i = 0; i < this.modelArr.length; i++) {
+      var ts = this.modelArr[i].get("finishedTs");
+      if (ts > end) {
+        end = ts;
+      }
+    }
+    if (end < begin) {
+      end = Date.now();
+    }
+
+    this.draw(begin, end);
+
+    if (this.modelArr.length > 0) {
+      this.setSelected(this.modelArr[0]);
+    }
+  },
+});
\ No newline at end of file

Reply via email to