etcher/lib/shared/models/selection-state.js
Benedict Aas 4140d49db3
refactor: multi-writes preparatory changes (#2124)
We add some preparatory changes including new utility functions, as well
as changes throughout the codebase that reflect the change from single
drives to a list of drives, given multi-writes is coming.

Change-Type: patch
Changelog-Entry: Various preparatory changes to account for
multi-writes.
2018-03-23 14:36:39 +00:00

445 lines
8.8 KiB
JavaScript

/*
* 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')
const store = require('../store')
const availableDrives = require('./available-drives')
/**
* @summary Select a drive by its device path
* @function
* @public
*
* @param {String} driveDevice - drive device
*
* @example
* selectionState.selectDrive('/dev/disk2');
*/
exports.selectDrive = (driveDevice) => {
store.dispatch({
type: store.Actions.SELECT_DRIVE,
data: driveDevice
})
}
/**
* @summary Toggle drive selection
* @function
* @public
*
* @param {String} driveDevice - drive device
*
* @example
* selectionState.toggleDrive('/dev/disk2');
*/
exports.toggleDrive = (driveDevice) => {
if (exports.isDriveSelected(driveDevice)) {
exports.deselectDrive(driveDevice)
} else {
exports.selectDrive(driveDevice)
}
}
/**
* @summary Deselect all other drives and keep the current drive's status
* @function
* @public
* @deprecated
*
* @description
* This is a temporary function during the transition to multi-writes,
* remove this and its uses when multi-selection should become user-facing.
*
* @param {String} driveDevice - drive device identifier
*
* @example
* console.log(selectionState.getSelectedDevices())
* > [ '/dev/disk1', '/dev/disk2', '/dev/disk3' ]
* selectionState.deselectOtherDrives('/dev/disk2')
* console.log(selectionState.getSelectedDevices())
* > [ '/dev/disk2' ]
*/
exports.deselectOtherDrives = (driveDevice) => {
if (exports.isDriveSelected(driveDevice)) {
const otherDevices = _.reject(exports.getSelectedDevices(), _.partial(_.isEqual, driveDevice))
_.each(otherDevices, exports.deselectDrive)
} else {
exports.deselectAllDrives()
}
}
/**
* @summary Select an image
* @function
* @public
*
* @param {Object} image - image
*
* @example
* selectionState.selectImage({
* path: 'foo.img',
* size: {
* original: 1000000000,
* final: {
* estimation: false,
* value: 1000000000
* }
* }
* });
*/
exports.selectImage = (image) => {
store.dispatch({
type: store.Actions.SELECT_IMAGE,
data: image
})
}
/**
* @summary Get all selected drives' devices
* @function
* @public
*
* @returns {String[]} selected drives' devices
*
* @example
* for (driveDevice of selectionState.getSelectedDevices()) {
* console.log(driveDevice)
* }
* > '/dev/disk1'
* > '/dev/disk2'
*/
exports.getSelectedDevices = () => {
return store.getState().getIn([ 'selection', 'devices' ]).toJS()
}
/**
* @summary Get all selected drive objects
* @function
* @public
*
* @returns {Object[]} selected drive objects
*
* @example
* for (drive of selectionState.getSelectedDrives()) {
* console.log(drive)
* }
* > '{ device: '/dev/disk1', size: 123456789, ... }'
* > '{ device: '/dev/disk2', size: 987654321, ... }'
*/
exports.getSelectedDrives = () => {
const drives = availableDrives.getDrives()
return _.map(exports.getSelectedDevices(), (device) => {
return _.find(drives, { device })
})
}
/**
* @summary Get the head of the list of selected drives
* @function
* @public
*
* @returns {Object} drive
*
* @example
* const drive = selectionState.getCurrentDrive();
* console.log(drive)
* > { device: '/dev/disk1', name: 'Flash drive', ... }
*/
exports.getCurrentDrive = () => {
const device = _.head(exports.getSelectedDevices())
return _.find(availableDrives.getDrives(), { device })
}
/**
* @summary Get the selected image
* @function
* @public
*
* @returns {Object} image
*
* @example
* const image = selectionState.getImage();
*/
exports.getImage = () => {
return _.get(store.getState().toJS(), [ 'selection', 'image' ])
}
/**
* @summary Get image path
* @function
* @public
*
* @returns {String} image path
*
* @example
* const imagePath = selectionState.getImagePath();
*/
exports.getImagePath = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'path'
])
}
/**
* @summary Get image size
* @function
* @public
*
* @returns {Number} image size
*
* @example
* const imageSize = selectionState.getImageSize();
*/
exports.getImageSize = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'size',
'final',
'value'
])
}
/**
* @summary Get image url
* @function
* @public
*
* @returns {String} image url
*
* @example
* const imageUrl = selectionState.getImageUrl();
*/
exports.getImageUrl = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'url'
])
}
/**
* @summary Get image name
* @function
* @public
*
* @returns {String} image name
*
* @example
* const imageName = selectionState.getImageName();
*/
exports.getImageName = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'name'
])
}
/**
* @summary Get image logo
* @function
* @public
*
* @returns {String} image logo
*
* @example
* const imageLogo = selectionState.getImageLogo();
*/
exports.getImageLogo = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'logo'
])
}
/**
* @summary Get image support url
* @function
* @public
*
* @returns {String} image support url
*
* @example
* const imageSupportUrl = selectionState.getImageSupportUrl();
*/
exports.getImageSupportUrl = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'supportUrl'
])
}
/**
* @summary Get image recommended drive size
* @function
* @public
*
* @returns {String} image recommended drive size
*
* @example
* const imageRecommendedDriveSize = selectionState.getImageRecommendedDriveSize();
*/
exports.getImageRecommendedDriveSize = () => {
return _.get(store.getState().toJS(), [
'selection',
'image',
'recommendedDriveSize'
])
}
/**
* @summary Check if there is a selected drive
* @function
* @public
*
* @returns {Boolean} whether there is a selected drive
*
* @example
* if (selectionState.hasDrive()) {
* console.log('There is a drive!');
* }
*/
exports.hasDrive = () => {
return Boolean(exports.getSelectedDevices().length)
}
/**
* @summary Check if there is a selected image
* @function
* @public
*
* @returns {Boolean} whether there is a selected image
*
* @example
* if (selectionState.hasImage()) {
* console.log('There is an image!');
* }
*/
exports.hasImage = () => {
return Boolean(exports.getImage())
}
/**
* @summary Remove drive from selection
* @function
* @public
*
* @param {String} driveDevice - drive device identifier
*
* @example
* selectionState.deselectDrive('/dev/sdc');
*
* @example
* selectionState.deselectDrive('\\\\.\\PHYSICALDRIVE3');
*/
exports.deselectDrive = (driveDevice) => {
store.dispatch({
type: store.Actions.DESELECT_DRIVE,
data: driveDevice
})
}
/**
* @summary Deselect image
* @function
* @public
*
* @example
* selectionState.deselectImage();
*/
exports.deselectImage = () => {
store.dispatch({
type: store.Actions.DESELECT_IMAGE
})
}
/**
* @summary Unselect all drives
* @function
* @public
*
* @example
* selectionState.deselectAllDrives()
*/
exports.deselectAllDrives = () => {
_.each(exports.getSelectedDevices(), exports.deselectDrive)
}
/**
* @summary Clear selections
* @function
* @public
*
* @example
* selectionState.clear();
*/
exports.clear = () => {
exports.deselectImage()
exports.deselectAllDrives()
}
/**
* @summary Check if a drive is the current drive
* @function
* @public
*
* @param {String} driveDevice - drive device
* @returns {Boolean} whether the drive is the current drive
*
* @example
* if (selectionState.isCurrentDrive('/dev/sdb')) {
* console.log('This is the current drive!');
* }
*/
exports.isCurrentDrive = (driveDevice) => {
if (!driveDevice) {
return false
}
return driveDevice === _.get(exports.getCurrentDrive(), [ 'device' ])
}
/**
* @summary Check whether a given device is selected.
* @function
* @public
*
* @param {String} driveDevice - drive device identifier
* @returns {Boolean}
*
* @example
* const isSelected = selectionState.isDriveSelected('/dev/sdb')
*
* if (isSelected) {
* selectionState.deselectDrive(driveDevice)
* }
*/
exports.isDriveSelected = (driveDevice) => {
if (!driveDevice) {
return false
}
const selectedDriveDevices = exports.getSelectedDevices()
return _.includes(selectedDriveDevices, driveDevice)
}