From b3d2abf99eaa1a0cf1f93643f42acaa02ef68fd1 Mon Sep 17 00:00:00 2001 From: Menaka Jayawardena Date: Mon, 11 Sep 2017 13:20:18 +0530 Subject: [PATCH] Added tags to platform create page and basic backend integration api implementation. --- .../src/main/resources/publisher/package.json | 28 ++--- .../src/main/resources/publisher/src/App.css | 0 .../src/main/resources/publisher/src/App.jsx | 22 +++- .../src/main/resources/publisher/src/App.scss | 5 + .../publisher/src/api/AuthHandler.js | 28 +++++ .../resources/publisher/src/api/Endpoints.js | 103 +++++++++++++++++- .../src/api/helpers/AppMgtApiHelpers.js | 49 +++++++++ .../publisher/src/common/constants.js | 14 +++ .../Application/ApplicationCreate.jsx | 7 +- .../Application/CreateSteps/Step2.jsx | 21 ++-- .../components/Platform/PlatformCreate.jsx | 72 ++++++++++++ .../components/Platform/PlatformListing.jsx | 4 +- .../src/components/User/Login/Login.jsx | 98 ++++++++++------- 13 files changed, 376 insertions(+), 75 deletions(-) delete mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.css create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.scss create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/helpers/AppMgtApiHelpers.js diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/package.json index 5e5fd515b50..445560ff204 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/package.json @@ -11,38 +11,40 @@ "dependencies": { "axios": "^0.16.2", "flux": "^3.1.3", - "history": "^4.6.3", + "history": "^4.7.2", "latest-version": "^3.1.0", - "material-ui": "^0.19.0", + "material-ui": "^0.19.1", "prop-types": "^15.5.10", "qs": "^6.5.0", "react": "^15.6.1", "react-dom": "^15.6.1", - "react-dropzone": "^4.1.0", + "react-dropzone": "^4.1.2", "react-images-uploader": "^1.1.0", - "react-material-ui-form-validator": "^0.5.0", - "react-modal": "^2.2.2", - "react-router": "^4.1.2", - "react-router-dom": "^4.1.2", + "react-material-ui-form-validator": "^0.5.1", + "react-modal": "^2.3.2", + "react-router": "^4.2.0", + "react-router-dom": "^4.2.2", "react-scripts": "1.0.10", "react-sliding-pane": "^1.2.3", "react-tap-event-plugin": "^2.0.1" }, "devDependencies": { - "babel-core": "^6.24.1", - "babel-loader": "^7.0.0", + "babel-core": "^6.26.0", + "babel-loader": "^7.1.2", "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-es2015": "^6.24.1", - "chai": "^4.0.2", "babel-preset-react": "^6.24.1", - "babel-register": "^6.24.1", - "css-loader": "^0.28.2", + "babel-register": "^6.26.0", + "chai": "^4.1.2", + "css-loader": "^0.28.7", "less": "^2.7.2", "less-loader": "^4.0.4", "mocha": "^3.4.1", "mock-local-storage": "^1.0.2", + "node-sass": "^4.5.3", + "sass-loader": "^6.0.6", "style-loader": "^0.18.1", - "webpack": "^2.5.0" + "webpack": "^2.7.0" }, "scripts": { "start": "react-scripts start", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.css deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.jsx b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.jsx index 9dac4fa9c29..24dcb2848ae 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.jsx +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.jsx @@ -16,7 +16,7 @@ * under the License. */ -import './App.css'; +import './App.scss'; import React, {Component} from 'react'; import createHistory from 'history/createBrowserHistory'; import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom' @@ -54,12 +54,21 @@ class Base extends Component { constructor() { super(); this.state = { - user: "admin" + user: "s" } } + componentWillMount() { + + } + + componentDidMount() { + + } + render() { if (this.state.user) { + console.log("Have User."); return (
@@ -69,8 +78,8 @@ class Base extends Component { - - + + @@ -80,8 +89,11 @@ class Base extends Component {
) + } else { + console.log("No user"); + return () } - return () + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.scss b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.scss new file mode 100644 index 00000000000..3f4bc89fefb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/App.scss @@ -0,0 +1,5 @@ +.middle-content { + width: 95%; + height: 100%; + margin: 1% 0 0 0; +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/AuthHandler.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/AuthHandler.js index 9eb827eb700..62604f68a36 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/AuthHandler.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/AuthHandler.js @@ -15,3 +15,31 @@ * specific language governing permissions and limitations * under the License. */ +'use strict'; + +import Axios from 'axios'; + +/** + * Handles all tasks related to Authentication and Authorization. + * Generate access tokens, verify the user has necessary permissions etc. + * */ +class AuthHandler { + + /** + * Generate client id and client secret to generate access tokens. + * */ + login(userName, password) { + Axios.post("https://localhost:9443/auth/application-mgt/v1.0/auth/tokens?userName=admin&password=admin").then() + } + + isLoggedIn() { + + } + + getloggedInUser() { + + } + + + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/Endpoints.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/Endpoints.js index e3e76b69c23..0f6ab3bd140 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/Endpoints.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/Endpoints.js @@ -15,7 +15,106 @@ * specific language governing permissions and limitations * under the License. */ +'use strict'; + +import Helper from './helpers/AppMgtApiHelpers'; /** - * Defines the list of App Manager APIs. - * */ \ No newline at end of file + * Application related apis + * */ +export default class Endpoint{ + + /** + * Api for create an application. + * @param: applicationData: The application data object. This contains an object array of each step data from + * application creation wizard. + * + * From that data array, the proper application object is created and send it to the api. + * */ + static createApplication(applicationData) { + + console.log("In application create application", applicationData); + Helper.buildApplication(applicationData); + + } + + /** + * Method to handle application release process. + * */ + static releaseApplication() { + + } + + /** + * Edit created application. + * @param applicationData: The modified application data. + * */ + static editApplication(applicationData) { + + } + + /** + * Get all the created applications for the user. + * */ + static getApplications() { + + } + + /** + * Get specific application. + * @param appId : The application Id. + * */ + static getApplication(appId) { + + } + + /** + * Delete specified application. + * @param appId: The id of the application which is to be deleted. + * */ + static deleteApplication(appId) { + + } + + + /** + * Platform related apis + * */ + /** + * Create a new Platform + * @param platformData: The platform data object. + * */ + static createPlatform(platformData) { + // /api/application-mgt/v1.0/platforms/1.0.0/ + // { + // identifier: "${platform_identifier}", + // name: "New Platform", + // description : "New Platform" + // } + } + + /** + * Get available platforms + * */ + static getPlatforms() { + + } + + /** + * Get the user specified platform + * @param platformId: The identifier of the platform + * */ + static getPlatform(platformId) { + + } + + /** + * Delete specified platform + * @param platformId: The id of the platform which is to be deleted. + * */ + static deletePlatform(platformId) { + + } + + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/helpers/AppMgtApiHelpers.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/helpers/AppMgtApiHelpers.js new file mode 100644 index 00000000000..c52d9ed6cde --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/api/helpers/AppMgtApiHelpers.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use strict'; + +/** + * Helper methods for app publisher. + * */ +export default class Helper { + + /** + * Generate application object from form data passed. + * @param appData: Application data from the application creation form. + * */ + static buildApplication(appData) { + + let application = {}; + let images = {}; + + for (var step in appData) { + let tmpData = appData[step].data.step; + for (var prop in tmpData) { + if (prop === 'banner' || prop === 'screenshots' || prop === 'icon') { + images[prop] = tmpData[prop]; + } else { + application[prop] = tmpData[prop]; + } + } + } + + console.log(application, images); + } + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/common/constants.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/common/constants.js index 9eb827eb700..405042531c5 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/common/constants.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/common/constants.js @@ -15,3 +15,17 @@ * specific language governing permissions and limitations * under the License. */ + +scopes = 'perm:application:get perm:application:create perm:application:update perm:application-mgt:login' + + ' perm:application:delete perm:platform:add perm:platform:remove perm:roles:view perm:devices:view'; + +TOKEN_ENDPOINT = '/token'; +DYNAMIC_CLIENT_REGISTER_ENDPOINT = '/api-application-registration/register'; + +appManagerEndpoints = { + GET_ALL_APPS: '/api/application-mgt/v1.0/applications/1.0.0/', + CREATE_APP: '/api/application-mgt/v1.0/applications/1.0.0/', + UPLOAD_IMAGES: '/api/application-mgt/v1.0/applications/1.0.0/upload-image-artifacts/', //+appId +}; + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/ApplicationCreate.jsx b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/ApplicationCreate.jsx index 870ed0cdb9f..2542eaa5f7a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/ApplicationCreate.jsx +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/ApplicationCreate.jsx @@ -18,6 +18,7 @@ import React, {Component} from 'react'; import Dialog from 'material-ui/Dialog'; +import Endpoint from '../../api/Endpoints'; import {withRouter} from 'react-router-dom'; import FlatButton from 'material-ui/FlatButton'; import {Step1, Step2, Step3} from './CreateSteps'; @@ -80,6 +81,8 @@ class ApplicationCreate extends Component { * */ handleSubmit = () => { console.log(this.state.stepData); + Endpoint.createApplication(this.state.stepData); + }; /** @@ -164,11 +167,10 @@ class ApplicationCreate extends Component { setData={this.setStepData} removeData={this.removeStepData}/>; default: - return 'You\'re a long way from home sonny jim!'; + return
; } } - render() { const {finished, stepIndex} = this.state; const contentStyle = {margin: '0 16px'}; @@ -189,7 +191,6 @@ class ApplicationCreate extends Component { />, ]; - return (
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/Step2.jsx b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/Step2.jsx index 198055a0925..24c0b906305 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/Step2.jsx +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/Step2.jsx @@ -56,16 +56,16 @@ class Step2 extends Component { super(); this.state = { tags: [], + icon: [], + title: "", + errors: {}, + banner: [], defValue: "", category: 0, visibility: 0, - errors: {}, - title: "", - shortDescription: "", description: "", - banner: [], screenshots: [], - icon: [] + shortDescription: "" }; this.scriptId = "application-create-step2"; } @@ -243,13 +243,14 @@ class Step2 extends Component { * */ _setStepData() { let stepData = { - title: this.state.title, - description: this.state.description, - shortDescription: this.state.shortDescription, tags: this.state.tags, + icon: this.state.icon, + title: this.state.title, banner: this.state.banner, + category: this.state.category, screenshots: this.state.screenshots, - icon: this.state.icon + description: this.state.description, + shortDescription: this.state.shortDescription }; this.props.setData("step2", {step: stepData}); @@ -346,7 +347,7 @@ class Step2 extends Component { { + this.chipData = this.state.tags; + const chipToDelete = this.chipData.map((chip) => chip.key).indexOf(key); + this.chipData.splice(chipToDelete, 1); + this.setState({tags: this.chipData}); + }; + + /** + * Create a tag on Enter key press and set it to the state. + * Clears the tags text field. + * Chip gets two parameters: Key and value. + * */ + _addTags(event) { + let tags = this.state.tags; + if (event.charCode === 13) { + event.preventDefault(); + tags.push({key: Math.floor(Math.random() * 1000), value: event.target.value}); + this.setState({tags, defValue: ""}); + } + } + + /** + * Creates Chip array from state.tags. + * */ + _renderChip(data) { + return ( + this._handleTagDelete(data.key)} + style={this.styles.chip} + > + {data.value} + + ); + } + + /** + * Set the value for tag. + * */ + _handleTagChange(event) { + let defaultValue = this.state.defValue; + defaultValue = event.target.value; + this.setState({defValue: defaultValue}) + } + /** * Remove the selected property from the property list. * */ @@ -161,6 +214,10 @@ class PlatformCreate extends Component { }; _onCreatePlatform() { + //Call the platform create api. + let platform = {}; + + } @@ -193,6 +250,8 @@ class PlatformCreate extends Component { selectedProperty, propertyTypes, name, + tags, + defValue, description, property} = this.state; @@ -236,6 +295,19 @@ class PlatformCreate extends Component { onToggle={this._handleToggle.bind(this)} toggled={enabled} />
+
+
+ {tags.map(this._renderChip, this)} +
+

Platform Properties

diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Platform/PlatformListing.jsx b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Platform/PlatformListing.jsx index 34387fca7ea..0f994eb417d 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Platform/PlatformListing.jsx +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Platform/PlatformListing.jsx @@ -97,8 +97,8 @@ class PlatformListing extends Component { handleRowClick={this._onRowClick.bind(this)} noDataMessage={{type: 'button', text: 'Create Platform'}}/> - -
); +
+ ); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/User/Login/Login.jsx b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/User/Login/Login.jsx index 3b93e9e1b4c..5987730bab1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/User/Login/Login.jsx +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/User/Login/Login.jsx @@ -20,10 +20,10 @@ import qs from 'qs'; import PropTypes from 'prop-types'; import React, {Component} from 'react'; import Checkbox from 'material-ui/Checkbox'; +import TextField from 'material-ui/TextField'; import {Redirect, Switch} from 'react-router-dom'; import RaisedButton from 'material-ui/RaisedButton'; import {Card, CardActions, CardTitle} from 'material-ui/Card'; -import {TextValidator, ValidatorForm} from 'react-material-ui-form-validator'; //todo: remove the {TextValidator, ValidatorForm} and implement it manually. @@ -40,36 +40,43 @@ class Login extends Component { constructor() { super(); this.state = { - isLoggedIn: true, + isLoggedIn: false, referrer: "/", userName: "", password: "", - rememberMe: true + rememberMe: true, + errors: {} } } + componentWillMount() { + console.log("IN Login") + } + componentDidMount() { - let queryString = this.props.location.search; - console.log(queryString); - queryString = queryString.replace(/^\?/, ''); - /* With QS version up we can directly use {ignoreQueryPrefix: true} option */ - let params = qs.parse(queryString); - if (params.referrer) { - this.setState({referrer: params.referrer}); - } + console.log("in Login") + // let queryString = this.props.location.search; + // console.log(queryString); + // queryString = queryString.replace(/^\?/, ''); + // /* With QS version up we can directly use {ignoreQueryPrefix: true} option */ + // let params = qs.parse(queryString); + // if (params.referrer) { + // this.setState({referrer: params.referrer}); + // } } - handleLogin(event) { + _handleLogin(event) { event.preventDefault(); + this._validateForm(); } /** * Handles the username field change event. * */ - onUserNameChange(event) { + _onUserNameChange(event, value) { this.setState( { - userName: event.target.value + userName: value } ); } @@ -77,10 +84,10 @@ class Login extends Component { /** * Handles the password field change event. * */ - onPasswordChange(event) { + _onPasswordChange(event, value) { this.setState( { - password: event.target.value + password: value } ); } @@ -88,7 +95,7 @@ class Login extends Component { /** * Handles the remember me check. * */ - handleRememberMe() { + _handleRememberMe() { this.setState( { rememberMe: !this.state.rememberMe @@ -96,6 +103,22 @@ class Login extends Component { ); } + /** + * Validate the login form. + * */ + _validateForm() { + let errors = {}; + if (!this.state.password) { + errors["passwordError"] = "Password is Required"; + } + + if (!this.state.userName) { + errors["userNameError"] = "User Name is Required"; + } + + this.setState({errors: errors}, console.log(errors)); + } + render() { if (!this.state.isLoggedIn) { @@ -107,37 +130,32 @@ class Login extends Component { - console.log(errors)}> - + -
-
+ -
+ onChange={this._onPasswordChange.bind(this)} + />

-
+
);