Merge pull request #2571 from balena-io/restyle-success-screen

Restyle success screen and enlarge UI elements
This commit is contained in:
Lorenzo Alberto Maria Ambrosi 2018-12-19 19:36:49 +01:00 committed by GitHub
commit 07858eecac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 373 additions and 121 deletions

View File

@ -298,9 +298,6 @@ rules:
# ECMAScript 6
arrow-body-style:
- error
- always
arrow-parens:
- error
- always

View File

@ -0,0 +1,43 @@
/*
* Copyright 2018 resin.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.
*/
'use strict'
const React = require('react')
const PropTypes = require('prop-types')
const styled = require('styled-components').default
const { position, right } = require('styled-system')
const Div = styled.div `
${position}
${right}
`
const FlashAnother = (props) => {
return (
<Div position='absolute' right='152px'>
<button className="button button-primary button-brick" onClick={props.onClick.bind(null, { preserveImage: true })}>
<b>Flash Another</b>
</button>
</Div>
)
}
FlashAnother.propTypes = {
onClick: PropTypes.func
}
module.exports = FlashAnother

View File

@ -0,0 +1,34 @@
/*
* Copyright 2018 resin.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.
*/
'use strict'
/**
* @module Etcher.Components.FlashAnother
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.FlashAnother'
const FlashAnother = angular.module(MODULE_NAME, [])
FlashAnother.component(
'flashAnother',
react2angular(require('./flash-another.jsx'))
)
module.exports = MODULE_NAME

View File

@ -0,0 +1,66 @@
/*
* Copyright 2018 resin.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.
*/
'use strict'
const React = require('react')
const PropTypes = require('prop-types')
const _ = require('lodash')
const styled = require('styled-components').default
const { position, left, top, space } = require('styled-system')
const { Underline } = require('./../../styled-components')
const Div = styled.div `
${position}
${top}
${left}
${space}
`
/* eslint-disable no-inline-comments */
const FlashResults = (props) => {
return (
<Div position='absolute' left='153px' top='66px'>
<div className="inline-flex title">
<span className="tick tick--success space-right-medium"></span>
<h3>Flash Complete!</h3>
</div>
<Div className="results" mt='11px' mr='0' mb='0' ml='40px'>
<Underline
tooltip={props.errors()}>
{_.map(props.results.devices, (quantity, type) => {
return (quantity) ? (
<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">{ props.message[type](quantity) }</span>
</div>
) : null
})}
</Underline>
</Div>
</Div>
)
}
FlashResults.propTypes = {
results: PropTypes.object,
message: PropTypes.object,
errors: PropTypes.func
}
module.exports = FlashResults

View File

