Fix code issues in App Upload form in APPM UI

feature/appm-store/pbac
Jayasanka 5 years ago
parent 13bdeee883
commit b4d76b893d

@ -15,11 +15,15 @@
"acorn": "^6.2.0", "acorn": "^6.2.0",
"antd": "^3.23.6", "antd": "^3.23.6",
"axios": "^0.19.0", "axios": "^0.19.0",
"babel-eslint": "^9.0.0",
"d3": "^5.9.7", "d3": "^5.9.7",
"dagre": "^0.8.4", "dagre": "^0.8.4",
"eslint": "^5.16.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.16.0",
"fetch": "^1.1.0", "fetch": "^1.1.0",
"gapi": "0.0.3", "imagemin": "^6.1.0",
"gapi-client": "0.0.3",
"keymirror": "^0.1.1", "keymirror": "^0.1.1",
"rc-tween-one": "^2.4.1", "rc-tween-one": "^2.4.1",
"react-d3-graph": "^2.1.0", "react-d3-graph": "^2.1.0",
@ -34,7 +38,8 @@
"react-star-ratings": "^2.3.0", "react-star-ratings": "^2.3.0",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"shade-blend-color": "^1.0.0", "shade-blend-color": "^1.0.0",
"storm-react-diagrams": "^5.2.1" "storm-react-diagrams": "^5.2.1",
"typescript": "^3.6.4"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.5.0", "@babel/core": "^7.5.0",

@ -34,6 +34,7 @@ import {
Select Select
} from 'antd'; } from 'antd';
import axios from "axios"; import axios from "axios";
import "@babel/polyfill";
import {withConfigContext} from "../../../../context/ConfigContext"; import {withConfigContext} from "../../../../context/ConfigContext";
const {TextArea} = Input; const {TextArea} = Input;

