Skip to content

Commit

Permalink
Merge pull request #24 from skazi0/lazy-spinner
Browse files Browse the repository at this point in the history
Lazy spinner directive
  • Loading branch information
santiph authored Sep 14, 2016
2 parents e72b0cc + 2749747 commit d006ca7
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
vm.beginUpgrade = beginUpgrade;

vm.prechecks = {
running: false,
completed: false,
valid: false,
spinnerVisible: false,
checks: {
updates_installed: false,
network_sanity: false,
Expand All @@ -45,6 +47,7 @@
* Pre validation checks
*/
function runPrechecks() {
vm.prechecks.running = true;
upgradePrechecksFactory
.getAll()
.then(
Expand Down Expand Up @@ -74,6 +77,7 @@
function() {
// Either on sucess or failure, the prechecks has been completed.
vm.prechecks.completed = true;
vm.prechecks.running = false;
}
);

Expand Down
8 changes: 6 additions & 2 deletions assets/app/features/upgrade/templates/upgrade7/landing.jade
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@
}")
span(translate='upgrade7.steps.landing.prechecks.codes.{{::checkKey}}')

button.btn.btn-default.btn-sm(translate='',
button.btn.btn-default.btn-sm(
ng-disabled="Upgrade7LandingVm.prechecks.completed && Upgrade7LandingVm.prechecks.valid",
ng-class="{active: Upgrade7LandingVm.prechecks.spinnerVisible}",
ng-click="Upgrade7LandingVm.prechecks.runPrechecks()"
) upgrade7.steps.landing.prechecks.form.check-again
)
suse-lazy-spinner(delay="2000", active="Upgrade7LandingVm.prechecks.running",
visible="Upgrade7LandingVm.prechecks.spinnerVisible")
span(translate='') upgrade7.steps.landing.prechecks.form.check-again

p.note-message(translate='') upgrade7.steps.landing.note

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
i.fa.fa-fw.fa-spin.fa-spinner(aria-hidden="true")
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
(function() {
'use strict';

angular
.module('crowbarWidgets')
.directive('suseLazySpinner', suseLazySpinner)
.constant('SUSE_LAZY_SPINNER', { DEFAULT_DELAY: 2000 });

suseLazySpinner.$inject = ['$timeout', 'SUSE_LAZY_SPINNER'];

function suseLazySpinner($timeout, SUSE_LAZY_SPINNER) {
return {
restrict: 'E',
templateUrl: 'app/widgets/suse-lazy-spinner/suse-lazy-spinner.directive.html',
scope: {
active: '=',
visible: '=?',
delay: '@'
},
link: function(scope, elem) {
// dummy-init optional binding values
scope.visible = scope.visible || false;

scope.$watch('active', function(newVal) {
newVal ? showSpinner() : hideSpinner();
});

elem.on('$destroy', hideSpinner);

var timer = null;

function showSpinner() {
if (timer) {
return;
}
timer = $timeout(function() {
elem.removeClass('hidden');
scope.visible = true;
}, getDelay());
}

function hideSpinner() {
// cancel (possibly) pending timer
if (timer) {
$timeout.cancel(timer);
timer = null;
}

elem.addClass('hidden');
scope.visible = false;
}

function getDelay() {
var delay = parseInt(scope.delay);
return isFinite(delay) ? delay : SUSE_LAZY_SPINNER.DEFAULT_DELAY;
}
}
};
}
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*global bard $httpBackend assert $rootScope $compile $timeout */
describe('SUSE Lazy Spinner Directive', function () {

var directiveElement,
scope;

beforeEach(function () {
bard.appModule('crowbarApp');

bard.inject('$rootScope', '$compile', '$httpBackend', '$timeout');

//Mock requests that are expected to be made
$httpBackend.expectGET('app/features/upgrade/i18n/en.json').respond({});
$httpBackend.flush();

scope = $rootScope.$new();
});

function compileDirective(template) {
var element = angular.element(template),
compiledElement = $compile(element)(scope);
scope.$digest();

return compiledElement;
}

// Verify no unexpected http call has been made
bard.verifyNoOutstandingHttpRequests();

describe('directive created with default parameters', function () {
beforeEach(function () {
directiveElement = compileDirective('<suse-lazy-spinner active="testActive"></suse-lazy-spinner>');
});

it('should contain an icon with fa-spin class', function () {
var icons = directiveElement.find('i');
expect(icons.length).toEqual(1);
assert.isTrue(angular.element(icons[0]).hasClass('fa-spin'));
});

describe('attached to inactive model', function () {
beforeEach(function () {
scope.testActive = false;
scope.$digest();
// make sure nothing is scheduled
$timeout.flush();
});

it('should be inactive', function () {
assert.isFalse(directiveElement.isolateScope().active);
});

it('should be hidden', function () {
assert.isTrue(directiveElement.hasClass('hidden'));
});
});

describe('attached to active model', function () {
beforeEach(function () {
scope.testActive = true;
scope.$digest();
});

it('should be active', function () {
assert.isTrue(directiveElement.isolateScope().active);
});

it('should be hidden before the timeout', function () {
assert.isTrue(directiveElement.hasClass('hidden'));
});

it('should not be hidden after the timeout', function () {
$timeout.flush();
assert.isFalse(directiveElement.hasClass('hidden'));
});
});
});

describe('directive with custom delay', function () {
beforeEach(function () {
scope.testActive = true;
directiveElement = compileDirective(
'<suse-lazy-spinner active="testActive" delay="100"></suse-lazy-spinner>'
);
});

it('should have the delay value in the internal scope', function () {
// NOTE: the value is parsed internally in the directive which is not visible from the outside
expect(directiveElement.isolateScope().delay).toEqual('100');
});
});

describe('directive with exposed visiblity', function () {
beforeEach(function () {
directiveElement = compileDirective(
'<suse-lazy-spinner active="testActive" visible="spinnerVisible"></suse-lazy-spinner>'
);
});

describe('attached to active model', function () {
beforeEach(function () {
scope.testActive = true;
scope.$digest();
});

it('should set visibility to false before timeout', function () {
assert.isFalse(scope.spinnerVisible);
});

it('should set visibility to true after timeout', function () {
$timeout.flush();
assert.isTrue(scope.spinnerVisible);
});
});

describe('attached to inactive model', function () {
beforeEach(function () {
scope.testActive = false;
scope.$digest();
// make sure nothing is scheduled
$timeout.flush();
});

it('should set visibility to false', function () {
assert.isFalse(scope.spinnerVisible);
});
});
});
});
5 changes: 5 additions & 0 deletions assets/app/widgets/suse-lazy-spinner/suse-lazy-spinner.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* Start= widgets/suse-lazy-spinner/suse-lazy-spinner.less */
suse-lazy-spinner {
display: inline-block;
}
/* End= widgets/suse-lazy-spinner/suse-lazy-spinner.less */
3 changes: 2 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module.exports = function(config) {
'bower_components/bardjs/dist/bard.js',
'bower_components/bardjs/dist/bard-ngRouteTester.js',
'assets/app/**/*.module.js',
'assets/app/**/*.js'
'assets/app/**/*.js',
'public/app/crowbar-app.templates.js'
],


Expand Down
1 change: 1 addition & 0 deletions views/layout.jade
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ html(ng-app='crowbarApp')
script(src='app/widgets/crowbar-upgrade-steps/crowbar-upgrade-steps.directive.js')
script(src='app/widgets/crowbar-upgrade-nav/crowbar-upgrade-nav.directive.js')
script(src='app/widgets/crowbar-header/crowbar-header.directive.js')
script(src='app/widgets/suse-lazy-spinner/suse-lazy-spinner.directive.js')

// Crowbar Features
// Upgrade State
Expand Down

0 comments on commit d006ca7

Please sign in to comment.