diff --git a/build/css/main.css b/build/css/main.css index ee32e6e8..09b0b06c 100644 --- a/build/css/main.css +++ b/build/css/main.css @@ -5945,6 +5945,9 @@ html { margin-top: 10px; margin-bottom: 10px; } +.space-top-large, .page-settings .subtitle { + margin-top: 30px; } + .space-top-medium { margin-top: 15px; } @@ -5952,6 +5955,9 @@ html { margin-top: 30px; margin-bottom: 30px; } +.space-bottom-medium, .page-settings .subtitle { + margin-bottom: 15px; } + .space-bottom-large { margin-bottom: 30px; } @@ -6515,6 +6521,36 @@ button.btn:focus, button.progress-button:focus { .page-settings .checkbox input[type="checkbox"]:not(:checked) + * { color: #ddd; } +.modal-settings-dangerous-modal { + max-width: 50%; } + .modal-settings-dangerous-modal .modal-header { + text-align: center; + font-weight: bold; + color: #555555; + text-transform: initial; + font-size: 15px; + border-bottom: none; + padding: 0 0 15px; } + .modal-settings-dangerous-modal .modal-title { + display: flex; + justify-content: center; + align-items: center; } + .modal-settings-dangerous-modal .modal-title .glyphicon, .modal-settings-dangerous-modal .modal-title .tick { + margin-right: 3px; + color: #d9534f; } + .modal-settings-dangerous-modal .modal-content { + padding: 25px 30px; + height: 220px; } + .modal-settings-dangerous-modal .modal-body { + padding: 0; } + .modal-settings-dangerous-modal .modal-footer { + padding: 0; + padding-top: 20px; + border-top: 1px solid #eeeeee; + display: flex; } + .modal-settings-dangerous-modal .modal-footer > .btn, .modal-settings-dangerous-modal .modal-footer > .progress-button { + flex-basis: 50%; } + /* * Copyright 2016 Resin.io * diff --git a/lib/gui/models/store.js b/lib/gui/models/store.js index b6977340..29bb3215 100644 --- a/lib/gui/models/store.js +++ b/lib/gui/models/store.js @@ -37,6 +37,7 @@ const DEFAULT_STATE = Immutable.fromJS({ speed: 0 }, settings: { + unsafeMode: false, errorReporting: true, unmountOnSuccess: true, validateWriteOnSuccess: true, diff --git a/lib/gui/modules/drive-scanner.js b/lib/gui/modules/drive-scanner.js index 305ed7ce..66aab446 100644 --- a/lib/gui/modules/drive-scanner.js +++ b/lib/gui/modules/drive-scanner.js @@ -27,9 +27,11 @@ const EventEmitter = require('events').EventEmitter; const drivelist = require('drivelist'); const MODULE_NAME = 'Etcher.Modules.DriveScanner'; -const driveScanner = angular.module(MODULE_NAME, []); +const driveScanner = angular.module(MODULE_NAME, [ + require('../models/settings') +]); -driveScanner.factory('DriveScannerService', () => { +driveScanner.factory('DriveScannerService', (SettingsModel) => { const DRIVE_SCANNER_INTERVAL_MS = 2000; const emitter = new EventEmitter(); @@ -38,6 +40,10 @@ driveScanner.factory('DriveScannerService', () => { return Rx.Observable.fromNodeCallback(drivelist.list)(); }) .map((drives) => { + if (SettingsModel.get('unsafeMode')) { + return drives; + } + return _.reject(drives, (drive) => { return drive.system; }); diff --git a/lib/gui/pages/settings/controllers/settings-dangerous-modal.js b/lib/gui/pages/settings/controllers/settings-dangerous-modal.js new file mode 100644 index 00000000..c9978f0f --- /dev/null +++ b/lib/gui/pages/settings/controllers/settings-dangerous-modal.js @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +module.exports = function($uibModalInstance, message) { + + /** + * @summary Modal message + * @property + * @public + */ + this.message = message; + + /** + * @summary Reject the dangerous setting + * @function + * @public + * + * @example + * SettingsDangerousModalController.reject(); + */ + this.reject = () => { + $uibModalInstance.close(false); + }; + + /** + * @summary Accept the dangerous setting + * @function + * @public + * + * @example + * SettingsDangerousModalController.accept(); + */ + this.accept = () => { + $uibModalInstance.close(true); + }; + +}; diff --git a/lib/gui/pages/settings/controllers/settings.js b/lib/gui/pages/settings/controllers/settings.js index b96b9b05..e2d8f25c 100644 --- a/lib/gui/pages/settings/controllers/settings.js +++ b/lib/gui/pages/settings/controllers/settings.js @@ -16,14 +16,26 @@ 'use strict'; -module.exports = function(SettingsModel) { +const _ = require('lodash'); + +module.exports = function($uibModal, SettingsModel) { + + /** + * @summary Refresh current settings + * @function + * @public + */ + this.refreshSettings = () => { + this.currentData = SettingsModel.getAll(); + }; /** * @summary Current settings value * @type Object * @public */ - this.currentData = SettingsModel.getAll(); + this.currentData = {}; + this.refreshSettings(); /** * @summary Settings model @@ -32,4 +44,36 @@ module.exports = function(SettingsModel) { */ this.model = SettingsModel; + /** + * @summary Enable a dangerous setting + * @function + * @public + * + * @param {String} name - setting name + * @param {String} message - danger message + * @returns {Undefined} + * + * @example + * SettingsController.enableDangerousSetting('unsafeMode', 'Don\'t do this!'); + */ + this.enableDangerousSetting = (name, message) => { + if (!this.currentData[name]) { + this.model.set(name, false); + return this.refreshSettings(); + } + + $uibModal.open({ + animation: true, + templateUrl: './pages/settings/templates/settings-dangerous-modal.tpl.html', + controller: 'SettingsDangerousModalController as modal', + size: 'settings-dangerous-modal', + resolve: { + message: _.constant(message) + } + }).result.then((userAccepted) => { + this.model.set(name, Boolean(userAccepted)); + this.refreshSettings(); + }); + }; + }; diff --git a/lib/gui/pages/settings/settings.js b/lib/gui/pages/settings/settings.js index d9cbac17..b7fb6af8 100644 --- a/lib/gui/pages/settings/settings.js +++ b/lib/gui/pages/settings/settings.js @@ -28,6 +28,7 @@ const SettingsPage = angular.module(MODULE_NAME, [ ]); SettingsPage.controller('SettingsController', require('./controllers/settings')); +SettingsPage.controller('SettingsDangerousModalController', require('./controllers/settings-dangerous-modal')); SettingsPage.config(($stateProvider) => { $stateProvider diff --git a/lib/gui/pages/settings/styles/_settings.scss b/lib/gui/pages/settings/styles/_settings.scss index fae101af..04b89128 100644 --- a/lib/gui/pages/settings/styles/_settings.scss +++ b/lib/gui/pages/settings/styles/_settings.scss @@ -18,3 +18,52 @@ color: $gray-light; } +.page-settings .subtitle { + @extend .space-top-large; + @extend .space-bottom-medium; +} + +.modal-settings-dangerous-modal { + max-width: 50%; + + .modal-header { + text-align: center; + font-weight: bold; + color: $gray; + text-transform: initial; + font-size: 15px; + border-bottom: none; + padding: 0 0 15px; + } + + .modal-title { + display: flex; + justify-content: center; + align-items: center; + + .glyphicon { + margin-right: 3px; + color: $btn-danger-bg; + } + } + + .modal-content { + padding: 25px 30px; + height: 220px; + } + + .modal-body { + padding: 0; + } + + .modal-footer { + padding: 0; + padding-top: 20px; + border-top: 1px solid $gray-lighter; + display: flex; + + & > .btn { + flex-basis: 50%; + } + } +} diff --git a/lib/gui/pages/settings/templates/settings-dangerous-modal.tpl.html b/lib/gui/pages/settings/templates/settings-dangerous-modal.tpl.html new file mode 100644 index 00000000..5e7a85a9 --- /dev/null +++ b/lib/gui/pages/settings/templates/settings-dangerous-modal.tpl.html @@ -0,0 +1,18 @@ + + + + + diff --git a/lib/gui/pages/settings/templates/settings.tpl.html b/lib/gui/pages/settings/templates/settings.tpl.html index 79f0d71d..df6bce9d 100644 --- a/lib/gui/pages/settings/templates/settings.tpl.html +++ b/lib/gui/pages/settings/templates/settings.tpl.html @@ -30,4 +30,16 @@ Validate write on success + +

Advanced

+ +
+ +
diff --git a/lib/gui/scss/modules/_space.scss b/lib/gui/scss/modules/_space.scss index 73f8cb1f..160522ae 100644 --- a/lib/gui/scss/modules/_space.scss +++ b/lib/gui/scss/modules/_space.scss @@ -33,6 +33,10 @@ $spacing-tiny: 5px; margin-bottom: $spacing-small; } +.space-top-large { + margin-top: $spacing-large; +} + .space-top-medium { margin-top: $spacing-medium; } @@ -42,6 +46,10 @@ $spacing-tiny: 5px; margin-bottom: $spacing-large; } +.space-bottom-medium { + margin-bottom: $spacing-medium; +} + .space-bottom-large { margin-bottom: $spacing-large; }