mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-21 18:26:32 +00:00
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:
parent
00f193541d
commit
3ca50a1e2d
@ -45,19 +45,13 @@ export class FeaturedProject extends React.Component<
|
||||
|
||||
public async componentDidMount() {
|
||||
try {
|
||||
let endpoint =
|
||||
const url = new URL(
|
||||
(await settings.get('featuredProjectEndpoint')) ||
|
||||
'https://assets.balena.io/etcher-featured/index.html';
|
||||
const efpParams = {
|
||||
borderRight: false,
|
||||
darkBackground: true,
|
||||
};
|
||||
let params = '?';
|
||||
for (const [param, value] of Object.entries(efpParams)) {
|
||||
params += `${param}=${value}&`;
|
||||
}
|
||||
endpoint += params;
|
||||
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);
|
||||
}
|
||||
|
@ -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';
|
||||
@ -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);
|
||||
}}
|
||||
<FlashAnother
|
||||
onClick={() => {
|
||||
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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
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';
|
||||
@ -39,17 +40,21 @@ export function FlashResults({
|
||||
};
|
||||
}) {
|
||||
const allDevicesFailed = results.devices.successful === 0;
|
||||
const effectiveSpeed = bytesToMegabytes(
|
||||
results.sourceMetadata.size /
|
||||
(results.bytesWritten / results.averageFlashingSpeed),
|
||||
).toFixed(1);
|
||||
const effectiveSpeed = _.round(
|
||||
bytesToMegabytes(
|
||||
results.sourceMetadata.size /
|
||||
(results.bytesWritten / results.averageFlashingSpeed),
|
||||
),
|
||||
1,
|
||||
);
|
||||
return (
|
||||
<Flex
|
||||
flexDirection="column"
|
||||
mr="80px"
|
||||
height="90px"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '153px',
|
||||
top: '66px',
|
||||
position: 'relative',
|
||||
top: '25px',
|
||||
}}
|
||||
>
|
||||
<Flex alignItems="center">
|
||||
@ -66,12 +71,10 @@ export function FlashResults({
|
||||
Flash Complete!
|
||||
</Txt>
|
||||
</Flex>
|
||||
<Flex flexDirection="column" mr="0" mb="0" ml="40px">
|
||||
{Object.keys(results.devices).map((type: 'failed' | 'successful') => {
|
||||
const quantity = results.devices[type];
|
||||
<Flex flexDirection="column" mr="0" mb="0" ml="40px" color="#7e8085">
|
||||
{Object.entries(results.devices).map(([type, quantity]) => {
|
||||
return quantity ? (
|
||||
<Flex
|
||||
color="#fff"
|
||||
alignItems="center"
|
||||
tooltip={type === 'failed' ? errors : undefined}
|
||||
>
|
||||
@ -86,7 +89,6 @@ export function FlashResults({
|
||||
})}
|
||||
{!allDevicesFailed && (
|
||||
<Txt
|
||||
color="#787c7f"
|
||||
fontSize="10px"
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
|
@ -52,10 +52,10 @@ export class ReducedFlashingInfos extends React.Component<
|
||||
height="21px"
|
||||
contents={this.props.imageLogo}
|
||||
fallback={ImageSvg}
|
||||
style={{ marginRight: 9 }}
|
||||
style={{ marginRight: '9px' }}
|
||||
/>
|
||||
<Txt
|
||||
style={{ marginRight: 9 }}
|
||||
style={{ marginRight: '9px' }}
|
||||
tooltip={{ text: this.props.imageName, placement: 'right' }}
|
||||
>
|
||||
{middleEllipsis(this.props.imageName, 16)}
|
||||
@ -64,7 +64,7 @@ export class ReducedFlashingInfos extends React.Component<
|
||||
</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' }}>
|
||||
{middleEllipsis(this.props.driveTitle, 16)}
|
||||
</Txt>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -161,17 +161,21 @@ export class MainPage extends React.Component<
|
||||
!this.state.isFlashing || !this.state.isWebviewShowing;
|
||||
return (
|
||||
<>
|
||||
<header
|
||||
<Flex
|
||||
id="app-header"
|
||||
justifyContent="center"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '50px',
|
||||
padding: '13px 14px',
|
||||
textAlign: 'center',
|
||||
position: 'relative',
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<span
|
||||
<EtcherSvg
|
||||
width="123px"
|
||||
height="22px"
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
@ -179,11 +183,9 @@ export class MainPage extends React.Component<
|
||||
openExternal('https://www.balena.io/etcher?ref=etcher_footer')
|
||||
}
|
||||
tabIndex={100}
|
||||
>
|
||||
<EtcherSvg width="123px" height="22px" />
|
||||
</span>
|
||||
/>
|
||||
|
||||
<span
|
||||
<Flex
|
||||
style={{
|
||||
float: 'right',
|
||||
position: 'absolute',
|
||||
@ -208,8 +210,8 @@ export class MainPage extends React.Component<
|
||||
tabIndex={6}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</header>
|
||||
</Flex>
|
||||
</Flex>
|
||||
{this.state.hideSettings ? null : (
|
||||
<SettingsModal
|
||||
toggleModal={(value: boolean) => {
|
||||
@ -320,15 +322,23 @@ export class MainPage extends React.Component<
|
||||
|
||||
private renderSuccess() {
|
||||
return (
|
||||
<div className="section-loader isFinish">
|
||||
<Flex flexDirection="column" alignItems="center" height="100%">
|
||||
<FinishPage
|
||||
goToMain={() => {
|
||||
flashState.resetState();
|
||||
this.setState({ current: 'main' });
|
||||
}}
|
||||
/>
|
||||
<SafeWebview src="https://www.balena.io/etcher/success-banner/" />
|
||||
</div>
|
||||
<SafeWebview
|
||||
src="https://www.balena.io/etcher/success-banner/"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '320px',
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -14,17 +14,9 @@
|
||||
* 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;
|
||||
|
||||
@import "./modules/theme";
|
||||
@import "../pages/main/styles/main";
|
||||
@import "../pages/finish/styles/finish";
|
||||
@import "./desktop";
|
||||
|
||||
@font-face {
|
||||
@ -46,9 +38,11 @@ $disabled-opacity: 0.2;
|
||||
// Prevent white flash when running application
|
||||
html {
|
||||
background-color: $palette-theme-dark-background;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: $palette-theme-dark-background;
|
||||
letter-spacing: 0.1px;
|
||||
display: flex;
|
||||
@ -104,3 +98,7 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: $disabled-opacity;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user