mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
fix(GUI): backdrop click error on modals (#601)
When the user clicks on the backdrop of a modal, the modal promise gets rejected, therefore triggering our application error handler. UI Bootstrap provides a way to disable the backdrop completely, but doesn't provide a way to allow a backdrop click to simply close the modal rather than rejecting it, as if an issue happened. To mitigate this issue, and still preserve the backdrop functionality, we created `ModalService`, which abstracts the messy details of calling `$uibModal`, and has custom logic to ignore "backdrop click" errors. Change-Type: patch Changelog-Entry: Fix "backdrop click" uncaught errors on modals. Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
parent
2d1b2ccf6e
commit
d72364115d
@ -23,7 +23,7 @@
|
||||
const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Components.DriveSelector';
|
||||
const DriveSelector = angular.module(MODULE_NAME, [
|
||||
require('angular-ui-bootstrap'),
|
||||
require('../modal/modal'),
|
||||
require('../../models/drives'),
|
||||
require('../../models/selection-state'),
|
||||
require('../../utils/byte-size/byte-size')
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function($uibModal, $q) {
|
||||
module.exports = function(ModalService, $q) {
|
||||
|
||||
let modal = null;
|
||||
|
||||
@ -34,11 +34,9 @@ module.exports = function($uibModal, $q) {
|
||||
* });
|
||||
*/
|
||||
this.open = () => {
|
||||
modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: './components/drive-selector/templates/drive-selector-modal.tpl.html',
|
||||
controller: 'DriveSelectorController as modal',
|
||||
size: 'sm'
|
||||
modal = ModalService.open({
|
||||
template: './components/drive-selector/templates/drive-selector-modal.tpl.html',
|
||||
controller: 'DriveSelectorController as modal'
|
||||
});
|
||||
|
||||
return modal.result;
|
||||
|
31
lib/gui/components/modal/modal.js
Normal file
31
lib/gui/components/modal/modal.js
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 Etcher.Components.Modal
|
||||
*/
|
||||
|
||||
const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Components.Modal';
|
||||
const Modal = angular.module(MODULE_NAME, [
|
||||
require('angular-ui-bootstrap')
|
||||
]);
|
||||
|
||||
Modal.service('ModalService', require('./services/modal'));
|
||||
|
||||
module.exports = MODULE_NAME;
|
74
lib/gui/components/modal/services/modal.js
Normal file
74
lib/gui/components/modal/services/modal.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = function($uibModal, $q) {
|
||||
|
||||
/**
|
||||
* @summary Open a modal
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {Object} options - options
|
||||
* @param {String} options.template - template path
|
||||
* @param {String} options.controller - controller
|
||||
* @param {String} [options.size='sm'] - modal size
|
||||
* @param {Object} options.resolve - modal resolves
|
||||
* @returns {Object} modal
|
||||
*
|
||||
* @example
|
||||
* ModalService.open({
|
||||
* template: './path/to/modal.tpl.html',
|
||||
* controller: 'DriveSelectorController as modal',
|
||||
* });
|
||||
*/
|
||||
this.open = (options = {}) => {
|
||||
|
||||
_.defaults(options, {
|
||||
size: 'sm'
|
||||
});
|
||||
|
||||
const modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: options.template,
|
||||
controller: options.controller,
|
||||
size: options.size,
|
||||
resolve: options.resolve
|
||||
});
|
||||
|
||||
return {
|
||||
close: modal.close,
|
||||
result: $q((resolve, reject) => {
|
||||
modal.result
|
||||
.then(resolve)
|
||||
.catch((error) => {
|
||||
|
||||
// For some annoying reason, UI Bootstrap Modal rejects
|
||||
// the result reason if the user clicks on the backdrop
|
||||
// (e.g: the area surrounding the modal).
|
||||
if (error !== 'backdrop click') {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
};
|
@ -18,7 +18,7 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = function($uibModal) {
|
||||
module.exports = function(ModalService) {
|
||||
|
||||
/**
|
||||
* @summary Open the tooltip modal
|
||||
@ -37,9 +37,8 @@ module.exports = function($uibModal) {
|
||||
* });
|
||||
*/
|
||||
this.show = (options) => {
|
||||
return $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: './components/tooltip-modal/templates/tooltip-modal.tpl.html',
|
||||
return ModalService.open({
|
||||
template: './components/tooltip-modal/templates/tooltip-modal.tpl.html',
|
||||
controller: 'TooltipModalController as modal',
|
||||
size: 'tooltip-modal',
|
||||
resolve: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Components.TooltipModal';
|
||||
const TooltipModal = angular.module(MODULE_NAME, [
|
||||
require('angular-ui-bootstrap')
|
||||
require('../modal/modal')
|
||||
]);
|
||||
|
||||
TooltipModal.controller('TooltipModalController', require('./controllers/tooltip-modal'));
|
||||
|
@ -19,7 +19,7 @@
|
||||
const semver = require('semver');
|
||||
const etcherLatestVersion = require('etcher-latest-version');
|
||||
|
||||
module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) {
|
||||
module.exports = function($http, $q, ModalService, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) {
|
||||
|
||||
/**
|
||||
* @summary Get the latest available Etcher version
|
||||
@ -111,9 +111,8 @@ module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, Mani
|
||||
* UpdateNotifierService.notify();
|
||||
*/
|
||||
this.notify = () => {
|
||||
return $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: './components/update-notifier/templates/update-notifier-modal.tpl.html',
|
||||
return ModalService.open({
|
||||
template: './components/update-notifier/templates/update-notifier-modal.tpl.html',
|
||||
controller: 'UpdateNotifierController as modal',
|
||||
size: 'update-notifier'
|
||||
}).result;
|
||||
|
@ -23,7 +23,7 @@
|
||||
const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Components.UpdateNotifier';
|
||||
const UpdateNotifier = angular.module(MODULE_NAME, [
|
||||
require('angular-ui-bootstrap'),
|
||||
require('../modal/modal'),
|
||||
require('../../models/settings'),
|
||||
require('../../utils/manifest-bind/manifest-bind'),
|
||||
require('../../os/open-external/open-external')
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = function($uibModal, SettingsModel) {
|
||||
module.exports = function(ModalService, SettingsModel) {
|
||||
|
||||
/**
|
||||
* @summary Refresh current settings
|
||||
@ -62,9 +62,8 @@ module.exports = function($uibModal, SettingsModel) {
|
||||
return this.refreshSettings();
|
||||
}
|
||||
|
||||
$uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: './pages/settings/templates/settings-dangerous-modal.tpl.html',
|
||||
ModalService.open({
|
||||
template: './pages/settings/templates/settings-dangerous-modal.tpl.html',
|
||||
controller: 'SettingsDangerousModalController as modal',
|
||||
size: 'settings-dangerous-modal',
|
||||
resolve: {
|
||||
|
@ -24,6 +24,7 @@ const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Pages.Settings';
|
||||
const SettingsPage = angular.module(MODULE_NAME, [
|
||||
require('angular-ui-router'),
|
||||
require('../../components/modal/modal'),
|
||||
require('../../models/settings')
|
||||
]);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user