ONOS-3505 Skeletal project structure for driver-matrix UI app.
Change-Id: I257a5e1a58f7edb0b13ed8402a3c9032c82db6d1
Showing
10 changed files
with
552 additions
and
0 deletions
apps/drivermatrix/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2014 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-apps</artifactId> | ||
23 | + <version>1.4.0-SNAPSHOT</version> | ||
24 | + <relativePath>../pom.xml</relativePath> | ||
25 | + </parent> | ||
26 | + | ||
27 | + <artifactId>onos-app-drivermatrix</artifactId> | ||
28 | + <packaging>bundle</packaging> | ||
29 | + | ||
30 | + <description>Driver behaviour support matric</description> | ||
31 | + | ||
32 | + <properties> | ||
33 | + <onos.app.name>org.onosproject.drivermatrix</onos.app.name> | ||
34 | + </properties> | ||
35 | + | ||
36 | +</project> |
1 | +/* | ||
2 | + * Copyright 2014,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.drivermatrix; | ||
17 | + | ||
18 | +import com.google.common.collect.ImmutableList; | ||
19 | +import org.apache.felix.scr.annotations.Activate; | ||
20 | +import org.apache.felix.scr.annotations.Component; | ||
21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
22 | +import org.apache.felix.scr.annotations.Reference; | ||
23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
24 | +import org.onosproject.ui.UiExtension; | ||
25 | +import org.onosproject.ui.UiExtensionService; | ||
26 | +import org.onosproject.ui.UiMessageHandlerFactory; | ||
27 | +import org.onosproject.ui.UiView; | ||
28 | +import org.slf4j.Logger; | ||
29 | +import org.slf4j.LoggerFactory; | ||
30 | + | ||
31 | +import java.util.List; | ||
32 | + | ||
33 | +/** | ||
34 | + * Skeletal ONOS UI Table-View application component. | ||
35 | + */ | ||
36 | +@Component(immediate = true) | ||
37 | +public class DriverMatrixComponent { | ||
38 | + | ||
39 | + private static final String VIEW_ID = "driverMatrix"; | ||
40 | + private static final String VIEW_TEXT = "Driver Matrix"; | ||
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, VIEW_ID, VIEW_TEXT) | ||
50 | + ); | ||
51 | + | ||
52 | + // Factory for UI message handlers | ||
53 | + private final UiMessageHandlerFactory messageHandlerFactory = | ||
54 | + () -> ImmutableList.of( | ||
55 | + new DriverMatrixMessageHandler() | ||
56 | + ); | ||
57 | + | ||
58 | + // Application UI extension | ||
59 | + protected UiExtension extension = | ||
60 | + new UiExtension.Builder(getClass().getClassLoader(), uiViews) | ||
61 | + .resourcePath(VIEW_ID) | ||
62 | + .messageHandlerFactory(messageHandlerFactory) | ||
63 | + .build(); | ||
64 | + | ||
65 | + @Activate | ||
66 | + protected void activate() { | ||
67 | + uiExtensionService.register(extension); | ||
68 | + log.info("Started"); | ||
69 | + } | ||
70 | + | ||
71 | + @Deactivate | ||
72 | + protected void deactivate() { | ||
73 | + uiExtensionService.unregister(extension); | ||
74 | + log.info("Stopped"); | ||
75 | + } | ||
76 | + | ||
77 | +} |
apps/drivermatrix/src/main/java/org/onosproject/drivermatrix/DriverMatrixMessageHandler.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2014,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.drivermatrix; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import com.google.common.collect.ImmutableSet; | ||
20 | +import org.onosproject.ui.RequestHandler; | ||
21 | +import org.onosproject.ui.UiMessageHandler; | ||
22 | +import org.onosproject.ui.table.TableModel; | ||
23 | +import org.onosproject.ui.table.TableRequestHandler; | ||
24 | +import org.slf4j.Logger; | ||
25 | +import org.slf4j.LoggerFactory; | ||
26 | + | ||
27 | +import java.util.ArrayList; | ||
28 | +import java.util.Collection; | ||
29 | +import java.util.List; | ||
30 | + | ||
31 | +/** | ||
32 | + * Skeletal ONOS UI Table-View message handler. | ||
33 | + */ | ||
34 | +public class DriverMatrixMessageHandler extends UiMessageHandler { | ||
35 | + | ||
36 | + private static final String SAMPLE_TABLE_DATA_REQ = "driverMatrixDataRequest"; | ||
37 | + private static final String SAMPLE_TABLE_DATA_RESP = "driverMatrixDataResponse"; | ||
38 | + private static final String SAMPLE_TABLES = "driverMatrixs"; | ||
39 | + | ||
40 | + private static final String SAMPLE_TABLE_DETAIL_REQ = "driverMatrixDetailsRequest"; | ||
41 | + private static final String SAMPLE_TABLE_DETAIL_RESP = "driverMatrixDetailsResponse"; | ||
42 | + private static final String DETAILS = "details"; | ||
43 | + | ||
44 | + private static final String ID = "id"; | ||
45 | + private static final String LABEL = "label"; | ||
46 | + private static final String CODE = "code"; | ||
47 | + private static final String COMMENT = "comment"; | ||
48 | + private static final String RESULT = "result"; | ||
49 | + | ||
50 | + private static final String[] COLUMN_IDS = {ID, LABEL, CODE}; | ||
51 | + | ||
52 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
53 | + | ||
54 | + | ||
55 | + @Override | ||
56 | + protected Collection<RequestHandler> createRequestHandlers() { | ||
57 | + return ImmutableSet.of( | ||
58 | + new SampleTableDataRequestHandler(), | ||
59 | + new SampleTableDetailRequestHandler() | ||
60 | + ); | ||
61 | + } | ||
62 | + | ||
63 | + // handler for sample table requests | ||
64 | + private final class SampleTableDataRequestHandler extends TableRequestHandler { | ||
65 | + | ||
66 | + private SampleTableDataRequestHandler() { | ||
67 | + super(SAMPLE_TABLE_DATA_REQ, SAMPLE_TABLE_DATA_RESP, SAMPLE_TABLES); | ||
68 | + } | ||
69 | + | ||
70 | + // if necessary, override defaultColumnId() -- if it isn't "id" | ||
71 | + | ||
72 | + @Override | ||
73 | + protected String[] getColumnIds() { | ||
74 | + return COLUMN_IDS; | ||
75 | + } | ||
76 | + | ||
77 | + // if required, override createTableModel() to set column formatters / comparators | ||
78 | + | ||
79 | + @Override | ||
80 | + protected void populateTable(TableModel tm, ObjectNode payload) { | ||
81 | + // === NOTE: the table model supplied here will have been created | ||
82 | + // via a call to createTableModel(). To assign non-default | ||
83 | + // cell formatters or comparators to the table model, override | ||
84 | + // createTableModel() and set them there. | ||
85 | + | ||
86 | + // === retrieve table row items from some service... | ||
87 | + // SomeService ss = get(SomeService.class); | ||
88 | + // List<Item> items = ss.getItems() | ||
89 | + | ||
90 | + // fake data for demonstration purposes... | ||
91 | + List<Item> items = getItems(); | ||
92 | + for (Item item : items) { | ||
93 | + populateRow(tm.addRow(), item); | ||
94 | + } | ||
95 | + } | ||
96 | + | ||
97 | + private void populateRow(TableModel.Row row, Item item) { | ||
98 | + row.cell(ID, item.id()) | ||
99 | + .cell(LABEL, item.label()) | ||
100 | + .cell(CODE, item.code()); | ||
101 | + } | ||
102 | + } | ||
103 | + | ||
104 | + | ||
105 | + // handler for sample item details requests | ||
106 | + private final class SampleTableDetailRequestHandler extends RequestHandler { | ||
107 | + | ||
108 | + private SampleTableDetailRequestHandler() { | ||
109 | + super(SAMPLE_TABLE_DETAIL_REQ); | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public void process(long sid, ObjectNode payload) { | ||
114 | + String id = string(payload, ID, "(none)"); | ||
115 | + | ||
116 | + // SomeService ss = get(SomeService.class); | ||
117 | + // Item item = ss.getItemDetails(id) | ||
118 | + | ||
119 | + // fake data for demonstration purposes... | ||
120 | + Item item = getItem(id); | ||
121 | + | ||
122 | + ObjectNode rootNode = objectNode(); | ||
123 | + ObjectNode data = objectNode(); | ||
124 | + rootNode.set(DETAILS, data); | ||
125 | + | ||
126 | + if (item == null) { | ||
127 | + rootNode.put(RESULT, "Item with id '" + id + "' not found"); | ||
128 | + log.warn("attempted to get item detail for id '{}'", id); | ||
129 | + | ||
130 | + } else { | ||
131 | + rootNode.put(RESULT, "Found item with id '" + id + "'"); | ||
132 | + | ||
133 | + data.put(ID, item.id()); | ||
134 | + data.put(LABEL, item.label()); | ||
135 | + data.put(CODE, item.code()); | ||
136 | + data.put(COMMENT, "Some arbitrary comment"); | ||
137 | + } | ||
138 | + | ||
139 | + sendMessage(SAMPLE_TABLE_DETAIL_RESP, 0, rootNode); | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
143 | + | ||
144 | + // =================================================================== | ||
145 | + // NOTE: The code below this line is to create fake data for this | ||
146 | + // sample code. Normally you would use existing services to | ||
147 | + // provide real data. | ||
148 | + | ||
149 | + // Lookup a single item. | ||
150 | + private static Item getItem(String id) { | ||
151 | + // We realize this code is really inefficient, but | ||
152 | + // it suffices for our purposes of demonstration... | ||
153 | + for (Item item : getItems()) { | ||
154 | + if (item.id().equals(id)) { | ||
155 | + return item; | ||
156 | + } | ||
157 | + } | ||
158 | + return null; | ||
159 | + } | ||
160 | + | ||
161 | + // Produce a list of items. | ||
162 | + private static List<Item> getItems() { | ||
163 | + List<Item> items = new ArrayList<>(); | ||
164 | + items.add(new Item("item-1", "foo", 42)); | ||
165 | + items.add(new Item("item-2", "bar", 99)); | ||
166 | + items.add(new Item("item-3", "baz", 65)); | ||
167 | + return items; | ||
168 | + } | ||
169 | + | ||
170 | + // Simple model class to provide sample data | ||
171 | + private static class Item { | ||
172 | + private final String id; | ||
173 | + private final String label; | ||
174 | + private final int code; | ||
175 | + | ||
176 | + Item(String id, String label, int code) { | ||
177 | + this.id = id; | ||
178 | + this.label = label; | ||
179 | + this.code = code; | ||
180 | + } | ||
181 | + | ||
182 | + String id() { | ||
183 | + return id; | ||
184 | + } | ||
185 | + | ||
186 | + String label() { | ||
187 | + return label; | ||
188 | + } | ||
189 | + | ||
190 | + int code() { | ||
191 | + return code; | ||
192 | + } | ||
193 | + } | ||
194 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-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 | + * Driver support matrix app. | ||
19 | + */ | ||
20 | +package org.onosproject.drivermatrix; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* css for sample table view */ | ||
2 | + | ||
3 | +#ov-driver-matrix h2 { | ||
4 | + display: inline-block; | ||
5 | +} | ||
6 | + | ||
7 | +/* Panel Styling */ | ||
8 | +#ov-driver-matrix-item-details-panel.floatpanel { | ||
9 | + position: absolute; | ||
10 | + top: 115px; | ||
11 | +} | ||
12 | + | ||
13 | +.light #ov-driver-matrix-item-details-panel.floatpanel { | ||
14 | + background-color: rgb(229, 234, 237); | ||
15 | +} | ||
16 | +.dark #ov-driver-matrix-item-details-panel.floatpanel { | ||
17 | + background-color: #3A4042; | ||
18 | +} | ||
19 | + | ||
20 | +#ov-driver-matrix-item-details-panel h3 { | ||
21 | + margin: 0; | ||
22 | + font-size: large; | ||
23 | +} | ||
24 | + | ||
25 | +#ov-driver-matrix-item-details-panel h4 { | ||
26 | + margin: 0; | ||
27 | +} | ||
28 | + | ||
29 | +#ov-driver-matrix-item-details-panel td { | ||
30 | + padding: 5px; | ||
31 | +} | ||
32 | +#ov-driver-matrix-item-details-panel td.label { | ||
33 | + font-style: italic; | ||
34 | + opacity: 0.8; | ||
35 | +} |
1 | +<!-- partial HTML --> | ||
2 | +<div id="ov-driver-matrix"> | ||
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-driver-matrix-item-details-panel></ov-driver-matrix-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 = 'driverMatrixDetailsRequest', | ||
10 | + detailsResp = 'driverMatrixDetailsResponse', | ||
11 | + pName = 'ov-driver-matrix-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('ovDriverMatrix', []) | ||
48 | + .controller('OvDriverMatrixCtrl', | ||
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: 'driverMatrix', | ||
79 | + selCb: selCb | ||
80 | + }); | ||
81 | + | ||
82 | + // cleanup | ||
83 | + $scope.$on('$destroy', function () { | ||
84 | + wss.unbindHandlers(handlers); | ||
85 | + $log.log('OvDriverMatrixCtrl has been destroyed'); | ||
86 | + }); | ||
87 | + | ||
88 | + $log.log('OvDriverMatrixCtrl has been created'); | ||
89 | + }]) | ||
90 | + | ||
91 | + .directive('ovDriverMatrixItemDetailsPanel', ['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/driverMatrix/driverMatrix.css"> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<script src="app/view/driverMatrix/driverMatrix.js"></script> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -61,6 +61,7 @@ | ... | @@ -61,6 +61,7 @@ |
61 | <module>mlb</module> | 61 | <module>mlb</module> |
62 | <module>openstackswitching</module> | 62 | <module>openstackswitching</module> |
63 | <module>pathpainter</module> | 63 | <module>pathpainter</module> |
64 | + <module>drivermatrix</module> | ||
64 | <module>cpman</module> | 65 | <module>cpman</module> |
65 | </modules> | 66 | </modules> |
66 | 67 | ... | ... |
-
Please register or login to post a comment