Skip to content

Commit

Permalink
Merge pull request #3222 from balena-io/efp-restyle
Browse files Browse the repository at this point in the history
Efp restyle
  • Loading branch information
bulldozer-balena[bot] authored Jul 9, 2020
2 parents 72e5631 + 630f6c6 commit 7c24d14
Show file tree
Hide file tree
Showing 33 changed files with 762 additions and 2,005 deletions.
20 changes: 9 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ $(BUILD_DIRECTORY):
$(BUILD_TEMPORARY_DIRECTORY): | $(BUILD_DIRECTORY)
mkdir $@

# See https://stackoverflow.com/a/13468229/1641422
SHELL := /bin/bash
PATH := $(shell pwd)/node_modules/.bin:$(PATH)

# ---------------------------------------------------------------------
# Operating system and architecture detection
Expand Down Expand Up @@ -125,7 +123,7 @@ TARGETS = \
info \
lint \
lint-ts \
lint-sass \
lint-css \
lint-cpp \
lint-spell \
test-spectron \
Expand All @@ -140,15 +138,15 @@ TARGETS = \
electron-build

webpack:
./node_modules/.bin/webpack
npx webpack

.PHONY: $(TARGETS)

lint-ts:
balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts
npx balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts

lint-sass:
sass-lint -v lib/gui/app/scss/**/*.scss lib/gui/app/scss/*.scss
lint-css:
npx prettier --write lib/**/*.css

lint-cpp:
cpplint --recursive src
Expand All @@ -160,18 +158,18 @@ lint-spell:
--skip *.svg *.gz,*.bz2,*.xz,*.zip,*.img,*.dmg,*.iso,*.rpi-sdcard,*.wic,.DS_Store,*.dtb,*.dtbo,*.dat,*.elf,*.bin,*.foo,xz-without-extension \
lib tests docs Makefile *.md LICENSE

lint: lint-ts lint-sass lint-cpp lint-spell
lint: lint-ts lint-css lint-cpp lint-spell

MOCHA_OPTIONS=--recursive --reporter spec --require ts-node/register --require-main "tests/gui/allow-renderer-process-reuse.ts"

test-spectron:
mocha $(MOCHA_OPTIONS) tests/spectron/runner.spec.ts
npx mocha $(MOCHA_OPTIONS) tests/spectron/runner.spec.ts

test-gui:
electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox --renderer tests/gui/**/*.ts
npx electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox --renderer tests/gui/**/*.ts

test-sdk:
electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox tests/shared/**/*.ts
npx electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox tests/shared/**/*.ts

test: test-gui test-sdk test-spectron

Expand Down
4 changes: 0 additions & 4 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ technologies used in Etcher that you should become familiar with:
- [NodeJS][nodejs]
- [Redux][redux]
- [ImmutableJS][immutablejs]
- [Bootstrap][bootstrap]
- [Sass][sass]
- [Flexbox Grid][flexbox-grid]
- [Mocha][mocha]
- [JSDoc][jsdoc]

Expand Down Expand Up @@ -67,8 +65,6 @@ be documented instead!
[nodejs]: https://nodejs.org
[redux]: http://redux.js.org
[immutablejs]: http://facebook.github.io/immutable-js/
[bootstrap]: http://getbootstrap.com
[sass]: http://sass-lang.com
[flexbox-grid]: http://flexboxgrid.com
[mocha]: http://mochajs.org
[jsdoc]: http://usejsdoc.org
19 changes: 19 additions & 0 deletions lib/gui/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import * as ReactDOM from 'react-dom';
import { v4 as uuidV4 } from 'uuid';

import * as packageJSON from '../../../package.json';
import { isDriveValid, isSourceDrive } from '../../shared/drive-constraints';
import * as EXIT_CODES from '../../shared/exit-codes';
import * as messages from '../../shared/messages';
import * as availableDrives from './models/available-drives';
import * as flashState from './models/flash-state';
import { init as ledsInit } from './models/leds';
import { deselectImage, getImage, selectDrive } from './models/selection-state';
import * as settings from './models/settings';
import { Actions, observe, store } from './models/store';
import * as analytics from './modules/analytics';
Expand Down Expand Up @@ -247,9 +249,26 @@ async function addDrive(drive: Drive) {
const drives = getDrives();
drives[preparedDrive.device] = preparedDrive;
setDrives(drives);
if (
(await settings.get('autoSelectAllDrives')) &&
drive instanceof sdk.sourceDestination.BlockDevice &&
// @ts-ignore BlockDevice.drive is private
isDriveValid(drive.drive, getImage())
) {
selectDrive(drive.device);
}
}

