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