mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
Merge pull request #172 from resin-io/feat/router
Make use of UI Router
This commit is contained in:
commit
7899e2ed59
@ -1250,7 +1250,7 @@ mark,
|
||||
.text-left {
|
||||
text-align: left; }
|
||||
|
||||
.text-right {
|
||||
.text-right, .section-header {
|
||||
text-align: right; }
|
||||
|
||||
.text-center {
|
||||
@ -5854,23 +5854,13 @@ button.close {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px; }
|
||||
|
||||
.space-top-huge {
|
||||
margin-top: 45px; }
|
||||
|
||||
.space-vertical-large {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px; }
|
||||
|
||||
.space-horizontal-large {
|
||||
margin-left: 30px;
|
||||
margin-right: 30px; }
|
||||
|
||||
.space-bottom-large {
|
||||
margin-bottom: 30px; }
|
||||
|
||||
.space-bottom-huge {
|
||||
margin-bottom: 45px; }
|
||||
|
||||
.space-right-tiny {
|
||||
margin-right: 5px; }
|
||||
|
||||
@ -5981,8 +5971,13 @@ body {
|
||||
.checkbox input[type="checkbox"]:not(:checked) + * {
|
||||
color: #ddd; }
|
||||
|
||||
.btn-navigation {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
margin: 20px 60px; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0; }
|
||||
|
||||
.section-header {
|
||||
padding: 5px;
|
||||
font-size: 15px; }
|
||||
|
@ -29,6 +29,7 @@ const BrowserWindow = electron.remote.BrowserWindow;
|
||||
const currentWindow = BrowserWindow.fromId(1);
|
||||
|
||||
require('angular-ui-bootstrap');
|
||||
require('angular-ui-router');
|
||||
require('./browser/modules/selection-state');
|
||||
require('./browser/modules/settings');
|
||||
require('./browser/modules/drive-scanner');
|
||||
@ -37,6 +38,7 @@ require('./browser/modules/path');
|
||||
require('./browser/modules/analytics');
|
||||
|
||||
const app = angular.module('Etcher', [
|
||||
'ui.router',
|
||||
'ui.bootstrap',
|
||||
|
||||
// Etcher modules
|
||||
@ -48,55 +50,71 @@ const app = angular.module('Etcher', [
|
||||
'Etcher.analytics'
|
||||
]);
|
||||
|
||||
app.config(function($stateProvider, $urlRouterProvider) {
|
||||
$urlRouterProvider.otherwise('/main');
|
||||
|
||||
$stateProvider
|
||||
.state('main', {
|
||||
url: '/main',
|
||||
controller: 'AppController as app',
|
||||
templateUrl: './partials/main.html'
|
||||
})
|
||||
.state('success', {
|
||||
url: '/success',
|
||||
controller: 'FinishController as finish',
|
||||
templateUrl: './partials/success.html'
|
||||
})
|
||||
.state('settings', {
|
||||
url: '/settings',
|
||||
controller: 'SettingsController as settings',
|
||||
templateUrl: './partials/settings.html'
|
||||
});
|
||||
});
|
||||
|
||||
app.controller('AppController', function(
|
||||
$q,
|
||||
$state,
|
||||
DriveScannerService,
|
||||
SettingsService,
|
||||
SelectionStateService,
|
||||
ImageWriterService,
|
||||
AnalyticsService
|
||||
) {
|
||||
let self = this;
|
||||
this.settings = SettingsService;
|
||||
this.selection = SelectionStateService;
|
||||
this.writer = ImageWriterService;
|
||||
this.scanner = DriveScannerService;
|
||||
|
||||
this.restart = function(options) {
|
||||
AnalyticsService.logEvent('Restart');
|
||||
this.selection.clear(options);
|
||||
AnalyticsService.logEvent('Restart');
|
||||
|
||||
self.state = {
|
||||
if (!this.writer.isBurning()) {
|
||||
this.state = {
|
||||
progress: 0,
|
||||
percentage: 0
|
||||
};
|
||||
}
|
||||
|
||||
this.scanner.start(2000).on('scan', function(drives) {
|
||||
this.scanner.start(2000).on('scan', function(drives) {
|
||||
|
||||
// Notice we only autoselect the drive if there is an image,
|
||||
// which means that the first step was completed successfully,
|
||||
// otherwise the drive is selected while the drive step is disabled
|
||||
// which looks very weird.
|
||||
if (drives.length === 1 && self.selection.hasImage()) {
|
||||
const drive = _.first(drives);
|
||||
|
||||
// Do not autoselect the same drive over and over again
|
||||
// and fill the logs unnecessary.
|
||||
// `angular.equals` is used instead of `_.isEqual` to
|
||||
// cope with `$$hashKey`.
|
||||
if (!angular.equals(self.selection.getDrive(), drive)) {
|
||||
AnalyticsService.logEvent('Auto-select drive', {
|
||||
device: drive.device
|
||||
});
|
||||
self.selectDrive(drive);
|
||||
}
|
||||
// Notice we only autoselect the drive if there is an image,
|
||||
// which means that the first step was completed successfully,
|
||||
// otherwise the drive is selected while the drive step is disabled
|
||||
// which looks very weird.
|
||||
if (drives.length === 1 && self.selection.hasImage()) {
|
||||
const drive = _.first(drives);
|
||||
|
||||
// Do not autoselect the same drive over and over again
|
||||
// and fill the logs unnecessary.
|
||||
// `angular.equals` is used instead of `_.isEqual` to
|
||||
// cope with `$$hashKey`.
|
||||
if (!angular.equals(self.selection.getDrive(), drive)) {
|
||||
AnalyticsService.logEvent('Auto-select drive', {
|
||||
device: drive.device
|
||||
});
|
||||
self.selectDrive(drive);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
this.restart();
|
||||
}
|
||||
});
|
||||
|
||||
// We manually add `style="display: none;"` to <body>
|
||||
// and unset it here instead of using ngCloak since
|
||||
@ -167,6 +185,7 @@ app.controller('AppController', function(
|
||||
|
||||
}).then(function() {
|
||||
AnalyticsService.logEvent('Done');
|
||||
$state.go('success');
|
||||
}).catch(dialog.showError).finally(function() {
|
||||
|
||||
// Remove progress bar from task bar
|
||||
@ -179,3 +198,18 @@ app.controller('AppController', function(
|
||||
|
||||
this.open = shell.openExternal;
|
||||
});
|
||||
|
||||
app.controller('SettingsController', function(SettingsService) {
|
||||
this.storage = SettingsService.data;
|
||||
});
|
||||
|
||||
app.controller('NavigationController', function($state) {
|
||||
this.isState = $state.is;
|
||||
});
|
||||
|
||||
app.controller('FinishController', function($state, SelectionStateService) {
|
||||
this.restart = function(options) {
|
||||
SelectionStateService.clear(options);
|
||||
$state.go('main');
|
||||
};
|
||||
});
|
||||
|
@ -38,57 +38,4 @@ settings.service('SettingsService', function($localStorage) {
|
||||
errorReporting: true
|
||||
});
|
||||
|
||||
// All this functionality should be gone once
|
||||
// we make use of a real router on the application.
|
||||
// This is not the case yet since when the application
|
||||
// was first prototyped there was only one screen
|
||||
// and therefore a router would have been overkill.
|
||||
|
||||
/**
|
||||
* @summary Configuring state
|
||||
* @type Boolean
|
||||
* @private
|
||||
*/
|
||||
let configuring = false;
|
||||
|
||||
/**
|
||||
* @summary Check if the user is configuring
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @returns {Boolean} whether is configuring
|
||||
*
|
||||
* @example
|
||||
* if (SettingsService.isConfiguring()) {
|
||||
* console.log('User is on settings screen');
|
||||
* }
|
||||
*/
|
||||
this.isConfiguring = function() {
|
||||
return configuring;
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Enter settings screen
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* SettingsService.enter();
|
||||
*/
|
||||
this.enter = function() {
|
||||
configuring = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Leave settings screen
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* SettingsService.leave();
|
||||
*/
|
||||
this.leave = function() {
|
||||
configuring = false;
|
||||
};
|
||||
|
||||
});
|
||||
|
@ -35,6 +35,8 @@ body {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Prevent blue outline */
|
||||
input:focus,
|
||||
button:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
142
lib/index.html
142
lib/index.html
@ -24,142 +24,20 @@
|
||||
|
||||
<script src="./browser/app.js"></script>
|
||||
</head>
|
||||
<body ng-app="Etcher" ng-controller="AppController as app" style="display: none">
|
||||
<div class="content row middle-xs space-horizontal-large" ng-hide="app.settings.isConfiguring()">
|
||||
<button class="btn btn-link btn-navigation" ng-click="app.settings.enter()">
|
||||
<body ng-app="Etcher" style="display: none">
|
||||
<header class="section-header" ng-controller="NavigationController as navigation">
|
||||
<button class="btn btn-link" ui-sref="settings" ng-hide="navigation.isState('settings')">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
|
||||
<div class="col-xs">
|
||||
<div class="row around-xs space-bottom-huge" ng-hide="app.state.progress == 100 && !app.writer.isBurning()">
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<hero-icon path="images/image.svg" label="SELECT IMAGE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium">1</hero-badge>
|
||||
<button class="btn btn-link" ui-sref="main" ng-show="navigation.isState('settings')">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Back
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<div ng-hide="app.selection.hasImage()">
|
||||
<hero-button ng-click="app.selectImage()">Select image</hero-button>
|
||||
<p class="step-footer tiny">*supported files: .img, .iso</p>
|
||||
</div>
|
||||
<div ng-show="app.selection.hasImage()">
|
||||
<span ng-bind="app.selection.getImage() | basename" ng-click="app.reselectImage()"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="wrapper" ui-view></main>
|
||||
|
||||
<div class="col-xs">
|
||||
<div class="box text-center relative">
|
||||
<div class="step-border-left" ng-disabled="!app.selection.hasImage()"></div>
|
||||
<div class="step-border-right" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()"></div>
|
||||
|
||||
<hero-icon path="images/drive.svg" ng-disabled="!app.selection.hasImage()" label="SELECT DRIVE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage()">2</hero-badge>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<div ng-hide="app.selection.hasDrive()">
|
||||
|
||||
<div ng-show="app.scanner.hasAvailableDrives() || !app.selection.hasImage()">
|
||||
<div class="btn-group" uib-dropdown>
|
||||
<hero-button ng-disabled="!app.selection.hasImage()"
|
||||
uib-dropdown-toggle>Select drive</hero-button>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="drive in app.scanner.drives">
|
||||
<a href="#" ng-click="app.selectDrive(drive)" ng-bind="drive.name + ' - ' + drive.size"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="app.scanner.hasAvailableDrives() || !app.selection.hasImage()">
|
||||
<hero-button type="danger">Connect a drive</hero-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ng-show="app.selection.hasDrive()" ng-bind="app.selection.getDrive().name" ng-click="app.reselectDrive()"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<hero-icon path="images/burn.svg" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()" label="BURN IMAGE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">3</hero-badge>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<hero-progress-button percentage="{{ app.state.progress }}" ng-attr-active="{{ app.writer.isBurning() }}"
|
||||
ng-click="app.burn(app.selection.getImage(), app.selection.getDrive())"
|
||||
ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">
|
||||
<span ng-show="app.state.progress == 100 && app.writer.isBurning()">Finishing...</span>
|
||||
<span ng-show="app.state.progress == 0 && !app.writer.isBurning()">Burn!</span>
|
||||
<span ng-show="app.state.progress == 0 && app.writer.isBurning() && !app.state.speed">Starting...</span>
|
||||
<span ng-show="app.state.speed && app.state.progress != 100"
|
||||
ng-bind="app.state.progress + '% '"></span>
|
||||
</hero-progress-button>
|
||||
|
||||
<p class="step-footer" ng-bind="app.state.speed.toFixed(2) + ' MB/s'" ng-show="app.state.speed && app.state.progress != 100"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row around-xs space-bottom-huge" ng-show="app.state.progress == 100 && !app.writer.isBurning()">
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<h3><hero-tick type="success" class="space-right-tiny"></hero-tick> Burn Complete!</h3>
|
||||
<p class="soft">Safely ejected and ready for use</p>
|
||||
|
||||
<div class="row center-xs space-vertical-large">
|
||||
<div class="col-xs-4 space-medium">
|
||||
<div class="box">
|
||||
<p class="soft button-label">Would you like to burn the same image?</p>
|
||||
|
||||
<hero-button ng-click="app.restart({ preserveImage: true })">
|
||||
Use <b>same</b> image
|
||||
</hero-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs separator-xs"></div>
|
||||
|
||||
<div class="col-xs-4 space-medium">
|
||||
<div class="box">
|
||||
<p class="soft button-label">Would you like to burn a new image?</p>
|
||||
|
||||
<hero-button ng-click="app.restart()">
|
||||
Use <b>new</b> image
|
||||
</hero-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content row space-horizontal-large space-top-huge" ng-show="app.settings.isConfiguring()">
|
||||
<div class="col-xs" ng-show="app.settings.isConfiguring()">
|
||||
<button class="btn btn-link btn-navigation" ng-click="app.settings.leave()">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Back
|
||||
</button>
|
||||
|
||||
<div class="box text-left space-horizontal-large">
|
||||
<h1 class="space-bottom-large">Settings</h1>
|
||||
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="app.settings.data.errorReporting">
|
||||
<span>Enable error reporting</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-footer row between-xs middle-xs">
|
||||
<footer class="section-footer row between-xs middle-xs">
|
||||
<div class="col-xs">
|
||||
<div class="box text-left">
|
||||
<hero-icon path="images/resin.svg" width="85px" height="auto" ng-click="app.open('https://resin.io')"></hero-icon>
|
||||
@ -171,6 +49,6 @@
|
||||
<hero-caption><span ng-click="app.open('https://github.com/resin-io/etcher')">AN OPEN SOURCE PROJECT</span> BY <span ng-click="app.open('https://resin.io')">RESIN.IO</span></hero-caption>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
73
lib/partials/main.html
Normal file
73
lib/partials/main.html
Normal file
@ -0,0 +1,73 @@
|
||||
<div class="row around-xs">
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<hero-icon path="images/image.svg" label="SELECT IMAGE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium">1</hero-badge>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<div ng-hide="app.selection.hasImage()">
|
||||
<hero-button ng-click="app.selectImage()">Select image</hero-button>
|
||||
<p class="step-footer tiny">*supported files: .img, .iso</p>
|
||||
</div>
|
||||
<div ng-show="app.selection.hasImage()">
|
||||
<span ng-bind="app.selection.getImage() | basename" ng-click="app.reselectImage()"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs">
|
||||
<div class="box text-center relative">
|
||||
<div class="step-border-left" ng-disabled="!app.selection.hasImage()"></div>
|
||||
<div class="step-border-right" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()"></div>
|
||||
|
||||
<hero-icon path="images/drive.svg" ng-disabled="!app.selection.hasImage()" label="SELECT DRIVE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage()">2</hero-badge>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<div ng-hide="app.selection.hasDrive()">
|
||||
|
||||
<div ng-show="app.scanner.hasAvailableDrives() || !app.selection.hasImage()">
|
||||
<div class="btn-group" uib-dropdown>
|
||||
<hero-button ng-disabled="!app.selection.hasImage()"
|
||||
uib-dropdown-toggle>Select drive</hero-button>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="drive in app.scanner.drives">
|
||||
<a href="#" ng-click="app.selectDrive(drive)" ng-bind="drive.name + ' - ' + drive.size"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="app.scanner.hasAvailableDrives() || !app.selection.hasImage()">
|
||||
<hero-button type="danger">Connect a drive</hero-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ng-show="app.selection.hasDrive()" ng-bind="app.selection.getDrive().name" ng-click="app.reselectDrive()"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<hero-icon path="images/burn.svg" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()" label="BURN IMAGE"></hero-icon>
|
||||
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">3</hero-badge>
|
||||
|
||||
<div class="space-vertical-large">
|
||||
<hero-progress-button percentage="{{ app.state.progress }}" ng-attr-active="{{ app.writer.isBurning() }}"
|
||||
ng-click="app.burn(app.selection.getImage(), app.selection.getDrive())"
|
||||
ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">
|
||||
<span ng-show="app.state.progress == 100 && app.writer.isBurning()">Finishing...</span>
|
||||
<span ng-show="app.state.progress == 0 && !app.writer.isBurning()">Burn!</span>
|
||||
<span ng-show="app.state.progress == 0 && app.writer.isBurning() && !app.state.speed">Starting...</span>
|
||||
<span ng-show="app.state.speed && app.state.progress != 100"
|
||||
ng-bind="app.state.progress + '% '"></span>
|
||||
</hero-progress-button>
|
||||
|
||||
<p class="step-footer" ng-bind="app.state.speed.toFixed(2) + ' MB/s'" ng-show="app.state.speed && app.state.progress != 100"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
10
lib/partials/settings.html
Normal file
10
lib/partials/settings.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="text-left">
|
||||
<h1 class="space-bottom-large">Settings</h1>
|
||||
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="settings.storage.errorReporting">
|
||||
<span>Enable error reporting</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
32
lib/partials/success.html
Normal file
32
lib/partials/success.html
Normal file
@ -0,0 +1,32 @@
|
||||
<div class="row around-xs">
|
||||
<div class="col-xs">
|
||||
<div class="box text-center">
|
||||
<h3><hero-tick type="success" class="space-right-tiny"></hero-tick> Burn Complete!</h3>
|
||||
<p class="soft">Safely ejected and ready for use</p>
|
||||
|
||||
<div class="row center-xs space-vertical-large">
|
||||
<div class="col-xs-4 space-medium">
|
||||
<div class="box">
|
||||
<p class="soft button-label">Would you like to burn the same image?</p>
|
||||
|
||||
<hero-button ng-click="finish.restart({ preserveImage: true })">
|
||||
Use <b>same</b> image
|
||||
</hero-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs separator-xs"></div>
|
||||
|
||||
<div class="col-xs-4 space-medium">
|
||||
<div class="box">
|
||||
<p class="soft button-label">Would you like to burn a new image?</p>
|
||||
|
||||
<hero-button ng-click="finish.restart()">
|
||||
Use <b>new</b> image
|
||||
</hero-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -184,9 +184,17 @@ body {
|
||||
color: $gray-light;
|
||||
}
|
||||
|
||||
.btn-navigation {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
margin: 20px 60px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
@extend .text-right;
|
||||
padding: 5px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
$spacing-huge: 45px;
|
||||
$spacing-large: 30px;
|
||||
$spacing-medium: 15px;
|
||||
$spacing-tiny: 5px;
|
||||
@ -28,28 +27,15 @@ $spacing-tiny: 5px;
|
||||
margin-bottom: $spacing-medium;
|
||||
}
|
||||
|
||||
.space-top-huge {
|
||||
margin-top: $spacing-huge;
|
||||
}
|
||||
|
||||
.space-vertical-large {
|
||||
margin-top: $spacing-large;
|
||||
margin-bottom: $spacing-large;
|
||||
}
|
||||
|
||||
.space-horizontal-large {
|
||||
margin-left: $spacing-large;
|
||||
margin-right: $spacing-large;
|
||||
}
|
||||
|
||||
.space-bottom-large {
|
||||
margin-bottom: $spacing-large;
|
||||
}
|
||||
|
||||
.space-bottom-huge {
|
||||
margin-bottom: $spacing-huge;
|
||||
}
|
||||
|
||||
.space-right-tiny {
|
||||
margin-right: $spacing-tiny;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@
|
||||
"dependencies": {
|
||||
"angular": "^1.4.6",
|
||||
"angular-ui-bootstrap": "^1.2.1",
|
||||
"angular-ui-router": "^0.2.18",
|
||||
"bluebird": "^3.0.5",
|
||||
"bootstrap-sass": "^3.3.5",
|
||||
"drivelist": "^2.0.7",
|
||||
|
@ -1,51 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const m = require('mochainon');
|
||||
const angular = require('angular');
|
||||
require('angular-mocks');
|
||||
require('../../../lib/browser/modules/settings');
|
||||
|
||||
describe('Browser: Settings', function() {
|
||||
|
||||
beforeEach(angular.mock.module('Etcher.settings'));
|
||||
|
||||
describe('SettingsService', function() {
|
||||
|
||||
let SettingsService;
|
||||
|
||||
beforeEach(angular.mock.inject(function(_SettingsService_) {
|
||||
SettingsService = _SettingsService_;
|
||||
}));
|
||||
|
||||
describe('.isConfiguring()', function() {
|
||||
|
||||
it('should initially return false', function() {
|
||||
m.chai.expect(SettingsService.isConfiguring()).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.enter()', function() {
|
||||
|
||||
it('should be able to enter settings', function() {
|
||||
m.chai.expect(SettingsService.isConfiguring()).to.be.false;
|
||||
SettingsService.enter();
|
||||
m.chai.expect(SettingsService.isConfiguring()).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.leave()', function() {
|
||||
|
||||
it('should be able to leave settings', function() {
|
||||
SettingsService.enter();
|
||||
m.chai.expect(SettingsService.isConfiguring()).to.be.true;
|
||||
SettingsService.leave();
|
||||
m.chai.expect(SettingsService.isConfiguring()).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user