Committed by
Gerrit Code Review
ONOS-2325 - GUI -- Table View rows now flash yellow when their information updat…
…es. Minor device details panel bug fix. Change-Id: I78eb0f90af00ce4484255d7e9e0c3c8a10a0eda7
Showing
18 changed files
with
183 additions
and
22 deletions
... | @@ -172,6 +172,32 @@ | ... | @@ -172,6 +172,32 @@ |
172 | return true; | 172 | return true; |
173 | } | 173 | } |
174 | 174 | ||
175 | + // returns true if the two objects have all the same properties | ||
176 | + function sameObjProps(obj1, obj2) { | ||
177 | + var key; | ||
178 | + for (key in obj1) { | ||
179 | + if (obj1.hasOwnProperty(key)) { | ||
180 | + if (!(obj1[key] === obj2[key])) { | ||
181 | + return false; | ||
182 | + } | ||
183 | + } | ||
184 | + } | ||
185 | + return true; | ||
186 | + } | ||
187 | + | ||
188 | + // returns true if the array contains the object | ||
189 | + // does NOT use strict object reference equality, | ||
190 | + // instead checks each property individually for equality | ||
191 | + function containsObj(arr, obj) { | ||
192 | + var i; | ||
193 | + for (i = 0; i < arr.length; i++) { | ||
194 | + if (sameObjProps(arr[i], obj)) { | ||
195 | + return true; | ||
196 | + } | ||
197 | + } | ||
198 | + return false; | ||
199 | + } | ||
200 | + | ||
175 | // return the given string with the first character capitalized. | 201 | // return the given string with the first character capitalized. |
176 | function cap(s) { | 202 | function cap(s) { |
177 | return s.toLowerCase().replace(/^[a-z]/, function (m) { | 203 | return s.toLowerCase().replace(/^[a-z]/, function (m) { |
... | @@ -227,6 +253,8 @@ | ... | @@ -227,6 +253,8 @@ |
227 | inArray: inArray, | 253 | inArray: inArray, |
228 | removeFromArray: removeFromArray, | 254 | removeFromArray: removeFromArray, |
229 | isEmptyObject: isEmptyObject, | 255 | isEmptyObject: isEmptyObject, |
256 | + sameObjProps: sameObjProps, | ||
257 | + containsObj: containsObj, | ||
230 | cap: cap, | 258 | cap: cap, |
231 | noPx: noPx, | 259 | noPx: noPx, |
232 | noPxStyle: noPxStyle, | 260 | noPxStyle: noPxStyle, | ... | ... |
... | @@ -63,6 +63,17 @@ div.summary-list tr.no-data td { | ... | @@ -63,6 +63,17 @@ div.summary-list tr.no-data td { |
63 | background-color: #304860; | 63 | background-color: #304860; |
64 | } | 64 | } |
65 | 65 | ||
66 | +/* highlighting */ | ||
67 | +div.summary-list tr { | ||
68 | + transition: background-color 500ms; | ||
69 | +} | ||
70 | +.light div.summary-list tr.data-change { | ||
71 | + background-color: #FDFFDC; | ||
72 | +} | ||
73 | +.dark div.summary-list tr.data-change { | ||
74 | + background-color: #5A5600; | ||
75 | +} | ||
76 | + | ||
66 | div.summary-list td { | 77 | div.summary-list td { |
67 | padding: 6px; | 78 | padding: 6px; |
68 | text-align: left; | 79 | text-align: left; | ... | ... |
... | @@ -26,6 +26,7 @@ | ... | @@ -26,6 +26,7 @@ |
26 | // constants | 26 | // constants |
27 | var tableIconTdSize = 33, | 27 | var tableIconTdSize = 33, |
28 | pdg = 22, | 28 | pdg = 22, |
29 | + flashTime = 2000, | ||
29 | colWidth = 'col-width', | 30 | colWidth = 'col-width', |
30 | tableIcon = 'table-icon', | 31 | tableIcon = 'table-icon', |
31 | asc = 'asc', | 32 | asc = 'asc', |
... | @@ -208,7 +209,46 @@ | ... | @@ -208,7 +209,46 @@ |
208 | scope.$on('$destroy', function () { | 209 | scope.$on('$destroy', function () { |
209 | resetSort(); | 210 | resetSort(); |
210 | }); | 211 | }); |
211 | - } | 212 | + }; |
213 | + }]) | ||
214 | + | ||
215 | + .directive('onosFlashChanges', ['$log', '$parse', '$timeout', | ||
216 | + function ($log, $parse, $timeout) { | ||
217 | + return function (scope, element, attrs) { | ||
218 | + var rowData = $parse(attrs.row)(scope), | ||
219 | + id = attrs.rowId, | ||
220 | + tr = d3.select(element[0]), | ||
221 | + multiRows = d3.selectAll('.multi-row'), | ||
222 | + promise; | ||
223 | + | ||
224 | + scope.$watchCollection('changedData', function (newData) { | ||
225 | + angular.forEach(newData, function (item) { | ||
226 | + function classMultiRows(b) { | ||
227 | + if (!multiRows.empty()) { | ||
228 | + multiRows.each(function () { | ||
229 | + d3.select(this).classed('data-change', b); | ||
230 | + }); | ||
231 | + } | ||
232 | + } | ||
233 | + | ||
234 | + if (rowData[id] === item[id]) { | ||
235 | + tr.classed('data-change', true); | ||
236 | + classMultiRows(true); | ||
237 | + | ||
238 | + promise = $timeout(function () { | ||
239 | + tr.classed('data-change', false); | ||
240 | + classMultiRows(false); | ||
241 | + }, flashTime); | ||
242 | + } | ||
243 | + | ||
244 | + }); | ||
245 | + }); | ||
246 | + scope.$on('$destroy', function () { | ||
247 | + if (promise) { | ||
248 | + $timeout.cancel(promise); | ||
249 | + } | ||
250 | + }); | ||
251 | + }; | ||
212 | }]); | 252 | }]); |
213 | 253 | ||
214 | }()); | 254 | }()); | ... | ... |
... | @@ -30,7 +30,8 @@ | ... | @@ -30,7 +30,8 @@ |
30 | // { | 30 | // { |
31 | // scope: $scope, <- controller scope | 31 | // scope: $scope, <- controller scope |
32 | // tag: 'device', <- table identifier | 32 | // tag: 'device', <- table identifier |
33 | - // selCb: selCb <- row selection callback (optional) | 33 | + // selCb: selCb, <- row selection callback (optional) |
34 | + // respCb: respCb, <- websocket response callback (optional) | ||
34 | // query: params <- query parameters in URL (optional) | 35 | // query: params <- query parameters in URL (optional) |
35 | // } | 36 | // } |
36 | // Note: selCb() is passed the row data model of the selected row, | 37 | // Note: selCb() is passed the row data model of the selected row, |
... | @@ -45,31 +46,54 @@ | ... | @@ -45,31 +46,54 @@ |
45 | resp = o.tag + 'DataResponse', | 46 | resp = o.tag + 'DataResponse', |
46 | onSel = fs.isF(o.selCb), | 47 | onSel = fs.isF(o.selCb), |
47 | onResp = fs.isF(o.respCb), | 48 | onResp = fs.isF(o.respCb), |
49 | + oldTableData = [], | ||
48 | promise; | 50 | promise; |
49 | 51 | ||
50 | o.scope.tableData = []; | 52 | o.scope.tableData = []; |
53 | + o.scope.changedData = []; | ||
51 | o.scope.sortParams = {}; | 54 | o.scope.sortParams = {}; |
52 | o.scope.autoRefresh = true; | 55 | o.scope.autoRefresh = true; |
53 | o.scope.autoRefreshTip = 'Toggle auto refresh'; | 56 | o.scope.autoRefreshTip = 'Toggle auto refresh'; |
54 | 57 | ||
58 | + // === websocket functions -------------------- | ||
59 | + // response | ||
55 | function respCb(data) { | 60 | function respCb(data) { |
56 | o.scope.tableData = data[root]; | 61 | o.scope.tableData = data[root]; |
57 | onResp && onResp(); | 62 | onResp && onResp(); |
58 | o.scope.$apply(); | 63 | o.scope.$apply(); |
64 | + | ||
65 | + // checks if data changed for row flashing | ||
66 | + if (!angular.equals(o.scope.tableData, oldTableData)) { | ||
67 | + o.scope.changedData = []; | ||
68 | + // only flash the row if the data already exists | ||
69 | + if (oldTableData.length) { | ||
70 | + angular.forEach(o.scope.tableData, function (item) { | ||
71 | + if (!fs.containsObj(oldTableData, item)) { | ||
72 | + o.scope.changedData.push(item); | ||
73 | + } | ||
74 | + }); | ||
75 | + } | ||
76 | + angular.copy(o.scope.tableData, oldTableData); | ||
77 | + } | ||
59 | } | 78 | } |
79 | + handlers[resp] = respCb; | ||
80 | + wss.bindHandlers(handlers); | ||
60 | 81 | ||
82 | + // request | ||
61 | function sortCb(params) { | 83 | function sortCb(params) { |
62 | var p = angular.extend({}, params, o.query); | 84 | var p = angular.extend({}, params, o.query); |
63 | wss.sendEvent(req, p); | 85 | wss.sendEvent(req, p); |
64 | } | 86 | } |
65 | o.scope.sortCallback = sortCb; | 87 | o.scope.sortCallback = sortCb; |
66 | 88 | ||
89 | + // === selecting a row functions ---------------- | ||
67 | function selCb($event, selRow) { | 90 | function selCb($event, selRow) { |
68 | o.scope.selId = (o.scope.selId === selRow.id) ? null : selRow.id; | 91 | o.scope.selId = (o.scope.selId === selRow.id) ? null : selRow.id; |
69 | onSel && onSel($event, selRow); | 92 | onSel && onSel($event, selRow); |
70 | } | 93 | } |
71 | o.scope.selectCallback = selCb; | 94 | o.scope.selectCallback = selCb; |
72 | 95 | ||
96 | + // === autoRefresh functions ------------------ | ||
73 | function startRefresh() { | 97 | function startRefresh() { |
74 | promise = $interval(function () { | 98 | promise = $interval(function () { |
75 | if (fs.debugOn('widget')) { | 99 | if (fs.debugOn('widget')) { |
... | @@ -92,10 +116,7 @@ | ... | @@ -92,10 +116,7 @@ |
92 | } | 116 | } |
93 | o.scope.toggleRefresh = toggleRefresh; | 117 | o.scope.toggleRefresh = toggleRefresh; |
94 | 118 | ||
95 | - handlers[resp] = respCb; | 119 | + // === Cleanup on destroyed scope ----------------- |
96 | - wss.bindHandlers(handlers); | ||
97 | - | ||
98 | - // Cleanup on destroyed scope | ||
99 | o.scope.$on('$destroy', function () { | 120 | o.scope.$on('$destroy', function () { |
100 | wss.unbindHandlers(handlers); | 121 | wss.unbindHandlers(handlers); |
101 | stopRefresh(); | 122 | stopRefresh(); | ... | ... |
... | @@ -60,7 +60,8 @@ | ... | @@ -60,7 +60,8 @@ |
60 | 60 | ||
61 | <tr ng-repeat="app in tableData track by $index" | 61 | <tr ng-repeat="app in tableData track by $index" |
62 | ng-click="selectCallback($event, app)" | 62 | ng-click="selectCallback($event, app)" |
63 | - ng-class="{selected: app.id === selId}"> | 63 | + ng-class="{selected: app.id === selId}" |
64 | + onos-flash-changes row="{{app}}" row-id="id"> | ||
64 | <td class="table-icon"> | 65 | <td class="table-icon"> |
65 | <div icon icon-id="{{app._iconid_state}}"></div> | 66 | <div icon icon-id="{{app._iconid_state}}"></div> |
66 | </td> | 67 | </td> | ... | ... |
... | @@ -48,7 +48,8 @@ | ... | @@ -48,7 +48,8 @@ |
48 | </td> | 48 | </td> |
49 | </tr> | 49 | </tr> |
50 | 50 | ||
51 | - <tr ng-repeat="node in tableData track by $index"> | 51 | + <tr ng-repeat="node in tableData track by $index" |
52 | + onos-flash-changes row="{{node}}" row-id="id"> | ||
52 | <td class="table-icon"> | 53 | <td class="table-icon"> |
53 | <div icon icon-id="{{node._iconid_state}}"></div> | 54 | <div icon icon-id="{{node._iconid_state}}"></div> |
54 | </td> | 55 | </td> | ... | ... |
... | @@ -54,7 +54,8 @@ | ... | @@ -54,7 +54,8 @@ |
54 | 54 | ||
55 | <tr ng-repeat="dev in tableData track by $index" | 55 | <tr ng-repeat="dev in tableData track by $index" |
56 | ng-click="selectCallback($event, dev)" | 56 | ng-click="selectCallback($event, dev)" |
57 | - ng-class="{selected: dev.id === selId}"> | 57 | + ng-class="{selected: dev.id === selId}" |
58 | + onos-flash-changes row="{{dev}}" row-id="id"> | ||
58 | <td class="table-icon"> | 59 | <td class="table-icon"> |
59 | <div icon icon-id="{{dev._iconid_available}}"></div> | 60 | <div icon icon-id="{{dev._iconid_available}}"></div> |
60 | </td> | 61 | </td> | ... | ... |
... | @@ -250,6 +250,7 @@ | ... | @@ -250,6 +250,7 @@ |
250 | .directive('deviceDetailsPanel', ['$rootScope', '$window', | 250 | .directive('deviceDetailsPanel', ['$rootScope', '$window', |
251 | function ($rootScope, $window) { | 251 | function ($rootScope, $window) { |
252 | return function (scope) { | 252 | return function (scope) { |
253 | + var unbindWatch; | ||
253 | 254 | ||
254 | function heightCalc() { | 255 | function heightCalc() { |
255 | pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height') | 256 | pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height') |
... | @@ -268,7 +269,7 @@ | ... | @@ -268,7 +269,7 @@ |
268 | } | 269 | } |
269 | }); | 270 | }); |
270 | 271 | ||
271 | - $rootScope.$watchCollection( | 272 | + unbindWatch = $rootScope.$watchCollection( |
272 | function () { | 273 | function () { |
273 | return { | 274 | return { |
274 | h: $window.innerHeight, | 275 | h: $window.innerHeight, |
... | @@ -283,6 +284,7 @@ | ... | @@ -283,6 +284,7 @@ |
283 | ); | 284 | ); |
284 | 285 | ||
285 | scope.$on('$destroy', function () { | 286 | scope.$on('$destroy', function () { |
287 | + unbindWatch(); | ||
286 | ps.destroyPanel(pName); | 288 | ps.destroyPanel(pName); |
287 | }); | 289 | }); |
288 | }; | 290 | }; | ... | ... |
... | @@ -61,6 +61,24 @@ | ... | @@ -61,6 +61,24 @@ |
61 | background-color: #333; | 61 | background-color: #333; |
62 | } | 62 | } |
63 | 63 | ||
64 | +/* highlighted color */ | ||
65 | +.light #ov-flow tr:nth-child(6n + 1).data-change, | ||
66 | +.light #ov-flow tr:nth-child(6n + 2).data-change, | ||
67 | +.light #ov-flow tr:nth-child(6n + 3).data-change, | ||
68 | +.light #ov-flow tr:nth-child(6n + 4).data-change, | ||
69 | +.light #ov-flow tr:nth-child(6n + 5).data-change, | ||
70 | +.light #ov-flow tr:nth-child(6n).data-change { | ||
71 | + background-color: #FDFFDC; | ||
72 | +} | ||
73 | +.dark #ov-flow tr:nth-child(6n + 1).data-change, | ||
74 | +.dark #ov-flow tr:nth-child(6n + 2).data-change, | ||
75 | +.dark #ov-flow tr:nth-child(6n + 3).data-change, | ||
76 | +.dark #ov-flow tr:nth-child(6n + 4).data-change, | ||
77 | +.dark #ov-flow tr:nth-child(6n + 5).data-change, | ||
78 | +.dark #ov-flow tr:nth-child(6n).data-change { | ||
79 | + background-color: #5A5600; | ||
80 | +} | ||
81 | + | ||
64 | #ov-flow td.selector, | 82 | #ov-flow td.selector, |
65 | #ov-flow td.treatment { | 83 | #ov-flow td.treatment { |
66 | padding-left: 36px; | 84 | padding-left: 36px; | ... | ... |
... | @@ -55,7 +55,8 @@ | ... | @@ -55,7 +55,8 @@ |
55 | </td> | 55 | </td> |
56 | </tr> | 56 | </tr> |
57 | 57 | ||
58 | - <tr ng-repeat-start="flow in tableData track by $index"> | 58 | + <tr ng-repeat-start="flow in tableData track by $index" |
59 | + onos-flash-changes row="{{flow}}" row-id="id"> | ||
59 | <td>{{flow.id}}</td> | 60 | <td>{{flow.id}}</td> |
60 | <td>{{flow.appId}}</td> | 61 | <td>{{flow.appId}}</td> |
61 | <td>{{flow.groupId}}</td> | 62 | <td>{{flow.groupId}}</td> |
... | @@ -67,10 +68,10 @@ | ... | @@ -67,10 +68,10 @@ |
67 | <td>{{flow.packets}}</td> | 68 | <td>{{flow.packets}}</td> |
68 | <td>{{flow.bytes}}</td> | 69 | <td>{{flow.bytes}}</td> |
69 | </tr> | 70 | </tr> |
70 | - <tr> | 71 | + <tr class="multi-row"> |
71 | <td class="selector" colspan="10">{{flow.selector}}</td> | 72 | <td class="selector" colspan="10">{{flow.selector}}</td> |
72 | </tr> | 73 | </tr> |
73 | - <tr ng-repeat-end> | 74 | + <tr class="multi-row" ng-repeat-end> |
74 | <td class="treatment" colspan="10">{{flow.treatment}}</td> | 75 | <td class="treatment" colspan="10">{{flow.treatment}}</td> |
75 | </tr> | 76 | </tr> |
76 | </table> | 77 | </table> | ... | ... |
... | @@ -57,6 +57,20 @@ | ... | @@ -57,6 +57,20 @@ |
57 | background-color: #333; | 57 | background-color: #333; |
58 | } | 58 | } |
59 | 59 | ||
60 | +/* highlighted color */ | ||
61 | +.light #ov-group tr:nth-child(4n + 1).data-change, | ||
62 | +.light #ov-group tr:nth-child(4n + 2).data-change, | ||
63 | +.light #ov-group tr:nth-child(4n + 3).data-change, | ||
64 | +.light #ov-group tr:nth-child(4n).data-change { | ||
65 | + background-color: #FDFFDC; | ||
66 | +} | ||
67 | +.dark #ov-group tr:nth-child(4n + 1).data-change, | ||
68 | +.dark #ov-group tr:nth-child(4n + 2).data-change, | ||
69 | +.dark #ov-group tr:nth-child(4n + 3).data-change, | ||
70 | +.dark #ov-group tr:nth-child(4n).data-change { | ||
71 | + background-color: #5A5600; | ||
72 | +} | ||
73 | + | ||
60 | #ov-group td.buckets { | 74 | #ov-group td.buckets { |
61 | padding-left: 36px; | 75 | padding-left: 36px; |
62 | opacity: 0.65; | 76 | opacity: 0.65; | ... | ... |
... | @@ -67,7 +67,8 @@ | ... | @@ -67,7 +67,8 @@ |
67 | </td> | 67 | </td> |
68 | </tr> | 68 | </tr> |
69 | 69 | ||
70 | - <tr ng-repeat-start="group in tableData track by $index"> | 70 | + <tr ng-repeat-start="group in tableData track by $index" |
71 | + onos-flash-changes row="{{group}}" row-id="id"> | ||
71 | <td>{{group.id}}</td> | 72 | <td>{{group.id}}</td> |
72 | <td>{{group.app_id}}</td> | 73 | <td>{{group.app_id}}</td> |
73 | <td>{{group.state}}</td> | 74 | <td>{{group.state}}</td> |
... | @@ -75,7 +76,7 @@ | ... | @@ -75,7 +76,7 @@ |
75 | <td>{{group.packets}}</td> | 76 | <td>{{group.packets}}</td> |
76 | <td>{{group.bytes}}</td> | 77 | <td>{{group.bytes}}</td> |
77 | </tr> | 78 | </tr> |
78 | - <tr ng-repeat-end> | 79 | + <tr class="multi-row" ng-repeat-end> |
79 | <td class="buckets" colspan="6" | 80 | <td class="buckets" colspan="6" |
80 | ng-bind-html="group.buckets"></td> | 81 | ng-bind-html="group.buckets"></td> |
81 | </tr> | 82 | </tr> | ... | ... |
... | @@ -33,7 +33,8 @@ | ... | @@ -33,7 +33,8 @@ |
33 | </td> | 33 | </td> |
34 | </tr> | 34 | </tr> |
35 | 35 | ||
36 | - <tr ng-repeat="host in tableData track by $index"> | 36 | + <tr ng-repeat="host in tableData track by $index" |
37 | + onos-flash-changes row="{{host}}" row-id="id"> | ||
37 | <td class="table-icon"> | 38 | <td class="table-icon"> |
38 | <div icon icon-id="{{host._iconid_type}}"></div> | 39 | <div icon icon-id="{{host._iconid_type}}"></div> |
39 | </td> | 40 | </td> | ... | ... |
... | @@ -47,6 +47,23 @@ | ... | @@ -47,6 +47,23 @@ |
47 | background-color: #333; | 47 | background-color: #333; |
48 | } | 48 | } |
49 | 49 | ||
50 | +.light #ov-intent tr:nth-child(6n + 1).data-change, | ||
51 | +.light #ov-intent tr:nth-child(6n + 2).data-change, | ||
52 | +.light #ov-intent tr:nth-child(6n + 3).data-change, | ||
53 | +.light #ov-intent tr:nth-child(6n + 4).data-change, | ||
54 | +.light #ov-intent tr:nth-child(6n + 5).data-change, | ||
55 | +.light #ov-intent tr:nth-child(6n).data-change { | ||
56 | + background-color: #FDFFDC; | ||
57 | +} | ||
58 | +.dark #ov-intent tr:nth-child(6n + 1).data-change, | ||
59 | +.dark #ov-intent tr:nth-child(6n + 2).data-change, | ||
60 | +.dark #ov-intent tr:nth-child(6n + 3).data-change, | ||
61 | +.dark #ov-intent tr:nth-child(6n + 4).data-change, | ||
62 | +.dark #ov-intent tr:nth-child(6n + 5).data-change, | ||
63 | +.dark #ov-intent tr:nth-child(6n).data-change { | ||
64 | + background-color: #5A5600; | ||
65 | +} | ||
66 | + | ||
50 | #ov-intent td.resources, | 67 | #ov-intent td.resources, |
51 | #ov-intent td.details { | 68 | #ov-intent td.details { |
52 | padding-left: 36px; | 69 | padding-left: 36px; | ... | ... |
... | @@ -48,17 +48,18 @@ | ... | @@ -48,17 +48,18 @@ |
48 | </td> | 48 | </td> |
49 | </tr> | 49 | </tr> |
50 | 50 | ||
51 | - <tr ng-repeat-start="intent in tableData track by $index"> | 51 | + <tr ng-repeat-start="intent in tableData track by $index" |
52 | + onos-flash-changes row="{{intent}}" row-id="key"> | ||
52 | <td>{{intent.appId}}</td> | 53 | <td>{{intent.appId}}</td> |
53 | <td>{{intent.key}}</td> | 54 | <td>{{intent.key}}</td> |
54 | <td>{{intent.type}}</td> | 55 | <td>{{intent.type}}</td> |
55 | <td>{{intent.priority}}</td> | 56 | <td>{{intent.priority}}</td> |
56 | <td>{{intent.state}}</td> | 57 | <td>{{intent.state}}</td> |
57 | </tr> | 58 | </tr> |
58 | - <tr> | 59 | + <tr class="multi-row"> |
59 | <td class="resources" colspan="5">{{intent.resources}}</td> | 60 | <td class="resources" colspan="5">{{intent.resources}}</td> |
60 | </tr> | 61 | </tr> |
61 | - <tr ng-repeat-end> | 62 | + <tr class="multi-row" ng-repeat-end> |
62 | <td class="details" colspan="5">{{intent.details}}</td> | 63 | <td class="details" colspan="5">{{intent.details}}</td> |
63 | </tr> | 64 | </tr> |
64 | </table> | 65 | </table> | ... | ... |
... | @@ -49,7 +49,8 @@ | ... | @@ -49,7 +49,8 @@ |
49 | </td> | 49 | </td> |
50 | </tr> | 50 | </tr> |
51 | 51 | ||
52 | - <tr ng-repeat="link in tableData track by $index"> | 52 | + <tr ng-repeat="link in tableData track by $index" |
53 | + onos-flash-changes row="{{link}}" row-id="one"> | ||
53 | <td class="table-icon"> | 54 | <td class="table-icon"> |
54 | <div icon icon-id="{{link._iconid_state}}"></div> | 55 | <div icon icon-id="{{link._iconid_state}}"></div> |
55 | </td> | 56 | </td> | ... | ... |
... | @@ -69,7 +69,8 @@ | ... | @@ -69,7 +69,8 @@ |
69 | </td> | 69 | </td> |
70 | </tr> | 70 | </tr> |
71 | 71 | ||
72 | - <tr ng-repeat="port in tableData track by $index"> | 72 | + <tr ng-repeat="port in tableData track by $index" |
73 | + onos-flash-changes row="{{port}}" row-id="id"> | ||
73 | <td>{{port.id}}</td> | 74 | <td>{{port.id}}</td> |
74 | <td>{{port.pkt_rx}}</td> | 75 | <td>{{port.pkt_rx}}</td> |
75 | <td>{{port.pkt_tx}}</td> | 76 | <td>{{port.pkt_tx}}</td> | ... | ... |
... | @@ -33,7 +33,8 @@ | ... | @@ -33,7 +33,8 @@ |
33 | </td> | 33 | </td> |
34 | </tr> | 34 | </tr> |
35 | 35 | ||
36 | - <tr ng-repeat="prop in tableData track by $index"> | 36 | + <tr ng-repeat="prop in tableData track by $index" |
37 | + onos-flash-changes row="{{prop}}" row-id="id"> | ||
37 | <td>{{prop.component}}</td> | 38 | <td>{{prop.component}}</td> |
38 | <td>{{prop.id}}</td> | 39 | <td>{{prop.id}}</td> |
39 | <td>{{prop.type}}</td> | 40 | <td>{{prop.type}}</td> | ... | ... |
-
Please register or login to post a comment