Merge pull request #3195 from balena-io/ui-updates

Ui updates
This commit is contained in:
bulldozer-balena[bot] 2020-06-03 13:04:32 +00:00 committed by GitHub
commit bdb1690a49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 554 additions and 560 deletions

View File

@ -24,6 +24,7 @@
"generated",
"lib/shared/catalina-sudo/sudo-askpass.osascript.js"
],
"beforeBuild": "./beforeBuild.js",
"afterSign": "./afterSignHook.js",
"mac": {
"category": "public.app-category.developer-tools",

17
beforeBuild.js Normal file
View File

@ -0,0 +1,17 @@
'use strict'
const cp = require('child_process')
// Rebuild native modules for ia32 and run webpack again for the ia32 part of windows packages
exports.default = function(context) {
if (context.platform.name === 'windows') {
cp.execFileSync(
'bash',
['./node_modules/.bin/electron-rebuild', '--types', 'dev', '--arch', context.arch]
);
cp.execFileSync(
'bash',
['./node_modules/.bin/webpack']
);
}
}

View File

@ -4,6 +4,7 @@ productName: balenaEtcher
npmRebuild: true
nodeGypRebuild: true
publish: null
beforeBuild: "./beforeBuild.js"
afterPack: "./afterPack.js"
asar: false
files:

View File

@ -118,7 +118,7 @@ export function TargetSelector(props: TargetSelectorProps) {
}
return (
<>
<StepNameButton plain tooltip={props.tooltip}>
<StepNameButton plain tooltip={props.tooltip} fontSize={16}>
{targets.length} Targets
</StepNameButton>
{!props.flashing && (

View File

@ -67,7 +67,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
<div className="box center">
<div className="fallback-banner">
<div className="caption caption-big">
<div className="caption-big">
Thanks for using
<span
style={{ cursor: 'pointer' }}
@ -84,7 +84,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
></SVGIcon>
</span>
</div>
<div className="caption caption-small fallback-footer">
<div className="caption-small fallback-footer">
made with
<SVGIcon
paths={['love.svg']}

View File

@ -16,13 +16,13 @@
import * as React from 'react';
import styled from 'styled-components';
import { position, right } from 'styled-system';
import { BaseButton, ThemedProvider } from '../../styled-components';
import { BaseButton } from '../../styled-components';
const Div = styled.div<any>`
${position}
${right}
const FlashAnotherButton = styled(BaseButton)`
position: absolute;
right: 152px;
top: 60px;
`;
export interface FlashAnotherProps {
@ -31,12 +31,8 @@ export interface FlashAnotherProps {
export const FlashAnother = (props: FlashAnotherProps) => {
return (
<ThemedProvider>
<Div position="absolute" right="152px">
<BaseButton primary onClick={props.onClick}>
Flash Another
</BaseButton>
</Div>
</ThemedProvider>
<FlashAnotherButton primary onClick={props.onClick}>
Flash Another
</FlashAnotherButton>
);
};

View File

@ -15,6 +15,7 @@
*/
import * as _ from 'lodash';
import outdent from 'outdent';
import * as React from 'react';
import { Txt } from 'rendition';
import styled from 'styled-components';
@ -37,18 +38,31 @@ export function FlashResults({
}: {
errors: string;
results: {
bytesWritten: number;
sourceMetadata: {
size: number;
blockmappedSize: number;
};
averageFlashingSpeed: number;
devices: { failed: number; successful: number };
};
}) {
const averageSpeed = _.round(
bytesToMegabytes(results.averageFlashingSpeed),
const allDevicesFailed = results.devices.successful === 0;
const effectiveSpeed = _.round(
bytesToMegabytes(
results.sourceMetadata.size /
(results.bytesWritten / results.averageFlashingSpeed),
),
1,
);
return (
<Div position="absolute" left="153px" top="66px">
<div className="inline-flex title">
<span className="tick tick--success space-right-medium"></span>
<span
className={`tick tick--${
allDevicesFailed ? 'error' : 'success'
} space-right-medium`}
></span>
<h3>Flash Complete!</h3>
</div>
<Div className="results" mr="0" mb="0" ml="40px">
@ -71,16 +85,22 @@ export function FlashResults({
</Underline>
) : null;
})}
<Txt
color="#787c7f"
fontSize="10px"
style={{
fontWeight: 500,
textAlign: 'center',
}}
>
Writing speed: {averageSpeed} MB/s
</Txt>
{!allDevicesFailed && (
<Txt
color="#787c7f"
fontSize="10px"
style={{
fontWeight: 500,
textAlign: 'center',
}}
tooltip={outdent({ newline: ' ' })`
The speed is calculated by dividing the image size by the flashing time.
Disk images with ext partitions flash faster as we are able to skip unused parts.
`}
>
Effective speed: {effectiveSpeed} MB/s
</Txt>
)}
</Div>
</Div>
);

View File

@ -15,15 +15,16 @@
*/
import * as React from 'react';
import { ProgressBar } from 'rendition';
import { Button, Flex, ProgressBar, Txt } from 'rendition';
import { default as styled } from 'styled-components';
import { fromFlashState } from '../../modules/progress-status';
import { StepButton } from '../../styled-components';
const FlashProgressBar = styled(ProgressBar)`
> div {
width: 200px;
height: 48px;
width: 220px;
height: 12px;
color: white !important;
text-shadow: none !important;
transition-duration: 0s;
@ -32,8 +33,9 @@ const FlashProgressBar = styled(ProgressBar)`
}
}
width: 200px;
height: 48px;
width: 220px;
height: 12px;
border-radius: 14px;
font-size: 16px;
line-height: 48px;
@ -44,8 +46,9 @@ interface ProgressButtonProps {
type: 'decompressing' | 'flashing' | 'verifying';
active: boolean;
percentage: number;
label: string;
position: number;
disabled: boolean;
cancel: () => void;
callback: () => void;
}
@ -55,16 +58,41 @@ const colors = {
verifying: '#1ac135',
} as const;
const CancelButton = styled((props) => (
<Button plain {...props}>
Cancel
</Button>
))`
font-weight: 600;
&&& {
width: auto;
height: auto;
font-size: 14px;
}
`;
export class ProgressButton extends React.PureComponent<ProgressButtonProps> {
public render() {
const { status, position } = fromFlashState({
type: this.props.type,
position: this.props.position,
percentage: this.props.percentage,
});
if (this.props.active) {
return (
<FlashProgressBar
background={colors[this.props.type]}
value={this.props.percentage}
>
{this.props.label}
</FlashProgressBar>
<div>
<Flex justifyContent="space-between" style={{ fontWeight: 600 }}>
<Flex>
<Txt color="#fff">{status}&nbsp;</Txt>
<Txt color={colors[this.props.type]}>{position}</Txt>
</Flex>
<CancelButton onClick={this.props.cancel} color="#00aeef" />
</Flex>
<FlashProgressBar
background={colors[this.props.type]}
value={this.props.percentage}
/>
</div>
);
}
return (
@ -73,7 +101,7 @@ export class ProgressButton extends React.PureComponent<ProgressButtonProps> {
onClick={this.props.callback}
disabled={this.props.disabled}
>
{this.props.label}
Flash!
</StepButton>
);
}

View File

@ -39,7 +39,6 @@ import {
DetailsText,
StepButton,
StepNameButton,
StepSelection,
} from '../../styled-components';
import { colors } from '../../theme';
import { middleEllipsis } from '../../utils/middle-ellipsis';
@ -183,10 +182,12 @@ const FlowSelector = styled(
},
)`
border-radius: 24px;
color: rgba(255, 255, 255, 0.7);
:enabled:hover {
background-color: ${colors.primary.background};
color: ${colors.primary.foreground};
font-weight: 600;
svg {
color: ${colors.primary.foreground}!important;
@ -464,6 +465,7 @@ export class SourceSelector extends React.Component<
<>
<StepNameButton
plain
fontSize={16}
onClick={this.showSelectedImageDetails}
tooltip={imageName || imageBasename}
>
@ -479,7 +481,7 @@ export class SourceSelector extends React.Component<
</DetailsText>
</>
) : (
<StepSelection>
<>
<FlowSelector
key="Flash from file"
flow={{
@ -488,7 +490,6 @@ export class SourceSelector extends React.Component<
icon: <FontAwesomeIcon icon={faFile} />,
}}
/>
;
<FlowSelector
key="Flash from URL"
flow={{
@ -497,8 +498,7 @@ export class SourceSelector extends React.Component<
icon: <FontAwesomeIcon icon={faLink} />,
}}
/>
;
</StepSelection>
</>
)}
</div>
</div>

View File

@ -25,56 +25,53 @@ export interface FlashState {
type?: 'decompressing' | 'flashing' | 'verifying';
}
/**
* @summary Make the progress status subtitle string
*
* @param {Object} state - flashing metadata
*
* @returns {String}
*
* @example
* const status = progressStatus.fromFlashState({
* type: 'flashing'
* active: 1,
* failed: 0,
* percentage: 55,
* speed: 2049,
* })
*
* console.log(status)
* // '55% Flashing'
*/
export function fromFlashState({
type,
percentage,
position,
}: FlashState): string {
}: Pick<FlashState, 'type' | 'percentage' | 'position'>): {
status: string;
position?: string;
} {
if (type === undefined) {
return 'Starting...';
return { status: 'Starting...' };
} else if (type === 'decompressing') {
if (percentage == null) {
return 'Decompressing...';
return { status: 'Decompressing...' };
} else {
return `${percentage}% Decompressing`;
return { position: `${percentage}%`, status: 'Decompressing...' };
}
} else if (type === 'flashing') {
if (percentage != null) {
if (percentage < 100) {
return `${percentage}% Flashing`;
return { position: `${percentage}%`, status: 'Flashing...' };
} else {
return 'Finishing...';
return { status: 'Finishing...' };
}
} else {
return `${bytesToClosestUnit(position)} flashed`;
return {
status: 'Flashing...',
position: `${bytesToClosestUnit(position)}`,
};
}
} else if (type === 'verifying') {
if (percentage == null) {
return 'Validating...';
return { status: 'Validating...' };
} else if (percentage < 100) {
return `${percentage}% Validating`;
return { position: `${percentage}%`, status: 'Validating...' };
} else {
return 'Finishing...';
return { status: 'Finishing...' };
}
}
return 'Failed';
return { status: 'Failed' };
}
export function titleFromFlashState(
state: Pick<FlashState, 'type' | 'percentage' | 'position'>,
): string {
const { status, position } = fromFlashState(state);
if (position !== undefined) {
return `${position} ${status}`;
}
return status;
}

View File

@ -17,7 +17,7 @@
import * as electron from 'electron';
import { percentageToFloat } from '../../../shared/utils';
import { FlashState, fromFlashState } from '../modules/progress-status';
import { FlashState, titleFromFlashState } from '../modules/progress-status';
/**
* @summary The title of the main window upon program launch
@ -29,7 +29,7 @@ const INITIAL_TITLE = document.title;
*/
function getWindowTitle(state?: FlashState) {
if (state) {
return `${INITIAL_TITLE} ${fromFlashState(state)}`;
return `${INITIAL_TITLE} ${titleFromFlashState(state)}`;
}
return INITIAL_TITLE;
}

View File

@ -18,50 +18,12 @@
margin-top: 60px;
}
.col-xs-5.inline-flex.items-baseline > span, .col-xs-5.inline-flex.items-baseline > div {
margin-bottom: -10px;
}
.page-finish .button-label {
margin: 0 auto $spacing-medium;
// Keep some spacing at the sides
max-width: $btn-min-width - 5px;
}
.page-finish .button-primary {
min-width: $btn-min-width;
}
.page-finish .title,
.page-finish .title h3 {
color: $palette-theme-dark-foreground;
font-weight: bold;
}
.page-finish .huge-title {
font-size: 3.5em;
}
.page-finish .label {
display: inline-block;
> b {
color: $palette-theme-dark-soft-foreground;
}
}
.page-finish .soft {
color: $palette-theme-dark-soft-foreground;
}
.page-finish .separator-xs {
flex-grow: 0;
background-color: $palette-theme-dark-soft-background;
padding: 0px;
min-width: 2px;
}
.page-finish .center {
display: flex;
align-items: center;
@ -148,11 +110,7 @@
display: inline-flex;
}
.items-baseline {
align-items: baseline;
}
.page-finish .tick--success {
.page-finish .tick {
/* hack(Shou): for some reason the height is stretched */
height: 24px;
width: 24px;
@ -164,11 +122,3 @@
display: flex;
font-size: 16px;
}
.title-wrap {
margin-left: 5px;
> .title {
margin-bottom: 3px;
}
}

View File

@ -33,8 +33,8 @@ const StepBorder = styled.div<{
height: 2px;
background-color: ${(props) =>
props.disabled
? props.theme.customColors.dark.disabled.foreground
: props.theme.customColors.dark.foreground};
? props.theme.colors.dark.disabled.foreground
: props.theme.colors.dark.foreground};
position: absolute;
width: 124px;
top: 19px;

View File

@ -17,7 +17,8 @@
import * as _ from 'lodash';
import * as path from 'path';
import * as React from 'react';
import { Modal, Txt } from 'rendition';
import { Flex, Modal, Txt } from 'rendition';
import * as constraints from '../../../../shared/drive-constraints';
import * as messages from '../../../../shared/messages';
import { DriveSelectorModal } from '../../components/drive-selector/DriveSelectorModal';
@ -30,9 +31,7 @@ import * as selection from '../../models/selection-state';
import * as analytics from '../../modules/analytics';
import { scanner as driveScanner } from '../../modules/drive-scanner';
import * as imageWriter from '../../modules/image-writer';
import * as progressStatus from '../../modules/progress-status';
import * as notification from '../../os/notification';
import { StepSelection } from '../../styled-components';
const COMPLETED_PERCENTAGE = 100;
const SPEED_PRECISION = 2;
@ -73,6 +72,7 @@ const getErrorMessageFromCode = (errorCode: string) => {
};
async function flashImageToDrive(
isFlashing: boolean,
goToSuccess: () => void,
sourceOptions: SourceOptions,
): Promise<string> {
@ -82,7 +82,7 @@ async function flashImageToDrive(
return _.includes(devices, drive.device);
});
if (drives.length === 0 || flashState.isFlashing()) {
if (drives.length === 0 || isFlashing) {
return '';
}
@ -128,13 +128,6 @@ async function flashImageToDrive(
return '';
}
const getProgressButtonLabel = () => {
if (!flashState.isFlashing()) {
return 'Flash!';
}
return progressStatus.fromFlashState(flashState.getFlashState());
};
const formatSeconds = (totalSeconds: number) => {
if (!totalSeconds && !_.isNumber(totalSeconds)) {
return '';
@ -149,6 +142,14 @@ interface FlashStepProps {
shouldFlashStepBeDisabled: boolean;
goToSuccess: () => void;
source: SourceOptions;
isFlashing: boolean;
// TODO: factorize
step: 'decompressing' | 'flashing' | 'verifying';
percentage: number;
position: number;
failed: number;
speed?: number;
eta?: number;
}
interface FlashStepState {
@ -157,7 +158,10 @@ interface FlashStepState {
showDriveSelectorModal: boolean;
}
export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
export class FlashStep extends React.PureComponent<
FlashStepProps,
FlashStepState
> {
constructor(props: FlashStepProps) {
super(props);
this.state = {
@ -175,6 +179,7 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
}
this.setState({
errorMessage: await flashImageToDrive(
this.props.isFlashing,
this.props.goToSuccess,
this.props.source,
),
@ -200,7 +205,7 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
return _.includes(devices, drive.device);
},
);
if (drives.length === 0 || flashState.isFlashing()) {
if (drives.length === 0 || this.props.isFlashing) {
return;
}
const hasDangerStatus = constraints.hasListDriveImageCompatibilityStatus(
@ -213,6 +218,7 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
}
this.setState({
errorMessage: await flashImageToDrive(
this.props.isFlashing,
this.props.goToSuccess,
this.props.source,
),
@ -220,9 +226,6 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
}
public render() {
const state = flashState.getFlashState();
const isFlashing = flashState.isFlashing();
const flashErrorCode = flashState.getLastFlashErrorCode();
return (
<>
<div className="box text-center">
@ -234,51 +237,43 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
</div>
<div className="space-vertical-large">
<StepSelection>
<ProgressButton
type={state.type}
active={isFlashing}
percentage={state.percentage}
label={getProgressButtonLabel()}
disabled={
Boolean(flashErrorCode) ||
this.props.shouldFlashStepBeDisabled
}
callback={() => {
this.tryFlash();
}}
/>
</StepSelection>
<ProgressButton
type={this.props.step}
active={this.props.isFlashing}
percentage={this.props.percentage}
position={this.props.position}
disabled={this.props.shouldFlashStepBeDisabled}
cancel={imageWriter.cancel}
callback={() => {
this.tryFlash();
}}
/>
{isFlashing && (
<button
className="button button-link button-abort-write"
onClick={imageWriter.cancel}
>
<span className="glyphicon glyphicon-remove-sign"></span>
</button>
)}
{!_.isNil(state.speed) &&
state.percentage !== COMPLETED_PERCENTAGE && (
<p className="step-footer step-footer-split">
{Boolean(state.speed) && (
<span>{`${state.speed.toFixed(
SPEED_PRECISION,
)} MB/s`}</span>
{!_.isNil(this.props.speed) &&
this.props.percentage !== COMPLETED_PERCENTAGE && (
<Flex
justifyContent="space-between"
fontSize="14px"
color="#7e8085"
>
{!_.isNil(this.props.speed) && (
<Txt>{this.props.speed.toFixed(SPEED_PRECISION)} MB/s</Txt>
)}
{!_.isNil(state.eta) && (
<span>{`ETA: ${formatSeconds(state.eta)}`}</span>
{!_.isNil(this.props.eta) && (
<Txt>ETA: {formatSeconds(this.props.eta)}</Txt>
)}
</p>
</Flex>
)}
{Boolean(state.failed) && (
{Boolean(this.props.failed) && (
<div className="target-status-wrap">
<div className="target-status-line target-status-failed">
<span className="target-status-dot"></span>
<span className="target-status-quantity">{state.failed}</span>
<span className="target-status-quantity">
{this.props.failed}
</span>
<span className="target-status-message">
{messages.progress.failed(state.failed)}{' '}
{messages.progress.failed(this.props.failed)}{' '}
</span>
</div>
</div>

View File

@ -23,10 +23,10 @@ import * as React from 'react';
import { Flex } from 'rendition';
import styled from 'styled-components';
import { SafeWebview } from '../../components/safe-webview/safe-webview';
import { FeaturedProject } from '../../components/featured-project/featured-project';
import FinishPage from '../../components/finish/finish';
import { ReducedFlashingInfos } from '../../components/reduced-flashing-infos/reduced-flashing-infos';
import { SafeWebview } from '../../components/safe-webview/safe-webview';
import { SettingsModal } from '../../components/settings/settings';
import {
SourceOptions,
@ -131,6 +131,7 @@ export class MainPage extends React.Component<
}
private renderMain() {
const state = flashState.getFlashState();
const shouldDriveStepBeDisabled = !this.state.hasImage;
const shouldFlashStepBeDisabled =
!this.state.hasImage || !this.state.hasDrive;
@ -249,6 +250,13 @@ export class MainPage extends React.Component<
goToSuccess={() => this.setState({ current: 'success' })}
shouldFlashStepBeDisabled={shouldFlashStepBeDisabled}
source={this.state.source}
isFlashing={flashState.isFlashing()}
step={state.type}
percentage={state.percentage}
position={state.position}
failed={state.failed}
speed={state.speed}
eta={state.eta}
/>
</div>
</Flex>

View File

@ -28,101 +28,10 @@ img[disabled] {
height: 165px;
}
.page-main .step-selection-text {
display: flex;
flex-wrap: wrap;
justify-content: center;
color: $palette-theme-dark-foreground;
}
.page-main .text-disabled > span {
color: $palette-theme-dark-disabled-foreground;
}
.page-main .step-drive.text-warning {
color: $palette-theme-warning-background;
}
.page-main .relative {
position: relative;
}
.page-main .button-abort-write {
width: 20px;
height: 20px;
margin: 0;
padding: 0;
font-size: 16px;
position: absolute;
right: -17px;
top: 30%;
}
.button-brick {
width: 200px;
height: 48px;
font-size: 16px;
font-weight: 300;
}
.page-main .step-tooltip {
display: block;
margin: -5px auto -20px;
color: $palette-theme-dark-disabled-foreground;
font-size: 10px;
}
.page-main .step-footer {
width: 100%;
color: $palette-theme-dark-disabled-foreground;
font-size: 10px;
}
.page-main p.step-footer {
margin-top: 9px;
}
.page-main .step-footer-split {
position: absolute;
top: 39px;
left: 28px;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: space-between;
width: $btn-min-width;
}
.page-main .button.step-footer {
font-size: 16px;
color: $palette-theme-primary-background;
border-radius: 0;
padding: 0;
width: 100%;
font-weight: 300;
height: 21px;
}
.page-main .step-drive.glyphicon {
margin-top: 1px;
}
.page-main div.step-fill,
.page-main span.step-fill {
margin-top: 25px;
}
.page-main .step-drive.step-list {
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background-color: $palette-theme-dark-disabled-foreground;
border-radius: 4px;
}
}
.page-main .glyphicon {
vertical-align: text-top;
}
@ -137,22 +46,6 @@ img[disabled] {
color: $palette-theme-primary-foreground;
}
.page-main .step-size {
color: $palette-theme-dark-disabled-foreground;
margin: 0 0 8px 0;
font-size: 16px;
line-height: 1.5;
height: 21px;
width: 100%;
}
.page-main .step-list {
height: 80px;
margin: 15px;
overflow-y: auto;
color: $palette-theme-dark-disabled-foreground;
}
.target-status-wrap {
display: flex;
position: absolute;
@ -191,10 +84,6 @@ img[disabled] {
}
}
.tooltip-inner {
white-space: pre-line;
}
.space-vertical-large {
position: relative;
}

View File

@ -1,24 +0,0 @@
/*
* Copyright 2016 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
*/
.badge {
border: 2px solid;
border-radius: 50%;
padding: 7px 10px;
position: relative;
z-index: 10;
letter-spacing: 0;
}

View File

@ -1,99 +0,0 @@
/*
* Copyright 2016 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
*/
.button {
@extend .btn;
padding: 10px;
padding-top: 11px;
border-radius: 24px;
border: 0;
letter-spacing: .5px;
outline: none;
position: relative;
> .glyphicon {
top: 0;
width: 24px;
height: 24px;
}
&.button-primary{
width: 200px;
height: 48px;
}
&[disabled] {
@extend .button-no-hover;
background-color: $palette-theme-dark-disabled-background;
color: $palette-theme-dark-disabled-foreground;
opacity: 1;
}
}
.button-link {
@extend .btn-link;
}
.button-block {
display: block;
width: 100%;
}
.button-no-hover {
pointer-events: none;
}
// Create map from Bootstrap `.btn` type styles
// since its not possible to perform variable
// interpolation (e.g: `$btn-${type}-bg`).
// See https://github.com/sass/sass/issues/132
$button-types-styles: (
default: (
bg: $palette-theme-default-background,
color: $palette-theme-default-foreground
),
primary: (
bg: $palette-theme-primary-background,
color: $palette-theme-primary-foreground
),
danger: (
bg: $palette-theme-danger-background,
color: $palette-theme-danger-foreground
),
warning: (
bg: $palette-theme-warning-background,
color: $palette-theme-danger-foreground
)
);
@each $style in map-keys($button-types-styles) {
$button-styles: map-get($button-types-styles, $style);
.button-#{$style} {
background-color: map-get($button-styles, "bg");
color: map-get($button-styles, "color");
}
.button-#{$style}:focus,
.button-#{$style}:hover {
background-color: darken(map-get($button-styles, "bg"), 10%);
color: map-get($button-styles, "color");
}
}

View File

@ -1,21 +0,0 @@
/*
* Copyright 2016 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
*/
.caption {
font-weight: bold;
font-size: 11px;
margin-bottom: 0;
}

Binary file not shown.

Binary file not shown.

View File

@ -28,9 +28,6 @@ $disabled-opacity: 0.2;
@import "./modules/bootstrap";
@import "./modules/space";
@import "./components/label";
@import "./components/badge";
@import "./components/caption";
@import "./components/button";
@import "./components/tick";
@import "../components/drive-selector/styles/drive-selector";
@import "../pages/main/styles/main";
@ -38,66 +35,26 @@ $disabled-opacity: 0.2;
@import "./desktop";
@font-face {
font-family: "Nunito";
src: url("./fonts/Nunito-Regular.woff2") format("woff2");
font-weight: normal;
font-style: normal;
font-display: block;
}
@font-face {
font-family: "Nunito";
src: url("./fonts/Nunito-Bold.woff2") format("woff2");
font-weight: bold;
font-style: normal;
font-display: block;
}
@font-face {
font-family: "Nunito";
src: url("./fonts/Nunito-Light.woff2") format("woff2");
font-weight: 300;
font-style: normal;
font-display: block;
}
@font-face {
font-family: "CircularStd";
src: url("./fonts/CircularStd-Bold.woff2") format("woff2");
font-weight: bold;
font-style: normal;
font-display: block;
}
@font-face {
font-family: "CircularStd";
src: url("./fonts/CircularStd-Book.woff2") format("woff2");
font-family: "SourceSansPro";
src: url("./fonts/SourceSansPro-Regular.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: block;
}
@font-face {
font-family: "CircularStd";
src: url("./fonts/CircularStd-Medium.woff2") format("woff2");
font-weight: 400;
font-family: "SourceSansPro";
src: url("./fonts/SourceSansPro-SemiBold.ttf") format("truetype");
font-weight: 600;
font-style: normal;
font-display: block;
}
.circular {
font-family: "CircularStd";
font-weight: 500;
}
.nunito {
font-family: "Nunito";
}
body {
letter-spacing: 0.5px;
letter-spacing: 0.1px;
display: flex;
flex-direction: column;
font-family: "CircularStd";
font-family: "SourceSansPro";
> header {
flex: 0 0 auto;
@ -130,11 +87,6 @@ body {
}
}
.wrapper {
height: 100%;
margin: 20px 50px;
}
.featured-project {
webview {
flex: 0 1;

View File

@ -25,18 +25,3 @@ html {
body {
background-color: $palette-theme-dark-background;
}
// Fix slight checkbox vertical alignment issue
.checkbox input[type="checkbox"] {
position: initial;
margin-right: 2px;
}
[uib-tooltip] {
cursor: default;
}
.tooltip {
word-wrap: break-word;
}

View File

@ -15,15 +15,22 @@
*/
import * as React from 'react';
import { Button, ButtonProps, Flex, Provider, Txt } from 'rendition';
import { Button, ButtonProps, Provider, Txt } from 'rendition';
import styled from 'styled-components';
import { space } from 'styled-system';
import { colors } from './theme';
const font = 'SourceSansPro';
const theme = {
// TODO: Standardize how the colors are specified to match with rendition's format.
customColors: colors,
font,
titleFont: font,
global: {
font: {
family: font,
},
},
colors,
button: {
border: {
width: '0',
@ -33,10 +40,9 @@ const theme = {
opacity: 1,
},
extend: () => `
&& {
&& {
width: 200px;
height: 48px;
font-size: 16px;
&:disabled {
background-color: ${colors.dark.disabled.background};
@ -48,8 +54,8 @@ const theme = {
color: ${colors.dark.disabled.foreground};
}
}
}
`,
}
`,
},
};
@ -77,7 +83,7 @@ export const IconButton = styled((props) => <Button plain {...props} />)`
export const StepButton = styled((props: ButtonProps) => (
<Button {...props}></Button>
))`
color: rgba(255, 255, 255, 0.7);
color: #ffffff;
margin: auto;
`;
@ -117,10 +123,6 @@ export const StepNameButton = styled(Button)`
}
}
`;
export const StepSelection = styled(Flex)`
flex-wrap: wrap;
justify-content: center;
`;
export const Footer = styled(Txt)`
margin-top: 10px;
color: ${colors.dark.disabled.foreground};

View File

@ -49,6 +49,7 @@ export const colors = {
secondary: {
foreground: '#000',
background: '#ddd',
main: '#fff',
},
warning: {
foreground: '#fff',

317
npm-shrinkwrap.json generated
View File

@ -119,9 +119,9 @@
}
},
"@babel/runtime-corejs2": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.9.6.tgz",
"integrity": "sha512-TcdM3xc7weMrwTawuG3BTjtVE3mQLXUPQ9CxTbSKOrhn3QAcqCJ2fz+IIv25wztzUnhNZat7hr655YJa61F3zg==",
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.10.0.tgz",
"integrity": "sha512-sH02MTpZ4/f9glo0UNGXWQhl23e9gEB2MzjAqHZnKrztmY6eGxxPFJOniEHDOQisJwWZJlPAcBywi45lYc4h2w==",
"dev": true,
"requires": {
"core-js": "^2.6.5",
@ -839,9 +839,9 @@
}
},
"@types/react-native": {
"version": "0.62.11",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.62.11.tgz",
"integrity": "sha512-hRJSROGw+3JIp2w4WAAA+/4YM/HApeOQul7FVxOzLduaMKV/YZnm+1bfkS7hhKp9JqlbFNgqoRY/p2Ut7AD47g==",
"version": "0.62.12",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.62.12.tgz",
"integrity": "sha512-EuM2QOx0LGwY3mKQ313+QcTYOwJhw5eggmE42GO4ElIKIfNK+zxxM6Pe9dT1Eq8eCJXY0oG327L7gUBWniwNNA==",
"dev": true,
"requires": {
"@types/react": "*"
@ -2739,6 +2739,12 @@
"restore-cursor": "^3.1.0"
}
},
"cli-spinners": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
"integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==",
"dev": true
},
"cli-truncate": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
@ -2997,6 +3003,12 @@
"simple-swizzle": "^0.2.2"
}
},
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -4659,6 +4671,174 @@
}
}
},
"electron-rebuild": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.11.0.tgz",
"integrity": "sha512-cn6AqZBQBVtaEyj5jZW1/LOezZZ22PA1HvhEP7asvYPJ8PDF4i4UFt9be4i9T7xJKiSiomXvY5Fd+dSq3FXZxA==",
"dev": true,
"requires": {
"colors": "^1.3.3",
"debug": "^4.1.1",
"detect-libc": "^1.0.3",
"fs-extra": "^8.1.0",
"node-abi": "^2.11.0",
"node-gyp": "^6.0.1",
"ora": "^3.4.0",
"spawn-rx": "^3.0.0",
"yargs": "^14.2.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"requires": {
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
},
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
}
},
"yargs": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz",
"integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==",
"dev": true,
"requires": {
"cliui": "^5.0.0",
"decamelize": "^1.2.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^15.0.1"
}
},
"yargs-parser": {
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz",
"integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
"electron-updater": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.2.tgz",
@ -6622,6 +6802,12 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"highlight.js": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.0.3.tgz",
"integrity": "sha512-9FG7SSzv9yOY5CGGxfI6NDm7xLYtMOjKtPBxw7Zff3t5UcRcUNTGEeS8lNjhceL34KeetLMoGMFTGoaa83HwyQ==",
"dev": true
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@ -8045,6 +8231,12 @@
"lodash": ">=3.7.0"
}
},
"lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
"dev": true
},
"lodash.capitalize": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
@ -9769,6 +9961,74 @@
"word-wrap": "~1.2.3"
}
},
"ora": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
"integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
"dev": true,
"requires": {
"chalk": "^2.4.2",
"cli-cursor": "^2.1.0",
"cli-spinners": "^2.0.0",
"log-symbols": "^2.2.0",
"strip-ansi": "^5.2.0",
"wcwidth": "^1.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"dev": true,
"requires": {
"restore-cursor": "^2.0.0"
}
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"dev": true,
"requires": {
"chalk": "^2.0.1"
}
},
"onetime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
"mimic-fn": "^1.0.0"
}
},
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"dev": true,
"requires": {
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@ -10745,9 +11005,9 @@
"dev": true
},
"rendition": {
"version": "14.11.6",
"resolved": "https://registry.npmjs.org/rendition/-/rendition-14.11.6.tgz",
"integrity": "sha512-epV7isy+AjmPOI/ty6KBKk8rvHluIT6gi80oBhHAqTBNznHb8T5OQb+KES/3/8sjWX8dxtSgw8TLOHMm9f0yFg==",
"version": "14.13.0",
"resolved": "https://registry.npmjs.org/rendition/-/rendition-14.13.0.tgz",
"integrity": "sha512-MBKuUZnBsOkZApmVrDYycMWhD7KypJZqa6ZSD+y2uIoYEtFBSQ+kr4iJLh3lsgBuFTkouBrjYWJeN+X2FWb5bQ==",
"dev": true,
"requires": {
"@fortawesome/fontawesome-svg-core": "^1.2.25",
@ -10773,6 +11033,7 @@
"color-hash": "^1.0.3",
"copy-to-clipboard": "^3.0.8",
"grommet": "^2.13.0",
"highlight.js": "^10.0.3",
"jellyschema": "^0.11.9",
"lodash": "^4.17.11",
"marked": "^0.8.0",
@ -10781,7 +11042,7 @@
"react-google-recaptcha": "^2.0.0-rc.1",
"react-jsonschema-form": "^1.3.0",
"react-notifications-component": "^2.2.3",
"react-simplemde-editor": "^4.1.0",
"react-simplemde-editor": "^4.1.1",
"recompose": "0.26.0",
"regex-parser": "^2.2.7",
"sanitize-html": "^1.20.1",
@ -11931,6 +12192,34 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"spawn-rx": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/spawn-rx/-/spawn-rx-3.0.0.tgz",
"integrity": "sha512-dw4Ryg/KMNfkKa5ezAR5aZe9wNwPdKlnHEXtHOjVnyEDSPQyOpIPPRtcIiu7127SmtHhaCjw21yC43HliW0iIg==",
"dev": true,
"requires": {
"debug": "^2.5.1",
"lodash.assign": "^4.2.0",
"rxjs": "^6.3.1"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
}
}
},
"spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
@ -12964,9 +13253,9 @@
}
},
"uglify-js": {
"version": "3.9.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.3.tgz",
"integrity": "sha512-r5ImcL6QyzQGVimQoov3aL2ZScywrOgBXGndbWrdehKoSvGe/RmiE5Jpw/v+GvxODt6l2tpBXwA7n+qZVlHBMA==",
"version": "3.9.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz",
"integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==",
"dev": true,
"requires": {
"commander": "~2.20.3"
@ -14674,4 +14963,4 @@
}
}
}
}
}

View File

@ -74,6 +74,7 @@
"electron-builder": "^22.7.0",
"electron-mocha": "^8.2.0",
"electron-notarize": "^0.3.0",
"electron-rebuild": "^1.11.0",
"electron-updater": "^4.3.2",
"etcher-sdk": "^4.1.4",
"file-loader": "^6.0.0",
@ -96,7 +97,7 @@
"react": "^16.8.5",
"react-dom": "^16.8.5",
"redux": "^4.0.5",
"rendition": "^14.11.6",
"rendition": "^14.13.0",
"request": "^2.81.0",
"resin-corvus": "^2.0.5",
"roboto-fontface": "^0.10.0",

View File

@ -20,7 +20,7 @@ import * as settings from '../../../lib/gui/app/models/settings';
import * as progressStatus from '../../../lib/gui/app/modules/progress-status';
describe('Browser: progressStatus', function () {
describe('.fromFlashState()', function () {
describe('.titleFromFlashState()', function () {
beforeEach(function () {
this.state = {
active: 1,
@ -36,25 +36,31 @@ describe('Browser: progressStatus', function () {
});
it('should report 0% if percentage == 0 but speed != 0', function () {
expect(progressStatus.fromFlashState(this.state)).to.equal('0% Flashing');
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'0% Flashing...',
);
});
it('should handle percentage == 0, flashing, unmountOnSuccess', function () {
this.state.speed = 0;
expect(progressStatus.fromFlashState(this.state)).to.equal('0% Flashing');
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'0% Flashing...',
);
});
it('should handle percentage == 0, flashing, !unmountOnSuccess', function () {
this.state.speed = 0;
settings.set('unmountOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal('0% Flashing');
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'0% Flashing...',
);
});
it('should handle percentage == 0, verifying, unmountOnSuccess', function () {
this.state.speed = 0;
this.state.type = 'verifying';
expect(progressStatus.fromFlashState(this.state)).to.equal(
'0% Validating',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'0% Validating...',
);
});
@ -62,31 +68,31 @@ describe('Browser: progressStatus', function () {
this.state.speed = 0;
this.state.type = 'verifying';
settings.set('unmountOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
'0% Validating',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'0% Validating...',
);
});
it('should handle percentage == 50, flashing, unmountOnSuccess', function () {
this.state.percentage = 50;
expect(progressStatus.fromFlashState(this.state)).to.equal(
'50% Flashing',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'50% Flashing...',
);
});
it('should handle percentage == 50, flashing, !unmountOnSuccess', function () {
this.state.percentage = 50;
settings.set('unmountOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
'50% Flashing',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'50% Flashing...',
);
});
it('should handle percentage == 50, verifying, unmountOnSuccess', function () {
this.state.percentage = 50;
this.state.type = 'verifying';
expect(progressStatus.fromFlashState(this.state)).to.equal(
'50% Validating',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'50% Validating...',
);
});
@ -94,14 +100,14 @@ describe('Browser: progressStatus', function () {
this.state.percentage = 50;
this.state.type = 'verifying';
settings.set('unmountOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
'50% Validating',
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'50% Validating...',
);
});
it('should handle percentage == 100, flashing, unmountOnSuccess, validateWriteOnSuccess', function () {
this.state.percentage = 100;
expect(progressStatus.fromFlashState(this.state)).to.equal(
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'Finishing...',
);
});
@ -109,7 +115,7 @@ describe('Browser: progressStatus', function () {
it('should handle percentage == 100, flashing, unmountOnSuccess, !validateWriteOnSuccess', function () {
this.state.percentage = 100;
settings.set('validateWriteOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'Finishing...',
);
});
@ -118,7 +124,7 @@ describe('Browser: progressStatus', function () {
this.state.percentage = 100;
settings.set('unmountOnSuccess', false);
settings.set('validateWriteOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'Finishing...',
);
});
@ -126,7 +132,7 @@ describe('Browser: progressStatus', function () {
it('should handle percentage == 100, verifying, unmountOnSuccess', function () {
this.state.percentage = 100;
this.state.type = 'verifying';
expect(progressStatus.fromFlashState(this.state)).to.equal(
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'Finishing...',
);
});
@ -134,7 +140,7 @@ describe('Browser: progressStatus', function () {
it('should handle percentage == 100, validatinf, !unmountOnSuccess', function () {
this.state.percentage = 100;
settings.set('unmountOnSuccess', false);
expect(progressStatus.fromFlashState(this.state)).to.equal(
expect(progressStatus.titleFromFlashState(this.state)).to.equal(
'Finishing...',
);
});

View File

@ -74,20 +74,20 @@ describe('Browser: WindowProgress', function () {
it('should set the flashing title', function () {
windowProgress.set(this.state);
assert.calledWith(this.setTitleSpy, ' 85% Flashing');
assert.calledWith(this.setTitleSpy, ' 85% Flashing...');
});
it('should set the verifying title', function () {
this.state.type = 'verifying';
windowProgress.set(this.state);
assert.calledWith(this.setTitleSpy, ' 85% Validating');
assert.calledWith(this.setTitleSpy, ' 85% Validating...');
});
it('should set the starting title', function () {
this.state.percentage = 0;
this.state.speed = 0;
windowProgress.set(this.state);
assert.calledWith(this.setTitleSpy, ' 0% Flashing');
assert.calledWith(this.setTitleSpy, ' 0% Flashing...');
});
it('should set the finishing title', function () {