mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-28 05:36:34 +00:00
Convert settings modal to typescript
Change-type: patch Changelog-entry: Convert settings modal to typescript Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
parent
4c0a079d1e
commit
3b07946065
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,6 +1,8 @@
|
|||||||
# Javascript files must retain LF line-endings (to keep eslint happy)
|
# Javascript files must retain LF line-endings (to keep eslint happy)
|
||||||
*.js text eol=lf
|
*.js text eol=lf
|
||||||
*.jsx text eol=lf
|
*.jsx text eol=lf
|
||||||
|
*.ts text eol=lf
|
||||||
|
*.tsx text eol=lf
|
||||||
# CSS and SCSS files must retain LF line-endings (to keep ensure-staged-sass.sh happy)
|
# CSS and SCSS files must retain LF line-endings (to keep ensure-staged-sass.sh happy)
|
||||||
*.css text eol=lf
|
*.css text eol=lf
|
||||||
*.scss text eol=lf
|
*.scss text eol=lf
|
||||||
|
@ -94,7 +94,7 @@ const app = angular.module('Etcher', [
|
|||||||
// Pages
|
// Pages
|
||||||
require('./pages/main/main'),
|
require('./pages/main/main'),
|
||||||
require('./pages/finish/finish'),
|
require('./pages/finish/finish'),
|
||||||
require('./components/settings'),
|
require('./components/settings/index.ts').MODULE_NAME,
|
||||||
|
|
||||||
// OS
|
// OS
|
||||||
require('./os/open-external/open-external'),
|
require('./os/open-external/open-external'),
|
||||||
|
@ -189,7 +189,7 @@ const File = styled(UnstyledFile)`
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> div:last-child {
|
> div:last-child {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019 resin.io
|
* Copyright 2019 balena.io
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,21 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module Etcher.Components.FeaturedProject
|
* @module Etcher.Components.FeaturedProject
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const angular = require('angular')
|
import * as angular from 'angular';
|
||||||
const { react2angular } = require('react2angular')
|
import { react2angular } from 'react2angular';
|
||||||
|
import { SettingsButton } from './settings';
|
||||||
|
|
||||||
const MODULE_NAME = 'Etcher.Components.Settings'
|
export const MODULE_NAME = 'Etcher.Components.Settings';
|
||||||
const Settings = angular.module(MODULE_NAME, [])
|
const Settings = angular.module(MODULE_NAME, []);
|
||||||
|
|
||||||
Settings.component(
|
Settings.component('settings', react2angular(SettingsButton));
|
||||||
'settings',
|
|
||||||
react2angular(require('./settings.jsx').SettingsButton)
|
|
||||||
)
|
|
||||||
|
|
||||||
module.exports = MODULE_NAME
|
|
@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 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 { useState } = React
|
|
||||||
const propTypes = require('prop-types')
|
|
||||||
const _ = require('lodash')
|
|
||||||
const store = require('../../models/store')
|
|
||||||
const analytics = require('../../modules/analytics')
|
|
||||||
const settings = require('../../models/settings')
|
|
||||||
const { default: styled } = require('styled-components')
|
|
||||||
const { FaCog } = require('react-icons/fa')
|
|
||||||
const {
|
|
||||||
Badge,
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
Modal,
|
|
||||||
Provider
|
|
||||||
} = require('rendition')
|
|
||||||
const { colors } = require('../../theme')
|
|
||||||
|
|
||||||
const SettingsIcon = styled(FaCog) `
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
|
|
||||||
&&& {
|
|
||||||
color: ${colors.secondary.background}!important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const SettingsButton = () => {
|
|
||||||
const [ hideModal, setHideModal ] = useState(true)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Provider>
|
|
||||||
<Button
|
|
||||||
icon={<SettingsIcon/>}
|
|
||||||
plain
|
|
||||||
onClick={() => setHideModal(false)}
|
|
||||||
tabIndex="5">
|
|
||||||
</Button>
|
|
||||||
{ hideModal ? null : (
|
|
||||||
<SettingsModal toggleModal={(value) => setHideModal(!value)}>
|
|
||||||
</SettingsModal>
|
|
||||||
) }
|
|
||||||
</Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsButton.propTypes = {}
|
|
||||||
|
|
||||||
const WarningModal = ({
|
|
||||||
message,
|
|
||||||
confirmLabel,
|
|
||||||
cancel,
|
|
||||||
done
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
title={confirmLabel}
|
|
||||||
action={confirmLabel}
|
|
||||||
cancel={cancel}
|
|
||||||
done={done}
|
|
||||||
style={{
|
|
||||||
width: 420,
|
|
||||||
height: 300
|
|
||||||
}}
|
|
||||||
primaryButtonProps={{ warning: true }}>
|
|
||||||
{message}
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingsModal = styled((props) => {
|
|
||||||
const [ currentSettings, setCurrentSettings ] = useState(settings.getAll())
|
|
||||||
const [ warning, setWarning ] = useState({})
|
|
||||||
|
|
||||||
const toggleSetting = (setting, options) => {
|
|
||||||
const value = currentSettings[setting]
|
|
||||||
const dangerous = !_.isUndefined(options)
|
|
||||||
|
|
||||||
analytics.logEvent('Toggle setting', {
|
|
||||||
setting,
|
|
||||||
value,
|
|
||||||
dangerous,
|
|
||||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid
|
|
||||||
})
|
|
||||||
|
|
||||||
if (value || !dangerous) {
|
|
||||||
settings.set(setting, !value)
|
|
||||||
setCurrentSettings({
|
|
||||||
...currentSettings,
|
|
||||||
[setting]: !value
|
|
||||||
})
|
|
||||||
return setWarning({})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show warning since it's a dangerous setting
|
|
||||||
return setWarning({
|
|
||||||
setting,
|
|
||||||
settingValue: value,
|
|
||||||
...options
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
id='settings-modal'
|
|
||||||
title='Settings'
|
|
||||||
done={() => props.toggleModal(false)}
|
|
||||||
style={{
|
|
||||||
width: 780,
|
|
||||||
height: 460
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="6"
|
|
||||||
label="Anonymously report errors and usage statistics to balena.io"
|
|
||||||
checked={currentSettings.errorReporting}
|
|
||||||
onChange={() => toggleSetting('errorReporting')}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
// eslint-disable-next-line lines-around-comment
|
|
||||||
/* On Windows, "Unmounting" basically means "ejecting".
|
|
||||||
* On top of that, Windows users are usually not even
|
|
||||||
* familiar with the meaning of "unmount", which comes
|
|
||||||
* from the UNIX world. */
|
|
||||||
}
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="7"
|
|
||||||
label={`
|
|
||||||
${settings.platform === 'win32' ? 'Eject' : 'Auto-unmount'} on success
|
|
||||||
`}
|
|
||||||
checked={currentSettings.unmountOnSuccess}
|
|
||||||
onChange={() => toggleSetting('unmountOnSuccess')}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="8"
|
|
||||||
label="Validate write on success"
|
|
||||||
checked={currentSettings.validateWriteOnSuccess}
|
|
||||||
onChange={() => toggleSetting('validateWriteOnSuccess')}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="9"
|
|
||||||
label="Trim ext{2,3,4} partitions before writing (raw images only)"
|
|
||||||
checked={currentSettings.trim}
|
|
||||||
onChange={() => toggleSetting('trim')}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="10"
|
|
||||||
label="Auto-updates enabled"
|
|
||||||
checked={currentSettings.updatesEnabled}
|
|
||||||
onChange={() => toggleSetting('updatesEnabled')}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{ settings.get('disableUnsafeMode') ? null : (
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
toggle
|
|
||||||
tabIndex="11"
|
|
||||||
label={(<span>
|
|
||||||
Unsafe mode <Badge danger fontSize={12}>Dangerous</Badge>
|
|
||||||
</span>)}
|
|
||||||
checked={currentSettings.unsafeMode}
|
|
||||||
onChange={() => toggleSetting('unsafeMode', {
|
|
||||||
description: `Are you sure you want to turn this on?
|
|
||||||
You will be able to overwrite your system drives if you're not careful.`,
|
|
||||||
confirmLabel: 'Enable unsafe mode'
|
|
||||||
})}/>
|
|
||||||
</div>
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{ _.isEmpty(warning) ? null : (
|
|
||||||
<WarningModal
|
|
||||||
message={warning.description}
|
|
||||||
confirmLabel={warning.confirmLabel}
|
|
||||||
done={() => {
|
|
||||||
settings.set(warning.setting, !warning.settingValue)
|
|
||||||
setCurrentSettings({
|
|
||||||
...currentSettings,
|
|
||||||
[warning.setting]: true
|
|
||||||
})
|
|
||||||
setWarning({})
|
|
||||||
}}
|
|
||||||
cancel={() => {
|
|
||||||
setWarning({})
|
|
||||||
}}>
|
|
||||||
</WarningModal>
|
|
||||||
) }
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}) `
|
|
||||||
> div:nth-child(3) {
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
SettingsModal.propTypes = {
|
|
||||||
toggleModal: propTypes.func
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { SettingsButton, SettingsModal }
|
|
233
lib/gui/app/components/settings/settings.tsx
Normal file
233
lib/gui/app/components/settings/settings.tsx
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { faCog } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as propTypes from 'prop-types';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Badge, Button, Checkbox, Modal, Provider } from 'rendition';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import * as settings from '../../models/settings';
|
||||||
|
import * as store from '../../models/store';
|
||||||
|
import * as analytics from '../../modules/analytics';
|
||||||
|
import { colors } from '../../theme';
|
||||||
|
|
||||||
|
const { useState } = React;
|
||||||
|
const platform = os.platform();
|
||||||
|
|
||||||
|
export const SettingsButton = () => {
|
||||||
|
const [hideModal, setHideModal] = useState(true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Provider>
|
||||||
|
<Button
|
||||||
|
icon={<FontAwesomeIcon icon={faCog} />}
|
||||||
|
color={colors.secondary.background}
|
||||||
|
fontSize={24}
|
||||||
|
plain
|
||||||
|
onClick={() => setHideModal(false)}
|
||||||
|
tabIndex={5}
|
||||||
|
></Button>
|
||||||
|
{hideModal ? null : (
|
||||||
|
<SettingsModal toggleModal={(value: boolean) => setHideModal(!value)} />
|
||||||
|
)}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SettingsButton.propTypes = {};
|
||||||
|
|
||||||
|
interface WarningModalProps {
|
||||||
|
message: string;
|
||||||
|
confirmLabel: string;
|
||||||
|
cancel: () => void;
|
||||||
|
done: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WarningModal = ({
|
||||||
|
message,
|
||||||
|
confirmLabel,
|
||||||
|
cancel,
|
||||||
|
done,
|
||||||
|
}: WarningModalProps) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={confirmLabel}
|
||||||
|
action={confirmLabel}
|
||||||
|
cancel={cancel}
|
||||||
|
done={done}
|
||||||
|
style={{
|
||||||
|
width: 420,
|
||||||
|
height: 300,
|
||||||
|
}}
|
||||||
|
primaryButtonProps={{ warning: true }}
|
||||||
|
>
|
||||||
|
{message}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Setting {
|
||||||
|
name: string;
|
||||||
|
label: string | JSX.Element;
|
||||||
|
options?: any;
|
||||||
|
hide?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingsList: Setting[] = [
|
||||||
|
{
|
||||||
|
name: 'errorReporting',
|
||||||
|
label: 'Anonymously report errors and usage statistics to balena.io',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unmountOnSuccess',
|
||||||
|
/**
|
||||||
|
* On Windows, "Unmounting" basically means "ejecting".
|
||||||
|
* On top of that, Windows users are usually not even
|
||||||
|
* familiar with the meaning of "unmount", which comes
|
||||||
|
* from the UNIX world.
|
||||||
|
*/
|
||||||
|
label: `${platform === 'win32' ? 'Eject' : 'Auto-unmount'} on success`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'validateWriteOnSuccess',
|
||||||
|
label: 'Validate write on success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'trim',
|
||||||
|
label: 'Trim ext{2,3,4} partitions before writing (raw images only)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatesEnabled',
|
||||||
|
label: 'Auto-updates enabled',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unsafeMode',
|
||||||
|
label: (
|
||||||
|
<span>
|
||||||
|
Unsafe mode{' '}
|
||||||
|
<Badge danger fontSize={12}>
|
||||||
|
Dangerous
|
||||||
|
</Badge>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
options: {
|
||||||
|
description: `Are you sure you want to turn this on?
|
||||||
|
You will be able to overwrite your system drives if you're not careful.`,
|
||||||
|
confirmLabel: 'Enable unsafe mode',
|
||||||
|
},
|
||||||
|
hide: settings.get('disableUnsafeMode'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
interface SettingsModalProps {
|
||||||
|
toggleModal: (value: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SettingsModal: any = styled(
|
||||||
|
({ toggleModal }: SettingsModalProps) => {
|
||||||
|
const [currentSettings, setCurrentSettings] = useState(settings.getAll());
|
||||||
|
const [warning, setWarning]: [
|
||||||
|
any,
|
||||||
|
React.Dispatch<React.SetStateAction<any>>,
|
||||||
|
] = useState({});
|
||||||
|
|
||||||
|
const toggleSetting = async (setting: string, options?: any) => {
|
||||||
|
const value = currentSettings[setting];
|
||||||
|
const dangerous = !_.isUndefined(options);
|
||||||
|
|
||||||
|
analytics.logEvent('Toggle setting', {
|
||||||
|
setting,
|
||||||
|
value,
|
||||||
|
dangerous,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (value || !dangerous) {
|
||||||
|
await settings.set(setting, !value);
|
||||||
|
setCurrentSettings({
|
||||||
|
...currentSettings,
|
||||||
|
[setting]: !value,
|
||||||
|
});
|
||||||
|
setWarning({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show warning since it's a dangerous setting
|
||||||
|
setWarning({
|
||||||
|
setting,
|
||||||
|
settingValue: value,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
id="settings-modal"
|
||||||
|
title="Settings"
|
||||||
|
done={() => toggleModal(false)}
|
||||||
|
style={{
|
||||||
|
width: 780,
|
||||||
|
height: 420,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{_.map(settingsList, (setting: Setting, i: number) => {
|
||||||
|
return setting.hide ? null : (
|
||||||
|
<div key={setting.name}>
|
||||||
|
<Checkbox
|
||||||
|
toggle
|
||||||
|
tabIndex={6 + i}
|
||||||
|
label={setting.label}
|
||||||
|
checked={currentSettings[setting.name]}
|
||||||
|
onChange={() => toggleSetting(setting.name, setting.options)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{_.isEmpty(warning) ? null : (
|
||||||
|
<WarningModal
|
||||||
|
message={warning.description}
|
||||||
|
confirmLabel={warning.confirmLabel}
|
||||||
|
done={() => {
|
||||||
|
settings.set(warning.setting, !warning.settingValue);
|
||||||
|
setCurrentSettings({
|
||||||
|
...currentSettings,
|
||||||
|
[warning.setting]: true,
|
||||||
|
});
|
||||||
|
setWarning({});
|
||||||
|
}}
|
||||||
|
cancel={() => {
|
||||||
|
setWarning({});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)`
|
||||||
|
> div:nth-child(3) {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
SettingsModal.propTypes = {
|
||||||
|
toggleModal: propTypes.func,
|
||||||
|
};
|
@ -11,6 +11,15 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="section-header" ng-controller="HeaderController as header">
|
<header class="section-header" ng-controller="HeaderController as header">
|
||||||
|
<span
|
||||||
|
id="app-logo"
|
||||||
|
os-open-external="https://www.balena.io/etcher?ref=etcher_footer"
|
||||||
|
tabindex="100">
|
||||||
|
<svg-icon paths="[ '../../assets/etcher.svg' ]"
|
||||||
|
width="'123px'"
|
||||||
|
height="'22px'"></svg-icon>
|
||||||
|
</span>
|
||||||
|
|
||||||
<settings tabindex="4">
|
<settings tabindex="4">
|
||||||
</settings>
|
</settings>
|
||||||
|
|
||||||
@ -24,34 +33,6 @@
|
|||||||
|
|
||||||
<main class="wrapper" ui-view></main>
|
<main class="wrapper" ui-view></main>
|
||||||
|
|
||||||
<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">
|
|
||||||
<svg-icon paths="[ '../../assets/etcher.svg' ]"
|
|
||||||
width="'123px'"
|
|
||||||
height="'22px'"></svg-icon>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="caption">
|
|
||||||
is <span class="caption"
|
|
||||||
tabindex="101"
|
|
||||||
os-open-external="https://github.com/balena-io/etcher">an open source project</span> by
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span os-open-external="https://www.balena.io?ref=etcher"
|
|
||||||
tabindex="102">
|
|
||||||
<svg-icon paths="[ '../../assets/balena.svg' ]"
|
|
||||||
width="'79px'"
|
|
||||||
height="'23px'"></svg-icon>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="caption footer-right"
|
|
||||||
tabindex="103"
|
|
||||||
manifest-bind="version"
|
|
||||||
os-open-external="https://github.com/balena-io/etcher/blob/master/CHANGELOG.md"></span>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<div class="section-loader"
|
<div class="section-loader"
|
||||||
ng-controller="StateController as state"
|
ng-controller="StateController as state"
|
||||||
ng-class="{
|
ng-class="{
|
||||||
|
@ -120,7 +120,7 @@ svg-icon > img[disabled] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page-main .button.step-footer {
|
.page-main .button.step-footer {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
color: $palette-theme-primary-background;
|
color: $palette-theme-primary-background;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -166,7 +166,7 @@ svg-icon > img[disabled] {
|
|||||||
.page-main .step-size {
|
.page-main .step-size {
|
||||||
color: $palette-theme-dark-disabled-foreground;
|
color: $palette-theme-dark-disabled-foreground;
|
||||||
margin: 0 0 8px 0;
|
margin: 0 0 8px 0;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
height: 21px;
|
height: 21px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -191,7 +191,7 @@ svg-icon > img[disabled] {
|
|||||||
.target-status-line {
|
.target-status-line {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
|
||||||
> .target-status-dot {
|
> .target-status-dot {
|
||||||
@ -226,3 +226,17 @@ svg-icon > img[disabled] {
|
|||||||
.space-vertical-large {
|
.space-vertical-large {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.rendition-modal-open > div:last-child > div > div > div:last-child {
|
||||||
|
top: unset;
|
||||||
|
bottom: -200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-logo {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 123px;
|
||||||
|
}
|
||||||
|
@ -6453,7 +6453,7 @@ svg-icon > img[disabled] {
|
|||||||
padding-bottom: 2px; }
|
padding-bottom: 2px; }
|
||||||
|
|
||||||
.page-main .button.step-footer {
|
.page-main .button.step-footer {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
color: #2297de;
|
color: #2297de;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -6490,7 +6490,7 @@ svg-icon > img[disabled] {
|
|||||||
.page-main .step-size {
|
.page-main .step-size {
|
||||||
color: #787c7f;
|
color: #787c7f;
|
||||||
margin: 0 0 8px 0;
|
margin: 0 0 8px 0;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
height: 21px;
|
height: 21px;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
@ -6512,7 +6512,7 @@ svg-icon > img[disabled] {
|
|||||||
.target-status-line {
|
.target-status-line {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
font-family: inherit; }
|
font-family: inherit; }
|
||||||
.target-status-line > .target-status-dot {
|
.target-status-line > .target-status-dot {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
@ -6536,6 +6536,18 @@ svg-icon > img[disabled] {
|
|||||||
.space-vertical-large {
|
.space-vertical-large {
|
||||||
position: relative; }
|
position: relative; }
|
||||||
|
|
||||||
|
body.rendition-modal-open > div:last-child > div > div > div:last-child {
|
||||||
|
top: unset;
|
||||||
|
bottom: -200px; }
|
||||||
|
|
||||||
|
#app-logo {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 123px; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 resin.io
|
* Copyright 2016 resin.io
|
||||||
*
|
*
|
||||||
|
49
npm-shrinkwrap.json
generated
49
npm-shrinkwrap.json
generated
@ -984,11 +984,40 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.3.tgz",
|
||||||
"integrity": "sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg=="
|
"integrity": "sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg=="
|
||||||
},
|
},
|
||||||
|
"@fortawesome/fontawesome-common-types": {
|
||||||
|
"version": "0.2.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.25.tgz",
|
||||||
|
"integrity": "sha512-3RuZPDuuPELd7RXtUqTCfed14fcny9UiPOkdr2i+cYxBoTOfQgxcDoq77fHiiHcgWuo1LoBUpvGxFF1H/y7s3Q=="
|
||||||
|
},
|
||||||
"@fortawesome/fontawesome-free-webfonts": {
|
"@fortawesome/fontawesome-free-webfonts": {
|
||||||
"version": "1.0.9",
|
"version": "1.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-webfonts/-/fontawesome-free-webfonts-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-webfonts/-/fontawesome-free-webfonts-1.0.9.tgz",
|
||||||
"integrity": "sha512-nLgl6b6a+tXaoJJnSRw0hjN8cWM/Q5DhxKAwI9Xr0AiC43lQ2F98vQ1KLA6kw5OoYeAyisGGqmlwtBj0WqOI5Q=="
|
"integrity": "sha512-nLgl6b6a+tXaoJJnSRw0hjN8cWM/Q5DhxKAwI9Xr0AiC43lQ2F98vQ1KLA6kw5OoYeAyisGGqmlwtBj0WqOI5Q=="
|
||||||
},
|
},
|
||||||
|
"@fortawesome/fontawesome-svg-core": {
|
||||||
|
"version": "1.2.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.25.tgz",
|
||||||
|
"integrity": "sha512-MotKnn53JKqbkLQiwcZSBJVYtTgIKFbh7B8+kd05TSnfKYPFmjKKI59o2fpz5t0Hzl35vVGU6+N4twoOpZUrqA==",
|
||||||
|
"requires": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "^0.2.25"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@fortawesome/free-solid-svg-icons": {
|
||||||
|
"version": "5.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.11.2.tgz",
|
||||||
|
"integrity": "sha512-zBue4i0PAZJUXOmLBBvM7L0O7wmsDC8dFv9IhpW5QL4kT9xhhVUsYg/LX1+5KaukWq4/cbDcKT+RT1aRe543sg==",
|
||||||
|
"requires": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "^0.2.25"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@fortawesome/react-fontawesome": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-AHWSzOsHBe5vqOkrvs+CKw+8eLl+0XZsVixOWhTPpGpOA8WQUbVU6J9cmtAvTaxUU5OIf+rgxxF8ZKc3BVldxg==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.5.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@mrmlnc/readdir-enhanced": {
|
"@mrmlnc/readdir-enhanced": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||||
@ -10627,11 +10656,6 @@
|
|||||||
"prop-types": "^15.5.0"
|
"prop-types": "^15.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-confirm-alert": {
|
|
||||||
"version": "2.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-confirm-alert/-/react-confirm-alert-2.4.1.tgz",
|
|
||||||
"integrity": "sha512-Sc2N1paCTCS5HWEAhik2IQa9/vwSQLAoCT5uccjPH/VyTaBAkRPZPx9sUqFTy3q5VnnGwCPsoz7fnw54x79d/w=="
|
|
||||||
},
|
|
||||||
"react-desc": {
|
"react-desc": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-desc/-/react-desc-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-desc/-/react-desc-4.1.2.tgz",
|
||||||
@ -10662,21 +10686,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-icon-base/-/react-icon-base-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-icon-base/-/react-icon-base-2.1.0.tgz",
|
||||||
"integrity": "sha1-oZbjP98eeqof2jrvu2i9rZ6Cp50="
|
"integrity": "sha1-oZbjP98eeqof2jrvu2i9rZ6Cp50="
|
||||||
},
|
},
|
||||||
"react-icons": {
|
|
||||||
"version": "3.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.7.0.tgz",
|
|
||||||
"integrity": "sha512-7MyPwjIhuyW0D2N3s4DEd0hGPGFf0sK+IIRKhc1FvSpZNVmnUoGvHbmAwzGJU+3my+fvihVWgwU5SDtlAri56Q==",
|
|
||||||
"requires": {
|
|
||||||
"camelcase": "^5.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"camelcase": {
|
|
||||||
"version": "5.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
|
||||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.8.1",
|
"version": "16.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.1.tgz",
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.11.2",
|
||||||
|
"@fortawesome/react-fontawesome": "^0.1.7",
|
||||||
"angular": "1.7.6",
|
"angular": "1.7.6",
|
||||||
"angular-if-state": "^1.0.0",
|
"angular-if-state": "^1.0.0",
|
||||||
"angular-moment": "^1.0.1",
|
"angular-moment": "^1.0.1",
|
||||||
@ -65,9 +68,7 @@
|
|||||||
"pretty-bytes": "^1.0.4",
|
"pretty-bytes": "^1.0.4",
|
||||||
"prop-types": "^15.5.9",
|
"prop-types": "^15.5.9",
|
||||||
"react": "^16.8.5",
|
"react": "^16.8.5",
|
||||||
"react-confirm-alert": "^2.4.1",
|
|
||||||
"react-dom": "^16.8.5",
|
"react-dom": "^16.8.5",
|
||||||
"react-icons": "^3.7.0",
|
|
||||||
"react2angular": "^4.0.2",
|
"react2angular": "^4.0.2",
|
||||||
"redux": "^3.5.2",
|
"redux": "^3.5.2",
|
||||||
"rendition": "^11.24.0",
|
"rendition": "^11.24.0",
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es2017",
|
"target": "es2017",
|
||||||
"jsx": "react"
|
"jsx": "react",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"lib/**/*.ts",
|
"lib/**/*.ts",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user