mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-27 13:16:36 +00:00
Refactor settings page into modal
Change-type: patch Changelog-entry: Refactor settings page into modal Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
parent
1878b39e21
commit
4c0a079d1e
@ -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('./pages/settings/settings'),
|
require('./components/settings'),
|
||||||
|
|
||||||
// OS
|
// OS
|
||||||
require('./os/open-external/open-external'),
|
require('./os/open-external/open-external'),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 resin.io
|
* Copyright 2019 resin.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,14 +14,21 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.page-settings .checkbox input[type="checkbox"] + * {
|
'use strict'
|
||||||
color: $palette-theme-dark-foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-settings .checkbox input[type="checkbox"]:not(:checked) + * {
|
/**
|
||||||
color: $palette-theme-dark-soft-foreground;
|
* @module Etcher.Components.FeaturedProject
|
||||||
}
|
*/
|
||||||
|
|
||||||
.page-settings .title {
|
const angular = require('angular')
|
||||||
color: $palette-theme-dark-foreground;
|
const { react2angular } = require('react2angular')
|
||||||
}
|
|
||||||
|
const MODULE_NAME = 'Etcher.Components.Settings'
|
||||||
|
const Settings = angular.module(MODULE_NAME, [])
|
||||||
|
|
||||||
|
Settings.component(
|
||||||
|
'settings',
|
||||||
|
react2angular(require('./settings.jsx').SettingsButton)
|
||||||
|
)
|
||||||
|
|
||||||
|
module.exports = MODULE_NAME
|
233
lib/gui/app/components/settings/settings.jsx
Normal file
233
lib/gui/app/components/settings/settings.jsx
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* 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 }
|
@ -11,25 +11,14 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="section-header" ng-controller="HeaderController as header">
|
<header class="section-header" ng-controller="HeaderController as header">
|
||||||
|
<settings tabindex="4">
|
||||||
|
</settings>
|
||||||
|
|
||||||
<button class="button button-link"
|
<button class="button button-link"
|
||||||
ng-if="header.shouldShowHelp()"
|
ng-if="header.shouldShowHelp()"
|
||||||
ng-click="header.openHelpPage()"
|
ng-click="header.openHelpPage()"
|
||||||
tabindex="4">
|
|
||||||
<span class="glyphicon glyphicon-question-sign"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="button button-link"
|
|
||||||
ui-sref="settings"
|
|
||||||
hide-if-state="settings"
|
|
||||||
tabindex="5">
|
tabindex="5">
|
||||||
<span class="glyphicon glyphicon-cog"></span>
|
<span class="glyphicon glyphicon-question-sign"></span>
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="button button-link"
|
|
||||||
tabindex="5"
|
|
||||||
ui-sref="main"
|
|
||||||
show-if-state="settings">
|
|
||||||
<span class="glyphicon glyphicon-chevron-left"></span> Back
|
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -1,123 +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 os = require('os')
|
|
||||||
const _ = require('lodash')
|
|
||||||
const store = require('../../../models/store')
|
|
||||||
const settings = require('../../../models/settings')
|
|
||||||
const analytics = require('../../../modules/analytics')
|
|
||||||
const exceptionReporter = require('../../../modules/exception-reporter')
|
|
||||||
|
|
||||||
module.exports = function (WarningModalService) {
|
|
||||||
/**
|
|
||||||
* @summary Client platform
|
|
||||||
* @type {String}
|
|
||||||
* @constant
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
this.platform = os.platform()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Refresh current settings
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* SettingsController.refreshSettings();
|
|
||||||
*/
|
|
||||||
this.refreshSettings = () => {
|
|
||||||
this.currentData = settings.getAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Current settings value
|
|
||||||
* @type {Object}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
this.currentData = {}
|
|
||||||
this.refreshSettings()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Settings model
|
|
||||||
* @type {Object}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
this.model = settings
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Toggle setting
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @description
|
|
||||||
* If warningOptions is given, it should be an object having `description` and `confirmationLabel`;
|
|
||||||
* these will be used to present a user confirmation modal before enabling the setting.
|
|
||||||
* If warningOptions is missing, no confirmation modal is displayed.
|
|
||||||
*
|
|
||||||
* @param {String} setting - setting key
|
|
||||||
* @param {Object} [options] - options
|
|
||||||
* @param {String} [options.description] - warning modal description
|
|
||||||
* @param {String} [options.confirmationLabel] - warning modal confirmation label
|
|
||||||
* @returns {Undefined}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* SettingsController.toggle('unsafeMode', {
|
|
||||||
* description: 'Don\'t do this!',
|
|
||||||
* confirmationLabel: 'Do it!'
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
this.toggle = (setting, options) => {
|
|
||||||
const value = this.currentData[setting]
|
|
||||||
const dangerous = !_.isUndefined(options)
|
|
||||||
|
|
||||||
analytics.logEvent('Toggle setting', {
|
|
||||||
setting,
|
|
||||||
value,
|
|
||||||
dangerous,
|
|
||||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!value || !dangerous) {
|
|
||||||
return this.model.set(setting, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep the checkbox unchecked until the user confirms
|
|
||||||
this.currentData[setting] = false
|
|
||||||
|
|
||||||
return WarningModalService.display(options).then((userAccepted) => {
|
|
||||||
if (userAccepted) {
|
|
||||||
this.model.set(setting, true)
|
|
||||||
this.refreshSettings()
|
|
||||||
}
|
|
||||||
}).catch(exceptionReporter.report)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Show unsafe mode based on an env var
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* SettingsController.shouldShowUnsafeMode()
|
|
||||||
*/
|
|
||||||
this.shouldShowUnsafeMode = () => {
|
|
||||||
return !settings.get('disableUnsafeMode')
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +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'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @module Etcher.Pages.Settings
|
|
||||||
*/
|
|
||||||
|
|
||||||
const angular = require('angular')
|
|
||||||
const MODULE_NAME = 'Etcher.Pages.Settings'
|
|
||||||
const SettingsPage = angular.module(MODULE_NAME, [
|
|
||||||
require('angular-ui-router'),
|
|
||||||
require('../../components/warning-modal/warning-modal')
|
|
||||||
])
|
|
||||||
|
|
||||||
SettingsPage.controller('SettingsController', require('./controllers/settings'))
|
|
||||||
|
|
||||||
SettingsPage.config(($stateProvider) => {
|
|
||||||
$stateProvider
|
|
||||||
.state('settings', {
|
|
||||||
url: '/settings',
|
|
||||||
controller: 'SettingsController as settings',
|
|
||||||
template: require('./templates/settings.tpl.html')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = MODULE_NAME
|
|
@ -1,80 +0,0 @@
|
|||||||
<div class="page-settings text-left">
|
|
||||||
<h1 class="title space-bottom-large">Settings</h1>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="6"
|
|
||||||
ng-model="settings.currentData.errorReporting"
|
|
||||||
ng-change="settings.toggle('errorReporting')">
|
|
||||||
|
|
||||||
<span>Anonymously report errors and usage statistics to balena.io</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="7"
|
|
||||||
ng-model="settings.currentData.unmountOnSuccess"
|
|
||||||
ng-change="settings.toggle('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. -->
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<span ng-show="settings.platform == 'win32'">Eject</span>
|
|
||||||
<span ng-hide="settings.platform == 'win32'">Auto-unmount</span>
|
|
||||||
on success
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="8"
|
|
||||||
ng-model="settings.currentData.validateWriteOnSuccess"
|
|
||||||
ng-change="settings.toggle('validateWriteOnSuccess')">
|
|
||||||
|
|
||||||
<span>Validate write on success</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="8"
|
|
||||||
ng-model="settings.currentData.trim"
|
|
||||||
ng-change="settings.toggle('trim')">
|
|
||||||
|
|
||||||
<span>Trim ext{2,3,4} partitions before writing (raw images only)</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="9"
|
|
||||||
ng-model="settings.currentData.updatesEnabled"
|
|
||||||
ng-change="settings.toggle('updatesEnabled')">
|
|
||||||
|
|
||||||
<span>Auto-updates enabled</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox" ng-if="settings.shouldShowUnsafeMode()">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
tabindex="10"
|
|
||||||
ng-model="settings.currentData.unsafeMode"
|
|
||||||
ng-change="settings.toggle('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.',
|
|
||||||
confirmationLabel: 'Enable unsafe mode'
|
|
||||||
})">
|
|
||||||
<span>Unsafe mode <span class="label label-danger">Dangerous</span></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -29,8 +29,9 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
> .glyphicon {
|
> .glyphicon {
|
||||||
top: 2px;
|
top: 0;
|
||||||
margin-right: 2px;
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.button-primary{
|
&.button-primary{
|
||||||
|
@ -38,7 +38,6 @@ $disabled-opacity: 0.2;
|
|||||||
@import "../components/warning-modal/styles/warning-modal";
|
@import "../components/warning-modal/styles/warning-modal";
|
||||||
@import "../components/file-selector/styles/file-selector";
|
@import "../components/file-selector/styles/file-selector";
|
||||||
@import "../pages/main/styles/main";
|
@import "../pages/main/styles/main";
|
||||||
@import "../pages/settings/styles/settings";
|
|
||||||
@import "../pages/finish/styles/finish";
|
@import "../pages/finish/styles/finish";
|
||||||
|
|
||||||
$fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/webfonts";
|
$fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/webfonts";
|
||||||
@ -212,11 +211,21 @@ body {
|
|||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 5px 8px;
|
padding: 13px 14px;
|
||||||
|
|
||||||
> .button {
|
> .button {
|
||||||
padding-left: 3px;
|
padding: 0;
|
||||||
padding-right: 3px;
|
|
||||||
|
> .glyphicon {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 24px;
|
||||||
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@ exports.colors = {
|
|||||||
foreground: '#fff',
|
foreground: '#fff',
|
||||||
background: '#2297de'
|
background: '#2297de'
|
||||||
},
|
},
|
||||||
|
secondary: {
|
||||||
|
foreground: '#000',
|
||||||
|
background: '#ddd'
|
||||||
|
},
|
||||||
warning: {
|
warning: {
|
||||||
foreground: '#fff',
|
foreground: '#fff',
|
||||||
background: '#fca321'
|
background: '#fca321'
|
||||||
|
@ -6035,8 +6035,9 @@ body {
|
|||||||
outline: none;
|
outline: none;
|
||||||
position: relative; }
|
position: relative; }
|
||||||
.button > .glyphicon, .button > .tick {
|
.button > .glyphicon, .button > .tick {
|
||||||
top: 2px;
|
top: 0;
|
||||||
margin-right: 2px; }
|
width: 24px;
|
||||||
|
height: 24px; }
|
||||||
.button.button-primary {
|
.button.button-primary {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 48px; }
|
height: 48px; }
|
||||||
@ -6535,30 +6536,6 @@ svg-icon > img[disabled] {
|
|||||||
.space-vertical-large {
|
.space-vertical-large {
|
||||||
position: relative; }
|
position: relative; }
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
.page-settings .checkbox input[type="checkbox"] + * {
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
.page-settings .checkbox input[type="checkbox"]:not(:checked) + * {
|
|
||||||
color: #ddd; }
|
|
||||||
|
|
||||||
.page-settings .title {
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 resin.io
|
* Copyright 2016 resin.io
|
||||||
*
|
*
|
||||||
@ -9973,10 +9950,16 @@ body {
|
|||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 5px 8px; }
|
padding: 13px 14px; }
|
||||||
.section-header > .button {
|
.section-header > .button {
|
||||||
padding-left: 3px;
|
padding: 0; }
|
||||||
padding-right: 3px; }
|
.section-header > .button > .glyphicon, .section-header > .button > .tick {
|
||||||
|
font-size: 24px; }
|
||||||
|
.section-header > * {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 24px;
|
||||||
|
margin: 0 10px; }
|
||||||
|
|
||||||
featured-project webview {
|
featured-project webview {
|
||||||
flex: 0 1;
|
flex: 0 1;
|
||||||
|
642
npm-shrinkwrap.json
generated
642
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
@ -65,10 +65,12 @@
|
|||||||
"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": "^8.7.2",
|
"rendition": "^11.24.0",
|
||||||
"request": "^2.81.0",
|
"request": "^2.81.0",
|
||||||
"resin-corvus": "^2.0.3",
|
"resin-corvus": "^2.0.3",
|
||||||
"roboto-fontface": "^0.9.0",
|
"roboto-fontface": "^0.9.0",
|
||||||
|
@ -25,6 +25,9 @@ angularValidate.validate(
|
|||||||
path.join(PROJECT_ROOT, 'lib', 'gui', '**/*.html')
|
path.join(PROJECT_ROOT, 'lib', 'gui', '**/*.html')
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
|
customtags: [
|
||||||
|
'settings'
|
||||||
|
],
|
||||||
customattrs: [
|
customattrs: [
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 m = require('mochainon')
|
|
||||||
const fs = require('fs')
|
|
||||||
const angular = require('angular')
|
|
||||||
require('angular-mocks')
|
|
||||||
|
|
||||||
describe('Browser: SettingsPage', function () {
|
|
||||||
beforeEach(angular.mock.module(
|
|
||||||
require('../../../lib/gui/app/pages/settings/settings')
|
|
||||||
))
|
|
||||||
|
|
||||||
describe('page template', function () {
|
|
||||||
let $state
|
|
||||||
|
|
||||||
beforeEach(angular.mock.inject(function (_$state_) {
|
|
||||||
$state = _$state_
|
|
||||||
}))
|
|
||||||
|
|
||||||
it('should match the file contents', function () {
|
|
||||||
const {
|
|
||||||
template
|
|
||||||
} = $state.get('settings')
|
|
||||||
const contents = fs.readFileSync('lib/gui/app/pages/settings/templates/settings.tpl.html', {
|
|
||||||
encoding: 'utf-8'
|
|
||||||
})
|
|
||||||
m.chai.expect(template).to.equal(contents)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
Loading…
x
Reference in New Issue
Block a user