Simon Hunt
Committed by Gerrit Code Review

ONOS-2851 - Web UI - create archetype for table view based app.

- added uitab overlay archetype.
- renamed stuff so ui apps can coexist.
- WIP ... custom view source needs to be pared down.

Change-Id: I196e10d69ddc231eb0bc9cc5923f29872035b4fd
Showing 22 changed files with 768 additions and 47 deletions
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
38 <module>bundle</module> 38 <module>bundle</module>
39 <module>cli</module> 39 <module>cli</module>
40 <module>ui</module> 40 <module>ui</module>
41 + <module>uitab</module>
41 </modules> 42 </modules>
42 43
43 <build> 44 <build>
......
...@@ -26,6 +26,6 @@ ...@@ -26,6 +26,6 @@
26 <artifactId>onos-ui-archetype</artifactId> 26 <artifactId>onos-ui-archetype</artifactId>
27 <packaging>maven-archetype</packaging> 27 <packaging>maven-archetype</packaging>
28 28
29 - <description>ONOS UI overlay archetype</description> 29 + <description>ONOS UI Custom-View overlay archetype</description>
30 30
31 </project> 31 </project>
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 <version>${version}</version> 22 <version>${version}</version>
23 <packaging>bundle</packaging> 23 <packaging>bundle</packaging>
24 24
25 - <description>ONOS OSGi UI bundle archetype</description> 25 + <description>ONOS OSGi UI Custom-View bundle archetype</description>
26 <url>http://onosproject.org</url> 26 <url>http://onosproject.org</url>
27 27
28 <properties> 28 <properties>
......
...@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; ...@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
34 import java.util.List; 34 import java.util.List;
35 35
36 /** 36 /**
37 - * Skeletal ONOS UI application component. 37 + * Skeletal ONOS UI Custom-View application component.
38 */ 38 */
39 @Component(immediate = true) 39 @Component(immediate = true)
40 public class AppUiComponent { 40 public class AppUiComponent {
...@@ -46,7 +46,7 @@ public class AppUiComponent { ...@@ -46,7 +46,7 @@ public class AppUiComponent {
46 46
47 // List of application views 47 // List of application views
48 private final List<UiView> uiViews = ImmutableList.of( 48 private final List<UiView> uiViews = ImmutableList.of(
49 - new UiView(UiView.Category.OTHER, "sample", "Sample") 49 + new UiView(UiView.Category.OTHER, "sampleCustom", "Sample Custom")
50 ); 50 );
51 51
52 // Factory for UI message handlers 52 // Factory for UI message handlers
......
...@@ -33,18 +33,17 @@ import java.util.Collection; ...@@ -33,18 +33,17 @@ import java.util.Collection;
33 import java.util.List; 33 import java.util.List;
34 34
35 /** 35 /**
36 - * Skeletal ONOS UI message handler. 36 + * Skeletal ONOS UI Custom-View message handler.
37 - * <p>
38 - * This example specifically supporting a "table" view.
39 */ 37 */
40 public class AppUiMessageHandler extends UiMessageHandler { 38 public class AppUiMessageHandler extends UiMessageHandler {
39 + // TODO: reduce the code down to just the custom view example
41 40
42 - private static final String SAMPLE_DATA_REQ = "sampleDataRequest"; 41 + private static final String SAMPLE_CUSTOM_DATA_REQ = "sampleCustomDataRequest";
43 - private static final String SAMPLE_DATA_RESP = "sampleDataResponse"; 42 + private static final String SAMPLE_CUSTOM_DATA_RESP = "sampleCustomDataResponse";
44 - private static final String SAMPLES = "samples"; 43 + private static final String SAMPLE_CUSTOMS = "sampleCustoms";
45 44
46 - private static final String SAMPLE_DETAIL_REQ = "sampleDetailsRequest"; 45 + private static final String SAMPLE_CUSTOM_DETAIL_REQ = "sampleCustomDetailsRequest";
47 - private static final String SAMPLE_DETAIL_RESP = "sampleDetailsResponse"; 46 + private static final String SAMPLE_CUSTOM_DETAIL_RESP = "sampleCustomDetailsResponse";
48 private static final String DETAILS = "details"; 47 private static final String DETAILS = "details";
49 48
50 private static final String ID = "id"; 49 private static final String ID = "id";
...@@ -61,20 +60,18 @@ public class AppUiMessageHandler extends UiMessageHandler { ...@@ -61,20 +60,18 @@ public class AppUiMessageHandler extends UiMessageHandler {
61 @Override 60 @Override
62 protected Collection<RequestHandler> createRequestHandlers() { 61 protected Collection<RequestHandler> createRequestHandlers() {
63 return ImmutableSet.of( 62 return ImmutableSet.of(
64 - new SampleDataRequestHandler(), 63 + new SampleCustomDataRequestHandler(),
65 - new SampleDetailRequestHandler() 64 + new SampleCustomDetailRequestHandler()
66 ); 65 );
67 } 66 }
68 67
69 // handler for sample table requests 68 // handler for sample table requests
70 - private final class SampleDataRequestHandler extends TableRequestHandler { 69 + private final class SampleCustomDataRequestHandler extends TableRequestHandler {
71 70
72 - private SampleDataRequestHandler() { 71 + private SampleCustomDataRequestHandler() {
73 - super(SAMPLE_DATA_REQ, SAMPLE_DATA_RESP, SAMPLES); 72 + super(SAMPLE_CUSTOM_DATA_REQ, SAMPLE_CUSTOM_DATA_RESP, SAMPLE_CUSTOMS);
74 } 73 }
75 74
76 - // if necessary, override defaultColumnId() -- if it isn't "id"
77 -
78 @Override 75 @Override
79 protected String[] getColumnIds() { 76 protected String[] getColumnIds() {
80 return COLUMN_IDS; 77 return COLUMN_IDS;
...@@ -106,10 +103,10 @@ public class AppUiMessageHandler extends UiMessageHandler { ...@@ -106,10 +103,10 @@ public class AppUiMessageHandler extends UiMessageHandler {
106 103
107 104
108 // handler for sample item details requests 105 // handler for sample item details requests
109 - private final class SampleDetailRequestHandler extends RequestHandler { 106 + private final class SampleCustomDetailRequestHandler extends RequestHandler {
110 107
111 - private SampleDetailRequestHandler() { 108 + private SampleCustomDetailRequestHandler() {
112 - super(SAMPLE_DETAIL_REQ); 109 + super(SAMPLE_CUSTOM_DETAIL_REQ);
113 } 110 }
114 111
115 @Override 112 @Override
...@@ -139,7 +136,7 @@ public class AppUiMessageHandler extends UiMessageHandler { ...@@ -139,7 +136,7 @@ public class AppUiMessageHandler extends UiMessageHandler {
139 data.put(COMMENT, "Some arbitrary comment"); 136 data.put(COMMENT, "Some arbitrary comment");
140 } 137 }
141 138
142 - sendMessage(SAMPLE_DETAIL_RESP, 0, rootNode); 139 + sendMessage(SAMPLE_CUSTOM_DETAIL_RESP, 0, rootNode);
143 } 140 }
144 } 141 }
145 142
......
...@@ -5,31 +5,31 @@ ...@@ -5,31 +5,31 @@
5 } 5 }
6 6
7 /* Panel Styling */ 7 /* Panel Styling */
8 -#item-details-panel.floatpanel { 8 +#ov-sample-custom-item-details-panel.floatpanel {
9 position: absolute; 9 position: absolute;
10 top: 115px; 10 top: 115px;
11 } 11 }
12 12
13 -.light #item-details-panel.floatpanel { 13 +.light #ov-sample-custom-item-details-panel.floatpanel {
14 background-color: rgb(229, 234, 237); 14 background-color: rgb(229, 234, 237);
15 } 15 }
16 -.dark #item-details-panel.floatpanel { 16 +.dark #ov-sample-custom-item-details-panel.floatpanel {
17 background-color: #3A4042; 17 background-color: #3A4042;
18 } 18 }
19 19
20 -#item-details-panel h3 { 20 +#ov-sample-custom-item-details-panel h3 {
21 margin: 0; 21 margin: 0;
22 font-size: large; 22 font-size: large;
23 } 23 }
24 24
25 -#item-details-panel h4 { 25 +#ov-sample-custom-item-details-panel h4 {
26 margin: 0; 26 margin: 0;
27 } 27 }
28 28
29 -#item-details-panel td { 29 +#ov-sample-custom-item-details-panel td {
30 padding: 5px; 30 padding: 5px;
31 } 31 }
32 -#item-details-panel td.label { 32 +#ov-sample-custom-item-details-panel td.label {
33 font-style: italic; 33 font-style: italic;
34 opacity: 0.8; 34 opacity: 0.8;
35 -}
...\ No newline at end of file ...\ No newline at end of file
35 +}
......
1 <!-- partial HTML --> 1 <!-- partial HTML -->
2 -<div id="ov-sample"> 2 +<div id="ov-sample-custom">
3 <div class="tabular-header"> 3 <div class="tabular-header">
4 <h2>Items ({{tableData.length}} total)</h2> 4 <h2>Items ({{tableData.length}} total)</h2>
5 <div class="ctrl-btns"> 5 <div class="ctrl-btns">
...@@ -42,5 +42,5 @@ ...@@ -42,5 +42,5 @@
42 42
43 </div> 43 </div>
44 44
45 - <item-details-panel></item-details-panel> 45 + <ov-sample-custom-item-details-panel></ov-sample-custom-item-details-panel>
46 </div> 46 </div>
......
1 -// js for sample app view 1 +// js for sample app custom view
2 (function () { 2 (function () {
3 'use strict'; 3 'use strict';
4 4
5 // injected refs 5 // injected refs
6 - var $log, $scope, fs, wss, ps; 6 + var $log, $scope, fs, wss;
7 7
8 // constants 8 // constants
9 - var detailsReq = 'sampleDetailsRequest', 9 + var detailsReq = 'sampleCustomDetailsRequest',
10 - detailsResp = 'sampleDetailsResponse', 10 + detailsResp = 'sampleCustomDetailsResponse',
11 - pName = 'item-details-panel', 11 + pName = 'ov-sample-custom-item-details-panel',
12 12
13 propOrder = ['id', 'label', 'code'], 13 propOrder = ['id', 'label', 'code'],
14 friendlyProps = ['Item ID', 'Item Label', 'Special Code']; 14 friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
...@@ -44,8 +44,8 @@ ...@@ -44,8 +44,8 @@
44 $scope.$apply(); 44 $scope.$apply();
45 } 45 }
46 46
47 - angular.module('ovSample', []) 47 + angular.module('ovSampleCustom', [])
48 - .controller('OvSampleCtrl', 48 + .controller('OvSampleCustomCtrl',
49 ['$log', '$scope', 'TableBuilderService', 49 ['$log', '$scope', 'TableBuilderService',
50 'FnService', 'WebSocketService', 50 'FnService', 'WebSocketService',
51 51
...@@ -75,24 +75,24 @@ ...@@ -75,24 +75,24 @@
75 // TableBuilderService creating a table for us 75 // TableBuilderService creating a table for us
76 tbs.buildTable({ 76 tbs.buildTable({
77 scope: $scope, 77 scope: $scope,
78 - tag: 'sample', 78 + tag: 'sampleCustom',
79 selCb: selCb 79 selCb: selCb
80 }); 80 });
81 81
82 // cleanup 82 // cleanup
83 $scope.$on('$destroy', function () { 83 $scope.$on('$destroy', function () {
84 wss.unbindHandlers(handlers); 84 wss.unbindHandlers(handlers);
85 + $log.log('OvSampleCustomCtrl has been destroyed');
85 }); 86 });
86 87
87 - $log.log('OvSampleCtrl has been created'); 88 + $log.log('OvSampleCustomCtrl has been created');
88 }]) 89 }])
89 90
90 - .directive('itemDetailsPanel', ['PanelService', 'KeyService', 91 + .directive('ovSampleCustomItemDetailsPanel', ['PanelService', 'KeyService',
91 - function (_ps_, ks) { 92 + function (ps, ks) {
92 return { 93 return {
93 restrict: 'E', 94 restrict: 'E',
94 link: function (scope, element, attrs) { 95 link: function (scope, element, attrs) {
95 - ps = _ps_;
96 // insert details panel with PanelService 96 // insert details panel with PanelService
97 // create the panel 97 // create the panel
98 var panel = ps.createPanel(pName, { 98 var panel = ps.createPanel(pName, {
...@@ -107,7 +107,9 @@ ...@@ -107,7 +107,9 @@
107 if (panel.isVisible()) { 107 if (panel.isVisible()) {
108 $scope.selId = null; 108 $scope.selId = null;
109 panel.hide(); 109 panel.hide();
110 + return true;
110 } 111 }
112 + return false;
111 } 113 }
112 114
113 // create key bindings to handle panel 115 // create key bindings to handle panel
......
1 -<link rel="stylesheet" href="app/view/sample/sample.css">
...\ No newline at end of file ...\ No newline at end of file
1 +<link rel="stylesheet" href="app/view/sampleCustom/sampleCustom.css">
...\ No newline at end of file ...\ No newline at end of file
......
1 -<script src="app/view/sample/sample.js"></script>
...\ No newline at end of file ...\ No newline at end of file
1 +<script src="app/view/sampleCustom/sampleCustom.js"></script>
...\ No newline at end of file ...\ No newline at end of file
......
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<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/xsd/maven-4.0.0.xsd">
18 + <modelVersion>4.0.0</modelVersion>
19 +
20 + <parent>
21 + <groupId>org.onosproject</groupId>
22 + <artifactId>onos-archetypes</artifactId>
23 + <version>1.4.0-SNAPSHOT</version>
24 + </parent>
25 +
26 + <artifactId>onos-uitab-archetype</artifactId>
27 + <packaging>maven-archetype</packaging>
28 +
29 + <description>ONOS UI Table-View overlay archetype</description>
30 +
31 +</project>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +
3 +<!--
4 + ~ Copyright 2015 Open Networking Laboratory
5 + ~
6 + ~ Licensed under the Apache License, Version 2.0 (the "License");
7 + ~ you may not use this file except in compliance with the License.
8 + ~ You may obtain a copy of the License at
9 + ~
10 + ~ http://www.apache.org/licenses/LICENSE-2.0
11 + ~
12 + ~ Unless required by applicable law or agreed to in writing, software
13 + ~ distributed under the License is distributed on an "AS IS" BASIS,
14 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 + ~ See the License for the specific language governing permissions and
16 + ~ limitations under the License.
17 + -->
18 +<archetype-descriptor
19 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
20 + name="onos-uitab" partial="true"
21 + xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
22 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
23 + <fileSets>
24 + <fileSet filtered="true" packaged="true" encoding="UTF-8">
25 + <directory>src/main/java</directory>
26 + <includes>
27 + <include>**/*.java</include>
28 + </includes>
29 + </fileSet>
30 + <fileSet filtered="true" packaged="false" encoding="UTF-8">
31 + <directory>src/main/resources</directory>
32 + <includes>
33 + <include>**/*.html</include>
34 + <include>**/*.js</include>
35 + <include>**/*.css</include>
36 + </includes>
37 + </fileSet>
38 + </fileSets>
39 +</archetype-descriptor>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +
3 +<!--
4 + ~ Copyright 2015 Open Networking Laboratory
5 + ~
6 + ~ Licensed under the Apache License, Version 2.0 (the "License");
7 + ~ you may not use this file except in compliance with the License.
8 + ~ You may obtain a copy of the License at
9 + ~
10 + ~ http://www.apache.org/licenses/LICENSE-2.0
11 + ~
12 + ~ Unless required by applicable law or agreed to in writing, software
13 + ~ distributed under the License is distributed on an "AS IS" BASIS,
14 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 + ~ See the License for the specific language governing permissions and
16 + ~ limitations under the License.
17 + -->
18 +<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/xsd/maven-4.0.0.xsd">
19 + <modelVersion>4.0.0</modelVersion>
20 +
21 + <groupId>${groupId}</groupId>
22 + <artifactId>${artifactId}</artifactId>
23 + <version>${version}</version>
24 + <packaging>bundle</packaging>
25 +
26 + <description>ONOS OSGi UI Table-View bundle archetype</description>
27 + <url>http://onosproject.org</url>
28 +
29 + <properties>
30 + <onos.version>1.4.0-SNAPSHOT</onos.version>
31 + <!-- Uncomment to generate ONOS app from this module.
32 + <onos.app.name>org.foo.app</onos.app.name>
33 + <onos.app.origin>Foo, Inc.</onos.app.origin>
34 + -->
35 + </properties>
36 +
37 + <dependencies>
38 + <dependency>
39 + <groupId>org.onosproject</groupId>
40 + <artifactId>onos-api</artifactId>
41 + <version>${onos.version}</version>
42 + </dependency>
43 +
44 + <dependency>
45 + <groupId>org.onosproject</groupId>
46 + <artifactId>onlab-osgi</artifactId>
47 + <version>${onos.version}</version>
48 + </dependency>
49 +
50 + <dependency>
51 + <groupId>junit</groupId>
52 + <artifactId>junit</artifactId>
53 + <version>4.11</version>
54 + <scope>test</scope>
55 + </dependency>
56 +
57 + <dependency>
58 + <groupId>org.onosproject</groupId>
59 + <artifactId>onos-api</artifactId>
60 + <version>${onos.version}</version>
61 + <scope>test</scope>
62 + <classifier>tests</classifier>
63 + </dependency>
64 +
65 + <dependency>
66 + <groupId>org.apache.felix</groupId>
67 + <artifactId>org.apache.felix.scr.annotations</artifactId>
68 + <version>1.9.8</version>
69 + <scope>provided</scope>
70 + </dependency>
71 + </dependencies>
72 +
73 + <build>
74 + <plugins>
75 + <plugin>
76 + <groupId>org.apache.felix</groupId>
77 + <artifactId>maven-bundle-plugin</artifactId>
78 + <version>2.5.3</version>
79 + <extensions>true</extensions>
80 + </plugin>
81 + <plugin>
82 + <groupId>org.apache.maven.plugins</groupId>
83 + <artifactId>maven-compiler-plugin</artifactId>
84 + <version>2.5.1</version>
85 + <configuration>
86 + <source>1.8</source>
87 + <target>1.8</target>
88 + </configuration>
89 + </plugin>
90 + <plugin>
91 + <groupId>org.apache.felix</groupId>
92 + <artifactId>maven-scr-plugin</artifactId>
93 + <version>1.20.0</version>
94 + <executions>
95 + <execution>
96 + <id>generate-scr-srcdescriptor</id>
97 + <goals>
98 + <goal>scr</goal>
99 + </goals>
100 + </execution>
101 + </executions>
102 + <configuration>
103 + <supportedProjectTypes>
104 + <supportedProjectType>bundle</supportedProjectType>
105 + <supportedProjectType>war</supportedProjectType>
106 + </supportedProjectTypes>
107 + </configuration>
108 + </plugin>
109 + <plugin>
110 + <groupId>org.onosproject</groupId>
111 + <artifactId>onos-maven-plugin</artifactId>
112 + <version>1.5</version>
113 + <executions>
114 + <execution>
115 + <id>cfg</id>
116 + <phase>generate-resources</phase>
117 + <goals>
118 + <goal>cfg</goal>
119 + </goals>
120 + </execution>
121 + <execution>
122 + <id>swagger</id>
123 + <phase>generate-sources</phase>
124 + <goals>
125 + <goal>swagger</goal>
126 + </goals>
127 + </execution>
128 + <execution>
129 + <id>app</id>
130 + <phase>package</phase>
131 + <goals>
132 + <goal>app</goal>
133 + </goals>
134 + </execution>
135 + </executions>
136 + </plugin>
137 + </plugins>
138 + </build>
139 +
140 +</project>
1 +#set( $symbol_pound = '#' )
2 +#set( $symbol_dollar = '$' )
3 +#set( $symbol_escape = '\' )
4 +/*
5 + * Copyright 2014,2015 Open Networking Laboratory
6 + *
7 + * Licensed under the Apache License, Version 2.0 (the "License");
8 + * you may not use this file except in compliance with the License.
9 + * You may obtain a copy of the License at
10 + *
11 + * http://www.apache.org/licenses/LICENSE-2.0
12 + *
13 + * Unless required by applicable law or agreed to in writing, software
14 + * distributed under the License is distributed on an "AS IS" BASIS,
15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 + * See the License for the specific language governing permissions and
17 + * limitations under the License.
18 + */
19 +package ${package};
20 +
21 +import com.google.common.collect.ImmutableList;
22 +import org.apache.felix.scr.annotations.Activate;
23 +import org.apache.felix.scr.annotations.Component;
24 +import org.apache.felix.scr.annotations.Deactivate;
25 +import org.apache.felix.scr.annotations.Reference;
26 +import org.apache.felix.scr.annotations.ReferenceCardinality;
27 +import org.onosproject.ui.UiExtension;
28 +import org.onosproject.ui.UiExtensionService;
29 +import org.onosproject.ui.UiMessageHandlerFactory;
30 +import org.onosproject.ui.UiView;
31 +import org.slf4j.Logger;
32 +import org.slf4j.LoggerFactory;
33 +
34 +import java.util.List;
35 +
36 +/**
37 + * Skeletal ONOS UI Table-View application component.
38 + */
39 +@Component(immediate = true)
40 +public class AppUiComponent {
41 +
42 + private final Logger log = LoggerFactory.getLogger(getClass());
43 +
44 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 + protected UiExtensionService uiExtensionService;
46 +
47 + // List of application views
48 + private final List<UiView> uiViews = ImmutableList.of(
49 + new UiView(UiView.Category.OTHER, "sampleTable", "Sample Table")
50 + );
51 +
52 + // Factory for UI message handlers
53 + private final UiMessageHandlerFactory messageHandlerFactory =
54 + () -> ImmutableList.of(
55 + new AppUiMessageHandler()
56 + );
57 +
58 + // Application UI extension
59 + protected UiExtension extension =
60 + new UiExtension.Builder(getClass().getClassLoader(), uiViews)
61 + .messageHandlerFactory(messageHandlerFactory)
62 + .build();
63 +
64 + @Activate
65 + protected void activate() {
66 + uiExtensionService.register(extension);
67 + log.info("Started");
68 + }
69 +
70 + @Deactivate
71 + protected void deactivate() {
72 + uiExtensionService.unregister(extension);
73 + log.info("Stopped");
74 + }
75 +
76 +}
1 +#set( $symbol_pound = '#' )
2 +#set( $symbol_dollar = '$' )
3 +#set( $symbol_escape = '\' )
4 +/*
5 + * Copyright 2014,2015 Open Networking Laboratory
6 + *
7 + * Licensed under the Apache License, Version 2.0 (the "License");
8 + * you may not use this file except in compliance with the License.
9 + * You may obtain a copy of the License at
10 + *
11 + * http://www.apache.org/licenses/LICENSE-2.0
12 + *
13 + * Unless required by applicable law or agreed to in writing, software
14 + * distributed under the License is distributed on an "AS IS" BASIS,
15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 + * See the License for the specific language governing permissions and
17 + * limitations under the License.
18 + */
19 +package ${package};
20 +
21 +import com.fasterxml.jackson.databind.node.ObjectNode;
22 +import com.google.common.collect.ImmutableSet;
23 +import org.onosproject.ui.RequestHandler;
24 +import org.onosproject.ui.UiMessageHandler;
25 +import org.onosproject.ui.table.TableModel;
26 +import org.onosproject.ui.table.TableRequestHandler;
27 +import org.slf4j.Logger;
28 +import org.slf4j.LoggerFactory;
29 +
30 +import java.lang.Override;
31 +import java.util.ArrayList;
32 +import java.util.Collection;
33 +import java.util.List;
34 +
35 +/**
36 + * Skeletal ONOS UI Table-View message handler.
37 + */
38 +public class AppUiMessageHandler extends UiMessageHandler {
39 +
40 + private static final String SAMPLE_TABLE_DATA_REQ = "sampleTableDataRequest";
41 + private static final String SAMPLE_TABLE_DATA_RESP = "sampleTableDataResponse";
42 + private static final String SAMPLE_TABLES = "sampleTables";
43 +
44 + private static final String SAMPLE_TABLE_DETAIL_REQ = "sampleTableDetailsRequest";
45 + private static final String SAMPLE_TABLE_DETAIL_RESP = "sampleTableDetailsResponse";
46 + private static final String DETAILS = "details";
47 +
48 + private static final String ID = "id";
49 + private static final String LABEL = "label";
50 + private static final String CODE = "code";
51 + private static final String COMMENT = "comment";
52 + private static final String RESULT = "result";
53 +
54 + private static final String[] COLUMN_IDS = { ID, LABEL, CODE };
55 +
56 + private final Logger log = LoggerFactory.getLogger(getClass());
57 +
58 +
59 + @Override
60 + protected Collection<RequestHandler> createRequestHandlers() {
61 + return ImmutableSet.of(
62 + new SampleTableDataRequestHandler(),
63 + new SampleTableDetailRequestHandler()
64 + );
65 + }
66 +
67 + // handler for sample table requests
68 + private final class SampleTableDataRequestHandler extends TableRequestHandler {
69 +
70 + private SampleTableDataRequestHandler() {
71 + super(SAMPLE_TABLE_DATA_REQ, SAMPLE_TABLE_DATA_RESP, SAMPLE_TABLES);
72 + }
73 +
74 + // if necessary, override defaultColumnId() -- if it isn't "id"
75 +
76 + @Override
77 + protected String[] getColumnIds() {
78 + return COLUMN_IDS;
79 + }
80 +
81 + // if required, override createTableModel() to set column formatters / comparators
82 +
83 + @Override
84 + protected void populateTable(TableModel tm, ObjectNode payload) {
85 + // === NOTE: the table model supplied here will have been created
86 + // via a call to createTableModel(). To assign non-default
87 + // cell formatters or comparators to the table model, override
88 + // createTableModel() and set them there.
89 +
90 + // === retrieve table row items from some service...
91 + // SomeService ss = get(SomeService.class);
92 + // List<Item> items = ss.getItems()
93 +
94 + // fake data for demonstration purposes...
95 + List<Item> items = getItems();
96 + for (Item item: items) {
97 + populateRow(tm.addRow(), item);
98 + }
99 + }
100 +
101 + private void populateRow(TableModel.Row row, Item item) {
102 + row.cell(ID, item.id())
103 + .cell(LABEL, item.label())
104 + .cell(CODE, item.code());
105 + }
106 + }
107 +
108 +
109 + // handler for sample item details requests
110 + private final class SampleTableDetailRequestHandler extends RequestHandler {
111 +
112 + private SampleTableDetailRequestHandler() {
113 + super(SAMPLE_TABLE_DETAIL_REQ);
114 + }
115 +
116 + @Override
117 + public void process(long sid, ObjectNode payload) {
118 + String id = string(payload, ID, "(none)");
119 +
120 + // SomeService ss = get(SomeService.class);
121 + // Item item = ss.getItemDetails(id)
122 +
123 + // fake data for demonstration purposes...
124 + Item item = getItem(id);
125 +
126 + ObjectNode rootNode = MAPPER.createObjectNode();
127 + ObjectNode data = MAPPER.createObjectNode();
128 + rootNode.set(DETAILS, data);
129 +
130 + if (item == null) {
131 + rootNode.put(RESULT, "Item with id '" + id + "' not found");
132 + log.warn("attempted to get item detail for id '{}'", id);
133 +
134 + } else {
135 + rootNode.put(RESULT, "Found item with id '" + id + "'");
136 +
137 + data.put(ID, item.id());
138 + data.put(LABEL, item.label());
139 + data.put(CODE, item.code());
140 + data.put(COMMENT, "Some arbitrary comment");
141 + }
142 +
143 + sendMessage(SAMPLE_TABLE_DETAIL_RESP, 0, rootNode);
144 + }
145 + }
146 +
147 +
148 + // ===================================================================
149 + // NOTE: The code below this line is to create fake data for this
150 + // sample code. Normally you would use existing services to
151 + // provide real data.
152 +
153 + // Lookup a single item.
154 + private static Item getItem(String id) {
155 + // We realize this code is really inefficient, but
156 + // it suffices for our purposes of demonstration...
157 + for (Item item : getItems()) {
158 + if (item.id().equals(id)) {
159 + return item;
160 + }
161 + }
162 + return null;
163 + }
164 +
165 + // Produce a list of items.
166 + private static List<Item> getItems() {
167 + List<Item> items = new ArrayList<>();
168 + items.add(new Item("item-1", "foo", 42));
169 + items.add(new Item("item-2", "bar", 99));
170 + items.add(new Item("item-3", "baz", 65));
171 + return items;
172 + }
173 +
174 + // Simple model class to provide sample data
175 + private static class Item {
176 + private final String id;
177 + private final String label;
178 + private final int code;
179 +
180 + Item(String id, String label, int code) {
181 + this.id = id;
182 + this.label = label;
183 + this.code = code;
184 + }
185 +
186 + String id() { return id; }
187 + String label() { return label; }
188 + int code() { return code; }
189 + }
190 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/* css for sample app view */
2 +
3 +#ov-sample h2 {
4 + display: inline-block;
5 +}
6 +
7 +/* Panel Styling */
8 +#ov-sample-table-item-details-panel.floatpanel {
9 + position: absolute;
10 + top: 115px;
11 +}
12 +
13 +.light #ov-sample-table-item-details-panel.floatpanel {
14 + background-color: rgb(229, 234, 237);
15 +}
16 +.dark #ov-sample-table-item-details-panel.floatpanel {
17 + background-color: #3A4042;
18 +}
19 +
20 +#ov-sample-table-item-details-panel h3 {
21 + margin: 0;
22 + font-size: large;
23 +}
24 +
25 +#ov-sample-table-item-details-panel h4 {
26 + margin: 0;
27 +}
28 +
29 +#ov-sample-table-item-details-panel td {
30 + padding: 5px;
31 +}
32 +#ov-sample-table-item-details-panel td.label {
33 + font-style: italic;
34 + opacity: 0.8;
35 +}
1 +<!-- partial HTML -->
2 +<div id="ov-sample-table">
3 + <div class="tabular-header">
4 + <h2>Items ({{tableData.length}} total)</h2>
5 + <div class="ctrl-btns">
6 + <div class="refresh" ng-class="{active: autoRefresh}"
7 + icon icon-id="refresh" icon-size="36"
8 + tooltip tt-msg="autoRefreshTip"
9 + ng-click="toggleRefresh()"></div>
10 + </div>
11 + </div>
12 +
13 + <div class="summary-list" onos-table-resize>
14 +
15 + <div class="table-header" onos-sortable-header>
16 + <table>
17 + <tr>
18 + <td colId="id" sortable>Item ID </td>
19 + <td colId="label" sortable>Label </td>
20 + <td colId="code" sortable>Code </td>
21 + </tr>
22 + </table>
23 + </div>
24 +
25 + <div class="table-body">
26 + <table>
27 + <tr ng-if="!tableData.length" class="no-data">
28 + <td colspan="3">
29 + No Items found
30 + </td>
31 + </tr>
32 +
33 + <tr ng-repeat="item in tableData track by $index"
34 + ng-click="selectCallback($event, item)"
35 + ng-class="{selected: item.id === selId}">
36 + <td>{{item.id}}</td>
37 + <td>{{item.label}}</td>
38 + <td>{{item.code}}</td>
39 + </tr>
40 + </table>
41 + </div>
42 +
43 + </div>
44 +
45 + <ov-sample-table-item-details-panel></ov-sample-table-item-details-panel>
46 +</div>
1 +// js for sample app table view
2 +(function () {
3 + 'use strict';
4 +
5 + // injected refs
6 + var $log, $scope, fs, wss;
7 +
8 + // constants
9 + var detailsReq = 'sampleTableDetailsRequest',
10 + detailsResp = 'sampleTableDetailsResponse',
11 + pName = 'ov-sample-table-item-details-panel',
12 +
13 + propOrder = ['id', 'label', 'code'],
14 + friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
15 +
16 +
17 + function addProp(tbody, index, value) {
18 + var tr = tbody.append('tr');
19 +
20 + function addCell(cls, txt) {
21 + tr.append('td').attr('class', cls).html(txt);
22 + }
23 + addCell('label', friendlyProps[index] + ' :');
24 + addCell('value', value);
25 + }
26 +
27 + function populatePanel(panel) {
28 + var title = panel.append('h3'),
29 + tbody = panel.append('table').append('tbody');
30 +
31 + title.text('Item Details');
32 +
33 + propOrder.forEach(function (prop, i) {
34 + addProp(tbody, i, $scope.panelDetails[prop]);
35 + });
36 +
37 + panel.append('hr');
38 + panel.append('h4').text('Comments');
39 + panel.append('p').text($scope.panelDetails.comment);
40 + }
41 +
42 + function respDetailsCb(data) {
43 + $scope.panelDetails = data.details;
44 + $scope.$apply();
45 + }
46 +
47 + angular.module('ovSampleTable', [])
48 + .controller('OvSampleTableCtrl',
49 + ['$log', '$scope', 'TableBuilderService',
50 + 'FnService', 'WebSocketService',
51 +
52 + function (_$log_, _$scope_, tbs, _fs_, _wss_) {
53 + $log = _$log_;
54 + $scope = _$scope_;
55 + fs = _fs_;
56 + wss = _wss_;
57 +
58 + var handlers = {};
59 + $scope.panelDetails = {};
60 +
61 + // details response handler
62 + handlers[detailsResp] = respDetailsCb;
63 + wss.bindHandlers(handlers);
64 +
65 + // custom selection callback
66 + function selCb($event, row) {
67 + if ($scope.selId) {
68 + wss.sendEvent(detailsReq, { id: row.id });
69 + } else {
70 + $scope.hidePanel();
71 + }
72 + $log.debug('Got a click on:', row);
73 + }
74 +
75 + // TableBuilderService creating a table for us
76 + tbs.buildTable({
77 + scope: $scope,
78 + tag: 'sampleTable',
79 + selCb: selCb
80 + });
81 +
82 + // cleanup
83 + $scope.$on('$destroy', function () {
84 + wss.unbindHandlers(handlers);
85 + $log.log('OvSampleTableCtrl has been destroyed');
86 + });
87 +
88 + $log.log('OvSampleTableCtrl has been created');
89 + }])
90 +
91 + .directive('ovSampleTableItemDetailsPanel', ['PanelService', 'KeyService',
92 + function (ps, ks) {
93 + return {
94 + restrict: 'E',
95 + link: function (scope, element, attrs) {
96 + // insert details panel with PanelService
97 + // create the panel
98 + var panel = ps.createPanel(pName, {
99 + width: 200,
100 + margin: 20,
101 + hideMargin: 0
102 + });
103 + panel.hide();
104 + scope.hidePanel = function () { panel.hide(); };
105 +
106 + function closePanel() {
107 + if (panel.isVisible()) {
108 + $scope.selId = null;
109 + panel.hide();
110 + return true;
111 + }
112 + return false;
113 + }
114 +
115 + // create key bindings to handle panel
116 + ks.keyBindings({
117 + esc: [closePanel, 'Close the details panel'],
118 + _helpFormat: ['esc']
119 + });
120 + ks.gestureNotes([
121 + ['click', 'Select a row to show item details']
122 + ]);
123 +
124 + // update the panel's contents when the data is changed
125 + scope.$watch('panelDetails', function () {
126 + if (!fs.isEmptyObject(scope.panelDetails)) {
127 + panel.empty();
128 + populatePanel(panel);
129 + panel.show();
130 + }
131 + });
132 +
133 + // cleanup on destroyed scope
134 + scope.$on('$destroy', function () {
135 + ks.unbindKeys();
136 + ps.destroyPanel(pName);
137 + });
138 + }
139 + };
140 + }]);
141 +}());
1 +<link rel="stylesheet" href="app/view/sampleTable/sampleTable.css">
...\ No newline at end of file ...\ No newline at end of file
1 +<script src="app/view/sampleTable/sampleTable.js"></script>
...\ No newline at end of file ...\ No newline at end of file
1 +#
2 +# Copyright 2014 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 +#Thu Dec 04 09:24:50 PST 2014
18 +package=it.pkg
19 +version=0.1-SNAPSHOT
20 +groupId=archetype.it
21 +artifactId=basic