diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js
index cf7d6fc4c9a..5a25c80ae98 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js
@@ -2,35 +2,22 @@ import React from "react";
import {
Card,
Button,
- message,
+ Steps,
Row,
Col,
- Input,
- Icon,
- Select,
- Switch,
Form,
- Upload,
- Divider,
+ Result,
notification,
Spin
} from "antd";
import axios from "axios";
import {withRouter} from 'react-router-dom'
import config from "../../../public/conf/config.json";
+import NewAppDetailsForm from "./subForms/NewAppDetailsForm";
+import NewAppUploadForm from "./subForms/NewAppUploadForm";
-const {Option} = Select;
-const {TextArea} = Input;
-const InputGroup = Input.Group;
+const {Step} = Steps;
-const formItemLayout = {
- labelCol: {
- span: 5,
- },
- wrapperCol: {
- span: 19,
- },
-};
class AddNewAppFormComponent extends React.Component {
@@ -43,53 +30,59 @@ class AddNewAppFormComponent extends React.Component {
icons: [],
screenshots: [],
loading: false,
- binaryFiles: []
+ binaryFiles: [],
+ application: null,
+ release: null,
+ isError: false
};
}
- componentDidMount() {
- this.getCategories();
- this.getTags();
- }
+ onSuccessApplicationData = (application) => {
+ this.setState({
+ application,
+ current: 1
+ });
+ };
- getCategories = () => {
- axios.get(
- config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories"
- ).then(res => {
- if (res.status === 200) {
- let categories = JSON.parse(res.data.data);
- this.setState({
- categories: categories,
- loading: false
- });
- }
+ onSuccessReleaseData = (releaseData) => {
+ this.setState({
+ loading: true,
+ isError: false
+ });
+ const {application} = this.state;
+ const {data, release} = releaseData;
+ const {formConfig} = this.props;
- }).catch((error) => {
- if (error.hasOwnProperty("response") && error.response.status === 401) {
- window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
- } else {
- notification["error"]({
- message: "There was a problem",
- duration: 0,
- description:
- "Error occurred while trying to load categories.",
- });
- }
- this.setState({
- loading: false
- });
+ //add release wrapper
+ application[formConfig.releaseWrapperName] = [release];
+
+ const json = JSON.stringify(application);
+ const blob = new Blob([json], {
+ type: 'application/json'
});
- };
+ data.append(formConfig.jsonPayloadName, blob);
- getTags = () => {
- axios.get(
- config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags"
+ const url = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications" + formConfig.endpoint;
+
+ axios.post(
+ url,
+ data,
+ {
+ headers: {
+ 'X-Platform': config.serverConfig.platform
+ },
+ }
).then(res => {
- if (res.status === 200) {
- let tags = JSON.parse(res.data.data);
+ if (res.status === 201) {
+ this.setState({
+ loading: false,
+ current: 2
+ });
+ } else {
this.setState({
- tags: tags,
loading: false,
+ isError: true,
+ current: 2
});
}
@@ -98,463 +91,74 @@ class AddNewAppFormComponent extends React.Component {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else {
notification["error"]({
- message: "There was a problem",
- duration: 0,
+ message: "Something went wrong!",
description:
- "Error occurred while trying to load tags.",
+ "Sorry, we were unable to complete your request.",
});
+
}
this.setState({
- loading: false
+ loading: false,
+ isError: true,
+ current: 2
});
});
- };
-
- handleCategoryChange = (value) => {
- // console.log(`selected ${value}`);
- };
-
- handleSubmit = e => {
- e.preventDefault();
- const {formConfig} = this.props;
- const {specificElements} = formConfig;
-
- this.props.form.validateFields((err, values) => {
- if (!err) {
- this.setState({
- loading: true
- });
- const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values;
- const application = {
- name,
- description,
- categories,
- subMethod: (price === undefined || parseInt(price) === 0) ? "FREE" : "PAID",
- tags,
- unrestrictedRoles: [],
- };
-
- const data = new FormData();
-
- if (formConfig.installationType !== "WEB_CLIP") {
- application.deviceType = values.deviceType;
- } else {
- application.type = "WEB_CLIP";
- application.deviceType = "ALL";
- }
-
- if (specificElements.hasOwnProperty("binaryFile")) {
- data.append('binaryFile', binaryFile[0].originFileObj);
- }
-
- //add release data
- const release = {
- description: releaseDescription,
- price: (price === undefined) ? 0 : parseInt(price),
- isSharedWithAllTenants,
- metaData: "string",
- releaseType: releaseType
- };
-
- if (formConfig.installationType !== "WEB_CLIP") {
- release.supportedOsVersions = "4.0-10.0";
- }
-
- if (specificElements.hasOwnProperty("version")) {
- release.version = values.version;
- }
- if (specificElements.hasOwnProperty("url")) {
- release.url = values.url;
- }
- if (specificElements.hasOwnProperty("packageName")) {
- release.packageName = values.packageName;
- }
-
- //add release wrapper
- application[formConfig.releaseWrapperName] = [release];
-
- data.append('icon', icon[0].originFileObj);
- data.append('screenshot1', screenshots[0].originFileObj);
- data.append('screenshot2', screenshots[1].originFileObj);
- data.append('screenshot3', screenshots[2].originFileObj);
-
- const json = JSON.stringify(application);
- const blob = new Blob([json], {
- type: 'application/json'
- });
- data.append(formConfig.jsonPayloadName, blob);
-
- const url = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications" + formConfig.endpoint;
-
- axios.post(
- url,
- data,
- {
- headers: {
- 'X-Platform': config.serverConfig.platform
- },
- }
- ).then(res => {
- if (res.status === 201) {
- this.setState({
- loading: false,
- });
-
- notification["success"]({
- message: "Done!",
- description:
- "New app was added successfully",
- });
-
- this.props.history.push('/publisher/apps');
-
- // window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/apps';
-
- }
-
- }).catch((error) => {
- if (error.hasOwnProperty("response") && error.response.status === 401) {
- window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
- } else {
- notification["error"]({
- message: "Something went wrong!",
- description:
- "Sorry, we were unable to complete your request.",
- });
-
- }
- this.setState({
- loading: false
- });
- });
- }
- });
- };
- normFile = e => {
- if (Array.isArray(e)) {
- return e;
- }
- return e && e.fileList;
};
- handleIconChange = ({fileList}) => this.setState({icons: fileList});
- handleBinaryFileChange = ({fileList}) => this.setState({binaryFiles: fileList});
-
- handleScreenshotChange = ({fileList}) => this.setState({screenshots: fileList});
-
- validateIcon = (rule, value, callback) => {
- const {icons} = this.state;
- if (icons.length !== 1) {
- callback("Please select icon file");
- }
- callback();
+ onClickBackButton = () => {
+ const current = this.state.current - 1;
+ this.setState({current});
};
render() {
- const {categories, tags, icons, screenshots, loading, binaryFiles} = this.state;
- const {getFieldDecorator} = this.props.form;
+ const { loading, current, isError} = this.state;
const {formConfig} = this.props;
+
return (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {!isError && ( this.props.history.push('/publisher/apps')}>
+ Go to applications
+
+ ]}
+ />)}
+
+ {isError && (Back}
+ />)}
+
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppDetailsForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppDetailsForm.js
new file mode 100644
index 00000000000..446659a43dc
--- /dev/null
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppDetailsForm.js
@@ -0,0 +1,266 @@
+import React from "react";
+import {Button, Col, Divider, Form, Icon, Input, notification, Row, Select, Switch, Upload} from "antd";
+import axios from "axios";
+import config from "../../../../public/conf/config.json";
+
+const formItemLayout = {
+ labelCol: {
+ xs: { span: 24 },
+ sm: { span: 5 },
+ },
+ wrapperCol: {
+ xs: { span: 24 },
+ sm: { span: 19 },
+ },
+};
+const {Option} = Select;
+const {TextArea} = Input;
+const InputGroup = Input.Group;
+
+class NewAppDetailsForm extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ categories: [],
+ tags: []
+ }
+ }
+
+
+ handleSubmit = e => {
+ e.preventDefault();
+ const {formConfig} = this.props;
+ const {specificElements} = formConfig;
+
+ this.props.form.validateFields((err, values) => {
+ if (!err) {
+ this.setState({
+ loading: true
+ });
+ const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values;
+ const application = {
+ name,
+ description,
+ categories,
+ subMethod: (price === undefined || parseInt(price) === 0) ? "FREE" : "PAID",
+ tags,
+ unrestrictedRoles: [],
+ };
+
+ if (formConfig.installationType !== "WEB_CLIP") {
+ application.deviceType = values.deviceType;
+ } else {
+ application.type = "WEB_CLIP";
+ application.deviceType = "ALL";
+ }
+
+ this.props.onSuccessApplicationData(application);
+ }
+ });
+ };
+
+ componentDidMount() {
+ this.getCategories();
+ this.getTags();
+ }
+
+ getCategories = () => {
+ axios.get(
+ config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories"
+ ).then(res => {
+ if (res.status === 200) {
+ let categories = JSON.parse(res.data.data);
+ this.setState({
+ categories: categories,
+ loading: false
+ });
+ }
+
+ }).catch((error) => {
+ if (error.hasOwnProperty("response") && error.response.status === 401) {
+ window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
+ } else {
+ notification["error"]({
+ message: "There was a problem",
+ duration: 0,
+ description:
+ "Error occurred while trying to load categories.",
+ });
+ }
+ this.setState({
+ loading: false
+ });
+ });
+ };
+
+ getTags = () => {
+ axios.get(
+ config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags"
+ ).then(res => {
+ if (res.status === 200) {
+ let tags = JSON.parse(res.data.data);
+ this.setState({
+ tags: tags,
+ loading: false,
+ });
+ }
+
+ }).catch((error) => {
+ if (error.hasOwnProperty("response") && error.response.status === 401) {
+ window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
+ } else {
+ notification["error"]({
+ message: "There was a problem",
+ duration: 0,
+ description:
+ "Error occurred while trying to load tags.",
+ });
+ }
+ this.setState({
+ loading: false
+ });
+ });
+ };
+
+ render() {
+ const {formConfig} = this.props;
+ const {categories, tags} = this.state;
+ const {getFieldDecorator} = this.props.form;
+
+ return (
+
+
+
+
+
+
+
+ {getFieldDecorator('deviceType', {
+ rules: [
+ {
+ required: true,
+ message: 'Please select device type'
+ }
+ ],
+
+ }
+ )(
+
+ )}
+
+ )}
+
+ {/*app name*/}
+
+ {getFieldDecorator('name', {
+ rules: [{
+ required: true,
+ message: 'Please input a name'
+ }],
+ })(
+
+ )}
+
+
+ {/*description*/}
+
+ {getFieldDecorator('description', {
+ rules: [{
+ required: true,
+ message: 'Please enter a description'
+ }],
+ })(
+
+
+ {getFieldDecorator('categories', {
+ rules: [{
+ required: true,
+ message: 'Please select categories'
+ }],
+ })(
+
+ )}
+
+
+ {getFieldDecorator('tags', {
+ rules: [{
+ required: true,
+ message: 'Please select tags'
+ }],
+ })(
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+}
+
+export default (Form.create({name: 'app-details-form'})(NewAppDetailsForm));
\ No newline at end of file
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js
new file mode 100644
index 00000000000..3a103f9ac75
--- /dev/null
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js
@@ -0,0 +1,295 @@
+import React from "react";
+import {Button, Col, Form, Icon, Input, Row, Select, Switch, Upload, InputNumber} from "antd";
+
+const formItemLayout = {
+ labelCol: {
+ xs: {span: 24},
+ sm: {span: 5},
+ },
+ wrapperCol: {
+ xs: {span: 24},
+ sm: {span: 19},
+ },
+};
+const {Option} = Select;
+const {TextArea} = Input;
+
+class NewAppUploadForm extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ icons: [],
+ screenshots: [],
+ loading: false,
+ binaryFiles: [],
+ application: null
+ }
+ }
+
+ normFile = e => {
+ if (Array.isArray(e)) {
+ return e;
+ }
+ return e && e.fileList;
+ };
+
+ handleSubmit = e => {
+ e.preventDefault();
+ const {formConfig} = this.props;
+ const {specificElements} = formConfig;
+
+ this.props.form.validateFields((err, values) => {
+ if (!err) {
+ this.setState({
+ loading: true
+ });
+
+ const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values;
+
+ //add release data
+ const release = {
+ description: releaseDescription,
+ price: (price === undefined) ? 0 : parseInt(price),
+ isSharedWithAllTenants,
+ metaData: "string",
+ releaseType: releaseType
+ };
+
+ if (formConfig.installationType !== "WEB_CLIP") {
+ release.supportedOsVersions = "4.0-10.0";
+ }
+
+ if (specificElements.hasOwnProperty("version")) {
+ release.version = values.version;
+ }
+ if (specificElements.hasOwnProperty("url")) {
+ release.url = values.url;
+ }
+ if (specificElements.hasOwnProperty("packageName")) {
+ release.packageName = values.packageName;
+ }
+
+ const data = new FormData();
+
+ if (specificElements.hasOwnProperty("binaryFile")) {
+ data.append('binaryFile', binaryFile[0].originFileObj);
+ }
+
+ data.append('icon', icon[0].originFileObj);
+ data.append('screenshot1', screenshots[0].originFileObj);
+ data.append('screenshot2', screenshots[1].originFileObj);
+ data.append('screenshot3', screenshots[2].originFileObj);
+
+ this.props.onSuccessReleaseData({data, release});
+ }
+ });
+ };
+
+ handleIconChange = ({fileList}) => this.setState({icons: fileList});
+ handleBinaryFileChange = ({fileList}) => this.setState({binaryFiles: fileList});
+
+ handleScreenshotChange = ({fileList}) => this.setState({screenshots: fileList});
+
+ render() {
+ const {formConfig} = this.props;
+ const {getFieldDecorator} = this.props.form;
+ const {icons, screenshots, binaryFiles} = this.state;
+
+
+ return (
+
+
+
+
+
+
+
+ {getFieldDecorator('binaryFile', {
+ valuePropName: 'binaryFile',
+ getValueFromEvent: this.normFile,
+ required: true,
+ message: 'Please select application'
+ })(
+ false}
+ >
+ {binaryFiles.length !== 1 && (
+
+ )}
+ ,
+ )}
+
+ )}
+
+
+ {getFieldDecorator('icon', {
+ valuePropName: 'icon',
+ getValueFromEvent: this.normFile,
+ required: true,
+ message: 'Please select a icon'
+ })(
+ false}
+ >
+ {icons.length !== 1 && (
+
+ )}
+ ,
+ )}
+
+
+
+
+
+
+
+
+
+ {getFieldDecorator('screenshots', {
+ valuePropName: 'icon',
+ getValueFromEvent: this.normFile,
+ required: true,
+ message: 'Please select a icon'
+ })(
+ false}
+ multiple
+ >
+
+ {screenshots.length < 3 && (
+
+ )}
+
+
+ ,
+ )}
+
+
+ {formConfig.specificElements.hasOwnProperty("packageName") && (
+
+ {getFieldDecorator('packageName', {
+ rules: [{
+ required: true,
+ message: 'Please input the package name'
+ }],
+ })(
+
+ )}
+
+ )}
+
+ {formConfig.specificElements.hasOwnProperty("url") && (
+
+ {getFieldDecorator('url', {
+ rules: [{
+ required: true,
+ message: 'Please input the url'
+ }],
+ })(
+
+ )}
+
+ )}
+
+ {formConfig.specificElements.hasOwnProperty("version") && (
+
+ {getFieldDecorator('version', {
+ rules: [{
+ required: true,
+ message: 'Please input the version'
+ }],
+ })(
+
+ )}
+
+ )}
+
+
+ {getFieldDecorator('releaseType', {
+ rules: [{
+ required: true,
+ message: 'Please input the Release Type'
+ }],
+ })(
+
+ )}
+
+
+
+ {getFieldDecorator('releaseDescription', {
+ rules: [{
+ required: true,
+ message: 'Please enter a description for release'
+ }],
+ })(
+
+
+
+ {getFieldDecorator('price', {
+ rules: [{
+ required: false
+ }],
+ })(
+ `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
+ parser={value => value.replace(/\$\s?|(,*)/g, '')}
+ />
+ )}
+
+
+
+ {getFieldDecorator('isSharedWithAllTenants', {
+ rules: [{
+ required: true,
+ message: 'Please select'
+ }],
+ initialValue: false
+ })(
+ }
+ unCheckedChildren={}
+ />
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+}
+
+export default (Form.create({name: 'app-upload-form'})(NewAppUploadForm));
\ No newline at end of file