GUI -- Added applications view.
Fixed table.js column width computation.
Fixed app.xml files to leave out ONOS from description.

Change-Id: Icfe323e63c7965dd8c3a268421ea58065c5c8236
diff --git a/apps/bgprouter/app.xml b/apps/bgprouter/app.xml
index 13489ca..bd71c6b 100644
--- a/apps/bgprouter/app.xml
+++ b/apps/bgprouter/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.bgprouter" origin="ON.Lab" version="1.2.0"
         features="onos-app-bgprouter">
-    <description>ONOS BGP router application</description>
+    <description>BGP router application</description>
 </app>
diff --git a/apps/config/app.xml b/apps/config/app.xml
index 3e52fb7..ab4af9e 100644
--- a/apps/config/app.xml
+++ b/apps/config/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.config" origin="ON.Lab" version="1.2.0"
         features="onos-app-config">
-    <description>ONOS network configuration application</description>
+    <description>Network configuration application</description>
 </app>
diff --git a/apps/fwd/app.xml b/apps/fwd/app.xml
index e3de97a..e6f022e 100644
--- a/apps/fwd/app.xml
+++ b/apps/fwd/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.fwd" origin="ON.Lab" version="1.2.0"
         features="onos-app-fwd">
-    <description>ONOS Reactive forwarding application using flow subsystem</description>
+    <description>Reactive forwarding application using flow subsystem</description>
 </app>
diff --git a/apps/metrics/app.xml b/apps/metrics/app.xml
index f1137aa..53375b9 100644
--- a/apps/metrics/app.xml
+++ b/apps/metrics/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.metrics" origin="ON.Lab" version="1.2.0"
         features="onos-app-metrics">
-    <description>ONOS performance metrics collection</description>
+    <description>Performance metrics collection</description>
 </app>
diff --git a/apps/mobility/app.xml b/apps/mobility/app.xml
index a7b9bbb..4cbc1be 100644
--- a/apps/mobility/app.xml
+++ b/apps/mobility/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.mobility" origin="ON.Lab" version="1.2.0"
         features="onos-app-mobility">
-    <description>ONOS host mobility application</description>
+    <description>Host mobility application</description>
 </app>
diff --git a/apps/optical/app.xml b/apps/optical/app.xml
index c579870..f12f840 100644
--- a/apps/optical/app.xml
+++ b/apps/optical/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.optical" origin="ON.Lab" version="1.2.0"
         features="onos-app-optical">
-    <description>ONOS Packet/Optical use-case application</description>
+    <description>Packet/Optical use-case application</description>
 </app>
diff --git a/apps/proxyarp/app.xml b/apps/proxyarp/app.xml
index aa7067a..54c2fd8 100644
--- a/apps/proxyarp/app.xml
+++ b/apps/proxyarp/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.proxyarp" origin="ON.Lab" version="1.2.0"
         features="onos-app-proxyarp">
-    <description>ONOS proxy ARP/NDP application</description>
+    <description>Proxy ARP/NDP application</description>
 </app>
diff --git a/apps/sdnip/app.xml b/apps/sdnip/app.xml
index 4868361..0e9627f 100644
--- a/apps/sdnip/app.xml
+++ b/apps/sdnip/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.sdnip" origin="ON.Lab" version="1.2.0"
         features="onos-app-sdnip">
-    <description>ONOS SDN/IP use-case application</description>
+    <description>SDN/IP use-case application</description>
 </app>
diff --git a/apps/test/election/app.xml b/apps/test/election/app.xml
index 0db483d..a907d33 100644
--- a/apps/test/election/app.xml
+++ b/apps/test/election/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.election" origin="ON.Lab" version="1.2.0"
         features="onos-app-election">
-    <description>ONOS master election test application</description>
+    <description>Master election test application</description>
 </app>
diff --git a/apps/test/intent-perf/src/assembly/app.xml b/apps/test/intent-perf/src/assembly/app.xml
index 05bdc7e..c20888b 100644
--- a/apps/test/intent-perf/src/assembly/app.xml
+++ b/apps/test/intent-perf/src/assembly/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0"
      features="onos-app-intent-perf">
-    <description>Intent performance application</description>
+    <description>Intent performance test application</description>
 </app>
