mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-23 11:16:39 +00:00
Remove remaining angular
Change-type: patch
This commit is contained in:
parent
26d0e46367
commit
d5eb679cf0
@ -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,18 +73,6 @@ 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([
|
||||
' _____ _ _',
|
||||
'| ___| | | |',
|
||||
@ -104,9 +86,7 @@ app.run(() => {
|
||||
'',
|
||||
`Version = ${packageJSON.version}, Type = ${packageJSON.packageType}`
|
||||
].join('\n'))
|
||||
})
|
||||
|
||||
app.run(() => {
|
||||
const currentVersion = packageJSON.version
|
||||
|
||||
analytics.logEvent('Application start', {
|
||||
@ -114,9 +94,7 @@ app.run(() => {
|
||||
version: currentVersion,
|
||||
applicationSessionUuid
|
||||
})
|
||||
})
|
||||
|
||||
app.run(() => {
|
||||
store.observe(() => {
|
||||
if (!flashState.isFlashing()) {
|
||||
return
|
||||
@ -141,7 +119,6 @@ app.run(() => {
|
||||
|
||||
windowProgress.set(currentFlashState)
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* @summary The radix used by USB ID numbers
|
||||
@ -197,7 +174,6 @@ const COMPUTE_MODULE_DESCRIPTIONS = {
|
||||
[USB_PRODUCT_ID_BCM2710_BOOT]: 'Compute Module 3'
|
||||
}
|
||||
|
||||
app.run(($timeout) => {
|
||||
const BLACKLISTED_DRIVES = settings.has('driveBlacklist')
|
||||
? settings.get('driveBlacklist').split(',')
|
||||
: []
|
||||
@ -252,12 +228,6 @@ app.run(($timeout) => {
|
||||
// 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
|
||||
@ -309,12 +279,10 @@ app.run(($timeout) => {
|
||||
})
|
||||
|
||||
driveScanner.start()
|
||||
})
|
||||
|
||||
app.run(($window) => {
|
||||
let popupExists = false
|
||||
|
||||
$window.addEventListener('beforeunload', (event) => {
|
||||
window.addEventListener('beforeunload', (event) => {
|
||||
if (!flashState.isFlashing() || popupExists) {
|
||||
analytics.logEvent('Close application', {
|
||||
isFlashing: flashState.isFlashing(),
|
||||
@ -365,74 +333,12 @@ app.run(($window) => {
|
||||
updateLock.extend()
|
||||
}
|
||||
|
||||
$window.addEventListener('click', extendLock)
|
||||
$window.addEventListener('touchstart', extendLock)
|
||||
window.addEventListener('click', extendLock)
|
||||
window.addEventListener('touchstart', 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')
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>',
|
||||
});
|
||||
});
|
@ -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));
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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) => {
|
||||
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);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setWebviewShowing = (isShowing: boolean) => {
|
||||
setIsWebviewShowing(isShowing);
|
||||
store.dispatch({
|
||||
type: 'SET_WEBVIEW_SHOWING_STATUS',
|
||||
data: Boolean(isShowing),
|
||||
});
|
||||
private stateHelper(): MainPageStateFromStore {
|
||||
return {
|
||||
isFlashing: flashState.isFlashing(),
|
||||
hasImage: selectionState.hasImage(),
|
||||
hasDrive: selectionState.hasDrive(),
|
||||
imageLogo: selectionState.getImageLogo(),
|
||||
imageSize: selectionState.getImageSize(),
|
||||
imageName: getImageBasename(),
|
||||
driveTitle: getDrivesTitle(),
|
||||
};
|
||||
}
|
||||
|
||||
const isFlashing = flashState.isFlashing();
|
||||
const shouldDriveStepBeDisabled = !selectionState.hasImage();
|
||||
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;
|
||||
|
@ -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>',
|
||||
});
|
||||
});
|
@ -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
59
npm-shrinkwrap.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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')
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user