diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js
index c3ee1ddc..65eef47c 100644
--- a/lib/gui/app/app.js
+++ b/lib/gui/app/app.js
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 resin.io
+ * Copyright 2016 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,6 @@ const settings = require('./models/settings')
const windowProgress = require('./os/window-progress')
const analytics = require('./modules/analytics')
const availableDrives = require('./models/available-drives')
-const selectionState = require('./models/selection-state')
const driveScanner = require('./modules/drive-scanner')
const osDialog = require('./os/dialog')
const exceptionReporter = require('./modules/exception-reporter')
@@ -52,7 +51,7 @@ const updateLock = require('./modules/update-lock')
// See https://github.com/visionmedia/debug#browser-support
//
// Enable drivelist debugging information
-// See https://github.com/resin-io-modules/drivelist
+// See https://github.com/balena-io-modules/drivelist
process.env.DRIVELIST_DEBUG = /drivelist|^\*$/i.test(process.env.DEBUG) ? '1' : ''
window.localStorage.debug = process.env.DEBUG
@@ -87,21 +86,11 @@ const app = angular.module('Etcher', [
// Components
require('./components/svg-icon'),
- require('./components/warning-modal/warning-modal'),
require('./components/safe-webview'),
- require('./components/file-selector'),
// Pages
- require('./pages/main/main'),
- require('./pages/finish/finish'),
- require('./components/settings/index.ts').MODULE_NAME,
-
- // OS
- require('./os/open-external/open-external'),
- require('./os/dropzone/dropzone'),
-
- // Utils
- require('./utils/manifest-bind/manifest-bind')
+ require('./pages/main/main.ts').MODULE_NAME,
+ require('./components/finish/index.ts').MODULE_NAME
])
app.run(() => {
@@ -421,40 +410,6 @@ app.config(($locationProvider) => {
})
})
-app.controller('HeaderController', function (OSOpenExternalService) {
- /**
- * @summary Open help page
- * @function
- * @public
- *
- * @description
- * This application will open either the image's support url, declared
- * in the archive `manifest.json`, or the default Etcher help page.
- *
- * @example
- * HeaderController.openHelpPage();
- */
- this.openHelpPage = () => {
- const DEFAULT_SUPPORT_URL = 'https://github.com/resin-io/etcher/blob/master/SUPPORT.md'
- const supportUrl = selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL
- OSOpenExternalService.open(supportUrl)
- }
-
- /**
- * @summary Whether to show the help link
- * @function
- * @public
- *
- * @returns {Boolean}
- *
- * @example
- * HeaderController.shouldShowHelp()
- */
- this.shouldShowHelp = () => {
- return !settings.get('disableExternalLinks')
- }
-})
-
app.controller('StateController', function ($rootScope, $scope) {
const unregisterStateChange = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
this.previousName = fromState.name
@@ -492,13 +447,6 @@ app.controller('StateController', function ($rootScope, $scope) {
this.currentName = null
})
-// Handle keyboard shortcut to open the settings
-app.run(($state) => {
- electron.ipcRenderer.on('menu:preferences', () => {
- $state.go('settings')
- })
-})
-
// Ensure user settings are loaded before
// we bootstrap the Angular.js application
angular.element(document).ready(() => {
diff --git a/lib/gui/app/components/confirm-modal/confirm-modal.js b/lib/gui/app/components/confirm-modal/confirm-modal.js
deleted file mode 100644
index c5c09a89..00000000
--- a/lib/gui/app/components/confirm-modal/confirm-modal.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2018 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.ConfirmModal
- */
-
-const angular = require('angular')
-const MODULE_NAME = 'Etcher.Components.ConfirmModal'
-const ConfirmModal = angular.module(MODULE_NAME, [
- require('../modal/modal')
-])
-
-ConfirmModal.controller('ConfirmModalController', require('./controllers/confirm-modal'))
-ConfirmModal.service('ConfirmModalService', require('./services/confirm-modal'))
-
-module.exports = MODULE_NAME
diff --git a/lib/gui/app/components/confirm-modal/controllers/confirm-modal.js b/lib/gui/app/components/confirm-modal/controllers/confirm-modal.js
deleted file mode 100644
index 983f7db7..00000000
--- a/lib/gui/app/components/confirm-modal/controllers/confirm-modal.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2018 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, options) {
- /**
- * @summary Modal options
- * @type {Object}
- * @public
- */
- this.options = options
-
- /**
- * @summary Reject the warning prompt
- * @function
- * @public
- *
- * @example
- * WarningModalController.reject();
- */
- this.reject = () => {
- $uibModalInstance.close(false)
- }
-
- /**
- * @summary Accept the warning prompt
- * @function
- * @public
- *
- * @example
- * WarningModalController.accept();
- */
- this.accept = () => {
- $uibModalInstance.close(true)
- }
-}
diff --git a/lib/gui/app/components/confirm-modal/services/confirm-modal.js b/lib/gui/app/components/confirm-modal/services/confirm-modal.js
deleted file mode 100644
index 497b98e1..00000000
--- a/lib/gui/app/components/confirm-modal/services/confirm-modal.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2018 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 ($sce, ModalService) {
- /**
- * @summary show the confirm modal
- * @function
- * @public
- *
- * @param {Object} options - options
- * @param {String} options.description - danger message
- * @param {String} options.confirmationLabel - confirmation button text
- * @param {String} options.rejectionLabel - rejection button text
- * @fulfil {Boolean} - whether the user accepted or rejected the confirm
- * @returns {Promise}
- *
- * @example
- * ConfirmModalService.show({
- * description: 'Don\'t do this!',
- * confirmationLabel: 'Yes, continue!'
- * });
- */
- this.show = (options = {}) => {
- options.description = $sce.trustAsHtml(options.description)
- return ModalService.open({
- name: 'confirm',
- template: require('../templates/confirm-modal.tpl.html'),
- controller: 'ConfirmModalController as modal',
- size: 'confirm-modal',
- resolve: {
- options: _.constant(options)
- }
- }).result
- }
-}
diff --git a/lib/gui/app/components/confirm-modal/styles/confirm-modal.scss b/lib/gui/app/components/confirm-modal/styles/confirm-modal.scss
deleted file mode 100644
index b13cafa7..00000000
--- a/lib/gui/app/components/confirm-modal/styles/confirm-modal.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-.modal-confirm-modal .modal-content {
- width: 350px;
-}
-
-.modal-confirm-modal .modal-title .glyphicon {
- color: $palette-theme-danger-background;
-}
-
-.modal-confirm-modal .modal-body {
- max-height: 200px;
- overflow-y: auto;
-}
diff --git a/lib/gui/app/components/confirm-modal/templates/confirm-modal.tpl.html b/lib/gui/app/components/confirm-modal/templates/confirm-modal.tpl.html
deleted file mode 100644
index d0f5cf04..00000000
--- a/lib/gui/app/components/confirm-modal/templates/confirm-modal.tpl.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
{{ ::modal.options.message }}
-
-
-
-
diff --git a/lib/gui/app/components/drive-selector/DriveSelectorModal.jsx b/lib/gui/app/components/drive-selector/DriveSelectorModal.jsx
new file mode 100644
index 00000000..ac47c2ac
--- /dev/null
+++ b/lib/gui/app/components/drive-selector/DriveSelectorModal.jsx
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2019 balena.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')
+const React = require('react')
+const { Modal } = require('rendition')
+const {
+ isDriveValid,
+ getDriveImageCompatibilityStatuses,
+ hasListDriveImageCompatibilityStatus,
+ COMPATIBILITY_STATUS_TYPES
+} = require('../../../../shared/drive-constraints')
+const store = require('../../models/store')
+const analytics = require('../../modules/analytics')
+const availableDrives = require('../../models/available-drives')
+const selectionState = require('../../models/selection-state')
+const { bytesToClosestUnit } = require('../../../../shared/units')
+const utils = require('../../../../shared/utils')
+const { open: openExternal } = require('../../os/open-external/services/open-external')
+
+/**
+ * @summary Determine if we can change a drive's selection state
+ * @function
+ * @private
+ *
+ * @param {Object} drive - drive
+ * @returns {Promise}
+ *
+ * @example
+ * shouldChangeDriveSelectionState(drive)
+ * .then((shouldChangeDriveSelectionState) => {
+ * if (shouldChangeDriveSelectionState) doSomething();
+ * });
+ */
+const shouldChangeDriveSelectionState = (drive) => {
+ return isDriveValid(drive, selectionState.getImage())
+}
+
+/**
+ * @summary Toggle a drive selection
+ * @function
+ * @public
+ *
+ * @param {Object} drive - drive
+ * @returns {void}
+ *
+ * @example
+ * toggleDrive({
+ * device: '/dev/disk2',
+ * size: 999999999,
+ * name: 'Cruzer USB drive'
+ * });
+ */
+const toggleDrive = (drive) => {
+ const canChangeDriveSelectionState = shouldChangeDriveSelectionState(drive)
+
+ if (canChangeDriveSelectionState) {
+ analytics.logEvent('Toggle drive', {
+ drive,
+ previouslySelected: selectionState.isCurrentDrive(availableDrives.device),
+ applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
+ flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
+ })
+
+ selectionState.toggleDrive(drive.device)
+ }
+}
+
+/**
+ * @summary Memoized getDrives function
+ * @function
+ * @public
+ *
+ * @returns {Array