[Application configuration support] [Fix component unmount leak]
This commit is contained in:
36
src/components/ConfigurationItem/ConfigurationItem.css
Normal file
36
src/components/ConfigurationItem/ConfigurationItem.css
Normal file
@@ -0,0 +1,36 @@
|
||||
.ConfigurationItem {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input.Input {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
border-radius: var(--border_radius);
|
||||
background: rgba(160, 160, 160, 0.1);
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
color: var(--text_color);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.Select {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
border-radius: var(--border_radius);
|
||||
background: rgba(160, 160, 160, 0.1);
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
color: var(--text_color);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.Option {
|
||||
background: rgba(10, 10, 15, 0.8);
|
||||
border-color: rgba(10, 10, 20, 0.9);
|
||||
color: var(--text_color);
|
||||
}
|
||||
107
src/components/ConfigurationItem/ConfigurationItem.js
Normal file
107
src/components/ConfigurationItem/ConfigurationItem.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import React from 'react';
|
||||
import CSSModules from 'react-css-modules';
|
||||
import styles from './ConfigurationItem.css';
|
||||
|
||||
export default CSSModules((props) => {
|
||||
const handleChanged = (e) => {
|
||||
const target = e.target;
|
||||
if (target.type === 'checkbox') {
|
||||
target.value = e.target.checked ? "true" : "false";
|
||||
}
|
||||
props.changed(target);
|
||||
};
|
||||
|
||||
let data;
|
||||
switch (props.template.type) {
|
||||
case "bool":
|
||||
data = <input checked={JSON.parse(props.value)}
|
||||
onChange={e=>handleChanged(e)}
|
||||
type={'checkbox'}/>;
|
||||
break;
|
||||
|
||||
case "double":
|
||||
data = <input min={0.0}
|
||||
onChange={e=>handleChanged(e)}
|
||||
step={"0.01"}
|
||||
styleName='Input'
|
||||
type={'number'}
|
||||
value={parseFloat(props.value).toFixed(2)}/>;
|
||||
break;
|
||||
|
||||
case "list":
|
||||
const options = props.items.map((s, i) => {
|
||||
return (
|
||||
<option styleName='Option' key={i} value={s}>{s}</option>
|
||||
);
|
||||
});
|
||||
|
||||
data = (
|
||||
<select onChange={e=>handleChanged(e)}
|
||||
styleName='Select'
|
||||
value={props.value}>
|
||||
{options}
|
||||
</select>
|
||||
);
|
||||
break;
|
||||
|
||||
case "string":
|
||||
data = <input onChange={e=>handleChanged(e)}
|
||||
styleName='Input'
|
||||
type={'text'}
|
||||
value={props.value}/>;
|
||||
break;
|
||||
|
||||
case "uint8":
|
||||
data = <input max={255}
|
||||
min={0}
|
||||
onChange={e=>handleChanged(e)}
|
||||
styleName='Input'
|
||||
type={'number'}
|
||||
value={props.value}/>;
|
||||
break;
|
||||
|
||||
case "uint16":
|
||||
data = <input max={65535}
|
||||
min={0}
|
||||
onChange={e=>handleChanged(e)}
|
||||
styleName='Input'
|
||||
type={'number'}
|
||||
value={props.value}/>;
|
||||
break;
|
||||
|
||||
case "uint32":
|
||||
data = <input max={4294967295}
|
||||
min={0}
|
||||
onChange={e=>handleChanged(e)}
|
||||
styleName='Input'
|
||||
type={'number'}
|
||||
value={props.value}/>;
|
||||
break;
|
||||
|
||||
case "uint64":
|
||||
data = <input max={18446744073709551615}
|
||||
min={0}
|
||||
onChange={e=>handleChanged(e)}
|
||||
styleName='Input'
|
||||
type={'number'}
|
||||
value={props.value}/>;
|
||||
break;
|
||||
|
||||
default:
|
||||
data = <div>{props.value}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div styleName='ConfigurationItem'>
|
||||
<table cellPadding='2'
|
||||
width='100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width='100%'>{props.label}</td>
|
||||
<td>{data}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}, styles, {allowMultiple: true});
|
||||
@@ -8,15 +8,15 @@ export default CSSModules((props) => {
|
||||
const items = props.dependencies.map((k, i)=> {
|
||||
return (
|
||||
<Dependency allowDownload={props.allowDownload}
|
||||
download={k.download}
|
||||
key={i}
|
||||
name={k.display}
|
||||
download={k.download}
|
||||
onDownload={props.onDownload}/>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Box dxDark dxStyle={{width: '300px', height: 'auto', padding: '5px'}}>
|
||||
<Box dxStyle={{width: '300px', height: 'auto', padding: '5px'}}>
|
||||
<div style={{width: '100%', height: 'auto', paddingBottom: '5px', boxSizing: 'border-box'}}>
|
||||
<h1 style={{width: '100%', textAlign: 'center'}}>Missing Dependencies</h1>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import styles from './DownloadProgress.css';
|
||||
export default CSSModules((props) => {
|
||||
|
||||
return (
|
||||
<Box dxDark dxStyle={{width: '380px', height: 'auto', padding: '5px'}}>
|
||||
<Box dxStyle={{width: '380px', height: 'auto', padding: '5px'}}>
|
||||
<div style={{width: '100%', height: 'auto'}}>
|
||||
<h1 style={{width: '100%', textAlign: 'center'}}>{'Downloading ' + props.display}</h1>
|
||||
</div>
|
||||
|
||||
@@ -4,21 +4,34 @@ import styles from './MountItem.css';
|
||||
import DropDown from '../UI/DropDown/DropDown';
|
||||
import Button from '../UI/Button/Button';
|
||||
import Loader from 'react-loader-spinner';
|
||||
import configureImage from '../../assets/images/configure.png';
|
||||
|
||||
export default CSSModules((props) => {
|
||||
let configButton = null;
|
||||
if (props.allowConfig) {
|
||||
configButton = (
|
||||
<img alt=''
|
||||
height={'16px'}
|
||||
onClick={props.configClicked}
|
||||
src={configureImage}
|
||||
style={{padding: 0, border: 0, margin: 0, cursor: 'pointer'}}
|
||||
width={'16px'}/>
|
||||
);
|
||||
}
|
||||
|
||||
let inputControl = null;
|
||||
let mountWidth = '70%';
|
||||
if (props.platform === 'win32') {
|
||||
inputControl = <DropDown disabled={!props.allowMount || props.mounted}
|
||||
inputControl = <DropDown changed={props.changed}
|
||||
disabled={!props.allowMount || props.mounted}
|
||||
items={props.items}
|
||||
selected={props.items.indexOf(props.location)}
|
||||
changed={props.changed}/>;
|
||||
selected={props.items.indexOf(props.location)}/>;
|
||||
mountWidth = '18%';
|
||||
} else {
|
||||
inputControl = <input disabled={!props.allowMount || props.mounted}
|
||||
onChange={props.changed}
|
||||
type={'text'}
|
||||
value={props.location}
|
||||
onChange={props.changed}/>;
|
||||
value={props.location}/>;
|
||||
}
|
||||
|
||||
let actionDisplay = null;
|
||||
@@ -28,21 +41,29 @@ export default CSSModules((props) => {
|
||||
} else {
|
||||
actionDisplay = <Loader color={'var(--heading_text_color)'}
|
||||
height='24px'
|
||||
width='24px'
|
||||
type='Circles'/>;
|
||||
type='Circles'
|
||||
width='24px'/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div styleName='MountItem'>
|
||||
<h2>{props.title}</h2>
|
||||
<table width='100%' cellPadding='2'>
|
||||
<table><tbody><tr><td>{configButton}</td><td><h2>{props.title}</h2></td></tr></tbody></table>
|
||||
<table cellPadding='2'
|
||||
width='100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width={mountWidth} height='30px'>{inputControl}</td>
|
||||
<td width='25%' align='center' valign='middle'>
|
||||
<td height='30px'
|
||||
width={mountWidth}>{inputControl}
|
||||
</td>
|
||||
<td align='center'
|
||||
valign='middle'
|
||||
width='25%'>
|
||||
{actionDisplay}
|
||||
</td>
|
||||
<td>
|
||||
<input type='checkbox' checked={props.autoMount} onChange={props.autoMountChanged}/>Auto-mount
|
||||
<input checked={props.autoMount}
|
||||
onChange={props.autoMountChanged}
|
||||
type='checkbox'/>Auto-mount
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import CSSModules from 'react-css-modules';
|
||||
import styles from './DropDown.css';
|
||||
import CSSModules from 'react-css-modules';
|
||||
|
||||
export default CSSModules((props) => {
|
||||
const options = props.items.map((s, i) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.UpgradeIcon {
|
||||
display: block;
|
||||
margin: 0;
|
||||
margin-right: 2px;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
@@ -10,6 +10,10 @@ export default CSSModules((props) => {
|
||||
}
|
||||
|
||||
return props.available ?
|
||||
<img alt='' style={style} styleName='UpgradeIcon' src={availableImage} onClick={props.clicked}/> :
|
||||
<img alt=''
|
||||
onClick={props.clicked}
|
||||
src={availableImage}
|
||||
style={style}
|
||||
styleName='UpgradeIcon'/> :
|
||||
null;
|
||||
}, styles, {allowMultiple: true});
|
||||
@@ -6,22 +6,22 @@ import styles from './UpgradeUI.css';
|
||||
|
||||
export default CSSModules((props) => {
|
||||
return (
|
||||
<Box dxDark dxStyle={{width: '180px', height: 'auto', padding: '5px'}}>
|
||||
<Box dxStyle={{width: '180px', height: 'auto', padding: '5px'}}>
|
||||
<div style={{width: '100%', height: 'auto'}}>
|
||||
<h1 style={{width: '100%', textAlign: 'center'}}>UI Upgrade Available</h1>
|
||||
</div>
|
||||
<table cellSpacing={5} width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<Button buttonStyles={{width: '100%'}}
|
||||
clicked={props.upgrade}>Install</Button>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<Button buttonStyles={{width: '100%'}}
|
||||
clicked={props.cancel}>Cancel</Button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<Button buttonStyles={{width: '100%'}}
|
||||
clicked={props.upgrade}>Install</Button>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<Button buttonStyles={{width: '100%'}}
|
||||
clicked={props.cancel}>Cancel</Button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Box>);
|
||||
|
||||
Reference in New Issue
Block a user