function removeDrive(drive: Drive) {
if (
drive instanceof sdk.sourceDestination.BlockDevice &&
// @ts-ignore BlockDevice.drive is private
isSourceDrive(drive.drive, getImage())
) {
// Deselect the image if it was on the drive that was removed.
// This will also deselect the image if the drive mountpoints change.
deselectImage();
}
const preparedDrive = prepareDrive(drive);
const drives = getDrives();
delete drives[preparedDrive.device];
Expand Down
27 changes: 22 additions & 5 deletions lib/gui/app/components/featured-project/featured-project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ import * as analytics from '../../modules/analytics';
import { SafeWebview } from '../safe-webview/safe-webview';

interface FeaturedProjectProps {
shouldShow: boolean;
onWebviewShow: (isWebviewShowing: boolean) => void;
style?: React.CSSProperties;
}

interface FeaturedProjectState {
endpoint: string | null;
show: boolean;
}

export class FeaturedProject extends React.Component<
Expand All @@ -34,23 +37,37 @@ export class FeaturedProject extends React.Component<
> {
constructor(props: FeaturedProjectProps) {
super(props);
this.state = { endpoint: null };
this.state = {
endpoint: null,
show: false,
};
}

public async componentDidMount() {
try {
const endpoint =
const url = new URL(
(await settings.get('featuredProjectEndpoint')) ||
'https://assets.balena.io/etcher-featured/index.html';
this.setState({ endpoint });
'https://assets.balena.io/etcher-featured/index.html',
);
url.searchParams.append('borderRight', 'false');
url.searchParams.append('darkBackground', 'true');
this.setState({ endpoint: url.toString() });
} catch (error) {
analytics.logException(error);
}
}

public render() {
const { style = {} } = this.props;
return this.state.endpoint ? (
<SafeWebview src={this.state.endpoint} {...this.props}></SafeWebview>
<SafeWebview
src={this.state.endpoint}
style={{
display: this.state.show ? 'block' : 'none',
...style,
}}
{...this.props}
></SafeWebview>
) : null;
}
}
80 changes: 38 additions & 42 deletions lib/gui/app/components/finish/finish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import * as _ from 'lodash';
import * as React from 'react';
import { Flex } from 'rendition';
import { v4 as uuidV4 } from 'uuid';

import * as flashState from '../../models/flash-state';
Expand Down Expand Up @@ -56,50 +57,45 @@ function formattedErrors() {
function FinishPage({ goToMain }: { goToMain: () => void }) {
const results = flashState.getFlashResults().results || {};
return (
<div className="page-finish row around-xs">
<div className="col-xs">
<div className="box center">
<FlashResults results={results} errors={formattedErrors()} />
<Flex flexDirection="column" width="100%" color="#fff">
<Flex height="160px" alignItems="center" justifyContent="center">
<FlashResults results={results} errors={formattedErrors()} />

<FlashAnother
onClick={() => {
restart(goToMain);
}}
/>
</div>
<FlashAnother
onClick={() => {
restart(goToMain);
}}
/>
</Flex>

<div className="box center">
<div className="fallback-banner">
<div className="caption-big">
Thanks for using
<span
style={{ cursor: 'pointer' }}
onClick={() =>
openExternal(
'https://balena.io/etcher?ref=etcher_offline_banner',
)
}
>
<EtcherSvg width="165px" style={{ margin: '0 10px' }} />
</span>
</div>
<div className="caption-small fallback-footer">
made with
<LoveSvg height="20px" style={{ margin: '0 10px' }} />
by
<span
style={{ cursor: 'pointer' }}
onClick={() =>
openExternal('https://balena.io?ref=etcher_success')
}
>
<BalenaSvg height="20px" style={{ margin: '0 10px' }} />
</span>
</div>
</div>
</div>
</div>
</div>
<Flex
flexDirection="column"
height="320px"
justifyContent="space-between"
alignItems="center"
>
<Flex fontSize="28px" mt="40px">
Thanks for using
<EtcherSvg
width="165px"
style={{ margin: '0 10px', cursor: 'pointer' }}
onClick={() =>
openExternal('https://balena.io/etcher?ref=etcher_offline_banner')
}
/>
</Flex>
<Flex mb="10px">
made with
<LoveSvg height="20px" style={{ margin: '0 10px' }} />
by
<BalenaSvg
height="20px"
style={{ margin: '0 10px', cursor: 'pointer' }}
onClick={() => openExternal('https://balena.io?ref=etcher_success')}
/>
</Flex>
</Flex>
</Flex>
);
}

Expand Down
11 changes: 2 additions & 9 deletions lib/gui/app/components/flash-another/flash-another.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,17 @@
*/

import * as React from 'react';
import styled from 'styled-components';

import { BaseButton } from '../../styled-components';

const FlashAnotherButton = styled(BaseButton)`
position: absolute;
right: 152px;
top: 60px;
`;

export interface FlashAnotherProps {
onClick: () => void;
}

export const FlashAnother = (props: FlashAnotherProps) => {
return (
<FlashAnotherButton primary onClick={props.onClick}>
<BaseButton primary onClick={props.onClick}>
Flash Another
</FlashAnotherButton>
</BaseButton>
);
};
53 changes: 23 additions & 30 deletions lib/gui/app/components/flash-results/flash-results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,15 @@
* limitations under the License.
*/

import { faCheckCircle } from '@fortawesome/free-solid-svg-icons';
import { faCheckCircle, faCircle } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as _ from 'lodash';
import outdent from 'outdent';
import * as React from 'react';
import { Txt, Flex } from 'rendition';
import styled from 'styled-components';
import { left, position, space, top } from 'styled-system';

import { progress } from '../../../../shared/messages';
import { bytesToMegabytes } from '../../../../shared/units';
import { Underline } from '../../styled-components';

const Div = styled.div<any>`
${position}
${top}
${left}
${space}
`;

export function FlashResults({
errors,
Expand All @@ -58,7 +48,15 @@ export function FlashResults({
1,
);
return (
<Div position="absolute" left="153px" top="66px">
<Flex
flexDirection="column"
mr="80px"
height="90px"
style={{
position: 'relative',
top: '25px',
}}
>
<Flex alignItems="center">
<FontAwesomeIcon
icon={faCheckCircle}
Expand All @@ -73,29 +71,24 @@ export function FlashResults({
Flash Complete!
</Txt>
</Flex>
<Div className="results" mr="0" mb="0" ml="40px">
{_.map(results.devices, (quantity, type) => {
<Flex flexDirection="column" mr="0" mb="0" ml="40px" color="#7e8085">
{Object.entries(results.devices).map(([type, quantity]) => {
return quantity ? (
<Underline
<Flex
alignItems="center"
tooltip={type === 'failed' ? errors : undefined}
key={type}
>
<div
key={type}
className={`target-status-line target-status-${type}`}
>
<span className="target-status-dot"></span>
<span className="target-status-quantity">{quantity}</span>
<span className="target-status-message">
{progress[type](quantity)}
</span>
</div>
</Underline>
<FontAwesomeIcon
color={type === 'failed' ? '#ff4444' : '#1ac135'}
icon={faCircle}
/>
<Txt ml={10}>{quantity}</Txt>
<Txt ml={10}>{progress[type](quantity)}</Txt>
</Flex>
) : null;
})}
{!allDevicesFailed && (
<Txt
color="#787c7f"
fontSize="10px"
style={{
fontWeight: 500,
Expand All @@ -109,7 +102,7 @@ export function FlashResults({
Effective speed: {effectiveSpeed} MB/s
</Txt>
)}
</Div>
</Div>
</Flex>
</Flex>
);
}
Loading

0 comments on commit 7c24d14

Please sign in to comment.