Add functionality to edit UCI defaults

A new section in Advanced section is introduced that can be used to
build custom images with custom UCI defaults

Fixes #10

Signed-off-by: Sudhanshu Gautam <me@sudhanshug.com>
This commit is contained in:
Sudhanshu Gautam 2019-09-13 02:20:41 +05:30
parent db14840f4a
commit b835f928a4
4 changed files with 129 additions and 100 deletions

View file

@ -19,6 +19,7 @@ import {
Select, Select,
Tab, Tab,
Tabs, Tabs,
TextField,
Tooltip, Tooltip,
Typography, Typography,
ExpansionPanel, ExpansionPanel,
@ -91,6 +92,7 @@ class Home extends React.Component {
basicInterface: 0, basicInterface: 0,
errorDialogMessage: <></>, errorDialogMessage: <></>,
openErrorDialog: false, openErrorDialog: false,
uciDefaults: '',
}; };
confirmingBuild = false; confirmingBuild = false;
@ -303,6 +305,12 @@ class Home extends React.Component {
} }
}; };
uciDefaultsEdit = event => {
this.setState({
uciDefaults: event.target.value,
});
};
closeConfirmBuildDialog = () => { closeConfirmBuildDialog = () => {
this.confirmingBuild = false; this.confirmingBuild = false;
}; };
@ -408,12 +416,15 @@ class Home extends React.Component {
buildImage = async () => { buildImage = async () => {
try { try {
this.closeConfirmBuildDialog(); this.closeConfirmBuildDialog();
const board = this.state.selection.device.id; const { packages, selection, data, uciDefaults } = this.state;
const packages = this.state.packages; const {
const target = this.state.selection.device['target']; device: { id: board, target },
const version = this.state.data[ version: versionId,
this.state.selection.version } = selection;
].name.toLowerCase(); let {
[versionId]: { name: version },
} = data;
version = version.toLowerCase();
this.setState({ this.setState({
isBuilding: true, isBuilding: true,
builtImages: [], builtImages: [],
@ -422,7 +433,8 @@ class Home extends React.Component {
board, board,
packages, packages,
target, target,
version version,
uciDefaults
); );
if ( if (
buildResponse.status === 202 && buildResponse.status === 202 &&
@ -437,6 +449,7 @@ class Home extends React.Component {
throw buildResponse.data; throw buildResponse.data;
} }
} catch (e) { } catch (e) {
console.log(e);
if (e.response.status === 409) { if (e.response.status === 409) {
this.setState({ this.setState({
isBuilding: false, isBuilding: false,
@ -483,11 +496,15 @@ class Home extends React.Component {
}; };
render() { render() {
const warning432 = this.state.showDeviceData && let warning432 = <> </>;
if (
this.state.showDeviceData &&
this.state.deviceLoaded && this.state.deviceLoaded &&
parseInt( parseInt(
(this.state.selection.device['image_size'] || '').slice(0, -1) (this.state.selection.device['image_size'] || '').slice(0, -1)
) <= 4000 && ( ) <= 4000
) {
warning432 = (
<Paper className="warning-432" elevation={0}> <Paper className="warning-432" elevation={0}>
<Grid container direction="row" justify="center" alignItems="center"> <Grid container direction="row" justify="center" alignItems="center">
<Grid item> <Grid item>
@ -499,6 +516,63 @@ class Home extends React.Component {
</Grid> </Grid>
</Paper> </Paper>
); );
}
let deviceInfoGrid = <></>;
if (this.state.builtImages.length > 0 && !this.state.configChanged) {
deviceInfoGrid = (
<Grid container className="device-info">
<Grid item xs>
{this.props.t('Model')}:{' '}
<b> {this.state.selection.device['title']} </b> <br />
{this.props.t('Target')}: {this.state.selection.device['target']}{' '}
<br />
{this.props.t('Version')}: {'('}
{this.state.data[this.state.selection.version].name}
{this.state.data[this.state.selection.version].revision}
{')'}
<ExpansionPanel className="installed-packages" elevation={0}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="packages-manifest"
>
<Typography className="installed-packages-title">
Installed Packages ({this.state.builtDeviceManifest.length})
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<div>
{this.state.builtDeviceManifest.map(package_name => (
<div key={package_name}>{package_name}</div>
))}
</div>
</ExpansionPanelDetails>
</ExpansionPanel>
</Grid>
<Grid item xs>
<b>{this.props.t('Downloads')}: </b>
{this.state.builtImages.map(image => (
<div key={image.url}>
<Button
className="download-button"
href={image.url}
color="primary"
variant="contained"
onClick={() => this.downloadingImageIndicatorShow()}
>
<CloudDownloadIcon className="download-icon" />
{image.type}
</Button>
</div>
))}
&nbsp;
{this.state.downloading && <CircularProgress size={20} />}
</Grid>
</Grid>
);
}
const notLoaded = <CircularProgress />; const notLoaded = <CircularProgress />;
const onLoad = ( const onLoad = (
<> <>
@ -676,33 +750,48 @@ class Home extends React.Component {
) : ( ) : (
<TabContainer> <TabContainer>
<Paper elevation={0} className="package-list-input"> <Paper elevation={0} className="package-list-input">
<div> <Grid container>
{this.state.packages.map((package_name, i) => ( <Grid item xs={12} md={8}>
<Chip <h3>Packages</h3>
className="package" {this.state.packages.map((package_name, i) => (
key={package_name + i} <Chip
size="small" className="package"
onDelete={() => this.deletePackage(i)} key={package_name + i}
label={package_name} size="small"
/> onDelete={() => this.deletePackage(i)}
))} label={package_name}
<Tooltip />
title={ ))}
<span> <Tooltip
Use comma or new line separated array. <br /> title={
Press enter to apply. <span>
</span> Use comma or new line separated array. <br />
} Press enter to apply.
> </span>
<Input }
>
<Input
multiline
value={this.state.packageName}
onKeyUp={this.addPackage}
onChange={this.changeAddPackageInput}
placeholder={this.props.t('Add package(s)')}
/>
</Tooltip>
</Grid>
<Grid item xs={12} md={4}>
<h3>UCI defaults (alpha)</h3>
<TextField
style={{ width: '100%' }}
multiline multiline
value={this.state.packageName} variant="outlined"
onKeyUp={this.addPackage} rows={10}
onChange={this.changeAddPackageInput} value={this.state.uciDefaults}
placeholder={this.props.t('Add package(s)')} onChange={this.uciDefaultsEdit}
placeholder={this.props.t('Edit UCI defaults')}
/> />
</Tooltip> </Grid>
</div> </Grid>
<br /> <br />
{this.state.configChanged && !this.state.isBuilding && ( {this.state.configChanged && !this.state.isBuilding && (
<Button <Button
@ -744,70 +833,7 @@ class Home extends React.Component {
... ...
</> </>
)} )}
{this.state.builtImages.length > 0 && {deviceInfoGrid}
!this.state.configChanged && (
<Grid container className="device-info">
<Grid item xs>
{this.props.t('Model')}:{' '}
<b> {this.state.selection.device['title']} </b> <br />
{this.props.t('Target')}:{' '}
{this.state.selection.device['target']} <br />
{this.props.t('Version')}:{' '}
{this.state.data[this.state.selection.version].name} (
{
this.state.data[this.state.selection.version]
.revision
}
)
<ExpansionPanel
className="installed-packages"
elevation={0}
>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id="packages-manifest"
>
<Typography className="installed-packages-title">
Installed Packages (
{this.state.builtDeviceManifest.length})
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<div>
{this.state.builtDeviceManifest.map(
package_name => (
<div key={package_name}>{package_name}</div>
)
)}
</div>
</ExpansionPanelDetails>
</ExpansionPanel>
</Grid>
<Grid item xs>
<b>{this.props.t('Downloads')}: </b>
{this.state.builtImages.map(image => (
<div key={image.url}>
<Button
className="download-button"
href={image.url}
color="primary"
variant="contained"
onClick={() =>
this.downloadingImageIndicatorShow()
}
>
<CloudDownloadIcon className="download-icon" />
{image.type}
</Button>
</div>
))}
&nbsp;
{this.state.downloading && (
<CircularProgress size={20} />
)}
</Grid>
</Grid>
)}
</Paper> </Paper>
</TabContainer> </TabContainer>
)} )}
@ -815,6 +841,7 @@ class Home extends React.Component {
)} )}
</> </>
); );
return ( return (
<> <>
<ErrorSnackBar <ErrorSnackBar

View file

@ -15,6 +15,7 @@
"Build": "Bauen", "Build": "Bauen",
"Cancel": "Abbrechen", "Cancel": "Abbrechen",
"Add package(s)": "Paket (e) hinzufügen", "Add package(s)": "Paket (e) hinzufügen",
"Edit UCI defaults": "Bearbeiten Sie die UCI-Standardeinstellungen",
"Version": "Ausführung", "Version": "Ausführung",
"Please confirm that you want to perform this action": "Bitte bestätigen Sie, dass Sie diese Aktion ausführen möchten", "Please confirm that you want to perform this action": "Bitte bestätigen Sie, dass Sie diese Aktion ausführen möchten",
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Das Erstellen eines Image erfordert Rechenressourcen. Wir bitten Sie daher, zu prüfen, ob diese Auswahl Ihren Wünschen entspricht", "Building image requires computation resources, so we would request you to check if this selection is what you want": "Das Erstellen eines Image erfordert Rechenressourcen. Wir bitten Sie daher, zu prüfen, ob diese Auswahl Ihren Wünschen entspricht",

View file

@ -15,6 +15,7 @@
"Build": "Build", "Build": "Build",
"Cancel": "Cancel", "Cancel": "Cancel",
"Add package(s)": "Add package(s)", "Add package(s)": "Add package(s)",
"Edit UCI defaults": "Edit UCI defaults",
"Version": "Version", "Version": "Version",
"Please confirm that you want to perform this action": "Please confirm that you want to perform this action", "Please confirm that you want to perform this action": "Please confirm that you want to perform this action",
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Building image requires computation resources, so we would request you to check if this selection is what you want", "Building image requires computation resources, so we would request you to check if this selection is what you want": "Building image requires computation resources, so we would request you to check if this selection is what you want",

View file

@ -26,11 +26,11 @@ class DataService {
profile.toLowerCase() profile.toLowerCase()
); );
buildImage = (board, packages, target, version) => buildImage = (board, packages, target, version, uciDefaults) =>
axios.post(base_api + 'build-request', { axios.post(base_api + 'build-request', {
profile: board, profile: board,
board, board,
defaults: '', defaults: uciDefaults,
distro: 'openwrt', distro: 'openwrt',
packages, packages,
target, target,