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' 'use strict'
/* eslint-disable no-var */
var angular = require('angular')
/* eslint-enable no-var */
const electron = require('electron') const electron = require('electron')
const sdk = require('etcher-sdk') const sdk = require('etcher-sdk')
const _ = require('lodash') const _ = require('lodash')
@ -79,18 +73,6 @@ store.dispatch({
const applicationSessionUuid = store.getState().toJS().applicationSessionUuid const applicationSessionUuid = store.getState().toJS().applicationSessionUuid
const flashingWorkflowUuid = store.getState().toJS().flashingWorkflowUuid 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([
' _____ _ _', ' _____ _ _',
'| ___| | | |', '| ___| | | |',
@ -104,9 +86,7 @@ app.run(() => {
'', '',
`Version = ${packageJSON.version}, Type = ${packageJSON.packageType}` `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', {
@ -114,9 +94,7 @@ app.run(() => {
version: currentVersion, version: currentVersion,
applicationSessionUuid applicationSessionUuid
}) })
})
app.run(() => {
store.observe(() => { store.observe(() => {
if (!flashState.isFlashing()) { if (!flashState.isFlashing()) {
return return
@ -141,7 +119,6 @@ app.run(() => {
windowProgress.set(currentFlashState) windowProgress.set(currentFlashState)
}) })
})
/** /**
* @summary The radix used by USB ID numbers * @summary The radix used by USB ID numbers
@ -197,7 +174,6 @@ const COMPUTE_MODULE_DESCRIPTIONS = {
[USB_PRODUCT_ID_BCM2710_BOOT]: 'Compute Module 3' [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(',') ? settings.get('driveBlacklist').split(',')
: [] : []
@ -252,12 +228,6 @@ app.run(($timeout) => {
// eslint-disable-next-line require-jsdoc // eslint-disable-next-line require-jsdoc
const setDrives = (drives) => { const setDrives = (drives) => {
availableDrives.setDrives(_.values(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 // eslint-disable-next-line require-jsdoc
@ -309,12 +279,10 @@ app.run(($timeout) => {
}) })
driveScanner.start() driveScanner.start()
})
app.run(($window) => {
let popupExists = false let popupExists = false
$window.addEventListener('beforeunload', (event) => { window.addEventListener('beforeunload', (event) => {
if (!flashState.isFlashing() || popupExists) { if (!flashState.isFlashing() || popupExists) {
analytics.logEvent('Close application', { analytics.logEvent('Close application', {
isFlashing: flashState.isFlashing(), isFlashing: flashState.isFlashing(),
@ -365,74 +333,12 @@ app.run(($window) => {
updateLock.extend() updateLock.extend()
} }
$window.addEventListener('click', extendLock) window.addEventListener('click', extendLock)
$window.addEventListener('touchstart', extendLock) window.addEventListener('touchstart', extendLock)
// Initial update lock acquisition // Initial update lock acquisition
extendLock() extendLock()
})
app.run(($rootScope) => { settings.load().catch(exceptionReporter.report)
$rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState) => {
// Ignore first navigation
if (!fromState.name) {
return
}
analytics.logEvent('Navigate', { require('./tsapp.tsx')
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)
})

View File

@ -29,7 +29,7 @@ import { FlashAnother } from '../flash-another/flash-another';
import { FlashResults } from '../flash-results/flash-results'; import { FlashResults } from '../flash-results/flash-results';
import * as SVGIcon from '../svg-icon/svg-icon'; import * as SVGIcon from '../svg-icon/svg-icon';
const restart = (options: any, $state: any) => { const restart = (options: any, goToMain: () => void) => {
const { const {
applicationSessionUuid, applicationSessionUuid,
flashingWorkflowUuid, flashingWorkflowUuid,
@ -54,7 +54,7 @@ const restart = (options: any, $state: any) => {
data: uuidV4(), data: uuidV4(),
}); });
$state.go('main'); goToMain();
}; };
const formattedErrors = () => { const formattedErrors = () => {
@ -67,7 +67,7 @@ const formattedErrors = () => {
return errors.join('\n'); return errors.join('\n');
}; };
function FinishPage({ $state }: any) { function FinishPage({ goToMain }: { goToMain: () => void }) {
// @ts-ignore // @ts-ignore
const results = flashState.getFlashResults().results || {}; const results = flashState.getFlashResults().results || {};
const progressMessage = messages.progress; const progressMessage = messages.progress;
@ -82,7 +82,7 @@ function FinishPage({ $state }: any) {
></FlashResults> ></FlashResults>
<FlashAnother <FlashAnother
onClick={(options: any) => restart(options, $state)} onClick={(options: any) => restart(options, goToMain)}
></FlashAnother> ></FlashAnother>
</div> </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="../../../node_modules/flexboxgrid/dist/flexboxgrid.css">
<link rel="stylesheet" type="text/css" href="../css/main.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/desktop.css">
<link rel="stylesheet" type="text/css" href="../css/angular.css">
<script src="../../../generated/gui.js"></script>
</head> </head>
<body> <body>
<main id="main"></main>
<main ui-view></main> <script src="../../../generated/gui.js"></script>
<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>
</body> </body>
</html> </html>

View File

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

View File

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

View File

@ -21,8 +21,10 @@ import * as React from 'react';
import { Button } from 'rendition'; import { Button } from 'rendition';
import * as FeaturedProject from '../../components/featured-project/featured-project'; 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 ImageSelector from '../../components/image-selector/image-selector';
import * as ReducedFlashingInfos from '../../components/reduced-flashing-infos/reduced-flashing-infos'; 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 { SettingsModal } from '../../components/settings/settings';
import * as SvgIcon from '../../components/svg-icon/svg-icon.jsx'; import * as SvgIcon from '../../components/svg-icon/svg-icon.jsx';
import * as flashState from '../../models/flash-state'; import * as flashState from '../../models/flash-state';
@ -34,19 +36,16 @@ import { ThemedProvider } from '../../styled-components';
import { colors } from '../../theme'; import { colors } from '../../theme';
import * as middleEllipsis from '../../utils/middle-ellipsis'; import * as middleEllipsis from '../../utils/middle-ellipsis';
import * as messages from '../../../../shared/messages';
import { bytesToClosestUnit } from '../../../../shared/units'; import { bytesToClosestUnit } from '../../../../shared/units';
import { DriveSelector } from './DriveSelector'; import { DriveSelector } from './DriveSelector';
import { Flash } from './Flash'; import { Flash } from './Flash';
const DEFAULT_SUPPORT_URL = function getDrivesTitle() {
'https://github.com/balena-io/etcher/blob/master/SUPPORT.md'; const drives = selectionState.getSelectedDrives();
const getDrivesTitle = (selection: any) => {
const drives = selection.getSelectedDrives();
if (drives.length === 1) { if (drives.length === 1) {
// @ts-ignore
return drives[0].description || 'Untitled Device'; return drives[0].description || 'Untitled Device';
} }
@ -55,51 +54,74 @@ const getDrivesTitle = (selection: any) => {
} }
return `${drives.length} Targets`; return `${drives.length} Targets`;
}; }
const getImageBasename = (selection: any) => { function getImageBasename() {
if (!selection.hasImage()) { if (!selectionState.hasImage()) {
return ''; return '';
} }
const selectionImageName = selection.getImageName(); const selectionImageName = selectionState.getImageName();
const imageBasename = path.basename(selection.getImagePath()); const imageBasename = path.basename(selectionState.getImagePath());
return selectionImageName || imageBasename; return selectionImageName || imageBasename;
}
interface MainPageStateFromStore {
isFlashing: boolean;
hasImage: boolean;
hasDrive: boolean;
imageLogo: string;
imageSize: number;
imageName: string;
driveTitle: string;
}
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 MainPage = ({ $state }: any) => { private stateHelper(): MainPageStateFromStore {
const setRefresh = React.useState(false)[1]; return {
const [isWebviewShowing, setIsWebviewShowing] = React.useState(false); isFlashing: flashState.isFlashing(),
const [hideSettings, setHideSettings] = React.useState(true); hasImage: selectionState.hasImage(),
React.useEffect(() => { hasDrive: selectionState.hasDrive(),
return (store as any).observe(() => { imageLogo: selectionState.getImageLogo(),
setRefresh(ref => !ref); imageSize: selectionState.getImageSize(),
}); imageName: getImageBasename(),
}, []); driveTitle: getDrivesTitle(),
const setWebviewShowing = (isShowing: boolean) => {
setIsWebviewShowing(isShowing);
store.dispatch({
type: 'SET_WEBVIEW_SHOWING_STATUS',
data: Boolean(isShowing),
});
}; };
}
const isFlashing = flashState.isFlashing(); public componentDidMount() {
const shouldDriveStepBeDisabled = !selectionState.hasImage(); (store as any).observe(() => {
this.setState(this.stateHelper());
});
}
public render() {
const shouldDriveStepBeDisabled = !this.state.hasImage;
const shouldFlashStepBeDisabled = const shouldFlashStepBeDisabled =
!selectionState.hasDrive() || shouldDriveStepBeDisabled; !this.state.hasImage || !this.state.hasDrive;
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;
if (this.state.current === 'main') {
return ( return (
<ThemedProvider style={{ height: '100%' }}> <ThemedProvider style={{ height: '100%', width: '100%' }}>
<header <header
id="app-header" id="app-header"
style={{ style={{
@ -137,7 +159,7 @@ const MainPage = ({ $state }: any) => {
fontSize={24} fontSize={24}
style={{ width: '30px' }} style={{ width: '30px' }}
plain plain
onClick={() => setHideSettings(false)} onClick={() => this.setState({ hideSettings: false })}
tabIndex={5} tabIndex={5}
/> />
{!settings.get('disableExternalLinks') && ( {!settings.get('disableExternalLinks') && (
@ -149,7 +171,8 @@ const MainPage = ({ $state }: any) => {
plain plain
onClick={() => onClick={() =>
openExternal( openExternal(
selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL, selectionState.getImageSupportUrl() ||
'https://github.com/balena-io/etcher/blob/master/SUPPORT.md',
) )
} }
tabIndex={5} tabIndex={5}
@ -157,60 +180,78 @@ const MainPage = ({ $state }: any) => {
)} )}
</span> </span>
</header> </header>
{hideSettings ? null : ( {this.state.hideSettings ? null : (
<SettingsModal <SettingsModal
toggleModal={(value: boolean) => { 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"> <div className="col-xs">
<ImageSelector flashing={isFlashing} /> <ImageSelector flashing={this.state.isFlashing} />
</div> </div>
<div className="col-xs"> <div className="col-xs">
<DriveSelector <DriveSelector
webviewShowing={isWebviewShowing} webviewShowing={this.state.isWebviewShowing}
disabled={shouldDriveStepBeDisabled} disabled={shouldDriveStepBeDisabled}
nextStepDisabled={shouldFlashStepBeDisabled} nextStepDisabled={shouldFlashStepBeDisabled}
hasDrive={hasDrive} hasDrive={this.state.hasDrive}
flashing={isFlashing} flashing={this.state.isFlashing}
/> />
</div> </div>
{isFlashing && ( {this.state.isFlashing && (
<div <div
className={`featured-project ${ 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>
)} )}
<div> <div>
<ReducedFlashingInfos <ReducedFlashingInfos
imageLogo={imageLogo} imageLogo={this.state.imageLogo}
imageName={imageName} imageName={middleEllipsis(this.state.imageName, 16)}
imageSize={imageSize} imageSize={bytesToClosestUnit(this.state.imageSize)}
driveTitle={driveTitle} driveTitle={middleEllipsis(this.state.driveTitle, 16)}
shouldShow={shouldShowFlashingInfos} shouldShow={
this.state.isFlashing && this.state.isWebviewShowing
}
/> />
</div> </div>
<div className="col-xs"> <div className="col-xs">
<Flash <Flash
goToSuccess={() => $state.go('success')} goToSuccess={() => this.setState({ current: 'success' })}
shouldFlashStepBeDisabled={shouldFlashStepBeDisabled} shouldFlashStepBeDisabled={shouldFlashStepBeDisabled}
lastFlashErrorCode={lastFlashErrorCode}
progressMessage={progressMessage}
/> />
</div> </div>
</div> </div>
</ThemedProvider> </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; 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,7 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
[ng-click] { import * as React from 'react';
cursor: pointer; import * as ReactDOM from 'react-dom';
-webkit-app-region: no-drag;
} 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" "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": { "@types/bluebird": {
"version": "3.5.28", "version": "3.5.28",
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.28.tgz", "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", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz",
"integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==" "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": { "@types/marked": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.3.0.tgz", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.3.0.tgz",
@ -1597,25 +1584,6 @@
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
"dev": true "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": { "ansi-align": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "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", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
"integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" "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": { "lodash.isequal": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "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", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" "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": { "nice-try": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "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", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "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": { "read-config-file": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-5.0.0.tgz", "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-brands-svg-icons": "^5.11.2",
"@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/react-fontawesome": "^0.1.7", "@fortawesome/react-fontawesome": "^0.1.7",
"angular": "1.7.6",
"angular-ui-router": "^0.4.2",
"bindings": "^1.3.0", "bindings": "^1.3.0",
"bluebird": "^3.5.3", "bluebird": "^3.5.3",
"bootstrap-sass": "^3.3.6", "bootstrap-sass": "^3.3.6",
@ -79,7 +77,6 @@
"react": "^16.8.5", "react": "^16.8.5",
"react-dom": "^16.8.5", "react-dom": "^16.8.5",
"react-dropzone": "^10.2.1", "react-dropzone": "^10.2.1",
"react2angular": "^4.0.2",
"redux": "^3.5.2", "redux": "^3.5.2",
"rendition": "^11.24.0", "rendition": "^11.24.0",
"request": "^2.81.0", "request": "^2.81.0",
@ -98,7 +95,6 @@
"@babel/preset-env": "^7.6.0", "@babel/preset-env": "^7.6.0",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@types/react-dom": "^16.8.4", "@types/react-dom": "^16.8.4",
"angular-mocks": "1.7.6",
"babel-loader": "^8.0.4", "babel-loader": "^8.0.4",
"chalk": "^1.1.3", "chalk": "^1.1.3",
"electron": "6.1.4", "electron": "6.1.4",

View File

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