Introduce interface to list packages in built image

A dropdown interface that lists all the installed packages for the
built images.

Fixes #7

Signed-off-by: Sudhanshu Gautam <me@sudhanshug.com>
This commit is contained in:
Sudhanshu Gautam 2019-09-02 02:23:20 +05:30
parent acdb7741e8
commit 3f46d13ccf
3 changed files with 127 additions and 63 deletions

View file

@ -37,7 +37,8 @@
padding: 15px 10%; padding: 15px 10%;
box-sizing: border-box; box-sizing: border-box;
text-align: left; text-align: left;
border-radius: 0 border-radius: 0;
z-index: 10;
} }
.report-link { .report-link {

View file

@ -21,10 +21,14 @@ import {
Tabs, Tabs,
Tooltip, Tooltip,
Typography, Typography,
ExpansionPanel,
ExpansionPanelSummary,
ExpansionPanelDetails
} from '@material-ui/core'; } from '@material-ui/core';
import CloudDownloadIcon from '@material-ui/icons/CloudDownload'; import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
import WarningIcon from '@material-ui/icons/Warning'; import WarningIcon from '@material-ui/icons/Warning';
import BuildIcon from '@material-ui/icons/Build'; import BuildIcon from '@material-ui/icons/Build';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import './home.scss'; import './home.scss';
import {withTranslation} from 'react-i18next'; import {withTranslation} from 'react-i18next';
import FuzzySet from 'fuzzyset.js'; import FuzzySet from 'fuzzyset.js';
@ -74,6 +78,7 @@ class Home extends React.Component {
packages: this.packages, packages: this.packages,
configChanged: true, configChanged: true,
packageName: '', packageName: '',
builtDeviceManifest: [],
builtImages: [], builtImages: [],
isBuilding: false, isBuilding: false,
queuePosition: -1, queuePosition: -1,
@ -280,6 +285,12 @@ class Home extends React.Component {
}; };
displayBuiltImageData = async (buildStatusResponse) => { displayBuiltImageData = async (buildStatusResponse) => {
const manifestResponse = await this.dataService.getDeviceManifest(
buildStatusResponse.data.image_folder + '/' + buildStatusResponse.data.image_prefix + '.manifest'
);
const builtDeviceManifest = manifestResponse.data.split('\n');
let builtImages = []; let builtImages = [];
buildStatusResponse.data.images.forEach((image) => { buildStatusResponse.data.images.forEach((image) => {
builtImages.push({ builtImages.push({
@ -290,6 +301,7 @@ class Home extends React.Component {
}); });
if (this.state.isBuilding) { if (this.state.isBuilding) {
this.setState({ this.setState({
builtDeviceManifest,
builtImages, builtImages,
configChanged: false, configChanged: false,
isBuilding: false, isBuilding: false,
@ -298,7 +310,6 @@ class Home extends React.Component {
}; };
buildImageCheck = async (request_hash) => { buildImageCheck = async (request_hash) => {
return new Promise(async (resolve, reject) => {
try { try {
if (!this.state.isBuilding) { if (!this.state.isBuilding) {
return; return;
@ -312,10 +323,8 @@ class Home extends React.Component {
} }
await sleep(buildStatusCheckInterval); await sleep(buildStatusCheckInterval);
await this.buildImageCheck(request_hash); await this.buildImageCheck(request_hash);
resolve();
} else if (buildStatusResponse.status === 200) { } else if (buildStatusResponse.status === 200) {
await this.displayBuiltImageData(buildStatusResponse); await this.displayBuiltImageData(buildStatusResponse);
resolve();
} else if (buildStatusResponse.status === 409) { } else if (buildStatusResponse.status === 409) {
this.setState({ this.setState({
openErrorDialog: true, openErrorDialog: true,
@ -326,14 +335,38 @@ class Home extends React.Component {
</> </>
), ),
}); });
resolve();
} else { } else {
throw buildStatusResponse.data; throw buildStatusResponse.data;
} }
} catch (e) { } catch (e) {
reject(e); if (e.response.status === 409) {
} this.setState({
isBuilding: false,
openErrorDialog: true,
errorDialogMessage: (
<>
{e.response.data.error} <br />
<a href={asu + e.response.data.log} target="_blank" rel="noopener noreferrer">Build logs</a>
</>
),
}); });
} else if (e.response.status === 422) {
this.setState({
isBuilding: false,
openErrorDialog: true,
errorDialogMessage: (
<>
{e.response.data.error}
</>
),
});
} else {
this.setState({
isBuilding: false,
showUnexpectedErrorBar: true,
});
}
}
}; };
buildImage = async () => { buildImage = async () => {
@ -348,7 +381,6 @@ class Home extends React.Component {
builtImages: [], builtImages: [],
}); });
let buildResponse = await this.dataService.buildImage(board, packages, target, version); let buildResponse = await this.dataService.buildImage(board, packages, target, version);
console.log(buildResponse);
if (buildResponse.status === 202 && buildResponse.data['request_hash'] !== undefined) { if (buildResponse.status === 202 && buildResponse.data['request_hash'] !== undefined) {
const request_hash = buildResponse.data['request_hash']; const request_hash = buildResponse.data['request_hash'];
await sleep(buildStatusCheckInterval); await sleep(buildStatusCheckInterval);
@ -638,15 +670,32 @@ class Home extends React.Component {
{this.props.t('Model')}: <b> {this.state.selection.device['title']} </b> <br /> {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('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}) {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>
<Grid item xs> <Grid item xs>
<b>{this.props.t('Downloads')}: </b> <b>{this.props.t('Downloads')}: </b>
{ {
this.state.builtImages.map((image) => ( this.state.builtImages.map((image) =>
<> <div key={image.url}>
<br />
<Button <Button
key={image.url}
className="download-button" className="download-button"
href={image.url} href={image.url}
color="primary" color="primary"
@ -657,8 +706,8 @@ class Home extends React.Component {
className="download-icon"/> className="download-icon"/>
{image.type} {image.type}
</Button> </Button>
</> </div>
)) )
} }
&nbsp; &nbsp;
{ {

View file

@ -23,6 +23,19 @@ $bg-color: #f0f0f0;
.device-info { .device-info {
margin-bottom: 15px; margin-bottom: 15px;
.installed-packages {
width: 80%;
border: 1px solid #e3e3e3;
border-radius: 7px;
margin-top: 16px !important;
}
.installed-packages::before {
display: none;
}
.installed-packages-title {
font-weight: bold;
}
} }
.version-select { .version-select {
@ -76,6 +89,7 @@ $bg-color: #f0f0f0;
margin-bottom: 15px; margin-bottom: 15px;
} }
.download-button { .download-button {
margin-top: 17px; margin-top: 17px;