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