@ -0,0 +1,34 @@
/*
* Copyright 2018 resin.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.
*/
'use strict'
/**
* @module Etcher.Components.FlashResults
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.FlashResults'
const FlashResults = angular.module(MODULE_NAME, [])
FlashResults.component(
'flashResults',
react2angular(require('./flash-results.jsx'))
)
module.exports = MODULE_NAME

View File

@ -19,6 +19,7 @@
const React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const { color } = require('styled-system')
const SvgIcon = require('../svg-icon/svg-icon.jsx')
const Div = styled.div `
@ -48,19 +49,23 @@ const Div = styled.div `
}
`
const Span = styled.span `
${color}
`
const ReducedFlashingInfos = (props) => {
return (props.shouldShow) ? (
<Div>
<span className="step-name">
<Span className="step-name">
<SvgIcon disabled contents={[ props.imageLogo ]} paths={[ '../../assets/image.svg' ]} width='20px'></SvgIcon>
<span>{ props.imageName }</span>
<span style={{ color: '#7e8085' }}>{ props.imageSize }</span>
</span>
<Span>{ props.imageName }</Span>
<Span color='#7e8085'>{ props.imageSize }</Span>
</Span>
<span className="step-name">
<Span className="step-name">
<SvgIcon disabled paths={[ '../../assets/drive.svg' ]} width='20px'></SvgIcon>
<span>{ props.driveTitle }</span>
</span>
<Span>{ props.driveTitle }</Span>
</Span>
</Div>
) : null
}

View File

@ -35,7 +35,7 @@
<main class="wrapper" ui-view></main>
<footer class="section-footer" ng-controller="StateController as state"
<footer class="section-footer-main" ng-controller="StateController as state"
ng-hide="state.currentName === 'success'">
<span os-open-external="https://www.balena.io/etcher?ref=etcher_footer"
tabindex="100">

View File

@ -43,6 +43,8 @@ module.exports = function ($state) {
this.progressMessage = messages.progress
this.results = this.flash.getFlashResults().results || {}
/**
* @summary Restart the flashing process
* @function

View File

@ -15,8 +15,12 @@
*/
.page-finish {
margin-top: -25px;
margin-top: -15px;
flex: 1;
.col-xs-5.inline-flex.items-baseline > span, .col-xs-5.inline-flex.items-baseline > div {
margin-bottom: -10px;
}
}
.page-finish .button-label {
@ -30,7 +34,8 @@
min-width: $btn-min-width;
}
.page-finish .title {
.page-finish .title,
.page-finish .title h3 {
color: $palette-theme-dark-foreground;
font-weight: bold;
}
@ -65,12 +70,8 @@
justify-content: center;
}
.page-finish .box > div {
margin-bottom: 20px;
> button {
margin-right: 20px;
}
.page-finish .box > div > button {
margin-right: 20px;
}
.page-finish webview {
@ -83,46 +84,58 @@
}
.page-finish .fallback-banner {
padding-top: 35px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 300px;
flex-direction: column;
position: absolute;
top: 125px;
left: 0;
background-color: $palette-theme-dark-background;
color: $palette-theme-dark-foreground;
font-weight: 300;
bottom: 0;
color: white;
height: 320px;
width: 100vw;
> * {
display: flex;
justify-content: center;
align-items: center;
}
.caption {
display: flex;
font-weight: normal;
font-weight: 500;
}
.caption-big {
font-size: 30px;
font-size: 28px;
font-weight: bold;
position: absolute;
top: 75px;
}
.caption-small {
font-size: 20px;
padding: 15px;
font-size: 12px;
}
.footer-right {
padding: 0;
border-bottom: 1px dashed;
.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;
}
.svg-icon {
margin-left: 0.3em;
margin-right: 0.3em
margin: 0 10px;
}
.section-footer {
border-top: none;
height: 39px;
position: absolute;
right: 0;
bottom: 0;
}
}
@ -136,7 +149,15 @@
.page-finish .tick--success {
/* hack(Shou): for some reason the height is stretched */
height: 28.9px;
height: 24px;
width: 24px;
border: none;
padding: 0;
margin: 0 15px 0 0;
justify-content: center;
align-items: center;
display: flex;
font-size: 16px;
}
.title-wrap {

View File

@ -1,25 +1,14 @@
<div class="page-finish row around-xs">
<div class="col-xs">
<div class="box center">
<div class="col-xs-5 inline-flex items-baseline">
<span class="tick tick--success space-right-tiny"></span>
<div uib-tooltip="{{ finish.formattedErrors() }}" tooltip-placement="bottom" class="title-wrap">
<h3 class="title">Flash Complete!</h3>
<div class="target-status-line target-status-{{ type }}"
ng-repeat="(type, quantity) in finish.flash.getFlashResults().results.devices"
ng-if="quantity">
<span class="target-status-dot"></span>
<span class="target-status-quantity">{{ quantity }}</span>
<span class="target-status-message">{{ finish.progressMessage[type](quantity) }}</span>
</div>
</div>
</div>
<flash-results
results="finish.results"
message="finish.progressMessage"
errors="finish.formattedErrors">
</flash-results>
<div class="col-xs-4">
<button class="button button-primary button-brick" ng-click="finish.restart({ preserveImage: true })">
<b>Flash Another</b>
</button>
</div>
<flash-another on-click="finish.restart">
</flash-another>
</div>
<div class="box center">
@ -32,23 +21,23 @@
</svg-icon>
</span>
</div>
<div class="caption caption-small">
<div class="caption caption-small fallback-footer">
made with
<svg-icon paths="[ '../../assets/love.svg' ]"
width="'20px'"
height="'auto'"></svg-icon>
width="'auto'"
height="'20px'"></svg-icon>
by
<span os-open-external="https://resin.io?ref=etcher_success">
<svg-icon paths="[ '../../assets/balena.svg' ]"
width="'100px'"
height="'auto'">
width="'auto'"
height="'20px'">
</svg-icon>
</span>
</div>
<div class="section-footer">
<span class="caption footer-right"
manifest-bind="version"
os-open-external="https://github.com/resin-io/etcher/blob/master/CHANGELOG.md"></span>
<div class="section-footer">
<span class="caption footer-right"
manifest-bind="version"
os-open-external="https://github.com/resin-io/etcher/blob/master/CHANGELOG.md"></span>
</div>
</div>
</div>
</div>

View File

@ -42,6 +42,8 @@ const MainPage = angular.module(MODULE_NAME, [
require('../../components/file-selector'),
require('../../components/featured-project'),
require('../../components/reduced-flashing-infos'),
require('../../components/flash-another'),
require('../../components/flash-results'),
require('../../os/open-external/open-external'),
require('../../os/dropzone/dropzone'),

View File

@ -47,7 +47,6 @@ svg-icon > img[disabled] {
}
.page-main .button-brick {
min-width: $btn-min-width;
width: 200px;
height: 48px;
font-size: 16px;
@ -64,6 +63,12 @@ svg-icon > img[disabled] {
top: 30%;
}
.button-brick {
width: 200px;
height: 48px;
font-size: 16px;
}
%step-border {
height: 2px;
background-color: $palette-theme-dark-foreground;
@ -184,14 +189,14 @@ svg-icon > img[disabled] {
.target-status-line {
display: flex;
align-items: baseline;
font-size: 11px;
font-size: 14px;
font-family: inherit;
> .target-status-dot {
width: 8px;
height: 8px;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 6px;
margin-right: 10px;
}
&.target-status-successful > .target-status-dot {
@ -208,7 +213,7 @@ svg-icon > img[disabled] {
> .target-status-message {
color: gray;
margin-left: 6px;
margin-left: 10px;
}
}

View File

@ -37,6 +37,7 @@
@extend .button-no-hover;
background-color: $palette-theme-dark-disabled-background;
color: $palette-theme-dark-disabled-foreground;
opacity: 1;
}
}

View File

@ -106,7 +106,7 @@ body,
font-family: Roboto;
}
.section-footer {
.section-footer-main {
display: flex;
align-items: center;
justify-content: center;

View File

@ -32,6 +32,7 @@ exports.StepButton = styled(Button) `
&:disabled {
background-color: ${colors.dark.disabled.background};
color: ${colors.dark.disabled.foreground};
opacity: 1;
&:hover {
background-color: ${colors.dark.disabled.background};
color: ${colors.dark.disabled.foreground};

View File

@ -26,7 +26,7 @@ exports.colors = {
},
disabled: {
foreground: '#787c7f',
background: '#313339'
background: '#3a3c41'
}
},
light: {

View File

@ -6076,7 +6076,8 @@ body {
margin-right: 2px; }
.button[disabled] {
background-color: #3a3c41;
color: #787c7f; }
color: #787c7f;
opacity: 1; }
.button-block {
display: block;
@ -6425,7 +6426,6 @@ svg-icon > img[disabled] {
position: relative; }
.page-main .button-brick {
min-width: 170px;
width: 200px;
height: 48px;
font-size: 16px; }
@ -6440,6 +6440,11 @@ svg-icon > img[disabled] {
right: -17px;
top: 30%; }
.button-brick {
width: 200px;
height: 48px;
font-size: 16px; }
.page-main .step-border-left, .page-main .step-border-right {
height: 2px;
background-color: #fff;
@ -6536,13 +6541,13 @@ svg-icon > img[disabled] {
.target-status-line {
display: flex;
align-items: baseline;
font-size: 11px;
font-size: 14px;
font-family: inherit; }
.target-status-line > .target-status-dot {
width: 8px;
height: 8px;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 6px; }
margin-right: 10px; }
.target-status-line.target-status-successful > .target-status-dot {
background-color: #5fb835; }
.target-status-line.target-status-failed > .target-status-dot {
@ -6552,7 +6557,7 @@ svg-icon > img[disabled] {
font-weight: bold; }
.target-status-line > .target-status-message {
color: gray;
margin-left: 6px; }
margin-left: 10px; }
.tooltip-inner {
white-space: pre-line; }
@ -6600,8 +6605,10 @@ svg-icon > img[disabled] {
* limitations under the License.
*/
.page-finish {
margin-top: -25px;
margin-top: -15px;
flex: 1; }
.page-finish .col-xs-5.inline-flex.items-baseline > span, .page-finish .col-xs-5.inline-flex.items-baseline > div {
margin-bottom: -10px; }
.page-finish .button-label {
margin: 0 auto 15px;
@ -6610,7 +6617,8 @@ svg-icon > img[disabled] {
.page-finish .button-primary {
min-width: 170px; }
.page-finish .title {
.page-finish .title,
.page-finish .title h3 {
color: #fff;
font-weight: bold; }
@ -6637,10 +6645,8 @@ svg-icon > img[disabled] {
align-items: center;
justify-content: center; }
.page-finish .box > div {
margin-bottom: 20px; }
.page-finish .box > div > button {
margin-right: 20px; }
.page-finish .box > div > button {
margin-right: 20px; }
.page-finish webview {
width: 800px;
@ -6651,35 +6657,45 @@ svg-icon > img[disabled] {
z-index: 9001; }
.page-finish .fallback-banner {
padding-top: 35px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 300px;
flex-direction: column;
position: absolute;
top: 125px;
left: 0;
background-color: #4d5057;
color: #fff;
font-weight: 300; }
bottom: 0;
color: white;
height: 320px;
width: 100vw; }
.page-finish .fallback-banner > * {
display: flex;
justify-content: center;
align-items: center; }
.page-finish .fallback-banner .caption {
display: flex;
font-weight: normal; }
font-weight: 500; }
.page-finish .fallback-banner .caption-big {
font-size: 30px; }
font-size: 28px;
font-weight: bold;
position: absolute;
top: 75px; }
.page-finish .fallback-banner .caption-small {
font-size: 20px;
padding: 15px; }
.page-finish .fallback-banner .footer-right {
padding: 0;
border-bottom: 1px dashed; }
font-size: 12px; }
.page-finish .fallback-banner .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; }
.page-finish .fallback-banner .svg-icon {
margin-left: 0.3em;
margin-right: 0.3em; }
margin: 0 10px; }
.page-finish .fallback-banner .section-footer {
border-top: none;
height: 39px; }
position: absolute;
right: 0;
bottom: 0; }
.inline-flex {
display: inline-flex; }
@ -6689,7 +6705,15 @@ svg-icon > img[disabled] {
.page-finish .tick--success {
/* hack(Shou): for some reason the height is stretched */
height: 28.9px; }
height: 24px;
width: 24px;
border: none;
padding: 0;
margin: 0 15px 0 0;
justify-content: center;
align-items: center;
display: flex;
font-size: 16px; }
.title-wrap {
margin-left: 5px; }
@ -9910,7 +9934,7 @@ body,
.popover {
font-family: Roboto; }
.section-footer {
.section-footer-main {
display: flex;
align-items: center;
justify-content: center;
@ -9920,20 +9944,20 @@ body,
padding-top: 15px;
border-top: 2px solid #64686a;
text-align: center; }
.section-footer .col-xs {
.section-footer-main .col-xs {
padding: 0; }
.section-footer .svg-icon {
.section-footer-main .svg-icon {
margin: 0 13px; }
.section-footer .caption[os-open-external] {
.section-footer-main .caption[os-open-external] {
border-bottom: 1px dashed;
padding-bottom: 2px; }
.section-footer .caption[os-open-external]:hover {
.section-footer-main .caption[os-open-external]:hover {
color: #85898c; }
.section-footer .footer-right {
.section-footer-main .footer-right {
font-size: 10px;
position: absolute;
right: 0; }
.section-footer > span[os-open-external] {
.section-footer-main > span[os-open-external] {
display: flex; }
.section-loader webview {

34
npm-shrinkwrap.json generated
View File

@ -2,9 +2,29 @@
"name": "balena-etcher",
"version": "1.4.8",
"dependencies": {
"@babel/runtime": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.2.0.tgz",
"dependencies": {
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz"
}
}
},
"@balena/grid-styled": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@balena/grid-styled/-/grid-styled-3.1.1.tgz"
"resolved": "https://registry.npmjs.org/@balena/grid-styled/-/grid-styled-3.1.1.tgz",
"dependencies": {
"prop-types": {
"version": "15.6.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz"
},
"styled-system": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/styled-system/-/styled-system-1.1.7.tgz"
}
}
},
"@fortawesome/fontawesome-free-webfonts": {
"version": "1.0.9",
@ -6727,6 +6747,14 @@
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/rendition/-/rendition-4.41.1.tgz",
"dependencies": {
"prop-types": {
"version": "15.6.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz"
},
"styled-system": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/styled-system/-/styled-system-1.1.7.tgz"
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz"
@ -7645,8 +7673,8 @@
}
},
"styled-system": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/styled-system/-/styled-system-1.1.7.tgz",
"version": "3.1.11",
"resolved": "https://registry.npmjs.org/styled-system/-/styled-system-3.1.11.tgz",
"dependencies": {
"prop-types": {
"version": "15.6.2",

View File

@ -92,7 +92,7 @@
"semver": "5.1.1",
"speedometer": "1.0.0",
"styled-components": "3.2.3",
"styled-system": "1.1.7",
"styled-system": "3.1.11",
"sudo-prompt": "8.2.3",
"udif": "0.13.0",
"unbzip2-stream": "github:resin-io-modules/unbzip2-stream#core-streams",