ONOS-2143 - GUI -- Tabular views display a loading wheel while waiting for a server response.
Change-Id: I2e2dbb4189a76c168aaa0cc03871eacc3ffd8d12
Showing
14 changed files
with
116 additions
and
9 deletions
| ... | @@ -144,6 +144,45 @@ | ... | @@ -144,6 +144,45 @@ |
| 144 | '83.5,37.7c0-2.1-1.2-3.8-2.7-3.8h-0.7c-1.5,0-2.7,1.7-2.7,3.8v55.9' + | 144 | '83.5,37.7c0-2.1-1.2-3.8-2.7-3.8h-0.7c-1.5,0-2.7,1.7-2.7,3.8v55.9' + |
| 145 | 'c0,2.1,1.2,3.8,2.7,3.8h0.7c1.5,0,2.7-1.7,2.7-3.8V37.7z', | 145 | 'c0,2.1,1.2,3.8,2.7,3.8h0.7c1.5,0,2.7-1.7,2.7-3.8V37.7z', |
| 146 | 146 | ||
| 147 | + loading: 'M103.1,53.1c0,0,0,0.2,0,0.5c0,0.2,0,0.4,0,0.7c0,0.3,0,0' + | ||
| 148 | + '.6,0,0.9c-0.1,1.3-0.2,3-0.5,4.8c-0.5,3.4-1.6,6.8-1.6,6.8l-9.2-2.' + | ||
| 149 | + '7c0,0,0.8-2.7,1.1-5.5c0.2-1.4,0.3-2.8,0.3-3.8c0-0.3,0-0.5,0-0.7c' + | ||
| 150 | + '0-0.2,0-0.4,0-0.6c0-0.3,0-0.5,0-0.5L103.1,53.1z M87.3,74.3c0,0-0' + | ||
| 151 | + '.1,0.2-0.3,0.5c-0.2,0.3-0.4,0.6-0.7,1.1c-0.6,0.9-1.4,2-2.3,3.1c-' + | ||
| 152 | + '1.8,2.2-3.9,4.1-3.9,4.1l5.7,6.5c0,0,0.7-0.5,1.6-1.4c1-0.9,2.2-2.' + | ||
| 153 | + '1,3.3-3.4c1.1-1.3,2.2-2.6,3-3.7c0.4-0.5,0.7-1,0.9-1.3c0.2-0.3,0.' + | ||
| 154 | + '3-0.4,0.3-0.4L87.3,74.3z M70.8,89.2c0,0-0.2,0.1-0.5,0.2c-0.3,0.2' + | ||
| 155 | + '-0.6,0.3-1.2,0.5c-1,0.4-2.3,0.9-3.7,1.4c-2.7,0.9-5.5,1.3-5.5,1.3' + | ||
| 156 | + 'l1.1,7.6c0,0,0.8-0.1,2.1-0.3c1.3-0.2,2.9-0.6,4.6-1c1.6-0.5,3.3-1' + | ||
| 157 | + ',4.5-1.5c0.6-0.2,1.2-0.5,1.5-0.6c0.3-0.1,0.5-0.2,0.5-0.2L70.8,89' + | ||
| 158 | + '.2z M48.6,92.9c0,0-0.2,0-0.5-0.1c-0.4,0-0.7-0.1-1.3-0.2c-1.1-0.2' + | ||
| 159 | + '-2.5-0.5-3.9-0.8c-2.8-0.7-5.4-1.9-5.4-1.9L34.6,96c0,0,3,1.5,6.3,' + | ||
| 160 | + '2.5c1.6,0.5,3.3,0.9,4.5,1.2c0.6,0.1,1.2,0.2,1.5,0.3c0.3,0.1,0.5,' + | ||
| 161 | + '0.1,0.5,0.1L48.6,92.9z M27.6,83.8c0,0-0.1-0.1-0.4-0.3c-0.3-0.2-0' + | ||
| 162 | + '.6-0.5-1-0.9c-0.8-0.7-1.8-1.8-2.8-2.8c-2-2.2-3.6-4.6-3.6-4.6l-5,' + | ||
| 163 | + '3.2c0,0,0.4,0.7,1.1,1.7c0.7,1,1.7,2.4,2.8,3.7c1.1,1.3,2.2,2.5,3.' + | ||
| 164 | + '1,3.4c0.4,0.4,0.9,0.8,1.1,1.1c0.3,0.2,0.4,0.4,0.4,0.4L27.6,83.8z' + | ||
| 165 | + 'M14.8,64.7c0,0-0.1-0.2-0.2-0.5c-0.1-0.3-0.2-0.7-0.4-1.3c-0.3-1.1' + | ||
| 166 | + '-0.6-2.5-0.8-4c-0.5-2.9-0.5-5.9-0.5-5.9l-5,0c0,0,0,0.8,0,2.1c0,1' + | ||
| 167 | + '.2,0.1,2.9,0.3,4.5c0.2,1.6,0.5,3.3,0.8,4.5c0.1,0.6,0.3,1.2,0.4,1' + | ||
| 168 | + '.5c0.1,0.3,0.1,0.5,0.1,0.5L14.8,64.7z M14.3,41.4c0,0,0.1-0.2,0.1' + | ||
| 169 | + '-0.5c0.1-0.3,0.2-0.7,0.4-1.3c0.3-1.1,0.8-2.5,1.4-3.8c1.2-2.7,2.8' + | ||
| 170 | + '-5.3,2.8-5.3l-3.4-2.2c0,0-1.8,2.7-3.2,5.7c-0.7,1.5-1.3,3-1.7,4.2' + | ||
| 171 | + 'c-0.2,0.6-0.4,1.1-0.5,1.4C10,39.9,10,40.1,10,40.1L14.3,41.4z M26' + | ||
| 172 | + '.7,21.3c0,0,0.1-0.1,0.4-0.4c0.3-0.2,0.6-0.5,1-0.9c0.9-0.7,2.1-1.' + | ||
| 173 | + '6,3.3-2.5c1.2-0.8,2.5-1.6,3.5-2.1c1-0.5,1.7-0.9,1.7-0.9l-1.3-2.9' + | ||
| 174 | + 'c0,0-0.7,0.3-1.8,0.9c-1.1,0.5-2.5,1.3-3.9,2.2c-1.4,0.9-2.7,1.8-3' + | ||
| 175 | + '.7,2.5c-0.5,0.4-0.9,0.7-1.2,0.9c-0.3,0.2-0.4,0.3-0.4,0.3L26.7,21' + | ||
| 176 | + '.3z M48.2,11c0,0,0.2,0,0.5-0.1c0.3,0,0.8-0.1,1.4-0.2c1.1-0.1,2.6' + | ||
| 177 | + '-0.3,4.2-0.3c3-0.1,6.1,0.3,6.1,0.3l0.3-2.3c0,0-0.8-0.1-2-0.3C57.' + | ||
| 178 | + '4,8.1,55.8,8,54.2,8c-1.6,0-3.2,0-4.4,0.1c-0.6,0-1.1,0.1-1.5,0.1c' + | ||
| 179 | + '-0.3,0-0.5,0.1-0.5,0.1L48.2,11z M72,14c0,0,0.7,0.3,1.7,0.8c1,0.5' + | ||
| 180 | + ',2.4,1.2,3.7,2c2.6,1.6,5,3.6,5,3.6l0.9-1c0,0-2.4-2.1-5-3.9c-1.3-' + | ||
| 181 | + '0.9-2.7-1.7-3.8-2.3c-1.1-0.6-1.8-0.9-1.8-0.9L72,14zM90.7,29.6c0,' + | ||
| 182 | + '0,0.4,0.6,1,1.6c0.6,1,1.4,2.3,2,3.7c0.7,1.4,1.3,2.8,1.7,3.9c0.4,' + | ||
| 183 | + '1.1,0.6,1.8,0.6,1.8l0.4-0.1c0,0-0.2-0.8-0.6-1.9c-0.4-1.1-0.9-2.6' + | ||
| 184 | + '-1.5-4c-0.6-1.4-1.3-2.9-1.9-3.9c-0.6-1-1-1.7-1-1.7L90.7,29.6z', | ||
| 185 | + | ||
| 147 | // --- Navigation glyphs ------------------------------------ | 186 | // --- Navigation glyphs ------------------------------------ |
| 148 | 187 | ||
| 149 | flowTable: 'M15.9,19.1h-8v-13h8V19.1z M90.5,6.1H75.6v13h14.9V6.1z' + | 188 | flowTable: 'M15.9,19.1h-8v-13h8V19.1z M90.5,6.1H75.6v13h14.9V6.1z' + | ... | ... |
| ... | @@ -43,6 +43,8 @@ | ... | @@ -43,6 +43,8 @@ |
| 43 | upArrow: 'triangleUp', | 43 | upArrow: 'triangleUp', |
| 44 | downArrow: 'triangleDown', | 44 | downArrow: 'triangleDown', |
| 45 | 45 | ||
| 46 | + loading: 'loading', | ||
| 47 | + | ||
| 46 | appInactive: 'unknown', | 48 | appInactive: 'unknown', |
| 47 | 49 | ||
| 48 | devIcon_SWITCH: 'switch', | 50 | devIcon_SWITCH: 'switch', | ... | ... |
| ... | @@ -22,6 +22,31 @@ div.summary-list { | ... | @@ -22,6 +22,31 @@ div.summary-list { |
| 22 | border-spacing: 0; | 22 | border-spacing: 0; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | +div.loading-wheel { | ||
| 26 | + display: inline-block; | ||
| 27 | + position: absolute; | ||
| 28 | + margin-top: 40px; | ||
| 29 | + left: 47%; | ||
| 30 | + animation: spin reverse 2s ease infinite; | ||
| 31 | + z-index: 1000; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +@keyframes spin { | ||
| 35 | + to { | ||
| 36 | + transform: rotate(360deg); | ||
| 37 | + } | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +div.loading-wheel svg.embeddedIcon g.icon .glyph { | ||
| 41 | + opacity: .8; | ||
| 42 | +} | ||
| 43 | +.light div.loading-wheel svg.embeddedIcon g.icon .glyph { | ||
| 44 | + fill: #964949; | ||
| 45 | +} | ||
| 46 | +.dark div.loading-wheel svg.embeddedIcon g.icon .glyph { | ||
| 47 | + fill: whitesmoke; | ||
| 48 | +} | ||
| 49 | + | ||
| 25 | div.summary-list table { | 50 | div.summary-list table { |
| 26 | border-collapse: collapse; | 51 | border-collapse: collapse; |
| 27 | table-layout: fixed; | 52 | table-layout: fixed; | ... | ... |
| ... | @@ -21,10 +21,11 @@ | ... | @@ -21,10 +21,11 @@ |
| 21 | 'use strict'; | 21 | 'use strict'; |
| 22 | 22 | ||
| 23 | // injected refs | 23 | // injected refs |
| 24 | - var $log, $interval, fs, wss; | 24 | + var $log, $interval, $timeout, fs, wss; |
| 25 | 25 | ||
| 26 | // constants | 26 | // constants |
| 27 | - var refreshInterval = 2000; | 27 | + var refreshInterval = 2000, |
| 28 | + loadingWait = 500; | ||
| 28 | 29 | ||
| 29 | // example params to buildTable: | 30 | // example params to buildTable: |
| 30 | // { | 31 | // { |
| ... | @@ -47,17 +48,21 @@ | ... | @@ -47,17 +48,21 @@ |
| 47 | onSel = fs.isF(o.selCb), | 48 | onSel = fs.isF(o.selCb), |
| 48 | onResp = fs.isF(o.respCb), | 49 | onResp = fs.isF(o.respCb), |
| 49 | oldTableData = [], | 50 | oldTableData = [], |
| 50 | - promise; | 51 | + loaded = false, |
| 52 | + refreshPromise, loadingPromise; | ||
| 51 | 53 | ||
| 52 | o.scope.tableData = []; | 54 | o.scope.tableData = []; |
| 53 | o.scope.changedData = []; | 55 | o.scope.changedData = []; |
| 54 | o.scope.sortParams = {}; | 56 | o.scope.sortParams = {}; |
| 57 | + o.scope.loading = true; | ||
| 55 | o.scope.autoRefresh = true; | 58 | o.scope.autoRefresh = true; |
| 56 | o.scope.autoRefreshTip = 'Toggle auto refresh'; | 59 | o.scope.autoRefreshTip = 'Toggle auto refresh'; |
| 57 | 60 | ||
| 58 | // === websocket functions -------------------- | 61 | // === websocket functions -------------------- |
| 59 | // response | 62 | // response |
| 60 | function respCb(data) { | 63 | function respCb(data) { |
| 64 | + loaded = true; | ||
| 65 | + o.scope.loading = false; | ||
| 61 | o.scope.tableData = data[root]; | 66 | o.scope.tableData = data[root]; |
| 62 | onResp && onResp(); | 67 | onResp && onResp(); |
| 63 | 68 | ||
| ... | @@ -83,9 +88,20 @@ | ... | @@ -83,9 +88,20 @@ |
| 83 | function sortCb(params) { | 88 | function sortCb(params) { |
| 84 | var p = angular.extend({}, params, o.query); | 89 | var p = angular.extend({}, params, o.query); |
| 85 | wss.sendEvent(req, p); | 90 | wss.sendEvent(req, p); |
| 91 | + stillLoading(); | ||
| 86 | } | 92 | } |
| 87 | o.scope.sortCallback = sortCb; | 93 | o.scope.sortCallback = sortCb; |
| 88 | 94 | ||
| 95 | + // show loading wheel if it's taking a while for the server to respond | ||
| 96 | + function stillLoading() { | ||
| 97 | + loaded = false; | ||
| 98 | + loadingPromise = $timeout(function () { | ||
| 99 | + if (!loaded) { | ||
| 100 | + o.scope.loading = true; | ||
| 101 | + } | ||
| 102 | + }, loadingWait); | ||
| 103 | + } | ||
| 104 | + | ||
| 89 | // === selecting a row functions ---------------- | 105 | // === selecting a row functions ---------------- |
| 90 | function selCb($event, selRow) { | 106 | function selCb($event, selRow) { |
| 91 | o.scope.selId = (o.scope.selId === selRow.id) ? null : selRow.id; | 107 | o.scope.selId = (o.scope.selId === selRow.id) ? null : selRow.id; |
| ... | @@ -95,7 +111,7 @@ | ... | @@ -95,7 +111,7 @@ |
| 95 | 111 | ||
| 96 | // === autoRefresh functions ------------------ | 112 | // === autoRefresh functions ------------------ |
| 97 | function startRefresh() { | 113 | function startRefresh() { |
| 98 | - promise = $interval(function () { | 114 | + refreshPromise = $interval(function () { |
| 99 | if (fs.debugOn('widget')) { | 115 | if (fs.debugOn('widget')) { |
| 100 | $log.debug('Refreshing ' + root + ' page'); | 116 | $log.debug('Refreshing ' + root + ' page'); |
| 101 | } | 117 | } |
| ... | @@ -104,9 +120,9 @@ | ... | @@ -104,9 +120,9 @@ |
| 104 | } | 120 | } |
| 105 | 121 | ||
| 106 | function stopRefresh() { | 122 | function stopRefresh() { |
| 107 | - if (angular.isDefined(promise)) { | 123 | + if (angular.isDefined(refreshPromise)) { |
| 108 | - $interval.cancel(promise); | 124 | + $interval.cancel(refreshPromise); |
| 109 | - promise = undefined; | 125 | + refreshPromise = undefined; |
| 110 | } | 126 | } |
| 111 | } | 127 | } |
| 112 | 128 | ||
| ... | @@ -120,6 +136,10 @@ | ... | @@ -120,6 +136,10 @@ |
| 120 | o.scope.$on('$destroy', function () { | 136 | o.scope.$on('$destroy', function () { |
| 121 | wss.unbindHandlers(handlers); | 137 | wss.unbindHandlers(handlers); |
| 122 | stopRefresh(); | 138 | stopRefresh(); |
| 139 | + if (angular.isDefined(loadingPromise)) { | ||
| 140 | + $timeout.cancel(loadingPromise); | ||
| 141 | + loadingPromise = undefined; | ||
| 142 | + } | ||
| 123 | }); | 143 | }); |
| 124 | 144 | ||
| 125 | sortCb(); | 145 | sortCb(); |
| ... | @@ -128,11 +148,12 @@ | ... | @@ -128,11 +148,12 @@ |
| 128 | 148 | ||
| 129 | angular.module('onosWidget') | 149 | angular.module('onosWidget') |
| 130 | .factory('TableBuilderService', | 150 | .factory('TableBuilderService', |
| 131 | - ['$log', '$interval', 'FnService', 'WebSocketService', | 151 | + ['$log', '$interval', '$timeout', 'FnService', 'WebSocketService', |
| 132 | 152 | ||
| 133 | - function (_$log_, _$interval_, _fs_, _wss_) { | 153 | + function (_$log_, _$interval_, _$timeout_, _fs_, _wss_) { |
| 134 | $log = _$log_; | 154 | $log = _$log_; |
| 135 | $interval = _$interval_; | 155 | $interval = _$interval_; |
| 156 | + $timeout = _$timeout_; | ||
| 136 | fs = _fs_; | 157 | fs = _fs_; |
| 137 | wss = _wss_; | 158 | wss = _wss_; |
| 138 | 159 | ... | ... |
| ... | @@ -37,6 +37,8 @@ | ... | @@ -37,6 +37,8 @@ |
| 37 | </div> | 37 | </div> |
| 38 | 38 | ||
| 39 | <div class="summary-list" onos-table-resize> | 39 | <div class="summary-list" onos-table-resize> |
| 40 | + <div ng-show="loading" class="loading-wheel" | ||
| 41 | + icon icon-id="loading" icon-size="75"></div> | ||
| 40 | 42 | ||
| 41 | <div class="table-header" onos-sortable-header> | 43 | <div class="table-header" onos-sortable-header> |
| 42 | <table> | 44 | <table> | ... | ... |
| ... | @@ -27,6 +27,8 @@ | ... | @@ -27,6 +27,8 @@ |
| 27 | </div> | 27 | </div> |
| 28 | 28 | ||
| 29 | <div class="summary-list" onos-table-resize> | 29 | <div class="summary-list" onos-table-resize> |
| 30 | + <div ng-show="loading" class="loading-wheel" | ||
| 31 | + icon icon-id="loading" icon-size="75"></div> | ||
| 30 | 32 | ||
| 31 | <div class="table-header" onos-sortable-header> | 33 | <div class="table-header" onos-sortable-header> |
| 32 | <table> | 34 | <table> | ... | ... |
| ... | @@ -27,6 +27,8 @@ | ... | @@ -27,6 +27,8 @@ |
| 27 | </div> | 27 | </div> |
| 28 | 28 | ||
| 29 | <div class="summary-list" onos-table-resize> | 29 | <div class="summary-list" onos-table-resize> |
| 30 | + <div ng-show="loading" class="loading-wheel" | ||
| 31 | + icon icon-id="loading" icon-size="75"></div> | ||
| 30 | 32 | ||
| 31 | <div class="table-header" onos-sortable-header> | 33 | <div class="table-header" onos-sortable-header> |
| 32 | <table> | 34 | <table> | ... | ... |
| ... | @@ -29,6 +29,8 @@ | ... | @@ -29,6 +29,8 @@ |
| 29 | </div> | 29 | </div> |
| 30 | 30 | ||
| 31 | <div class="summary-list" onos-table-resize> | 31 | <div class="summary-list" onos-table-resize> |
| 32 | + <div ng-show="loading" class="loading-wheel" | ||
| 33 | + icon icon-id="loading" icon-size="75"></div> | ||
| 32 | 34 | ||
| 33 | <div class="table-header" onos-sortable-header> | 35 | <div class="table-header" onos-sortable-header> |
| 34 | <table> | 36 | <table> | ... | ... |
| ... | @@ -45,6 +45,8 @@ | ... | @@ -45,6 +45,8 @@ |
| 45 | </div> | 45 | </div> |
| 46 | 46 | ||
| 47 | <div class="summary-list" onos-table-resize> | 47 | <div class="summary-list" onos-table-resize> |
| 48 | + <div ng-show="loading" class="loading-wheel" | ||
| 49 | + icon icon-id="loading" icon-size="75"></div> | ||
| 48 | 50 | ||
| 49 | <div class="table-header" onos-sortable-header> | 51 | <div class="table-header" onos-sortable-header> |
| 50 | <table> | 52 | <table> | ... | ... |
| ... | @@ -11,6 +11,8 @@ | ... | @@ -11,6 +11,8 @@ |
| 11 | </div> | 11 | </div> |
| 12 | 12 | ||
| 13 | <div class="summary-list" onos-table-resize> | 13 | <div class="summary-list" onos-table-resize> |
| 14 | + <div ng-show="loading" class="loading-wheel" | ||
| 15 | + icon icon-id="loading" icon-size="75"></div> | ||
| 14 | 16 | ||
| 15 | <div class="table-header" onos-sortable-header> | 17 | <div class="table-header" onos-sortable-header> |
| 16 | <table> | 18 | <table> | ... | ... |
| ... | @@ -27,6 +27,8 @@ | ... | @@ -27,6 +27,8 @@ |
| 27 | </div> | 27 | </div> |
| 28 | 28 | ||
| 29 | <div class="summary-list" onos-table-resize> | 29 | <div class="summary-list" onos-table-resize> |
| 30 | + <div ng-show="loading" class="loading-wheel" | ||
| 31 | + icon icon-id="loading" icon-size="75"></div> | ||
| 30 | 32 | ||
| 31 | <div class="table-header" onos-sortable-header> | 33 | <div class="table-header" onos-sortable-header> |
| 32 | <table> | 34 | <table> | ... | ... |
| ... | @@ -27,6 +27,8 @@ | ... | @@ -27,6 +27,8 @@ |
| 27 | </div> | 27 | </div> |
| 28 | 28 | ||
| 29 | <div class="summary-list" onos-table-resize> | 29 | <div class="summary-list" onos-table-resize> |
| 30 | + <div ng-show="loading" class="loading-wheel" | ||
| 31 | + icon icon-id="loading" icon-size="75"></div> | ||
| 30 | 32 | ||
| 31 | <div class="table-header" onos-sortable-header> | 33 | <div class="table-header" onos-sortable-header> |
| 32 | <table> | 34 | <table> | ... | ... |
| ... | @@ -45,6 +45,8 @@ | ... | @@ -45,6 +45,8 @@ |
| 45 | </div> | 45 | </div> |
| 46 | 46 | ||
| 47 | <div class="summary-list" onos-table-resize> | 47 | <div class="summary-list" onos-table-resize> |
| 48 | + <div ng-show="loading" class="loading-wheel" | ||
| 49 | + icon icon-id="loading" icon-size="75"></div> | ||
| 48 | 50 | ||
| 49 | <div class="table-header" onos-sortable-header> | 51 | <div class="table-header" onos-sortable-header> |
| 50 | <table> | 52 | <table> | ... | ... |
| ... | @@ -11,6 +11,8 @@ | ... | @@ -11,6 +11,8 @@ |
| 11 | </div> | 11 | </div> |
| 12 | 12 | ||
| 13 | <div class="summary-list" onos-table-resize> | 13 | <div class="summary-list" onos-table-resize> |
| 14 | + <div ng-show="loading" class="loading-wheel" | ||
| 15 | + icon icon-id="loading" icon-size="75"></div> | ||
| 14 | 16 | ||
| 15 | <div class="table-header" onos-sortable-header> | 17 | <div class="table-header" onos-sortable-header> |
| 16 | <table> | 18 | <table> | ... | ... |
-
Please register or login to post a comment