Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 7101ef0

Browse files
BoykoAlexghillert
authored andcommitted
Add progress bar when creating stream
* Use bootstrap progress bar * Show growl message on success * Ensure progress bar shows up for a bit with very fast create streams operation
1 parent 0af2210 commit 7101ef0

File tree

2 files changed

+101
-48
lines changed

2 files changed

+101
-48
lines changed

ui/app/scripts/stream/controllers/create-streams-dialog.js

Lines changed: 93 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,31 @@ define(function(require) {
2424

2525
var angular = require('angular');
2626

27+
var PROGRESS_BAR_WAIT_TIME = 600; // to account for animation delay
28+
2729
return ['DataflowUtils', '$scope', 'StreamService', '$modalInstance', 'definitionData', 'StreamMetamodelService', 'StreamParserService',
2830
function (utils, $scope, streamService, $modalInstance, definitionData, metaModelService, ParserService) {
2931

32+
function waitForStreamDef(streamDefNameToWaitFor, attemptCount) {
33+
var deferred = utils.$q.defer();
34+
if (attemptCount === 10) {
35+
utils.$log.info('Aborting after 10 attempts, cannot find the stream: '+streamDefNameToWaitFor);
36+
deferred.resolve();
37+
}
38+
streamService.getSingleStreamDefinition(streamDefNameToWaitFor).success(function() {
39+
utils.$log.info('Stream '+streamDefNameToWaitFor+' is ok!');
40+
deferred.resolve();
41+
}).error(function() {
42+
utils.$log.info('Stream '+streamDefNameToWaitFor+' is not there yet (attempt=#'+attemptCount+')');
43+
utils.$timeout(function() {
44+
$scope.waitForStreamDef(streamDefNameToWaitFor, attemptCount+1).then(function() {
45+
deferred.resolve();
46+
});
47+
},400);
48+
});
49+
return deferred.promise;
50+
}
51+
3052
$scope.streamdefs = [];
3153
$scope.errors = [];
3254
$scope.warnings = [];
@@ -74,70 +96,96 @@ define(function(require) {
7496
}
7597

7698
$scope.canSubmit = function() {
77-
return $scope.streamForm.$valid && $scope.streamdefs && $scope.streamdefs.length && !($scope.errors && $scope.errors.length);
99+
return !$scope.isStreamCreationInProgress() && $scope.streamForm.$valid && $scope.streamdefs && $scope.streamdefs.length && !($scope.errors && $scope.errors.length);
78100
};
79101

80102
$scope.submitStreams = function() {
81103
if ($scope.canSubmit()) {
82-
$scope.createStreams();
104+
// Find index of the first not yet created stream
105+
// Can't use Array#findIndex(...) because not all browsers support it
106+
var index = 0;
107+
for (; index < $scope.streamdefs.length && $scope.streamdefs[index].created; index++) {
108+
// nothing to do - just loop to the not created stream def
109+
}
110+
// Setup progress bar data
111+
$scope.createProgressData(($scope.streamdefs.length - index) * 2 - 1); // create, wait for each - wait for the last
112+
// Start stream(s) creation
113+
$scope.createStreams(index);
83114
}
84115
};
85116

117+
$scope.createProgressData = function(total, count) {
118+
$scope.progressData = {
119+
count: count ? count : 0,
120+
total: total,
121+
getPercent: function() {
122+
return Math.round(this.count / this.total * 100);
123+
}
124+
};
125+
};
126+
86127
/**
87128
* Function creating streams based on the info in scopes flo.streamdefs contents.
88129
*
89130
* After calling the REST API to create a stream, it doesn't mean it is fully defined yet. So this createStreams()
90131
* function can be passed a stream name that it should wait on before continuing. This ensures that if a later
91132
* stream depends on an earlier stream, everything works.
92133
*/
93-
$scope.createStreams = function(streamDefNameToWaitFor, attemptCount) {
94-
// Are we waiting for a stream to be available?
95-
if (streamDefNameToWaitFor) {
96-
if (attemptCount === 10) {
97-
utils.$log.info('Aborting after 10 attempts, cannot find the stream: '+streamDefNameToWaitFor);
98-
return;
99-
}
100-
streamService.getSingleStreamDefinition(streamDefNameToWaitFor).success(function() {
101-
utils.$log.info('Stream '+streamDefNameToWaitFor+' is ok!');
102-
utils.$timeout(function(){$scope.createStreams();},0);
103-
}).error(function() {
104-
utils.$log.info('Stream '+streamDefNameToWaitFor+' is not there yet (attempt=#'+attemptCount+')');
105-
utils.$timeout(function(){$scope.createStreams(streamDefNameToWaitFor,attemptCount+1);},400);
106-
});
134+
$scope.createStreams = function(index) {
135+
if (index < 0 || index >= $scope.streamdefs.length) {
136+
// Invalid index means all streams have been created, close the dialog.
137+
$modalInstance.close(true);
107138
} else {
108-
// Find index of the first not yet created stream
109-
// Can't use Array#findIndex(...) because not all browsers support it
110-
var index = 0;
111-
for (; index < $scope.streamdefs.length && $scope.streamdefs[index].created; index++) {
112-
// nothing to do - just loop to the not created stream def
113-
}
114-
if (index < 0 || index >= $scope.streamdefs.length) {
115-
// Invalid index means all streams have been created, close the dialog.
116-
$modalInstance.close(true);
117-
} else {
118-
// Send the request to create a stream
119-
var def = $scope.streamdefs[index];
120-
streamService.create(def.name, def.def, $scope.deploy).success(function() {
121-
utils.$log.info('Stream '+def.name+' created OK');
122-
// Stream created successfully, mark it as created
123-
def.created = true;
124-
if ($scope.streamdefs.length - 1 === index) {
125-
// Last stream created, close the dialog
139+
// Send the request to create a stream
140+
var def = $scope.streamdefs[index];
141+
streamService.create(def.name, def.def, $scope.deploy).success(function () {
142+
utils.$log.info('Stream ' + def.name + ' created OK');
143+
// Stream created successfully, mark it as created
144+
def.created = true;
145+
$scope.createProgressData($scope.progressData.total, $scope.progressData.count + 1);
146+
if ($scope.streamdefs.length - 1 === index) {
147+
// Last stream created, close the dialog
148+
// Delay closing the dialog thus progress bar 100% would stay up for a short a bit
149+
utils.$timeout(function() {
126150
$modalInstance.close(true);
127-
} else {
128-
// There are more streams to create, so create the next one
129-
$scope.createStreams(def.name,0);
130-
}
131-
}).error(function(error) {
132-
for (var e=0; e<error.length; e++) {
133-
utils.growl.error('Problem creating stream: ' + def.name + ':' + error[e].message);
134-
}
135-
utils.$log.error('Failed to create stream ' + JSON.stringify(def));
136-
});
137-
}
151+
utils.growl.success('Stream(s) have been created successfully');
152+
}, PROGRESS_BAR_WAIT_TIME);
153+
} else {
154+
// There are more streams to create, so create the next one
155+
waitForStreamDef(def.name, 0).then(function () {
156+
$scope.createProgressData($scope.progressData.total, $scope.progressData.count + 1);
157+
$scope.createStreams(index + 1);
158+
}, function() {
159+
// Error handling
160+
// Previous stream creation request was issues but the stream resource is still unavailable for some reason
161+
// Never mind and keep creating the rest of the streams?
162+
$scope.createProgressData($scope.progressData.total, $scope.progressData.count + 1);
163+
$scope.createStreams(index + 1);
164+
});
165+
}
166+
}).error(function (error) {
167+
// Delay hiding the progress bar thus user can see it if operation went too fast
168+
utils.$timeout(function() {
169+
$scope.progressData = undefined;
170+
}, PROGRESS_BAR_WAIT_TIME);
171+
for (var e = 0; e < error.length; e++) {
172+
utils.growl.error('Problem creating stream: ' + def.name + ':' + error[e].message);
173+
}
174+
utils.$log.error('Failed to create stream ' + JSON.stringify(def));
175+
});
176+
}
177+
};
178+
179+
$scope.getProgressPercent = function() {
180+
if ($scope.progressData) {
181+
return $scope.progressData.getPercent();
138182
}
139183
};
140184

185+
$scope.isStreamCreationInProgress = function() {
186+
return $scope.progressData;
187+
};
188+
141189
$scope.cancel = function() {
142190
$modalInstance.dismiss();
143191
};

ui/app/scripts/stream/views/create-stream-dialog.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ <h4 class="modal-title">Confirm Stream(s) Creation</h4>
2323
<tbody>
2424
<tr ng-repeat="def in streamdefs" ng-if="!def.created" ng-class="streamForm['stream-' + $index].$invalid ? 'has-warning has-feedback' : ''">
2525
<td>
26-
<input class="form-control" name="{{'stream-' + $index}}" type="text" placeholder="<Stream Name>" ng-model-options="{ debounce: 250 }"
26+
<input ng-disabled="isStreamCreationInProgress()" class="form-control" name="{{'stream-' + $index}}" type="text" placeholder="<Stream Name>" ng-model-options="{ debounce: 250 }"
2727
ng-model="def.name" ng-pattern="/^\s*[\w\-]+\s*$/" ng-trim="true" required unique-field-values="stream-" unique-stream-name/>
2828
<p ng-show="streamForm['stream-' + $index].$error.required" class="help-block validation-block">Stream name is required!</p>
2929
<p ng-show="streamForm['stream-' + $index].$error.uniqueStreamName" class="help-block validation-block">Stream name is already taken!</p>
@@ -36,10 +36,15 @@ <h4 class="modal-title">Confirm Stream(s) Creation</h4>
3636
</tr>
3737
</tbody>
3838
</table>
39-
<label class="dialog-control"><input type="checkbox" ng-model="deploy"/>Deploy stream(s)</label>
39+
<label class="dialog-control"><input ng-disabled="isStreamCreationInProgress()" type="checkbox" ng-model="deploy"/>Deploy stream(s)</label>
40+
<div ng-if="isStreamCreationInProgress()">
41+
<hr/>
42+
<div>Creating Streams...</div>
43+
<progressbar animate="true" value="getProgressPercent()" type="success"><b>{{getProgressPercent()}}%</b></progressbar>
44+
</div>
4045
</div>
4146
<div class="modal-footer">
42-
<button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button>
47+
<button type="button" class="btn btn-default" ng-click="cancel()">{{isStreamCreationInProgress() ? 'Close' : 'Cancel'}}</button>
4348
<button type="submit" class="btn btn-primary" ng-disabled="!canSubmit()">Create</button>
4449
</div>
4550
</form>

0 commit comments

Comments
 (0)