\ No newline at end of file
diff --git a/providers/null/app.xml b/providers/null/app.xml
index a773530..a6343d2 100644
--- a/providers/null/app.xml
+++ b/providers/null/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.null" origin="ON.Lab" version="1.2.0"
         features="onos-null">
-    <description>ONOS null southbound providers for testing</description>
+    <description>Null southbound providers for testing</description>
 </app>
diff --git a/providers/openflow/app.xml b/providers/openflow/app.xml
index 0ab83f6..5159d74 100644
--- a/providers/openflow/app.xml
+++ b/providers/openflow/app.xml
@@ -16,5 +16,5 @@
   -->
 <app name="org.onosproject.openflow" origin="ON.Lab" version="1.2.0"
         features="onos-openflow">
-    <description>ONOS OpenFlow protocol southbound providers</description>
+    <description>OpenFlow protocol southbound providers</description>
 </app>
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
new file mode 100644
index 0000000..800b57d
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.
+ */
+package org.onosproject.ui.impl;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.app.ApplicationState;
+import org.onosproject.core.Application;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.onosproject.app.ApplicationState.ACTIVE;
+
+/**
+ * Message handler for application view related messages.
+ */
+public class ApplicationViewMessageHandler extends AbstractTabularViewMessageHandler {
+
+    /**
+     * Creates a new message handler for the application messages.
+     */
+    protected ApplicationViewMessageHandler() {
+        super(ImmutableSet.of("appDataRequest"));
+    }
+
+    @Override
+    public void process(ObjectNode message) {
+        ObjectNode payload = payload(message);
+        String sortCol = string(payload, "sortCol", "id");
+        String sortDir = string(payload, "sortDir", "asc");
+
+        ApplicationService service = get(ApplicationService.class);
+        TableRow[] rows = generateTableRows(service);
+        RowComparator rc =
+                new RowComparator(sortCol, RowComparator.direction(sortDir));
+        Arrays.sort(rows, rc);
+        ArrayNode applications = generateArrayNode(rows);
+        ObjectNode rootNode = mapper.createObjectNode();
+        rootNode.set("applications", applications);
+
+        connection().sendMessage("appDataResponse", 0, rootNode);
+    }
+
+    private TableRow[] generateTableRows(ApplicationService service) {
+        List<TableRow> list = service.getApplications().stream()
+                .map(application -> new ApplicationTableRow(service, application))
+                .collect(Collectors.toList());
+        return list.toArray(new TableRow[list.size()]);
+    }
+
+    /**
+     * TableRow implementation for {@link org.onosproject.core.Application applications}.
+     */
+    private static class ApplicationTableRow extends AbstractTableRow {
+
+        private static final String STATE = "state";
+        private static final String STATE_IID = "_iconid_state";
+        private static final String ID = "id";
+        private static final String VERSION = "version";
+        private static final String ORIGIN = "origin";
+        private static final String DESC = "desc";
+
+        private static final String[] COL_IDS = {
+                STATE, STATE_IID, ID, VERSION, ORIGIN, DESC
+        };
+
+        private static final String ICON_ID_ACTIVE = "appActive";
+        private static final String ICON_ID_INACTIVE = "appInactive";
+
+
+        public ApplicationTableRow(ApplicationService service, Application app) {
+            ApplicationState state = service.getState(app.id());
+            String iconId = state == ACTIVE ? ICON_ID_ACTIVE : ICON_ID_INACTIVE;
+
+            add(STATE, state.toString());
+            add(STATE_IID, iconId);
+            add(ID, app.id().name());
+            add(VERSION, app.version().toString());
+            add(ORIGIN, app.origin());
+            add(DESC, app.description());
+        }
+
+        @Override
+        protected String[] columnIds() {
+            return COL_IDS;
+        }
+    }
+
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
index 73f7b8e..f0541f6 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
@@ -59,12 +59,14 @@
         List<UiView> coreViews = of(new UiView("topo", "Topology View"),
                                     new UiView("device", "Devices"),
                                     new UiView("host", "Hosts"),
+                                    new UiView("app", "Applications"),
                                     new UiView("sample", "Sample"));
         UiMessageHandlerFactory messageHandlerFactory =
                 () -> ImmutableList.of(
                         new TopologyViewMessageHandler(),
                         new DeviceViewMessageHandler(),
-                        new HostViewMessageHandler()
+                        new HostViewMessageHandler(),
+                        new ApplicationViewMessageHandler()
                 );
         return new UiExtension(coreViews, messageHandlerFactory, "core",
                                UiExtensionManager.class.getClassLoader());
diff --git a/web/gui/src/main/resources/core/css.html b/web/gui/src/main/resources/core/css.html
index ca58b8c..3ff410c 100644
--- a/web/gui/src/main/resources/core/css.html
+++ b/web/gui/src/main/resources/core/css.html
@@ -2,3 +2,4 @@
 <link rel="stylesheet" href="app/view/topo/topo.css">
 <link rel="stylesheet" href="app/view/device/device.css">
 <link rel="stylesheet" href="app/view/host/host.css">
+<link rel="stylesheet" href="app/view/app/app.css">
diff --git a/web/gui/src/main/resources/core/js.html b/web/gui/src/main/resources/core/js.html
index 0c4cffc..c2ad984 100644
--- a/web/gui/src/main/resources/core/js.html
+++ b/web/gui/src/main/resources/core/js.html
@@ -13,4 +13,5 @@
 <script src="app/view/topo/topoToolbar.js"></script>
 <script src="app/view/device/device.js"></script>
 <script src="app/view/host/host.js"></script>
+<script src="app/view/app/app.js"></script>
 <script src="app/view/sample/sample.js"></script>
diff --git a/web/gui/src/main/webapp/app/common.css b/web/gui/src/main/webapp/app/common.css
index 43755d3..5c7d2a1 100644
--- a/web/gui/src/main/webapp/app/common.css
+++ b/web/gui/src/main/webapp/app/common.css
@@ -43,10 +43,21 @@
     background-color: #444;
 }
 
