GUI -- Added applications view.
Fixed table.js column width computation. Fixed app.xml files to leave out ONOS from description. Change-Id: Icfe323e63c7965dd8c3a268421ea58065c5c8236
Showing
28 changed files
with
306 additions
and
29 deletions
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.bgprouter" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.bgprouter" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-bgprouter"> | 18 | features="onos-app-bgprouter"> |
19 | - <description>ONOS BGP router application</description> | 19 | + <description>BGP router application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.config" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.config" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-config"> | 18 | features="onos-app-config"> |
19 | - <description>ONOS network configuration application</description> | 19 | + <description>Network configuration application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.fwd" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.fwd" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-fwd"> | 18 | features="onos-app-fwd"> |
19 | - <description>ONOS Reactive forwarding application using flow subsystem</description> | 19 | + <description>Reactive forwarding application using flow subsystem</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.metrics" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.metrics" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-metrics"> | 18 | features="onos-app-metrics"> |
19 | - <description>ONOS performance metrics collection</description> | 19 | + <description>Performance metrics collection</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.mobility" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.mobility" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-mobility"> | 18 | features="onos-app-mobility"> |
19 | - <description>ONOS host mobility application</description> | 19 | + <description>Host mobility application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.optical" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.optical" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-optical"> | 18 | features="onos-app-optical"> |
19 | - <description>ONOS Packet/Optical use-case application</description> | 19 | + <description>Packet/Optical use-case application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.proxyarp" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.proxyarp" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-proxyarp"> | 18 | features="onos-app-proxyarp"> |
19 | - <description>ONOS proxy ARP/NDP application</description> | 19 | + <description>Proxy ARP/NDP application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.sdnip" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.sdnip" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-sdnip"> | 18 | features="onos-app-sdnip"> |
19 | - <description>ONOS SDN/IP use-case application</description> | 19 | + <description>SDN/IP use-case application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.election" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.election" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-election"> | 18 | features="onos-app-election"> |
19 | - <description>ONOS master election test application</description> | 19 | + <description>Master election test application</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0" |
18 | features="onos-app-intent-perf"> | 18 | features="onos-app-intent-perf"> |
19 | - <description>Intent performance application</description> | 19 | + <description>Intent performance test application</description> |
20 | </app> | 20 | </app> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.null" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.null" origin="ON.Lab" version="1.2.0" |
18 | features="onos-null"> | 18 | features="onos-null"> |
19 | - <description>ONOS null southbound providers for testing</description> | 19 | + <description>Null southbound providers for testing</description> |
20 | </app> | 20 | </app> | ... | ... |
... | @@ -16,5 +16,5 @@ | ... | @@ -16,5 +16,5 @@ |
16 | --> | 16 | --> |
17 | <app name="org.onosproject.openflow" origin="ON.Lab" version="1.2.0" | 17 | <app name="org.onosproject.openflow" origin="ON.Lab" version="1.2.0" |
18 | features="onos-openflow"> | 18 | features="onos-openflow"> |
19 | - <description>ONOS OpenFlow protocol southbound providers</description> | 19 | + <description>OpenFlow protocol southbound providers</description> |
20 | </app> | 20 | </app> | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.ui.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import com.google.common.collect.ImmutableSet; | ||
21 | +import org.onosproject.app.ApplicationService; | ||
22 | +import org.onosproject.app.ApplicationState; | ||
23 | +import org.onosproject.core.Application; | ||
24 | + | ||
25 | +import java.util.Arrays; | ||
26 | +import java.util.List; | ||
27 | +import java.util.stream.Collectors; | ||
28 | + | ||
29 | +import static org.onosproject.app.ApplicationState.ACTIVE; | ||
30 | + | ||
31 | +/** | ||
32 | + * Message handler for application view related messages. | ||
33 | + */ | ||
34 | +public class ApplicationViewMessageHandler extends AbstractTabularViewMessageHandler { | ||
35 | + | ||
36 | + /** | ||
37 | + * Creates a new message handler for the application messages. | ||
38 | + */ | ||
39 | + protected ApplicationViewMessageHandler() { | ||
40 | + super(ImmutableSet.of("appDataRequest")); | ||
41 | + } | ||
42 | + | ||
43 | + @Override | ||
44 | + public void process(ObjectNode message) { | ||
45 | + ObjectNode payload = payload(message); | ||
46 | + String sortCol = string(payload, "sortCol", "id"); | ||
47 | + String sortDir = string(payload, "sortDir", "asc"); | ||
48 | + | ||
49 | + ApplicationService service = get(ApplicationService.class); | ||
50 | + TableRow[] rows = generateTableRows(service); | ||
51 | + RowComparator rc = | ||
52 | + new RowComparator(sortCol, RowComparator.direction(sortDir)); | ||
53 | + Arrays.sort(rows, rc); | ||
54 | + ArrayNode applications = generateArrayNode(rows); | ||
55 | + ObjectNode rootNode = mapper.createObjectNode(); | ||
56 | + rootNode.set("applications", applications); | ||
57 | + | ||
58 | + connection().sendMessage("appDataResponse", 0, rootNode); | ||
59 | + } | ||
60 | + | ||
61 | + private TableRow[] generateTableRows(ApplicationService service) { | ||
62 | + List<TableRow> list = service.getApplications().stream() | ||
63 | + .map(application -> new ApplicationTableRow(service, application)) | ||
64 | + .collect(Collectors.toList()); | ||
65 | + return list.toArray(new TableRow[list.size()]); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * TableRow implementation for {@link org.onosproject.core.Application applications}. | ||
70 | + */ | ||
71 | + private static class ApplicationTableRow extends AbstractTableRow { | ||
72 | + | ||
73 | + private static final String STATE = "state"; | ||
74 | + private static final String STATE_IID = "_iconid_state"; | ||
75 | + private static final String ID = "id"; | ||
76 | + private static final String VERSION = "version"; | ||
77 | + private static final String ORIGIN = "origin"; | ||
78 | + private static final String DESC = "desc"; | ||
79 | + | ||
80 | + private static final String[] COL_IDS = { | ||
81 | + STATE, STATE_IID, ID, VERSION, ORIGIN, DESC | ||
82 | + }; | ||
83 | + | ||
84 | + private static final String ICON_ID_ACTIVE = "appActive"; | ||
85 | + private static final String ICON_ID_INACTIVE = "appInactive"; | ||
86 | + | ||
87 | + | ||
88 | + public ApplicationTableRow(ApplicationService service, Application app) { | ||
89 | + ApplicationState state = service.getState(app.id()); | ||
90 | + String iconId = state == ACTIVE ? ICON_ID_ACTIVE : ICON_ID_INACTIVE; | ||
91 | + | ||
92 | + add(STATE, state.toString()); | ||
93 | + add(STATE_IID, iconId); | ||
94 | + add(ID, app.id().name()); | ||
95 | + add(VERSION, app.version().toString()); | ||
96 | + add(ORIGIN, app.origin()); | ||
97 | + add(DESC, app.description()); | ||
98 | + } | ||
99 | + | ||
100 | + @Override | ||
101 | + protected String[] columnIds() { | ||
102 | + return COL_IDS; | ||
103 | + } | ||
104 | + } | ||
105 | + | ||
106 | +} |
... | @@ -59,12 +59,14 @@ public class UiExtensionManager implements UiExtensionService { | ... | @@ -59,12 +59,14 @@ public class UiExtensionManager implements UiExtensionService { |
59 | List<UiView> coreViews = of(new UiView("topo", "Topology View"), | 59 | List<UiView> coreViews = of(new UiView("topo", "Topology View"), |
60 | new UiView("device", "Devices"), | 60 | new UiView("device", "Devices"), |
61 | new UiView("host", "Hosts"), | 61 | new UiView("host", "Hosts"), |
62 | + new UiView("app", "Applications"), | ||
62 | new UiView("sample", "Sample")); | 63 | new UiView("sample", "Sample")); |
63 | UiMessageHandlerFactory messageHandlerFactory = | 64 | UiMessageHandlerFactory messageHandlerFactory = |
64 | () -> ImmutableList.of( | 65 | () -> ImmutableList.of( |
65 | new TopologyViewMessageHandler(), | 66 | new TopologyViewMessageHandler(), |
66 | new DeviceViewMessageHandler(), | 67 | new DeviceViewMessageHandler(), |
67 | - new HostViewMessageHandler() | 68 | + new HostViewMessageHandler(), |
69 | + new ApplicationViewMessageHandler() | ||
68 | ); | 70 | ); |
69 | return new UiExtension(coreViews, messageHandlerFactory, "core", | 71 | return new UiExtension(coreViews, messageHandlerFactory, "core", |
70 | UiExtensionManager.class.getClassLoader()); | 72 | UiExtensionManager.class.getClassLoader()); | ... | ... |
... | @@ -2,3 +2,4 @@ | ... | @@ -2,3 +2,4 @@ |
2 | <link rel="stylesheet" href="app/view/topo/topo.css"> | 2 | <link rel="stylesheet" href="app/view/topo/topo.css"> |
3 | <link rel="stylesheet" href="app/view/device/device.css"> | 3 | <link rel="stylesheet" href="app/view/device/device.css"> |
4 | <link rel="stylesheet" href="app/view/host/host.css"> | 4 | <link rel="stylesheet" href="app/view/host/host.css"> |
5 | +<link rel="stylesheet" href="app/view/app/app.css"> | ... | ... |
... | @@ -13,4 +13,5 @@ | ... | @@ -13,4 +13,5 @@ |
13 | <script src="app/view/topo/topoToolbar.js"></script> | 13 | <script src="app/view/topo/topoToolbar.js"></script> |
14 | <script src="app/view/device/device.js"></script> | 14 | <script src="app/view/device/device.js"></script> |
15 | <script src="app/view/host/host.js"></script> | 15 | <script src="app/view/host/host.js"></script> |
16 | +<script src="app/view/app/app.js"></script> | ||
16 | <script src="app/view/sample/sample.js"></script> | 17 | <script src="app/view/sample/sample.js"></script> | ... | ... |
... | @@ -43,10 +43,21 @@ table.summary-list tbody { | ... | @@ -43,10 +43,21 @@ table.summary-list tbody { |
43 | background-color: #444; | 43 | background-color: #444; |
44 | } | 44 | } |
45 | 45 | ||
46 | +.light table.summary-list tr.selected { | ||
47 | + background-color: deepskyblue; | ||
48 | +} | ||
49 | + | ||
50 | +.dark table.summary-list tr.selected { | ||
51 | + background-color: #304860; | ||
52 | +} | ||
53 | + | ||
54 | +table.summary-list td,th { | ||
55 | + padding: 6px 6px 6px 6px; | ||
56 | + text-align: left; | ||
57 | +} | ||
58 | + | ||
46 | table.summary-list th { | 59 | table.summary-list th { |
47 | - padding: 10px; | ||
48 | letter-spacing: 0.02em; | 60 | letter-spacing: 0.02em; |
49 | - text-align: left; | ||
50 | cursor: pointer; | 61 | cursor: pointer; |
51 | } | 62 | } |
52 | table.summary-list th:first-child { | 63 | table.summary-list th:first-child { |
... | @@ -55,6 +66,7 @@ table.summary-list th:first-child { | ... | @@ -55,6 +66,7 @@ table.summary-list th:first-child { |
55 | table.summary-list th:last-child { | 66 | table.summary-list th:last-child { |
56 | border-radius: 0 8px 0 0; | 67 | border-radius: 0 8px 0 0; |
57 | } | 68 | } |
69 | + | ||
58 | .light table.summary-list th { | 70 | .light table.summary-list th { |
59 | background-color: #bbb; | 71 | background-color: #bbb; |
60 | } | 72 | } |
... | @@ -63,11 +75,6 @@ table.summary-list th:last-child { | ... | @@ -63,11 +75,6 @@ table.summary-list th:last-child { |
63 | color: #ccc; | 75 | color: #ccc; |
64 | } | 76 | } |
65 | 77 | ||
66 | -table.summary-list td { | ||
67 | - padding: 6px 10px 6px 10px; | ||
68 | - text-align: left; | ||
69 | -} | ||
70 | - | ||
71 | .dark table.summary-list td { | 78 | .dark table.summary-list td { |
72 | color: #ccc; | 79 | color: #ccc; |
73 | } | 80 | } | ... | ... |
... | @@ -28,6 +28,29 @@ svg.embeddedIcon .icon .glyph { | ... | @@ -28,6 +28,29 @@ svg.embeddedIcon .icon .glyph { |
28 | fill-rule: evenodd; | 28 | fill-rule: evenodd; |
29 | } | 29 | } |
30 | 30 | ||
31 | +/* | ||
32 | + FIXME: The following should be consolidated to result in much less CSS and | ||
33 | + not to require entries for every icon. | ||
34 | + */ | ||
35 | + | ||
36 | +.light svg.embeddedIcon .icon.appActive, | ||
37 | +.light svg.embeddedIcon .icon.appInactive { | ||
38 | + fill: none; | ||
39 | +} | ||
40 | + | ||
41 | +.dark svg.embeddedIcon .icon.appActive, | ||
42 | +.dark svg.embeddedIcon .icon.appInactive { | ||
43 | + fill: none; | ||
44 | +} | ||
45 | + | ||
46 | +.light svg.embeddedIcon .icon.appActive .glyph { | ||
47 | + fill: green; | ||
48 | +} | ||
49 | +.dark svg.embeddedIcon .icon.appActive .glyph { | ||
50 | + fill: #266610; | ||
51 | +} | ||
52 | + | ||
53 | + | ||
31 | .light svg.embeddedIcon .icon.deviceOnline, | 54 | .light svg.embeddedIcon .icon.deviceOnline, |
32 | .light svg.embeddedIcon .icon.deviceOffline { | 55 | .light svg.embeddedIcon .icon.deviceOffline { |
33 | fill: none; | 56 | fill: none; |
... | @@ -73,6 +96,10 @@ svg.embeddedIcon .icon .glyph { | ... | @@ -73,6 +96,10 @@ svg.embeddedIcon .icon .glyph { |
73 | fill: #ccc; | 96 | fill: #ccc; |
74 | } | 97 | } |
75 | 98 | ||
99 | +.light svg.embeddedIcon .icon.appActive rect, | ||
100 | +.light svg.embeddedIcon .icon.appInactive rect, | ||
101 | +.dark svg.embeddedIcon .icon.appActive rect, | ||
102 | +.dark svg.embeddedIcon .icon.appInactive rect, | ||
76 | .light svg.embeddedIcon .icon.deviceOnline rect, | 103 | .light svg.embeddedIcon .icon.deviceOnline rect, |
77 | .light svg.embeddedIcon .icon.deviceOffline rect, | 104 | .light svg.embeddedIcon .icon.deviceOffline rect, |
78 | .dark svg.embeddedIcon .icon.deviceOnline rect, | 105 | .dark svg.embeddedIcon .icon.deviceOnline rect, | ... | ... |
... | @@ -29,6 +29,9 @@ | ... | @@ -29,6 +29,9 @@ |
29 | // Maps icon ID to the glyph ID it uses. | 29 | // Maps icon ID to the glyph ID it uses. |
30 | // NOTE: icon ID maps to a CSS class for styling that icon | 30 | // NOTE: icon ID maps to a CSS class for styling that icon |
31 | var glyphMapping = { | 31 | var glyphMapping = { |
32 | + appActive: 'checkMark', | ||
33 | + appInactive: 'unknown', | ||
34 | + | ||
32 | deviceOnline: 'checkMark', | 35 | deviceOnline: 'checkMark', |
33 | deviceOffline: 'xMark', | 36 | deviceOffline: 'xMark', |
34 | devIcon_SWITCH: 'switch', | 37 | devIcon_SWITCH: 'switch', | ... | ... |
... | @@ -29,19 +29,31 @@ | ... | @@ -29,19 +29,31 @@ |
29 | // Functions for creating a fixed header on a table (Angular Directive) | 29 | // Functions for creating a fixed header on a table (Angular Directive) |
30 | 30 | ||
31 | function setTableWidth(t) { | 31 | function setTableWidth(t) { |
32 | - var tHeaders, tdElement, colWidth, numCols, | 32 | + var tHeaders, tdElement, colWidth, numIcons, numNonIcons, |
33 | winWidth = fs.windowSize().width; | 33 | winWidth = fs.windowSize().width; |
34 | 34 | ||
35 | tHeaders = t.selectAll('th'); | 35 | tHeaders = t.selectAll('th'); |
36 | - numCols = tHeaders[0].length; | 36 | + numIcons = 0; |
37 | - colWidth = Math.floor(winWidth / numCols); | 37 | + numNonIcons = 0; |
38 | + | ||
39 | + // FIXME: This should observe custom-set width from the HTML | ||
38 | 40 | ||
39 | tHeaders.each(function(thElement, index) { | 41 | tHeaders.each(function(thElement, index) { |
40 | thElement = d3.select(this); | 42 | thElement = d3.select(this); |
43 | + if (thElement.classed('table-icon')) { | ||
44 | + numIcons = numIcons + 1; | ||
45 | + } else { | ||
46 | + numNonIcons = numNonIcons + 1; | ||
47 | + } | ||
48 | + }); | ||
41 | 49 | ||
50 | + colWidth = Math.floor((winWidth - (numIcons * tableIconTdSize)) / numNonIcons); | ||
51 | + | ||
52 | + tHeaders.each(function(thElement, index) { | ||
53 | + thElement = d3.select(this); | ||
42 | tdElement = t.select('td:nth-of-type(' + (index + 1) + ')'); | 54 | tdElement = t.select('td:nth-of-type(' + (index + 1) + ')'); |
43 | 55 | ||
44 | - if (tdElement.classed('table-icon')) { | 56 | + if (thElement.classed('table-icon')) { |
45 | thElement.style('width', tableIconTdSize + 'px'); | 57 | thElement.style('width', tableIconTdSize + 'px'); |
46 | tdElement.style('width', tableIconTdSize + 'px'); | 58 | tdElement.style('width', tableIconTdSize + 'px'); |
47 | } else { | 59 | } else { | ... | ... |
web/gui/src/main/webapp/app/view/app/app.css
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Host View -- CSS file | ||
19 | + */ | ||
20 | + | ||
21 | +#ov-app td { | ||
22 | +} |
1 | +<!-- app partial HTML --> | ||
2 | +<div id="ov-app"> | ||
3 | + <h2>Applications ({{ctrl.appData.length}} total)</h2> | ||
4 | + <table class="summary-list" | ||
5 | + onos-fixed-header | ||
6 | + onos-sortable-header | ||
7 | + sort-callback="sortCallback(requestParams)"> | ||
8 | + <thead> | ||
9 | + <tr> | ||
10 | + <th colId="state" class="table-icon" sortable></th> | ||
11 | + <th colId="id" sortable>App ID </th> | ||
12 | + <th colId="version" sortable>Version</th> | ||
13 | + <th colId="origin" sortable>Origin </th> | ||
14 | + <th colId="desc">Description </th> | ||
15 | + </tr> | ||
16 | + </thead> | ||
17 | + | ||
18 | + <tbody> | ||
19 | + <tr ng-repeat="app in ctrl.appData" | ||
20 | + ng-click="setSelected(app.id)" | ||
21 | + ng-class="{selected: app.id === selectedAppId}" | ||
22 | + ng-repeat-done> | ||
23 | + <td class="table-icon"> | ||
24 | + <div icon icon-id="{{app._iconid_state}}"></div> | ||
25 | + </td> | ||
26 | + <td>{{app.id}}</td> | ||
27 | + <td>{{app.version}}</td> | ||
28 | + <td>{{app.origin}}</td> | ||
29 | + <td>{{app.desc}}</td> | ||
30 | + </tr> | ||
31 | + </tbody> | ||
32 | + </table> | ||
33 | + | ||
34 | +</div> |
web/gui/src/main/webapp/app/view/app/app.js
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- App View Module | ||
19 | + */ | ||
20 | + | ||
21 | +(function () { | ||
22 | + 'use strict'; | ||
23 | + | ||
24 | + angular.module('ovApp', []) | ||
25 | + .controller('OvAppCtrl', | ||
26 | + ['$log', '$scope', '$location', 'FnService', 'WebSocketService', | ||
27 | + | ||
28 | + function ($log, $scope, $location, fs, wss) { | ||
29 | + var self = this; | ||
30 | + self.appData = []; | ||
31 | + | ||
32 | + $scope.responseCallback = function(data) { | ||
33 | + self.appData = data.applications; | ||
34 | + $scope.$apply(); | ||
35 | + }; | ||
36 | + | ||
37 | + $scope.sortCallback = function (requestParams) { | ||
38 | + wss.sendEvent('appDataRequest', requestParams); | ||
39 | + }; | ||
40 | + | ||
41 | + $scope.selectedAppId = null; | ||
42 | + $scope.setSelected = function (appId) { | ||
43 | + $scope.selectedAppId = appId; | ||
44 | + }; | ||
45 | + | ||
46 | + var handlers = { | ||
47 | + appDataResponse: $scope.responseCallback | ||
48 | + }; | ||
49 | + wss.bindHandlers(handlers); | ||
50 | + | ||
51 | + // Cleanup on destroyed scope | ||
52 | + $scope.$on('$destroy', function () { | ||
53 | + wss.unbindHandlers(handlers); | ||
54 | + }); | ||
55 | + | ||
56 | + $scope.sortCallback(); | ||
57 | + | ||
58 | + $log.log('OvAppCtrl has been created'); | ||
59 | + }]); | ||
60 | +}()); |
... | @@ -7,8 +7,8 @@ | ... | @@ -7,8 +7,8 @@ |
7 | sort-callback="sortCallback(requestParams)"> | 7 | sort-callback="sortCallback(requestParams)"> |
8 | <thead> | 8 | <thead> |
9 | <tr> | 9 | <tr> |
10 | - <th colId="available"></th> | 10 | + <th colId="available" class="table-icon" sortable></th> |
11 | - <th colId="type"></th> | 11 | + <th colId="type" class="table-icon" sortable></th> |
12 | <th colId="id" sortable>Device ID </th> | 12 | <th colId="id" sortable>Device ID </th> |
13 | <th colId="mfr" sortable>Vendor </th> | 13 | <th colId="mfr" sortable>Vendor </th> |
14 | <th colId="hw" sortable>H/W Version </th> | 14 | <th colId="hw" sortable>H/W Version </th> | ... | ... |
... | @@ -101,6 +101,7 @@ | ... | @@ -101,6 +101,7 @@ |
101 | <script src="app/view/topo/topoToolbar.js"></script> | 101 | <script src="app/view/topo/topoToolbar.js"></script> |
102 | <script src="app/view/device/device.js"></script> | 102 | <script src="app/view/device/device.js"></script> |
103 | <script src="app/view/host/host.js"></script> | 103 | <script src="app/view/host/host.js"></script> |
104 | + <script src="app/view/app/app.js"></script> | ||
104 | <script src="app/view/sample/sample.js"></script> | 105 | <script src="app/view/sample/sample.js"></script> |
105 | <!-- {INJECTED-JAVASCRIPT-END} --> | 106 | <!-- {INJECTED-JAVASCRIPT-END} --> |
106 | 107 | ||
... | @@ -110,6 +111,7 @@ | ... | @@ -110,6 +111,7 @@ |
110 | <link rel="stylesheet" href="app/view/topo/topo.css"> | 111 | <link rel="stylesheet" href="app/view/topo/topo.css"> |
111 | <link rel="stylesheet" href="app/view/device/device.css"> | 112 | <link rel="stylesheet" href="app/view/device/device.css"> |
112 | <link rel="stylesheet" href="app/view/host/host.css"> | 113 | <link rel="stylesheet" href="app/view/host/host.css"> |
114 | + <link rel="stylesheet" href="app/view/app/app.css"> | ||
113 | <link rel="stylesheet" href="app/view/sample/sample.css"> | 115 | <link rel="stylesheet" href="app/view/sample/sample.css"> |
114 | <!-- {INJECTED-STYLESHEETS-END} --> | 116 | <!-- {INJECTED-STYLESHEETS-END} --> |
115 | 117 | ... | ... |
-
Please register or login to post a comment