Connect DriveSelector with SelectionStateModel (#305)

Previously, `DriveSelector` kept a temporary selection state until the
modal was closed, which caused the selected drives to be passed to
`SelectionStateModel`.

This proves to be problematic when attempting to pass changes to
`SelectionStateModel` to `DriveSelector`. For example, consider the case
where the `DriveSelector` modal is opened with two drives, and one is
ejected. The remaining drive will be auto-selected by Etcher in the
background, but `DriveSelector` will not update itself with such change.

Fixes: https://github.com/resin-io/etcher/issues/304
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-04-12 14:42:51 -04:00
parent aba6e946e3
commit e3bac8dc64
5 changed files with 52 additions and 17 deletions

View File

@ -23,10 +23,12 @@
const angular = require('angular'); const angular = require('angular');
require('angular-ui-bootstrap'); require('angular-ui-bootstrap');
require('../../../browser/modules/drive-scanner'); require('../../../browser/modules/drive-scanner');
require('../../../browser/models/selection-state');
const DriveSelector = angular.module('Etcher.Components.DriveSelector', [ const DriveSelector = angular.module('Etcher.Components.DriveSelector', [
'ui.bootstrap', 'ui.bootstrap',
'Etcher.drive-scanner' 'Etcher.drive-scanner',
'Etcher.Models.SelectionState'
]); ]);
DriveSelector.controller('DriveSelectorController', require('./controllers/drive-selector')); DriveSelector.controller('DriveSelectorController', require('./controllers/drive-selector'));

View File

@ -18,7 +18,8 @@
const _ = require('lodash'); const _ = require('lodash');
module.exports = function() { module.exports = function(SelectionStateModel) {
let self = this;
/** /**
* @summary Toggle select drive * @summary Toggle select drive
@ -32,9 +33,9 @@ module.exports = function() {
*/ */
this.toggleSelectDrive = function(drive) { this.toggleSelectDrive = function(drive) {
if (this.isSelectedDrive(drive)) { if (this.isSelectedDrive(drive)) {
this.selectedDrive = null; SelectionStateModel.removeDrive();
} else { } else {
this.selectedDrive = drive; SelectionStateModel.setDrive(drive);
} }
}; };
@ -56,7 +57,7 @@ module.exports = function() {
return false; return false;
} }
return drive.device === _.get(this.selectedDrive, 'device'); return drive.device === _.get(self.getSelectedDrive(), 'device');
}; };
/** /**
@ -69,12 +70,6 @@ module.exports = function() {
* @example * @example
* const drive = DriveSelectorStateService.getSelectedDrive(); * const drive = DriveSelectorStateService.getSelectedDrive();
*/ */
this.getSelectedDrive = function() { this.getSelectedDrive = SelectionStateModel.getDrive;
if (_.isEmpty(this.selectedDrive)) {
return;
}
return this.selectedDrive;
};
}; };

View File

@ -75,6 +75,10 @@ SelectionStateModel.service('SelectionStateModel', function() {
* const drive = SelectionStateModel.getDrive(); * const drive = SelectionStateModel.getDrive();
*/ */
this.getDrive = function() { this.getDrive = function() {
if (_.isEmpty(selection.drive)) {
return;
}
return selection.drive; return selection.drive;
}; };

View File

@ -12,11 +12,17 @@ describe('Browser: DriveSelector', function() {
describe('DriveSelectorStateService', function() { describe('DriveSelectorStateService', function() {
let DriveSelectorStateService; let DriveSelectorStateService;
let SelectionStateModel;
beforeEach(angular.mock.inject(function(_DriveSelectorStateService_) { beforeEach(angular.mock.inject(function(_DriveSelectorStateService_, _SelectionStateModel_) {
DriveSelectorStateService = _DriveSelectorStateService_; DriveSelectorStateService = _DriveSelectorStateService_;
SelectionStateModel = _SelectionStateModel_;
})); }));
beforeEach(function() {
SelectionStateModel.clear();
});
describe('.toggleSelectDrive()', function() { describe('.toggleSelectDrive()', function() {
it('should be able to toggle a drive', function() { it('should be able to toggle a drive', function() {
@ -63,7 +69,7 @@ describe('Browser: DriveSelector', function() {
size: '16GB' size: '16GB'
}; };
DriveSelectorStateService.selectedDrive = null; SelectionStateModel.removeDrive();
m.chai.expect(DriveSelectorStateService.isSelectedDrive(drive)).to.be.false; m.chai.expect(DriveSelectorStateService.isSelectedDrive(drive)).to.be.false;
}); });
@ -96,22 +102,33 @@ describe('Browser: DriveSelector', function() {
}); });
it('should return false if there is no selected drive and an empty object is passed', function() { it('should return false if there is no selected drive and an empty object is passed', function() {
DriveSelectorStateService.selectedDrive = undefined; SelectionStateModel.removeDrive();
m.chai.expect(DriveSelectorStateService.isSelectedDrive({})).to.be.false; m.chai.expect(DriveSelectorStateService.isSelectedDrive({})).to.be.false;
}); });
it('should return true if the drive is selected in SelectionStateModel', function() {
const drive = {
device: '/dev/disk2',
name: 'USB Drive',
size: '16GB'
};
SelectionStateModel.setDrive(drive);
m.chai.expect(DriveSelectorStateService.isSelectedDrive(drive)).to.be.true;
});
}); });
describe('.getSelectedDrive()', function() { describe('.getSelectedDrive()', function() {
it('should return undefined if no selected drive', function() { it('should return undefined if no selected drive', function() {
DriveSelectorStateService.selectedDrive = null; SelectionStateModel.removeDrive();
const drive = DriveSelectorStateService.getSelectedDrive(); const drive = DriveSelectorStateService.getSelectedDrive();
m.chai.expect(drive).to.not.exist; m.chai.expect(drive).to.not.exist;
}); });
it('should return undefined if the selected drive is an empty object', function() { it('should return undefined if the selected drive is an empty object', function() {
DriveSelectorStateService.selectedDrive = {}; SelectionStateModel.setDrive({});
const drive = DriveSelectorStateService.getSelectedDrive(); const drive = DriveSelectorStateService.getSelectedDrive();
m.chai.expect(drive).to.not.exist; m.chai.expect(drive).to.not.exist;
}); });

View File

@ -45,6 +45,23 @@ describe('Browser: SelectionState', function() {
}); });
describe('given an empty object drive', function() {
beforeEach(function() {
SelectionStateModel.setDrive({});
});
describe('.getDrive()', function() {
it('should return undefined', function() {
const drive = SelectionStateModel.getDrive();
m.chai.expect(drive).to.be.undefined;
});
});
});
describe('given a drive', function() { describe('given a drive', function() {
beforeEach(function() { beforeEach(function() {