-table.summary-list th {
-    padding: 10px;
-    letter-spacing: 0.02em;
+.light table.summary-list tr.selected {
+    background-color: deepskyblue;
+}
+
+.dark table.summary-list tr.selected {
+    background-color: #304860;
+}
+
+table.summary-list td,th {
+    padding: 6px 6px 6px 6px;
     text-align: left;
+}
+
+table.summary-list th {
+    letter-spacing: 0.02em;
     cursor: pointer;
 }
 table.summary-list th:first-child {
@@ -55,6 +66,7 @@
 table.summary-list th:last-child {
     border-radius: 0 8px 0 0;
 }
+
 .light table.summary-list th {
     background-color: #bbb;
 }
@@ -63,11 +75,6 @@
     color: #ccc;
 }
 
-table.summary-list td {
-    padding: 6px 10px 6px 10px;
-    text-align: left;
-}
-
 .dark table.summary-list td {
     color: #ccc;
 }
diff --git a/web/gui/src/main/webapp/app/fw/svg/icon.css b/web/gui/src/main/webapp/app/fw/svg/icon.css
index 7f3e8f4..6d83da2 100644
--- a/web/gui/src/main/webapp/app/fw/svg/icon.css
+++ b/web/gui/src/main/webapp/app/fw/svg/icon.css
@@ -28,6 +28,29 @@
     fill-rule: evenodd;
 }
 
+/*
+ FIXME: The following should be consolidated to result in much less CSS and
+ not to require entries for every icon.
+ */
+
+.light svg.embeddedIcon .icon.appActive,
+.light svg.embeddedIcon .icon.appInactive {
+    fill: none;
+}
+
+.dark svg.embeddedIcon .icon.appActive,
+.dark svg.embeddedIcon .icon.appInactive {
+    fill: none;
+}
+
+.light svg.embeddedIcon .icon.appActive .glyph {
+    fill: green;
+}
+.dark svg.embeddedIcon .icon.appActive .glyph {
+    fill: #266610;
+}
+
+
 .light svg.embeddedIcon .icon.deviceOnline,
 .light svg.embeddedIcon .icon.deviceOffline {
     fill: none;
@@ -73,6 +96,10 @@
     fill: #ccc;
 }
 
+.light svg.embeddedIcon .icon.appActive rect,
+.light svg.embeddedIcon .icon.appInactive rect,
+.dark svg.embeddedIcon .icon.appActive rect,
+.dark svg.embeddedIcon .icon.appInactive rect,
 .light svg.embeddedIcon .icon.deviceOnline rect,
 .light svg.embeddedIcon .icon.deviceOffline rect,
 .dark svg.embeddedIcon .icon.deviceOnline rect,
