diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index 127a5e7eaea..0032b91112c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -15,6 +15,7 @@ "axios": "^0.18.0", "d3": "^5.9.2", "dagre": "^0.8.4", + "fetch": "^1.1.0", "keymirror": "^0.1.1", "rc-tween-one": "^2.4.1", "react": "^16.8.4", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js index bd7a2ef8a8a..8100a25a05b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js @@ -10,12 +10,12 @@ const {Option} = Select; const {Title, Text} = Typography; const Search = Input.Search; // connecting state.apps with the component -const mapStateToProps = state => { - return {apps: state.apps} -}; +// const mapStateToProps = state => { +// return {apps: state.apps} +// }; -class ConnectedListApps extends React.Component { +class ListApps extends React.Component { constructor(props) { super(props); this.state = { @@ -70,6 +70,6 @@ class ConnectedListApps extends React.Component { } } -const ListApps = connect(mapStateToProps, {getApps})(ConnectedListApps); +// const ListApps = connect(mapStateToProps, {getApps})(ConnectedListApps); export default ListApps; \ 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/AddNewAppForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js new file mode 100644 index 00000000000..91cd8bc0ac9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js @@ -0,0 +1,569 @@ +import React from "react"; +import "antd/dist/antd.css"; +import { + PageHeader, + Typography, + Card, + Steps, + Button, + message, + Row, + Col, + Tag, + Tooltip, + Input, + Icon, + Select, + Switch, + Form, + Upload, + Divider, notification +} from "antd"; +import IconImage from "./IconImg"; +import UploadScreenshots from "./UploadScreenshots"; +import axios from "axios"; +import config from "../../../public/conf/config.json"; + +const Paragraph = Typography; +const Dragger = Upload.Dragger; + +const props = { + name: 'file', + multiple: false, + action: '//jsonplaceholder.typicode.com/posts/', + onChange(info) { + const status = info.file.status; + if (status !== 'uploading') { + console.log(info.file, info.fileList); + } + if (status === 'done') { + message.success(`${info.file.name} file uploaded successfully.`); + } else if (status === 'error') { + message.error(`${info.file.name} file upload failed.`); + } + }, +}; + +// +// const steps = [{ +// title: 'First', +// content: Step1 +// }, { +// title: 'Second', +// content: Step2, +// }, { +// title: 'Last', +// content: Step3, +// }]; + + +const {Option} = Select; +const {TextArea} = Input; +const InputGroup = Input.Group; + +const formItemLayout = { + labelCol: { + span: 4, + }, + wrapperCol: { + span: 20, + }, +}; + +class AddNewAppFormComponent extends React.Component { + + constructor(props) { + super(props); + this.state = { + current: 0, + categories: [], + tags: [], + icons: [], + screenshots: [] + }; + } + + 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", + { + headers: {'X-Platform': config.serverConfig.platform} + }).then(res => { + if (res.status === 200) { + let categories = JSON.parse(res.data.data); + this.setState({ + categories: categories, + loading: false + }); + } + + }).catch((error) => { + if (error.response.status === 401) { + window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; + } else { + message.warning('Something went wrong'); + + } + 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", + { + headers: {'X-Platform': config.serverConfig.platform} + }).then(res => { + if (res.status === 200) { + let tags = JSON.parse(res.data.data); + this.setState({ + tags: tags, + loading: false, + }); + } + + }).catch((error) => { + if (error.response.status === 401) { + window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; + } else { + message.warning('Something went wrong'); + + } + this.setState({ + loading: false + }); + }); + }; + + handleCategoryChange = (value) => { + console.log(`selected ${value}`); + }; + + handleSubmit = e => { + e.preventDefault(); + this.props.form.validateFields((err, values) => { + if (!err) { + const {name, description, appCategories, tags, deviceType, price, isSharedWithAllTenants, binaryFile, icon, screenshots} = values; + const payload = { + binaryFile: binaryFile[0].originFileObj, + icon: icon[0].originFileObj, + screenshot1: screenshots[0].originFileObj, + screenshot2: screenshots[1].originFileObj, + screenshot3: screenshots[2].originFileObj, + application: { + name, + description, + appCategories, + subType: (price === undefined || parseInt(price) === 0) ? "FREE" : "PAID", + tags, + unrestrictedRoles: [], + deviceType, + entAppReleaseWrappers: [{ + description, + price: (price === undefined) ? 0 : parseInt(price), + isSharedWithAllTenants, + metaData: "string", + supportedOsVersions: "4.0-10.0" + }] + } + }; + + console.log(payload); + + // let data = new FormData(); + // + // const url = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/ent-app"; + // + // 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); + // data.append('application', JSON.toString(payload.application)); + + // let request = new XMLHttpRequest(); + // request.open('POST', url); + // request.send(data); + + + // var xhr = new XMLHttpRequest(); + // // xhr.withCredentials = true; + // + // xhr.addEventListener("readystatechange", function () { + // if (this.readyState === 4) { + // console.log(this.responseText); + // } + // }); + // + // xhr.open("POST", "https://localhost:9443/ui-request-handler/invoke/application-mgt-publisher/v1.0/applications/ent-app"); + // xhr.open("GET", "https://localhost:9443/ui-request-handler/invoke/application-mgt-publisher/v1.0/applications/tags"); + + // xhr.setRequestHeader("Content-Type", "multipart/mixed"); + // xhr.setRequestHeader("X-Platform", "publisher"); + // + + // // xhr.setRequestHeader("Accept", "*/*"); + // + // xhr.send(data); + + // xhr.send(); + + // const options = {method: 'POST', body: data}; + // + // fetch(url, options).then(function (response) { + // console.log(response); + // }); + + + // axios.post( + // url, + // data, + // { + // headers:{ + // 'X-Platform': config.serverConfig.platform, + // 'Content-Type': 'multipart/mixed', + // 'content-type': 'multipart/form-data' + // }, + // 'Content-Type': 'multipart/mixed', + // 'content-type': 'multipart/form-data' + // } + // ).then(res => { + // if (res.status === 201) { + // this.setState({ + // loading: false, + // }); + // + // notification["success"]({ + // message: "Done!", + // description: + // "New app was added successfully", + // }); + // } + // + // }).catch((error) => { + // if (error.response.status === 401) { + // window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; + // } else { + // message.warning('Something went wrong'); + // + // } + // this.setState({ + // loading: false + // }); + // }); + + + + var data = new FormData(); + // data.append("binaryFile", "/Users/jayasanka/Desktop/gov/viber/a.apk"); + // data.append("application", "{\n\t\"name\": \"Tub1111\",\n\t\"description\": \"Watch thousands of hit movies and TV series for free. Tubi is 100% legal unlimited streaming, with no credit cards and no subscription required. Choose what you want to watch, when you want to watch it, with fewer ads than regular TV. Tubi is the largest free streaming service featuring award-winning movies and TV series. There is something for everybody; from comedy to drama, kids to classics, and niche favorites such as Korean dramas, anime, and British series. Download now and start streaming entertainment for free, today!\",\n\t\"appCategories\": [\"EMM\"],\n\t\"subType\": \"FREE\",\n\t\"tags\": [\"tv\", \"movies\"],\n\t\"unrestrictedRoles\": [],\n\t\"deviceType\": \"android\",\n\t\"entAppReleaseWrappers\": [{\n\t\t\"description\": \" SEND A MESSAGE -Skip exchanging phone numbers, just send a message. It's seamless across devices. * SHOW YOUR REACTION - Add a silly sticker\",\n\t\t\"releaseType\": \"GA\",\n\t\t\"price\": 0.0,\n\t\t\"isSharedWithAllTenants\": false,\n\t\t\"metaData\": \"{\\\"developer\\\":\\\"Facebook, Inc.\\\",\\\"Copyright\\\":\\\"\\u00A9 Facebook, Inc.\\\",\\\"Location\\\":\\\"This app may use your location even when it isn't open, which can decrease battery life.\\\"}\",\n\t\t\"ratedUsers\": 0,\n\t\t\"rating\": 0,\n\t\t\"supportedOsVersions\": \"4.0-10.0\"\n\t}]\n}"); + // data.append("icon", "/Users/jayasanka/Desktop/gov/angular/i.png"); + // data.append("screenshot1", "/Users/jayasanka/Desktop/gov/angular/1.webp"); + // data.append("screenshot2", "/Users/jayasanka/Desktop/gov/angular/2.webp"); + // data.append("screenshot3", "/Users/jayasanka/Desktop/gov/angular/3.webp"); + + + 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); + data.append('application', JSON.toString(payload.application)); + + + var xhr = new XMLHttpRequest(); + xhr.withCredentials = true; + + xhr.addEventListener("readystatechange", function () { + if (this.readyState === 4) { + console.log(this.responseText); + } + }); + + xhr.open("POST", "https://localhost:9443/ui-request-handler/invoke/application-mgt-publisher/v1.0/applications/ent-app"); + xhr.setRequestHeader("Content-Type", "multipart/mixed"); + xhr.setRequestHeader("X-Platform", "publisher"); + + xhr.send(data); + + } + }); + }; + + normFile = e => { + console.log('Upload event:', e); + if (Array.isArray(e)) { + return e; + } + return e && e.fileList; + }; + + handleIconChange = ({fileList}) => this.setState({icons: 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(); + }; + + render() { + const {categories, tags, icons, screenshots} = this.state; + const {getFieldDecorator} = this.props.form; + return ( +
+ + + +
+ + +
+ {/*device type*/} + + {getFieldDecorator('deviceType', { + rules: [{ + required: false, + message: 'Please select device type' + }, + { + validator: this.validateIcon + }], + })( + + )} + + + {/*app name*/} + + {getFieldDecorator('name', { + rules: [{ + required: false, + message: 'Please input a name' + }], + })( + + )} + + + {/*description*/} + + {getFieldDecorator('description', { + rules: [{ + required: false, + message: 'Please enter a description' + }], + })( +