forked from community/device-mgt-core
commit
d0a52bec98
@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<version>3.0.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.wso2.carbon.device.application.mgt.authhandler</artifactId>
|
||||
<version>3.0.46-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>WSO2 Carbon - Application Management Authentication Handler API</name>
|
||||
<description>Proxy Service for Authentication Handling in WSO2 App Manager.</description>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<packagingExcludes>WEB-INF/lib/*cxf*.jar</packagingExcludes>
|
||||
<warName>auth#application-mgt#v1.0</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<defaultGoal>compile</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<copy todir="${basedir}/../../../repository/deployment/server/webapps" overwrite="true">
|
||||
<fileset dir="${basedir}/target">
|
||||
<include name="auth#application-mgt#v1.0.war" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>client</id>
|
||||
<build>
|
||||
<defaultGoal>test</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxws</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-transports-http</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json.wso2</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec.wso2</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-core -->
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>9.5.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-jackson -->
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jackson</artifactId>
|
||||
<version>9.5.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-jackson -->
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
<version>9.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.service;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
@Path("/auth")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface AuthHandlerService {
|
||||
|
||||
@POST
|
||||
@Path("/login")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
Response login(@QueryParam("userName") String userName, @QueryParam("password") String password);
|
||||
|
||||
@POST
|
||||
@Path("/refresh")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
Response refresh(@QueryParam("refreshToken") String refreshToken, @QueryParam("clientId") String clientId,
|
||||
@QueryParam("clientSecret") String clientSecret);
|
||||
|
||||
@POST
|
||||
@Path("/logout")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
Response logout(@QueryParam("token") String token, @QueryParam("clientId") String clientId,
|
||||
@QueryParam("clientSecret") String clientSecret);
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.service.impl;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.auth.BasicAuthRequestInterceptor;
|
||||
import feign.jackson.JacksonDecoder;
|
||||
import feign.jackson.JacksonEncoder;
|
||||
import feign.jaxrs.JAXRSContract;
|
||||
import org.json.JSONObject;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.service.AuthHandlerService;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.Constants;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.ApiApplicationKey;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.ApiApplicationRegistrationService;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.ApiRegistrationProfile;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.TokenIssuerService;
|
||||
import org.wso2.carbon.device.application.mgt.auth.handler.util.dto.TokenRevokeService;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@Path("/auth")
|
||||
public class AuthHandlerServiceImpl implements AuthHandlerService {
|
||||
|
||||
private TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private Client disableHostnameVerification = new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String s, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@POST
|
||||
@Path("/login")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Override
|
||||
public Response login(@QueryParam("userName") String userName, @QueryParam("password") String password) {
|
||||
|
||||
try {
|
||||
ApiApplicationRegistrationService apiApplicationRegistrationService = Feign.builder()
|
||||
.client(disableHostnameVerification)
|
||||
.requestInterceptor(new BasicAuthRequestInterceptor(userName, password))
|
||||
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
|
||||
.target(ApiApplicationRegistrationService.class, Constants.API_APPLICATION_ENDPOINT);
|
||||
ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile();
|
||||
apiRegistrationProfile.setApplicationName(Constants.APPLICATION_NAME);
|
||||
apiRegistrationProfile.setIsAllowedToAllDomains(false);
|
||||
apiRegistrationProfile.setIsMappingAnExistingOAuthApp(false);
|
||||
apiRegistrationProfile.setTags(Constants.TAGS);
|
||||
ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile);
|
||||
|
||||
//PasswordGrantType
|
||||
TokenIssuerService tokenIssuerService = Feign.builder().client(disableHostnameVerification)
|
||||
.requestInterceptor(new BasicAuthRequestInterceptor(apiApplicationKey.getConsumerKey(),
|
||||
apiApplicationKey.getConsumerSecret()))
|
||||
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
|
||||
.target(TokenIssuerService.class, Constants.TOKEN_ENDPOINT);
|
||||
AccessTokenInfo accessTokenInfo = tokenIssuerService.getToken(Constants.PASSWORD_GRANT_TYPE,
|
||||
userName, password, Constants.SCOPES);
|
||||
JSONObject loginInfo = new JSONObject(accessTokenInfo);
|
||||
loginInfo.append(Constants.USER_NAME, userName);
|
||||
loginInfo.append(Constants.APPLICATION_INFO, new JSONObject(apiApplicationKey));
|
||||
return Response.status(200).entity(loginInfo.toString()).build();
|
||||
} catch (Exception e) {
|
||||
return Response.status(500).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/refresh")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Override
|
||||
public Response refresh(@QueryParam("refresh_token") String refresh_token, @QueryParam("clientId") String clientId,
|
||||
@QueryParam("clientSecret") String clientSecret) {
|
||||
try {
|
||||
TokenIssuerService tokenIssuerService = Feign.builder().client(disableHostnameVerification)
|
||||
.requestInterceptor(new BasicAuthRequestInterceptor(clientId, clientSecret))
|
||||
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
|
||||
.target(TokenIssuerService.class, Constants.TOKEN_ENDPOINT);
|
||||
AccessTokenInfo accessTokenInfo = tokenIssuerService.getRefreshToken(Constants.REFRESH_GRANT_TYPE, refresh_token);
|
||||
return Response.status(200).entity(new JSONObject(accessTokenInfo)).build();
|
||||
} catch (Exception e) {
|
||||
return Response.status(500).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/logout")
|
||||
@Override
|
||||
public Response logout(@QueryParam("token") String token, @QueryParam("clientId") String clientId,
|
||||
@QueryParam("clientSecret") String clientSecret) {
|
||||
try {
|
||||
TokenRevokeService tokenRevokeService = Feign.builder().client(disableHostnameVerification)
|
||||
.requestInterceptor(new BasicAuthRequestInterceptor(clientId, clientSecret))
|
||||
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
|
||||
.target(TokenRevokeService.class, Constants.TOKEN_ENDPOINT);
|
||||
tokenRevokeService.revoke(token);
|
||||
|
||||
return Response.status(200).build();
|
||||
} catch (Exception e) {
|
||||
return Response.status(500).build();
|
||||
}
|
||||
}
|
||||
|
||||
private SSLSocketFactory getTrustedSSLSocketFactory() {
|
||||
try {
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
return sc.getSocketFactory();
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util;
|
||||
|
||||
//TODO: Remove hardcoded localhost and ports
|
||||
public class Constants {
|
||||
public static String 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 perm:platform:get";
|
||||
|
||||
public static String[] TAGS = {"device_management"};
|
||||
public static String USER_NAME = "userName";
|
||||
public static String APPLICATION_NAME = "applicationmgt_publisher";
|
||||
public static String TOKEN_ENDPOINT = "https://localhost:8243";
|
||||
public static String PASSWORD_GRANT_TYPE = "password";
|
||||
public static String REFRESH_GRANT_TYPE = "refresh_token";
|
||||
public static String API_APPLICATION_ENDPOINT = "https://localhost:9443/api-application-registration/";
|
||||
public static String APPLICATION_INFO = "application_info";
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* This hold access token info that returned from the api call
|
||||
*/
|
||||
@XmlRootElement(name = "AccessTokenInfo")
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class AccessTokenInfo {
|
||||
|
||||
@XmlElement(required = true, name = "token_type")
|
||||
private String token_type;
|
||||
|
||||
@XmlElement(required = true, name = "expires_in")
|
||||
private String expires_in;
|
||||
|
||||
@XmlElement(required = true, name = "refresh_token")
|
||||
private String refresh_token;
|
||||
|
||||
@XmlElement(required = true, name = "access_token")
|
||||
private String access_token;
|
||||
|
||||
public AccessTokenInfo() {}
|
||||
|
||||
public String getToken_type() {
|
||||
return token_type;
|
||||
}
|
||||
|
||||
public void setToken_type(String token_type) {
|
||||
this.token_type = token_type;
|
||||
}
|
||||
|
||||
public String getExpires_in() {
|
||||
return expires_in;
|
||||
}
|
||||
|
||||
public void setExpires_in(String expires_in) {
|
||||
this.expires_in = expires_in;
|
||||
}
|
||||
|
||||
public String getRefresh_token() {
|
||||
return refresh_token;
|
||||
}
|
||||
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
public String getAccess_token() {
|
||||
return access_token;
|
||||
}
|
||||
|
||||
public void setAccess_token(String access_token) {
|
||||
this.access_token = access_token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return access_token + " " + token_type + " " + refresh_token + " ";
|
||||
}
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* This holds api application consumer key and secret.
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class ApiApplicationKey {
|
||||
@XmlElement
|
||||
private String client_id;
|
||||
@XmlElement
|
||||
private String client_secret;
|
||||
|
||||
public String getConsumerKey() {
|
||||
return this.client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String consumerKey) {
|
||||
this.client_id = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return this.client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String consumerSecret) {
|
||||
this.client_secret = consumerSecret;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This is the application registration service that exposed for apimApplicationRegistration
|
||||
*/
|
||||
|
||||
@Path("/register")
|
||||
public interface ApiApplicationRegistrationService {
|
||||
|
||||
/**
|
||||
* This method is used to register api application
|
||||
*
|
||||
* @param registrationProfile contains the necessary attributes that are needed in order to register an app.
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ApiApplicationKey register(ApiRegistrationProfile registrationProfile);
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class ApiRegistrationProfile {
|
||||
|
||||
public String applicationName;
|
||||
public String tags[];
|
||||
public boolean isAllowedToAllDomains;
|
||||
public String consumerKey;
|
||||
public String consumerSecret;
|
||||
public boolean isMappingAnExistingOAuthApp;
|
||||
|
||||
public String getApplicationName() {
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
public void setApplicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(String[] tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public boolean isAllowedToAllDomains() {
|
||||
return isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
|
||||
this.isAllowedToAllDomains = isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public boolean isMappingAnExistingOAuthApp() {
|
||||
return isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
|
||||
this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public String getConsumerKey() {
|
||||
return consumerKey;
|
||||
}
|
||||
|
||||
public void setConsumerKey(String consumerKey) {
|
||||
this.consumerKey = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return consumerSecret;
|
||||
}
|
||||
|
||||
public void setConsumerSecret(String consumerSecret) {
|
||||
this.consumerSecret = consumerSecret;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
|
||||
import static feign.Util.checkNotNull;
|
||||
|
||||
/**
|
||||
* This is a request interceptor to add oauth token header.
|
||||
*/
|
||||
public class OAuthRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
private final String headerValue;
|
||||
|
||||
/**
|
||||
* Creates an interceptor that authenticates all requests with the specified OAUTH token
|
||||
*
|
||||
* @param token the access token to use for authentication
|
||||
*/
|
||||
public OAuthRequestInterceptor(String token) {
|
||||
checkNotNull(token, "access_token");
|
||||
headerValue = "Bearer " + token;
|
||||
}
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
template.header("Authorization", headerValue);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class RegistrationProfile {
|
||||
|
||||
public String callbackUrl;
|
||||
public String clientName;
|
||||
public String tokenScope;
|
||||
public String owner;
|
||||
public String grantType;
|
||||
public String applicationType;
|
||||
|
||||
private static final String TAG = RegistrationProfile.class.getSimpleName();
|
||||
|
||||
public String getCallbackUrl() {
|
||||
return callbackUrl;
|
||||
}
|
||||
|
||||
public void setCallbackUrl(String callBackUrl) {
|
||||
this.callbackUrl = callBackUrl;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public String getTokenScope() {
|
||||
return tokenScope;
|
||||
}
|
||||
|
||||
public void setTokenScope(String tokenScope) {
|
||||
this.tokenScope = tokenScope;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getGrantType() {
|
||||
return grantType;
|
||||
}
|
||||
|
||||
public void setGrantType(String grantType) {
|
||||
this.grantType = grantType;
|
||||
}
|
||||
|
||||
public String getApplicationType() {
|
||||
return applicationType;
|
||||
}
|
||||
|
||||
public void setApplicationType(String applicationType) {
|
||||
this.applicationType = applicationType;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This hold the api definition that is used as a contract with netflix feign.
|
||||
*/
|
||||
@Path("/token")
|
||||
public interface TokenIssuerService {
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
|
||||
@QueryParam("password") String password, @QueryParam("scope") String scope);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getRefreshToken(@QueryParam("grant_type") String grantType,
|
||||
@QueryParam("refreshToken") String refreshToken);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.auth.handler.util.dto;
|
||||
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* Api definition for token revoke that will be used as Feign contract.
|
||||
* */
|
||||
@Path("/revoke")
|
||||
public interface TokenRevokeService {
|
||||
|
||||
@POST
|
||||
Response revoke(@QueryParam("token")String accessToken);
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, 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.
|
||||
-->
|
||||
|
||||
<!-- This file contains the list of permissions that are associated with URL end points
|
||||
of the web app. Each permission should contain the name, permission path ,API path
|
||||
(URL) , HTTP method and OAUTH2 authorization scope (not-required).
|
||||
When defining dynamic paths for APIs, path variables are denoted by '*' notation.
|
||||
For ex:
|
||||
Actual API endpoint: devicemgt_admin/1.0.0/devices/{device-id}
|
||||
URL to be represented here: /devices/*
|
||||
NOTE: All the endpoints of the web app should be available in this file. Otherwise
|
||||
it will result 403 error at the runtime.
|
||||
-->
|
||||
<PermissionConfiguration>
|
||||
<APIVersion></APIVersion>
|
||||
|
||||
<!-- Application related permissions -->
|
||||
|
||||
</PermissionConfiguration>
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!--
|
||||
~ Copyright (c) 2015, 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
|
||||
-->
|
||||
<Classloading xmlns="http://wso2.org/projects/as/classloading">
|
||||
|
||||
<!-- Parent-first or child-first. Default behaviour is child-first.-->
|
||||
<ParentFirst>false</ParentFirst>
|
||||
|
||||
<!--
|
||||
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
|
||||
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
|
||||
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
|
||||
-->
|
||||
<Environments>CXF,Carbon</Environments>
|
||||
</Classloading>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
|
||||
|
||||
<jaxrs:server id="applicationMgtAuthService" address="/">
|
||||
<jaxrs:serviceBeans>
|
||||
<ref bean="applicationMgtAuthServiceBean"/>
|
||||
</jaxrs:serviceBeans>
|
||||
</jaxrs:server>
|
||||
|
||||
<bean id="applicationMgtAuthServiceBean"
|
||||
class="org.wso2.carbon.device.application.mgt.auth.handler.service.impl.AuthHandlerServiceImpl"/>
|
||||
|
||||
|
||||
</beans>
|
||||
|
||||
|
@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, 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.
|
||||
-->
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
<display-name>Application Management Auth Webapp</display-name>
|
||||
<servlet>
|
||||
<description>JAX-WS/JAX-RS Application Management Endpoint</description>
|
||||
<display-name>JAX-WS/JAX-RS Servlet</display-name>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<servlet-class>
|
||||
org.apache.cxf.transport.servlet.CXFServlet
|
||||
</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<session-config>
|
||||
<session-timeout>60</session-timeout>
|
||||
</session-config>
|
||||
<context-param>
|
||||
<param-name>doAuthentication</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<!--publish to apim-->
|
||||
<context-param>
|
||||
<param-name>managed-api-enabled</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-owner</param-name>
|
||||
<param-value>admin</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>isSharedWithAllTenants</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
|
||||
<filter>
|
||||
<filter-name>CorsFilter</filter-name>
|
||||
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>cors.allowed.origins</param-name>
|
||||
<param-value>*</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>cors.allowed.methods</param-name>
|
||||
<param-value>GET,POST,DELETE,PUT</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>cors.allowed.headers</param-name>
|
||||
<param-value>Content-Type</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>HttpHeaderSecurityFilter</filter-name>
|
||||
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>hstsEnabled</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>ContentTypeBasedCachePreventionFilter</filter-name>
|
||||
<filter-class>org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>patterns</param-name>
|
||||
<param-value>text/html" ,application/json" ,text/plain</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>filterAction</param-name>
|
||||
<param-value>enforce</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>httpHeaders</param-name>
|
||||
<param-value>Cache-Control: no-store, no-cache, must-revalidate, private</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>HttpHeaderSecurityFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>ContentTypeBasedCachePreventionFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>CorsFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
</web-app>
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.application.mgt.common;
|
||||
|
||||
/**
|
||||
* This represents a image artifact of a application. Icon, Screen-shot or Banner.
|
||||
* It consists of a name, type and base64 encoded string format of the image.
|
||||
*/
|
||||
public class ImageArtifact {
|
||||
private String name;
|
||||
private String type;
|
||||
private String encodedImage;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getEncodedImage() {
|
||||
return encodedImage;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setEncodedImage(String encodedImage) {
|
||||
this.encodedImage = encodedImage;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,6 @@
|
||||
{
|
||||
"theme": {
|
||||
"type": "default",
|
||||
"value": "lightBaseTheme"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 443 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.image {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
height: auto;
|
||||
transition: .5s ease;
|
||||
backface-visibility: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-content {
|
||||
transition: .5s ease;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background-color: rgba(243, 243, 243, 0.43);
|
||||
border-radius: 50%;
|
||||
border: solid 1px #ffffff;
|
||||
transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%)
|
||||
}
|
||||
|
||||
.image-container:hover .image {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.image-container:hover .btn-content {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,483 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Body Styling */
|
||||
body {
|
||||
width: 100%;
|
||||
font-family: Roboto sans-serif;
|
||||
}
|
||||
|
||||
/* Login page styles*/
|
||||
#userName {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#password {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#login-btn {
|
||||
border-radius: 0;
|
||||
background-color: navy;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#login-container {
|
||||
width: 50%;
|
||||
margin: 0 auto
|
||||
}
|
||||
|
||||
#login-card {
|
||||
border-radius: 0;
|
||||
background-color: #BaBaBa;
|
||||
}
|
||||
|
||||
/* Base layout container */
|
||||
#container {
|
||||
background-color: #ffffff;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Base layout header content*/
|
||||
#header-content {
|
||||
height: 125px;
|
||||
width: 100%;
|
||||
margin: 0 10px 0 0;
|
||||
background-color: #3b33bd;
|
||||
position: fixed; /* Set the navbar to fixed position */
|
||||
top: 0; /* Position the navbar at the top of the page */
|
||||
z-index: 2;
|
||||
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
/* Contains the header styles.*/
|
||||
#header {
|
||||
margin: 16px 16px 20px 16px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#header-text {
|
||||
color: #ffffff;
|
||||
font-size: 25px;
|
||||
top: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* The buttons in the header (User and Notification)*/
|
||||
#header-btn-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.btn-header {
|
||||
margin-top: 15px;
|
||||
margin-right: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Search box styles */
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
#search-box {
|
||||
display: flex;
|
||||
color: #a8a8a8;
|
||||
position: relative;
|
||||
float: right;
|
||||
top: 75px;
|
||||
left: 80px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
#search {
|
||||
position: relative;
|
||||
color: white;
|
||||
background-color: transparent;
|
||||
left: 15px;
|
||||
top: 0px;
|
||||
height: 25px;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 0%;
|
||||
}
|
||||
|
||||
/* Application Add button */
|
||||
#add-btn-container {
|
||||
position: absolute;
|
||||
left: 12%;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
/* Holds the app publisher pages. */
|
||||
#application-content {
|
||||
height: auto;
|
||||
width: 80%;
|
||||
margin: 150px auto;
|
||||
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
padding: 10px 10px 10px 10px;
|
||||
}
|
||||
|
||||
.stepper-header {
|
||||
width: 100%;
|
||||
border-bottom: solid 1px cornflowerblue;
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.platform-link-placeholder {
|
||||
color: #888888;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#application-list {
|
||||
margin-top: 20px;
|
||||
transition: margin-right .5s;
|
||||
}
|
||||
|
||||
#app-image-screenshot {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#app-image-icon {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#app-image-banner {
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.application-create-banner-dropzone {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
border-radius: 5%;
|
||||
position: relative;
|
||||
background-color: rgba(157, 159, 157, 0.53);
|
||||
border: dashed #888888 2px;
|
||||
}
|
||||
|
||||
.application-create-banner-dropzone i {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
left: 145px;
|
||||
}
|
||||
|
||||
.application-create-screenshot-dropzone {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin: 0 5px 0 5px;
|
||||
border-radius: 10%;
|
||||
position: relative;
|
||||
background-color: rgba(157, 159, 157, 0.53);
|
||||
border: dashed #888888 2px;
|
||||
}
|
||||
|
||||
.application-create-screenshot-dropzone i {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
left: 65px;
|
||||
}
|
||||
|
||||
.application-create-icon-dropzone {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border-radius: 10%;
|
||||
position: relative;
|
||||
background-color: rgba(157, 159, 157, 0.53);
|
||||
border: dashed #888888 2px;
|
||||
}
|
||||
|
||||
.application-create-icon-dropzone i {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
left: 65px;
|
||||
}
|
||||
|
||||
#screenshot-container {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
#app-icon-container {
|
||||
height: 300px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
#modal-body-content {
|
||||
max-height: 700px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#img-btn-screenshot {
|
||||
margin: 0 5px 0 5px;
|
||||
}
|
||||
|
||||
#app-create-modal {
|
||||
max-width: 700px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
#store {
|
||||
border: none;
|
||||
border-bottom: solid #BDBDBD 1px;
|
||||
border-radius: 0px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#version {
|
||||
border: none;
|
||||
border-bottom: solid #BDBDBD 1px;
|
||||
border-radius: 0px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#app-release-switch-content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#app-release-switch-label {
|
||||
position: absolute;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#app-release-switch-switch {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.image-sub-title {
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
/* Application View */
|
||||
#application-view-content {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#application-view-row {
|
||||
margin: 10px 10px 20px 20px;
|
||||
}
|
||||
|
||||
#app-icon {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
border: solid 1px black;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.app-updated-date {
|
||||
color: #888888;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.app-install-count {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.app-details-tbl {
|
||||
outline: none;
|
||||
border-color: #2196F3;
|
||||
}
|
||||
|
||||
.app-details-tbl tr {
|
||||
margin: 20px 0 0 0;
|
||||
}
|
||||
|
||||
.app-details-tbl td {
|
||||
margin-left: 10px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
/* Application Edit Base Layout */
|
||||
#application-edit-header {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
border-bottom: solid 1px #d8d8d8;
|
||||
}
|
||||
|
||||
.application-header-text {
|
||||
margin: 10px 0px 0px 10px;
|
||||
}
|
||||
|
||||
#save-btn-content {
|
||||
float: right;
|
||||
|
||||
}
|
||||
|
||||
#app-save-btn {
|
||||
border-radius: 0%;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
margin: 5px 5px 5px 0px;
|
||||
height: 70%;
|
||||
width: 50%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.save-btn:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*Tab styling*/
|
||||
div.tab {
|
||||
float: left;
|
||||
border-right: 1px solid #d8d8d8;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Style the tab buttons */
|
||||
div.tab button {
|
||||
display: block;
|
||||
background-color: inherit;
|
||||
color: black;
|
||||
padding: 15px 16px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* Change background color of buttons on hover */
|
||||
div.tab button:hover {
|
||||
background-color: #ddd6d7;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Create an active/current "tab button" class */
|
||||
div.tab button.active {
|
||||
background-color: #1b3bcc;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
#application-edit-main-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#application-edit-outer-content {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#application-edit-content {
|
||||
margin: 5px 10px 5px 10px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
#app-edit-content {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.back-to-app {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.back-to-app i {
|
||||
padding: 10px 10px 10px 10px;
|
||||
}
|
||||
|
||||
.back-to-app:hover {
|
||||
cursor: pointer;
|
||||
background-color: #dedede;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
/* Create Release and Release management */
|
||||
.release-header {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.release-create {
|
||||
height: 150px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.release-detail-content {
|
||||
width: 100%;
|
||||
margin-top: 20%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
float: right;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.release-content {
|
||||
height: 180px;
|
||||
width: 95%;
|
||||
border: dashed 1px #626262;
|
||||
border-radius: 2%;
|
||||
position: relative;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
|
||||
.release-content:after {
|
||||
content: "";
|
||||
letter-spacing: 4px;
|
||||
}
|
||||
|
||||
.release {
|
||||
margin: 30px 10px 20px 30px;
|
||||
}
|
||||
|
||||
.no-release-content {
|
||||
position: absolute;
|
||||
margin-top: 10px;
|
||||
left: 40%;
|
||||
}
|
||||
|
||||
.button-add:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.release-inner {
|
||||
margin-top: 5%;
|
||||
}
|
||||
|
||||
/* Application Edit General Info */
|
||||
.app-edit-general-info {
|
||||
margin-top: 20px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.save-info {
|
||||
float: right;
|
||||
margin-bottom: 10px;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.app-view-drawer {
|
||||
height: 100%; /* 100% Full-height */
|
||||
width: 0; /* 0 width - change this with JavaScript */
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1; /* Stay on top */
|
||||
top: 8%;
|
||||
right: 0%;
|
||||
background-color: #ffffff;
|
||||
overflow-x: hidden; /* Disable horizontal scroll */
|
||||
padding-top: 60px; /* Place content 60px from the top */
|
||||
transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */
|
||||
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.app-view-drawer a {
|
||||
padding: 8px 8px 8px 32px;
|
||||
text-decoration: none;
|
||||
font-size: 25px;
|
||||
color: #818181;
|
||||
display: block;
|
||||
transition: 0.3s
|
||||
}
|
||||
|
||||
|
||||
/* Position and style the close button (top right corner) */
|
||||
.app-view-drawer .closebtn {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 25px;
|
||||
font-size: 36px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.drawer-close-btn {
|
||||
height: 40px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.drawer-close-btn:hover {
|
||||
cursor: pointer;
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
|
||||
#main {
|
||||
transition: margin-left .5s;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
|
||||
@media screen and (max-height: 450px) {
|
||||
.sidenav {padding-top: 15px;}
|
||||
.sidenav a {font-size: 18px;}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.btn-circle {
|
||||
color: white;
|
||||
position: relative;
|
||||
background-color: #e65100;
|
||||
border-radius: 50%;
|
||||
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.btn-circle i {
|
||||
position: absolute;
|
||||
margin-top: 37%;
|
||||
margin-left: 37%;
|
||||
}
|
||||
|
||||
.small {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.medium {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.btn-circle:hover {
|
||||
cursor: pointer;
|
||||
background-color: rgb(255, 93, 2);
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: blue;
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
.notification-app-icon {
|
||||
border-radius: 50%;
|
||||
border: solid 1px black;
|
||||
}
|
||||
|
||||
.small {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.medium {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#notification-view-content {
|
||||
width: 50%;
|
||||
border: solid 1px black;
|
||||
margin: 0 auto;
|
||||
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
#notification-content {
|
||||
margin: 20px 10px 20px 10px;
|
||||
}
|
||||
|
||||
#app-reject-msg {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: #888888;
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {display:none;}
|
||||
|
||||
/* The slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(16px);
|
||||
-ms-transform: translateX(16px);
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
import Axios from 'axios';
|
||||
import AuthHandler from './authHandler';
|
||||
import Constants from '../common/constants';
|
||||
import Helper from './helpers/appMgtApiHelpers';
|
||||
|
||||
/**
|
||||
* Api definitions related to application management.
|
||||
* TODO: Work to be done on Application release.
|
||||
* */
|
||||
export default class ApplicationMgtApi {
|
||||
|
||||
/**
|
||||
* 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 applicationData, the proper application object will be created and send it to the api.
|
||||
* */
|
||||
static createApplication(applicationData) {
|
||||
let {application, images} = Helper.buildApplication(applicationData);
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
console.log(application);
|
||||
console.log(images);
|
||||
Axios.post(Constants.appManagerEndpoints.CREATE_APP, application, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload the image artifacts (banner, icon, screenshots) related to the application.
|
||||
* @param appId: The application uuid of the application which the images should be uploaded to.
|
||||
* @param images: The images object. This contains icon, banner and screenshots.
|
||||
* */
|
||||
static uploadImageArtifacts(appId, images) {
|
||||
let formData = new FormData();
|
||||
formData.append('icon', images.icon);
|
||||
formData.append('banner', images.banner);
|
||||
formData.append('screenshot', images.screenshots);
|
||||
console.log("Image", formData);
|
||||
const headers = AuthHandler.createAuthenticationHeaders("multipart/form-data");
|
||||
return Axios.post(Constants.appManagerEndpoints.UPLOAD_IMAGE_ARTIFACTS + appId, formData, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle application release process.
|
||||
* */
|
||||
static releaseApplication(appId) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote the current life cycle state of the application.
|
||||
* @param appId: The uuid of the application which the state should be updated.
|
||||
* @param nextState: The next lifecycle state that the application can be updated to.
|
||||
*
|
||||
* URL Pattern : /application/1.0/
|
||||
* */
|
||||
static updateLifeCycleState(appId, nextState) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next possible state, which the application can be promoted to.
|
||||
* @param appId: The application uuid.
|
||||
*/
|
||||
static getNextLifeCycleState(appId) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit created application.
|
||||
* @param applicationData: The modified application data.
|
||||
* */
|
||||
static editApplication(applicationData) {
|
||||
let app = Helper.buildApplication(applicationData).application;
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.put(Constants.appManagerEndpoints.CREATE_APP, app, {headers: headers});
|
||||
}
|
||||
|
||||
static getApplicationArtifacts(appId, artifactName) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("image/png");
|
||||
return Axios.get(Constants.appManagerEndpoints.GET_IMAGE_ARTIFACTS + appId + "?name=" + artifactName,
|
||||
{headers: headers});
|
||||
}
|
||||
|
||||
static editApplicationArtifacts(appId, images) {
|
||||
let formData = new FormData();
|
||||
formData.append('icon', images.icon);
|
||||
formData.append('banner', images.banner);
|
||||
formData.append('screenshot', images.screenshots);
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.put(Constants.appManagerEndpoints.UPLOAD_IMAGE_ARTIFACTS + appId, formData, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the created applications for the user.
|
||||
* @return Object: The response object from the axios post.
|
||||
* */
|
||||
static getApplications() {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.get(Constants.appManagerEndpoints.GET_ALL_APPS, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific application.
|
||||
* @param appId: The application Id.
|
||||
* */
|
||||
static getApplication(appId) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.get(Constants.appManagerEndpoints.GET_ALL_APPS + appId, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specified application.
|
||||
* @param appId: The id of the application which is to be deleted.
|
||||
* */
|
||||
static deleteApplication(appId) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.delete(Constants.appManagerEndpoints.GET_ALL_APPS + appId, {headers: headers});
|
||||
}
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
import Axios from 'axios';
|
||||
import User from './data/user';
|
||||
import Utils from './data/utils';
|
||||
import Constants from "../common/constants";
|
||||
|
||||
/**
|
||||
* Handles all tasks related to Authentication and Authorization.
|
||||
* Generate access tokens, verify the user has necessary permissions etc.
|
||||
* */
|
||||
class AuthHandler {
|
||||
|
||||
/**
|
||||
* Sends a request to the auth handler endpoint (auth/application-mgt/v1.0/auth/login) and generate token pair.
|
||||
* @param userName: The user name of the user.
|
||||
* @param password: The user password.
|
||||
* @return Object: The response object from the axios post.
|
||||
* */
|
||||
static login(userName, password) {
|
||||
const headers = {"Content-type": "application/json"};
|
||||
let login_promise =
|
||||
Axios.post(Constants.userConstants.LOGIN_URL+"?userName=" + userName+ "&password=" + password,
|
||||
null, {headers: headers});
|
||||
|
||||
login_promise.then(response => {
|
||||
console.log(response);
|
||||
const userName = response.data.userName;
|
||||
const validityPeriod = response.data.expires_in; // In seconds
|
||||
const WSO2_IOT_TOKEN = response.data.access_token;
|
||||
const refreshToken = response.data.refresh_token;
|
||||
const clientId = response.data.application_info[0].consumerKey;
|
||||
const clientSecret = response.data.application_info[0].consumerSecret;
|
||||
|
||||
const user = new User(userName, clientId, clientSecret, validityPeriod);
|
||||
console.log(user);
|
||||
user.setAuthToken(WSO2_IOT_TOKEN, validityPeriod);
|
||||
let expiresIn = Date.now() + (validityPeriod * 1000);
|
||||
localStorage.setItem("expiresIn", expiresIn);
|
||||
AuthHandler.setUser(user);
|
||||
}
|
||||
);
|
||||
return login_promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Persists the user object in browser's local storage.
|
||||
* @param user: The user object.
|
||||
* */
|
||||
static setUser(user) {
|
||||
if (!user instanceof User) {
|
||||
throw "Invalid user object";
|
||||
}
|
||||
user.created = Date.now();
|
||||
localStorage.setItem(Constants.userConstants.WSO2_USER, JSON.stringify(user.toJson()));
|
||||
/* TODO: IMHO it's better to get this key (`wso2_user`) from configs */
|
||||
}
|
||||
|
||||
static unauthorizedErrorHandler(error_response) {
|
||||
if (error_response.status !== 401) { /* Skip unrelated response code to handle in unauthorizedErrorHandler*/
|
||||
throw error_response;
|
||||
/* re throwing the error since we don't handle it here and propagate to downstream error handlers in catch chain*/
|
||||
}
|
||||
let message = "The session has expired" + ".<br/> You will be redirect to the login page ...";
|
||||
if (true) {
|
||||
alert(message);
|
||||
} else {
|
||||
throw error_response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logged in user.
|
||||
* @return User: The logged in user object.
|
||||
* */
|
||||
static getUser() {
|
||||
const userData = localStorage.getItem(Constants.userConstants.WSO2_USER);
|
||||
const partialToken = Utils.getCookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||
|
||||
if (!(userData && partialToken)) {
|
||||
return null;
|
||||
}
|
||||
return User.fromJson(JSON.parse(userData));
|
||||
}
|
||||
|
||||
isLoggedIn() {
|
||||
|
||||
}
|
||||
|
||||
static logout() {
|
||||
const user = AuthHandler.getUser();
|
||||
const clientId = user.getClientId();
|
||||
const clientSecret = user.getClientSecret();
|
||||
const token = user.getAuthToken();
|
||||
const headers = {"Content-type": "application/json"};
|
||||
|
||||
let login_promise = Axios.post(Constants.userConstants.LOGOUT_URL+"?token=" + token + "&clientId=" + clientId
|
||||
+ "&clientSecret=" + clientSecret,
|
||||
null, {headers: headers});
|
||||
login_promise.then(
|
||||
(response) => {
|
||||
Utils.delete_cookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||
localStorage.removeItem(Constants.userConstants.WSO2_USER);
|
||||
window.location = "/";
|
||||
}
|
||||
).catch(
|
||||
(err) => {
|
||||
AuthHandler.unauthorizedErrorHandler(err);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the access token is expired.
|
||||
* @return boolean: True if expired. False otherwise.
|
||||
* */
|
||||
static isTokenExpired() {
|
||||
const expiresIn = localStorage.getItem("expiresIn");
|
||||
return (expiresIn < Date.now());
|
||||
}
|
||||
|
||||
static createAuthenticationHeaders(contentType) {
|
||||
if (AuthHandler.getUser().getAuthToken()) {
|
||||
return {
|
||||
"Authorization": "Bearer " + AuthHandler.getUser().getAuthToken(),
|
||||
"Content-Type": contentType,
|
||||
};
|
||||
}
|
||||
return "User not found";
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
export default AuthHandler;
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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";
|
||||
|
||||
import Utils from './utils'
|
||||
import Constants from '../../common/constants';
|
||||
/**
|
||||
* Represent an user logged in to the application, There will be allays one user per session and
|
||||
* this user details will be persist in browser localstorage.
|
||||
*/
|
||||
export default class User {
|
||||
constructor(name, clientId, clientSecret, validityPeriod) {
|
||||
if (User._instance) {
|
||||
return User._instance;
|
||||
}
|
||||
|
||||
this._userName = name;
|
||||
this._clientId = clientId;
|
||||
this._clientSecret = clientSecret;
|
||||
this._expires = validityPeriod;
|
||||
User._instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth scopes which are available for use by this user
|
||||
* @returns {Array} : An array of scopes
|
||||
*/
|
||||
get scopes() {
|
||||
return this._scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OAuth scopes available to be used by this user
|
||||
* @param {Array} newScopes : An array of scopes
|
||||
*/
|
||||
set scopes(newScopes) {
|
||||
Object.assign(this.scopes, newScopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JS accessible access token fragment from cookie storage.
|
||||
* @returns {String|null}
|
||||
*/
|
||||
getAuthToken() {
|
||||
return Utils.getCookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||
}
|
||||
|
||||
getClientId() {
|
||||
return this._clientId;
|
||||
}
|
||||
|
||||
getClientSecret() {
|
||||
return this._clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the JavaScript accessible access token segment in cookie storage
|
||||
* @param {String} newToken : Part of the access token which needs when accessing REST API
|
||||
* @param {Number} validityPeriod : Validity period of the cookie in seconds
|
||||
*/
|
||||
setAuthToken(newToken, validityPeriod) {
|
||||
Utils.delete_cookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||
Utils.setCookie(Constants.userConstants.PARTIAL_TOKEN, newToken, validityPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user name of logged in user.
|
||||
* @return String: User name
|
||||
* */
|
||||
getUserName() {
|
||||
return this._userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide user data in JSON structure.
|
||||
* @returns {JSON} : JSON representation of the user object
|
||||
*/
|
||||
toJson() {
|
||||
return {
|
||||
name: this._userName,
|
||||
clientId: this._clientId,
|
||||
clientSecret: this._clientSecret,
|
||||
expires: this._expires
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* User utility method to create an user from JSON object.
|
||||
* @param {JSON} userJson : Need to provide user information in JSON structure to create an user object
|
||||
* @returns {User} : An instance of User(this) class.
|
||||
*/
|
||||
static fromJson(userJson) {
|
||||
const _user = new User(userJson.name);
|
||||
_user._clientId = userJson.clientId;
|
||||
_user._clientSecret = userJson.clientSecret;
|
||||
_user._expires = userJson.expires;
|
||||
|
||||
console.log(_user);
|
||||
return _user;
|
||||
}
|
||||
}
|
||||
|
||||
User._instance = null; // A private class variable to preserve the single instance of a swaggerClient
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility class for Publisher application
|
||||
*/
|
||||
class PublisherUtils {
|
||||
|
||||
/**
|
||||
* TODO: Remove this method one the initial phase is done, This is used to continue the API class until the login page is create
|
||||
* @returns {promise}
|
||||
*/
|
||||
// static autoLogin() {
|
||||
// let auth = new AuthManager();
|
||||
// return auth.authenticateUser('admin', 'admin');
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get JavaScript accessible cookies saved in browser, by giving the cooke name.
|
||||
* @param {String} name : Name of the cookie which need to be retrived
|
||||
* @returns {String|null} : If found a cookie with given name , return its value,Else null value is returned
|
||||
*/
|
||||
static getCookie(name) {
|
||||
let pairs = document.cookie.split(";");
|
||||
let cookie = null;
|
||||
for (let pair of pairs) {
|
||||
pair = pair.split("=");
|
||||
let cookie_name = pair[0].trim();
|
||||
let value = encodeURIComponent(pair[1]);
|
||||
if (cookie_name === name) {
|
||||
cookie = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a browser cookie given its name
|
||||
* @param {String} name : Name of the cookie which need to be deleted
|
||||
*/
|
||||
static delete_cookie(name) {
|
||||
document.cookie = name + '=; Path=' + "/" + '; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cookie with given name and value assigned to it. Cookies can be only set to the same origin,
|
||||
* which the script is running
|
||||
* @param {String} name : Name of the cookie which need to be set
|
||||
* @param {String} value : Value of the cookie, expect it to be URLEncoded
|
||||
* @param {number} validityPeriod : (Optional) Validity period of the cookie in seconds
|
||||
* @param {String} path : Path which needs to set the given cookie
|
||||
* @param {boolean} secured : secured parameter is set
|
||||
*/
|
||||
static setCookie(name, value, validityPeriod, path = "/", secured = true) {
|
||||
let expires = "";
|
||||
const securedDirective = secured ? "; Secure" : "";
|
||||
if (validityPeriod) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + validityPeriod * 1000);
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
}
|
||||
|
||||
document.cookie = name + "=" + value + expires + "; path=" + path + securedDirective + validityPeriod
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object returns whether the object is empty or not
|
||||
* @param {Object} object : Any JSON object
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static isEmptyObject(object) {
|
||||
return Object.keys(object).length === 0 && object.constructor === Object
|
||||
}
|
||||
}
|
||||
|
||||
export default PublisherUtils;
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
* @return {Object, Object}: The application object and the set of images related to the application.
|
||||
* */
|
||||
static buildApplication(appData) {
|
||||
|
||||
let application = {};
|
||||
let images = {};
|
||||
|
||||
for (let step in appData) {
|
||||
let tmpData = appData[step].data.step;
|
||||
for (let prop in tmpData) {
|
||||
if (prop === 'banner' || prop === 'screenshots' || prop === 'icon') {
|
||||
images[prop] = tmpData[prop];
|
||||
} else if(prop === 'tags') {
|
||||
application[prop] = Helper.stringifyTags(tmpData[prop]);
|
||||
} else {
|
||||
application[prop] = tmpData[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
return {application, images};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String array from tags array.
|
||||
* */
|
||||
static stringifyTags(tags) {
|
||||
let tmpTags = [];
|
||||
for (let tag in tags) {
|
||||
console.log(tag);
|
||||
tmpTags.push(tags[tag].value);
|
||||
}
|
||||
|
||||
return tmpTags;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
import Axios from 'axios';
|
||||
import AuthHandler from './authHandler';
|
||||
import Constants from '../common/constants';
|
||||
|
||||
/**
|
||||
* Api definitions for Platform management.
|
||||
* */
|
||||
export default class PlatformMgtApi{
|
||||
/**
|
||||
* Create a new Platform
|
||||
* @param platformData: The platform data object.
|
||||
* */
|
||||
static createPlatform(platformData) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
Axios.post(Constants.platformManagerEndpoints.CREATE_PLATFORM, platformData, {headers: headers}).then(
|
||||
function (response) {
|
||||
console.log(response);
|
||||
}
|
||||
).catch(function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available platforms
|
||||
* */
|
||||
static getPlatforms() {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.get(Constants.platformManagerEndpoints.GET_ENABLED_PLATFORMS, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user specified platform
|
||||
* @param platformId: The identifier of the platform
|
||||
* */
|
||||
static getPlatform(platformId) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.get(Constants.platformManagerEndpoints.GET_PLATFORM + platformId, {headers: headers});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specified platform
|
||||
* @param platformId: The id of the platform which is to be deleted.
|
||||
* */
|
||||
static deletePlatform(platformId) {
|
||||
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||
return Axios.delete(Constants.platformManagerEndpoints.GET_PLATFORM + platformId, {headers: headers});
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import AuthHandler from "../../api/authHandler";
|
||||
import ApplicationCreate from '../Application/Create/ApplicationCreate';
|
||||
import {Col, Container, Input, Row,} from 'reactstrap';
|
||||
import FloatingButton from "../UIComponents/FloatingButton/FloatingButton";
|
||||
|
||||
/**
|
||||
* Base Layout:
|
||||
* App bar
|
||||
* Left Navigation
|
||||
* Middle content.
|
||||
* */
|
||||
class BaseLayout extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
notifications: 0,
|
||||
user: 'Admin',
|
||||
openModal: false
|
||||
};
|
||||
this.logout = this.logout.bind(this);
|
||||
this.closeModal = this.closeModal.bind(this);
|
||||
}
|
||||
|
||||
handleApplicationClick() {
|
||||
this.handleHistory('/assets/apps');
|
||||
}
|
||||
|
||||
handleApplicationCreateClick(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.setState({openModal: true});
|
||||
}
|
||||
|
||||
/**
|
||||
* The method to update the history.
|
||||
* to: The URL to route.
|
||||
* */
|
||||
handleHistory(to) {
|
||||
this.props.history.push(to);
|
||||
}
|
||||
|
||||
logout(event, index, value) {
|
||||
AuthHandler.logout();
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
this.setState({openModal: false});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container noGutters fluid id="container">
|
||||
<div id="header-content">
|
||||
<div id="header">
|
||||
<span id="header-text">
|
||||
WSO2 IoT App Publisher
|
||||
</span>
|
||||
<div id="header-btn-container">
|
||||
<i className="fw fw-notification btn-header"></i>
|
||||
<i className="fw fw-user btn-header"></i>
|
||||
</div>
|
||||
<div id="search-box">
|
||||
<i className="fw fw-search search-icon">
|
||||
</i>
|
||||
<Input
|
||||
id="search"
|
||||
name="search"
|
||||
placeholder={'Search for Applications'}
|
||||
onChange={(event) => console.log(event.target.value)} //TODO: Remove this
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="add-btn-container">
|
||||
<FloatingButton
|
||||
className="add-btn small"
|
||||
onClick={this.handleApplicationCreateClick.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="application-content" style={this.state.style}>
|
||||
<Row>
|
||||
<Col>
|
||||
{this.props.children}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<ApplicationCreate open={this.state.openModal} close={this.closeModal}/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BaseLayout.propTypes = {
|
||||
children: PropTypes.element
|
||||
};
|
||||
|
||||
export default withRouter(BaseLayout);
|
@ -1,234 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {Step1, Step2, Step3} from './CreateSteps';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import {Card, CardActions, CardTitle} from 'material-ui/Card';
|
||||
import {Step, StepLabel, Stepper,} from 'material-ui/Stepper';
|
||||
|
||||
|
||||
/**
|
||||
* The App Create Component.
|
||||
*
|
||||
* Application creation is handled through a Wizard. (We use Material UI Stepper.)
|
||||
*
|
||||
* In each step, data will be set to the state separately.
|
||||
* When the wizard is completed, data will be arranged and sent to the api.
|
||||
* */
|
||||
class ApplicationCreate extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.setStepData.bind(this);
|
||||
this.removeStepData.bind(this);
|
||||
this.handleSubmit.bind(this);
|
||||
this.handleCancel.bind(this);
|
||||
this.handleYes.bind(this);
|
||||
this.handleNo.bind(this);
|
||||
this.state = {
|
||||
finished: false,
|
||||
stepIndex: 0,
|
||||
stepData: [],
|
||||
isDialogOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles next button click event.
|
||||
* */
|
||||
handleNext = () => {
|
||||
console.log("Handle Next");
|
||||
const {stepIndex} = this.state;
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
finished: stepIndex >= 2,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles form submit.
|
||||
* */
|
||||
handleSubmit = () => {
|
||||
console.log(this.state.stepData);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles cancel button click event.
|
||||
* This will show a confirmation dialog to cancel the application creation process.
|
||||
* */
|
||||
handleCancel = () => {
|
||||
this.setState({isDialogOpen: true});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handled [ < Prev ] button click.
|
||||
* This clears the data in the current step and returns to the previous step.
|
||||
* */
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.removeStepData();
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves form data in each step in to the state.
|
||||
* */
|
||||
setStepData = (step, data) => {
|
||||
console.log(step, data, this.state.stepData);
|
||||
let tmpStepData = this.state.stepData;
|
||||
tmpStepData.push({step: step, data: data});
|
||||
|
||||
this.setState({stepData: tmpStepData}, this.handleNext())
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the last data point
|
||||
* */
|
||||
removeStepData = () => {
|
||||
let tempData = this.state.stepData;
|
||||
tempData.pop();
|
||||
this.setState({stepData: tempData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the Yes button in app creation cancellation dialog.
|
||||
* Clears all the form data and reset the wizard.
|
||||
* */
|
||||
handleYes = () => {
|
||||
this.setState({finished: false, stepIndex: 0, stepData: [], isDialogOpen: false});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles No button in app creation cancellation dialog.
|
||||
* Returns to the same step.
|
||||
* */
|
||||
handleNo = () => {
|
||||
this.setState({isDialogOpen: false});
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines all the Steps in the stepper. (Wizard)
|
||||
*
|
||||
* Extension Point: If any extra steps needed, follow the instructions below.
|
||||
* 1. Create the required form ./Forms directory.
|
||||
* 2. Add defined case statements.
|
||||
* 3. Define the Step in render function.
|
||||
*
|
||||
* */
|
||||
getStepContent(stepIndex) {
|
||||
switch (stepIndex) {
|
||||
case 0:
|
||||
return <Step1 handleNext={this.handleNext}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}/>;
|
||||
case 1:
|
||||
return <Step2 handleNext={this.handleNext}
|
||||
handlePrev={this.handlePrev}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}/>;
|
||||
case 2:
|
||||
return <Step3 handleFinish={this.handleNext}
|
||||
handlePrev={this.handlePrev}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}/>;
|
||||
default:
|
||||
return 'You\'re a long way from home sonny jim!';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const {finished, stepIndex} = this.state;
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
|
||||
/**
|
||||
* Defines the dialog box actions. [Yes][No]
|
||||
* */
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={this.handleYes}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="No"
|
||||
secondary={true}
|
||||
onClick={this.handleNo}
|
||||
/>,
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<div className="middle" style={{width: '95%', height: '100%', marginTop: '1%'}}>
|
||||
<Card style={{maxHeight: '700px', overflow: 'auto'}}>
|
||||
<CardTitle title="Create Application"/>
|
||||
|
||||
{/**
|
||||
* The stepper goes here.
|
||||
*/}
|
||||
<CardActions>
|
||||
<div style={{width: '100%', margin: 'auto'}}>
|
||||
<Stepper activeStep={stepIndex}>
|
||||
<Step>
|
||||
<StepLabel>Select Application Platform</StepLabel>
|
||||
</Step>
|
||||
<Step>
|
||||
<StepLabel>Enter Application Details</StepLabel>
|
||||
</Step>
|
||||
<Step>
|
||||
<StepLabel>Release</StepLabel>
|
||||
</Step>
|
||||
</Stepper>
|
||||
<div style={contentStyle}>
|
||||
{finished ? (
|
||||
<div>
|
||||
<p>Create App?</p>
|
||||
<form>
|
||||
<RaisedButton primary={true} label="Create" onClick={this.handleSubmit}/>
|
||||
<FlatButton label="Cancel" onClick={this.handleCancel}/>
|
||||
</form>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
{this.getStepContent(stepIndex)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardActions>
|
||||
</Card>
|
||||
<Dialog
|
||||
actions={actions}
|
||||
modal={false}
|
||||
open={this.state.isDialogOpen}
|
||||
onRequestClose={this.handleNo}
|
||||
>
|
||||
Do you really want to cancel?
|
||||
</Dialog>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationCreate.propTypes = {};
|
||||
|
||||
export default withRouter(ApplicationCreate);
|
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import AuthHandler from "../../../api/authHandler";
|
||||
import {Step1, Step2, Step3, Step4} from './CreateSteps/index';
|
||||
import ApplicationMgtApi from '../../../api/applicationMgtApi';
|
||||
import {Button, Col, Modal, ModalBody, ModalFooter, ModalHeader, Row} from 'reactstrap';
|
||||
|
||||
/**
|
||||
* The App Create Component.
|
||||
*
|
||||
* Application creation is handled through a Wizard. (We use Material UI Stepper.)
|
||||
*
|
||||
* In each step, data will be set to the state separately.
|
||||
* When the wizard is completed, data will be arranged and sent to the api.
|
||||
* */
|
||||
class ApplicationCreate extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.scriptId = "application-create";
|
||||
this.setStepData = this.setStepData.bind(this);
|
||||
this.removeStepData = this.removeStepData.bind(this);
|
||||
this.onSubmit = this.onSubmit.bind(this);
|
||||
this.handleCancel = this.handleCancel.bind(this);
|
||||
this.handleYes = this.handleYes.bind(this);
|
||||
this.handleNo = this.handleNo.bind(this);
|
||||
this.onPrevClick = this.onPrevClick.bind(this);
|
||||
this.onNextClick = this.onNextClick.bind(this);
|
||||
this.onClose = this.onClose.bind(this);
|
||||
this.state = {
|
||||
finished: false,
|
||||
stepIndex: 0,
|
||||
stepData: [],
|
||||
isDialogOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props, nextprops) {
|
||||
this.setState({open: props.open})
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({open: this.props.open});
|
||||
}
|
||||
|
||||
|
||||
onClose() {
|
||||
this.setState({stepIndex: 0}, this.props.close());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles next button click event.
|
||||
* */
|
||||
onNextClick() {
|
||||
console.log("Handle Next"); //TODO: Remove this
|
||||
const {stepIndex} = this.state;
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
finished: stepIndex >= 2,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles form submit.
|
||||
* */
|
||||
onSubmit() {
|
||||
let stepData = this.state.stepData;
|
||||
let applicationCreationPromise = ApplicationMgtApi.createApplication(stepData);
|
||||
applicationCreationPromise.then(response => {
|
||||
this.handleYes();
|
||||
}
|
||||
).catch(
|
||||
function (err) {
|
||||
AuthHandler.unauthorizedErrorHandler(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles cancel button click event.
|
||||
* This will show a confirmation dialog to cancel the application creation process.
|
||||
* */
|
||||
handleCancel() {
|
||||
this.setState({isDialogOpen: true});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handled [ < Prev ] button click.
|
||||
* This clears the data in the current step and returns to the previous step.
|
||||
* */
|
||||
onPrevClick() {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.removeStepData();
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves form data in each step in to the state.
|
||||
* @param step: The step number of the step data.
|
||||
* @param data: The form data of the step.
|
||||
* */
|
||||
setStepData(step, data) {
|
||||
console.log(step, data, this.state.stepData); //TODO: Remove this
|
||||
let tmpStepData = this.state.stepData;
|
||||
tmpStepData.push({step: step, data: data});
|
||||
|
||||
this.setState({stepData: tmpStepData}, this.onNextClick())
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the last data point
|
||||
* */
|
||||
removeStepData() {
|
||||
let tempData = this.state.stepData;
|
||||
tempData.pop();
|
||||
this.setState({stepData: tempData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the Yes button in app creation cancellation dialog.
|
||||
* Clears all the form data and reset the wizard.
|
||||
* */
|
||||
handleYes() {
|
||||
this.setState({finished: false, stepIndex: 0, stepData: [], isDialogOpen: false});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles No button in app creation cancellation dialog.
|
||||
* Returns to the same step.
|
||||
* */
|
||||
handleNo() {
|
||||
this.setState({isDialogOpen: false});
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines all the Steps in the stepper. (Wizard)
|
||||
*
|
||||
* Extension Point: If any extra steps needed, follow the instructions below.
|
||||
* 1. Create the required form ./Forms directory.
|
||||
* 2. Add defined case statements.
|
||||
* 3. Define the Step in render function.
|
||||
*
|
||||
* */
|
||||
getStepContent(stepIndex) {
|
||||
switch (stepIndex) {
|
||||
case 0:
|
||||
return (
|
||||
<Step1
|
||||
handleNext={this.onNextClick}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}
|
||||
/>
|
||||
);
|
||||
case 1:
|
||||
return (
|
||||
<Step2
|
||||
handleNext={this.onNextClick}
|
||||
handlePrev={this.onPrevClick}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}
|
||||
/>
|
||||
);
|
||||
case 2:
|
||||
return (
|
||||
<Step3
|
||||
handleFinish={this.onNextClick}
|
||||
handlePrev={this.onPrevClick}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}
|
||||
/>
|
||||
);
|
||||
case 3: {
|
||||
return (
|
||||
<Step4
|
||||
handleNext={this.onNextClick}
|
||||
setData={this.setStepData}
|
||||
removeData={this.removeStepData}
|
||||
/>
|
||||
)
|
||||
}
|
||||
default:
|
||||
return <div/>;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {finished, stepIndex} = this.state;
|
||||
|
||||
return (
|
||||
<div id="create-application-modal">
|
||||
<Modal isOpen={this.state.open} toggle={this.toggle} id="app-create-modal"
|
||||
backdrop={'static'}>
|
||||
<ModalHeader toggle={this.toggle}>Create Application</ModalHeader>
|
||||
<ModalBody id="modal-body-content">
|
||||
<Row>
|
||||
<Col>
|
||||
<div className="stepper-header">
|
||||
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
{this.getStepContent(stepIndex)}
|
||||
</Col>
|
||||
</Row>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
{stepIndex === 0 ? <div/> :
|
||||
<Button color="primary" onClick={this.onPrevClick}>Back</Button>}
|
||||
<Button color="secondary" onClick={this.onClose}>Cancel</Button>
|
||||
{finished ?
|
||||
<Button color="primary" onClick={this.onSubmit}>Finish</Button> :
|
||||
<Button color="primary" onClick={this.onNextClick}>Continue</Button>}
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationCreate.propTypes = {};
|
||||
|
||||
export default withRouter(ApplicationCreate);
|
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {Badge, FormGroup, Input, Label} from 'reactstrap';
|
||||
|
||||
/**
|
||||
* The Second step of application create wizard.
|
||||
* This contains following components.
|
||||
* * App Title
|
||||
* * Short Description
|
||||
* * Application Description
|
||||
* * Application Visibility
|
||||
* * Application Tags : {Used Material UI Chip component}
|
||||
* * Application Category.
|
||||
* * Platform Specific properties.
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* * onNextClick : {type: function, Invokes onNextClick function in Parent.}
|
||||
* * onPrevClick : {type: function, Invokes onPrevClick function in Parent}
|
||||
* * setData : {type: function, Invokes setStepData function in Parent}
|
||||
* * removeData : {type: Invokes removeStepData function in Parent}
|
||||
* */
|
||||
class Step1 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
tags: [],
|
||||
icon: [],
|
||||
title: "",
|
||||
errors: {},
|
||||
banner: [],
|
||||
defValue: "",
|
||||
category: 0,
|
||||
visibility: 0,
|
||||
description: "",
|
||||
screenshots: [],
|
||||
identifier: "",
|
||||
shortDescription: ""
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: ""}, console.log(tags));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for tag.
|
||||
* */
|
||||
handleTagChange(event) {
|
||||
let defaultValue = this.state.defValue;
|
||||
defaultValue = event.target.value;
|
||||
this.setState({defValue: defaultValue})
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Chip delete function.
|
||||
* Removes the tag from state.tags
|
||||
* */
|
||||
handleRequestDelete(event) {
|
||||
this.chipData = this.state.tags;
|
||||
console.log(event.target);
|
||||
const chipToDelete = this.chipData.map((chip) => chip.value).indexOf(event.target.value);
|
||||
this.chipData.splice(chipToDelete, 1);
|
||||
this.setState({tags: this.chipData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an object with the current step data and persist in the parent.
|
||||
* */
|
||||
setStepData() {
|
||||
let stepData = {};
|
||||
this.props.setData("step1", {step: stepData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set text field values to state.
|
||||
* */
|
||||
onTextFieldChange(event, value) {
|
||||
let field = event.target.id;
|
||||
switch (field) {
|
||||
case "name": {
|
||||
this.setState({name: value});
|
||||
break;
|
||||
}
|
||||
case "shortDescription": {
|
||||
this.setState({shortDescription: value});
|
||||
break;
|
||||
}
|
||||
case "description": {
|
||||
this.setState({description: value});
|
||||
break;
|
||||
}
|
||||
case "identifier": {
|
||||
this.setState({identifier: value});
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="createStep2Content">
|
||||
<div>
|
||||
<div>
|
||||
<FormGroup>
|
||||
<Label for="app-title">Title*</Label>
|
||||
<Input
|
||||
required
|
||||
type="text"
|
||||
name="appName"
|
||||
id="app-title"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-description">Description*</Label>
|
||||
<Input
|
||||
required
|
||||
type="textarea"
|
||||
name="appDescription"
|
||||
id="app-description"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-category">Category</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="category"
|
||||
id="app-category"
|
||||
>
|
||||
<option>Business</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-visibility">Visibility</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="visibility"
|
||||
id="app-visibility"
|
||||
>
|
||||
<option>Devices</option>
|
||||
<option>Roles</option>
|
||||
<option>Groups</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-tags">Tags*</Label>
|
||||
<Input
|
||||
required
|
||||
type="text"
|
||||
value={this.state.defValue}
|
||||
name="app-tags"
|
||||
id="app-tags"
|
||||
onChange={this.handleTagChange.bind(this)}
|
||||
onKeyPress={this.addTags.bind(this)}
|
||||
/>
|
||||
<div id="batch-content">
|
||||
{this.state.tags.map(tag => {
|
||||
return (
|
||||
<Badge
|
||||
style={{margin: '0 2px 0 2px'}}
|
||||
value={tag.value}
|
||||
onClick={this.handleRequestDelete.bind(this)}
|
||||
>
|
||||
{tag.value}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step1.prototypes = {
|
||||
handleNext: PropTypes.func,
|
||||
handlePrev: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step1;
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import AuthHandler from "../../../../api/authHandler";
|
||||
import PlatformMgtApi from "../../../../api/platformMgtApi";
|
||||
import {FormGroup, Input, Label} from 'reactstrap';
|
||||
|
||||
/**
|
||||
* The first step of the application creation wizard.
|
||||
* This contains following components:
|
||||
* * Application Title
|
||||
* * Store Type
|
||||
* * Application Platform
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* 1. onNextClick: {type: function, Invokes onNextClick function of parent component}
|
||||
* 2. setData : {type: function, Sets current form data to the state of the parent component}
|
||||
* 3. removeData: {type: function, Invokes the removeStepData function click of parent}
|
||||
* */
|
||||
class Step2 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.setPlatforms = this.setPlatforms.bind(this);
|
||||
this.setStepData = this.setStepData.bind(this);
|
||||
this.platforms = [];
|
||||
this.state = {
|
||||
finished: false,
|
||||
stepIndex: 0,
|
||||
store: 1,
|
||||
platformSelectedIndex: 0,
|
||||
platform: "",
|
||||
platforms: [],
|
||||
stepData: [],
|
||||
title: "",
|
||||
titleError: ""
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
//Get the list of available platforms and set to the state.
|
||||
PlatformMgtApi.getPlatforms().then(response => {
|
||||
console.log(response);
|
||||
this.setPlatforms(response.data);
|
||||
}).catch(err => {
|
||||
AuthHandler.unauthorizedErrorHandler(err);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the platforms from the response data and populate the state.
|
||||
* @param platforms: The array returned as the response.
|
||||
* */
|
||||
setPlatforms(platforms) {
|
||||
let tmpPlatforms = [];
|
||||
for (let index in platforms) {
|
||||
let platform = {};
|
||||
platform = platforms[index];
|
||||
tmpPlatforms.push(platform);
|
||||
}
|
||||
this.setState({platforms: tmpPlatforms, platformSelectedIndex: 0, platform: tmpPlatforms[0].name})
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the current form data to the state.
|
||||
* */
|
||||
setStepData() {
|
||||
let step = {
|
||||
store: this.state.store,
|
||||
platform: this.state.platforms[this.state.platformSelectedIndex]
|
||||
};
|
||||
this.props.setData("step2", {step: step});
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers when changing the Platform selection.
|
||||
* */
|
||||
onChangePlatform(event) {
|
||||
console.log(event.target.value, this.state.platforms);
|
||||
let id = event.target.value;
|
||||
let selectedPlatform = this.state.platforms.filter((platform) => {
|
||||
return platform.identifier === id;
|
||||
});
|
||||
this.setState({platform: selectedPlatform});
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggers when changing the Store selection.
|
||||
* */
|
||||
onChangeStore(event) {
|
||||
this.setState({store: event.target.value});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
<FormGroup>
|
||||
<Label for="store">Store Type</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="store"
|
||||
className="input-custom"
|
||||
onChange={this.onChangeStore.bind(this)}
|
||||
>
|
||||
<option>Enterprise</option>
|
||||
<option>Public</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="store">Platform</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="store"
|
||||
onChange={this.onChangePlatform.bind(this)}
|
||||
>
|
||||
{this.state.platforms.length > 0 ? this.state.platforms.map(platform => {
|
||||
return (
|
||||
<option value={platform.identifier}>
|
||||
{platform.name}
|
||||
</option>
|
||||
)
|
||||
}) : <option>No Platforms</option>}
|
||||
</Input>
|
||||
</FormGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step2.propTypes = {
|
||||
handleNext: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step2;
|
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import Chip from 'material-ui/Chip';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import React, {Component} from 'react';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import {FormGroup, Label} from 'reactstrap';
|
||||
import AppImage from "../../../UIComponents/AppImage/AppImage";
|
||||
|
||||
/**
|
||||
* The Third step of application create wizard.
|
||||
* This contains following components.
|
||||
* * Screenshots
|
||||
* * Banner
|
||||
* * Icon
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* * onNextClick : {type: function, Invokes onNextClick function in Parent.}
|
||||
* * onPrevClick : {type: function, Invokes onPrevClick function in Parent}
|
||||
* * setData : {type: function, Invokes setStepData function in Parent}
|
||||
* * removeData : {type: Invokes removeStepData function in Parent}
|
||||
* */
|
||||
class Step3 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
tags: [],
|
||||
icon: [],
|
||||
title: "",
|
||||
errors: {},
|
||||
banner: [],
|
||||
defValue: "",
|
||||
category: 0,
|
||||
visibility: 0,
|
||||
description: "",
|
||||
screenshots: [],
|
||||
identifier: "",
|
||||
shortDescription: ""
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Chip delete function.
|
||||
* Removes the tag from state.tags
|
||||
* */
|
||||
handleRequestDelete(event) {
|
||||
this.chipData = this.state.tags;
|
||||
console.log(event.target); //TODO: Remove Console log.
|
||||
const chipToDelete = this.chipData.map((chip) => chip.value).indexOf(event.target.value);
|
||||
this.chipData.splice(chipToDelete, 1);
|
||||
this.setState({tags: this.chipData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an object with the current step data and persist in the parent.
|
||||
* */
|
||||
setStepData() {
|
||||
let stepData = {
|
||||
icon: this.state.icon,
|
||||
banner: this.state.banner,
|
||||
screenshots: this.state.screenshots
|
||||
};
|
||||
|
||||
this.props.setData("step2", {step: stepData});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removed user uploaded banner.
|
||||
* */
|
||||
removeBanner(event, d) {
|
||||
console.log(event, d); //TODO: Remove this
|
||||
this.setState({banner: []});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes uploaded icon.
|
||||
* */
|
||||
removeIcon(event) {
|
||||
this.setState({icon: []});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes selected screenshot.
|
||||
* */
|
||||
removeScreenshot(event) {
|
||||
console.log(event.target) //TODO: Remove this.
|
||||
};
|
||||
|
||||
//TODO: Remove inline css.
|
||||
render() {
|
||||
return (
|
||||
<div className="createStep2Content">
|
||||
<div>
|
||||
<FormGroup>
|
||||
<Label for="app-screenshots">Screenshots*</Label>
|
||||
<span className="image-sub-title"> (600 X 800 32 bit PNG)</span>
|
||||
<div id="screenshot-container">
|
||||
{this.state.screenshots.map((tile) => (
|
||||
<div id="app-image-screenshot">
|
||||
<AppImage image={tile[0].preview}/>
|
||||
</div>
|
||||
))}
|
||||
{this.state.screenshots.length < 3 ?
|
||||
<Dropzone
|
||||
className="application-create-screenshot-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(screenshots, rejected) => {
|
||||
let tmpScreenshots = this.state.screenshots;
|
||||
tmpScreenshots.push(screenshots);
|
||||
console.log(screenshots); //TODO: Remove this
|
||||
this.setState({
|
||||
screenshots: tmpScreenshots
|
||||
});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div style={{display: 'flex'}}>
|
||||
<div style={{float: 'left', marginRight: '15px'}}>
|
||||
<FormGroup>
|
||||
<Label for="app-icon">Icon*</Label>
|
||||
<span className="image-sub-title"> (512 X 512 32 bit PNG)</span>
|
||||
<div id="app-icon-container">
|
||||
{this.state.icon.map((tile) => (
|
||||
<div id="app-image-icon">
|
||||
<AppImage image={tile.preview}/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{this.state.icon.length === 0 ?
|
||||
<Dropzone
|
||||
className="application-create-icon-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(icon, rejected) => {
|
||||
this.setState({icon, rejected});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div style={{marginLeft: '15px'}}>
|
||||
<FormGroup>
|
||||
<Label for="app-banner">Banner*</Label>
|
||||
<span className="image-sub-title"> (1000 X 400 32 bit PNG)</span>
|
||||
<div id="app-banner-container">
|
||||
{this.state.banner.map((tile) => (
|
||||
<div id="app-image-banner">
|
||||
<AppImage image={tile.preview}/>
|
||||
</div>
|
||||
))}
|
||||
{this.state.banner.length === 0 ?
|
||||
<Dropzone
|
||||
className="application-create-banner-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(banner, rejected) => {
|
||||
this.setState({banner, rejected});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>
|
||||
}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step3.prototypes = {
|
||||
handleNext: PropTypes.func,
|
||||
handlePrev: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step3;
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {Collapse, FormGroup, Input, Label, FormText} from 'reactstrap';
|
||||
import Switch from '../../../UIComponents/Switch/Switch'
|
||||
|
||||
/**
|
||||
* The Third step of application create wizard. {Application Release Step}
|
||||
* This step is not compulsory.
|
||||
*
|
||||
* When click finish, user will prompt to confirm the application creation.
|
||||
* User can go ahead and create the app or cancel.
|
||||
*
|
||||
* This contains following components:
|
||||
* * Toggle to select application release. Un-hides the Application Release form.
|
||||
*
|
||||
* Application Release Form.
|
||||
* * Release Channel
|
||||
* * Application Version
|
||||
* * Upload component for application.
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* * handleFinish : {type: function, Invokes onNextClick function in Parent.}
|
||||
* * onPrevClick : {type: function, Invokes onPrevClick function in Parent}
|
||||
* * setData : {type: function, Invokes setStepData function in Parent}
|
||||
* * removeData : {type: Invokes removeStepData function in Parent}
|
||||
* */
|
||||
class Step4 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.handleToggle = this.handleToggle.bind(this);
|
||||
this.handlePrev = this.handlePrev.bind(this);
|
||||
this.handleToggle = this.handleToggle.bind(this);
|
||||
this.handleFinish = this.handleFinish.bind(this);
|
||||
this.state = {
|
||||
showForm: false,
|
||||
releaseChannel: 1,
|
||||
errors: {}
|
||||
};
|
||||
this.scriptId = "application-create-step3";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles finish button click.
|
||||
* This invokes onNextClick function in parent component.
|
||||
* */
|
||||
handleFinish() {
|
||||
this.props.handleFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes Prev button click.
|
||||
* */
|
||||
handlePrev() {
|
||||
this.props.handlePrev();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles release application selection.
|
||||
* */
|
||||
handleToggle() {
|
||||
let hide = this.state.showForm;
|
||||
this.setState({showForm: !hide});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="applicationCreateStepMiddle">
|
||||
<div>
|
||||
<FormGroup>
|
||||
<div id="app-release-switch-content">
|
||||
<div id="app-release-switch-label">
|
||||
<Label for="app-release-switch">
|
||||
<strong>
|
||||
Add Release to Application
|
||||
</strong>
|
||||
</Label>
|
||||
</div>
|
||||
<div id="app-release-switch-switch">
|
||||
<Switch
|
||||
id="app-release-switch"
|
||||
onChange={this.handleToggle.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</FormGroup>
|
||||
<br/>
|
||||
<div>
|
||||
<FormText color="muted">
|
||||
<i>Info: </i>
|
||||
Enabling this will create a release for the current Application.
|
||||
To upload the Application, please visit to the Release management section of
|
||||
Application Edit View.
|
||||
</FormText>
|
||||
</div>
|
||||
{/*If toggle is true, the release form will be shown.*/}
|
||||
<Collapse isOpen={this.state.showForm}>
|
||||
<FormGroup>
|
||||
<Label for="release-channel">Release Channel</Label>
|
||||
<Input
|
||||
type="select"
|
||||
id="release-channel"
|
||||
style={{
|
||||
width: '200px',
|
||||
border: 'none',
|
||||
borderRadius: '0',
|
||||
borderBottom: 'solid 1px #BDBDBD'
|
||||
}}>
|
||||
<option>GA</option>
|
||||
<option>Alpha</option>
|
||||
<option>Beta</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="version">Version*</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id="version input-custom"
|
||||
placeholder="v1.0"
|
||||
required
|
||||
/>
|
||||
</FormGroup>
|
||||
</Collapse>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step4.propTypes = {
|
||||
handleFinish: PropTypes.func,
|
||||
handlePrev: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step4;
|
3
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/index.js → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/Create/CreateSteps/index.js
3
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/CreateSteps/index.js → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Application/Create/CreateSteps/index.js
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
|
||||
/**
|
||||
* The first step of the application creation wizard.
|
||||
* This contains following components:
|
||||
* * Application Title
|
||||
* * Store Type
|
||||
* * Application Platform
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* 1. handleNext: {type: function, Invokes handleNext function of parent component}
|
||||
* 2. setData : {type: function, Sets current form data to the state of the parent component}
|
||||
* 3. removeData: {type: function, Invokes the removeStepData function click of parent}
|
||||
* */
|
||||
class Step1 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
finished: false,
|
||||
stepIndex: 0,
|
||||
store: 1,
|
||||
platform: 1,
|
||||
stepData: [],
|
||||
title: "",
|
||||
titleError: ""
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
//Get the list of available platforms and set to the state.
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the handleNext function in Create component.
|
||||
* */
|
||||
_handleNext = () => {
|
||||
this.props.handleNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* Persist the current form data to the state.
|
||||
* */
|
||||
_setStepData() {
|
||||
var step = {
|
||||
store: this.state.store,
|
||||
platform: this.state.platform
|
||||
};
|
||||
this.props.setData("step1", {step: step});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Next button click.
|
||||
* Validates the form.
|
||||
* Sets the data to the state.
|
||||
* Invokes the handleNext method of Create component.
|
||||
* */
|
||||
_handleClick() {
|
||||
this._setStepData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers when changing the Platform selection.
|
||||
* */
|
||||
_onChangePlatform = (event, index, value) => {
|
||||
console.log(value);
|
||||
this.setState({platform: value});
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggers when changing the Store selection.
|
||||
* */
|
||||
_onChangeStore = (event, index, value) => {
|
||||
this.setState({store: value});
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggers when user types on Title text field.
|
||||
* */
|
||||
_onChangeTitle = (event, value) => {
|
||||
this.setState({title: value});
|
||||
};
|
||||
|
||||
render() {
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
return (
|
||||
<div>
|
||||
<div style={contentStyle}>
|
||||
<div>
|
||||
<div>
|
||||
<SelectField
|
||||
floatingLabelText="Store Type*"
|
||||
value={this.state.store}
|
||||
floatingLabelFixed={true}
|
||||
onChange={this._onChangeStore.bind(this)}
|
||||
>
|
||||
<MenuItem value={1} primaryText="Enterprise"/>
|
||||
<MenuItem value={2} primaryText="Public"/>
|
||||
</SelectField> <br/>
|
||||
<SelectField
|
||||
floatingLabelText="Platform*"
|
||||
value={this.state.platform}
|
||||
floatingLabelFixed={true}
|
||||
onChange={this._onChangePlatform.bind(this)}
|
||||
>
|
||||
<MenuItem value={1} primaryText="Android"/>
|
||||
<MenuItem value={2} primaryText="iOS"/>
|
||||
<MenuItem value={{name: "Web", id:3}} primaryText="Web"/>
|
||||
</SelectField>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<div style={{marginTop: 12}}>
|
||||
<RaisedButton
|
||||
label="Next >"
|
||||
primary={true}
|
||||
onClick={this._handleClick.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step1.propTypes = {
|
||||
handleNext: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step1;
|
@ -1,489 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import Chip from 'material-ui/Chip';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import React, {Component} from 'react';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import IconButton from 'material-ui/IconButton';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import Clear from 'material-ui/svg-icons/content/clear';
|
||||
import {GridList, GridTile} from 'material-ui/GridList';
|
||||
|
||||
/**
|
||||
* The Second step of application create wizard.
|
||||
* This contains following components.
|
||||
* * App Title
|
||||
* * Short Description
|
||||
* * Application Description
|
||||
* * Application Visibility
|
||||
* * Application Tags : {Used Material UI Chip component}
|
||||
* * Application Category.
|
||||
* * Platform Specific properties.
|
||||
* * Screenshots
|
||||
* * Banner
|
||||
* * Icon
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* * handleNext : {type: function, Invokes handleNext function in Parent.}
|
||||
* * handlePrev : {type: function, Invokes handlePrev function in Parent}
|
||||
* * setData : {type: function, Invokes setStepData function in Parent}
|
||||
* * removeData : {type: Invokes removeStepData function in Parent}
|
||||
* */
|
||||
class Step2 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
tags: [],
|
||||
defValue: "",
|
||||
category: 0,
|
||||
visibility: 0,
|
||||
errors: {},
|
||||
title: "",
|
||||
shortDescription: "",
|
||||
description: "",
|
||||
banner: [],
|
||||
screenshots: [],
|
||||
icon: []
|
||||
};
|
||||
|
||||
this.styles = {
|
||||
chip: {
|
||||
margin: 4,
|
||||
},
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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: ""});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for tag.
|
||||
* */
|
||||
_handleTagChange(event) {
|
||||
let defaultValue = this.state.defValue;
|
||||
defaultValue = event.target.value;
|
||||
this.setState({defValue: defaultValue})
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the handleNext function in Create component.
|
||||
* */
|
||||
_handleNext() {
|
||||
let fields = [{name: "Title", value: this.state.title},
|
||||
{name: "Short Description", value: this.state.shortDescription},
|
||||
{name: "Description", value: this.state.description},
|
||||
{name: "Banner", value: this.state.banner},
|
||||
{name: "Screenshots", value: this.state.screenshots},
|
||||
{name: "Icon", value: this.state.icon}];
|
||||
this._validate(fields);
|
||||
// this.props.handleNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the handlePrev function in Create component.
|
||||
* */
|
||||
_handlePrev() {
|
||||
this.props.handlePrev();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Chip delete function.
|
||||
* Removes the tag from state.tags
|
||||
* */
|
||||
_handleRequestDelete = (key) => {
|
||||
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});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates Chip array from state.tags.
|
||||
* */
|
||||
_renderChip(data) {
|
||||
return (
|
||||
<Chip
|
||||
key={data.key}
|
||||
onRequestDelete={() => this._handleRequestDelete(data.key)}
|
||||
style={this.styles.chip}
|
||||
>
|
||||
{data.value}
|
||||
</Chip>
|
||||
);
|
||||
}
|
||||
|
||||
_onVisibilitySelect = (event, index, value) => {
|
||||
console.log(value);
|
||||
let comp = <SelectField> <MenuItem value={0} primaryText="Public"/>
|
||||
<MenuItem value={1} primaryText="Roles"/>
|
||||
<MenuItem value={2} primaryText="Devices"/> </SelectField>;
|
||||
if (value === 1) {
|
||||
this.setState({visibilityComponent: comp});
|
||||
} else if (value === 2) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the form.
|
||||
* */
|
||||
_validate(fields) {
|
||||
let errors = {};
|
||||
let errorsPresent = false;
|
||||
fields.forEach(function (field) {
|
||||
switch (field.name) {
|
||||
case 'Title': {
|
||||
if (field.value === "") {
|
||||
errors[field.name] = field.name + " is required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'Short Description': {
|
||||
if (field.value === "") {
|
||||
errors[field.name] = field.name + " is required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'Description': {
|
||||
if (field.value === "") {
|
||||
errors[field.name] = field.name + " is required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'Banner': {
|
||||
if (field.value.length === 0) {
|
||||
errors[field.name] = field.name + " is required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'Icon': {
|
||||
if (field.value.length === 0) {
|
||||
errors[field.name] = field.name + " is required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'Screenshots': {
|
||||
if (field.value.length < 3) {
|
||||
errors[field.name] = "3 " +field.name + " are required!";
|
||||
errorsPresent = true;
|
||||
} else {
|
||||
errorsPresent = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(errorsPresent);
|
||||
if (!errorsPresent) {
|
||||
this._setStepData();
|
||||
} else {
|
||||
this.setState({errors: errors}, console.log(errors));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object with the current step data and persist in the parent.
|
||||
* */
|
||||
_setStepData() {
|
||||
let stepData = {
|
||||
title: this.state.title,
|
||||
description: this.state.description,
|
||||
shortDescription: this.state.shortDescription,
|
||||
tags: this.state.tags,
|
||||
banner: this.state.banner,
|
||||
screenshots: this.state.screenshots,
|
||||
icon: this.state.icon
|
||||
};
|
||||
|
||||
this.props.setData("step2", {step: stepData});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text field values to state.
|
||||
* */
|
||||
_onTextFieldChange(event, value) {
|
||||
let field = event.target.id;
|
||||
switch (field) {
|
||||
case "title": {
|
||||
this.setState({title: value});
|
||||
break;
|
||||
}
|
||||
case "shortDescription": {
|
||||
this.setState({shortDescription: value});
|
||||
break;
|
||||
}
|
||||
case "description": {
|
||||
this.setState({description: value});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed user uploaded banner.
|
||||
* */
|
||||
_removeBanner(event, d) {
|
||||
console.log(event, d);
|
||||
this.setState({banner: []});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes uploaded icon.
|
||||
* */
|
||||
_removeIcon(event) {
|
||||
this.setState({icon: []});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes selected screenshot.
|
||||
* */
|
||||
_removeScreenshot(event) {
|
||||
console.log(event.target)
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log(this.state.visibilityComponent);
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
return (
|
||||
<div style={contentStyle}>
|
||||
<div>
|
||||
<div>
|
||||
<TextField
|
||||
id="title"
|
||||
hintText="Enter a title for your application."
|
||||
errorText={this.state.errors["Title"]}
|
||||
floatingLabelText="Title*"
|
||||
floatingLabelFixed={true}
|
||||
onChange={this._onTextFieldChange.bind(this)}
|
||||
/><br/>
|
||||
<TextField
|
||||
id="shortDescription"
|
||||
hintText="Enter a short description for your application."
|
||||
errorText={this.state.errors["Short Description"]}
|
||||
floatingLabelText="Short Description*"
|
||||
floatingLabelFixed={true}
|
||||
multiLine={true}
|
||||
rows={2}
|
||||
onChange={this._onTextFieldChange.bind(this)}
|
||||
|
||||
/><br/>
|
||||
<TextField
|
||||
id="description"
|
||||
errorText={this.state.errors["Description"]}
|
||||
hintText="Enter the description."
|
||||
floatingLabelText="Description*"
|
||||
floatingLabelFixed={true}
|
||||
multiLine={true}
|
||||
rows={4}
|
||||
onChange={this._onTextFieldChange.bind(this)}
|
||||
/><br/>
|
||||
<SelectField
|
||||
floatingLabelText="Visibility*"
|
||||
value={this.state.visibility}
|
||||
floatingLabelFixed={true}
|
||||
onChange={this._onVisibilitySelect.bind(this)}
|
||||
>
|
||||
<MenuItem value={0} primaryText="Public"/>
|
||||
<MenuItem value={1} primaryText="Roles"/>
|
||||
<MenuItem value={2} primaryText="Devices"/>
|
||||
</SelectField><br/>
|
||||
<TextField
|
||||
id="tags"
|
||||
errorText={this.state.errors["tags"]}
|
||||
hintText="Enter application tags.."
|
||||
floatingLabelText="Tags*"
|
||||
floatingLabelFixed={true}
|
||||
value={this.state.defValue}
|
||||
onChange={this._handleTagChange.bind(this)}
|
||||
onKeyPress={this._addTags.bind(this)}
|
||||
/><br/>
|
||||
<div style={this.styles.wrapper}>
|
||||
{this.state.tags.map(this._renderChip, this)}
|
||||
</div>
|
||||
<br/>
|
||||
<SelectField
|
||||
floatingLabelText="Category*"
|
||||
value={this.state.category}
|
||||
floatingLabelFixed={true}
|
||||
>
|
||||
<MenuItem value={0} primaryText="Business"/>
|
||||
</SelectField> <br/>
|
||||
{/*Platform Specific Properties.*/}
|
||||
<div style={{border: 'solid #BDBDBD 1px'}}>
|
||||
<p style={{color: '#BDBDBD'}}>Platform Specific Properties</p>
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<p style={{color: '#f44336'}}>{this.state.errors["Banner"]}</p>
|
||||
<p style={{color: '#BDBDBD'}}>Banner*:</p>
|
||||
<GridList style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
overflowX: 'auto',
|
||||
}} cols={1.1}>
|
||||
{this.state.banner.map((tile) => (
|
||||
<GridTile key={Math.floor(Math.random() * 1000)}
|
||||
title={tile.name}
|
||||
actionIcon={
|
||||
<IconButton onClick={this._removeBanner.bind(this)}>
|
||||
<Clear />
|
||||
</IconButton>}>
|
||||
<img src={tile.preview}/></GridTile>
|
||||
))}
|
||||
{this.state.banner.length === 0 ?
|
||||
<Dropzone style={{width: '300px', height: '150px', border: 'dashed #BDBDBD 1px'}}
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(banner, rejected) => {
|
||||
this.setState({banner, rejected});
|
||||
}}>
|
||||
<p style={{margin: '70px 40px 40px 150px'}}>+</p>
|
||||
</Dropzone> : <div />}
|
||||
|
||||
</GridList>
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<p style={{color: '#f44336'}}>{this.state.errors["Screenshots"]}</p>
|
||||
<p style={{color: '#BDBDBD'}}>Screenshots*:</p>
|
||||
<GridList style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
overflowX: 'auto',
|
||||
}} cols={1.1}>
|
||||
{this.state.screenshots.map((file) => (
|
||||
<GridTile key={Math.floor(Math.random() * 1000)}
|
||||
title={file[0].name}
|
||||
actionIcon={
|
||||
<IconButton onClick={this._removeScreenshot.bind(this)}>
|
||||
<Clear/>
|
||||
</IconButton>}>
|
||||
<img src={file[0].preview}/></GridTile>
|
||||
))}
|
||||
{this.state.screenshots.length < 3 ?
|
||||
<Dropzone style={{width: '150px', height: '150px', border: 'dashed #BDBDBD 1px'}}
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(screenshots, rejected) => {
|
||||
let tmpScreenshots = this.state.screenshots;
|
||||
tmpScreenshots.push(screenshots);
|
||||
this.setState({
|
||||
screenshots: tmpScreenshots});
|
||||
}}>
|
||||
<p style={{margin: '70px 40px 70px 70px'}}>+</p>
|
||||
</Dropzone> : <div />}
|
||||
</GridList>
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<p style={{color: '#f44336'}}>{this.state.errors["Icon"]}</p>
|
||||
<p style={{color: '#BDBDBD'}}>Icon*:</p>
|
||||
<GridList style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
overflowX: 'auto',
|
||||
}} cols={1.1}>
|
||||
{this.state.icon.map((tile) => (
|
||||
<GridTile key={Math.floor(Math.random() * 1000)}
|
||||
title={tile.name}
|
||||
actionIcon={
|
||||
<IconButton onClick={this._removeIcon.bind(this)}>
|
||||
<Clear />
|
||||
</IconButton>}>
|
||||
<img src={tile.preview}/></GridTile>
|
||||
))}
|
||||
{this.state.icon.length === 0 ?
|
||||
<Dropzone style={{width: '150px', height: '150px', border: 'dashed #BDBDBD 1px'}}
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(icon, rejected) => {this.setState({icon, rejected});}}>
|
||||
<p style={{margin: '70px 40px 70px 70px'}}>+</p>
|
||||
</Dropzone> : <div />}
|
||||
</GridList>
|
||||
</div>
|
||||
<br/>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<div style={{marginTop: 12}}>
|
||||
<FlatButton
|
||||
label="< Back"
|
||||
disabled={false}
|
||||
onClick={this._handlePrev.bind(this)}
|
||||
style={{marginRight: 12}}
|
||||
/>
|
||||
<RaisedButton
|
||||
label="Next >"
|
||||
primary={true}
|
||||
onClick={this._handleNext.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step2.prototypes = {
|
||||
handleNext: PropTypes.func,
|
||||
handlePrev: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step2;
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import Toggle from 'material-ui/Toggle';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
|
||||
/**
|
||||
* The Third step of application create wizard. {Application Release Step}
|
||||
* This step is not compulsory.
|
||||
*
|
||||
* When click finish, user will prompt to confirm the application creation.
|
||||
* User can go ahead and create the app or cancel.
|
||||
*
|
||||
* This contains following components:
|
||||
* * Toggle to select application release. Un-hides the Application Release form.
|
||||
*
|
||||
* Application Release Form.
|
||||
* * Release Channel
|
||||
* * Application Version
|
||||
* * Upload component for application.
|
||||
*
|
||||
* Parent Component: Create
|
||||
* Props:
|
||||
* * handleFinish : {type: function, Invokes handleNext function in Parent.}
|
||||
* * handlePrev : {type: function, Invokes handlePrev function in Parent}
|
||||
* * setData : {type: function, Invokes setStepData function in Parent}
|
||||
* * removeData : {type: Invokes removeStepData function in Parent}
|
||||
* */
|
||||
class Step3 extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
showForm: false,
|
||||
releaseChannel: 1,
|
||||
errors: {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles finish button click.
|
||||
* This invokes handleNext function in parent component.
|
||||
* */
|
||||
_handleFinish() {
|
||||
this.props.handleFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes Prev button click.
|
||||
* */
|
||||
_handlePrev() {
|
||||
this.props.handlePrev();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles release application selection.
|
||||
* */
|
||||
_handleToggle() {
|
||||
let hide = this.state.showForm;
|
||||
this.setState({showForm: !hide});
|
||||
}
|
||||
|
||||
render() {
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
return (
|
||||
<div style={contentStyle}>
|
||||
<div>
|
||||
<Toggle
|
||||
label="Release the Application"
|
||||
labelPosition="right"
|
||||
onToggle={this._handleToggle.bind(this)}
|
||||
defaultToggled={this.state.showForm}
|
||||
/>
|
||||
{/*If toggle is true, the release form will be shown.*/}
|
||||
{!this.state.showForm ? <div/> : <div>
|
||||
<SelectField
|
||||
floatingLabelText="Select Release Channel*"
|
||||
value={this.state.releaseChannel}
|
||||
floatingLabelFixed={true}
|
||||
>
|
||||
<MenuItem value={1} primaryText="Alpha"/>
|
||||
<MenuItem value={2} primaryText="Beta"/>
|
||||
<MenuItem value={3} primaryText="GA"/>
|
||||
</SelectField> <br/>
|
||||
<TextField
|
||||
hintText="1.0.0"
|
||||
floatingLabelText="Version*"
|
||||
errorText={this.state.errors["title"]}
|
||||
floatingLabelFixed={true}
|
||||
/><br/>
|
||||
</div>}
|
||||
|
||||
<div style={{marginTop: 12}}>
|
||||
<FlatButton
|
||||
label="< Back"
|
||||
disabled={false}
|
||||
onClick={this._handlePrev.bind(this)}
|
||||
style={{marginRight: 12}}
|
||||
/>
|
||||
<RaisedButton
|
||||
label="Finish"
|
||||
primary={true}
|
||||
onClick={this._handleFinish.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Step3.propTypes = {
|
||||
handleFinish: PropTypes.func,
|
||||
handlePrev: PropTypes.func,
|
||||
setData: PropTypes.func,
|
||||
removeData: PropTypes.func
|
||||
};
|
||||
|
||||
export default Step3;
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import {Col, Row} from "reactstrap";
|
||||
import React, {Component} from 'react';
|
||||
import GeneralInfo from "../GenenralInfo/GeneralInfo";
|
||||
import ReleaseManager from '../../Release/ReleaseMgtBase/ReleaseManager';
|
||||
|
||||
class ApplicationEdit extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.getTabContent = this.getTabContent.bind(this);
|
||||
this.state = {
|
||||
general: "active",
|
||||
release: "",
|
||||
pkgmgt: "",
|
||||
activeTab: 1
|
||||
}
|
||||
}
|
||||
|
||||
handleTabClick(event) {
|
||||
event.stopPropagation();
|
||||
const key = event.target.value;
|
||||
|
||||
switch (key) {
|
||||
case "1": {
|
||||
this.setState({activeTab: 1, general: "active", release: "", pkgmgt: ""});
|
||||
break;
|
||||
}
|
||||
case "2": {
|
||||
this.setState({activeTab: 2, general: "", release: "active", pkgmgt: ""});
|
||||
break;
|
||||
}
|
||||
case "3": {
|
||||
this.setState({activeTab: 3, general: "", release: "", pkgmgt: "active"});
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return "No Content";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getTabContent(tab) {
|
||||
switch (tab) {
|
||||
case 1: {
|
||||
return <GeneralInfo/>
|
||||
}
|
||||
case 2: {
|
||||
return <ReleaseManager/>
|
||||
}
|
||||
case 3: {
|
||||
return ("Step3")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleOnBackClick() {
|
||||
window.location.href = "/publisher/assets/apps"
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="application-edit-base">
|
||||
<Row id="application-edit-header">
|
||||
<Col xs="3">
|
||||
<a className="back-to-app" onClick={this.handleOnBackClick.bind(this)}>
|
||||
<i className="fw fw-left-arrow"></i>
|
||||
</a>
|
||||
</Col>
|
||||
<Col>
|
||||
Application Name
|
||||
</Col>
|
||||
</Row>
|
||||
<Row id="application-edit-main-container">
|
||||
<Col xs="3">
|
||||
<div className="tab">
|
||||
<button className={this.state.general} value={1} onClick={this.handleTabClick.bind(this)}>
|
||||
General
|
||||
</button>
|
||||
<button className={this.state.release} value={2} onClick={this.handleTabClick.bind(this)}>
|
||||
App
|
||||
Releases
|
||||
</button>
|
||||
<button className={this.state.pkgmgt} value={3} onClick={this.handleTabClick.bind(this)}>
|
||||
Package Manager
|
||||
</button>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs="9">
|
||||
<div id="app-edit-content">
|
||||
<Row>
|
||||
<Col xs="12">
|
||||
<div id="application-edit-outer-content">
|
||||
{/* Application edit content */}
|
||||
<div id="application-edit-content">
|
||||
{this.getTabContent(this.state.activeTab)}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplicationEdit;
|
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Badge, Button, FormGroup, Input, Label, Row} from 'reactstrap';
|
||||
import Dropzone from 'react-dropzone';
|
||||
|
||||
class GeneralInfo extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
defValue: "",
|
||||
tags: [],
|
||||
screenshots: [],
|
||||
icon: [],
|
||||
banner: []
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Remove Console logs.
|
||||
render() {
|
||||
return (
|
||||
<div className="app-edit-general-info">
|
||||
<Row>
|
||||
<form>
|
||||
<FormGroup>
|
||||
<Label for="app-title">Title*</Label>
|
||||
<Input
|
||||
required
|
||||
type="text"
|
||||
name="appName"
|
||||
id="app-title"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-title">Description*</Label>
|
||||
<Input
|
||||
required
|
||||
type="textarea"
|
||||
multiline
|
||||
name="appName"
|
||||
id="app-title"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-category">Category</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="category"
|
||||
id="app-category"
|
||||
>
|
||||
<option>Business</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-visibility">Visibility</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name="visibility"
|
||||
id="app-visibility"
|
||||
>
|
||||
<option>Devices</option>
|
||||
<option>Roles</option>
|
||||
<option>Groups</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label for="app-tags">Tags*</Label>
|
||||
<Input
|
||||
required
|
||||
type="text"
|
||||
value={this.state.defValue}
|
||||
name="app-tags"
|
||||
id="app-tags"
|
||||
/>
|
||||
<div id="batch-content">
|
||||
{this.state.tags.map(tag => {
|
||||
return (
|
||||
<Badge
|
||||
style={{margin: '0 2px 0 2px'}}
|
||||
value={tag.value}
|
||||
>
|
||||
{tag.value}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</FormGroup>
|
||||
<div>
|
||||
<FormGroup>
|
||||
<Label for="app-screenshots">Screenshots*</Label>
|
||||
<span className="image-sub-title"> (600 X 800 32 bit PNG)</span>
|
||||
<div id="screenshot-container">
|
||||
{this.state.screenshots.map((tile) => (
|
||||
<button id="img-btn-screenshot" style={{height: '210px', width: '410px'}}
|
||||
onMouseEnter={() => {
|
||||
console.log("Mouse Entered")
|
||||
}}>
|
||||
{console.log(tile[0].preview)}
|
||||
<img style={{height: '200px', width: '400px'}} src={tile[0].preview}/>
|
||||
</button>
|
||||
))}
|
||||
{this.state.screenshots.length < 3 ?
|
||||
<Dropzone
|
||||
className="application-create-screenshot-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(screenshots, rejected) => {
|
||||
let tmpScreenshots = this.state.screenshots;
|
||||
tmpScreenshots.push(screenshots);
|
||||
console.log(screenshots);
|
||||
this.setState({
|
||||
screenshots: tmpScreenshots
|
||||
});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div style={{display: 'flex'}}>
|
||||
<div style={{float: 'left', marginRight: '15px'}}>
|
||||
<FormGroup>
|
||||
<Label for="app-icon">Icon*</Label>
|
||||
<span className="image-sub-title"> (512 X 512 32 bit PNG)</span>
|
||||
<div id="app-icon-container">
|
||||
{this.state.icon.map((tile) => (
|
||||
<button onMouseEnter={() => {
|
||||
console.log("Mouse Entered")
|
||||
}}>
|
||||
<img style={{height: '200px', width: '200px'}} src={tile.preview}/>
|
||||
</button>
|
||||
))}
|
||||
{this.state.icon.length === 0 ?
|
||||
<Dropzone
|
||||
className="application-create-icon-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(icon, rejected) => {
|
||||
this.setState({icon, rejected});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div style={{marginLeft: '15px'}}>
|
||||
<FormGroup>
|
||||
<Label for="app-banner">Banner*</Label>
|
||||
<span className="image-sub-title"> (1000 X 400 32 bit PNG)</span>
|
||||
<div id="app-banner-container">
|
||||
{this.state.banner.map((tile) => (
|
||||
<button onMouseEnter={() => {
|
||||
console.log("Mouse Entered")
|
||||
}}>
|
||||
<img style={{height: '200px', width: '400px'}} src={tile.preview}/>
|
||||
</button>
|
||||
))}
|
||||
{this.state.banner.length === 0 ?
|
||||
<Dropzone
|
||||
className="application-create-banner-dropzone"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(banner, rejected) => {
|
||||
this.setState({banner, rejected});
|
||||
}}
|
||||
>
|
||||
<i className="fw fw-add"></i>
|
||||
</Dropzone> : <div/>
|
||||
}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
<div className="save-info">
|
||||
<Button>Save</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default GeneralInfo;
|
||||
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {Button, FormGroup, FormText, Input, Label, Row} from "reactstrap";
|
||||
import UploadPackage from "./UploadPackage";
|
||||
|
||||
class CreateRelease extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.onTestMethodChange = this.onTestMethodChange.bind(this);
|
||||
this.showUploadArtifacts = this.showUploadArtifacts.bind(this);
|
||||
this.onBackClick = this.onBackClick.bind(this);
|
||||
this.onBackToRelease = this.onBackToRelease.bind(this);
|
||||
this.state = {
|
||||
open: true,
|
||||
hiddenMain: false
|
||||
}
|
||||
}
|
||||
|
||||
onTestMethodChange(event) {
|
||||
let type = event.target.value;
|
||||
if (type !== 'open') {
|
||||
this.setState({open: false})
|
||||
} else {
|
||||
this.setState({open: true})
|
||||
}
|
||||
}
|
||||
|
||||
showUploadArtifacts() {
|
||||
this.setState({hiddenMain: true})
|
||||
}
|
||||
|
||||
onBackClick() {
|
||||
this.props.handleBack();
|
||||
}
|
||||
|
||||
onBackToRelease() {
|
||||
this.setState({hiddenMain: false});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {channel} = this.props;
|
||||
console.log(channel);
|
||||
return (
|
||||
<div>
|
||||
|
||||
{this.state.hiddenMain ?
|
||||
<div>
|
||||
<UploadPackage
|
||||
backToRelease={this.onBackToRelease}
|
||||
selectedChannel={channel}
|
||||
/>
|
||||
</div> :
|
||||
|
||||
<div>
|
||||
<Row>
|
||||
<div className="release-header">
|
||||
<a onClick={this.onBackClick}>{"<-"}</a>
|
||||
<span id="create-release-header">
|
||||
<strong>{channel} Release</strong>
|
||||
</span>
|
||||
</div>
|
||||
</Row>
|
||||
<Row>
|
||||
<div className="release-create">
|
||||
<div>
|
||||
<span>
|
||||
<strong>Create Release</strong>
|
||||
</span>
|
||||
<p>
|
||||
{channel === 'Production' ? "" :
|
||||
"You could create " + channel + " release for your application and let " +
|
||||
"the test users to test the application for it's stability."}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button id="create-release-btn" onClick={this.showUploadArtifacts}>Create a {channel} Release</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
{channel !== 'Production' ?
|
||||
<Row>
|
||||
<div>
|
||||
<span>
|
||||
<strong>Manage Test Method</strong>
|
||||
</span>
|
||||
<p>
|
||||
This section allows you to change the test method and the users who would be
|
||||
able to test your application.
|
||||
</p>
|
||||
<div>
|
||||
<form>
|
||||
<FormGroup>
|
||||
<Label for="test-method">Test Method*</Label>
|
||||
<Input
|
||||
required
|
||||
type="select"
|
||||
name="testMethod"
|
||||
id="test-method"
|
||||
onChange={this.onTestMethodChange}
|
||||
>
|
||||
<option value="open">Open {channel}</option>
|
||||
<option value="closed">Closed {channel}</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
{!this.state.open ? (
|
||||
<FormGroup>
|
||||
<Label for="user-list">Users List*</Label>
|
||||
<Input
|
||||
required
|
||||
name="userList"
|
||||
id="user-list"
|
||||
type="text"
|
||||
/>
|
||||
<FormText color="muted">
|
||||
Provide a comma separated list of email
|
||||
addresses.
|
||||
</FormText>
|
||||
</FormGroup>
|
||||
) : <div/>}
|
||||
<FormGroup>
|
||||
<Label for="app-title">Feedback Method*</Label>
|
||||
<Input
|
||||
required
|
||||
name="appName"
|
||||
id="app-title"
|
||||
/>
|
||||
<FormText color="muted">
|
||||
Provide an Email address or a URL for your users to provide
|
||||
feedback on the application.
|
||||
</FormText>
|
||||
</FormGroup>
|
||||
<div>
|
||||
<Button className="form-btn">Save</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</Row> :
|
||||
<div/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CreateRelease.propTypes = {
|
||||
channel: PropTypes.string,
|
||||
handleBack: PropTypes.func
|
||||
};
|
||||
|
||||
export default CreateRelease;
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {Button, Col, FormGroup, Input, Label, Row} from "reactstrap";
|
||||
|
||||
class UploadPackage extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.handleBack = this.handleBack.bind(this)
|
||||
}
|
||||
|
||||
handleBack() {
|
||||
this.props.onBackToRelease();
|
||||
}
|
||||
|
||||
render() {
|
||||
const {selectedChannel} = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<div className="release-header">
|
||||
<a onClick={this.handleBack}>{"<-"}</a>
|
||||
<span id="create-release-header">
|
||||
<strong>New Release for {selectedChannel}</strong>
|
||||
</span>
|
||||
</div>
|
||||
</Row>
|
||||
<Row>
|
||||
<div className="release-header">
|
||||
<span id="create-release-header">
|
||||
<strong>Upload Package File</strong>
|
||||
</span>
|
||||
</div>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs="3">
|
||||
<Button>Upload</Button>
|
||||
</Col>
|
||||
<Col xs="3">
|
||||
<Button>Select from package library</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<div className="release-detail-content">
|
||||
<form>
|
||||
<FormGroup>
|
||||
<Label>Release Name *</Label>
|
||||
<Input
|
||||
required
|
||||
type="text"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label>Release Notes *</Label>
|
||||
<Input
|
||||
required
|
||||
type="textarea"
|
||||
/>
|
||||
</FormGroup>
|
||||
<div className="form-btn">
|
||||
<Button>Send for Review</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UploadPackage.protoTypes = {
|
||||
backToRelease: PropTypes.func,
|
||||
channel: PropTypes.string
|
||||
};
|
||||
|
||||
export default UploadPackage;
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {Button, Col, Row} from "reactstrap";
|
||||
import CreateRelease from "../Create/CreateRelease";
|
||||
|
||||
class ReleaseManager extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.getNoReleaseContent = this.getNoReleaseContent.bind(this);
|
||||
this.onCreateRelease = this.onCreateRelease.bind(this);
|
||||
this.onBackClick = this.onBackClick.bind(this);
|
||||
this.state = {
|
||||
createRelease: false,
|
||||
onGoing: ""
|
||||
}
|
||||
}
|
||||
|
||||
onCreateRelease(event) {
|
||||
event.preventDefault();
|
||||
this.setState({createRelease: true, onGoing: event.target.value})
|
||||
}
|
||||
|
||||
onBackClick() {
|
||||
this.setState({createRelease: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a generic message saying there are no current release in the specified release channel.
|
||||
* */
|
||||
getNoReleaseContent(release) {
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Col sm="12" md={{size: 8, offset: 4}}>
|
||||
<p>You have no on-going {release} Releases!</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col sm="12" md={{size: 8, offset: 5}}>
|
||||
<Button
|
||||
className="button-add"
|
||||
id={release.toLowerCase()}
|
||||
value={release}
|
||||
onClick={this.onCreateRelease}
|
||||
>
|
||||
Create a Release
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{this.state.createRelease ?
|
||||
<CreateRelease
|
||||
channel={this.state.onGoing}
|
||||
handleBack={this.onBackClick}
|
||||
/> :
|
||||
<div id="release-mgt-content">
|
||||
<Row>
|
||||
<Col sm="12">
|
||||
<div className="release" id="production">
|
||||
<span>Production Releases</span>
|
||||
<div className="release-content">
|
||||
<div className="release-inner">
|
||||
{this.getNoReleaseContent("Production")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col sm="12">
|
||||
<div className="release" id="beta">
|
||||
<span>Beta Releases</span>
|
||||
<div className="release-content">
|
||||
<div className="release-inner">
|
||||
{this.getNoReleaseContent("Beta")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col sm="12">
|
||||
<div className="release" id="alpha">
|
||||
<span>Alpha Releases</span>
|
||||
<div className="release-content">
|
||||
<div className="release-inner">
|
||||
{this.getNoReleaseContent("Alpha")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ReleaseManager;
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import {Col, Row} from "reactstrap";
|
||||
|
||||
/**
|
||||
* Application view component.
|
||||
* Shows the details of the application.
|
||||
* */
|
||||
class ApplicationView extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
application: {}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props, nextProps) {
|
||||
this.setState({application: props.application});
|
||||
console.log(props.application, nextProps)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
//TODO: Download image artifacts.
|
||||
}
|
||||
|
||||
handleEdit() {
|
||||
this.props.history.push("/assets/apps/edit/" + this.state.application.uuid);
|
||||
}
|
||||
|
||||
render() {
|
||||
const platform = this.state.application;
|
||||
console.log(platform);
|
||||
|
||||
return (
|
||||
<div id="application-view-content">
|
||||
<div id="application-view-row">
|
||||
<Row>
|
||||
<Col>
|
||||
<div id="app-icon">
|
||||
|
||||
</div>
|
||||
</Col>
|
||||
<Col>
|
||||
<Row>
|
||||
<span><strong>Facebook</strong></span>
|
||||
</Row>
|
||||
<Row>
|
||||
<span className="app-updated-date">Last updated on 2017-09-23</span>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<div id="application-view-row">
|
||||
<Row>
|
||||
<Col>
|
||||
<span className="app-install-count">2k Installs</span>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
<i className="fw fw-star"></i>
|
||||
<i className="fw fw-star"></i>
|
||||
<i className="fw fw-star"></i>
|
||||
<i className="fw fw-star"></i>
|
||||
</Col>
|
||||
<Col>
|
||||
<a href="#">View in Store</a>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<hr/>
|
||||
<div id="application-view-row">
|
||||
<Row>
|
||||
<Col>
|
||||
<span><strong>Description: </strong></span>
|
||||
</Col>
|
||||
<Col>
|
||||
<p>sdfjlkdsjfsjdfjsdf sfjdslkjfdsflkjdsfslkdjfl j</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
<span><strong>Tags: </strong></span>
|
||||
</Col>
|
||||
<Col>
|
||||
<p>[list of tags...]</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
<span><strong>Release: </strong></span>
|
||||
</Col>
|
||||
<Col>
|
||||
<p>Production</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
<span><strong>Version: </strong></span>
|
||||
</Col>
|
||||
<Col>
|
||||
<p>v1.0</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(ApplicationView);
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import Theme from '../../../theme';
|
||||
|
||||
/**
|
||||
* Component for holding uploaded image.
|
||||
* This component has the feature to remove selected image from the array.
|
||||
* */
|
||||
class AppImage extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.removeImage = this.removeImage.bind(this);
|
||||
this.scriptId = "appImage";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the parent method to remove the selected image.
|
||||
* @param event: The click event of the component.
|
||||
* */
|
||||
removeImage(event) {
|
||||
event.preventDefault();
|
||||
this.props.onRemove(event.target.id);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {image, imageId} = this.props;
|
||||
return (
|
||||
<div className="image-container" style={this.props.imageStyles}>
|
||||
<img src={image} className="image" id={imageId}/>
|
||||
<div className="btn-content">
|
||||
<i className="close-btn" id={imageId} onClick={this.removeImage}>X</i>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AppImage.propTypes = {
|
||||
image: PropTypes.string,
|
||||
imageId: PropTypes.string,
|
||||
onRemove: PropTypes.func,
|
||||
imageStyles: PropTypes.object
|
||||
};
|
||||
|
||||
export default AppImage;
|
35
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Overview/PublisherOverview.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/Chip/Chip.jsx
35
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/Overview/PublisherOverview.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/Chip/Chip.jsx
58
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable/DataTable.jsx
58
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable/DataTable.jsx
36
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTableHeader.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable/DataTableHeader.jsx
36
components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTableHeader.jsx → components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/src/main/resources/publisher/src/components/UIComponents/DataTable/DataTableHeader.jsx
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import Theme from '../../../theme';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import IconButton from 'material-ui/IconButton';
|
||||
import Create from 'material-ui/svg-icons/content/create'
|
||||
import {TableRow, TableRowColumn} from 'material-ui/Table';
|
||||
import Avatar from 'material-ui/Avatar';
|
||||
|
||||
|
||||
/**
|
||||
* Data table row component.
|
||||
* This component created a row in the data table according to the props.
|
||||
* */
|
||||
class DataTableRow extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
dataItem: {}
|
||||
};
|
||||
this.scriptId = "data-table";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({dataItem: this.props.dataItem});
|
||||
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the click event on the data table row.
|
||||
* */
|
||||
handleClick(event) {
|
||||
event.stopPropagation();
|
||||
this.props.handleClick(this.state.dataItem.id);
|
||||
}
|
||||
|
||||
handleBtnClick(event) {
|
||||
event.stopPropagation();
|
||||
console.log(event.target['id'])
|
||||
this.props.handleButtonClick(event.target['id']);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {dataItem} = this.state;
|
||||
return (
|
||||
<TableRow
|
||||
key={this.props.key}
|
||||
onClick={this.handleClick.bind(this)}
|
||||
>
|
||||
<TableRowColumn
|
||||
className="datatableRowColumn"
|
||||
key={Math.random()}
|
||||
>
|
||||
<Avatar>{dataItem.name}</Avatar>
|
||||
</TableRowColumn>
|
||||
{Object.keys(dataItem).map((key) => {
|
||||
if (key !== 'id') {
|
||||
return (
|
||||
<TableRowColumn
|
||||
className="datatableRowColumn"
|
||||
key={key}
|
||||
>
|
||||
{dataItem[key]}
|
||||
</TableRowColumn>)
|
||||
}
|
||||
|
||||
})}
|
||||
<TableRowColumn
|
||||
className="datatableRowColumn"
|
||||
key={dataItem.id}
|
||||
>
|
||||
<IconButton id={dataItem.id} onClick={this.handleBtnClick.bind(this)}>
|
||||
<Create id={dataItem.id}/>
|
||||
</IconButton>
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DataTableRow.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
data: PropTypes.object
|
||||
};
|
||||
|
||||
export default DataTableRow;
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import {TableRow, TableRowColumn} from 'material-ui/Table';
|
||||
|
||||
/**
|
||||
* Data table row component.
|
||||
* This component created a row in the data table according to the props.
|
||||
* */
|
||||
class DataTableRow extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
dataItem: {}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({dataItem: this.props.dataItem})
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the click event on the data table row.
|
||||
* */
|
||||
_handleClick() {
|
||||
this.props.handleClick(this.state.dataItem.id);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {dataItem} = this.state;
|
||||
return (
|
||||
<TableRow key={this.props.key} onClick={this._handleClick.bind(this)} >
|
||||
{Object.keys(dataItem).map((key) => {
|
||||
if (key !== 'id') {
|
||||
return <TableRowColumn style={{alignItems: 'center'}}
|
||||
key={key}>{dataItem[key]}</TableRowColumn>
|
||||
} else {
|
||||
return <TableRowColumn key={key}/>
|
||||
}
|
||||
|
||||
} )}
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DataTableRow.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
data: PropTypes.object
|
||||
};
|
||||
|
||||
export default DataTableRow;
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import Theme from '../../../theme'
|
||||
|
||||
/**
|
||||
* Custom React component for Application View.
|
||||
* */
|
||||
class Drawer extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.closeDrawer = this.closeDrawer.bind(this);
|
||||
this.scriptId = "drawer";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the drawer.
|
||||
* */
|
||||
closeDrawer() {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div id="app-view" className="app-view-drawer" style={this.props.style}>
|
||||
<a onClick={this.closeDrawer} className="drawer-close-btn"><i className="fw fw-uncheck"></i></a>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Drawer.propTypes = {
|
||||
style: PropTypes.object,
|
||||
children: PropTypes.node,
|
||||
onClose: PropTypes.func
|
||||
};
|
||||
|
||||
export default Drawer;
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import Theme from '../../../theme';
|
||||
|
||||
/**
|
||||
* Floating Action button.
|
||||
* */
|
||||
class FloatingButton extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.scriptId = "floatingButton";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
handleClick(event) {
|
||||
this.props.onClick(event);
|
||||
}
|
||||
|
||||
render() {
|
||||
let classes = 'btn-circle ' + this.props.className;
|
||||
return (
|
||||
<div className={classes} onClick={this.handleClick.bind(this)}>
|
||||
<i className="fw fw-add"></i>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FloatingButton.propTypes = {
|
||||
classNames: PropTypes.string,
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
export default FloatingButton;
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import Dropzone from "react-dropzone";
|
||||
import {Row} from "reactstrap";
|
||||
import Theme from '../../../theme';
|
||||
|
||||
|
||||
class ImageUploader extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.setImages = this.setImages.bind(this);
|
||||
this.state = {
|
||||
images: []
|
||||
};
|
||||
this.scriptId = "imageUploader";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
setImages(images) {
|
||||
this.props.setImages(images);
|
||||
}
|
||||
|
||||
render() {
|
||||
let {images, height, width, accepted, multiple, maxAmount} = this.props;
|
||||
return (
|
||||
<div id="screenshot-container">
|
||||
<Row>
|
||||
{images.map((tile) => (
|
||||
<input type="image" src={tile[0].preview} onClick=""/>
|
||||
)
|
||||
)}
|
||||
</Row>
|
||||
|
||||
{this.state.screenshots.length < maxAmount ?
|
||||
<Dropzone
|
||||
className="add-image"
|
||||
accept="image/jpeg, image/png"
|
||||
onDrop={(accepted, rejected) => {
|
||||
this.setImages(accepted);
|
||||
}}
|
||||
>
|
||||
<p className="add-image-symbol">+</p>
|
||||
</Dropzone> : <div/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ImageUploader.prototypes = {
|
||||
height: PropTypes.string,
|
||||
width: PropTypes.string,
|
||||
accepted: PropTypes.array,
|
||||
multiple: PropTypes.bool,
|
||||
maxAmount: PropTypes.number,
|
||||
setImages: PropTypes.func
|
||||
};
|
||||
|
||||
|
||||
export default ImageUploader;
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Col, Row} from "reactstrap";
|
||||
import Theme from '../../../theme'
|
||||
|
||||
class NotificationItem extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.scriptId = "notification";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Col>
|
||||
<div className="notification-app-icon small">
|
||||
<img/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col>
|
||||
<p>Your application, Facebook has been published.</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NotificationItem;
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Col, Row} from "reactstrap";
|
||||
import './notification.css';
|
||||
import Theme from '../../../theme'
|
||||
|
||||
class NotificationView extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.scriptId = "notification";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="notification-view-content">
|
||||
<div>
|
||||
<Row id="notification-content">
|
||||
<Col xs="3">
|
||||
<div className="notification-app-icon medium">
|
||||
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs="9">
|
||||
<Row>
|
||||
<span><strong>Application Name</strong></span>
|
||||
</Row>
|
||||
<Row>
|
||||
<span>Version 1.0</span>
|
||||
</Row>
|
||||
<Row>
|
||||
<p id="app-reject-msg">Your Application was rejected</p>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<hr/>
|
||||
<Row id="notification-content">
|
||||
<Col xs="12">
|
||||
<p>Following validations were detected in your review submission.
|
||||
Please attend to them and re-submit</p>
|
||||
<ul>
|
||||
<li>sdjjfsdfsdfkjs shdfjhlkds hflkhfdslkd </li>
|
||||
<li>sdfkds jfdsljfklsdfjksdjlksdjdlkf</li>
|
||||
<li>sfksdf slkjskd jfjds lkfjdsfdsfdslkf sjf lkdsf</li>
|
||||
<li>skfjslkdjfsdjfjksldjf sdkl jflkds jfkslfjs</li>
|
||||
<li>ksdf jks;kshflk hlkjhds lkjhdsklhsd lkf</li>
|
||||
<li> jsdljflksd jfklsdfskljfkjshf;ks ldj</li>
|
||||
</ul>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NotificationView;
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Theme from '../../../theme';
|
||||
|
||||
class Switch extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.scriptId = "switch";
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/**
|
||||
*Loading the theme files based on the the user-preference.
|
||||
*/
|
||||
Theme.insertThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Theme.removeThemingScripts(this.scriptId);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {height, width} = this.props;
|
||||
return (
|
||||
<label className="switch">
|
||||
<input type="checkbox" onChange={this.props.onChange}/>
|
||||
<span className="slider round"></span>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Switch;
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"theme" : {
|
||||
"current" : "default",
|
||||
"default" : "lightBaseTheme",
|
||||
"custom" : "custom-theme"
|
||||
"theme": {
|
||||
"type": "default",
|
||||
"value": "lightBaseTheme"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export class ApplicationStore {};
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export class PlatformStore{};
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export class ReviewStore{};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue