Remove remaining angular

Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2020-01-03 19:07:21 +01:00 committed by Lorenzo Alberto Maria Ambrosi
parent 26d0e46367
commit d5eb679cf0
13 changed files with 387 additions and 627 deletions

View File

@ -20,12 +20,6 @@
'use strict'
/* eslint-disable no-var */
var angular = require('angular')
/* eslint-enable no-var */
const electron = require('electron')
const sdk = require('etcher-sdk')
const _ = require('lodash')
@ -79,19 +73,7 @@ store.dispatch({
const applicationSessionUuid = store.getState().toJS().applicationSessionUuid
const flashingWorkflowUuid = store.getState().toJS().flashingWorkflowUuid
const app = angular.module('Etcher', [
require('angular-ui-router'),
// Components
require('./components/safe-webview').MODULE_NAME,
// Pages
require('./pages/main/main.ts').MODULE_NAME,
require('./components/finish/index.ts').MODULE_NAME
])
app.run(() => {
console.log([
console.log([
' _____ _ _',
'| ___| | | |',
'| |__ | |_ ___| |__ ___ _ __',
@ -103,21 +85,17 @@ app.run(() => {
'Drop us a line at join+etcher@balena.io',
'',
`Version = ${packageJSON.version}, Type = ${packageJSON.packageType}`
].join('\n'))
})
].join('\n'))
app.run(() => {
const currentVersion = packageJSON.version
const currentVersion = packageJSON.version
analytics.logEvent('Application start', {
analytics.logEvent('Application start', {
packageType: packageJSON.packageType,
version: currentVersion,
applicationSessionUuid
})
})
app.run(() => {
store.observe(() => {
store.observe(() => {
if (!flashState.isFlashing()) {
return
}
@ -140,7 +118,6 @@ app.run(() => {
)
windowProgress.set(currentFlashState)
})
})
/**
@ -197,22 +174,21 @@ const COMPUTE_MODULE_DESCRIPTIONS = {
[USB_PRODUCT_ID_BCM2710_BOOT]: 'Compute Module 3'
}
app.run(($timeout) => {
const BLACKLISTED_DRIVES = settings.has('driveBlacklist')
const BLACKLISTED_DRIVES = settings.has('driveBlacklist')
? settings.get('driveBlacklist').split(',')
: []
// eslint-disable-next-line require-jsdoc
const driveIsAllowed = (drive) => {
// eslint-disable-next-line require-jsdoc
const driveIsAllowed = (drive) => {
return !(
BLACKLISTED_DRIVES.includes(drive.devicePath) ||
BLACKLISTED_DRIVES.includes(drive.device) ||
BLACKLISTED_DRIVES.includes(drive.raw)
)
}
}
// eslint-disable-next-line require-jsdoc,consistent-return
const prepareDrive = (drive) => {
// eslint-disable-next-line require-jsdoc,consistent-return
const prepareDrive = (drive) => {
if (drive instanceof sdk.sourceDestination.BlockDevice) {
return drive.drive
} else if (drive instanceof sdk.sourceDestination.UsbbootDrive) {
@ -247,26 +223,20 @@ app.run(($timeout) => {
].join(' ')
}
}
}
}
// eslint-disable-next-line require-jsdoc
const setDrives = (drives) => {
// eslint-disable-next-line require-jsdoc
const setDrives = (drives) => {
availableDrives.setDrives(_.values(drives))
}
// Safely trigger a digest cycle.
// In some cases, AngularJS doesn't acknowledge that the
// available drives list has changed, and incorrectly
// keeps asking the user to "Connect a drive".
$timeout()
}
// eslint-disable-next-line require-jsdoc
const getDrives = () => {
// eslint-disable-next-line require-jsdoc
const getDrives = () => {
return _.keyBy(availableDrives.getDrives() || [], 'device')
}
}
// eslint-disable-next-line require-jsdoc
const addDrive = (drive) => {
// eslint-disable-next-line require-jsdoc
const addDrive = (drive) => {
const preparedDrive = prepareDrive(drive)
if (!driveIsAllowed(preparedDrive)) {
return
@ -274,31 +244,31 @@ app.run(($timeout) => {
const drives = getDrives()
drives[preparedDrive.device] = preparedDrive
setDrives(drives)
}
}
// eslint-disable-next-line require-jsdoc
const removeDrive = (drive) => {
// eslint-disable-next-line require-jsdoc
const removeDrive = (drive) => {
const preparedDrive = prepareDrive(drive)
const drives = getDrives()
// eslint-disable-next-line prefer-reflect
delete drives[preparedDrive.device]
setDrives(drives)
}
}
// eslint-disable-next-line require-jsdoc
const updateDriveProgress = (drive, progress) => {
// eslint-disable-next-line require-jsdoc
const updateDriveProgress = (drive, progress) => {
const drives = getDrives()
const driveInMap = drives[drive.device]
if (driveInMap) {
driveInMap.progress = progress
setDrives(drives)
}
}
}
driveScanner.on('attach', addDrive)
driveScanner.on('detach', removeDrive)
driveScanner.on('attach', addDrive)
driveScanner.on('detach', removeDrive)
driveScanner.on('error', (error) => {
driveScanner.on('error', (error) => {
// Stop the drive scanning loop in case of errors,
// otherwise we risk presenting the same error over
// and over again to the user, while also heavily
@ -306,15 +276,13 @@ app.run(($timeout) => {
driveScanner.stop()
return exceptionReporter.report(error)
})
driveScanner.start()
})
app.run(($window) => {
let popupExists = false
driveScanner.start()
$window.addEventListener('beforeunload', (event) => {
let popupExists = false
window.addEventListener('beforeunload', (event) => {
if (!flashState.isFlashing() || popupExists) {
analytics.logEvent('Close application', {
isFlashing: flashState.isFlashing(),
@ -352,87 +320,25 @@ app.run(($window) => {
analytics.logEvent('Close rejected while flashing', { applicationSessionUuid, flashingWorkflowUuid })
popupExists = false
}).catch(exceptionReporter.report)
})
})
/**
/**
* @summary Helper fn for events
* @function
* @private
* @example
* window.addEventListener('click', extendLock)
*/
const extendLock = () => {
const extendLock = () => {
updateLock.extend()
}
}
$window.addEventListener('click', extendLock)
$window.addEventListener('touchstart', extendLock)
window.addEventListener('click', extendLock)
window.addEventListener('touchstart', extendLock)
// Initial update lock acquisition
extendLock()
})
// Initial update lock acquisition
extendLock()
app.run(($rootScope) => {
$rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
// Ignore first navigation
if (!fromState.name) {
return
}
settings.load().catch(exceptionReporter.report)
analytics.logEvent('Navigate', {
to: toState.name,
from: fromState.name,
applicationSessionUuid
})
})
})
app.config(($urlRouterProvider) => {
$urlRouterProvider.otherwise('/main')
})
app.config(($provide) => {
$provide.decorator('$exceptionHandler', ($delegate) => {
return (exception, cause) => {
exceptionReporter.report(exception)
$delegate(exception, cause)
}
})
})
app.config(($locationProvider) => {
// NOTE(Shou): this seems to invoke a minor perf decrease when set to true
$locationProvider.html5Mode({
rewriteLinks: false
})
})
app.controller('StateController', function ($rootScope, $scope) {
const unregisterStateChange = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
this.currentName = toState.name
})
$scope.$on('$destroy', unregisterStateChange)
/**
* @summary Get the current state name
* @function
* @public
*
* @returns {String} current state name
*
* @example
* if (StateController.currentName === 'main') {
* console.log('We are on the main screen!');
* }
*/
this.currentName = null
})
// Ensure user settings are loaded before
// we bootstrap the Angular.js application
angular.element(document).ready(() => {
settings.load().then(() => {
angular.bootstrap(document, [ 'Etcher' ])
}).catch(exceptionReporter.report)
})
require('./tsapp.tsx')

View File

@ -29,7 +29,7 @@ import { FlashAnother } from '../flash-another/flash-another';
import { FlashResults } from '../flash-results/flash-results';
import * as SVGIcon from '../svg-icon/svg-icon';
const restart = (options: any, $state: any) => {
const restart = (options: any, goToMain: () => void) => {
const {
applicationSessionUuid,
flashingWorkflowUuid,
@ -54,7 +54,7 @@ const restart = (options: any, $state: any) => {
data: uuidV4(),
});
$state.go('main');
goToMain();
};
const formattedErrors = () => {
@ -67,7 +67,7 @@ const formattedErrors = () => {
return errors.join('\n');
};
function FinishPage({ $state }: any) {
function FinishPage({ goToMain }: { goToMain: () => void }) {
// @ts-ignore
const results = flashState.getFlashResults().results || {};
const progressMessage = messages.progress;
@ -82,7 +82,7 @@ function FinishPage({ $state }: any) {
></FlashResults>
<FlashAnother
onClick={(options: any) => restart(options, $state)}
onClick={(options: any) => restart(options, goToMain)}
></FlashAnother>
</div>

View File

@ -1,35 +0,0 @@
/*
* 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.
*/
/**
* @module Etcher.Pages.Finish
*/
import * as angular from 'angular';
import { react2angular } from 'react2angular';
import FinishPage from './finish';
export const MODULE_NAME = 'Etcher.Pages.Finish';
const Finish = angular.module(MODULE_NAME, []);
Finish.component('finish', react2angular(FinishPage, [], ['$state']));
Finish.config(($stateProvider: any) => {
$stateProvider.state('success', {
url: '/success',
template: '<finish style="width:100%"></finish>',
});
});

View File

@ -1,28 +0,0 @@
/*
* Copyright 2018 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.
*/
/**
* @module Etcher.Components.SafeWebview
*/
import * as angular from 'angular';
import { react2angular } from 'react2angular';
import * as SafeWebview from './safe-webview';
export const MODULE_NAME = 'Etcher.Components.SafeWebview';
const AngularSafeWebview = angular.module(MODULE_NAME, []);
AngularSafeWebview.component('safeWebview', react2angular(SafeWebview));

View File

@ -6,21 +6,9 @@
<link rel="stylesheet" type="text/css" href="../../../node_modules/flexboxgrid/dist/flexboxgrid.css">
<link rel="stylesheet" type="text/css" href="../css/main.css">
<link rel="stylesheet" type="text/css" href="../css/desktop.css">
<link rel="stylesheet" type="text/css" href="../css/angular.css">
<script src="../../../generated/gui.js"></script>
</head>
<body>
<main ui-view></main>
<div class="section-loader"
ng-controller="StateController as state"
ng-class="{
isFinish: state.currentName === 'success'
}">
<safe-webview src="'https://www.balena.io/etcher/success-banner/'">
</safe-webview>
</div>
<main id="main"></main>
<script src="../../../generated/gui.js"></script>
</body>
</html>

View File

@ -112,8 +112,7 @@ const ACTIONS = _.fromPairs(_.map([
'DESELECT_DRIVE',
'DESELECT_IMAGE',
'SET_APPLICATION_SESSION_UUID',
'SET_FLASHING_WORKFLOW_UUID',
'SET_WEBVIEW_SHOWING_STATUS'
'SET_FLASHING_WORKFLOW_UUID'
], (message) => {
return [ message, message ]
}))
@ -507,10 +506,6 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
return state.set('flashingWorkflowUuid', action.data)
}
case ACTIONS.SET_WEBVIEW_SHOWING_STATUS: {
return state.set('isWebviewShowing', action.data)
}
default: {
return state
}

View File

@ -160,15 +160,10 @@ const formatSeconds = (totalSeconds: number) => {
return `${minutes}m${seconds}s`;
};
export const Flash = ({
shouldFlashStepBeDisabled,
lastFlashErrorCode,
progressMessage,
goToSuccess,
}: any) => {
export const Flash = ({ shouldFlashStepBeDisabled, goToSuccess }: any) => {
const state: any = flashState.getFlashState();
const isFlashing = flashState.isFlashing();
const flashErrorCode = lastFlashErrorCode();
const flashErrorCode = flashState.getLastFlashErrorCode();
const [warningMessages, setWarningMessages] = React.useState<string[]>([]);
const [errorMessage, setErrorMessage] = React.useState('');
@ -272,7 +267,7 @@ export const Flash = ({
<span className="target-status-dot"></span>
<span className="target-status-quantity">{state.failed}</span>
<span className="target-status-message">
{progressMessage.failed(state.failed)}{' '}
{messages.progress.failed(state.failed)}{' '}
</span>
</div>
</div>

View File

@ -21,8 +21,10 @@ import * as React from 'react';
import { Button } from 'rendition';
import * as FeaturedProject from '../../components/featured-project/featured-project';
import FinishPage from '../../components/finish/finish';
import * as ImageSelector from '../../components/image-selector/image-selector';
import * as ReducedFlashingInfos from '../../components/reduced-flashing-infos/reduced-flashing-infos';
import * as SafeWebview from '../../components/safe-webview/safe-webview';
import { SettingsModal } from '../../components/settings/settings';
import * as SvgIcon from '../../components/svg-icon/svg-icon.jsx';
import * as flashState from '../../models/flash-state';
@ -34,19 +36,16 @@ import { ThemedProvider } from '../../styled-components';
import { colors } from '../../theme';
import * as middleEllipsis from '../../utils/middle-ellipsis';
import * as messages from '../../../../shared/messages';
import { bytesToClosestUnit } from '../../../../shared/units';
import { DriveSelector } from './DriveSelector';
import { Flash } from './Flash';
const DEFAULT_SUPPORT_URL =
'https://github.com/balena-io/etcher/blob/master/SUPPORT.md';
const getDrivesTitle = (selection: any) => {
const drives = selection.getSelectedDrives();
function getDrivesTitle() {
const drives = selectionState.getSelectedDrives();
if (drives.length === 1) {
// @ts-ignore
return drives[0].description || 'Untitled Device';
}
@ -55,51 +54,74 @@ const getDrivesTitle = (selection: any) => {
}
return `${drives.length} Targets`;
};
}
const getImageBasename = (selection: any) => {
if (!selection.hasImage()) {
function getImageBasename() {
if (!selectionState.hasImage()) {
return '';
}
const selectionImageName = selection.getImageName();
const imageBasename = path.basename(selection.getImagePath());
const selectionImageName = selectionState.getImageName();
const imageBasename = path.basename(selectionState.getImagePath());
return selectionImageName || imageBasename;
};
}
const MainPage = ({ $state }: any) => {
const setRefresh = React.useState(false)[1];
const [isWebviewShowing, setIsWebviewShowing] = React.useState(false);
const [hideSettings, setHideSettings] = React.useState(true);
React.useEffect(() => {
return (store as any).observe(() => {
setRefresh(ref => !ref);
});
}, []);
interface MainPageStateFromStore {
isFlashing: boolean;
hasImage: boolean;
hasDrive: boolean;
imageLogo: string;
imageSize: number;
imageName: string;
driveTitle: string;
}
const setWebviewShowing = (isShowing: boolean) => {
setIsWebviewShowing(isShowing);
store.dispatch({
type: 'SET_WEBVIEW_SHOWING_STATUS',
data: Boolean(isShowing),
});
interface MainPageState {
current: 'main' | 'success';
isWebviewShowing: boolean;
hideSettings: boolean;
}
export class MainPage extends React.Component<
{},
MainPageState & MainPageStateFromStore
> {
constructor(props: {}) {
super(props);
this.state = {
current: 'main',
isWebviewShowing: false,
hideSettings: true,
...this.stateHelper(),
};
}
const isFlashing = flashState.isFlashing();
const shouldDriveStepBeDisabled = !selectionState.hasImage();
private stateHelper(): MainPageStateFromStore {
return {
isFlashing: flashState.isFlashing(),
hasImage: selectionState.hasImage(),
hasDrive: selectionState.hasDrive(),
imageLogo: selectionState.getImageLogo(),
imageSize: selectionState.getImageSize(),
imageName: getImageBasename(),
driveTitle: getDrivesTitle(),
};
}
public componentDidMount() {
(store as any).observe(() => {
this.setState(this.stateHelper());
});
}
public render() {
const shouldDriveStepBeDisabled = !this.state.hasImage;
const shouldFlashStepBeDisabled =
!selectionState.hasDrive() || shouldDriveStepBeDisabled;
const hasDrive = selectionState.hasDrive();
const imageLogo = selectionState.getImageLogo();
const imageSize = bytesToClosestUnit(selectionState.getImageSize());
const imageName = middleEllipsis(getImageBasename(selectionState), 16);
const driveTitle = middleEllipsis(getDrivesTitle(selectionState), 16);
const shouldShowFlashingInfos = isFlashing && isWebviewShowing;
const lastFlashErrorCode = flashState.getLastFlashErrorCode;
const progressMessage = messages.progress;
!this.state.hasImage || !this.state.hasDrive;
if (this.state.current === 'main') {
return (
<ThemedProvider style={{ height: '100%' }}>
<ThemedProvider style={{ height: '100%', width: '100%' }}>
<header
id="app-header"
style={{
@ -137,7 +159,7 @@ const MainPage = ({ $state }: any) => {
fontSize={24}
style={{ width: '30px' }}
plain
onClick={() => setHideSettings(false)}
onClick={() => this.setState({ hideSettings: false })}
tabIndex={5}
/>
{!settings.get('disableExternalLinks') && (
@ -149,7 +171,8 @@ const MainPage = ({ $state }: any) => {
plain
onClick={() =>
openExternal(
selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL,
selectionState.getImageSupportUrl() ||
'https://github.com/balena-io/etcher/blob/master/SUPPORT.md',
)
}
tabIndex={5}
@ -157,60 +180,78 @@ const MainPage = ({ $state }: any) => {
)}
</span>
</header>
{hideSettings ? null : (
{this.state.hideSettings ? null : (
<SettingsModal
toggleModal={(value: boolean) => {
setHideSettings(!value);
this.setState({ hideSettings: !value });
}}
/>
)}
<div className="page-main row around-xs" style={{ margin: '110px 50px' }}>
<div
className="page-main row around-xs"
style={{ margin: '110px 50px' }}
>
<div className="col-xs">
<ImageSelector flashing={isFlashing} />
<ImageSelector flashing={this.state.isFlashing} />
</div>
<div className="col-xs">
<DriveSelector
webviewShowing={isWebviewShowing}
webviewShowing={this.state.isWebviewShowing}
disabled={shouldDriveStepBeDisabled}
nextStepDisabled={shouldFlashStepBeDisabled}
hasDrive={hasDrive}
flashing={isFlashing}
hasDrive={this.state.hasDrive}
flashing={this.state.isFlashing}
/>
</div>
{isFlashing && (
{this.state.isFlashing && (
<div
className={`featured-project ${
isFlashing && isWebviewShowing ? 'fp-visible' : ''
this.state.isFlashing && this.state.isWebviewShowing
? 'fp-visible'
: ''
}`}
>
<FeaturedProject onWebviewShow={setWebviewShowing} />
<FeaturedProject
onWebviewShow={(isWebviewShowing: boolean) => {
this.setState({ isWebviewShowing });
}}
/>
</div>
)}
<div>
<ReducedFlashingInfos
imageLogo={imageLogo}
imageName={imageName}
imageSize={imageSize}
driveTitle={driveTitle}
shouldShow={shouldShowFlashingInfos}
imageLogo={this.state.imageLogo}
imageName={middleEllipsis(this.state.imageName, 16)}
imageSize={bytesToClosestUnit(this.state.imageSize)}
driveTitle={middleEllipsis(this.state.driveTitle, 16)}
shouldShow={
this.state.isFlashing && this.state.isWebviewShowing
}
/>
</div>
<div className="col-xs">
<Flash
goToSuccess={() => $state.go('success')}
goToSuccess={() => this.setState({ current: 'success' })}
shouldFlashStepBeDisabled={shouldFlashStepBeDisabled}
lastFlashErrorCode={lastFlashErrorCode}
progressMessage={progressMessage}
/>
</div>
</div>
</ThemedProvider>
);
};
} else if (this.state.current === 'success') {
return (
<div className="section-loader isFinish">
<FinishPage goToMain={() => this.setState({ current: 'main' })} />
<SafeWebview src="https://www.balena.io/etcher/success-banner/" />
</div>
);
}
}
}
export default MainPage;

View File

@ -1,40 +0,0 @@
/*
* 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.
*/
/**
* This page represents the application main page.
*
* @module Etcher.Pages.Main
*/
import * as angular from 'angular';
// @ts-ignore
import * as angularRouter from 'angular-ui-router';
import { react2angular } from 'react2angular';
import MainPage from './MainPage';
export const MODULE_NAME = 'Etcher.Pages.Main';
const Main = angular.module(MODULE_NAME, [angularRouter]);
Main.component('mainPage', react2angular(MainPage, [], ['$state']));
Main.config(($stateProvider: any) => {
$stateProvider.state('main', {
url: '/main',
template: '<main-page style="width:100%"></main-page>',
});
});

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016 balena.io
* Copyright 2020 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,9 @@
* limitations under the License.
*/
[ng-click] {
cursor: pointer;
-webkit-app-region: no-drag;
}
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import MainPage from './pages/main/MainPage';
ReactDOM.render(<MainPage />, document.getElementById('main'));

59
npm-shrinkwrap.json generated
View File

@ -1092,11 +1092,6 @@
"defer-to-connect": "^1.0.1"
}
},
"@types/angular": {
"version": "1.6.56",
"resolved": "https://registry.npmjs.org/@types/angular/-/angular-1.6.56.tgz",
"integrity": "sha512-HxtqilvklZ7i6XOaiP7uIJIrFXEVEhfbSY45nfv2DeBRngncI58Y4ZOUMiUkcT8sqgLL1ablmbfylChUg7A3GA=="
},
"@types/bluebird": {
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.28.tgz",
@ -1186,14 +1181,6 @@
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz",
"integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg=="
},
"@types/lodash.frompairs": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@types/lodash.frompairs/-/lodash.frompairs-4.0.6.tgz",
"integrity": "sha512-rwCUf4NMKhXpiVjL/RXP8YOk+rd02/J4tACADEgaMXRVnzDbSSlBMKFZoX/ARmHVLg3Qc98Um4PErGv8FbxU7w==",
"requires": {
"@types/lodash": "*"
}
},
"@types/marked": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.3.0.tgz",
@ -1597,25 +1584,6 @@
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
"dev": true
},
"angular": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.7.6.tgz",
"integrity": "sha512-QELpvuMIe1FTGniAkRz93O6A+di0yu88niDwcdzrSqtUHNtZMgtgFS4f7W/6Gugbuwej8Kyswlmymwdp8iPCWg=="
},
"angular-mocks": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/angular-mocks/-/angular-mocks-1.7.6.tgz",
"integrity": "sha512-t3eQmuAZczdOVdOQj7muCBwH+MBNwd+/FaAsV1SNp+597EQVWABQwxI6KXE0k0ZlyJ5JbtkNIKU8kGAj1znxhw==",
"dev": true
},
"angular-ui-router": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/angular-ui-router/-/angular-ui-router-0.4.3.tgz",
"integrity": "sha512-EGBG7G7ArFVkJPM+ZIgPKuMYuT16UQrr3zj3BEiXHKwxss867bGt3u7QD9g4BxR+K2qQOSWok6JGvgTWXAko3A==",
"requires": {
"angular": "^1.0.8"
}
},
"ansi-align": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
@ -9081,11 +9049,6 @@
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
"integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c="
},
"lodash.frompairs": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz",
"integrity": "sha1-vE5SB/onV8E25XNhTpZkUGsrG9I="
},
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@ -10115,17 +10078,6 @@
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
"ngcomponent": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ngcomponent/-/ngcomponent-4.1.0.tgz",
"integrity": "sha512-cGL3iVoqMWTpCfaIwgRKhdaGqiy2Z+CCG0cVfjlBvdqE8saj8xap9B4OTf+qwObxLVZmDTJPDgx3bN6Q/lZ7BQ==",
"requires": {
"@types/angular": "^1.6.39",
"@types/lodash": "^4.14.85",
"angular": ">=1.5.0",
"lodash": "^4.17.4"
}
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@ -11569,17 +11521,6 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react2angular": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/react2angular/-/react2angular-4.0.6.tgz",
"integrity": "sha512-MDl2WRoTyu7Gyh4+FAIlmsM2mxIa/DjSz6G/d90L1tK8ZRubqVEayKF6IPyAruC5DMhGDVJ7tlAIcu/gMNDjXg==",
"requires": {
"@types/lodash.frompairs": "^4.0.5",
"angular": ">=1.5",
"lodash.frompairs": "^4.0.1",
"ngcomponent": "^4.1.0"
}
},
"read-config-file": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-5.0.0.tgz",

View File

@ -56,8 +56,6 @@
"@fortawesome/free-brands-svg-icons": "^5.11.2",
"@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/react-fontawesome": "^0.1.7",
"angular": "1.7.6",
"angular-ui-router": "^0.4.2",
"bindings": "^1.3.0",
"bluebird": "^3.5.3",
"bootstrap-sass": "^3.3.6",
@ -79,7 +77,6 @@
"react": "^16.8.5",
"react-dom": "^16.8.5",
"react-dropzone": "^10.2.1",
"react2angular": "^4.0.2",
"redux": "^3.5.2",
"rendition": "^11.24.0",
"request": "^2.81.0",
@ -98,7 +95,6 @@
"@babel/preset-env": "^7.6.0",
"@babel/preset-react": "^7.0.0",
"@types/react-dom": "^16.8.4",
"angular-mocks": "1.7.6",
"babel-loader": "^8.0.4",
"chalk": "^1.1.3",
"electron": "6.1.4",

View File

@ -1,12 +1,11 @@
'use strict'
const _ = require('lodash')
const m = require('mochainon')
const ipc = require('node-ipc')
const angular = require('angular')
const Bluebird = require('bluebird')
const flashState = require('../../../lib/gui/app/models/flash-state')
const imageWriter = require('../../../lib/gui/app/modules/image-writer')
require('angular-mocks')
describe('Browser: imageWriter', () => {
describe('.flash()', () => {
@ -41,7 +40,7 @@ describe('Browser: imageWriter', () => {
})
const writing = imageWriter.flash('foo.img', [ '/dev/disk2' ])
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(angular.noop)
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(_.noop)
writing.finally(() => {
m.chai.expect(this.performWriteStub).to.have.been.calledOnce
})
@ -73,13 +72,13 @@ describe('Browser: imageWriter', () => {
})
it('should set flashing to false when done', () => {
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(angular.noop).finally(() => {
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(_.noop).finally(() => {
m.chai.expect(flashState.isFlashing()).to.be.false
})
})
it('should set the error code in the flash results', () => {
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(angular.noop).finally(() => {
imageWriter.flash('foo.img', [ '/dev/disk2' ]).catch(_.noop).finally(() => {
const flashResults = flashState.getFlashResults()
m.chai.expect(flashResults.errorCode).to.equal('FOO')
})