@ -17,37 +17,24 @@
*/ */
import React from "react"; import React from "react";
import { import {Button, Col, Form, Icon, Input, Row, Select, Switch, Upload, InputNumber, Modal} from "antd";
Modal, import "@babel/polyfill";
Button,
Icon,
notification,
Spin,
Tooltip,
Upload,
Input,
Switch,
Form,
Divider,
Row,
Col,
Select
} from 'antd';
import axios from "axios"; import axios from "axios";
import {withConfigContext} from "../../../context/ConfigContext"; import {handleApiError} from "../../../js/Utils";
const {TextArea} = Input;
const InputGroup = Input.Group;
const {Option} = Select;
const formItemLayout = { const formItemLayout = {
labelCol: { labelCol: {
span: 8, xs: {span: 24},
sm: {span: 8},
}, },
wrapperCol: { wrapperCol: {
span: 16, xs: {span: 24},
sm: {span: 16},
}, },
}; };
const {Option} = Select;
const {TextArea} = Input;
const InputGroup = Input.Group;
function getBase64(file) { function getBase64(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -58,168 +45,30 @@ function getBase64(file) {
}); });
} }
class EditReleaseModal extends React.Component { class NewAppUploadForm extends React.Component {
// To add subscription type & tenancy sharing, refer https://gitlab.com/entgra/carbon-device-mgt/merge_requests/331
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
visible: false,
current: 0,
categories: [],
tags: [],
icons: [], icons: [],
screenshots: [], screenshots: [],
loading: false, loading: false,
binaryFiles: [], binaryFiles: [],
metaData: [], application: null,
formConfig: { isFree: true,
specificElements: {} previewVisible: false,
} previewImage: '',
binaryFileHelperText: '',
iconHelperText: '',
screenshotHelperText: '',
osVersionsHelperText: '',
osVersionsValidateStatus: 'validating',
metaData: []
}; };
this.lowerOsVersion = null; this.lowerOsVersion = null;
this.upperOsVersion = null; this.upperOsVersion = null;
} }
componentDidMount = () => {
this.generateConfig();
};
generateConfig = () => {
const {type} = this.props;
const formConfig = {
type
};
switch (type) {
case "ENTERPRISE":
formConfig.endpoint = "/ent-app-release";
formConfig.specificElements = {
binaryFile: {
required: true
}
};
break;
case "PUBLIC":
formConfig.endpoint = "/public-app-release";
formConfig.specificElements = {
packageName: {
required: true
},
version: {
required: true
}
};
break;
case "WEB_CLIP":
formConfig.endpoint = "/web-app-release";
formConfig.specificElements = {
version: {
required: true
},
url: {
required: true
}
};
break;
case "CUSTOM":
formConfig.endpoint = "/custom-app-release";
formConfig.specificElements = {
binaryFile: {
required: true
},
packageName: {
required: true
},
version: {
required: true
}
};
break;
}
this.setState({
formConfig
});
};
showModal = () => {
const config = this.props.context;
const {app, release} = this.props;
const {formConfig} = this.state;
const {specificElements} = formConfig;
let metaData = [];
try {
metaData = JSON.parse(release.metaData);
} catch (e) {
}
this.props.form.setFields({
releaseType: {
value: release.releaseType
},
releaseDescription: {
value: release.description
}
});
if ((config.deviceTypes.mobileTypes.includes(this.props.deviceType))) {
const osVersions = release.supportedOsVersions.split("-");
this.lowerOsVersion = osVersions[0];
this.upperOsVersion = osVersions[1];
this.props.form.setFields({
lowerOsVersion: {
value: osVersions[0]
},
upperOsVersion: {
value: osVersions[1]
}
});
}
if (specificElements.hasOwnProperty("version")) {
this.props.form.setFields({
version: {
value: release.version
}
});
}
if (specificElements.hasOwnProperty("url")) {
this.props.form.setFields({
url: {
value: release.url
}
});
}
if (specificElements.hasOwnProperty("packageName")) {
this.props.form.setFields({
packageName: {
value: release.packageName
}
});
}
this.setState({
visible: true,
metaData
});
};
handleOk = e => {
this.setState({
visible: false,
});
};
handleCancel = e => {
this.setState({
visible: false,
});
};
normFile = e => { normFile = e => {
if (Array.isArray(e)) { if (Array.isArray(e)) {
return e; return e;
@ -227,18 +76,9 @@ class EditReleaseModal extends React.Component {
return e && e.fileList; return e && e.fileList;
}; };
handleIconChange = ({fileList}) => this.setState({icons: fileList});
handleBinaryFileChange = ({fileList}) => this.setState({binaryFiles: fileList});
handleScreenshotChange = ({fileList}) => this.setState({screenshots: fileList});
handleSubmit = e => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
const {uuid} = this.props.release; const {formConfig} = this.props;
const config = this.props.context;
const {formConfig} = this.state;
const {specificElements} = formConfig; const {specificElements} = formConfig;
this.props.form.validateFields((err, values) => { this.props.form.validateFields((err, values) => {
@ -246,11 +86,7 @@ class EditReleaseModal extends React.Component {
this.setState({ this.setState({
loading: true loading: true
}); });
const {releaseDescription, releaseType} = values; const {price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values;
const {icons, screenshots, binaryFiles} = this.state;
const data = new FormData();
//add release data //add release data
const release = { const release = {
@ -258,98 +94,115 @@ class EditReleaseModal extends React.Component {
price: 0, price: 0,
isSharedWithAllTenants: false, isSharedWithAllTenants: false,
metaData: JSON.stringify(this.state.metaData), metaData: JSON.stringify(this.state.metaData),
releaseType: releaseType, releaseType: releaseType
}; };
if ((config.deviceTypes.mobileTypes.includes(this.props.deviceType))) {
release.supportedOsVersions = `${this.lowerOsVersion}-${this.upperOsVersion}`;
}
if (specificElements.hasOwnProperty("binaryFile") && binaryFiles.length === 1) {
data.append('binaryFile', binaryFiles[0].originFileObj);
}
if (specificElements.hasOwnProperty("version")) { if (specificElements.hasOwnProperty("version")) {
release.version = values.version; release.version = values.version;
} }
if (specificElements.hasOwnProperty("url")) { if (specificElements.hasOwnProperty("url")) {
release.url = values.url; release.url = values.url;
} }
if (specificElements.hasOwnProperty("packageName")) {
if (icons.length === 1) { release.packageName = values.packageName;
data.append('icon', icons[0].originFileObj);
} }
if (screenshots.length > 0) { const data = new FormData();
data.append('screenshot1', screenshots[0].originFileObj); let isFormValid = true; // flag to check if this form is valid
}
if (screenshots.length > 1) { if (formConfig.installationType !== "WEB_CLIP" && formConfig.installationType !== "CUSTOM") {
data.append('screenshot2', screenshots[1].originFileObj); if (this.lowerOsVersion == null || this.upperOsVersion == null) {
isFormValid = false;
this.setState({
osVersionsHelperText: 'Please select supported OS versions',
osVersionsValidateStatus: 'error',
});
} else if (this.lowerOsVersion >= this.upperOsVersion) {
isFormValid = false;
this.setState({
osVersionsHelperText: 'Please select valid range',
osVersionsValidateStatus: 'error',
});
} else {
release.supportedOsVersions = `${this.lowerOsVersion}-${this.upperOsVersion}`;
} }
if (screenshots.length > 2) {
data.append('screenshot3', screenshots[2].originFileObj);
} }
const json = JSON.stringify(release); if (specificElements.hasOwnProperty("binaryFile") && this.state.binaryFiles.length !== 1) {
const blob = new Blob([json], { isFormValid = false;
type: 'application/json' this.setState({
binaryFileHelperText: 'Please select the application'
}); });
}
data.append("applicationRelease", blob); if (this.state.icons.length !== 1) {
isFormValid = false;
const url = window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications" + formConfig.endpoint + "/" + uuid;
axios.put(
url,
data
).then(res => {
if (res.status === 200) {
const updatedRelease = res.data.data;
this.setState({ this.setState({
loading: false, iconHelperText: 'Please select an icon'
visible: false,
}); });
}
notification["success"]({ if (this.state.screenshots.length !== 3) {
message: "Done!", isFormValid = false;
description: this.setState({
"Saved!", screenshotHelperText: 'Please select 3 screenshots'
}); });
// console.log(updatedRelease);
this.props.updateRelease(updatedRelease);
} }
}).catch((error) => { if (this.state.screenshots.length !== 3) {
if (error.hasOwnProperty("response") && error.response.status === 401) { isFormValid = false;
window.location.href = window.location.origin + '/publisher/login'; this.setState({
} else { screenshotHelperText: 'Please select 3 screenshots'
notification["error"]({ });
message: "Something went wrong!", }
description: if (isFormValid) {
"Sorry, we were unable to complete your request.", data.append('icon', icon[0].originFileObj);
data.append('screenshot1', screenshots[0].originFileObj);
data.append('screenshot2', screenshots[1].originFileObj);
data.append('screenshot3', screenshots[2].originFileObj);
if (specificElements.hasOwnProperty("binaryFile")) {
data.append('binaryFile', binaryFile[0].originFileObj);
}
this.props.onSuccessReleaseData({data, release});
}
}
}); });
};
handleIconChange = ({fileList}) => {
if (fileList.length === 1) {
this.setState({
iconHelperText: ''
});
} }
this.setState({ this.setState({
loading: false icons: fileList
});
};
handleBinaryFileChange = ({fileList}) => {
if (fileList.length === 1) {
this.setState({
binaryFileHelperText: ''
}); });
}
this.setState({binaryFiles: fileList});
};
handleScreenshotChange = ({fileList}) => {
if (fileList.length === 3) {
this.setState({
screenshotHelperText: ''
}); });
} }
this.setState({
screenshots: fileList
}); });
}; };
addNewMetaData = () => { handlePriceTypeChange = (value) => {
this.setState({ this.setState({
metaData: this.state.metaData.concat({'key': '', 'value': ''}) isFree: (value === 'free')
}) });
}; };
handlePreviewCancel = () => this.setState({previewVisible: false}); handlePreviewCancel = () => this.setState({previewVisible: false});
handlePreview = async file => { handlePreview = async file => {
if (!file.url && !file.preview) { if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj); file.preview = await getBase64(file.originFileObj);
@ -361,31 +214,45 @@ class EditReleaseModal extends React.Component {
}); });
}; };
addNewMetaData = () => {
this.setState({
metaData: this.state.metaData.concat({'key': '', 'value': ''})
})
};
handleLowerOsVersionChange = (lowerOsVersion) => { handleLowerOsVersionChange = (lowerOsVersion) => {
this.lowerOsVersion = lowerOsVersion; this.lowerOsVersion = parseFloat(lowerOsVersion);
this.setState({
osVersionsValidateStatus: 'validating',
osVersionsHelperText: ''
});
}; };
handleUpperOsVersionChange = (upperOsVersion) => { handleUpperOsVersionChange = (upperOsVersion) => {
this.upperOsVersion = upperOsVersion; this.upperOsVersion = parseFloat(upperOsVersion);
this.setState({
osVersionsValidateStatus: 'validating',
osVersionsHelperText: ''
});
}; };
render() { render() {
const {formConfig, supportedOsVersions} = this.props;
const {getFieldDecorator} = this.props.form;
const { const {
formConfig,
icons, icons,
screenshots, screenshots,
loading,
binaryFiles, binaryFiles,
metaData, isFree,
previewImage, previewImage,
previewVisible, previewVisible,
binaryFileHelperText, binaryFileHelperText,
iconHelperText, iconHelperText,
screenshotHelperText screenshotHelperText,
metaData,
osVersionsHelperText,
osVersionsValidateStatus
} = this.state; } = this.state;
const {getFieldDecorator} = this.props.form;
const {isAppUpdatable, supportedOsVersions, deviceType} = this.props;
const config = this.props.context;
const uploadButton = ( const uploadButton = (
<div> <div>
<Icon type="plus"/> <Icon type="plus"/>
@ -395,26 +262,20 @@ class EditReleaseModal extends React.Component {
return ( return (
<div> <div>
<Tooltip title={isAppUpdatable ? "Edit this release" : "This release isn't in an editable state"}> <Row>
<Button <Col md={5}>
disabled={!isAppUpdatable}
size="small" type="primary" onClick={this.showModal}> </Col>
<Icon type="edit"/> Edit <Col md={14}>
</Button> <Form
</Tooltip> labelAlign="right"
<Modal layout="horizontal"
title="Edit release"
visible={this.state.visible}
footer={null}
width={580}
onCancel={this.handleCancel}>
<div>
<Spin tip="Uploading..." spinning={loading}>
<Form labelAlign="left" layout="horizontal"
hideRequiredMark
onSubmit={this.handleSubmit}> onSubmit={this.handleSubmit}>
{formConfig.specificElements.hasOwnProperty("binaryFile") && ( {formConfig.specificElements.hasOwnProperty("binaryFile") && (
<Form.Item {...formItemLayout} label="Application"> <Form.Item {...formItemLayout}
label="Application"
validateStatus="error"
help={binaryFileHelperText}>
{getFieldDecorator('binaryFile', { {getFieldDecorator('binaryFile', {
valuePropName: 'binaryFile', valuePropName: 'binaryFile',
getValueFromEvent: this.normFile, getValueFromEvent: this.normFile,
@ -424,11 +285,10 @@ class EditReleaseModal extends React.Component {
<Upload <Upload
name="binaryFile" name="binaryFile"
onChange={this.handleBinaryFileChange} onChange={this.handleBinaryFileChange}
beforeUpload={() => false} beforeUpload={() => false}>
>
{binaryFiles.length !== 1 && ( {binaryFiles.length !== 1 && (
<Button> <Button>
<Icon type="upload"/> Change <Icon type="upload"/> Click to upload
</Button> </Button>
)} )}
</Upload>, </Upload>,
@ -436,33 +296,10 @@ class EditReleaseModal extends React.Component {
</Form.Item> </Form.Item>
)} )}
{formConfig.specificElements.hasOwnProperty("url") && ( <Form.Item {...formItemLayout}
<Form.Item {...formItemLayout} label="URL"> label="Icon"
{getFieldDecorator('url', { validateStatus="error"
rules: [{ help={iconHelperText}>
required: true,
message: 'Please input the url'
}],
})(
<Input placeholder="url"/>
)}
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty("version") && (
<Form.Item {...formItemLayout} label="Version">
{getFieldDecorator('version', {
rules: [{
required: true,
message: 'Please input the version'
}],
})(
<Input placeholder="Version"/>
)}
</Form.Item>
)}
<Form.Item {...formItemLayout} label="Icon">
{getFieldDecorator('icon', { {getFieldDecorator('icon', {
valuePropName: 'icon', valuePropName: 'icon',
getValueFromEvent: this.normFile, getValueFromEvent: this.normFile,
@ -480,7 +317,10 @@ class EditReleaseModal extends React.Component {
)} )}
</Form.Item> </Form.Item>
<Form.Item {...formItemLayout} label="Screenshots"> <Form.Item {...formItemLayout}
label="Screenshots"
validateStatus="error"
help={screenshotHelperText}>
{getFieldDecorator('screenshots', { {getFieldDecorator('screenshots', {
valuePropName: 'icon', valuePropName: 'icon',
getValueFromEvent: this.normFile, getValueFromEvent: this.normFile,
@ -498,6 +338,45 @@ class EditReleaseModal extends React.Component {
)} )}
</Form.Item> </Form.Item>
{formConfig.specificElements.hasOwnProperty("packageName") && (
<Form.Item {...formItemLayout} label="Package Name">
{getFieldDecorator('packageName', {
rules: [{
required: true,
message: 'Please input the package name'
}],
})(
<Input placeholder="Package Name"/>
)}
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty("url") && (
<Form.Item {...formItemLayout} label="URL">
{getFieldDecorator('url', {
rules: [{
required: true,
message: 'Please input the url'
}],
})(
<Input placeholder="url"/>
)}
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty("version") && (
<Form.Item {...formItemLayout} label="Version">
{getFieldDecorator('version', {
rules: [{
required: true,
message: 'Please input the version'
}],
})(
<Input placeholder="Version"/>
)}
</Form.Item>
)}
<Form.Item {...formItemLayout} label="Release Type"> <Form.Item {...formItemLayout} label="Release Type">
{getFieldDecorator('releaseType', { {getFieldDecorator('releaseType', {
rules: [{ rules: [{
@ -516,24 +395,26 @@ class EditReleaseModal extends React.Component {
message: 'Please enter a description for release' message: 'Please enter a description for release'
}], }],
})( })(
<TextArea placeholder="Enter a description for release" <TextArea placeholder="Enter a description for release" rows={5}/>
rows={5}/>
)} )}
</Form.Item> </Form.Item>
{(config.deviceTypes.mobileTypes.includes(deviceType)) && (
<Form.Item {...formItemLayout} label="Supported OS Versions"> {(formConfig.installationType !== "WEB_CLIP" && formConfig.installationType !== "CUSTOM") && (
{getFieldDecorator('supportedOS')( <Form.Item
{...formItemLayout}
label="Supported OS Versions"
validateStatus={osVersionsValidateStatus}
help={osVersionsHelperText}>
{getFieldDecorator('supportedOS', {
rules: [{
required: true
}],
initialValue: false
})(
<div> <div>
<InputGroup> <InputGroup>
<Row gutter={8}> <Row gutter={8}>
<Col span={11}> <Col span={11}>
<Form.Item>
{getFieldDecorator('lowerOsVersion', {
rules: [{
required: true,
message: 'Please select Value'
}],
})(
<Select <Select
placeholder="Lower version" placeholder="Lower version"
style={{width: "100%"}} style={{width: "100%"}}
@ -545,20 +426,11 @@ class EditReleaseModal extends React.Component {
</Option> </Option>
))} ))}
</Select> </Select>
)}
</Form.Item>
</Col> </Col>
<Col span={2}> <Col span={2}>
<p> - </p> <p> - </p>
</Col> </Col>
<Col span={11}> <Col span={11}>
<Form.Item>
{getFieldDecorator('upperOsVersion', {
rules: [{
required: true,
message: 'Please select Value'
}],
})(
<Select style={{width: "100%"}} <Select style={{width: "100%"}}
placeholder="Upper version" placeholder="Upper version"
onChange={this.handleUpperOsVersionChange}> onChange={this.handleUpperOsVersionChange}>
@ -569,9 +441,6 @@ class EditReleaseModal extends React.Component {
</Option> </Option>
))} ))}
</Select> </Select>
)}
</Form.Item>
</Col> </Col>
</Row> </Row>
</InputGroup> </InputGroup>
@ -580,20 +449,14 @@ class EditReleaseModal extends React.Component {
</Form.Item> </Form.Item>
)} )}
<Form.Item {...formItemLayout} label="Meta Data"> <Form.Item {...formItemLayout} label="Meta Data">
{getFieldDecorator('meta', { {getFieldDecorator('meta', {})(
rules: [{
required: true,
message: 'Please fill empty fields'
}],
initialValue: false
})(
<div> <div>
{ {
metaData.map((data, index) => { metaData.map((data, index) => {
return ( return (
<InputGroup key={index}> <InputGroup key={index}>
<Row gutter={8}> <Row gutter={8}>
<Col span={10}> <Col span={5}>
<Input <Input
placeholder="key" placeholder="key"
value={data.key} value={data.key}
@ -604,7 +467,7 @@ class EditReleaseModal extends React.Component {
}) })
}}/> }}/>
</Col> </Col>
<Col span={10}> <Col span={8}>
<Input <Input
placeholder="value" placeholder="value"
value={data.value} value={data.value}
@ -637,32 +500,26 @@ class EditReleaseModal extends React.Component {
</Button> </Button>
</div> </div>
)} )}
</Form.Item> </Form.Item>
<Divider/>
<Form.Item style={{float: "right", marginLeft: 8}}> <Form.Item style={{float: "right", marginLeft: 8}}>
<Button type="primary" htmlType="submit"> <Button type="primary" htmlType="submit">
Update Submit
</Button> </Button>
</Form.Item> </Form.Item>
<Form.Item style={{float: "right"}}> <Form.Item style={{float: "right"}}>
<Button htmlType="button" onClick={this.handleCancel}> <Button htmlType="button" onClick={this.props.onClickBackButton}>
Back Back
</Button> </Button>
</Form.Item> </Form.Item>
<br/>
</Form> </Form>
</Spin> </Col>
</div> </Row>
<Modal visible={previewVisible} footer={null} onCancel={this.handlePreviewCancel}> <Modal visible={previewVisible} footer={null} onCancel={this.handlePreviewCancel}>
<img alt="Preview Image" style={{width: '100%'}} src={previewImage}/> <img alt="Preview Image" style={{width: '100%'}} src={previewImage}/>
</Modal> </Modal>
</Modal>
</div> </div>
); );
} }
} }
const EditRelease = withConfigContext(Form.create({name: 'add-new-release'})(EditReleaseModal)); export default (Form.create({name: 'app-upload-form'})(NewAppUploadForm));
export default EditRelease;
Loading…
Cancel
Save