Refactor UI grid to use rendition

Change-type: patch
Changelog-entry: Refactor UI grid to use rendition
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
Lorenzo Alberto Maria Ambrosi 2020-06-12 13:14:16 +02:00
parent 72e5631167
commit 9b71772e35
7 changed files with 195 additions and 221 deletions

View File

@ -84,7 +84,9 @@ export class ProgressButton extends React.PureComponent<ProgressButtonProps> {
return (
<>
<Flex
alignItems="baseline"
justifyContent="space-between"
width="100%"
style={{
marginTop: 42,
marginBottom: '6px',

View File

@ -22,7 +22,14 @@ import * as _ from 'lodash';
import { GPTPartition, MBRPartition } from 'partitioninfo';
import * as path from 'path';
import * as React from 'react';
import { ButtonProps, Card as BaseCard, Input, Modal, Txt } from 'rendition';
import {
ButtonProps,
Card as BaseCard,
Input,
Modal,
Txt,
Flex,
} from 'rendition';
import styled from 'styled-components';
import * as errors from '../../../../shared/errors';
@ -464,61 +471,55 @@ export class SourceSelector extends React.Component<
return (
<>
<div
className="box text-center relative"
<Flex
flexDirection="column"
alignItems="center"
onDrop={this.onDrop}
onDragEnter={this.onDragEnter}
onDragOver={this.onDragOver}
>
<div className="center-block">
<SVGIcon
contents={imageLogo}
fallback={<ImageSvg width="40px" height="40px" />}
/>
</div>
<SVGIcon
contents={imageLogo}
fallback={<ImageSvg width="40px" />}
/>
<div className="space-vertical-large">
{hasImage ? (
<>
<StepNameButton
plain
fontSize={16}
onClick={this.showSelectedImageDetails}
tooltip={imageName || imageBasename}
>
{middleEllipsis(imageName || imageBasename, 20)}
</StepNameButton>
{!flashing && (
<ChangeButton plain mb={14} onClick={this.reselectImage}>
Remove
</ChangeButton>
)}
<DetailsText>
{shared.bytesToClosestUnit(imageSize)}
</DetailsText>
</>
) : (
<>
<FlowSelector
key="Flash from file"
flow={{
onClick: this.openImageSelector,
label: 'Flash from file',
icon: <FontAwesomeIcon icon={faFile} />,
}}
/>
<FlowSelector
key="Flash from URL"
flow={{
onClick: this.openURLSelector,
label: 'Flash from URL',
icon: <FontAwesomeIcon icon={faLink} />,
}}
/>
</>
)}
</div>
</div>
{hasImage ? (
<>
<StepNameButton
plain
onClick={this.showSelectedImageDetails}
tooltip={imageName || imageBasename}
>
{middleEllipsis(imageName || imageBasename, 20)}
</StepNameButton>
{!flashing && (
<ChangeButton plain mb={14} onClick={this.reselectImage}>
Remove
</ChangeButton>
)}
<DetailsText>{shared.bytesToClosestUnit(imageSize)}</DetailsText>
</>
) : (
<>
<FlowSelector
key="Flash from file"
flow={{
onClick: this.openImageSelector,
label: 'Flash from file',
icon: <FontAwesomeIcon icon={faFile} />,
}}
/>
<FlowSelector
key="Flash from URL"
flow={{
onClick: this.openURLSelector,
label: 'Flash from URL',
icon: <FontAwesomeIcon icon={faLink} />,
}}
/>
</>
)}
</Flex>
{this.state.warning != null && (
<Modal

View File

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

View File

@ -16,8 +16,7 @@
import { scanner } from 'etcher-sdk';
import * as React from 'react';
import styled from 'styled-components';
import { Flex } from 'rendition';
import { TargetSelector } from '../../components/target-selector/target-selector-button';
import { TargetSelectorModal } from '../../components/target-selector/target-selector-modal';
import {
@ -30,27 +29,8 @@ import {
import * as settings from '../../models/settings';
import { observe } from '../../models/store';
import * as analytics from '../../modules/analytics';
import DriveSvg from '../../../assets/drive.svg';
const StepBorder = styled.div<{
disabled: boolean;
left?: boolean;
right?: boolean;
}>`
height: 2px;
background-color: ${(props) =>
props.disabled
? props.theme.colors.dark.disabled.foreground
: props.theme.colors.dark.foreground};
position: absolute;
width: 124px;
top: 19px;
left: ${(props) => (props.left ? '-67px' : undefined)};
right: ${(props) => (props.right ? '-67px' : undefined)};
`;
const getDriveListLabel = () => {
return getSelectedDrives()
.map((drive: any) => {
@ -100,17 +80,13 @@ export const selectAllTargets = (
};
interface DriveSelectorProps {
webviewShowing: boolean;
disabled: boolean;
nextStepDisabled: boolean;
hasDrive: boolean;
flashing: boolean;
}
export const DriveSelector = ({
webviewShowing,
disabled,
nextStepDisabled,
hasDrive,
flashing,
}: DriveSelectorProps) => {
@ -129,38 +105,25 @@ export const DriveSelector = ({
});
}, []);
const showStepConnectingLines = !webviewShowing || !flashing;
return (
<div className="box text-center relative">
{showStepConnectingLines && (
<>
<StepBorder disabled={disabled} left />
<StepBorder disabled={nextStepDisabled} right />
</>
)}
<Flex flexDirection="column" alignItems="center">
<DriveSvg className={disabled ? 'disabled' : ''} width="40px" />
<div className="center-block">
<DriveSvg className={disabled ? 'disabled' : ''} width="40px" />
</div>
<div className="space-vertical-large">
<TargetSelector
disabled={disabled}
show={!hasDrive && showDrivesButton}
tooltip={driveListLabel}
openDriveSelector={() => {
setShowTargetSelectorModal(true);
}}
reselectDrive={() => {
analytics.logEvent('Reselect drive');
setShowTargetSelectorModal(true);
}}
flashing={flashing}
targets={targets}
image={image}
/>
</div>
<TargetSelector
disabled={disabled}
show={!hasDrive && showDrivesButton}
tooltip={driveListLabel}
openDriveSelector={() => {
setShowTargetSelectorModal(true);
}}
reselectDrive={() => {
analytics.logEvent('Reselect drive');
setShowTargetSelectorModal(true);
}}
flashing={flashing}
targets={targets}
image={image}
/>
{showTargetSelectorModal && (
<TargetSelectorModal
@ -171,6 +134,6 @@ export const DriveSelector = ({
}}
></TargetSelectorModal>
)}
</div>
</Flex>
);
};

View File

@ -234,62 +234,59 @@ export class FlashStep extends React.PureComponent<
public render() {
return (
<>
<div className="box text-center">
<div className="center-block">
<FlashSvg
width="40px"
className={this.props.shouldFlashStepBeDisabled ? 'disabled' : ''}
/>
</div>
<Flex flexDirection="column" alignItems="center">
<FlashSvg
width="40px"
className={this.props.shouldFlashStepBeDisabled ? 'disabled' : ''}
/>
<div className="space-vertical-large">
<ProgressButton
type={this.props.step}
active={this.props.isFlashing}
percentage={this.props.percentage}
position={this.props.position}
disabled={this.props.shouldFlashStepBeDisabled}
cancel={imageWriter.cancel}
warning={this.hasListWarnings(
selection.getSelectedDrives(),
selection.getImage(),
)}
callback={() => {
this.tryFlash();
}}
/>
{!_.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(this.props.eta) && (
<Txt>ETA: {formatSeconds(this.props.eta)}</Txt>
)}
</Flex>
)}
{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">
{this.props.failed}
</span>
<span className="target-status-message">
{messages.progress.failed(this.props.failed)}{' '}
</span>
</div>
</div>
<ProgressButton
type={this.props.step}
active={this.props.isFlashing}
percentage={this.props.percentage}
position={this.props.position}
disabled={this.props.shouldFlashStepBeDisabled}
cancel={imageWriter.cancel}
warning={this.hasListWarnings(
selection.getSelectedDrives(),
selection.getImage(),
)}
</div>
</div>
callback={() => {
this.tryFlash();
}}
/>
{!_.isNil(this.props.speed) &&
this.props.percentage !== COMPLETED_PERCENTAGE && (
<Flex
justifyContent="space-between"
fontSize="14px"
color="#7e8085"
width="100%"
>
{!_.isNil(this.props.speed) && (
<Txt>{this.props.speed.toFixed(SPEED_PRECISION)} MB/s</Txt>
)}
{!_.isNil(this.props.eta) && (
<Txt>ETA: {formatSeconds(this.props.eta)}</Txt>
)}
</Flex>
)}
{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">
{this.props.failed}
</span>
<span className="target-status-message">
{messages.progress.failed(this.props.failed)}{' '}
</span>
</div>
</div>
)}
</Flex>
{this.state.warningMessages.length > 0 && (
<Modal

View File

@ -78,6 +78,26 @@ function getImageBasename() {
return selectionImageName || imageBasename;
}
const StepBorder = styled.div<{
disabled: boolean;
left?: boolean;
right?: boolean;
}>`
position: relative;
height: 2px;
background-color: ${(props) =>
props.disabled
? props.theme.colors.dark.disabled.foreground
: props.theme.colors.dark.foreground};
width: 120px;
top: 19px;
left: ${(props) => (props.left ? '-67px' : undefined)};
margin-right: ${(props) => (props.left ? '-120px' : undefined)};
right: ${(props) => (props.right ? '-67px' : undefined)};
margin-left: ${(props) => (props.right ? '-120px' : undefined)};
`;
interface MainPageStateFromStore {
isFlashing: boolean;
hasImage: boolean;
@ -193,73 +213,65 @@ export class MainPage extends React.Component<
/>
)}
<Flex
className="page-main row around-xs"
style={{ margin: '110px 50px' }}
>
<div className="col-xs">
<SourceSelector
flashing={this.state.isFlashing}
afterSelected={(source: SourceOptions) =>
this.setState({ source })
}
/>
</div>
<Flex m="110px 55px" justifyContent="space-between">
<SourceSelector
flashing={this.state.isFlashing}
afterSelected={(source: SourceOptions) => this.setState({ source })}
/>
<div className="col-xs">
<DriveSelector
webviewShowing={this.state.isWebviewShowing}
disabled={shouldDriveStepBeDisabled}
nextStepDisabled={shouldFlashStepBeDisabled}
hasDrive={this.state.hasDrive}
flashing={this.state.isFlashing}
/>
</div>
{(!this.state.isWebviewShowing || !this.state.isFlashing) && (
<Flex>
<StepBorder disabled={shouldDriveStepBeDisabled} left />
</Flex>
)}
{this.state.isFlashing && (
<div
className={`featured-project ${
this.state.isFlashing && this.state.isWebviewShowing
? 'fp-visible'
: ''
}`}
>
<DriveSelector
disabled={shouldDriveStepBeDisabled}
hasDrive={this.state.hasDrive}
flashing={this.state.isFlashing}
/>
{(!this.state.isWebviewShowing || !this.state.isFlashing) && (
<Flex>
<StepBorder disabled={shouldFlashStepBeDisabled} right />
</Flex>
)}
{this.state.isFlashing && this.state.isWebviewShowing && (
<>
<FeaturedProject
onWebviewShow={(isWebviewShowing: boolean) => {
this.setState({ isWebviewShowing });
}}
/>
</div>
<ReducedFlashingInfos
imageLogo={this.state.imageLogo}
imageName={middleEllipsis(this.state.imageName, 16)}
imageSize={
_.isNumber(this.state.imageSize)
? (bytesToClosestUnit(this.state.imageSize) as string)
: ''
}
driveTitle={middleEllipsis(this.state.driveTitle, 16)}
shouldShow={
this.state.isFlashing && this.state.isWebviewShowing
}
/>
</>
)}
<div>
<ReducedFlashingInfos
imageLogo={this.state.imageLogo}
imageName={middleEllipsis(this.state.imageName, 16)}
imageSize={
_.isNumber(this.state.imageSize)
? (bytesToClosestUnit(this.state.imageSize) as string)
: ''
}
driveTitle={middleEllipsis(this.state.driveTitle, 16)}
shouldShow={this.state.isFlashing && this.state.isWebviewShowing}
/>
</div>
<div className="col-xs">
<FlashStep
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>
<FlashStep
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}
/>
</Flex>
</>
);

View File

@ -54,7 +54,6 @@ export const StepButton = styled((props: ButtonProps) => (
<BaseButton {...props}></BaseButton>
))`
color: #ffffff;
margin: auto;
`;
export const ChangeButton = styled(Button)`