diff --git a/web/gui/src/main/webapp/app/fw/svg/icon.js b/web/gui/src/main/webapp/app/fw/svg/icon.js
index 400b7aa..8a8b35f 100644
--- a/web/gui/src/main/webapp/app/fw/svg/icon.js
+++ b/web/gui/src/main/webapp/app/fw/svg/icon.js
@@ -29,6 +29,9 @@
     // Maps icon ID to the glyph ID it uses.
     // NOTE: icon ID maps to a CSS class for styling that icon
     var glyphMapping = {
+        appActive: 'checkMark',
+        appInactive: 'unknown',
+
         deviceOnline: 'checkMark',
         deviceOffline: 'xMark',
         devIcon_SWITCH: 'switch',
diff --git a/web/gui/src/main/webapp/app/fw/widget/table.js b/web/gui/src/main/webapp/app/fw/widget/table.js
index 2fc3277..285d21d 100644
--- a/web/gui/src/main/webapp/app/fw/widget/table.js
+++ b/web/gui/src/main/webapp/app/fw/widget/table.js
@@ -29,19 +29,31 @@
     // Functions for creating a fixed header on a table (Angular Directive)
 
     function setTableWidth(t) {
-        var tHeaders, tdElement, colWidth, numCols,
+        var tHeaders, tdElement, colWidth, numIcons, numNonIcons,
             winWidth = fs.windowSize().width;
 
         tHeaders = t.selectAll('th');
-        numCols = tHeaders[0].length;
-        colWidth = Math.floor(winWidth / numCols);
+        numIcons = 0;
+        numNonIcons = 0;
+
+        // FIXME: This should observe custom-set width from the HTML
 
         tHeaders.each(function(thElement, index) {
             thElement = d3.select(this);
+            if (thElement.classed('table-icon')) {
+                numIcons = numIcons + 1;
+            } else {
+                numNonIcons = numNonIcons + 1;
+            }
+        });
 
+        colWidth = Math.floor((winWidth - (numIcons * tableIconTdSize)) / numNonIcons);
+
+        tHeaders.each(function(thElement, index) {
+            thElement = d3.select(this);
             tdElement = t.select('td:nth-of-type(' + (index + 1) + ')');
 
-            if (tdElement.classed('table-icon')) {
+            if (thElement.classed('table-icon')) {
                 thElement.style('width', tableIconTdSize + 'px');
                 tdElement.style('width', tableIconTdSize + 'px');
             } else {
diff --git a/web/gui/src/main/webapp/app/view/app/app.css b/web/gui/src/main/webapp/app/view/app/app.css
new file mode 100644
index 0000000..b30f488
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/app/app.css
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.
+ */
+
+/*
+ ONOS GUI -- Host View -- CSS file
+ */
+
+#ov-app td {
+}
diff --git a/web/gui/src/main/webapp/app/view/app/app.html b/web/gui/src/main/webapp/app/view/app/app.html
new file mode 100644
index 0000000..c219eb8
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/app/app.html
@@ -0,0 +1,34 @@
+<!-- app partial HTML -->
+<div id="ov-app">
+    <h2>Applications ({{ctrl.appData.length}} total)</h2>
+    <table class="summary-list"
+           onos-fixed-header
+           onos-sortable-header
+           sort-callback="sortCallback(requestParams)">
+        <thead>
+            <tr>
+                <th colId="state" class="table-icon" sortable></th>
+                <th colId="id" sortable>App ID </th>
+                <th colId="version" sortable>Version</th>
+                <th colId="origin" sortable>Origin </th>
+                <th colId="desc">Description </th>
+            </tr>
+        </thead>
+
+        <tbody>
+        <tr ng-repeat="app in ctrl.appData"
+            ng-click="setSelected(app.id)"
+            ng-class="{selected: app.id === selectedAppId}"
+            ng-repeat-done>
+            <td class="table-icon">
+                <div icon icon-id="{{app._iconid_state}}"></div>
+            </td>
+            <td>{{app.id}}</td>
+            <td>{{app.version}}</td>
+            <td>{{app.origin}}</td>
+            <td>{{app.desc}}</td>
+        </tr>
+        </tbody>
+    </table>
+
+</div>
diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
new file mode 100644
index 0000000..d2bab39
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.
+ */
+
+/*
+ ONOS GUI -- App View Module
+ */
+
+(function () {
+    'use strict';
+
+    angular.module('ovApp', [])
+    .controller('OvAppCtrl',
+        ['$log', '$scope', '$location', 'FnService', 'WebSocketService',
+
+        function ($log, $scope, $location, fs, wss) {
+            var self = this;
+            self.appData = [];
+
+            $scope.responseCallback = function(data) {
+                self.appData = data.applications;
+                $scope.$apply();
+            };
+
+            $scope.sortCallback = function (requestParams) {
+                wss.sendEvent('appDataRequest', requestParams);
+            };
+
+            $scope.selectedAppId = null;
+            $scope.setSelected = function (appId) {
+                $scope.selectedAppId = appId;
+            };
+
+            var handlers = {
+                appDataResponse: $scope.responseCallback
+            };
+            wss.bindHandlers(handlers);
+
+            // Cleanup on destroyed scope
+            $scope.$on('$destroy', function () {
+                wss.unbindHandlers(handlers);
+            });
+
+            $scope.sortCallback();
+
+            $log.log('OvAppCtrl has been created');
+        }]);
+}());
diff --git a/web/gui/src/main/webapp/app/view/device/device.css b/web/gui/src/main/webapp/app/view/device/device.css
index bfc1ebc..53cdabe 100644
--- a/web/gui/src/main/webapp/app/view/device/device.css
+++ b/web/gui/src/main/webapp/app/view/device/device.css
@@ -18,6 +18,5 @@
  ONOS GUI -- Device View -- CSS file
  */
 
-#ov-device {
-    /* placeholder */
-}
\ No newline at end of file
+#ov-device td {
+}
diff --git a/web/gui/src/main/webapp/app/view/device/device.html b/web/gui/src/main/webapp/app/view/device/device.html
index c37f295..1db7900 100644
--- a/web/gui/src/main/webapp/app/view/device/device.html
+++ b/web/gui/src/main/webapp/app/view/device/device.html
@@ -7,8 +7,8 @@
            sort-callback="sortCallback(requestParams)">
         <thead>
             <tr>
-                <th colId="available"></th>
-                <th colId="type"></th>
+                <th colId="available" class="table-icon" sortable></th>
+                <th colId="type" class="table-icon" sortable></th>
                 <th colId="id" sortable>Device ID </th>
                 <th colId="mfr" sortable>Vendor </th>
                 <th colId="hw" sortable>H/W Version </th>
diff --git a/web/gui/src/main/webapp/app/view/host/host.css b/web/gui/src/main/webapp/app/view/host/host.css
index 708dc23..94815f5 100644
--- a/web/gui/src/main/webapp/app/view/host/host.css
+++ b/web/gui/src/main/webapp/app/view/host/host.css
@@ -19,5 +19,5 @@
  */
 
 #ov-host td {
-    padding: 12px 10px;
+    height: 20px;
 }
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 89c5aff..ef45356 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -101,6 +101,7 @@
     <script src="app/view/topo/topoToolbar.js"></script>
     <script src="app/view/device/device.js"></script>
     <script src="app/view/host/host.js"></script>
+    <script src="app/view/app/app.js"></script>
     <script src="app/view/sample/sample.js"></script>
     <!-- {INJECTED-JAVASCRIPT-END} -->
 
@@ -110,6 +111,7 @@
     <link rel="stylesheet" href="app/view/topo/topo.css">
     <link rel="stylesheet" href="app/view/device/device.css">
     <link rel="stylesheet" href="app/view/host/host.css">
+    <link rel="stylesheet" href="app/view/app/app.css">
     <link rel="stylesheet" href="app/view/sample/sample.css">
     <!-- {INJECTED-STYLESHEETS-END} -->
 
diff --git a/web/gui/src/main/webapp/onos.js b/web/gui/src/main/webapp/onos.js
index d63d6d9..2822cf6 100644
--- a/web/gui/src/main/webapp/onos.js
+++ b/web/gui/src/main/webapp/onos.js
@@ -39,6 +39,7 @@
         'topo',
         'device',
         'host',
+        'app',
         'sample',
         // {INJECTED-VIEW-IDS-END}