Refactor UI without bootstrap & flexboxgrid

Change-type: patch
Changelog-entry: Refactor UI without bootstrap & flexboxgrid
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
Lorenzo Alberto Maria Ambrosi 2020-06-23 11:22:33 +02:00
parent 00f193541d
commit 3ca50a1e2d
No known key found for this signature in database
GPG Key ID: 0D424CCA84D4C9D4
9 changed files with 90 additions and 219 deletions

View File

@ -45,19 +45,13 @@ export class FeaturedProject extends React.Component<
public async componentDidMount() { public async componentDidMount() {
try { try {
let endpoint = const url = new URL(
(await settings.get('featuredProjectEndpoint')) || (await settings.get('featuredProjectEndpoint')) ||
'https://assets.balena.io/etcher-featured/index.html'; 'https://assets.balena.io/etcher-featured/index.html',
const efpParams = { );
borderRight: false, url.searchParams.append('borderRight', 'false');
darkBackground: true, url.searchParams.append('darkBackground', 'true');
}; this.setState({ endpoint: url.toString() });
let params = '?';
for (const [param, value] of Object.entries(efpParams)) {
params += `${param}=${value}&`;
}
endpoint += params;
this.setState({ endpoint });
} catch (error) { } catch (error) {
analytics.logException(error); analytics.logException(error);
} }

View File

@ -16,6 +16,7 @@
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as React from 'react'; import * as React from 'react';
import { Flex } from 'rendition';
import { v4 as uuidV4 } from 'uuid'; import { v4 as uuidV4 } from 'uuid';
import * as flashState from '../../models/flash-state'; import * as flashState from '../../models/flash-state';
@ -56,50 +57,45 @@ function formattedErrors() {
function FinishPage({ goToMain }: { goToMain: () => void }) { function FinishPage({ goToMain }: { goToMain: () => void }) {
const results = flashState.getFlashResults().results || {}; const results = flashState.getFlashResults().results || {};
return ( return (
<div className="page-finish row around-xs"> <Flex flexDirection="column" width="100%" color="#fff">
<div className="col-xs"> <Flex height="160px" alignItems="center" justifyContent="center">
<div className="box center"> <FlashResults results={results} errors={formattedErrors()} />
<FlashResults results={results} errors={formattedErrors()} />
<FlashAnother <FlashAnother
onClick={() => { onClick={() => {
restart(goToMain); restart(goToMain);
}} }}
/>
</Flex>
<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')
}
/> />
</div> </Flex>
<Flex mb="10px">
<div className="box center"> made with
<div className="fallback-banner"> <LoveSvg height="20px" style={{ margin: '0 10px' }} />
<div className="caption-big"> by
Thanks for using <BalenaSvg
<span height="20px"
style={{ cursor: 'pointer' }} style={{ margin: '0 10px', cursor: 'pointer' }}
onClick={() => onClick={() => openExternal('https://balena.io?ref=etcher_success')}
openExternal( />
'https://balena.io/etcher?ref=etcher_offline_banner', </Flex>
) </Flex>
} </Flex>
>
<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>
); );
} }

View File

@ -15,24 +15,17 @@
*/ */
import * as React from 'react'; import * as React from 'react';
import styled from 'styled-components';
import { BaseButton } from '../../styled-components'; import { BaseButton } from '../../styled-components';
const FlashAnotherButton = styled(BaseButton)`
position: absolute;
right: 152px;
top: 60px;
`;
export interface FlashAnotherProps { export interface FlashAnotherProps {
onClick: () => void; onClick: () => void;
} }
export const FlashAnother = (props: FlashAnotherProps) => { export const FlashAnother = (props: FlashAnotherProps) => {
return ( return (
<FlashAnotherButton primary onClick={props.onClick}> <BaseButton primary onClick={props.onClick}>
Flash Another Flash Another
</FlashAnotherButton> </BaseButton>
); );
}; };

View File

@ -16,6 +16,7 @@
import { faCheckCircle, faCircle } from '@fortawesome/free-solid-svg-icons'; import { faCheckCircle, faCircle } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as _ from 'lodash';
import outdent from 'outdent'; import outdent from 'outdent';
import * as React from 'react'; import * as React from 'react';
import { Txt, Flex } from 'rendition'; import { Txt, Flex } from 'rendition';
@ -39,17 +40,21 @@ export function FlashResults({
}; };
}) { }) {
const allDevicesFailed = results.devices.successful === 0; const allDevicesFailed = results.devices.successful === 0;
const effectiveSpeed = bytesToMegabytes( const effectiveSpeed = _.round(
results.sourceMetadata.size / bytesToMegabytes(
(results.bytesWritten / results.averageFlashingSpeed), results.sourceMetadata.size /
).toFixed(1); (results.bytesWritten / results.averageFlashingSpeed),
),
1,
);
return ( return (
<Flex <Flex
flexDirection="column" flexDirection="column"
mr="80px"
height="90px"
style={{ style={{
position: 'absolute', position: 'relative',
left: '153px', top: '25px',
top: '66px',
}} }}
> >
<Flex alignItems="center"> <Flex alignItems="center">
@ -66,12 +71,10 @@ export function FlashResults({
Flash Complete! Flash Complete!
</Txt> </Txt>
</Flex> </Flex>
<Flex flexDirection="column" mr="0" mb="0" ml="40px"> <Flex flexDirection="column" mr="0" mb="0" ml="40px" color="#7e8085">
{Object.keys(results.devices).map((type: 'failed' | 'successful') => { {Object.entries(results.devices).map(([type, quantity]) => {
const quantity = results.devices[type];
return quantity ? ( return quantity ? (
<Flex <Flex
color="#fff"
alignItems="center" alignItems="center"
tooltip={type === 'failed' ? errors : undefined} tooltip={type === 'failed' ? errors : undefined}
> >
@ -86,7 +89,6 @@ export function FlashResults({
})} })}
{!allDevicesFailed && ( {!allDevicesFailed && (
<Txt <Txt
color="#787c7f"
fontSize="10px" fontSize="10px"
style={{ style={{
fontWeight: 500, fontWeight: 500,

View File

@ -52,10 +52,10 @@ export class ReducedFlashingInfos extends React.Component<
height="21px" height="21px"
contents={this.props.imageLogo} contents={this.props.imageLogo}
fallback={ImageSvg} fallback={ImageSvg}
style={{ marginRight: 9 }} style={{ marginRight: '9px' }}
/> />
<Txt <Txt
style={{ marginRight: 9 }} style={{ marginRight: '9px' }}
tooltip={{ text: this.props.imageName, placement: 'right' }} tooltip={{ text: this.props.imageName, placement: 'right' }}
> >
{middleEllipsis(this.props.imageName, 16)} {middleEllipsis(this.props.imageName, 16)}
@ -64,7 +64,7 @@ export class ReducedFlashingInfos extends React.Component<
</Flex> </Flex>
<Flex> <Flex>
<DriveSvg width="21px" height="21px" style={{ marginRight: 9 }} /> <DriveSvg width="21px" height="21px" style={{ marginRight: '9px' }} />
<Txt tooltip={{ text: this.props.driveLabel, placement: 'right' }}> <Txt tooltip={{ text: this.props.driveLabel, placement: 'right' }}>
{middleEllipsis(this.props.driveTitle, 16)} {middleEllipsis(this.props.driveTitle, 16)}
</Txt> </Txt>

View File

@ -1,103 +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.
*/
.page-finish {
margin-top: 60px;
}
.page-finish .title,
.page-finish .title h3 {
color: $palette-theme-dark-foreground;
font-weight: bold;
}
.page-finish .center {
display: flex;
align-items: center;
justify-content: center;
}
.page-finish .box > div > button {
margin-right: 20px;
}
.page-finish webview {
width: 800px;
height: 300px;
position: absolute;
top: 80px;
left: 0;
z-index: 9001;
}
.page-finish .fallback-banner {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: absolute;
bottom: 0;
color: white;
height: 320px;
width: 100vw;
left: 0;
> * {
display: flex;
justify-content: center;
align-items: center;
}
.caption {
display: flex;
font-weight: 500;
}
.caption-big {
font-size: 28px;
font-weight: bold;
position: absolute;
top: 75px;
}
.caption-small {
font-size: 12px;
}
.fallback-footer {
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
position: absolute;
bottom: 0;
max-height: 21px;
margin-bottom: 17px;
}
.section-footer {
position: absolute;
right: 0;
bottom: 0;
.footer-right {
color: #7e8085;
font-size: 12px;
margin-right: 30px;
}
}
}

View File

@ -161,17 +161,21 @@ export class MainPage extends React.Component<
!this.state.isFlashing || !this.state.isWebviewShowing; !this.state.isFlashing || !this.state.isWebviewShowing;
return ( return (
<> <>
<header <Flex
id="app-header" id="app-header"
justifyContent="center"
style={{ style={{
width: '100%', width: '100%',
height: '50px',
padding: '13px 14px', padding: '13px 14px',
textAlign: 'center', textAlign: 'center',
position: 'relative', position: 'relative',
zIndex: 1, zIndex: 1,
}} }}
> >
<span <EtcherSvg
width="123px"
height="22px"
style={{ style={{
cursor: 'pointer', cursor: 'pointer',
}} }}
@ -179,11 +183,9 @@ export class MainPage extends React.Component<
openExternal('https://www.balena.io/etcher?ref=etcher_footer') openExternal('https://www.balena.io/etcher?ref=etcher_footer')
} }
tabIndex={100} tabIndex={100}
> />
<EtcherSvg width="123px" height="22px" />
</span>
<span <Flex
style={{ style={{
float: 'right', float: 'right',
position: 'absolute', position: 'absolute',
@ -208,8 +210,8 @@ export class MainPage extends React.Component<
tabIndex={6} tabIndex={6}
/> />
)} )}
</span> </Flex>
</header> </Flex>
{this.state.hideSettings ? null : ( {this.state.hideSettings ? null : (
<SettingsModal <SettingsModal
toggleModal={(value: boolean) => { toggleModal={(value: boolean) => {
@ -320,15 +322,23 @@ export class MainPage extends React.Component<
private renderSuccess() { private renderSuccess() {
return ( return (
<div className="section-loader isFinish"> <Flex flexDirection="column" alignItems="center" height="100%">
<FinishPage <FinishPage
goToMain={() => { goToMain={() => {
flashState.resetState(); flashState.resetState();
this.setState({ current: 'main' }); this.setState({ current: 'main' });
}} }}
/> />
<SafeWebview src="https://www.balena.io/etcher/success-banner/" /> <SafeWebview
</div> src="https://www.balena.io/etcher/success-banner/"
style={{
width: '100%',
height: '320px',
position: 'absolute',
bottom: 0,
}}
/>
</Flex>
); );
} }

View File

@ -1,19 +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.
*/
.disabled {
opacity: $disabled-opacity;
}

View File

@ -14,17 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
$icon-font-path: "../../../../node_modules/bootstrap-sass/assets/fonts/bootstrap/";
$font-size-base: 16px;
$cursor-disabled: initial;
$link-hover-decoration: none;
$btn-min-width: 170px;
$link-color: #ddd;
$disabled-opacity: 0.2; $disabled-opacity: 0.2;
@import "./modules/theme"; @import "./modules/theme";
@import "../pages/main/styles/main";
@import "../pages/finish/styles/finish";
@import "./desktop"; @import "./desktop";
@font-face { @font-face {
@ -46,9 +38,11 @@ $disabled-opacity: 0.2;
// Prevent white flash when running application // Prevent white flash when running application
html { html {
background-color: $palette-theme-dark-background; background-color: $palette-theme-dark-background;
margin: 0;
} }
body { body {
margin: 0;
background-color: $palette-theme-dark-background; background-color: $palette-theme-dark-background;
letter-spacing: 0.1px; letter-spacing: 0.1px;
display: flex; display: flex;
@ -104,3 +98,7 @@ body {
overflow: hidden; overflow: hidden;
} }
} }
.disabled {
opacity: $disabled-opacity;
}