Change the checkboxes to chips. Provide input field for extra modules

On considerations, the checkboxes were found to be limited as the
customization was limited by that interface. Now a "chip" styled
interface has been introduced alongside a text input field to add
custom packages.
An array separated by commas or newline can be feeded into the input
for bigger lists.

Signed-off-by: Sudhanshu Gautam <me@sudhanshug.com>
This commit is contained in:
Sudhanshu Gautam 2019-07-14 13:18:56 +05:30
parent 40f466153b
commit c05ac4dc2c
4 changed files with 106 additions and 78 deletions

View file

@ -2,7 +2,7 @@ import React from 'react';
import {
AppBar,
Button,
Checkbox,
Chip,
CircularProgress,
ClickAwayListener,
Container,
@ -12,9 +12,8 @@ import {
DialogContentText,
DialogTitle,
FormControl,
FormControlLabel,
FormGroup,
Grid,
Input,
InputAdornment,
List,
ListItem,
@ -23,6 +22,7 @@ import {
Tab,
Tabs,
TextField,
Tooltip,
Typography,
} from '@material-ui/core';
import {fade, makeStyles} from '@material-ui/core/styles';
@ -116,25 +116,6 @@ function AlertDialog({open, handleClose, text, title, t}) {
class Home extends React.Component {
deviceNames = [];
deviceNamesID = {};
state = {
showDeviceData: false,
device: {},
deviceLoaded: false,
devices: [],
devicesLoaded: false,
searchResults: [],
showSearch: false,
selectedSearchIndex: 0,
query: '',
downloading: false,
packages: {},
release_version_number: '',
};
fuzzySet;
basicInterface = 0;
confirmingBuild = false;
packages = [
'opkg',
'ip6tables',
@ -163,6 +144,26 @@ class Home extends React.Component {
'iptables',
'firewall',
'luci'];
deviceNames = [];
deviceNamesID = {};
state = {
showDeviceData: false,
device: {},
deviceLoaded: false,
devices: [],
devicesLoaded: false,
searchResults: [],
showSearch: false,
selectedSearchIndex: 0,
query: '',
downloading: false,
packages: this.packages,
release_version_number: '',
packageName: '',
};
fuzzySet;
basicInterface = 0;
confirmingBuild = false;
getDevicesData = () => fetch(
'https://chef.libremesh.org/download/json/devices.json')
@ -185,13 +186,6 @@ class Home extends React.Component {
release_version_number: data['version_number'],
});
});
let packages = {};
this.packages.forEach((package_name) => {
packages[package_name] = true;
});
this.setState({
packages,
});
}
selectDevice = (device_name) => {
@ -242,14 +236,6 @@ class Home extends React.Component {
this.basicInterface = val;
};
packageSettingChange = (event, package_name) => {
let packages = this.state.packages;
packages[package_name] = event.target.checked;
this.setState({
packages,
});
};
downloadingImageIndicatorShow = (i) => {
this.setState({
downloading: true,
@ -261,6 +247,37 @@ class Home extends React.Component {
}, 1000);
};
changeAddPackageInput = (event) => {
this.setState({
packageName: event.target.value,
});
};
deletePackage = (i) => {
let packages = this.state.packages;
packages.splice(i, 1);
this.setState({
packages,
});
};
addPackage = (event) => {
if ((event.which || event.keyCode) === 13 && !event.shiftKey) {
let packages = this.state.packages;
const packageArray = this.state.packageName.split(/[,\n]+/);
packageArray.forEach((package_name) => {
package_name = package_name.replace(' ', '');
if (package_name !== '') {
packages.push(package_name);
}
});
this.setState({
packages,
packageName: '',
});
}
};
closeConfirmBuildDialog = (v) => {
this.confirmingBuild = false;
console.log(v);
@ -419,34 +436,39 @@ class Home extends React.Component {
</TabContainer>
) : (
<TabContainer>
<FormGroup row>
{
this.packages.map((package_name, i) => {
return (
<FormControlLabel
className="package"
key={i}
control={
<Checkbox
onChange={(event) => this.packageSettingChange(
event, package_name)}
value={this.state.packages[package_name]}
checked={this.state.packages[package_name]}
/>
}
label={package_name}
/>
);
})
}
</FormGroup>
<br/>
<Button variant="outlined" color="primary"
onClick={this.openConfirmBuildDialog}>
<BuildIcon/>
&nbsp;
{this.props.t('Build')}
</Button>
<Paper elevation={0} className="package-list-input">
<div>
{
this.state.packages.map((package_name, i) => {
return (
<Chip className="package"
key={package_name + i}
onDelete={() => this.deletePackage(
i)}
label={package_name}
/>
);
})
}
<Tooltip
title={<span>Use comma or new line separated array. <br/>Press enter to apply.</span>}>
<Input
multiline
value={this.state.packageName}
onKeyUp={this.addPackage}
onChange={this.changeAddPackageInput}
placeholder={this.props.t('Add package(s)')}
/>
</Tooltip>
</div>
<br/>
<Button variant="outlined" color="primary"
onClick={this.openConfirmBuildDialog}>
<BuildIcon/>
&nbsp;
{this.props.t('Build')}
</Button>
</Paper>
</TabContainer>
)
}

View file

@ -53,9 +53,11 @@
background-color: #fff;
z-index: 9;
overflow: hidden;
.interface-switch {
color: #000;
}
.advanced-settings {
border: 1px solid #999;
background-color: #f0f0f0;
@ -73,22 +75,24 @@
padding-top: 30px;
background-color: #fff;
}
}
}
.package {
padding-right: 15px;
padding-left: 5px;
border-radius: 30px;
user-select: none;
}
.package-list-input {
.package {
margin: 5px 10px 5px 0px;
border-radius: 30px;
vertical-align: middle;
user-select: none;
}
.package:hover {
background-color: #f0f0f0;
}
.package:hover {
background-color: #f0f0f0;
}
.package:focus, .package:active {
transition: .2s;
background-color: darken(#f0f0f0, 15%);
}
.package:focus, .package:active {
transition: .2s;
background-color: darken(#f0f0f0, 15%);
}
}
}