Merge branch 'application-mgt-new' of https://gitlab.com/entgra/carbon-device-mgt into application-mgt-new
4
.gitignore
vendored
@ -35,4 +35,8 @@ components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react
|
|||||||
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/dist/
|
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/dist/
|
||||||
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package-lock.json
|
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package-lock.json
|
||||||
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/tmp/
|
components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/tmp/
|
||||||
|
components/device-mgt/io.entgra.device.mgt.ui/react-app/node_modules/
|
||||||
|
components/device-mgt/io.entgra.device.mgt.ui/react-app/dist/
|
||||||
|
components/device-mgt/io.entgra.device.mgt.ui/react-app/package-lock.json
|
||||||
|
components/device-mgt/io.entgra.device.mgt.ui/react-app/tmp/
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
private static final String X_JWT_ASSERTION = "X-JWT-Assertion";
|
private static final String X_JWT_ASSERTION = "X-JWT-Assertion";
|
||||||
private static final String JWTTOKEN = "JWTToken";
|
private static final String JWTTOKEN = "JWTToken";
|
||||||
private static final String AUTHORIZATION = "Authorization";
|
private static final String AUTHORIZATION = "Authorization";
|
||||||
private static final String BEARER = "Bearer ";
|
private static final String BEARER = "Basic ";
|
||||||
private static final String CONTENT_TYPE = "Content-Type";
|
private static final String CONTENT_TYPE = "Content-Type";
|
||||||
|
|
||||||
private IOTServerConfiguration iotServerConfiguration;
|
private IOTServerConfiguration iotServerConfiguration;
|
||||||
@ -95,7 +95,7 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
log.debug("Verify Cert:\n" + mdmSignature);
|
log.debug("Verify Cert:\n" + mdmSignature);
|
||||||
}
|
}
|
||||||
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + "ios");
|
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + "ios");
|
||||||
Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker);
|
Map<String, String> certVerifyHeaders = this.setHeaders();
|
||||||
|
|
||||||
Certificate certificate = new Certificate();
|
Certificate certificate = new Certificate();
|
||||||
certificate.setPem(mdmSignature);
|
certificate.setPem(mdmSignature);
|
||||||
@ -127,7 +127,7 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
|
|
||||||
String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim());
|
String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim());
|
||||||
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType);
|
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType);
|
||||||
Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker);
|
Map<String, String> certVerifyHeaders = this.setHeaders();
|
||||||
Certificate certificate = new Certificate();
|
Certificate certificate = new Certificate();
|
||||||
certificate.setPem(subjectDN);
|
certificate.setPem(subjectDN);
|
||||||
certificate.setTenantId(tenantId);
|
certificate.setTenantId(tenantId);
|
||||||
@ -157,7 +157,7 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
}
|
}
|
||||||
String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim());
|
String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim());
|
||||||
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType);
|
URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType);
|
||||||
Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker);
|
Map<String, String> certVerifyHeaders = this.setHeaders();
|
||||||
|
|
||||||
Certificate certificate = new Certificate();
|
Certificate certificate = new Certificate();
|
||||||
certificate.setPem(encodedPem);
|
certificate.setPem(encodedPem);
|
||||||
@ -184,9 +184,6 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
log.error("Error while processing certificate.", e);
|
log.error("Error while processing certificate.", e);
|
||||||
return false;
|
return false;
|
||||||
} catch (APIMCertificateMGTException e) {
|
|
||||||
log.error("Error while processing certificate.", e);
|
|
||||||
return false;
|
|
||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
log.error("Certificate issue occurred when generating converting PEM to x509Certificate", e);
|
log.error("Certificate issue occurred when generating converting PEM to x509Certificate", e);
|
||||||
return false;
|
return false;
|
||||||
@ -212,9 +209,9 @@ public class AuthenticationHandler extends AbstractHandler {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> setHeaders(RESTInvoker restInvoker) throws APIMCertificateMGTException {
|
private Map<String, String> setHeaders() {
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
String accessToken = Utils.getAccessToken(iotServerConfiguration, restInvoker);
|
String accessToken = Utils.getBase64EncodedToken(iotServerConfiguration);
|
||||||
map.put(AUTHORIZATION, BEARER + accessToken);
|
map.put(AUTHORIZATION, BEARER + accessToken);
|
||||||
map.put(CONTENT_TYPE, "application/json");
|
map.put(CONTENT_TYPE, "application/json");
|
||||||
return map;
|
return map;
|
||||||
|
|||||||
@ -135,38 +135,14 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class get the access token from the key manager.
|
* This method is used to get the base64 encoded token.
|
||||||
*
|
*
|
||||||
* @param iotServerConfiguration Instance of the IoTsererConfiguration.
|
* @param iotServerConfiguration Instance of the IoTsererConfiguration.
|
||||||
* @return Access token will be returned.
|
* @return Access token will be returned.
|
||||||
* @throws APIMCertificateMGTException
|
|
||||||
*/
|
*/
|
||||||
public static String getAccessToken(IOTServerConfiguration iotServerConfiguration, RESTInvoker restInvoker)
|
public static String getBase64EncodedToken(IOTServerConfiguration iotServerConfiguration) {
|
||||||
throws APIMCertificateMGTException {
|
return Base64.encode((iotServerConfiguration.getUsername() + ":" + iotServerConfiguration.getPassword()).
|
||||||
try {
|
getBytes());
|
||||||
if (clientId == null || clientSecret == null) {
|
|
||||||
getClientSecretes(iotServerConfiguration, restInvoker);
|
|
||||||
}
|
|
||||||
URI tokenUrl = new URI(iotServerConfiguration.getOauthTokenEndpoint());
|
|
||||||
String tokenContent = "grant_type=password&username=" + iotServerConfiguration.getUsername() + "&password=" +
|
|
||||||
iotServerConfiguration.getPassword() + "&scope=activity-view";
|
|
||||||
String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes());
|
|
||||||
Map<String, String> tokenHeaders = new HashMap<>();
|
|
||||||
tokenHeaders.put("Authorization", tokenBasicAuth);
|
|
||||||
tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
|
|
||||||
RESTResponse response = restInvoker.invokePOST(tokenUrl, tokenHeaders, tokenContent);
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Token response:" + response.getContent());
|
|
||||||
}
|
|
||||||
JSONObject jsonResponse = new JSONObject(response.getContent());
|
|
||||||
return jsonResponse.getString("access_token");
|
|
||||||
|
|
||||||
} catch (URISyntaxException | IOException e) {
|
|
||||||
throw new APIMCertificateMGTException("Error occurred while trying to call oauth token endpoint", e);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
throw new APIMCertificateMGTException("Error occurred while converting the json to object", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -92,8 +92,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert");
|
transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getDCRResponse());
|
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(getValidationResponse());
|
this.mockClient.setResponse(getValidationResponse());
|
||||||
boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice"));
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice"));
|
||||||
@ -107,7 +105,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, "Test Header");
|
transportHeaders.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, "Test Header");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(getValidationResponse());
|
this.mockClient.setResponse(getValidationResponse());
|
||||||
boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice"));
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice"));
|
||||||
@ -121,7 +118,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.MUTUAL_AUTH_HEADER, "Test Header");
|
transportHeaders.put(AuthConstants.MUTUAL_AUTH_HEADER, "Test Header");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(getValidationResponse());
|
this.mockClient.setResponse(getValidationResponse());
|
||||||
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
||||||
@ -141,7 +137,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(getValidationResponse());
|
this.mockClient.setResponse(getValidationResponse());
|
||||||
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
||||||
@ -156,7 +151,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(getInvalidResponse());
|
this.mockClient.setResponse(getInvalidResponse());
|
||||||
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
||||||
@ -185,7 +179,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest {
|
|||||||
HashMap<String, String> transportHeaders = new HashMap<>();
|
HashMap<String, String> transportHeaders = new HashMap<>();
|
||||||
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem");
|
||||||
setMockClient();
|
setMockClient();
|
||||||
this.mockClient.setResponse(getAccessTokenReponse());
|
|
||||||
this.mockClient.setResponse(null);
|
this.mockClient.setResponse(null);
|
||||||
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration,
|
||||||
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
transportHeaders, "https://test.com/testservice/device-mgt/testdevice");
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
@ -172,6 +172,10 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
|||||||
sql += " AND AP_APP.DEVICE_TYPE_ID = ?";
|
sql += " AND AP_APP.DEVICE_TYPE_ID = ?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.getLimit() == -1) {
|
||||||
|
sql = sql.replace("LIMIT ? OFFSET ?", "");
|
||||||
|
}
|
||||||
|
|
||||||
String sortingOrder = "ASC";
|
String sortingOrder = "ASC";
|
||||||
if (!StringUtils.isEmpty(filter.getSortBy() )) {
|
if (!StringUtils.isEmpty(filter.getSortBy() )) {
|
||||||
sortingOrder = filter.getSortBy();
|
sortingOrder = filter.getSortBy();
|
||||||
@ -182,12 +186,14 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
|||||||
Connection conn = this.getDBConnection();
|
Connection conn = this.getDBConnection();
|
||||||
try (PreparedStatement stmt = conn.prepareStatement(sql);
|
try (PreparedStatement stmt = conn.prepareStatement(sql);
|
||||||
){
|
){
|
||||||
if (filter.getLimit() == 0) {
|
if (filter.getLimit() != -1) {
|
||||||
stmt.setInt(paramIndex++, 100);
|
if (filter.getLimit() == 0) {
|
||||||
} else {
|
stmt.setInt(paramIndex++, 100);
|
||||||
stmt.setInt(paramIndex++, filter.getLimit());
|
} else {
|
||||||
|
stmt.setInt(paramIndex++, filter.getLimit());
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIndex++, filter.getOffset());
|
||||||
}
|
}
|
||||||
stmt.setInt(paramIndex++, filter.getOffset());
|
|
||||||
stmt.setInt(paramIndex++, tenantId);
|
stmt.setInt(paramIndex++, tenantId);
|
||||||
|
|
||||||
if (filter.getAppType() != null && !filter.getAppType().isEmpty()) {
|
if (filter.getAppType() != null && !filter.getAppType().isEmpty()) {
|
||||||
|
|||||||
@ -147,9 +147,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
String msg = "Error occurred when obtaining database connection for updating the device subscriptions of "
|
String msg = "Error occurred while executing SQL to update the device subscriptions of application. "
|
||||||
+ "application. Updated by: " + updateBy + " and updating action triggered from "
|
+ "Updated by: " + updateBy + " and updating action triggered from " + actionTriggeredFrom;
|
||||||
+ actionTriggeredFrom;
|
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
}
|
}
|
||||||
@ -356,7 +355,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
String msg = "Error occurred while getting device subscription data for application ID: " + appReleaseId;
|
String msg = "Error occurred while while running SQL to get device subscription data for application ID: " + appReleaseId;
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
}
|
}
|
||||||
@ -618,12 +617,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
stmt.executeBatch();
|
stmt.executeBatch();
|
||||||
}
|
}
|
||||||
} catch (DBConnectionException e) {
|
} catch (DBConnectionException e) {
|
||||||
String msg = "Error occurred while obtaining the DB connection to update the user subscriptions of "
|
String msg = "Error occurred while obtaining the DB connection to update the user/role/group subscriptions "
|
||||||
+ "application.";
|
+ "of application.";
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
String msg = "Error occurred when obtaining database connection for updating the user subscriptions of "
|
String msg = "Error occurred while processing SQL to update the user/role/group subscriptions of "
|
||||||
+ "application.";
|
+ "application.";
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
@ -691,8 +690,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
String msg = "Error occurred when obtaining database connection for updating the subscription status of the "
|
String msg = "Error occurred when processing SQL to update the subscription status of the device "
|
||||||
+ "device subscription.";
|
+ "subscription.";
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
<Extension name="ApplicationStorageManager">
|
<Extension name="ApplicationStorageManager">
|
||||||
<ClassName>org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl</ClassName>
|
<ClassName>org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl</ClassName>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Parameter name="StoragePath">repository/resources/apps/</Parameter>
|
<Parameter name="StoragePath">/tmp/apps/</Parameter>
|
||||||
<Parameter name="MaxScreenShotCount">6</Parameter>
|
<Parameter name="MaxScreenShotCount">6</Parameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</Extension>
|
</Extension>
|
||||||
|
|||||||
@ -30,14 +30,8 @@ import org.wso2.carbon.apimgt.annotations.api.Scope;
|
|||||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||||
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
|
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
|
||||||
import org.wso2.carbon.device.application.mgt.common.PaginationResult;
|
import org.wso2.carbon.device.application.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.Review;
|
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
@ -69,13 +63,13 @@ tags = {
|
|||||||
scopes = {
|
scopes = {
|
||||||
@Scope(
|
@Scope(
|
||||||
name = "Update a Review",
|
name = "Update a Review",
|
||||||
description = "Update a Review of applications.",
|
description = "Update a Review of application.",
|
||||||
key = "perm:admin:app:review:update",
|
key = "perm:admin:app:review:update",
|
||||||
permissions = {"/app-mgt/publisher/admin/review/update"}
|
permissions = {"/app-mgt/publisher/admin/review/update"}
|
||||||
),
|
),
|
||||||
@Scope(
|
@Scope(
|
||||||
name = "Get Review Details",
|
name = "Get Review Details",
|
||||||
description = "Get review details of applications.",
|
description = "Get review details of application.",
|
||||||
key = "perm:admin:app:review:view",
|
key = "perm:admin:app:review:view",
|
||||||
permissions = {"/app-mgt/publisher/admin/review/view"}
|
permissions = {"/app-mgt/publisher/admin/review/view"}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -49,11 +49,11 @@ import javax.ws.rs.core.Response;
|
|||||||
@SwaggerDefinition(
|
@SwaggerDefinition(
|
||||||
info = @Info(
|
info = @Info(
|
||||||
version = "1.0.0",
|
version = "1.0.0",
|
||||||
title = "ApplicationDTO Storage Management Service",
|
title = "Application Storage Management Service",
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(properties = {
|
@Extension(properties = {
|
||||||
@ExtensionProperty(name = "name", value = "ApplicationStorageManagementService"),
|
@ExtensionProperty(name = "name", value = "ApplicationStorageManagementService"),
|
||||||
@ExtensionProperty(name = "context", value = "/api/application-mgt-store/v1.0/store-applications"),
|
@ExtensionProperty(name = "context", value = "/api/application-mgt-store/v1.0/applications"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@ -65,7 +65,7 @@ import javax.ws.rs.core.Response;
|
|||||||
@Scopes(
|
@Scopes(
|
||||||
scopes = {
|
scopes = {
|
||||||
@Scope(
|
@Scope(
|
||||||
name = "Get ApplicationDTO Details",
|
name = "Get Application Details",
|
||||||
description = "Get application details",
|
description = "Get application details",
|
||||||
key = "perm:app:store:view",
|
key = "perm:app:store:view",
|
||||||
permissions = {"/app-mgt/store/application/view"}
|
permissions = {"/app-mgt/store/application/view"}
|
||||||
@ -73,8 +73,8 @@ import javax.ws.rs.core.Response;
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
@Path("/applications")
|
@Path("/applications")
|
||||||
@Api(value = "ApplicationDTO Management", description = "This API carries all app store management related operations " +
|
@Api(value = "Application Management", description = "This API carries all app store management related operations such"
|
||||||
"such as get all the applications etc.")
|
+ " as get all the applications etc.")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public interface ApplicationManagementAPI {
|
public interface ApplicationManagementAPI {
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ public interface ApplicationManagementAPI {
|
|||||||
httpMethod = "GET",
|
httpMethod = "GET",
|
||||||
value = "get all applications",
|
value = "get all applications",
|
||||||
notes = "This will get all applications",
|
notes = "This will get all applications",
|
||||||
tags = "ApplicationDTO Management",
|
tags = "Application Management",
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(properties = {
|
@Extension(properties = {
|
||||||
@ExtensionProperty(name = SCOPE, value = "perm:app:store:view")
|
@ExtensionProperty(name = SCOPE, value = "perm:app:store:view")
|
||||||
@ -129,7 +129,7 @@ public interface ApplicationManagementAPI {
|
|||||||
httpMethod = "GET",
|
httpMethod = "GET",
|
||||||
value = "get the application of requesting application type",
|
value = "get the application of requesting application type",
|
||||||
notes = "This will get the application identified by the application type and name, if exists",
|
notes = "This will get the application identified by the application type and name, if exists",
|
||||||
tags = "ApplicationDTO Management",
|
tags = "Application Management",
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(properties = {
|
@Extension(properties = {
|
||||||
@ExtensionProperty(name = SCOPE, value = "perm:app:store:view")
|
@ExtensionProperty(name = SCOPE, value = "perm:app:store:view")
|
||||||
@ -144,7 +144,7 @@ public interface ApplicationManagementAPI {
|
|||||||
response = ApplicationDTO.class),
|
response = ApplicationDTO.class),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
code = 404,
|
code = 404,
|
||||||
message = "ApplicationDTO not found"),
|
message = "Application not found"),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
code = 500,
|
code = 500,
|
||||||
message = "Internal Server Error. \n Error occurred while getting relevant application.",
|
message = "Internal Server Error. \n Error occurred while getting relevant application.",
|
||||||
|
|||||||
@ -37,6 +37,10 @@
|
|||||||
<param-name>doAuthentication</param-name>
|
<param-name>doAuthentication</param-name>
|
||||||
<param-value>true</param-value>
|
<param-value>true</param-value>
|
||||||
</context-param>
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>basicAuth</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
<!--publish to apim-->
|
<!--publish to apim-->
|
||||||
<context-param>
|
<context-param>
|
||||||
|
|||||||
@ -324,9 +324,14 @@ public class CertificateGenerator {
|
|||||||
KeyStoreReader keyStoreReader = new KeyStoreReader();
|
KeyStoreReader keyStoreReader = new KeyStoreReader();
|
||||||
if (distinguishedName != null && !distinguishedName.isEmpty()) {
|
if (distinguishedName != null && !distinguishedName.isEmpty()) {
|
||||||
if (distinguishedName.contains("/CN=")) {
|
if (distinguishedName.contains("/CN=")) {
|
||||||
String[] dnSplits = distinguishedName.split("/CN=");
|
String[] dnSplits = distinguishedName.split("/");
|
||||||
String commonNameExtracted = dnSplits[dnSplits.length - 1];
|
for (String dnPart : dnSplits) {
|
||||||
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted);
|
if (dnPart.contains("CN=")) {
|
||||||
|
String commonNameExtracted = dnPart.replace("CN=", "");
|
||||||
|
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LdapName ldapName;
|
LdapName ldapName;
|
||||||
try {
|
try {
|
||||||
@ -711,4 +716,4 @@ public class CertificateGenerator {
|
|||||||
return generateCertificateFromCSR(privateKeyCA, certificationRequest,
|
return generateCertificateFromCSR(privateKeyCA, certificationRequest,
|
||||||
certCA.getIssuerX500Principal().getName());
|
certCA.getIssuerX500Principal().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
124
components/device-mgt/io.entgra.device.mgt.ui/pom.xml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?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.2.9-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>io.entgra.device.mgt.ui</artifactId>
|
||||||
|
<version>3.2.9-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>WSO2 Carbon - Device Management UI Component</name>
|
||||||
|
<url>http://wso2.org</url>
|
||||||
|
<description>This Component contains Device Management UI</description>
|
||||||
|
<dependencies>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<packagingExcludes>WEB-INF/lib/*cxf*.jar</packagingExcludes>
|
||||||
|
<warName>entgra</warName>
|
||||||
|
<webResources>
|
||||||
|
<resource>
|
||||||
|
<directory>${npm.output.directory}/dist</directory>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>${npm.output.directory}/public</directory>
|
||||||
|
<targetPath>public</targetPath>
|
||||||
|
</resource>
|
||||||
|
</webResources>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.github.eirslett</groupId>
|
||||||
|
<artifactId>frontend-maven-plugin</artifactId>
|
||||||
|
<version>${frontend.mave.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<workingDirectory>${npm.working.dir}</workingDirectory>
|
||||||
|
<!-- where to install npm -->
|
||||||
|
<installDirectory>${npm.install.dir}</installDirectory>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>install node and npm</id>
|
||||||
|
<goals>
|
||||||
|
<goal>install-node-and-npm</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<configuration>
|
||||||
|
<nodeVersion>${node.version}</nodeVersion>
|
||||||
|
<npmVersion>${npm.version}</npmVersion>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>npm install</id>
|
||||||
|
<goals>
|
||||||
|
<goal>npm</goal>
|
||||||
|
</goals>
|
||||||
|
<!-- Optional configuration which provides for running any npm command -->
|
||||||
|
<configuration>
|
||||||
|
<arguments>install</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>prod</id>
|
||||||
|
<goals>
|
||||||
|
<goal>npm</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<arguments>run-script ${npm.build.command}</arguments>
|
||||||
|
</configuration>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>platform-windows</id>
|
||||||
|
<activation>
|
||||||
|
<os>
|
||||||
|
<family>windows</family>
|
||||||
|
</os>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<!-- Override the executable names for Windows -->
|
||||||
|
<npm.executable>npm.cmd</npm.executable>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
<properties>
|
||||||
|
<maven.test.skip>false</maven.test.skip>
|
||||||
|
<npm.executable>npm</npm.executable>
|
||||||
|
<npm.build.command>build_prod</npm.build.command>
|
||||||
|
<npm.working.dir>./react-app</npm.working.dir>
|
||||||
|
<npm.install.dir>./react-app/tmp</npm.install.dir>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<npm.output.directory>react-app</npm.output.directory>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
module.exports = function (api) {
|
||||||
|
api.cache(true);
|
||||||
|
const presets = [ "@babel/preset-env",
|
||||||
|
"@babel/preset-react" ];
|
||||||
|
const plugins = ["@babel/plugin-proposal-class-properties"];
|
||||||
|
|
||||||
|
return {
|
||||||
|
presets,
|
||||||
|
plugins
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"name": "entgra",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Entgra device management",
|
||||||
|
"main": "App.js",
|
||||||
|
"license": "Apache License 2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^6.2.0",
|
||||||
|
"antd": "^3.22.0",
|
||||||
|
"axios": "^0.18.1",
|
||||||
|
"javascript-time-ago": "^2.0.1",
|
||||||
|
"keymirror": "^0.1.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"rc-viewer": "0.0.9",
|
||||||
|
"react-highlight-words": "^0.16.0",
|
||||||
|
"react-image-viewer-zoom": "^1.0.36",
|
||||||
|
"react-infinite-scroller": "^1.2.4",
|
||||||
|
"react-router": "^5.0.1",
|
||||||
|
"react-router-config": "^5.0.1",
|
||||||
|
"react-router-dom": "^5.0.1",
|
||||||
|
"react-scripts": "2.1.8",
|
||||||
|
"react-star-ratings": "^2.3.0",
|
||||||
|
"react-twemoji": "^0.2.3",
|
||||||
|
"react-virtualized": "^9.21.1",
|
||||||
|
"reqwest": "^2.0.5",
|
||||||
|
"storm-react-diagrams": "^5.2.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.5.4",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.5.0",
|
||||||
|
"@babel/preset-env": "^7.5.4",
|
||||||
|
"@babel/preset-react": "^7.0.0",
|
||||||
|
"@babel/register": "^7.4.4",
|
||||||
|
"babel-loader": "^8.0.6",
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"chai": "^4.1.2",
|
||||||
|
"css-loader": "^0.28.11",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-pino-logger": "^4.0.0",
|
||||||
|
"file-loader": "^2.0.0",
|
||||||
|
"html-loader": "^0.5.5",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"img-loader": "^3.0.1",
|
||||||
|
"json-loader": "^0.5.7",
|
||||||
|
"less": "^3.9.0",
|
||||||
|
"less-loader": "^4.1.0",
|
||||||
|
"mini-css-extract-plugin": "^0.5.0",
|
||||||
|
"mocha": "^5.2.0",
|
||||||
|
"mock-local-storage": "^1.0.5",
|
||||||
|
"node-env-run": "^3.0.2",
|
||||||
|
"node-sass": "^4.12.0",
|
||||||
|
"nodemon": "^1.19.1",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"pino-colada": "^1.4.5",
|
||||||
|
"postcss-loader": "^3.0.0",
|
||||||
|
"react": "^16.8.6",
|
||||||
|
"react-dom": "^16.8.6",
|
||||||
|
"react-intl": "^2.9.0",
|
||||||
|
"sass-loader": "^6.0.7",
|
||||||
|
"style-loader": "^0.18.2",
|
||||||
|
"url-loader": "^1.1.2",
|
||||||
|
"webpack": "^4.35.3",
|
||||||
|
"webpack-cli": "^3.3.5",
|
||||||
|
"webpack-dev-server": "^3.7.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --mode development --open",
|
||||||
|
"dev": "webpack --mode development",
|
||||||
|
"build": "webpack --mode production",
|
||||||
|
"watch": "webpack --watch --mode development",
|
||||||
|
"test": "react-scripts test --env=jsdom",
|
||||||
|
"eject": "react-scripts eject",
|
||||||
|
"build_prod": "NODE_ENV=production NODE_OPTIONS=--max_old_space_size=4096 webpack -p --display errors-only --hide-modules",
|
||||||
|
"build_dev": "NODE_ENV=development webpack -d --watch ",
|
||||||
|
"server": "node-env-run server --exec nodemon | pino-colada",
|
||||||
|
"dev2": "run-p server start"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"theme": {
|
||||||
|
"type": "default",
|
||||||
|
"value": "lightBaseTheme",
|
||||||
|
"logo" : "https://entgra.io/assets/images/svg/logo.svg",
|
||||||
|
"primaryColor": "rgb(24, 144, 255)"
|
||||||
|
},
|
||||||
|
"serverConfig": {
|
||||||
|
"invokerUri": "/ui-request-handler/invoke/application-mgt-entgra/v1.0",
|
||||||
|
"invoker": {
|
||||||
|
"uri": "/entgra-ui-request-handler/invoke",
|
||||||
|
"publisher": "/application-mgt-publisher/v1.0",
|
||||||
|
"entgra": "/application-mgt-entgra/v1.0",
|
||||||
|
"admin" : "",
|
||||||
|
"deviceMgt" : "/device-mgt/v1.0"
|
||||||
|
},
|
||||||
|
"loginUri": "/entgra-ui-request-handler/login",
|
||||||
|
"logoutUri": "/entgra-ui-request-handler/logout",
|
||||||
|
"platform": "entgra"
|
||||||
|
},
|
||||||
|
"defaultPlatformIcons": {
|
||||||
|
"default": {
|
||||||
|
"icon": "hdd",
|
||||||
|
"color": "#535c68",
|
||||||
|
"theme": "outlined"
|
||||||
|
},
|
||||||
|
"android": {
|
||||||
|
"icon": "android",
|
||||||
|
"color": "#7db343",
|
||||||
|
"theme": "filled"
|
||||||
|
},
|
||||||
|
"ios": {
|
||||||
|
"icon": "apple",
|
||||||
|
"color": "#535c68",
|
||||||
|
"theme": "filled"
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"icon": "windows",
|
||||||
|
"color": "#008cc4",
|
||||||
|
"theme": "filled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"short_name": "App Store",
|
||||||
|
"name": "WSO2 IoT App Store",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "images/favicon.png",
|
||||||
|
"sizes": "16x16",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "./index.html",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
||||||
15
components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.min.css
vendored
Normal file
|
After Width: | Height: | Size: 443 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,798 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 232 81" style="enable-background:new 0 0 232 81;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
.st1{clip-path:url(#SVGID_2_);fill:#308BD6;}
|
||||||
|
.st2{clip-path:url(#SVGID_2_);fill:#318CD6;}
|
||||||
|
.st3{clip-path:url(#SVGID_2_);fill:#328DD7;}
|
||||||
|
.st4{clip-path:url(#SVGID_2_);fill:#338ED7;}
|
||||||
|
.st5{clip-path:url(#SVGID_2_);fill:#348FD8;}
|
||||||
|
.st6{clip-path:url(#SVGID_2_);fill:#3590D8;}
|
||||||
|
.st7{clip-path:url(#SVGID_2_);fill:#3691D9;}
|
||||||
|
.st8{clip-path:url(#SVGID_2_);fill:#3792D9;}
|
||||||
|
.st9{clip-path:url(#SVGID_2_);fill:#3893DA;}
|
||||||
|
.st10{clip-path:url(#SVGID_2_);fill:#3994DA;}
|
||||||
|
.st11{clip-path:url(#SVGID_2_);fill:#3A95DA;}
|
||||||
|
.st12{clip-path:url(#SVGID_2_);fill:#3B96DB;}
|
||||||
|
.st13{clip-path:url(#SVGID_2_);fill:#3C97DB;}
|
||||||
|
.st14{clip-path:url(#SVGID_2_);fill:#3D98DC;}
|
||||||
|
.st15{clip-path:url(#SVGID_2_);fill:#3E99DC;}
|
||||||
|
.st16{clip-path:url(#SVGID_2_);fill:#3F9ADD;}
|
||||||
|
.st17{clip-path:url(#SVGID_2_);fill:#409BDD;}
|
||||||
|
.st18{clip-path:url(#SVGID_2_);fill:#419CDE;}
|
||||||
|
.st19{clip-path:url(#SVGID_2_);fill:#429DDE;}
|
||||||
|
.st20{clip-path:url(#SVGID_2_);fill:#439EDE;}
|
||||||
|
.st21{clip-path:url(#SVGID_2_);fill:#449FDF;}
|
||||||
|
.st22{clip-path:url(#SVGID_2_);fill:#45A0DF;}
|
||||||
|
.st23{clip-path:url(#SVGID_2_);fill:#46A1E0;}
|
||||||
|
.st24{clip-path:url(#SVGID_2_);fill:#47A2E0;}
|
||||||
|
.st25{clip-path:url(#SVGID_2_);fill:#48A4E1;}
|
||||||
|
.st26{clip-path:url(#SVGID_2_);fill:#49A5E1;}
|
||||||
|
.st27{clip-path:url(#SVGID_2_);fill:#4AA6E2;}
|
||||||
|
.st28{clip-path:url(#SVGID_2_);fill:#4BA7E2;}
|
||||||
|
.st29{clip-path:url(#SVGID_2_);fill:#4CA8E3;}
|
||||||
|
.st30{clip-path:url(#SVGID_2_);fill:#4DA9E3;}
|
||||||
|
.st31{clip-path:url(#SVGID_2_);fill:#4EAAE3;}
|
||||||
|
.st32{clip-path:url(#SVGID_2_);fill:#4FABE4;}
|
||||||
|
.st33{clip-path:url(#SVGID_2_);fill:#50ACE4;}
|
||||||
|
.st34{clip-path:url(#SVGID_2_);fill:#51ADE5;}
|
||||||
|
.st35{clip-path:url(#SVGID_2_);fill:#52AEE5;}
|
||||||
|
.st36{clip-path:url(#SVGID_2_);fill:#53AFE6;}
|
||||||
|
.st37{clip-path:url(#SVGID_2_);fill:#54B0E6;}
|
||||||
|
.st38{clip-path:url(#SVGID_2_);fill:#55B1E7;}
|
||||||
|
.st39{clip-path:url(#SVGID_2_);fill:#56B2E7;}
|
||||||
|
.st40{clip-path:url(#SVGID_2_);fill:#57B3E7;}
|
||||||
|
.st41{clip-path:url(#SVGID_2_);fill:#58B4E8;}
|
||||||
|
.st42{clip-path:url(#SVGID_2_);fill:#59B5E8;}
|
||||||
|
.st43{clip-path:url(#SVGID_2_);fill:#5AB6E9;}
|
||||||
|
.st44{clip-path:url(#SVGID_2_);fill:#5BB7E9;}
|
||||||
|
.st45{clip-path:url(#SVGID_2_);fill:#5CB8EA;}
|
||||||
|
.st46{clip-path:url(#SVGID_2_);fill:#5DB9EA;}
|
||||||
|
.st47{clip-path:url(#SVGID_2_);fill:#5EBAEB;}
|
||||||
|
.st48{clip-path:url(#SVGID_2_);fill:#5FBBEB;}
|
||||||
|
.st49{clip-path:url(#SVGID_4_);fill:#2E5E87;}
|
||||||
|
.st50{clip-path:url(#SVGID_4_);fill:#2E5F88;}
|
||||||
|
.st51{clip-path:url(#SVGID_4_);fill:#2F5F89;}
|
||||||
|
.st52{clip-path:url(#SVGID_4_);fill:#2F608A;}
|
||||||
|
.st53{clip-path:url(#SVGID_4_);fill:#30618B;}
|
||||||
|
.st54{clip-path:url(#SVGID_4_);fill:#30628C;}
|
||||||
|
.st55{clip-path:url(#SVGID_4_);fill:#31628D;}
|
||||||
|
.st56{clip-path:url(#SVGID_4_);fill:#31638E;}
|
||||||
|
.st57{clip-path:url(#SVGID_4_);fill:#31648F;}
|
||||||
|
.st58{clip-path:url(#SVGID_4_);fill:#326590;}
|
||||||
|
.st59{clip-path:url(#SVGID_4_);fill:#326591;}
|
||||||
|
.st60{clip-path:url(#SVGID_4_);fill:#336692;}
|
||||||
|
.st61{clip-path:url(#SVGID_4_);fill:#336793;}
|
||||||
|
.st62{clip-path:url(#SVGID_4_);fill:#346894;}
|
||||||
|
.st63{clip-path:url(#SVGID_4_);fill:#346895;}
|
||||||
|
.st64{clip-path:url(#SVGID_4_);fill:#356996;}
|
||||||
|
.st65{clip-path:url(#SVGID_4_);fill:#356A97;}
|
||||||
|
.st66{clip-path:url(#SVGID_4_);fill:#356B98;}
|
||||||
|
.st67{clip-path:url(#SVGID_4_);fill:#366B99;}
|
||||||
|
.st68{clip-path:url(#SVGID_4_);fill:#366C9A;}
|
||||||
|
.st69{clip-path:url(#SVGID_4_);fill:#376D9B;}
|
||||||
|
.st70{clip-path:url(#SVGID_4_);fill:#376E9C;}
|
||||||
|
.st71{clip-path:url(#SVGID_4_);fill:#386E9D;}
|
||||||
|
.st72{clip-path:url(#SVGID_4_);fill:#386F9E;}
|
||||||
|
.st73{clip-path:url(#SVGID_4_);fill:#38709F;}
|
||||||
|
.st74{clip-path:url(#SVGID_4_);fill:#3971A0;}
|
||||||
|
.st75{clip-path:url(#SVGID_4_);fill:#3971A1;}
|
||||||
|
.st76{clip-path:url(#SVGID_4_);fill:#3A72A2;}
|
||||||
|
.st77{clip-path:url(#SVGID_4_);fill:#3A73A3;}
|
||||||
|
.st78{clip-path:url(#SVGID_4_);fill:#3B74A4;}
|
||||||
|
.st79{clip-path:url(#SVGID_4_);fill:#3B74A5;}
|
||||||
|
.st80{clip-path:url(#SVGID_4_);fill:#3C75A7;}
|
||||||
|
.st81{clip-path:url(#SVGID_4_);fill:#3C76A8;}
|
||||||
|
.st82{clip-path:url(#SVGID_4_);fill:#3C76A9;}
|
||||||
|
.st83{clip-path:url(#SVGID_4_);fill:#3D77AA;}
|
||||||
|
.st84{clip-path:url(#SVGID_4_);fill:#3D78AB;}
|
||||||
|
.st85{clip-path:url(#SVGID_4_);fill:#3E79AC;}
|
||||||
|
.st86{clip-path:url(#SVGID_4_);fill:#3E79AD;}
|
||||||
|
.st87{clip-path:url(#SVGID_4_);fill:#3F7AAE;}
|
||||||
|
.st88{clip-path:url(#SVGID_4_);fill:#3F7BAF;}
|
||||||
|
.st89{clip-path:url(#SVGID_4_);fill:#3F7CB0;}
|
||||||
|
.st90{clip-path:url(#SVGID_4_);fill:#407CB1;}
|
||||||
|
.st91{clip-path:url(#SVGID_4_);fill:#407DB2;}
|
||||||
|
.st92{clip-path:url(#SVGID_4_);fill:#417EB3;}
|
||||||
|
.st93{clip-path:url(#SVGID_4_);fill:#417FB4;}
|
||||||
|
.st94{clip-path:url(#SVGID_4_);fill:#427FB5;}
|
||||||
|
.st95{clip-path:url(#SVGID_4_);fill:#4280B6;}
|
||||||
|
.st96{clip-path:url(#SVGID_4_);fill:#4281B7;}
|
||||||
|
.st97{clip-path:url(#SVGID_4_);fill:#4382B8;}
|
||||||
|
.st98{clip-path:url(#SVGID_4_);fill:#4382B9;}
|
||||||
|
.st99{clip-path:url(#SVGID_4_);fill:#4483BA;}
|
||||||
|
.st100{clip-path:url(#SVGID_4_);fill:#4484BB;}
|
||||||
|
.st101{clip-path:url(#SVGID_4_);fill:#4585BC;}
|
||||||
|
.st102{clip-path:url(#SVGID_4_);fill:#4585BD;}
|
||||||
|
.st103{clip-path:url(#SVGID_4_);fill:#4686BE;}
|
||||||
|
.st104{clip-path:url(#SVGID_4_);fill:#4687BF;}
|
||||||
|
.st105{clip-path:url(#SVGID_4_);fill:#4688C0;}
|
||||||
|
.st106{clip-path:url(#SVGID_4_);fill:#4788C1;}
|
||||||
|
.st107{clip-path:url(#SVGID_4_);fill:#4789C2;}
|
||||||
|
.st108{clip-path:url(#SVGID_4_);fill:#488AC3;}
|
||||||
|
.st109{clip-path:url(#SVGID_4_);fill:#488BC4;}
|
||||||
|
.st110{clip-path:url(#SVGID_4_);fill:#498BC5;}
|
||||||
|
.st111{clip-path:url(#SVGID_4_);fill:#498CC6;}
|
||||||
|
.st112{clip-path:url(#SVGID_6_);fill:#4CE8C6;}
|
||||||
|
.st113{clip-path:url(#SVGID_6_);fill:#4BE8C7;}
|
||||||
|
.st114{clip-path:url(#SVGID_6_);fill:#4AE7C7;}
|
||||||
|
.st115{clip-path:url(#SVGID_6_);fill:#49E7C8;}
|
||||||
|
.st116{clip-path:url(#SVGID_6_);fill:#48E6C8;}
|
||||||
|
.st117{clip-path:url(#SVGID_6_);fill:#47E6C9;}
|
||||||
|
.st118{clip-path:url(#SVGID_6_);fill:#46E6C9;}
|
||||||
|
.st119{clip-path:url(#SVGID_6_);fill:#45E5CA;}
|
||||||
|
.st120{clip-path:url(#SVGID_6_);fill:#44E5CB;}
|
||||||
|
.st121{clip-path:url(#SVGID_6_);fill:#43E4CB;}
|
||||||
|
.st122{clip-path:url(#SVGID_6_);fill:#42E4CC;}
|
||||||
|
.st123{clip-path:url(#SVGID_6_);fill:#41E4CC;}
|
||||||
|
.st124{clip-path:url(#SVGID_6_);fill:#40E3CD;}
|
||||||
|
.st125{clip-path:url(#SVGID_6_);fill:#3FE3CE;}
|
||||||
|
.st126{clip-path:url(#SVGID_6_);fill:#3EE2CE;}
|
||||||
|
.st127{clip-path:url(#SVGID_6_);fill:#3DE2CF;}
|
||||||
|
.st128{clip-path:url(#SVGID_6_);fill:#3CE2CF;}
|
||||||
|
.st129{clip-path:url(#SVGID_6_);fill:#3BE1D0;}
|
||||||
|
.st130{clip-path:url(#SVGID_6_);fill:#3AE1D0;}
|
||||||
|
.st131{clip-path:url(#SVGID_6_);fill:#39E0D1;}
|
||||||
|
.st132{clip-path:url(#SVGID_6_);fill:#38E0D2;}
|
||||||
|
.st133{clip-path:url(#SVGID_6_);fill:#37E0D2;}
|
||||||
|
.st134{clip-path:url(#SVGID_6_);fill:#36DFD3;}
|
||||||
|
.st135{clip-path:url(#SVGID_6_);fill:#35DFD3;}
|
||||||
|
.st136{clip-path:url(#SVGID_6_);fill:#34DED4;}
|
||||||
|
.st137{clip-path:url(#SVGID_6_);fill:#33DED5;}
|
||||||
|
.st138{clip-path:url(#SVGID_6_);fill:#31DED5;}
|
||||||
|
.st139{clip-path:url(#SVGID_6_);fill:#30DDD6;}
|
||||||
|
.st140{clip-path:url(#SVGID_6_);fill:#2FDDD6;}
|
||||||
|
.st141{clip-path:url(#SVGID_6_);fill:#2EDCD7;}
|
||||||
|
.st142{clip-path:url(#SVGID_6_);fill:#2DDCD7;}
|
||||||
|
.st143{clip-path:url(#SVGID_6_);fill:#2CDCD8;}
|
||||||
|
.st144{clip-path:url(#SVGID_6_);fill:#2BDBD9;}
|
||||||
|
.st145{clip-path:url(#SVGID_6_);fill:#2ADBD9;}
|
||||||
|
.st146{clip-path:url(#SVGID_6_);fill:#29DADA;}
|
||||||
|
.st147{clip-path:url(#SVGID_6_);fill:#28DADA;}
|
||||||
|
.st148{clip-path:url(#SVGID_6_);fill:#27DADB;}
|
||||||
|
.st149{clip-path:url(#SVGID_6_);fill:#26D9DB;}
|
||||||
|
.st150{clip-path:url(#SVGID_6_);fill:#25D9DC;}
|
||||||
|
.st151{clip-path:url(#SVGID_6_);fill:#24D8DD;}
|
||||||
|
.st152{clip-path:url(#SVGID_6_);fill:#23D8DD;}
|
||||||
|
.st153{clip-path:url(#SVGID_6_);fill:#22D8DE;}
|
||||||
|
.st154{clip-path:url(#SVGID_6_);fill:#21D7DE;}
|
||||||
|
.st155{clip-path:url(#SVGID_6_);fill:#20D7DF;}
|
||||||
|
.st156{clip-path:url(#SVGID_6_);fill:#1FD6E0;}
|
||||||
|
.st157{clip-path:url(#SVGID_6_);fill:#1ED6E0;}
|
||||||
|
.st158{clip-path:url(#SVGID_6_);fill:#1DD6E1;}
|
||||||
|
.st159{clip-path:url(#SVGID_6_);fill:#1CD5E1;}
|
||||||
|
.st160{clip-path:url(#SVGID_6_);fill:#1BD5E2;}
|
||||||
|
.st161{clip-path:url(#SVGID_6_);fill:#1AD4E2;}
|
||||||
|
.st162{clip-path:url(#SVGID_6_);fill:#19D4E3;}
|
||||||
|
.st163{opacity:0.4;}
|
||||||
|
.st164{clip-path:url(#SVGID_8_);fill:#4CE8C6;}
|
||||||
|
.st165{clip-path:url(#SVGID_8_);fill:#4BE8C7;}
|
||||||
|
.st166{clip-path:url(#SVGID_8_);fill:#4AE7C7;}
|
||||||
|
.st167{clip-path:url(#SVGID_8_);fill:#49E7C8;}
|
||||||
|
.st168{clip-path:url(#SVGID_8_);fill:#48E6C8;}
|
||||||
|
.st169{clip-path:url(#SVGID_8_);fill:#47E6C9;}
|
||||||
|
.st170{clip-path:url(#SVGID_8_);fill:#46E6C9;}
|
||||||
|
.st171{clip-path:url(#SVGID_8_);fill:#45E5CA;}
|
||||||
|
.st172{clip-path:url(#SVGID_8_);fill:#44E5CB;}
|
||||||
|
.st173{clip-path:url(#SVGID_8_);fill:#43E4CB;}
|
||||||
|
.st174{clip-path:url(#SVGID_8_);fill:#42E4CC;}
|
||||||
|
.st175{clip-path:url(#SVGID_8_);fill:#41E4CC;}
|
||||||
|
.st176{clip-path:url(#SVGID_8_);fill:#40E3CD;}
|
||||||
|
.st177{clip-path:url(#SVGID_8_);fill:#3FE3CE;}
|
||||||
|
.st178{clip-path:url(#SVGID_8_);fill:#3EE2CE;}
|
||||||
|
.st179{clip-path:url(#SVGID_8_);fill:#3DE2CF;}
|
||||||
|
.st180{clip-path:url(#SVGID_8_);fill:#3CE2CF;}
|
||||||
|
.st181{clip-path:url(#SVGID_8_);fill:#3BE1D0;}
|
||||||
|
.st182{clip-path:url(#SVGID_8_);fill:#3AE1D0;}
|
||||||
|
.st183{clip-path:url(#SVGID_8_);fill:#39E0D1;}
|
||||||
|
.st184{clip-path:url(#SVGID_8_);fill:#38E0D2;}
|
||||||
|
.st185{clip-path:url(#SVGID_8_);fill:#37E0D2;}
|
||||||
|
.st186{clip-path:url(#SVGID_8_);fill:#36DFD3;}
|
||||||
|
.st187{clip-path:url(#SVGID_8_);fill:#35DFD3;}
|
||||||
|
.st188{clip-path:url(#SVGID_8_);fill:#34DED4;}
|
||||||
|
.st189{clip-path:url(#SVGID_8_);fill:#33DED5;}
|
||||||
|
.st190{clip-path:url(#SVGID_8_);fill:#31DED5;}
|
||||||
|
.st191{clip-path:url(#SVGID_8_);fill:#30DDD6;}
|
||||||
|
.st192{clip-path:url(#SVGID_8_);fill:#2FDDD6;}
|
||||||
|
.st193{clip-path:url(#SVGID_8_);fill:#2EDCD7;}
|
||||||
|
.st194{clip-path:url(#SVGID_8_);fill:#2DDCD7;}
|
||||||
|
.st195{clip-path:url(#SVGID_8_);fill:#2CDCD8;}
|
||||||
|
.st196{clip-path:url(#SVGID_8_);fill:#2BDBD9;}
|
||||||
|
.st197{clip-path:url(#SVGID_8_);fill:#2ADBD9;}
|
||||||
|
.st198{clip-path:url(#SVGID_8_);fill:#29DADA;}
|
||||||
|
.st199{clip-path:url(#SVGID_8_);fill:#28DADA;}
|
||||||
|
.st200{clip-path:url(#SVGID_8_);fill:#27DADB;}
|
||||||
|
.st201{clip-path:url(#SVGID_8_);fill:#26D9DB;}
|
||||||
|
.st202{clip-path:url(#SVGID_8_);fill:#25D9DC;}
|
||||||
|
.st203{clip-path:url(#SVGID_8_);fill:#24D8DD;}
|
||||||
|
.st204{clip-path:url(#SVGID_8_);fill:#23D8DD;}
|
||||||
|
.st205{clip-path:url(#SVGID_8_);fill:#22D8DE;}
|
||||||
|
.st206{clip-path:url(#SVGID_8_);fill:#21D7DE;}
|
||||||
|
.st207{clip-path:url(#SVGID_8_);fill:#20D7DF;}
|
||||||
|
.st208{clip-path:url(#SVGID_8_);fill:#1FD6E0;}
|
||||||
|
.st209{clip-path:url(#SVGID_8_);fill:#1ED6E0;}
|
||||||
|
.st210{clip-path:url(#SVGID_8_);fill:#1DD6E1;}
|
||||||
|
.st211{clip-path:url(#SVGID_8_);fill:#1CD5E1;}
|
||||||
|
.st212{clip-path:url(#SVGID_8_);fill:#1BD5E2;}
|
||||||
|
.st213{clip-path:url(#SVGID_8_);fill:#1AD4E2;}
|
||||||
|
.st214{clip-path:url(#SVGID_8_);fill:#19D4E3;}
|
||||||
|
.st215{opacity:0.5;}
|
||||||
|
.st216{clip-path:url(#SVGID_10_);fill:#316490;}
|
||||||
|
.st217{clip-path:url(#SVGID_10_);fill:#316591;}
|
||||||
|
.st218{clip-path:url(#SVGID_10_);fill:#326692;}
|
||||||
|
.st219{clip-path:url(#SVGID_10_);fill:#326693;}
|
||||||
|
.st220{clip-path:url(#SVGID_10_);fill:#336794;}
|
||||||
|
.st221{clip-path:url(#SVGID_10_);fill:#336895;}
|
||||||
|
.st222{clip-path:url(#SVGID_10_);fill:#346996;}
|
||||||
|
.st223{clip-path:url(#SVGID_10_);fill:#346997;}
|
||||||
|
.st224{clip-path:url(#SVGID_10_);fill:#356A98;}
|
||||||
|
.st225{clip-path:url(#SVGID_10_);fill:#356B99;}
|
||||||
|
.st226{clip-path:url(#SVGID_10_);fill:#366C9A;}
|
||||||
|
.st227{clip-path:url(#SVGID_10_);fill:#366C9B;}
|
||||||
|
.st228{clip-path:url(#SVGID_10_);fill:#366D9C;}
|
||||||
|
.st229{clip-path:url(#SVGID_10_);fill:#376E9D;}
|
||||||
|
.st230{clip-path:url(#SVGID_10_);fill:#376F9E;}
|
||||||
|
.st231{clip-path:url(#SVGID_10_);fill:#386F9F;}
|
||||||
|
.st232{clip-path:url(#SVGID_10_);fill:#3870A0;}
|
||||||
|
.st233{clip-path:url(#SVGID_10_);fill:#3971A1;}
|
||||||
|
.st234{clip-path:url(#SVGID_10_);fill:#3972A2;}
|
||||||
|
.st235{clip-path:url(#SVGID_10_);fill:#3A72A3;}
|
||||||
|
.st236{clip-path:url(#SVGID_10_);fill:#3A73A4;}
|
||||||
|
.st237{clip-path:url(#SVGID_10_);fill:#3B74A5;}
|
||||||
|
.st238{clip-path:url(#SVGID_10_);fill:#3B75A6;}
|
||||||
|
.st239{clip-path:url(#SVGID_10_);fill:#3B75A7;}
|
||||||
|
.st240{clip-path:url(#SVGID_10_);fill:#3C76A8;}
|
||||||
|
.st241{clip-path:url(#SVGID_10_);fill:#3C77A9;}
|
||||||
|
.st242{clip-path:url(#SVGID_10_);fill:#3D78AA;}
|
||||||
|
.st243{clip-path:url(#SVGID_10_);fill:#3D78AC;}
|
||||||
|
.st244{clip-path:url(#SVGID_10_);fill:#3E79AD;}
|
||||||
|
.st245{clip-path:url(#SVGID_10_);fill:#3E7AAE;}
|
||||||
|
.st246{clip-path:url(#SVGID_10_);fill:#3F7BAF;}
|
||||||
|
.st247{clip-path:url(#SVGID_10_);fill:#3F7BB0;}
|
||||||
|
.st248{clip-path:url(#SVGID_10_);fill:#3F7CB1;}
|
||||||
|
.st249{clip-path:url(#SVGID_10_);fill:#407DB2;}
|
||||||
|
.st250{clip-path:url(#SVGID_10_);fill:#407EB3;}
|
||||||
|
.st251{clip-path:url(#SVGID_10_);fill:#417EB4;}
|
||||||
|
.st252{clip-path:url(#SVGID_10_);fill:#417FB5;}
|
||||||
|
.st253{clip-path:url(#SVGID_10_);fill:#4280B6;}
|
||||||
|
.st254{clip-path:url(#SVGID_10_);fill:#4281B7;}
|
||||||
|
.st255{clip-path:url(#SVGID_10_);fill:#4381B8;}
|
||||||
|
.st256{clip-path:url(#SVGID_10_);fill:#4382B9;}
|
||||||
|
.st257{clip-path:url(#SVGID_10_);fill:#4483BA;}
|
||||||
|
.st258{clip-path:url(#SVGID_10_);fill:#4484BB;}
|
||||||
|
.st259{clip-path:url(#SVGID_10_);fill:#4484BC;}
|
||||||
|
.st260{clip-path:url(#SVGID_10_);fill:#4585BD;}
|
||||||
|
.st261{clip-path:url(#SVGID_10_);fill:#4586BE;}
|
||||||
|
.st262{clip-path:url(#SVGID_10_);fill:#4687BF;}
|
||||||
|
.st263{clip-path:url(#SVGID_10_);fill:#4687C0;}
|
||||||
|
.st264{clip-path:url(#SVGID_10_);fill:#4788C1;}
|
||||||
|
.st265{clip-path:url(#SVGID_10_);fill:#4789C2;}
|
||||||
|
.st266{clip-path:url(#SVGID_10_);fill:#488AC3;}
|
||||||
|
.st267{clip-path:url(#SVGID_10_);fill:#488AC4;}
|
||||||
|
.st268{clip-path:url(#SVGID_10_);fill:#498BC5;}
|
||||||
|
.st269{clip-path:url(#SVGID_10_);fill:#498CC6;}
|
||||||
|
.st270{clip-path:url(#SVGID_12_);fill:#5FBBEB;}
|
||||||
|
.st271{clip-path:url(#SVGID_12_);fill:#5EBAEB;}
|
||||||
|
.st272{clip-path:url(#SVGID_12_);fill:#5DB9EA;}
|
||||||
|
.st273{clip-path:url(#SVGID_12_);fill:#5CB8EA;}
|
||||||
|
.st274{clip-path:url(#SVGID_12_);fill:#5BB7E9;}
|
||||||
|
.st275{clip-path:url(#SVGID_12_);fill:#5AB6E9;}
|
||||||
|
.st276{clip-path:url(#SVGID_12_);fill:#59B5E8;}
|
||||||
|
.st277{clip-path:url(#SVGID_12_);fill:#58B4E8;}
|
||||||
|
.st278{clip-path:url(#SVGID_12_);fill:#57B3E7;}
|
||||||
|
.st279{clip-path:url(#SVGID_12_);fill:#56B2E7;}
|
||||||
|
.st280{clip-path:url(#SVGID_12_);fill:#55B1E7;}
|
||||||
|
.st281{clip-path:url(#SVGID_12_);fill:#54B0E6;}
|
||||||
|
.st282{clip-path:url(#SVGID_12_);fill:#53AFE6;}
|
||||||
|
.st283{clip-path:url(#SVGID_12_);fill:#52AEE5;}
|
||||||
|
.st284{clip-path:url(#SVGID_12_);fill:#51ADE5;}
|
||||||
|
.st285{clip-path:url(#SVGID_12_);fill:#50ACE4;}
|
||||||
|
.st286{clip-path:url(#SVGID_12_);fill:#4FABE4;}
|
||||||
|
.st287{clip-path:url(#SVGID_12_);fill:#4EAAE3;}
|
||||||
|
.st288{clip-path:url(#SVGID_12_);fill:#4DA9E3;}
|
||||||
|
.st289{clip-path:url(#SVGID_12_);fill:#4CA8E3;}
|
||||||
|
.st290{clip-path:url(#SVGID_12_);fill:#4BA7E2;}
|
||||||
|
.st291{clip-path:url(#SVGID_12_);fill:#4AA6E2;}
|
||||||
|
.st292{clip-path:url(#SVGID_12_);fill:#49A5E1;}
|
||||||
|
.st293{clip-path:url(#SVGID_12_);fill:#48A4E1;}
|
||||||
|
.st294{clip-path:url(#SVGID_12_);fill:#47A2E0;}
|
||||||
|
.st295{clip-path:url(#SVGID_12_);fill:#46A1E0;}
|
||||||
|
.st296{clip-path:url(#SVGID_12_);fill:#45A0DF;}
|
||||||
|
.st297{clip-path:url(#SVGID_12_);fill:#449FDF;}
|
||||||
|
.st298{clip-path:url(#SVGID_12_);fill:#439EDE;}
|
||||||
|
.st299{clip-path:url(#SVGID_12_);fill:#429DDE;}
|
||||||
|
.st300{clip-path:url(#SVGID_12_);fill:#419CDE;}
|
||||||
|
.st301{clip-path:url(#SVGID_12_);fill:#409BDD;}
|
||||||
|
.st302{clip-path:url(#SVGID_12_);fill:#3F9ADD;}
|
||||||
|
.st303{clip-path:url(#SVGID_12_);fill:#3E99DC;}
|
||||||
|
.st304{clip-path:url(#SVGID_12_);fill:#3D98DC;}
|
||||||
|
.st305{clip-path:url(#SVGID_12_);fill:#3C97DB;}
|
||||||
|
.st306{clip-path:url(#SVGID_12_);fill:#3B96DB;}
|
||||||
|
.st307{clip-path:url(#SVGID_12_);fill:#3A95DA;}
|
||||||
|
.st308{clip-path:url(#SVGID_12_);fill:#3994DA;}
|
||||||
|
.st309{clip-path:url(#SVGID_12_);fill:#3893DA;}
|
||||||
|
.st310{clip-path:url(#SVGID_12_);fill:#3792D9;}
|
||||||
|
.st311{clip-path:url(#SVGID_12_);fill:#3691D9;}
|
||||||
|
.st312{clip-path:url(#SVGID_12_);fill:#3590D8;}
|
||||||
|
.st313{clip-path:url(#SVGID_12_);fill:#348FD8;}
|
||||||
|
.st314{clip-path:url(#SVGID_12_);fill:#338ED7;}
|
||||||
|
.st315{clip-path:url(#SVGID_12_);fill:#328DD7;}
|
||||||
|
.st316{clip-path:url(#SVGID_12_);fill:#318CD6;}
|
||||||
|
.st317{clip-path:url(#SVGID_12_);fill:#308BD6;}
|
||||||
|
.st318{fill:#316490;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M224,81H8c-4.4,0-8-3.6-8-8V8c0-4.4,3.6-8,8-8h216c4.4,0,8,3.6,8,8v65C232,77.4,228.4,81,224,81z"/>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_1_" points="15.2,15 15.2,62.9 59.2,56 59.2,8.1 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_2_">
|
||||||
|
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<polygon class="st1" points="56.7,62.9 59.2,56 59.2,62.9 "/>
|
||||||
|
<polygon class="st1" points="55.7,62.9 59.2,53.1 59.2,56 56.7,62.9 "/>
|
||||||
|
<polygon class="st2" points="54.6,62.9 59.2,50.3 59.2,53.1 55.7,62.9 "/>
|
||||||
|
<polygon class="st3" points="53.6,62.9 59.2,47.4 59.2,50.3 54.6,62.9 "/>
|
||||||
|
<polygon class="st4" points="52.6,62.9 59.2,44.6 59.2,47.4 53.6,62.9 "/>
|
||||||
|
<polygon class="st5" points="51.5,62.9 59.2,41.7 59.2,44.6 52.6,62.9 "/>
|
||||||
|
<polygon class="st6" points="50.5,62.9 59.2,38.9 59.2,41.7 51.5,62.9 "/>
|
||||||
|
<polygon class="st7" points="49.4,62.9 59.2,36 59.2,38.9 50.5,62.9 "/>
|
||||||
|
<polygon class="st8" points="48.4,62.9 59.2,33.1 59.2,36 49.4,62.9 "/>
|
||||||
|
<polygon class="st9" points="47.4,62.9 59.2,30.3 59.2,33.1 48.4,62.9 "/>
|
||||||
|
<polygon class="st10" points="46.3,62.9 59.2,27.4 59.2,30.3 47.4,62.9 "/>
|
||||||
|
<polygon class="st11" points="45.3,62.9 59.2,24.6 59.2,27.4 46.3,62.9 "/>
|
||||||
|
<polygon class="st12" points="44.2,62.9 59.2,21.7 59.2,24.6 45.3,62.9 "/>
|
||||||
|
<polygon class="st13" points="43.2,62.9 59.2,18.9 59.2,21.7 44.2,62.9 "/>
|
||||||
|
<polygon class="st14" points="42.2,62.9 59.2,16 59.2,18.9 43.2,62.9 "/>
|
||||||
|
<polygon class="st15" points="41.1,62.9 59.2,13.2 59.2,16 42.2,62.9 "/>
|
||||||
|
<polygon class="st16" points="40.1,62.9 59.2,10.3 59.2,13.2 41.1,62.9 "/>
|
||||||
|
<polygon class="st17" points="39,62.9 59,8.1 59.2,8.1 59.2,10.3 40.1,62.9 "/>
|
||||||
|
<polygon class="st18" points="38,62.9 57.9,8.1 59,8.1 39,62.9 "/>
|
||||||
|
<polygon class="st19" points="37,62.9 56.9,8.1 57.9,8.1 38,62.9 "/>
|
||||||
|
<polygon class="st20" points="35.9,62.9 55.9,8.1 56.9,8.1 37,62.9 "/>
|
||||||
|
<polygon class="st21" points="34.9,62.9 54.8,8.1 55.9,8.1 35.9,62.9 "/>
|
||||||
|
<polygon class="st22" points="33.8,62.9 53.8,8.1 54.8,8.1 34.9,62.9 "/>
|
||||||
|
<polygon class="st23" points="32.8,62.9 52.7,8.1 53.8,8.1 33.8,62.9 "/>
|
||||||
|
<polygon class="st24" points="31.8,62.9 51.7,8.1 52.7,8.1 32.8,62.9 "/>
|
||||||
|
<polygon class="st25" points="30.7,62.9 50.7,8.1 51.7,8.1 31.8,62.9 "/>
|
||||||
|
<polygon class="st26" points="29.7,62.9 49.6,8.1 50.7,8.1 30.7,62.9 "/>
|
||||||
|
<polygon class="st27" points="28.7,62.9 48.6,8.1 49.6,8.1 29.7,62.9 "/>
|
||||||
|
<polygon class="st28" points="27.6,62.9 47.5,8.1 48.6,8.1 28.7,62.9 "/>
|
||||||
|
<polygon class="st29" points="26.6,62.9 46.5,8.1 47.5,8.1 27.6,62.9 "/>
|
||||||
|
<polygon class="st30" points="25.5,62.9 45.5,8.1 46.5,8.1 26.6,62.9 "/>
|
||||||
|
<polygon class="st31" points="24.5,62.9 44.4,8.1 45.5,8.1 25.5,62.9 "/>
|
||||||
|
<polygon class="st32" points="23.5,62.9 43.4,8.1 44.4,8.1 24.5,62.9 "/>
|
||||||
|
<polygon class="st33" points="22.4,62.9 42.3,8.1 43.4,8.1 23.5,62.9 "/>
|
||||||
|
<polygon class="st34" points="21.4,62.9 41.3,8.1 42.3,8.1 22.4,62.9 "/>
|
||||||
|
<polygon class="st35" points="20.3,62.9 40.3,8.1 41.3,8.1 21.4,62.9 "/>
|
||||||
|
<polygon class="st36" points="19.3,62.9 39.2,8.1 40.3,8.1 20.3,62.9 "/>
|
||||||
|
<polygon class="st37" points="18.3,62.9 38.2,8.1 39.2,8.1 19.3,62.9 "/>
|
||||||
|
<polygon class="st38" points="17.2,62.9 37.1,8.1 38.2,8.1 18.3,62.9 "/>
|
||||||
|
<polygon class="st39" points="16.2,62.9 36.1,8.1 37.1,8.1 17.2,62.9 "/>
|
||||||
|
<polygon class="st40" points="15.2,62.7 35.1,8.1 36.1,8.1 16.2,62.9 15.2,62.9 "/>
|
||||||
|
<polygon class="st41" points="15.2,59.9 34,8.1 35.1,8.1 15.2,62.7 "/>
|
||||||
|
<polygon class="st42" points="15.2,57 33,8.1 34,8.1 15.2,59.9 "/>
|
||||||
|
<polygon class="st43" points="15.2,54.2 32,8.1 33,8.1 15.2,57 "/>
|
||||||
|
<polygon class="st44" points="15.2,51.3 30.9,8.1 32,8.1 15.2,54.2 "/>
|
||||||
|
<polygon class="st45" points="15.2,48.5 29.9,8.1 30.9,8.1 15.2,51.3 "/>
|
||||||
|
<polygon class="st46" points="15.2,45.6 28.8,8.1 29.9,8.1 15.2,48.5 "/>
|
||||||
|
<polygon class="st47" points="15.2,42.7 27.8,8.1 28.8,8.1 15.2,45.6 "/>
|
||||||
|
<polygon class="st48" points="15.2,39.9 26.8,8.1 27.8,8.1 15.2,42.7 "/>
|
||||||
|
<polygon class="st48" points="26.8,8.1 15.2,39.9 15.2,8.1 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_3_" points="83,68.7 83,20.8 59.2,8.1 59.2,56 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_4_">
|
||||||
|
<use xlink:href="#SVGID_3_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<polygon class="st49" points="83,20.8 78.4,8.1 83,8.1 "/>
|
||||||
|
<polygon class="st49" points="83,22 77.9,8.1 78.4,8.1 83,20.8 "/>
|
||||||
|
<polygon class="st50" points="83,23.1 77.5,8.1 77.9,8.1 83,22 "/>
|
||||||
|
<polygon class="st51" points="83,24.3 77.1,8.1 77.5,8.1 83,23.1 "/>
|
||||||
|
<polygon class="st52" points="83,25.4 76.7,8.1 77.1,8.1 83,24.3 "/>
|
||||||
|
<polygon class="st53" points="83,26.6 76.3,8.1 76.7,8.1 83,25.4 "/>
|
||||||
|
<polygon class="st54" points="83,27.7 75.9,8.1 76.3,8.1 83,26.6 "/>
|
||||||
|
<polygon class="st55" points="83,28.8 75.4,8.1 75.9,8.1 83,27.7 "/>
|
||||||
|
<polygon class="st56" points="83,30 75,8.1 75.4,8.1 83,28.8 "/>
|
||||||
|
<polygon class="st57" points="83,31.1 74.6,8.1 75,8.1 83,30 "/>
|
||||||
|
<polygon class="st58" points="83,32.3 74.2,8.1 74.6,8.1 83,31.1 "/>
|
||||||
|
<polygon class="st59" points="83,33.4 73.8,8.1 74.2,8.1 83,32.3 "/>
|
||||||
|
<polygon class="st60" points="83,34.6 73.4,8.1 73.8,8.1 83,33.4 "/>
|
||||||
|
<polygon class="st61" points="83,35.7 72.9,8.1 73.4,8.1 83,34.6 "/>
|
||||||
|
<polygon class="st62" points="83,36.9 72.5,8.1 72.9,8.1 83,35.7 "/>
|
||||||
|
<polygon class="st63" points="83,38 72.1,8.1 72.5,8.1 83,36.9 "/>
|
||||||
|
<polygon class="st64" points="83,39.1 71.7,8.1 72.1,8.1 83,38 "/>
|
||||||
|
<polygon class="st65" points="83,40.3 71.3,8.1 71.7,8.1 83,39.1 "/>
|
||||||
|
<polygon class="st66" points="83,41.4 70.9,8.1 71.3,8.1 83,40.3 "/>
|
||||||
|
<polygon class="st67" points="83,42.6 70.4,8.1 70.9,8.1 83,41.4 "/>
|
||||||
|
<polygon class="st68" points="83,43.7 70,8.1 70.4,8.1 83,42.6 "/>
|
||||||
|
<polygon class="st69" points="83,44.9 69.6,8.1 70,8.1 83,43.7 "/>
|
||||||
|
<polygon class="st70" points="83,46 69.2,8.1 69.6,8.1 83,44.9 "/>
|
||||||
|
<polygon class="st71" points="83,47.2 68.8,8.1 69.2,8.1 83,46 "/>
|
||||||
|
<polygon class="st72" points="83,48.3 68.4,8.1 68.8,8.1 83,47.2 "/>
|
||||||
|
<polygon class="st73" points="83,49.5 67.9,8.1 68.4,8.1 83,48.3 "/>
|
||||||
|
<polygon class="st74" points="83,50.6 67.5,8.1 67.9,8.1 83,49.5 "/>
|
||||||
|
<polygon class="st75" points="83,51.7 67.1,8.1 67.5,8.1 83,50.6 "/>
|
||||||
|
<polygon class="st76" points="83,52.9 66.7,8.1 67.1,8.1 83,51.7 "/>
|
||||||
|
<polygon class="st77" points="83,54 66.3,8.1 66.7,8.1 83,52.9 "/>
|
||||||
|
<polygon class="st78" points="83,55.2 65.9,8.1 66.3,8.1 83,54 "/>
|
||||||
|
<polygon class="st79" points="83,56.3 65.4,8.1 65.9,8.1 83,55.2 "/>
|
||||||
|
<polygon class="st80" points="83,57.5 65,8.1 65.4,8.1 83,56.3 "/>
|
||||||
|
<polygon class="st81" points="83,58.6 64.6,8.1 65,8.1 83,57.5 "/>
|
||||||
|
<polygon class="st82" points="83,59.8 64.2,8.1 64.6,8.1 83,58.6 "/>
|
||||||
|
<polygon class="st83" points="83,60.9 63.8,8.1 64.2,8.1 83,59.8 "/>
|
||||||
|
<polygon class="st84" points="83,62 63.3,8.1 63.8,8.1 83,60.9 "/>
|
||||||
|
<polygon class="st85" points="83,63.2 62.9,8.1 63.3,8.1 83,62 "/>
|
||||||
|
<polygon class="st86" points="83,64.3 62.5,8.1 62.9,8.1 83,63.2 "/>
|
||||||
|
<polygon class="st87" points="83,65.5 62.1,8.1 62.5,8.1 83,64.3 "/>
|
||||||
|
<polygon class="st88" points="83,66.6 61.7,8.1 62.1,8.1 83,65.5 "/>
|
||||||
|
<polygon class="st89" points="83,67.8 61.3,8.1 61.7,8.1 83,66.6 "/>
|
||||||
|
<polygon class="st90" points="82.9,68.7 60.8,8.1 61.3,8.1 83,67.8 83,68.7 "/>
|
||||||
|
<polygon class="st91" points="82.5,68.7 60.4,8.1 60.8,8.1 82.9,68.7 "/>
|
||||||
|
<polygon class="st92" points="82.1,68.7 60,8.1 60.4,8.1 82.5,68.7 "/>
|
||||||
|
<polygon class="st93" points="81.6,68.7 59.6,8.1 60,8.1 82.1,68.7 "/>
|
||||||
|
<polygon class="st94" points="81.2,68.7 59.2,8.1 59.2,8.1 59.6,8.1 81.6,68.7 "/>
|
||||||
|
<polygon class="st95" points="80.8,68.7 59.2,9.3 59.2,8.1 81.2,68.7 "/>
|
||||||
|
<polygon class="st96" points="80.4,68.7 59.2,10.4 59.2,9.3 80.8,68.7 "/>
|
||||||
|
<polygon class="st97" points="80,68.7 59.2,11.6 59.2,10.4 80.4,68.7 "/>
|
||||||
|
<polygon class="st98" points="79.6,68.7 59.2,12.7 59.2,11.6 80,68.7 "/>
|
||||||
|
<polygon class="st99" points="79.1,68.7 59.2,13.8 59.2,12.7 79.6,68.7 "/>
|
||||||
|
<polygon class="st100" points="78.7,68.7 59.2,15 59.2,13.8 79.1,68.7 "/>
|
||||||
|
<polygon class="st101" points="78.3,68.7 59.2,16.1 59.2,15 78.7,68.7 "/>
|
||||||
|
<polygon class="st102" points="77.9,68.7 59.2,17.3 59.2,16.1 78.3,68.7 "/>
|
||||||
|
<polygon class="st103" points="77.5,68.7 59.2,18.4 59.2,17.3 77.9,68.7 "/>
|
||||||
|
<polygon class="st104" points="77.1,68.7 59.2,19.6 59.2,18.4 77.5,68.7 "/>
|
||||||
|
<polygon class="st105" points="76.6,68.7 59.2,20.7 59.2,19.6 77.1,68.7 "/>
|
||||||
|
<polygon class="st106" points="76.2,68.7 59.2,21.9 59.2,20.7 76.6,68.7 "/>
|
||||||
|
<polygon class="st107" points="75.8,68.7 59.2,23 59.2,21.9 76.2,68.7 "/>
|
||||||
|
<polygon class="st108" points="75.4,68.7 59.2,24.1 59.2,23 75.8,68.7 "/>
|
||||||
|
<polygon class="st109" points="75,68.7 59.2,25.3 59.2,24.1 75.4,68.7 "/>
|
||||||
|
<polygon class="st110" points="74.6,68.7 59.2,26.4 59.2,25.3 75,68.7 "/>
|
||||||
|
<polygon class="st111" points="74.1,68.7 59.2,27.6 59.2,26.4 74.6,68.7 "/>
|
||||||
|
<polygon class="st111" points="59.2,27.6 74.1,68.7 59.2,68.7 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_5_" points="39,75.5 83,68.7 59.2,56 15.2,62.9 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_6_">
|
||||||
|
<use xlink:href="#SVGID_5_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<path class="st112" d="M83,75.5v-6.9V75.5z"/>
|
||||||
|
<rect x="82.1" y="56" class="st112" width="0.9" height="19.5"/>
|
||||||
|
<rect x="81.2" y="56" class="st113" width="0.9" height="19.5"/>
|
||||||
|
<rect x="80.3" y="56" class="st114" width="0.9" height="19.5"/>
|
||||||
|
<rect x="79.4" y="56" class="st115" width="0.9" height="19.5"/>
|
||||||
|
<rect x="78.5" y="56" class="st116" width="0.9" height="19.5"/>
|
||||||
|
<rect x="77.6" y="56" class="st117" width="0.9" height="19.5"/>
|
||||||
|
<rect x="76.7" y="56" class="st118" width="0.9" height="19.5"/>
|
||||||
|
<rect x="75.8" y="56" class="st119" width="0.9" height="19.5"/>
|
||||||
|
<rect x="74.9" y="56" class="st120" width="0.9" height="19.5"/>
|
||||||
|
<rect x="74" y="56" class="st121" width="0.9" height="19.5"/>
|
||||||
|
<rect x="73.1" y="56" class="st122" width="0.9" height="19.5"/>
|
||||||
|
<rect x="72.2" y="56" class="st123" width="0.9" height="19.5"/>
|
||||||
|
<rect x="71.3" y="56" class="st124" width="0.9" height="19.5"/>
|
||||||
|
<rect x="70.4" y="56" class="st125" width="0.9" height="19.5"/>
|
||||||
|
<rect x="69.5" y="56" class="st126" width="0.9" height="19.5"/>
|
||||||
|
<rect x="68.6" y="56" class="st127" width="0.9" height="19.5"/>
|
||||||
|
<rect x="67.7" y="56" class="st128" width="0.9" height="19.5"/>
|
||||||
|
<rect x="66.8" y="56" class="st129" width="0.9" height="19.5"/>
|
||||||
|
<rect x="65.9" y="56" class="st130" width="0.9" height="19.5"/>
|
||||||
|
<rect x="65" y="56" class="st131" width="0.9" height="19.5"/>
|
||||||
|
<rect x="64.1" y="56" class="st132" width="0.9" height="19.5"/>
|
||||||
|
<rect x="63.2" y="56" class="st133" width="0.9" height="19.5"/>
|
||||||
|
<rect x="62.3" y="56" class="st134" width="0.9" height="19.5"/>
|
||||||
|
<rect x="61.4" y="56" class="st135" width="0.9" height="19.5"/>
|
||||||
|
<rect x="60.5" y="56" class="st136" width="0.9" height="19.5"/>
|
||||||
|
<rect x="59.6" y="56" class="st137" width="0.9" height="19.5"/>
|
||||||
|
<rect x="58.7" y="56" class="st138" width="0.9" height="19.5"/>
|
||||||
|
<rect x="57.8" y="56" class="st139" width="0.9" height="19.5"/>
|
||||||
|
<rect x="56.9" y="56" class="st140" width="0.9" height="19.5"/>
|
||||||
|
<rect x="56" y="56" class="st141" width="0.9" height="19.5"/>
|
||||||
|
<rect x="55.1" y="56" class="st142" width="0.9" height="19.5"/>
|
||||||
|
<rect x="54.2" y="56" class="st143" width="0.9" height="19.5"/>
|
||||||
|
<rect x="53.3" y="56" class="st144" width="0.9" height="19.5"/>
|
||||||
|
<rect x="52.4" y="56" class="st145" width="0.9" height="19.5"/>
|
||||||
|
<rect x="51.5" y="56" class="st146" width="0.9" height="19.5"/>
|
||||||
|
<rect x="50.6" y="56" class="st147" width="0.9" height="19.5"/>
|
||||||
|
<rect x="49.7" y="56" class="st148" width="0.9" height="19.5"/>
|
||||||
|
<rect x="48.8" y="56" class="st149" width="0.9" height="19.5"/>
|
||||||
|
<rect x="47.9" y="56" class="st150" width="0.9" height="19.5"/>
|
||||||
|
<rect x="47" y="56" class="st151" width="0.9" height="19.5"/>
|
||||||
|
<rect x="46.1" y="56" class="st152" width="0.9" height="19.5"/>
|
||||||
|
<rect x="45.2" y="56" class="st153" width="0.9" height="19.5"/>
|
||||||
|
<rect x="44.3" y="56" class="st154" width="0.9" height="19.5"/>
|
||||||
|
<rect x="43.4" y="56" class="st155" width="0.9" height="19.5"/>
|
||||||
|
<rect x="42.5" y="56" class="st156" width="0.9" height="19.5"/>
|
||||||
|
<rect x="41.6" y="56" class="st157" width="0.9" height="19.5"/>
|
||||||
|
<rect x="40.7" y="56" class="st158" width="0.9" height="19.5"/>
|
||||||
|
<rect x="39.8" y="56" class="st159" width="0.9" height="19.5"/>
|
||||||
|
<rect x="38.9" y="56" class="st160" width="0.9" height="19.5"/>
|
||||||
|
<rect x="38" y="56" class="st161" width="0.9" height="19.5"/>
|
||||||
|
<rect x="37.1" y="56" class="st162" width="0.9" height="19.5"/>
|
||||||
|
<rect x="15.2" y="56" class="st162" width="21.9" height="19.5"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g class="st163">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_7_" points="39,27.6 15.2,15 15.2,62.9 39,75.5 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_8_">
|
||||||
|
<use xlink:href="#SVGID_7_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<polygon class="st164" points="37.7,75.5 39,73.7 39,75.5 "/>
|
||||||
|
<polygon class="st165" points="36.4,75.5 39,71.8 39,73.7 37.7,75.5 "/>
|
||||||
|
<polygon class="st166" points="35.1,75.5 39,70 39,71.8 36.4,75.5 "/>
|
||||||
|
<polygon class="st167" points="33.8,75.5 39,68.1 39,70 35.1,75.5 "/>
|
||||||
|
<polygon class="st168" points="32.5,75.5 39,66.2 39,68.1 33.8,75.5 "/>
|
||||||
|
<polygon class="st169" points="31.9,75.5 31.4,75.2 39,64.4 39,66.2 32.5,75.5 "/>
|
||||||
|
<polygon class="st170" points="31.4,75.2 30.5,74.6 39,62.5 39,64.4 "/>
|
||||||
|
<polygon class="st171" points="30.5,74.6 29.7,74 39,60.7 39,62.5 "/>
|
||||||
|
<polygon class="st172" points="29.7,74 28.8,73.4 39,58.8 39,60.7 "/>
|
||||||
|
<polygon class="st173" points="28.8,73.4 27.9,72.8 39,57 39,58.8 "/>
|
||||||
|
<polygon class="st174" points="27.9,72.8 27.1,72.1 39,55.1 39,57 "/>
|
||||||
|
<polygon class="st175" points="27.1,72.1 26.2,71.5 39,53.3 39,55.1 "/>
|
||||||
|
<polygon class="st176" points="26.2,71.5 25.3,70.9 39,51.4 39,53.3 "/>
|
||||||
|
<polygon class="st177" points="25.3,70.9 24.4,70.3 39,49.6 39,51.4 "/>
|
||||||
|
<polygon class="st178" points="24.4,70.3 23.6,69.7 39,47.7 39,49.6 "/>
|
||||||
|
<polygon class="st179" points="23.6,69.7 22.7,69.1 39,45.9 39,47.7 "/>
|
||||||
|
<polygon class="st180" points="22.7,69.1 21.8,68.5 39,44 39,45.9 "/>
|
||||||
|
<polygon class="st181" points="21.8,68.5 21,67.9 39,42.2 39,44 "/>
|
||||||
|
<polygon class="st182" points="21,67.9 20.1,67.3 39,40.3 39,42.2 "/>
|
||||||
|
<polygon class="st183" points="20.1,67.3 19.2,66.7 39,38.4 39,40.3 "/>
|
||||||
|
<polygon class="st184" points="19.2,66.7 18.4,66 39,36.6 39,38.4 "/>
|
||||||
|
<polygon class="st185" points="18.4,66 17.5,65.4 39,34.7 39,36.6 "/>
|
||||||
|
<polygon class="st186" points="17.5,65.4 16.6,64.8 39,32.9 39,34.7 "/>
|
||||||
|
<polygon class="st187" points="16.6,64.8 15.7,64.2 39,31 39,32.9 "/>
|
||||||
|
<polygon class="st188" points="15.7,64.2 15.2,63.8 15.2,63.2 39,29.2 39,31 "/>
|
||||||
|
<polygon class="st189" points="15.2,61.3 39,27.3 39,29.2 15.2,63.2 "/>
|
||||||
|
<polygon class="st190" points="15.2,59.5 38.4,26.3 39,26.7 39,27.3 15.2,61.3 "/>
|
||||||
|
<polygon class="st191" points="15.2,57.6 37.5,25.7 38.4,26.3 15.2,59.5 "/>
|
||||||
|
<polygon class="st192" points="15.2,55.7 36.7,25 37.5,25.7 15.2,57.6 "/>
|
||||||
|
<polygon class="st193" points="15.2,53.9 35.8,24.4 36.7,25 15.2,55.7 "/>
|
||||||
|
<polygon class="st194" points="15.2,52 34.9,23.8 35.8,24.4 15.2,53.9 "/>
|
||||||
|
<polygon class="st195" points="15.2,50.2 34.1,23.2 34.9,23.8 15.2,52 "/>
|
||||||
|
<polygon class="st196" points="15.2,48.3 33.2,22.6 34.1,23.2 15.2,50.2 "/>
|
||||||
|
<polygon class="st197" points="15.2,46.5 32.3,22 33.2,22.6 15.2,48.3 "/>
|
||||||
|
<polygon class="st198" points="15.2,44.6 31.5,21.4 32.3,22 15.2,46.5 "/>
|
||||||
|
<polygon class="st199" points="15.2,42.8 30.6,20.8 31.5,21.4 15.2,44.6 "/>
|
||||||
|
<polygon class="st200" points="15.2,40.9 29.7,20.2 30.6,20.8 15.2,42.8 "/>
|
||||||
|
<polygon class="st201" points="15.2,39.1 28.8,19.6 29.7,20.2 15.2,40.9 "/>
|
||||||
|
<polygon class="st202" points="15.2,37.2 28,18.9 28.8,19.6 15.2,39.1 "/>
|
||||||
|
<polygon class="st203" points="15.2,35.4 27.1,18.3 28,18.9 15.2,37.2 "/>
|
||||||
|
<polygon class="st204" points="15.2,33.5 26.2,17.7 27.1,18.3 15.2,35.4 "/>
|
||||||
|
<polygon class="st205" points="15.2,31.6 25.4,17.1 26.2,17.7 15.2,33.5 "/>
|
||||||
|
<polygon class="st206" points="15.2,29.8 24.5,16.5 25.4,17.1 15.2,31.6 "/>
|
||||||
|
<polygon class="st207" points="15.2,27.9 23.6,15.9 24.5,16.5 15.2,29.8 "/>
|
||||||
|
<polygon class="st208" points="15.2,26.1 22.7,15.3 23.6,15.9 15.2,27.9 "/>
|
||||||
|
<polygon class="st209" points="15.2,24.2 21.7,15 22.3,15 22.7,15.3 15.2,26.1 "/>
|
||||||
|
<polygon class="st210" points="15.2,22.4 20.4,15 21.7,15 15.2,24.2 "/>
|
||||||
|
<polygon class="st211" points="15.2,20.5 19.1,15 20.4,15 15.2,22.4 "/>
|
||||||
|
<polygon class="st212" points="15.2,18.7 17.8,15 19.1,15 15.2,20.5 "/>
|
||||||
|
<polygon class="st213" points="15.2,16.8 16.5,15 17.8,15 15.2,18.7 "/>
|
||||||
|
<polygon class="st214" points="15.2,15 15.2,15 16.5,15 15.2,16.8 "/>
|
||||||
|
<polygon class="st214" points="15.2,15 15.2,15 15.2,15 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g class="st215">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_9_" points="83,20.8 59.2,8.1 15.2,15 39,27.6 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_10_">
|
||||||
|
<use xlink:href="#SVGID_9_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<path class="st216" d="M83,27.6v-6.9V27.6z"/>
|
||||||
|
<rect x="81.7" y="8.1" class="st216" width="1.3" height="19.5"/>
|
||||||
|
<rect x="80.4" y="8.1" class="st217" width="1.3" height="19.5"/>
|
||||||
|
<rect x="79.2" y="8.1" class="st218" width="1.3" height="19.5"/>
|
||||||
|
<rect x="77.9" y="8.1" class="st219" width="1.3" height="19.5"/>
|
||||||
|
<rect x="76.7" y="8.1" class="st220" width="1.3" height="19.5"/>
|
||||||
|
<rect x="75.4" y="8.1" class="st221" width="1.3" height="19.5"/>
|
||||||
|
<rect x="74.2" y="8.1" class="st222" width="1.3" height="19.5"/>
|
||||||
|
<rect x="72.9" y="8.1" class="st223" width="1.3" height="19.5"/>
|
||||||
|
<rect x="71.7" y="8.1" class="st224" width="1.3" height="19.5"/>
|
||||||
|
<rect x="70.4" y="8.1" class="st225" width="1.3" height="19.5"/>
|
||||||
|
<rect x="69.2" y="8.1" class="st226" width="1.3" height="19.5"/>
|
||||||
|
<rect x="67.9" y="8.1" class="st227" width="1.3" height="19.5"/>
|
||||||
|
<rect x="66.6" y="8.1" class="st228" width="1.3" height="19.5"/>
|
||||||
|
<rect x="65.4" y="8.1" class="st229" width="1.3" height="19.5"/>
|
||||||
|
<rect x="64.1" y="8.1" class="st230" width="1.3" height="19.5"/>
|
||||||
|
<rect x="62.9" y="8.1" class="st231" width="1.3" height="19.5"/>
|
||||||
|
<rect x="61.6" y="8.1" class="st232" width="1.3" height="19.5"/>
|
||||||
|
<rect x="60.4" y="8.1" class="st233" width="1.3" height="19.5"/>
|
||||||
|
<rect x="59.1" y="8.1" class="st234" width="1.3" height="19.5"/>
|
||||||
|
<rect x="57.9" y="8.1" class="st235" width="1.3" height="19.5"/>
|
||||||
|
<rect x="56.6" y="8.1" class="st236" width="1.3" height="19.5"/>
|
||||||
|
<rect x="55.3" y="8.1" class="st237" width="1.3" height="19.5"/>
|
||||||
|
<rect x="54.1" y="8.1" class="st238" width="1.3" height="19.5"/>
|
||||||
|
<rect x="52.8" y="8.1" class="st239" width="1.3" height="19.5"/>
|
||||||
|
<rect x="51.6" y="8.1" class="st240" width="1.3" height="19.5"/>
|
||||||
|
<rect x="50.3" y="8.1" class="st241" width="1.3" height="19.5"/>
|
||||||
|
<rect x="49.1" y="8.1" class="st242" width="1.3" height="19.5"/>
|
||||||
|
<rect x="47.8" y="8.1" class="st243" width="1.3" height="19.5"/>
|
||||||
|
<rect x="46.6" y="8.1" class="st244" width="1.3" height="19.5"/>
|
||||||
|
<rect x="45.3" y="8.1" class="st245" width="1.3" height="19.5"/>
|
||||||
|
<rect x="44.1" y="8.1" class="st246" width="1.3" height="19.5"/>
|
||||||
|
<rect x="42.8" y="8.1" class="st247" width="1.3" height="19.5"/>
|
||||||
|
<rect x="41.5" y="8.1" class="st248" width="1.3" height="19.5"/>
|
||||||
|
<rect x="40.3" y="8.1" class="st249" width="1.3" height="19.5"/>
|
||||||
|
<rect x="39" y="8.1" class="st250" width="1.3" height="19.5"/>
|
||||||
|
<rect x="37.8" y="8.1" class="st251" width="1.3" height="19.5"/>
|
||||||
|
<rect x="36.5" y="8.1" class="st252" width="1.3" height="19.5"/>
|
||||||
|
<rect x="35.3" y="8.1" class="st253" width="1.3" height="19.5"/>
|
||||||
|
<rect x="34" y="8.1" class="st254" width="1.3" height="19.5"/>
|
||||||
|
<rect x="32.8" y="8.1" class="st255" width="1.3" height="19.5"/>
|
||||||
|
<rect x="31.5" y="8.1" class="st256" width="1.3" height="19.5"/>
|
||||||
|
<rect x="30.2" y="8.1" class="st257" width="1.3" height="19.5"/>
|
||||||
|
<rect x="29" y="8.1" class="st258" width="1.3" height="19.5"/>
|
||||||
|
<rect x="27.7" y="8.1" class="st259" width="1.3" height="19.5"/>
|
||||||
|
<rect x="26.5" y="8.1" class="st260" width="1.3" height="19.5"/>
|
||||||
|
<rect x="25.2" y="8.1" class="st261" width="1.3" height="19.5"/>
|
||||||
|
<rect x="24" y="8.1" class="st262" width="1.3" height="19.5"/>
|
||||||
|
<rect x="22.7" y="8.1" class="st263" width="1.3" height="19.5"/>
|
||||||
|
<rect x="21.5" y="8.1" class="st264" width="1.3" height="19.5"/>
|
||||||
|
<rect x="20.2" y="8.1" class="st265" width="1.3" height="19.5"/>
|
||||||
|
<rect x="18.9" y="8.1" class="st266" width="1.3" height="19.5"/>
|
||||||
|
<rect x="17.7" y="8.1" class="st267" width="1.3" height="19.5"/>
|
||||||
|
<rect x="16.4" y="8.1" class="st268" width="1.3" height="19.5"/>
|
||||||
|
<polygon class="st269" points="15.2,15 15.2,8.1 16.4,8.1 16.4,27.6 15.2,27.6 "/>
|
||||||
|
<path class="st269" d="M15.2,8.1V15V8.1z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g class="st215">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<polygon id="SVGID_11_" points="39,27.6 39,75.5 83,68.7 83,20.8 "/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_12_">
|
||||||
|
<use xlink:href="#SVGID_11_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<polygon class="st270" points="77.2,75.5 83,68.7 83,75.5 "/>
|
||||||
|
<polygon class="st270" points="76.2,75.5 83,67.5 83,68.7 77.2,75.5 "/>
|
||||||
|
<polygon class="st271" points="75.3,75.5 83,66.3 83,67.5 76.2,75.5 "/>
|
||||||
|
<polygon class="st272" points="74.3,75.5 83,65.1 83,66.3 75.3,75.5 "/>
|
||||||
|
<polygon class="st273" points="73.3,75.5 83,64 83,65.1 74.3,75.5 "/>
|
||||||
|
<polygon class="st274" points="72.3,75.5 83,62.8 83,64 73.3,75.5 "/>
|
||||||
|
<polygon class="st275" points="71.3,75.5 83,61.6 83,62.8 72.3,75.5 "/>
|
||||||
|
<polygon class="st276" points="70.3,75.5 83,60.4 83,61.6 71.3,75.5 "/>
|
||||||
|
<polygon class="st277" points="69.3,75.5 83,59.3 83,60.4 70.3,75.5 "/>
|
||||||
|
<polygon class="st278" points="68.4,75.5 83,58.1 83,59.3 69.3,75.5 "/>
|
||||||
|
<polygon class="st279" points="67.4,75.5 83,56.9 83,58.1 68.4,75.5 "/>
|
||||||
|
<polygon class="st280" points="66.4,75.5 83,55.7 83,56.9 67.4,75.5 "/>
|
||||||
|
<polygon class="st281" points="65.4,75.5 83,54.6 83,55.7 66.4,75.5 "/>
|
||||||
|
<polygon class="st282" points="64.4,75.5 83,53.4 83,54.6 65.4,75.5 "/>
|
||||||
|
<polygon class="st283" points="63.4,75.5 83,52.2 83,53.4 64.4,75.5 "/>
|
||||||
|
<polygon class="st284" points="62.4,75.5 83,51 83,52.2 63.4,75.5 "/>
|
||||||
|
<polygon class="st285" points="61.5,75.5 83,49.9 83,51 62.4,75.5 "/>
|
||||||
|
<polygon class="st286" points="60.5,75.5 83,48.7 83,49.9 61.5,75.5 "/>
|
||||||
|
<polygon class="st287" points="59.5,75.5 83,47.5 83,48.7 60.5,75.5 "/>
|
||||||
|
<polygon class="st288" points="58.5,75.5 83,46.3 83,47.5 59.5,75.5 "/>
|
||||||
|
<polygon class="st289" points="57.5,75.5 83,45.2 83,46.3 58.5,75.5 "/>
|
||||||
|
<polygon class="st290" points="56.5,75.5 83,44 83,45.2 57.5,75.5 "/>
|
||||||
|
<polygon class="st291" points="55.6,75.5 83,42.8 83,44 56.5,75.5 "/>
|
||||||
|
<polygon class="st292" points="54.6,75.5 83,41.7 83,42.8 55.6,75.5 "/>
|
||||||
|
<polygon class="st293" points="53.6,75.5 83,40.5 83,41.7 54.6,75.5 "/>
|
||||||
|
<polygon class="st294" points="52.6,75.5 83,39.3 83,40.5 53.6,75.5 "/>
|
||||||
|
<polygon class="st295" points="51.6,75.5 83,38.1 83,39.3 52.6,75.5 "/>
|
||||||
|
<polygon class="st296" points="50.6,75.5 83,37 83,38.1 51.6,75.5 "/>
|
||||||
|
<polygon class="st297" points="49.6,75.5 83,35.8 83,37 50.6,75.5 "/>
|
||||||
|
<polygon class="st298" points="48.7,75.5 83,34.6 83,35.8 49.6,75.5 "/>
|
||||||
|
<polygon class="st299" points="47.7,75.5 83,33.4 83,34.6 48.7,75.5 "/>
|
||||||
|
<polygon class="st300" points="46.7,75.5 83,32.3 83,33.4 47.7,75.5 "/>
|
||||||
|
<polygon class="st301" points="45.7,75.5 83,31.1 83,32.3 46.7,75.5 "/>
|
||||||
|
<polygon class="st302" points="44.7,75.5 83,29.9 83,31.1 45.7,75.5 "/>
|
||||||
|
<polygon class="st303" points="43.7,75.5 83,28.7 83,29.9 44.7,75.5 "/>
|
||||||
|
<polygon class="st304" points="42.8,75.5 83,27.6 83,28.7 43.7,75.5 "/>
|
||||||
|
<polygon class="st305" points="41.8,75.5 83,26.4 83,27.6 42.8,75.5 "/>
|
||||||
|
<polygon class="st306" points="40.8,75.5 83,25.2 83,26.4 41.8,75.5 "/>
|
||||||
|
<polygon class="st307" points="39.8,75.5 83,24 83,25.2 40.8,75.5 "/>
|
||||||
|
<polygon class="st308" points="39,75.4 83,22.9 83,24 39.8,75.5 39,75.5 "/>
|
||||||
|
<polygon class="st309" points="39,74.2 83,21.7 83,22.9 39,75.4 "/>
|
||||||
|
<polygon class="st310" points="39,73 82.8,20.8 83,20.8 83,21.7 39,74.2 "/>
|
||||||
|
<polygon class="st311" points="39,71.8 81.8,20.8 82.8,20.8 39,73 "/>
|
||||||
|
<polygon class="st312" points="39,70.7 80.8,20.8 81.8,20.8 39,71.8 "/>
|
||||||
|
<polygon class="st313" points="39,69.5 79.8,20.8 80.8,20.8 39,70.7 "/>
|
||||||
|
<polygon class="st314" points="39,68.3 78.9,20.8 79.8,20.8 39,69.5 "/>
|
||||||
|
<polygon class="st315" points="39,67.1 77.9,20.8 78.9,20.8 39,68.3 "/>
|
||||||
|
<polygon class="st316" points="39,66 76.9,20.8 77.9,20.8 39,67.1 "/>
|
||||||
|
<polygon class="st317" points="39,64.8 75.9,20.8 76.9,20.8 39,66 "/>
|
||||||
|
<polygon class="st317" points="75.9,20.8 39,64.8 39,20.8 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M36.6,28.1c0-1.4,1.1-2.7,2.5-2.9l22.5-3.6v31.9c0,2.6-1.9,4.7-4.4,5.1L36.5,62L36.6,28.1z M56.7,27.3
|
||||||
|
l-15.3,2.4l0,26.6l15.4-2.5V27.3z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<rect x="36.6" y="48.3" class="st0" width="4.8" height="28.2"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<rect x="59.2" y="3.9" class="st0" width="2.4" height="36.7"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M83,23.4v42.4c0,1.5-1.1,2.9-2.6,3.1l-35.3,5.7c-1.9,0.3-3.6-1.2-3.6-3.1v-7.6c0-1.5,1.1-2.9,2.6-3.1l14-2.2
|
||||||
|
c2-0.3,3.5-2.1,3.5-4.1l0.2-39.7c0-2.4,2.5-3.9,4.6-2.8l14.3,7.7C82.1,20.4,83,21.8,83,23.4z M86.5,16L62.3,3
|
||||||
|
c-0.8-0.6-1.9-0.1-1.9,0.9l-1.1,51c0,0.6-0.4,1.1-1,1.2L40,59c-0.6,0.1-1,0.6-1,1.2l0,18.7c0,0.7,0.7,1.3,1.4,1.2L86,71.8
|
||||||
|
c0.6-0.1,1-0.6,1-1.2V17C87,16.6,86.8,16.3,86.5,16z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M59.2,11.7l0,7.5c0,1.6-1.2,3-2.7,3.2l-17.1,2.8c-1.6,0.3-2.7,1.6-2.7,3.2l0,40.3c0,2.5-2.6,4-4.8,2.9
|
||||||
|
l-14.8-7.9c-1.1-0.6-1.7-1.7-1.7-2.9V17.6c0-1.6,1.2-3,2.8-3.2l37.5-5.8C57.4,8.2,59.2,9.7,59.2,11.7z M58.8,2.6l-45.5,7.9
|
||||||
|
c-0.8,0.1-1.4,0.8-1.4,1.6l-0.2,49.6c-0.1,0.7,0.3,1.3,0.9,1.6l25.2,15.4c1.2,0.6,2.6-0.2,2.5-1.6L39,29.3c0-0.9,0.6-1.7,1.5-1.8
|
||||||
|
l18.5-2.1c0.9-0.1,1.5-0.8,1.5-1.7l0.2-19.4C60.8,3.3,59.8,2.4,58.8,2.6z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M47.5,43.8c-0.6,0-1.1-0.4-1.2-1c-0.1-0.7,0.3-1.3,1-1.4l10.1-1.6c0.7-0.1,1.3,0.3,1.4,1
|
||||||
|
c0.1,0.7-0.3,1.3-1,1.4l-10.1,1.6C47.6,43.8,47.6,43.8,47.5,43.8z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M55.2,42.6L55.2,42.6c0.8-0.1,1.6,0.5,1.6,1.3v8.7l4.5,0V30.1l-4.5,0.2V38c0,1.1-0.8,2-1.8,2.2l-1.7,0.3
|
||||||
|
L55.2,42.6z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st318" points="112.5,28.8 112.5,37.1 125.6,37.1 125.6,41.2 112.5,41.2 112.5,49.5 125.6,49.5 125.6,53.6
|
||||||
|
108,53.6 108,24.7 125.6,24.7 125.6,28.8 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st318" d="M147.2,38.3v14.2l-3.8,1.8h-0.6v-16c0-1.7-0.8-1.9-1.5-1.9h-4.3c-0.7,0-1.5,0.2-1.5,1.9v14.2l-3.8,1.8H131
|
||||||
|
v-16c0-4,2-6,6-6h4.3C145.2,32.3,147.2,34.3,147.2,38.3z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st318" points="161.5,32.3 161.5,32.9 159.8,36.4 156.7,36.4 156.7,52.5 152.8,54.3 152.2,54.3 152.2,27.7
|
||||||
|
156,25.9 156.7,25.9 156.7,32.3 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st318" d="M174.6,32.3h-4.3c-4,0-6,2-6,6v9.3c0,4,2,6,6,6h4.3c0.6,0,1.1-0.1,1.5-0.3v2c0,1.7-0.8,1.9-1.5,1.9h-10.3
|
||||||
|
v4.1h10.3c4,0,6-2,6-6v-17C180.5,34.3,178.5,32.3,174.6,32.3z M176.1,47.6c0,1.7-0.8,1.9-1.5,1.9h-4.3c-0.7,0-1.5-0.2-1.5-1.9
|
||||||
|
v-9.3c0-1.7,0.8-1.9,1.5-1.9h4.3c0.7,0,1.5,0.2,1.5,1.9V47.6z"/>
|
||||||
|
<path class="st318" d="M197,32.3v0.6l-1.6,3.5H192c-0.7,0-1.5,0.2-1.5,1.9v14.2l-3.8,1.8H186v-16c0-4,2-6,6-6H197z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st318" d="M208,32.3h-7v4.1h7c0.7,0,1.5,0.2,1.5,1.9v1.1c-0.5-0.2-1-0.3-1.5-0.3h-3.9c-4,0-6,2-6,6v2.6c0,4,2,6,6,6
|
||||||
|
h3.9c0.6,0,1.1-0.1,1.5-0.3v1.4h0.6l3.8-1.8V38.3C214,34.3,212,32.3,208,32.3z M208,49.5h-3.9c-0.7,0-1.5-0.2-1.5-1.9V45
|
||||||
|
c0-1.7,0.8-1.9,1.5-1.9h3.9c0.7,0,1.5,0.2,1.5,1.9v2.6C209.5,49.3,208.7,49.5,208,49.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 44 KiB |
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"Title" : "Title",
|
||||||
|
"Description" : "Description",
|
||||||
|
"ShortDescription" : "Short Description",
|
||||||
|
"Category" : "Category",
|
||||||
|
"Visibility" : "Visibility",
|
||||||
|
"Devices" : "Devices",
|
||||||
|
"Roles" : "Roles",
|
||||||
|
"Groups" : "Groups",
|
||||||
|
"Tags" : "Tags",
|
||||||
|
"Platform" : "Platform",
|
||||||
|
"Platforms" : "Platforms",
|
||||||
|
"Applications": "Applications",
|
||||||
|
"No.Platform" : "No Platforms",
|
||||||
|
"Screenshots" : "Screenshots",
|
||||||
|
"Icon" : "Icon",
|
||||||
|
"Info" : "Info",
|
||||||
|
"Banner" : "Banner",
|
||||||
|
"Create.Application" : "Create Application",
|
||||||
|
"Back" : "Back",
|
||||||
|
"Cancel" : "Cancel",
|
||||||
|
"Finish" : "Finish",
|
||||||
|
"Continue" : "Continue",
|
||||||
|
"Name" : "Name",
|
||||||
|
"Application.Name" : "Application Name",
|
||||||
|
"General" : "General",
|
||||||
|
"App.Releases" : "Application Releases",
|
||||||
|
"Package.Manager" : "Package Manager",
|
||||||
|
"Save" : "Save",
|
||||||
|
"Create.Release" : "Create Release",
|
||||||
|
"Release.Channel" : "Release Channel",
|
||||||
|
"Release" : "Release",
|
||||||
|
"New.Release.For" : "New Release for",
|
||||||
|
"Upload.Package.File" : "Upload Package File",
|
||||||
|
"Upload" : "Upload",
|
||||||
|
"Select.from.package.library" : "Select from package library",
|
||||||
|
"Release.Name" : "Release Name",
|
||||||
|
"Release.Notes" : "Release Notes",
|
||||||
|
"Send.for.Review" : "Send for Review",
|
||||||
|
"Production.Releases" : "Production Releases",
|
||||||
|
"Beta.Releases" : "Beta Releases",
|
||||||
|
"Alpha.Releases" : "Alpha Releases",
|
||||||
|
"Version" : "Version",
|
||||||
|
"Status" : "Status",
|
||||||
|
"App.Publisher" : "Application Publisher",
|
||||||
|
"Search.Apps" : "Search for Applications",
|
||||||
|
"View.In.Store" : "View in Store",
|
||||||
|
"Last.Updated" : "Last updated on",
|
||||||
|
"Installs" : "Installs",
|
||||||
|
"General.Info" : "General Info",
|
||||||
|
"Select.Platform": "Select Platform",
|
||||||
|
"Add.Release" : "Add Release to Application",
|
||||||
|
"Share.With.Tenants" : "Share with Tenants",
|
||||||
|
"Disable" : "Disable",
|
||||||
|
"File.Based" : "File Based",
|
||||||
|
"Activate" : "Activate",
|
||||||
|
"Yes" : "Yes",
|
||||||
|
"No" : "No",
|
||||||
|
"No.Platform.Tags" : "No Platform Tags",
|
||||||
|
"Create.Platform" : "Create Platform",
|
||||||
|
"Optional": "Optional",
|
||||||
|
"Identifier": "Identifier",
|
||||||
|
"Next": "Next",
|
||||||
|
"Platform.Enable": "Enable Platform",
|
||||||
|
"Share.with.Tenants": "Share between all tenants",
|
||||||
|
"Platform.Properties": "Platform Properties"
|
||||||
|
}
|
||||||
@ -0,0 +1,903 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roboto-Medium";
|
||||||
|
src: url('../../fonts/Roboto-Medium.woff');
|
||||||
|
src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.ttf") format("ttf");
|
||||||
|
src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.woff") format("woff");
|
||||||
|
src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roboto-Regular";
|
||||||
|
src: url("../../fonts/Roboto-Regular.woff");
|
||||||
|
src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.ttf") format("ttf");
|
||||||
|
src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.woff") format("woff");
|
||||||
|
src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Colors*/
|
||||||
|
.primary {
|
||||||
|
color: white;
|
||||||
|
background-color: #2196f3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary-flat {
|
||||||
|
color: #2196F3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger {
|
||||||
|
color: white;
|
||||||
|
background-color: #e91e63 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-flat {
|
||||||
|
color: #e91e63 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grey {
|
||||||
|
color: #b3b3b3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==================================================================== */
|
||||||
|
/* Custom button styles based on material design specs. */
|
||||||
|
|
||||||
|
.custom-raised {
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
padding-left: 16px !important;
|
||||||
|
border-radius: 2px !important;
|
||||||
|
padding-right: 16px !important;
|
||||||
|
height: 36px !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-raised:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
background-color: #1976D2 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-raised:focus {
|
||||||
|
box-shadow: none !important;
|
||||||
|
-webkit-box-shadow: none !important;
|
||||||
|
background-color: #1976D2 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-flat {
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
height: 36px !important;
|
||||||
|
border-radius: 2px !important;
|
||||||
|
margin-left: 8px !important;
|
||||||
|
margin-right: 8px !important;
|
||||||
|
padding-left: 8px !important;
|
||||||
|
padding-right: 8px !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
text-transform: uppercase;
|
||||||
|
outline: none !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-flat:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: rgba(0, 0, 0, 0.12) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-flat:focus {
|
||||||
|
outline: none !important;
|
||||||
|
border: none !important;
|
||||||
|
-webkit-box-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
background-color: rgba(0, 0, 0, 0.40) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-button {
|
||||||
|
border-radius: 100% !important;
|
||||||
|
height: 36px !important;
|
||||||
|
width: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==================================================================== */
|
||||||
|
|
||||||
|
/* Body Styling */
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
font-family: "Roboto-Regular" !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
background-color: #e8e8e8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-manager-title {
|
||||||
|
font-family: "Roboto-Medium";
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-manager-sub-title {
|
||||||
|
font-family: "Roboto-Regular";
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-mgt-footer {
|
||||||
|
clear: both;
|
||||||
|
position: relative;
|
||||||
|
height: 50px;
|
||||||
|
width: 100%;
|
||||||
|
color: white;
|
||||||
|
background-color: #334d88;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Login page styles*/
|
||||||
|
#userName {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#password {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-header {
|
||||||
|
background-color: #3f50b5;
|
||||||
|
color: white;
|
||||||
|
height: 128px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-card {
|
||||||
|
width: 25%;
|
||||||
|
height: 50%;
|
||||||
|
margin: 10% auto;
|
||||||
|
font-family: Roboto-Regular;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-header-title {
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-header-logo {
|
||||||
|
height: 70px;
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base layout container */
|
||||||
|
|
||||||
|
/* Base layout header content*/
|
||||||
|
.header-content {
|
||||||
|
height: 128px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
background-color: #3f50b5 !important;
|
||||||
|
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 {
|
||||||
|
padding: 24px 24px 10px 24px;
|
||||||
|
/*margin: 16px 16px 20px 16px;*/
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-text {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
top: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The buttons in the header (User and Notification)*/
|
||||||
|
.header-button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-user-name {
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-top: 15px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-image {
|
||||||
|
height: 43px;
|
||||||
|
width: 100px;
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-button {
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin-right: 10px;
|
||||||
|
position: relative;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-button:hover {
|
||||||
|
background-color: #4353bd;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-button i {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 19px;
|
||||||
|
left: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-header {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-right: 20px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-title {
|
||||||
|
font-family: Roboto-Regular;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-left: 18px;
|
||||||
|
color: RGBA(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search box styles */
|
||||||
|
.search-box {
|
||||||
|
display: flex;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box i {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
color: #BaBaBa;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
top: 98px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-btn {
|
||||||
|
background-color: #ff5722;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-btn:hover {
|
||||||
|
background-color: #E64A19;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-title-container {
|
||||||
|
height: 100px;
|
||||||
|
padding: 50px 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-container {
|
||||||
|
padding: 0 !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
margin-top: 128px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holds the app pages. */
|
||||||
|
.store-card {
|
||||||
|
height: auto;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-link-placeholder {
|
||||||
|
color: #888888;
|
||||||
|
float: right;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-link-placeholder i {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-list {
|
||||||
|
transition: margin-right .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#batch-content {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-icon {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-table-row {
|
||||||
|
height: 62px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 6px;
|
||||||
|
font-family: "Roboto-Regular";
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-table-row:hover {
|
||||||
|
color: white;
|
||||||
|
background-color: #3f50b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-table-header {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-family: "Roboto-Medium";
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-view-image {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-visibility-default {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-screenshot {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-icon {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-banner {
|
||||||
|
width: 400px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#form-error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-banner-dropzone {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
border-radius: 5%;
|
||||||
|
position: relative;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
border: dashed #888888 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-icon-dropzone i {
|
||||||
|
position: absolute;
|
||||||
|
top: 65px;
|
||||||
|
left: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenshot-container {
|
||||||
|
max-width: 600px;
|
||||||
|
display: flex;
|
||||||
|
overflow-x: auto;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-icon-container {
|
||||||
|
height: 300px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-body-content {
|
||||||
|
max-height: 700px;
|
||||||
|
padding-left: 24px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-footer {
|
||||||
|
justify-content: inherit !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-main-btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#img-btn-screenshot {
|
||||||
|
margin: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-create-modal {
|
||||||
|
max-width: 850px;
|
||||||
|
border-radius: 0% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-create-modal-header {
|
||||||
|
background-color: #4353bd;
|
||||||
|
color: white;
|
||||||
|
padding: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-create-modal-content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 {
|
||||||
|
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 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-icon {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
border: solid 1px black;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-updated-date {
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: 40px;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-edit-content {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-app {
|
||||||
|
position: absolute;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-app i {
|
||||||
|
padding: 12px 10px 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-view-field {
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-view-text {
|
||||||
|
font-family: Roboto-Regular;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Platform Specific Styles. */
|
||||||
|
#platform-listing {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-platform i {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#platform-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content {
|
||||||
|
margin: 10px;
|
||||||
|
padding-top: 16px;
|
||||||
|
box-shadow: 2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content .row {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content .col {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content-basic {
|
||||||
|
padding: 0 16px 0 16px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content-more-outer {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content-more {
|
||||||
|
padding: 16px 16px 24px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-content-footer {
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 8px 8px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-text-container {
|
||||||
|
padding: 8px 16px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-button {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-icon-letter {
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
font-size: 70px;
|
||||||
|
color: white;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-icon-container {
|
||||||
|
height: 120px;
|
||||||
|
width: 120px;
|
||||||
|
background-color: #01579B;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-property-container {
|
||||||
|
padding-top: 20px;
|
||||||
|
font-family: Roboto-Regular;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-property-row {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-btn-clear {
|
||||||
|
background-color: white !important;
|
||||||
|
color: rgba(0, 0, 0, 0.50) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-btn-clear:hover {
|
||||||
|
background-color: white !important;
|
||||||
|
color: rgba(0, 0, 0, 0.38) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-btn-clear:focus {
|
||||||
|
background-color: white !important;
|
||||||
|
color: rgba(0, 0, 0, 0.60) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table-row-cell {
|
||||||
|
padding-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-code {
|
||||||
|
text-align: center;
|
||||||
|
font-family: Roboto-Medium;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 15em;
|
||||||
|
color: #BaBaBa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-code p {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-text {
|
||||||
|
text-align: center;
|
||||||
|
font-family: Roboto-Regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #9e9e9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-btn-add {
|
||||||
|
background-color: #bababa !important;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
height: 30px !important;
|
||||||
|
width: 30px;
|
||||||
|
text-align: -webkit-center;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 6px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-btn-add:hover {
|
||||||
|
background-color: #828282 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
If you need to change the color of active steps in stepper,
|
||||||
|
uncomment the following and set the background color and font color as needed.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
.stepper-active-index {
|
||||||
|
background-color: #0a6eff !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-passed-index {
|
||||||
|
background-color: #0a6eff !important;
|
||||||
|
color: green !important;
|
||||||
|
}
|
||||||
|
*/
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ant-upload.ant-upload-drag {
|
||||||
|
height: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-icon{
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-icon img{
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 28%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-title{
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-screenshot img{
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
/*width: 120px;*/
|
||||||
|
height: 31px;
|
||||||
|
margin: 0 5px 16px 24px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image img{
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container{
|
||||||
|
background: #f0f2f5;
|
||||||
|
min-height: 780px
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile{
|
||||||
|
float:right;
|
||||||
|
margin-right: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
.main-container{
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
111
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import "antd/dist/antd.less";
|
||||||
|
import RouteWithSubRoutes from "./components/RouteWithSubRoutes";
|
||||||
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Redirect, Switch,
|
||||||
|
} from 'react-router-dom';
|
||||||
|
import axios from "axios";
|
||||||
|
import {Layout, Spin, Result} from "antd";
|
||||||
|
import ConfigContext from "./context/ConfigContext";
|
||||||
|
|
||||||
|
const {Content} = Layout;
|
||||||
|
const loadingView = (
|
||||||
|
<Layout>
|
||||||
|
<Content style={{
|
||||||
|
padding: '0 0',
|
||||||
|
paddingTop: 300,
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<Spin tip="Loading..."/>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
|
||||||
|
const errorView = (
|
||||||
|
<Result
|
||||||
|
style={{
|
||||||
|
paddingTop: 200
|
||||||
|
}}
|
||||||
|
status="500"
|
||||||
|
title="Error occurred while loading the configuration"
|
||||||
|
subTitle="Please refresh your browser window"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
class App extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
loading: true,
|
||||||
|
error: false,
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
axios.get(
|
||||||
|
window.location.origin + "/entgra/public/conf/config.json",
|
||||||
|
).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
config: res.data
|
||||||
|
})
|
||||||
|
}).catch((error) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
error: true
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {loading, error} = this.state;
|
||||||
|
|
||||||
|
const applicationView = (
|
||||||
|
<Router>
|
||||||
|
<ConfigContext.Provider value={this.state.config}>
|
||||||
|
<div>
|
||||||
|
<Switch>
|
||||||
|
<Redirect exact from="/entgra" to="/entgra/devices"/>
|
||||||
|
{this.props.routes.map((route) => (
|
||||||
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
|
))}
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
</ConfigContext.Provider>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{loading && loadingView}
|
||||||
|
{!loading && !error && applicationView}
|
||||||
|
{error && errorView}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
it('renders without crashing', () => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
ReactDOM.render(<App />, div);
|
||||||
|
ReactDOM.unmountComponentAtNode(div);
|
||||||
|
});
|
||||||
247
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js
vendored
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} from "antd";
|
||||||
|
import TimeAgo from 'javascript-time-ago'
|
||||||
|
|
||||||
|
// Load locale-specific relative date/time formatting rules.
|
||||||
|
import en from 'javascript-time-ago/locale/en'
|
||||||
|
import {withConfigContext} from "../../context/ConfigContext";
|
||||||
|
|
||||||
|
const {Text} = Typography;
|
||||||
|
|
||||||
|
let config = null;
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'Device',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Type',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
render: type => {
|
||||||
|
const defaultPlatformIcons = config.defaultPlatformIcons;
|
||||||
|
let icon = defaultPlatformIcons.default.icon;
|
||||||
|
let color = defaultPlatformIcons.default.color;
|
||||||
|
let theme = defaultPlatformIcons.default.theme;
|
||||||
|
|
||||||
|
if (defaultPlatformIcons.hasOwnProperty(type)) {
|
||||||
|
icon = defaultPlatformIcons[type].icon;
|
||||||
|
color = defaultPlatformIcons[type].color;
|
||||||
|
theme = defaultPlatformIcons[type].theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span style={{fontSize: 20, color: color, textAlign: "center"}}>
|
||||||
|
<Icon type={icon} theme={theme}/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// todo add filtering options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Owner',
|
||||||
|
dataIndex: 'enrolmentInfo',
|
||||||
|
key: 'owner',
|
||||||
|
render: enrolmentInfo => enrolmentInfo.owner
|
||||||
|
// todo add filtering options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Ownership',
|
||||||
|
dataIndex: 'enrolmentInfo',
|
||||||
|
key: 'ownership',
|
||||||
|
render: enrolmentInfo => enrolmentInfo.ownership
|
||||||
|
// todo add filtering options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Status',
|
||||||
|
dataIndex: 'enrolmentInfo',
|
||||||
|
key: 'status',
|
||||||
|
render: (enrolmentInfo) => {
|
||||||
|
const status = enrolmentInfo.status.toLowerCase();
|
||||||
|
let color = "#f9ca24";
|
||||||
|
switch (status) {
|
||||||
|
case "active":
|
||||||
|
color = "#badc58";
|
||||||
|
break;
|
||||||
|
case "created":
|
||||||
|
color = "#6ab04c";
|
||||||
|
break;
|
||||||
|
case "removed":
|
||||||
|
color = "#ff7979";
|
||||||
|
break;
|
||||||
|
case "inactive":
|
||||||
|
color = "#f9ca24";
|
||||||
|
break;
|
||||||
|
case "blocked":
|
||||||
|
color = "#636e72";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return <Tag color={color}>{status}</Tag>;
|
||||||
|
}
|
||||||
|
// todo add filtering options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Last Updated',
|
||||||
|
dataIndex: 'enrolmentInfo',
|
||||||
|
key: 'dateOfLastUpdate',
|
||||||
|
render: (data) => {
|
||||||
|
const {dateOfLastUpdate} = data;
|
||||||
|
const timeAgoString = getTimeAgo(dateOfLastUpdate);
|
||||||
|
return <Tooltip title={new Date(dateOfLastUpdate).toString()}>{timeAgoString}</Tooltip>;
|
||||||
|
}
|
||||||
|
// todo add filtering options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Action',
|
||||||
|
key: 'action',
|
||||||
|
render: () => (
|
||||||
|
<span>
|
||||||
|
<a><Icon type="edit" /></a>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<a><Text type="danger"><Icon type="delete" /></Text></a>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const getTimeAgo = (time) => {
|
||||||
|
const timeAgo = new TimeAgo('en-US');
|
||||||
|
return timeAgo.format(time);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceTable extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
config = this.props.context;
|
||||||
|
TimeAgo.addLocale(en);
|
||||||
|
this.state = {
|
||||||
|
data: [],
|
||||||
|
pagination: {},
|
||||||
|
loading: false,
|
||||||
|
selectedRows: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rowSelection = {
|
||||||
|
onChange: (selectedRowKeys, selectedRows) => {
|
||||||
|
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||||
|
this.setState({
|
||||||
|
selectedRows: selectedRows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//fetch data from api
|
||||||
|
fetch = (params = {}) => {
|
||||||
|
const config = this.props.context;
|
||||||
|
this.setState({loading: true});
|
||||||
|
// get current page
|
||||||
|
const currentPage = (params.hasOwnProperty("page")) ? params.page : 1;
|
||||||
|
|
||||||
|
const extraParams = {
|
||||||
|
offset: 10 * (currentPage - 1), //calculate the offset
|
||||||
|
limit: 10,
|
||||||
|
requireDeviceInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const encodedExtraParams = Object.keys(extraParams).map(key => key + '=' + extraParams[key]).join('&');
|
||||||
|
|
||||||
|
//send request to the invoker
|
||||||
|
axios.get(
|
||||||
|
window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt +
|
||||||
|
"/devices?" + encodedExtraParams,
|
||||||
|
).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
const pagination = {...this.state.pagination};
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
data: res.data.data.devices,
|
||||||
|
pagination,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch((error) => {
|
||||||
|
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
||||||
|
//todo display a popop with error
|
||||||
|
message.error('You are not logged in');
|
||||||
|
window.location.href = window.location.origin + '/entgra/login';
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: "There was a problem",
|
||||||
|
duration: 0,
|
||||||
|
description:
|
||||||
|
"Error occurred while trying to load devices.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({loading: false});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
const pager = {...this.state.pagination};
|
||||||
|
pager.current = pagination.current;
|
||||||
|
this.setState({
|
||||||
|
pagination: pager,
|
||||||
|
});
|
||||||
|
this.fetch({
|
||||||
|
results: pagination.pageSize,
|
||||||
|
page: pagination.current,
|
||||||
|
sortField: sorter.field,
|
||||||
|
sortOrder: sorter.order,
|
||||||
|
...filters,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {data, pagination, loading, selectedRows} = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey={record => record.deviceIdentifier}
|
||||||
|
dataSource={data}
|
||||||
|
pagination={{
|
||||||
|
...pagination,
|
||||||
|
size: "small",
|
||||||
|
// position: "top",
|
||||||
|
showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
|
||||||
|
// showQuickJumper: true
|
||||||
|
}}
|
||||||
|
loading={loading}
|
||||||
|
onChange={this.handleTableChange}
|
||||||
|
rowSelection={this.rowSelection}
|
||||||
|
scroll={{x: 1000}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(DeviceTable);
|
||||||
37
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/RouteWithSubRoutes.js
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from 'react';
|
||||||
|
import {Route} from 'react-router-dom';
|
||||||
|
class RouteWithSubRoutes extends React.Component{
|
||||||
|
props;
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.props = props;
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return(
|
||||||
|
<Route path={this.props.path} exact={this.props.exact} render={(props) => (
|
||||||
|
<this.props.component {...props} {...this.props} routes={this.props.routes}/>
|
||||||
|
)}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RouteWithSubRoutes;
|
||||||
34
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/context/ConfigContext.js
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
|
||||||
|
const ConfigContext = React.createContext();
|
||||||
|
|
||||||
|
export const withConfigContext = Component => {
|
||||||
|
return props => (
|
||||||
|
<ConfigContext.Consumer>
|
||||||
|
{context => {
|
||||||
|
return <Component {...props} context={context}/>;
|
||||||
|
}}
|
||||||
|
</ConfigContext.Consumer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConfigContext;
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-layout-header{
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
box-shadow: 0 2px 8px #f0f1f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.steps-content {
|
||||||
|
margin-top: 16px;
|
||||||
|
border: 1px dashed #e9e9e9;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
min-height: 200px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.steps-action {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input-affix-wrapper .ant-input{
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
~
|
||||||
|
~ Entgra (pvt) Ltd. 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/>
|
||||||
|
<title>Entgra Device Management</title>
|
||||||
|
</head>
|
||||||
|
<div id="root"></div>
|
||||||
|
</html>
|
||||||
68
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import * as serviceWorker from './serviceWorker';
|
||||||
|
import App from "./App";
|
||||||
|
import Login from "./pages/Login";
|
||||||
|
import Dashboard from "./pages/Dashboard/Dashboard";
|
||||||
|
import './index.css';
|
||||||
|
import Devices from "./pages/Dashboard/Devices/Devices";
|
||||||
|
import Reports from "./pages/Dashboard/Reports/Reports";
|
||||||
|
import Geo from "./pages/Dashboard/Geo/Geo";
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/entgra/login',
|
||||||
|
exact: true,
|
||||||
|
component: Login
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/entgra',
|
||||||
|
exact: false,
|
||||||
|
component: Dashboard,
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/entgra/devices',
|
||||||
|
component: Devices,
|
||||||
|
exact: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/entgra/geo',
|
||||||
|
component: Geo,
|
||||||
|
exact: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/entgra/reports',
|
||||||
|
component: Reports,
|
||||||
|
exact: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<App routes={routes}/>,
|
||||||
|
document.getElementById('root'));
|
||||||
|
|
||||||
|
// If you want your app e and load faster, you can change
|
||||||
|
// unregister() to register() below. Note this comes with some pitfalls.
|
||||||
|
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||||
|
serviceWorker.unregister();
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||||
|
<g fill="#61DAFB">
|
||||||
|
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||||
|
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||||
|
<path d="M520.5 78.1z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
94
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {Layout, Menu, Icon} from 'antd';
|
||||||
|
import {Switch, Link} from "react-router-dom";
|
||||||
|
import RouteWithSubRoutes from "../../components/RouteWithSubRoutes"
|
||||||
|
import {Redirect} from 'react-router'
|
||||||
|
import "../../App.css";
|
||||||
|
import {withConfigContext} from "../../context/ConfigContext";
|
||||||
|
import Logout from "./Logout/Logout";
|
||||||
|
|
||||||
|
const {Header, Content, Footer} = Layout;
|
||||||
|
const {SubMenu} = Menu;
|
||||||
|
|
||||||
|
|
||||||
|
class Dashboard extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
routes: props.routes,
|
||||||
|
selectedKeys: [],
|
||||||
|
deviceTypes: []
|
||||||
|
};
|
||||||
|
this.logo = this.props.context.theme.logo;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Layout className="layout">
|
||||||
|
<Header style={{paddingLeft: 0, paddingRight: 0}}>
|
||||||
|
<div className="logo-image">
|
||||||
|
<img alt="logo" src={this.logo}/>
|
||||||
|
</div>
|
||||||
|
<Menu
|
||||||
|
theme="light"
|
||||||
|
mode="horizontal"
|
||||||
|
defaultSelectedKeys={['1']}
|
||||||
|
style={{lineHeight: '64px'}}
|
||||||
|
>
|
||||||
|
<Menu.Item key="devices"><Link to="/entgra/devices"><Icon type="appstore"/>Devices</Link></Menu.Item>
|
||||||
|
<Menu.Item key="geo"><Link to="/entgra/geo"><Icon type="environment"/>Geo</Link></Menu.Item>
|
||||||
|
<Menu.Item key="reports"><Link to="/entgra/reports"><Icon type="bar-chart"/>Reports</Link></Menu.Item>
|
||||||
|
|
||||||
|
<SubMenu className="profile"
|
||||||
|
title={
|
||||||
|
<span className="submenu-title-wrapper">
|
||||||
|
<Icon type="user"/>
|
||||||
|
Profile
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Logout/>
|
||||||
|
</SubMenu>
|
||||||
|
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
</Header>
|
||||||
|
</Layout>
|
||||||
|
<Layout>
|
||||||
|
<Content style={{marginTop: 2}}>
|
||||||
|
<Switch>
|
||||||
|
<Redirect exact from="/entgra" to="/entgra/devices"/>
|
||||||
|
{this.state.routes.map((route) => (
|
||||||
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
|
))}
|
||||||
|
</Switch>
|
||||||
|
</Content>
|
||||||
|
<Footer style={{textAlign: 'center'}}>
|
||||||
|
©2019 entgra.io
|
||||||
|
</Footer>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Dashboard);
|
||||||
67
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {
|
||||||
|
PageHeader,
|
||||||
|
Typography,
|
||||||
|
Breadcrumb,
|
||||||
|
Icon,
|
||||||
|
Card
|
||||||
|
} from "antd";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import DeviceTable from "../../../components/Devices/DevicesTable";
|
||||||
|
|
||||||
|
const {Paragraph} = Typography;
|
||||||
|
|
||||||
|
class Devices extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader style={{paddingTop: 0}}>
|
||||||
|
<Breadcrumb style={{paddingBottom: 16}}>
|
||||||
|
<Breadcrumb.Item>
|
||||||
|
<Link to="/entgra/devices"><Icon type="home"/> Home</Link>
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>Devices</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="wrap">
|
||||||
|
<h3>Devices</h3>
|
||||||
|
<Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an
|
||||||
|
illud incorrupte nam.</Paragraph>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||||
|
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
|
||||||
|
<DeviceTable/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Devices;
|
||||||
65
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Geo/Geo.js
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {
|
||||||
|
PageHeader,
|
||||||
|
Typography,
|
||||||
|
Breadcrumb,
|
||||||
|
Icon,
|
||||||
|
Card
|
||||||
|
} from "antd";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import DeviceTable from "../../../components/Devices/DevicesTable";
|
||||||
|
|
||||||
|
const {Paragraph} = Typography;
|
||||||
|
|
||||||
|
class Geo extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader style={{paddingTop: 0}}>
|
||||||
|
<Breadcrumb style={{paddingBottom: 16}}>
|
||||||
|
<Breadcrumb.Item>
|
||||||
|
<Link to="/entgra"><Icon type="home"/> Home</Link>
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>Geo</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="wrap">
|
||||||
|
<h3>Geo</h3>
|
||||||
|
<Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an
|
||||||
|
illud incorrupte nam.</Paragraph>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Geo;
|
||||||
80
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Logout/Logout.js
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {notification, Menu, Icon} from 'antd';
|
||||||
|
import axios from 'axios';
|
||||||
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
|
||||||
|
/*
|
||||||
|
This class for call the logout api by sending request
|
||||||
|
*/
|
||||||
|
class Logout extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
inValid: false,
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
This function call the logout api when the request is success
|
||||||
|
*/
|
||||||
|
handleSubmit = () => {
|
||||||
|
|
||||||
|
const thisForm = this;
|
||||||
|
const config = this.props.context;
|
||||||
|
|
||||||
|
thisForm.setState({
|
||||||
|
inValid: false
|
||||||
|
});
|
||||||
|
|
||||||
|
axios.post(window.location.origin + config.serverConfig.logoutUri
|
||||||
|
).then(res => {
|
||||||
|
//if the api call status is correct then user will logout and then it goes to login page
|
||||||
|
if (res.status === 200) {
|
||||||
|
window.location = window.location.origin + "/entgra/login";
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
|
||||||
|
if (error.hasOwnProperty("response") && error.response.status === 400) {
|
||||||
|
thisForm.setState({
|
||||||
|
inValid: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: "There was a problem",
|
||||||
|
duration: 0,
|
||||||
|
description:
|
||||||
|
"Error occurred while trying to logout.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<Menu.Item key="1" onClick={this.handleSubmit}><Icon type="logout"/>Logout</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Logout);
|
||||||
65
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Reports/Reports.js
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {
|
||||||
|
PageHeader,
|
||||||
|
Typography,
|
||||||
|
Breadcrumb,
|
||||||
|
Icon,
|
||||||
|
Card
|
||||||
|
} from "antd";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import DeviceTable from "../../../components/Devices/DevicesTable";
|
||||||
|
|
||||||
|
const {Paragraph} = Typography;
|
||||||
|
|
||||||
|
class Reports extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader style={{paddingTop: 0}}>
|
||||||
|
<Breadcrumb style={{paddingBottom: 16}}>
|
||||||
|
<Breadcrumb.Item>
|
||||||
|
<Link to="/entgra"><Icon type="home"/> Home</Link>
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>Reports</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="wrap">
|
||||||
|
<h3>Reports</h3>
|
||||||
|
<Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an
|
||||||
|
illud incorrupte nam.</Paragraph>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Reports;
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@-moz-keyframes spin {
|
||||||
|
0% {
|
||||||
|
-moz-transform: rotate(0deg) scale(1.0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-moz-transform: rotate(360deg) scale(0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg) scale(1.0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg) scale(0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg) scale(1.0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg) scale(0.1);
|
||||||
|
transform: rotate(360deg) scale(0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.background {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center 110px;
|
||||||
|
background-size: 100%;
|
||||||
|
animation: spin 200s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
171
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.js
vendored
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 from "react";
|
||||||
|
import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox} from 'antd';
|
||||||
|
import './Login.css';
|
||||||
|
import axios from 'axios';
|
||||||
|
import {withConfigContext} from "../context/ConfigContext";
|
||||||
|
|
||||||
|
const {Title} = Typography;
|
||||||
|
const {Text} = Typography;
|
||||||
|
|
||||||
|
class Login extends React.Component {
|
||||||
|
render() {
|
||||||
|
const config = this.props.context;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="background">
|
||||||
|
</div>
|
||||||
|
<div className="content">
|
||||||
|
<Row>
|
||||||
|
<Col xs={3} sm={3} md={10}>
|
||||||
|
|
||||||
|
</Col>
|
||||||
|
<Col xs={18} sm={18} md={4}>
|
||||||
|
<Row style={{marginBottom: 20}}>
|
||||||
|
<Col style={{textAlign: "center"}}>
|
||||||
|
<img style={
|
||||||
|
{
|
||||||
|
marginTop: 36,
|
||||||
|
height: 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src={config.theme.logo}/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Title level={2}>Login</Title>
|
||||||
|
<WrappedNormalLoginForm/>
|
||||||
|
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={4} offset={10}>
|
||||||
|
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NormalLoginForm extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
inValid: false,
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = (e) => {
|
||||||
|
const thisForm = this;
|
||||||
|
const config = this.props.context;
|
||||||
|
console.log(config);
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.form.validateFields((err, values) => {
|
||||||
|
thisForm.setState({
|
||||||
|
inValid: false
|
||||||
|
});
|
||||||
|
if (!err) {
|
||||||
|
thisForm.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
const parameters = {
|
||||||
|
username: values.username,
|
||||||
|
password: values.password,
|
||||||
|
platform: "entgra"
|
||||||
|
};
|
||||||
|
|
||||||
|
const request = Object.keys(parameters).map(key => key + '=' + parameters[key]).join('&');
|
||||||
|
|
||||||
|
axios.post(window.location.origin+ config.serverConfig.loginUri, request
|
||||||
|
).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
window.location = window.location.origin+ "/entgra";
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
if (error.response.status === 400) {
|
||||||
|
thisForm.setState({
|
||||||
|
inValid: true,
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {getFieldDecorator} = this.props.form;
|
||||||
|
let errorMsg = "";
|
||||||
|
if (this.state.inValid) {
|
||||||
|
errorMsg = <Text type="danger">Invalid Login Details</Text>;
|
||||||
|
}
|
||||||
|
let loading = "";
|
||||||
|
if (this.state.loading) {
|
||||||
|
loading = <Text type="secondary">Loading..</Text>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Form onSubmit={this.handleSubmit} className="login-form">
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator('username', {
|
||||||
|
rules: [{required: true, message: 'Please input your username!'}],
|
||||||
|
})(
|
||||||
|
<Input name="username" style={{height: 32}}
|
||||||
|
prefix={<Icon type="user" style={{color: 'rgba(0,0,0,.25)'}}/>}
|
||||||
|
placeholder="Username"/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator('password', {
|
||||||
|
rules: [{required: true, message: 'Please input your Password!'}],
|
||||||
|
})(
|
||||||
|
<Input name="password" style={{height: 32}}
|
||||||
|
prefix={<Icon type="lock" style={{color: 'rgba(0,0,0,.25)'}}/>} type="password"
|
||||||
|
placeholder="Password"/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
{loading}
|
||||||
|
{errorMsg}
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator('remember', {
|
||||||
|
valuePropName: 'checked',
|
||||||
|
initialValue: true,
|
||||||
|
})(
|
||||||
|
<Checkbox>Remember me</Checkbox>
|
||||||
|
)}
|
||||||
|
<br/>
|
||||||
|
<a className="login-form-forgot" href="">Forgot password</a>
|
||||||
|
<Button block type="primary" htmlType="submit" className="login-form-button">
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const WrappedNormalLoginForm = withConfigContext(Form.create({name: 'normal_login'})(NormalLoginForm));
|
||||||
|
|
||||||
|
export default withConfigContext(Login);
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 120px;
|
||||||
|
height: 31px;
|
||||||
|
margin: 16px 0 16px 20px;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
img{
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input{
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
153
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/serviceWorker.js
vendored
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. 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 optional code is used to register a service worker.
|
||||||
|
// register() is not called by default.
|
||||||
|
|
||||||
|
// This lets the app load faster on subsequent visits in production, and gives
|
||||||
|
// it offline capabilities. However, it also means that developers (and users)
|
||||||
|
// will only see deployed updates on subsequent visits to a page, after all the
|
||||||
|
// existing tabs open on the page have been closed, since previously cached
|
||||||
|
// resources are updated in the background.
|
||||||
|
|
||||||
|
// To learn more about the benefits of this model and instructions on how to
|
||||||
|
// opt-in, read https://bit.ly/CRA-PWA
|
||||||
|
|
||||||
|
const isLocalhost = Boolean(
|
||||||
|
window.location.hostname === 'localhost' ||
|
||||||
|
// [::1] is the IPv6 localhost address.
|
||||||
|
window.location.hostname === '[::1]' ||
|
||||||
|
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||||
|
window.location.hostname.match(
|
||||||
|
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
export function register(config) {
|
||||||
|
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||||
|
// The URL constructor is available in all browsers that support SW.
|
||||||
|
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||||
|
if (publicUrl.origin !== window.location.origin) {
|
||||||
|
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||||
|
// from what our page is served on. This might happen if a CDN is used to
|
||||||
|
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||||
|
|
||||||
|
if (isLocalhost) {
|
||||||
|
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||||
|
checkValidServiceWorker(swUrl, config);
|
||||||
|
|
||||||
|
// Add some additional logging to localhost, pointing developers to the
|
||||||
|
// service worker/PWA documentation.
|
||||||
|
navigator.serviceWorker.ready.then(() => {
|
||||||
|
console.log(
|
||||||
|
'This web app is being served cache-first by a service ' +
|
||||||
|
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Is not localhost. Just register service worker
|
||||||
|
registerValidSW(swUrl, config);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerValidSW(swUrl, config) {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register(swUrl)
|
||||||
|
.then(registration => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing;
|
||||||
|
if (installingWorker == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
if (installingWorker.state === 'installed') {
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// At this point, the updated precached content has been fetched,
|
||||||
|
// but the previous service worker will still serve the older
|
||||||
|
// content until all client tabs are closed.
|
||||||
|
console.log(
|
||||||
|
'New content is available and will be used when all ' +
|
||||||
|
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onUpdate) {
|
||||||
|
config.onUpdate(registration);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// At this point, everything has been precached.
|
||||||
|
// It's the perfect time to display a
|
||||||
|
// "Content is cached for offline use." message.
|
||||||
|
console.log('Content is cached for offline use.');
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onSuccess) {
|
||||||
|
config.onSuccess(registration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error during service worker registration:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkValidServiceWorker(swUrl, config) {
|
||||||
|
// Check if the service worker can be found. If it can't reload the page.
|
||||||
|
fetch(swUrl)
|
||||||
|
.then(response => {
|
||||||
|
// Ensure service worker exists, and that we really are getting a JS file.
|
||||||
|
const contentType = response.headers.get('content-type');
|
||||||
|
if (
|
||||||
|
response.status === 404 ||
|
||||||
|
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||||
|
) {
|
||||||
|
// No service worker found. Probably a different app. Reload the page.
|
||||||
|
navigator.serviceWorker.ready.then(registration => {
|
||||||
|
registration.unregister().then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Service worker found. Proceed as normal.
|
||||||
|
registerValidSW(swUrl, config);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log(
|
||||||
|
'No internet connection found. App is running in offline mode.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregister() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.ready.then(registration => {
|
||||||
|
registration.unregister();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
var path = require('path');
|
||||||
|
const HtmlWebPackPlugin = require("html-webpack-plugin");
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
const configurations = require("./public/conf/config.json");
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
devtool: "source-map",
|
||||||
|
output: {
|
||||||
|
publicPath: '/entgra/'
|
||||||
|
},
|
||||||
|
watch: false,
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
AppData: path.resolve(__dirname, 'source/src/app/common/'),
|
||||||
|
AppComponents: path.resolve(__dirname, 'source/src/app/components/')
|
||||||
|
},
|
||||||
|
extensions: ['.jsx', '.js', '.ttf', '.woff', '.woff2', '.svg']
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js|jsx)$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'babel-loader'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.html$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "html-loader",
|
||||||
|
options: { minimize: true }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [MiniCssExtractPlugin.loader, "css-loader"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader,
|
||||||
|
"css-loader",
|
||||||
|
"postcss-loader",
|
||||||
|
"sass-loader"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: [ 'style-loader', 'scss-loader' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.less$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "style-loader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "css-loader",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "less-loader",
|
||||||
|
options: {
|
||||||
|
modifyVars: {
|
||||||
|
'primary-color': configurations.theme.primaryColor,
|
||||||
|
'link-color': configurations.theme.primaryColor,
|
||||||
|
},
|
||||||
|
javascriptEnabled: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff|woff2|eot|ttf|svg)$/,
|
||||||
|
loader: 'url-loader?limit=100000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g)/i,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "url-loader",
|
||||||
|
options: {
|
||||||
|
name: "./img/[name].[ext]",
|
||||||
|
limit: 10000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "img-loader"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebPackPlugin({
|
||||||
|
template: "./src/index.html",
|
||||||
|
filename: "./index.html"
|
||||||
|
}),
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "[name].css",
|
||||||
|
chunkFilename: "[id].css"
|
||||||
|
})
|
||||||
|
],
|
||||||
|
externals: {
|
||||||
|
'Config': JSON.stringify(require('./public/conf/config.json'))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
config.watch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?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>Entgra-Webapp</display-name>
|
||||||
|
<error-page>
|
||||||
|
<error-code>404</error-code>
|
||||||
|
<location>/index.html</location>
|
||||||
|
</error-page>
|
||||||
|
</web-app>
|
||||||
@ -901,12 +901,7 @@ public interface DeviceManagementService {
|
|||||||
required = true)
|
required = true)
|
||||||
@PathParam("device-id")
|
@PathParam("device-id")
|
||||||
@Size(max = 45)
|
@Size(max = 45)
|
||||||
String deviceId,
|
String deviceId);
|
||||||
@ApiParam(
|
|
||||||
name = "permanentDelete",
|
|
||||||
value = "Boolean flag indicating whether to permanently delete the device.",
|
|
||||||
required = false)
|
|
||||||
@QueryParam("permanentDelete") boolean permanentDelete);
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/{type}/{id}/features")
|
@Path("/{type}/{id}/features")
|
||||||
|
|||||||
@ -15,6 +15,22 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.jaxrs.service.api.admin;
|
package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
|
||||||
|
|
||||||
@ -76,6 +92,12 @@ import java.util.List;
|
|||||||
description = "Update the ownership of the device",
|
description = "Update the ownership of the device",
|
||||||
key = "perm:admin:devices:update-enrollment",
|
key = "perm:admin:devices:update-enrollment",
|
||||||
permissions = {"/device-mgt/admin/devices/update-enrollment"}
|
permissions = {"/device-mgt/admin/devices/update-enrollment"}
|
||||||
|
),
|
||||||
|
@Scope(
|
||||||
|
name = "Permanently Delete the device specified by device id",
|
||||||
|
description = "Permanently Delete the device specified by device id",
|
||||||
|
key = "perm:devices:permanent-delete",
|
||||||
|
permissions = {"/device-mgt/admin/devices/permanent-delete"}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -225,4 +247,72 @@ public interface DeviceManagementAdminService {
|
|||||||
value = "List of device identifiers.",
|
value = "List of device identifiers.",
|
||||||
required = true)
|
required = true)
|
||||||
List<String> deviceIdentifiers);
|
List<String> deviceIdentifiers);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/type/{device-type}/id/{device-id}")
|
||||||
|
@ApiOperation(
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
consumes = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "DELETE",
|
||||||
|
value = "Permanently remove the Device Specified by the Device ID",
|
||||||
|
notes = "Returns the status of the permanently deleted device operation and the details of the deleted device.",
|
||||||
|
tags = "Device Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:permanent-delete")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK. \n Successfully deleted the device permanently.",
|
||||||
|
response = Device.class,
|
||||||
|
responseHeaders = {
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "Content-Type",
|
||||||
|
description = "The content type of the body"),
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "ETag",
|
||||||
|
description = "Entity Tag of the response resource.\n" +
|
||||||
|
"Used by caches, or in conditional requests."),
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "Last-Modified",
|
||||||
|
description = "Date and time the resource has been modified the last time.\n" +
|
||||||
|
"Used by caches, or in conditional requests."),
|
||||||
|
}),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 304,
|
||||||
|
message = "Not Modified. Empty body because the client already has the latest " +
|
||||||
|
"version of the requested resource."),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 400,
|
||||||
|
message = "Bad Request. \n Invalid request or validation error.",
|
||||||
|
response = ErrorResponse.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 404,
|
||||||
|
message = "Not Found. \n No device is found under the provided type and id.",
|
||||||
|
response = ErrorResponse.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Internal Server Error. \n " +
|
||||||
|
"Server error occurred while retrieving information requested device.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response deleteDevicePermanently(
|
||||||
|
@ApiParam(
|
||||||
|
name = "device-type",
|
||||||
|
value = "The device type, such as ios, android, or windows.",
|
||||||
|
required = true)
|
||||||
|
@PathParam("device-type")
|
||||||
|
@Size(max = 45)
|
||||||
|
String deviceType,
|
||||||
|
@ApiParam(
|
||||||
|
name = "device-id",
|
||||||
|
value = "The device identifier of the device.",
|
||||||
|
required = true)
|
||||||
|
@PathParam("device-id")
|
||||||
|
@Size(max = 45)
|
||||||
|
String deviceId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,7 +105,6 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Path("/devices")
|
@Path("/devices")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@ -326,8 +325,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
|
|||||||
@Override
|
@Override
|
||||||
@Path("/type/{device-type}/id/{device-id}")
|
@Path("/type/{device-type}/id/{device-id}")
|
||||||
public Response deleteDevice(@PathParam("device-type") String deviceType,
|
public Response deleteDevice(@PathParam("device-type") String deviceType,
|
||||||
@PathParam("device-id") String deviceId,
|
@PathParam("device-id") String deviceId) {
|
||||||
@QueryParam("permanentDelete") boolean permanentDelete) {
|
|
||||||
DeviceManagementProviderService deviceManagementProviderService =
|
DeviceManagementProviderService deviceManagementProviderService =
|
||||||
DeviceMgtAPIUtils.getDeviceManagementService();
|
DeviceMgtAPIUtils.getDeviceManagementService();
|
||||||
try {
|
try {
|
||||||
@ -336,16 +334,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
|
|||||||
if (persistedDevice == null) {
|
if (persistedDevice == null) {
|
||||||
return Response.status(Response.Status.NOT_FOUND).build();
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
}
|
}
|
||||||
|
boolean response = deviceManagementProviderService.disenrollDevice(deviceIdentifier);
|
||||||
boolean response;
|
|
||||||
|
|
||||||
if (permanentDelete) {
|
|
||||||
response = deviceManagementProviderService.deleteDevice(deviceIdentifier);
|
|
||||||
} else {
|
|
||||||
response = deviceManagementProviderService.disenrollDevice(deviceIdentifier);
|
|
||||||
}
|
|
||||||
return Response.status(Response.Status.OK).entity(response).build();
|
return Response.status(Response.Status.OK).entity(response).build();
|
||||||
|
|
||||||
} catch (DeviceManagementException e) {
|
} catch (DeviceManagementException e) {
|
||||||
String msg = "Error encountered while deleting device of type : " + deviceType + " and " +
|
String msg = "Error encountered while deleting device of type : " + deviceType + " and " +
|
||||||
"ID : " + deviceId;
|
"ID : " + deviceId;
|
||||||
|
|||||||
@ -15,6 +15,22 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.jaxrs.service.impl.admin;
|
package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin;
|
||||||
|
|
||||||
@ -24,10 +40,12 @@ import org.wso2.carbon.base.MultitenantConstants;
|
|||||||
import org.wso2.carbon.context.CarbonContext;
|
import org.wso2.carbon.context.CarbonContext;
|
||||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException;
|
import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException;
|
||||||
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
|
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceManagementAdminService;
|
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceManagementAdminService;
|
||||||
@ -96,25 +114,53 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|||||||
@QueryParam("owner") String owner,
|
@QueryParam("owner") String owner,
|
||||||
List<String> deviceIdentifiers){
|
List<String> deviceIdentifiers){
|
||||||
try {
|
try {
|
||||||
if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)){
|
if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)) {
|
||||||
String msg = "Device owner is updated successfully.";
|
String msg = "Device owner is updated successfully.";
|
||||||
return Response.status(Response.Status.OK).entity(msg).build();
|
return Response.status(Response.Status.OK).entity(msg).build();
|
||||||
}
|
}
|
||||||
String msg = "Device owner updating is failed.";
|
String msg = "Device owner updating is failed.";
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
} catch(InvalidDeviceException e){
|
} catch (InvalidDeviceException e) {
|
||||||
String msg = "Invalid device identifiers are found with the request.";
|
String msg = "Invalid device identifiers are found with the request.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||||
}catch (DeviceManagementException e) {
|
} catch (DeviceManagementException e) {
|
||||||
String msg = "Error occurred when updating device owners.";
|
String msg = "Error occurred when updating device owners.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
} catch (UserNotFoundException e) {
|
} catch (UserNotFoundException e) {
|
||||||
String msg = "Couldn't found the owner in user store to update the owner of devices.";
|
String msg = "Couldn't found the owner in user store to update the owner of devices.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Override
|
||||||
|
@Path("/type/{device-type}/id/{device-id}")
|
||||||
|
public Response deleteDevicePermanently(@PathParam("device-type") String deviceType,
|
||||||
|
@PathParam("device-id") String deviceId) {
|
||||||
|
DeviceManagementProviderService deviceManagementProviderService =
|
||||||
|
DeviceMgtAPIUtils.getDeviceManagementService();
|
||||||
|
try {
|
||||||
|
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType);
|
||||||
|
Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, true);
|
||||||
|
if (persistedDevice == null) {
|
||||||
|
String msg = "No device found with the device type: " + deviceType +
|
||||||
|
" having the device ID: " + deviceId + " to permanently delete.";
|
||||||
|
log.error(msg);
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).entity(
|
||||||
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
|
}
|
||||||
|
boolean response = deviceManagementProviderService.deleteDevice(deviceIdentifier);
|
||||||
|
return Response.status(Response.Status.OK).entity(response).build();
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
String msg = "Error encountered while permanently deleting device of type : " + deviceType + " and " +
|
||||||
|
"ID : " + deviceId;
|
||||||
|
log.error(msg, e);
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity(
|
||||||
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -140,7 +140,8 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PUT
|
@PUT
|
||||||
public Response updateDeviceType(String type, DeviceType deviceType) {
|
@Path("/{type}")
|
||||||
|
public Response updateDeviceType(@PathParam("type") String type, DeviceType deviceType) {
|
||||||
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
|
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
|
||||||
if (deviceType.getName() == null || !deviceType.getName().equals(type)) {
|
if (deviceType.getName() == null || !deviceType.getName().equals(type)) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
|
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
|
||||||
@ -166,7 +167,10 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response addDeviceTypePlatformConfig(String type, PlatformConfiguration platformConfiguration) {
|
@POST
|
||||||
|
@Path("/{type}/configs")
|
||||||
|
public Response addDeviceTypePlatformConfig(@PathParam("type") String type,
|
||||||
|
PlatformConfiguration platformConfiguration) {
|
||||||
boolean isSaved;
|
boolean isSaved;
|
||||||
if (platformConfiguration.getType() == null || !platformConfiguration.getType().equals(type)) {
|
if (platformConfiguration.getType() == null || !platformConfiguration.getType().equals(type)) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
|
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
|
||||||
|
|||||||
@ -481,8 +481,7 @@ public class DeviceManagementServiceImplTest {
|
|||||||
public void testDeleteDevice() {
|
public void testDeleteDevice() {
|
||||||
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
|
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
|
||||||
.toReturn(this.deviceManagementProviderService);
|
.toReturn(this.deviceManagementProviderService);
|
||||||
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
|
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
|
||||||
, false);
|
|
||||||
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
|
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,8 +491,7 @@ public class DeviceManagementServiceImplTest {
|
|||||||
.toReturn(this.deviceManagementProviderService);
|
.toReturn(this.deviceManagementProviderService);
|
||||||
Mockito.when(this.deviceManagementProviderService
|
Mockito.when(this.deviceManagementProviderService
|
||||||
.getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null);
|
.getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null);
|
||||||
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
|
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
|
||||||
, false);
|
|
||||||
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
|
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
|
||||||
Mockito.reset(this.deviceManagementProviderService);
|
Mockito.reset(this.deviceManagementProviderService);
|
||||||
}
|
}
|
||||||
@ -504,8 +502,7 @@ public class DeviceManagementServiceImplTest {
|
|||||||
.toReturn(this.deviceManagementProviderService);
|
.toReturn(this.deviceManagementProviderService);
|
||||||
Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class)))
|
Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class)))
|
||||||
.thenThrow(new DeviceManagementException());
|
.thenThrow(new DeviceManagementException());
|
||||||
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
|
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
|
||||||
, false);
|
|
||||||
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
|
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
|
||||||
Mockito.reset(this.deviceManagementProviderService);
|
Mockito.reset(this.deviceManagementProviderService);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -277,6 +277,17 @@ public interface DeviceDAO {
|
|||||||
*/
|
*/
|
||||||
List<Device> getDevices(PaginationRequest request, int tenantId) throws DeviceManagementDAOException;
|
List<Device> getDevices(PaginationRequest request, int tenantId) throws DeviceManagementDAOException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to search for devices within a specific group.
|
||||||
|
*
|
||||||
|
* @param request PaginationRequest object holding the data for pagination
|
||||||
|
* @param tenantId tenant id.
|
||||||
|
* @return returns paginated list of devices.
|
||||||
|
* @throws DeviceManagementDAOException
|
||||||
|
*/
|
||||||
|
List<Device> searchDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to retrieve all the devices of a given tenant and device type.
|
* This method is used to retrieve all the devices of a given tenant and device type.
|
||||||
*
|
*
|
||||||
@ -498,7 +509,8 @@ public interface DeviceDAO {
|
|||||||
* @throws DeviceManagementDAOException throws {@link DeviceManagementDAOException} if connections establishment
|
* @throws DeviceManagementDAOException throws {@link DeviceManagementDAOException} if connections establishment
|
||||||
* fails.
|
* fails.
|
||||||
*/
|
*/
|
||||||
List<Device> getDevicesByIdentifiers(List<String> deviceIdentifiers, int tenantId) throws DeviceManagementDAOException;
|
List<Device> getDevicesByIdentifiers(List<String> deviceIdentifiers, int tenantId)
|
||||||
|
throws DeviceManagementDAOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to permanently delete the device and its related details
|
* This method is used to permanently delete the device and its related details
|
||||||
@ -508,4 +520,3 @@ public interface DeviceDAO {
|
|||||||
*/
|
*/
|
||||||
void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
|
void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1507,8 +1507,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
|
|||||||
}
|
}
|
||||||
return devices;
|
return devices;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags",
|
throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to get devices for"
|
||||||
e);
|
+ " given device identifiers.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -369,7 +369,11 @@ public class EnrollmentDAOImpl implements EnrollmentDAO {
|
|||||||
try {
|
try {
|
||||||
Connection conn = this.getConnection();
|
Connection conn = this.getConnection();
|
||||||
boolean updateStatus = true;
|
boolean updateStatus = true;
|
||||||
String sql = "UPDATE DM_ENROLMENT SET OWNER = ? WHERE ID = ? AND TENANT_ID = ?";
|
String sql = "UPDATE "
|
||||||
|
+ "DM_ENROLMENT "
|
||||||
|
+ "SET OWNER = ? "
|
||||||
|
+ "WHERE ID = ? AND "
|
||||||
|
+ "TENANT_ID = ?";
|
||||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
if (conn.getMetaData().supportsBatchUpdates()) {
|
if (conn.getMetaData().supportsBatchUpdates()) {
|
||||||
for (Device device : devices) {
|
for (Device device : devices) {
|
||||||
@ -381,6 +385,7 @@ public class EnrollmentDAOImpl implements EnrollmentDAO {
|
|||||||
for (int i : ps.executeBatch()) {
|
for (int i : ps.executeBatch()) {
|
||||||
if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) {
|
if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) {
|
||||||
updateStatus = false;
|
updateStatus = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -390,14 +395,15 @@ public class EnrollmentDAOImpl implements EnrollmentDAO {
|
|||||||
ps.setInt(3, tenantId);
|
ps.setInt(3, tenantId);
|
||||||
if (ps.executeUpdate() == 0) {
|
if (ps.executeUpdate() == 0) {
|
||||||
updateStatus = false;
|
updateStatus = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return updateStatus;
|
return updateStatus;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags",
|
throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to update the "
|
||||||
e);
|
+ "owner of the device enrollment.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -153,6 +153,137 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Device> searchDevicesInGroup(PaginationRequest request, int tenantId)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
Connection conn;
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<Device> devices = null;
|
||||||
|
|
||||||
|
int groupId = request.getGroupId();
|
||||||
|
String deviceType = request.getDeviceType();
|
||||||
|
boolean isDeviceTypeProvided = false;
|
||||||
|
String deviceName = request.getDeviceName();
|
||||||
|
boolean isDeviceNameProvided = false;
|
||||||
|
String owner = request.getOwner();
|
||||||
|
boolean isOwnerProvided = false;
|
||||||
|
String ownerPattern = request.getOwnerPattern();
|
||||||
|
boolean isOwnerPatternProvided = false;
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isOwnershipProvided = false;
|
||||||
|
String status = request.getStatus();
|
||||||
|
boolean isStatusProvided = false;
|
||||||
|
Date since = request.getSince();
|
||||||
|
boolean isSinceProvided = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = this.getConnection();
|
||||||
|
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
|
||||||
|
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
|
||||||
|
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
|
||||||
|
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
|
||||||
|
"FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " +
|
||||||
|
"FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" +
|
||||||
|
" d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?";
|
||||||
|
|
||||||
|
|
||||||
|
//Add the query for device-name
|
||||||
|
if (deviceName != null && !deviceName.isEmpty()) {
|
||||||
|
sql = sql + " AND d.NAME LIKE ?";
|
||||||
|
isDeviceNameProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + ") gd, DM_DEVICE_TYPE t";
|
||||||
|
|
||||||
|
if (since != null) {
|
||||||
|
sql = sql + ", DM_DEVICE_DETAIL dt";
|
||||||
|
isSinceProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
|
||||||
|
|
||||||
|
//Add query for last updated timestamp
|
||||||
|
if (isSinceProvided) {
|
||||||
|
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the query for device-type
|
||||||
|
if (deviceType != null && !deviceType.isEmpty()) {
|
||||||
|
sql = sql + " AND t.NAME = ?";
|
||||||
|
isDeviceTypeProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? ";
|
||||||
|
|
||||||
|
//Add the query for ownership
|
||||||
|
if (ownership != null && !ownership.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
isOwnershipProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for owner
|
||||||
|
if (owner != null && !owner.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER = ?";
|
||||||
|
isOwnerProvided = true;
|
||||||
|
} else if (ownerPattern != null && !ownerPattern.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER LIKE ?";
|
||||||
|
isOwnerPatternProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for status
|
||||||
|
if (status != null && !status.isEmpty()) {
|
||||||
|
sql = sql + " AND e.STATUS = ?";
|
||||||
|
isStatusProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " LIMIT ?,?";
|
||||||
|
|
||||||
|
stmt = conn.prepareStatement(sql);
|
||||||
|
|
||||||
|
stmt.setInt(1, groupId);
|
||||||
|
stmt.setInt(2, tenantId);
|
||||||
|
|
||||||
|
int paramIdx = 3;
|
||||||
|
if (isDeviceNameProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceName + "%");
|
||||||
|
}
|
||||||
|
if (isSinceProvided) {
|
||||||
|
stmt.setLong(paramIdx++, since.getTime());
|
||||||
|
}
|
||||||
|
if (isDeviceTypeProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
if (isOwnershipProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
if (isOwnerProvided) {
|
||||||
|
stmt.setString(paramIdx++, owner);
|
||||||
|
} else if (isOwnerPatternProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownerPattern + "%");
|
||||||
|
}
|
||||||
|
if (isStatusProvided) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
|
||||||
|
rs = stmt.executeQuery();
|
||||||
|
devices = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
Device device = DeviceManagementDAOUtil.loadDevice(rs);
|
||||||
|
devices.add(device);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DeviceManagementDAOException("Error occurred while retrieving information of" +
|
||||||
|
" devices belonging to group : " + groupId, e);
|
||||||
|
} finally {
|
||||||
|
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
||||||
throws DeviceManagementDAOException {
|
throws DeviceManagementDAOException {
|
||||||
|
|||||||
@ -159,6 +159,137 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Device> searchDevicesInGroup(PaginationRequest request, int tenantId)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
Connection conn;
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<Device> devices = null;
|
||||||
|
|
||||||
|
int groupId = request.getGroupId();
|
||||||
|
String deviceType = request.getDeviceType();
|
||||||
|
boolean isDeviceTypeProvided = false;
|
||||||
|
String deviceName = request.getDeviceName();
|
||||||
|
boolean isDeviceNameProvided = false;
|
||||||
|
String owner = request.getOwner();
|
||||||
|
boolean isOwnerProvided = false;
|
||||||
|
String ownerPattern = request.getOwnerPattern();
|
||||||
|
boolean isOwnerPatternProvided = false;
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isOwnershipProvided = false;
|
||||||
|
String status = request.getStatus();
|
||||||
|
boolean isStatusProvided = false;
|
||||||
|
Date since = request.getSince();
|
||||||
|
boolean isSinceProvided = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = this.getConnection();
|
||||||
|
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
|
||||||
|
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
|
||||||
|
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
|
||||||
|
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
|
||||||
|
"FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " +
|
||||||
|
"FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" +
|
||||||
|
" d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?";
|
||||||
|
|
||||||
|
|
||||||
|
//Add the query for device-name
|
||||||
|
if (deviceName != null && !deviceName.isEmpty()) {
|
||||||
|
sql = sql + " AND d.NAME LIKE ?";
|
||||||
|
isDeviceNameProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + ") gd, DM_DEVICE_TYPE t";
|
||||||
|
|
||||||
|
if (since != null) {
|
||||||
|
sql = sql + ", DM_DEVICE_DETAIL dt";
|
||||||
|
isSinceProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
|
||||||
|
|
||||||
|
//Add query for last updated timestamp
|
||||||
|
if (isSinceProvided) {
|
||||||
|
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the query for device-type
|
||||||
|
if (deviceType != null && !deviceType.isEmpty()) {
|
||||||
|
sql = sql + " AND t.NAME = ?";
|
||||||
|
isDeviceTypeProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? ";
|
||||||
|
|
||||||
|
//Add the query for ownership
|
||||||
|
if (ownership != null && !ownership.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
isOwnershipProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for owner
|
||||||
|
if (owner != null && !owner.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER = ?";
|
||||||
|
isOwnerProvided = true;
|
||||||
|
} else if (ownerPattern != null && !ownerPattern.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER LIKE ?";
|
||||||
|
isOwnerPatternProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for status
|
||||||
|
if (status != null && !status.isEmpty()) {
|
||||||
|
sql = sql + " AND e.STATUS = ?";
|
||||||
|
isStatusProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
|
||||||
|
|
||||||
|
stmt = conn.prepareStatement(sql);
|
||||||
|
|
||||||
|
stmt.setInt(1, groupId);
|
||||||
|
stmt.setInt(2, tenantId);
|
||||||
|
|
||||||
|
int paramIdx = 3;
|
||||||
|
if (isDeviceNameProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceName + "%");
|
||||||
|
}
|
||||||
|
if (isSinceProvided) {
|
||||||
|
stmt.setLong(paramIdx++, since.getTime());
|
||||||
|
}
|
||||||
|
if (isDeviceTypeProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
if (isOwnershipProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
if (isOwnerProvided) {
|
||||||
|
stmt.setString(paramIdx++, owner);
|
||||||
|
} else if (isOwnerPatternProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownerPattern + "%");
|
||||||
|
}
|
||||||
|
if (isStatusProvided) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
|
||||||
|
rs = stmt.executeQuery();
|
||||||
|
devices = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
Device device = DeviceManagementDAOUtil.loadDevice(rs);
|
||||||
|
devices.add(device);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DeviceManagementDAOException("Error occurred while retrieving information of" +
|
||||||
|
" devices belonging to group : " + groupId, e);
|
||||||
|
} finally {
|
||||||
|
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
||||||
throws DeviceManagementDAOException {
|
throws DeviceManagementDAOException {
|
||||||
|
|||||||
@ -140,6 +140,136 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Device> searchDevicesInGroup(PaginationRequest request, int tenantId)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
Connection conn;
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<Device> devices = null;
|
||||||
|
|
||||||
|
int groupId = request.getGroupId();
|
||||||
|
String deviceType = request.getDeviceType();
|
||||||
|
boolean isDeviceTypeProvided = false;
|
||||||
|
String deviceName = request.getDeviceName();
|
||||||
|
boolean isDeviceNameProvided = false;
|
||||||
|
String owner = request.getOwner();
|
||||||
|
boolean isOwnerProvided = false;
|
||||||
|
String ownerPattern = request.getOwnerPattern();
|
||||||
|
boolean isOwnerPatternProvided = false;
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isOwnershipProvided = false;
|
||||||
|
String status = request.getStatus();
|
||||||
|
boolean isStatusProvided = false;
|
||||||
|
Date since = request.getSince();
|
||||||
|
boolean isSinceProvided = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = this.getConnection();
|
||||||
|
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
|
||||||
|
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
|
||||||
|
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
|
||||||
|
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
|
||||||
|
"FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " +
|
||||||
|
"FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" +
|
||||||
|
" d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?";
|
||||||
|
|
||||||
|
|
||||||
|
//Add the query for device-name
|
||||||
|
if (deviceName != null && !deviceName.isEmpty()) {
|
||||||
|
sql = sql + " AND d.NAME LIKE ?";
|
||||||
|
isDeviceNameProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + ") gd, DM_DEVICE_TYPE t";
|
||||||
|
|
||||||
|
if (since != null) {
|
||||||
|
sql = sql + ", DM_DEVICE_DETAIL dt";
|
||||||
|
isSinceProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
|
||||||
|
|
||||||
|
//Add query for last updated timestamp
|
||||||
|
if (isSinceProvided) {
|
||||||
|
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the query for device-type
|
||||||
|
if (deviceType != null && !deviceType.isEmpty()) {
|
||||||
|
sql = sql + " AND t.NAME = ?";
|
||||||
|
isDeviceTypeProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? ";
|
||||||
|
|
||||||
|
//Add the query for ownership
|
||||||
|
if (ownership != null && !ownership.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
isOwnershipProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for owner
|
||||||
|
if (owner != null && !owner.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER = ?";
|
||||||
|
isOwnerProvided = true;
|
||||||
|
} else if (ownerPattern != null && !ownerPattern.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER LIKE ?";
|
||||||
|
isOwnerPatternProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for status
|
||||||
|
if (status != null && !status.isEmpty()) {
|
||||||
|
sql = sql + " AND e.STATUS = ?";
|
||||||
|
isStatusProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " LIMIT ? OFFSET ?";
|
||||||
|
|
||||||
|
stmt = conn.prepareStatement(sql);
|
||||||
|
|
||||||
|
stmt.setInt(1, groupId);
|
||||||
|
stmt.setInt(2, tenantId);
|
||||||
|
|
||||||
|
int paramIdx = 3;
|
||||||
|
if (isDeviceNameProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceName + "%");
|
||||||
|
}
|
||||||
|
if (isSinceProvided) {
|
||||||
|
stmt.setLong(paramIdx++, since.getTime());
|
||||||
|
}
|
||||||
|
if (isDeviceTypeProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
if (isOwnershipProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
if (isOwnerProvided) {
|
||||||
|
stmt.setString(paramIdx++, owner);
|
||||||
|
} else if (isOwnerPatternProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownerPattern + "%");
|
||||||
|
}
|
||||||
|
if (isStatusProvided) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
|
||||||
|
rs = stmt.executeQuery();
|
||||||
|
devices = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
Device device = DeviceManagementDAOUtil.loadDevice(rs);
|
||||||
|
devices.add(device);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DeviceManagementDAOException("Error occurred while retrieving information of" +
|
||||||
|
" devices belonging to group : " + groupId, e);
|
||||||
|
} finally {
|
||||||
|
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
||||||
throws DeviceManagementDAOException {
|
throws DeviceManagementDAOException {
|
||||||
|
|||||||
@ -156,6 +156,136 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Device> searchDevicesInGroup(PaginationRequest request, int tenantId)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
Connection conn;
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<Device> devices = null;
|
||||||
|
|
||||||
|
int groupId = request.getGroupId();
|
||||||
|
String deviceType = request.getDeviceType();
|
||||||
|
boolean isDeviceTypeProvided = false;
|
||||||
|
String deviceName = request.getDeviceName();
|
||||||
|
boolean isDeviceNameProvided = false;
|
||||||
|
String owner = request.getOwner();
|
||||||
|
boolean isOwnerProvided = false;
|
||||||
|
String ownerPattern = request.getOwnerPattern();
|
||||||
|
boolean isOwnerPatternProvided = false;
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isOwnershipProvided = false;
|
||||||
|
String status = request.getStatus();
|
||||||
|
boolean isStatusProvided = false;
|
||||||
|
Date since = request.getSince();
|
||||||
|
boolean isSinceProvided = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = this.getConnection();
|
||||||
|
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
|
||||||
|
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
|
||||||
|
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
|
||||||
|
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
|
||||||
|
"FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " +
|
||||||
|
"FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" +
|
||||||
|
" d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?";
|
||||||
|
|
||||||
|
|
||||||
|
//Add the query for device-name
|
||||||
|
if (deviceName != null && !deviceName.isEmpty()) {
|
||||||
|
sql = sql + " AND d.NAME LIKE ?";
|
||||||
|
isDeviceNameProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + ") gd, DM_DEVICE_TYPE t";
|
||||||
|
|
||||||
|
if (since != null) {
|
||||||
|
sql = sql + ", DM_DEVICE_DETAIL dt";
|
||||||
|
isSinceProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
|
||||||
|
|
||||||
|
//Add query for last updated timestamp
|
||||||
|
if (isSinceProvided) {
|
||||||
|
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the query for device-type
|
||||||
|
if (deviceType != null && !deviceType.isEmpty()) {
|
||||||
|
sql = sql + " AND t.NAME = ?";
|
||||||
|
isDeviceTypeProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? ";
|
||||||
|
|
||||||
|
//Add the query for ownership
|
||||||
|
if (ownership != null && !ownership.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
isOwnershipProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for owner
|
||||||
|
if (owner != null && !owner.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER = ?";
|
||||||
|
isOwnerProvided = true;
|
||||||
|
} else if (ownerPattern != null && !ownerPattern.isEmpty()) {
|
||||||
|
sql = sql + " AND e.OWNER LIKE ?";
|
||||||
|
isOwnerPatternProvided = true;
|
||||||
|
}
|
||||||
|
//Add the query for status
|
||||||
|
if (status != null && !status.isEmpty()) {
|
||||||
|
sql = sql + " AND e.STATUS = ?";
|
||||||
|
isStatusProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
|
||||||
|
|
||||||
|
stmt = conn.prepareStatement(sql);
|
||||||
|
|
||||||
|
stmt.setInt(1, groupId);
|
||||||
|
stmt.setInt(2, tenantId);
|
||||||
|
|
||||||
|
int paramIdx = 3;
|
||||||
|
if (isDeviceNameProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceName + "%");
|
||||||
|
}
|
||||||
|
if (isSinceProvided) {
|
||||||
|
stmt.setLong(paramIdx++, since.getTime());
|
||||||
|
}
|
||||||
|
if (isDeviceTypeProvided) {
|
||||||
|
stmt.setString(paramIdx++, deviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
if (isOwnershipProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
if (isOwnerProvided) {
|
||||||
|
stmt.setString(paramIdx++, owner);
|
||||||
|
} else if (isOwnerPatternProvided) {
|
||||||
|
stmt.setString(paramIdx++, ownerPattern + "%");
|
||||||
|
}
|
||||||
|
if (isStatusProvided) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
|
||||||
|
rs = stmt.executeQuery();
|
||||||
|
devices = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
Device device = DeviceManagementDAOUtil.loadDevice(rs);
|
||||||
|
devices.add(device);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DeviceManagementDAOException("Error occurred while retrieving information of" +
|
||||||
|
" devices belonging to group : " + groupId, e);
|
||||||
|
} finally {
|
||||||
|
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
public List<Device> getDevicesOfUser(PaginationRequest request, int tenantId)
|
||||||
throws DeviceManagementDAOException {
|
throws DeviceManagementDAOException {
|
||||||
|
|||||||
@ -827,7 +827,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
DeviceManagementDAOFactory.openConnection();
|
DeviceManagementDAOFactory.openConnection();
|
||||||
allDevices = deviceDAO.getDevices(request, tenantId);
|
if(request.getGroupId()!=0){
|
||||||
|
allDevices = deviceDAO.searchDevicesInGroup(request, tenantId);
|
||||||
|
} else{
|
||||||
|
allDevices = deviceDAO.getDevices(request, tenantId);
|
||||||
|
}
|
||||||
count = deviceDAO.getDeviceCount(request, tenantId);
|
count = deviceDAO.getDeviceCount(request, tenantId);
|
||||||
} catch (DeviceManagementDAOException e) {
|
} catch (DeviceManagementDAOException e) {
|
||||||
String msg = "Error occurred while retrieving device list pertaining to the current tenant";
|
String msg = "Error occurred while retrieving device list pertaining to the current tenant";
|
||||||
@ -3090,12 +3094,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
|||||||
DeviceManagementDAOFactory.rollbackTransaction();
|
DeviceManagementDAOFactory.rollbackTransaction();
|
||||||
return false;
|
return false;
|
||||||
} catch (TransactionManagementException e) {
|
} catch (TransactionManagementException e) {
|
||||||
String msg = "Error occurred while initiating transaction";
|
String msg = "Error occurred while initiating the transaction.";
|
||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
} catch (DeviceManagementDAOException e) {
|
} catch (DeviceManagementDAOException e) {
|
||||||
String msg = "Error occurred either verifying existence of device ids or updating owner of the device.";
|
String msg = "Error occurred either verifying existence of device ids or updating owner of the device.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
} finally {
|
} finally {
|
||||||
DeviceManagementDAOFactory.closeConnection();
|
DeviceManagementDAOFactory.closeConnection();
|
||||||
@ -3118,7 +3122,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
|||||||
return owner;
|
return owner;
|
||||||
} catch (UserStoreException e) {
|
} catch (UserStoreException e) {
|
||||||
String msg = "Error occurred when checking whether owner is exist or not. Owner: " + owner;
|
String msg = "Error occurred when checking whether owner is exist or not. Owner: " + owner;
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.wso2.carbon.device.mgt.extensions.device.type.template;
|
package org.wso2.carbon.device.mgt.extensions.device.type.template;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
@ -58,10 +59,12 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceDAOD
|
|||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.feature.ConfigurationBasedFeatureManager;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.feature.ConfigurationBasedFeatureManager;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypePluginConstants;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypePluginConstants;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils;
|
||||||
import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager;
|
import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService;
|
||||||
import org.wso2.carbon.registry.api.RegistryException;
|
import org.wso2.carbon.registry.api.RegistryException;
|
||||||
import org.wso2.carbon.registry.api.Resource;
|
import org.wso2.carbon.registry.api.Resource;
|
||||||
import org.wso2.carbon.utils.CarbonUtils;
|
import org.wso2.carbon.utils.CarbonUtils;
|
||||||
@ -213,6 +216,35 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setDeviceTypePluginManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set device type plugin DAO manager of each device type in a HashMap which can then be used via individual
|
||||||
|
* device type plugin in working with its DAO components
|
||||||
|
*/
|
||||||
|
private void setDeviceTypePluginManager() {
|
||||||
|
if (StringUtils.isNotEmpty(deviceType)) {
|
||||||
|
if (deviceTypePluginDAOManager != null) {
|
||||||
|
DeviceTypePluginExtensionService deviceTypeManagerExtensionService =
|
||||||
|
new DeviceTypePluginExtensionServiceImpl();
|
||||||
|
try {
|
||||||
|
deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager);
|
||||||
|
} catch (DeviceTypePluginExtensionException e) {
|
||||||
|
String msg = "Error occurred while saving DeviceTypePluginDAOManager for device type: "
|
||||||
|
+ deviceType;
|
||||||
|
log.error(msg);
|
||||||
|
throw new DeviceTypeDeployerPayloadException(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Could not save DeviceTypePluginDAOManager for device type: " + deviceType +
|
||||||
|
" since DeviceTypePluginDAOManager is null.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = "Could not save DeviceTypePluginDAOManager since device type is null or empty.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new DeviceTypeDeployerPayloadException(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -307,15 +339,11 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
||||||
}
|
}
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
|
||||||
} catch (DeviceTypeMgtPluginException ex) {
|
|
||||||
String msg = "Error occurred while roll back the device enrol transaction :" +
|
|
||||||
device.toString();
|
|
||||||
log.warn(msg, ex);
|
|
||||||
}
|
|
||||||
String msg = "Error while enrolling the " + deviceType + " device : " + device.getDeviceIdentifier();
|
String msg = "Error while enrolling the " + deviceType + " device : " + device.getDeviceIdentifier();
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -334,16 +362,12 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(device);
|
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(device);
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
|
||||||
} catch (DeviceTypeMgtPluginException mobileDAOEx) {
|
|
||||||
String msg = "Error occurred while roll back the update device transaction :" +
|
|
||||||
device.toString();
|
|
||||||
log.warn(msg, mobileDAOEx);
|
|
||||||
}
|
|
||||||
String msg = "Error while updating the enrollment of the " + deviceType + " device : " +
|
String msg = "Error while updating the enrollment of the " + deviceType + " device : " +
|
||||||
device.getDeviceIdentifier();
|
device.getDeviceIdentifier();
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -378,13 +402,7 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
deviceId.getId();
|
deviceId.getId();
|
||||||
throw new DeviceManagementException(msg, e);
|
throw new DeviceManagementException(msg, e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
|
||||||
String msg = "Error occurred while closing the transaction to check device " +
|
|
||||||
deviceId.getId() + " is enrolled.";
|
|
||||||
log.warn(msg, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return isEnrolled;
|
return isEnrolled;
|
||||||
}
|
}
|
||||||
@ -419,12 +437,7 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
throw new DeviceManagementException(
|
throw new DeviceManagementException(
|
||||||
"Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e);
|
"Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
|
||||||
String msg = "Error occurred while closing the transaction to get device " + deviceId.getId();
|
|
||||||
log.warn(msg, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
@ -447,14 +460,11 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(updatedDevice);
|
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(updatedDevice);
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
|
||||||
} catch (DeviceTypeMgtPluginException transactionException) {
|
|
||||||
String msg = "Error occurred while rolling back transaction for device: " + deviceId.getId();
|
|
||||||
log.warn(msg, transactionException);
|
|
||||||
}
|
|
||||||
throw new DeviceManagementException(
|
throw new DeviceManagementException(
|
||||||
"Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e);
|
"Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e);
|
||||||
|
} finally {
|
||||||
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -544,15 +554,12 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(existingDevice);
|
status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(existingDevice);
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
|
||||||
} catch (DeviceTypeMgtPluginException e1) {
|
|
||||||
log.warn("Error occurred while roll back the update device info transaction : '" +
|
|
||||||
device.toString() + "'", e1);
|
|
||||||
}
|
|
||||||
throw new DeviceManagementException(
|
throw new DeviceManagementException(
|
||||||
"Error occurred while updating the " + deviceType + " device: '" +
|
"Error occurred while updating the " + deviceType + " device: '" +
|
||||||
device.getDeviceIdentifier() + "'", e);
|
device.getDeviceIdentifier() + "'", e);
|
||||||
|
} finally {
|
||||||
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -572,12 +579,7 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
throw new DeviceManagementException("Error occurred while fetching all " + deviceType + " devices", e);
|
throw new DeviceManagementException("Error occurred while fetching all " + deviceType + " devices", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
|
||||||
String msg = "Error occurred while closing the transaction to get all devices.";
|
|
||||||
log.warn(msg, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
@ -600,15 +602,12 @@ public class DeviceTypeManager implements DeviceManager {
|
|||||||
status = deviceTypePluginDAOManager.getDeviceDAO().deleteDevice(existingDevice);
|
status = deviceTypePluginDAOManager.getDeviceDAO().deleteDevice(existingDevice);
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction();
|
||||||
} catch (DeviceTypeMgtPluginException e) {
|
} catch (DeviceTypeMgtPluginException e) {
|
||||||
try {
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
||||||
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
|
|
||||||
} catch (DeviceTypeMgtPluginException e1) {
|
|
||||||
log.warn("Error occurred while roll back the delete device info transaction : '" +
|
|
||||||
device.toString() + "'", e1);
|
|
||||||
}
|
|
||||||
throw new DeviceManagementException(
|
throw new DeviceManagementException(
|
||||||
"Error occurred while deleting the " + deviceType + " device: '" +
|
"Error occurred while deleting the " + deviceType + " device: '" +
|
||||||
device.getDeviceIdentifier() + "'", e);
|
device.getDeviceIdentifier() + "'", e);
|
||||||
|
} finally {
|
||||||
|
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (Pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.extensions.device.type.template;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DeviceTypePluginExtensionServiceImpl implements DeviceTypePluginExtensionService {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(DeviceTypePluginExtensionServiceImpl.class);
|
||||||
|
|
||||||
|
private static volatile Map<String, DeviceTypePluginDAOManager> pluginDAOManagers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager)
|
||||||
|
throws DeviceTypePluginExtensionException {
|
||||||
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||||
|
if (pluginDAOManager == null) {
|
||||||
|
String msg = "Cannot save DeviceTypePluginDAOManager against tenant id " + tenantId
|
||||||
|
+ " and device type: " + deviceType + " since DeviceTypePluginDAOManager is null";
|
||||||
|
log.error(msg);
|
||||||
|
throw new DeviceTypePluginExtensionException(msg);
|
||||||
|
}
|
||||||
|
if (!pluginDAOManagers.containsKey(tenantId + deviceType)) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Saving DeviceTypePluginDAOManager against tenant id " + tenantId +
|
||||||
|
" and device type: " + deviceType);
|
||||||
|
}
|
||||||
|
pluginDAOManagers.put(tenantId + deviceType, pluginDAOManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) throws DeviceTypePluginExtensionException {
|
||||||
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||||
|
if (pluginDAOManagers.containsKey(tenantId + deviceType)) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Retrieving DeviceTypePluginDAOManager against tenant id " + tenantId +
|
||||||
|
" and device type: " + deviceType);
|
||||||
|
}
|
||||||
|
return pluginDAOManagers.get(tenantId + deviceType);
|
||||||
|
} else {
|
||||||
|
String msg = "DeviceTypePluginDAOManager could not be found against tenant id " + tenantId +
|
||||||
|
" and device type: " + deviceType;
|
||||||
|
log.error(msg);
|
||||||
|
throw new DeviceTypePluginExtensionException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (Pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.extensions.device.type.template.dao;
|
package org.wso2.carbon.device.mgt.extensions.device.type.template.dao;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.exceptions.IllegalTransactionStateException;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException;
|
||||||
|
|
||||||
@ -31,7 +49,26 @@ public class DeviceTypeDAOHandler {
|
|||||||
Context ctx = new InitialContext();
|
Context ctx = new InitialContext();
|
||||||
dataSource = (DataSource) ctx.lookup(datasourceName);
|
dataSource = (DataSource) ctx.lookup(datasourceName);
|
||||||
} catch (NamingException e) {
|
} catch (NamingException e) {
|
||||||
throw new DeviceTypeDeployerPayloadException("Error while looking up the data source: " + datasourceName, e);
|
String msg = "Error while looking up the data source: " + datasourceName;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceTypeDeployerPayloadException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openConnection() throws DeviceTypeMgtPluginException {
|
||||||
|
try {
|
||||||
|
Connection conn = currentConnection.get();
|
||||||
|
if (conn != null) {
|
||||||
|
String msg = "Database connection has already been obtained.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new IllegalTransactionStateException(msg);
|
||||||
|
}
|
||||||
|
conn = dataSource.getConnection();
|
||||||
|
currentConnection.set(conn);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Failed to get a database connection.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceTypeMgtPluginException(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +78,9 @@ public class DeviceTypeDAOHandler {
|
|||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
currentConnection.set(conn);
|
currentConnection.set(conn);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceTypeMgtPluginException("Error occurred while retrieving datasource connection", e);
|
String msg = "Error occurred while retrieving datasource connection";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceTypeMgtPluginException(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,58 +89,58 @@ public class DeviceTypeDAOHandler {
|
|||||||
try {
|
try {
|
||||||
currentConnection.set(dataSource.getConnection());
|
currentConnection.set(dataSource.getConnection());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceTypeMgtPluginException("Error occurred while retrieving data source connection", e);
|
String msg = "Error occurred while retrieving data source connection";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceTypeMgtPluginException(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return currentConnection.get();
|
return currentConnection.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void commitTransaction() throws DeviceTypeMgtPluginException {
|
public void commitTransaction() {
|
||||||
|
Connection conn = currentConnection.get();
|
||||||
|
if (conn == null) {
|
||||||
|
String msg = "No connection is associated with the current transaction. This might have ideally been " +
|
||||||
|
"caused by not properly initiating the transaction via " +
|
||||||
|
"'beginTransaction'/'openConnection' methods";
|
||||||
|
log.error(msg);
|
||||||
|
throw new IllegalStateException(msg);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Connection conn = currentConnection.get();
|
conn.commit();
|
||||||
if (conn != null) {
|
|
||||||
conn.commit();
|
|
||||||
} else {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Datasource connection associated with the current thread is null, hence commit "
|
|
||||||
+ "has not been attempted");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceTypeMgtPluginException("Error occurred while committing the transaction", e);
|
String msg = "Error occurred while committing the transaction.";
|
||||||
} finally {
|
log.error(msg, e);
|
||||||
closeConnection();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeConnection() throws DeviceTypeMgtPluginException {
|
public void closeConnection() {
|
||||||
|
|
||||||
Connection con = currentConnection.get();
|
Connection con = currentConnection.get();
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
try {
|
try {
|
||||||
con.close();
|
con.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Error occurred while close the connection");
|
String msg = "Error occurred while close the connection";
|
||||||
|
log.error(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentConnection.remove();
|
currentConnection.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rollbackTransaction() throws DeviceTypeMgtPluginException {
|
public void rollbackTransaction() {
|
||||||
|
Connection conn = currentConnection.get();
|
||||||
|
if (conn == null) {
|
||||||
|
String msg = "No connection is associated with the current transaction. This might have ideally been " +
|
||||||
|
"caused by not properly initiating the transaction via " +
|
||||||
|
"'beginTransaction'/'openConnection' methods";
|
||||||
|
log.error(msg);
|
||||||
|
throw new IllegalStateException(msg);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Connection conn = currentConnection.get();
|
conn.rollback();
|
||||||
if (conn != null) {
|
|
||||||
conn.rollback();
|
|
||||||
} else {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Datasource connection associated with the current thread is null, hence rollback "
|
|
||||||
+ "has not been attempted");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DeviceTypeMgtPluginException("Error occurred while rollback the transaction", e);
|
String msg = "Error occurred while roll-backing the transaction.";
|
||||||
} finally {
|
log.error(msg, e);
|
||||||
closeConnection();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.extensions.device.type.template.exception;
|
||||||
|
|
||||||
|
public class DeviceTypePluginExtensionException extends Exception {
|
||||||
|
|
||||||
|
public DeviceTypePluginExtensionException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceTypePluginExtensionException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,23 @@
|
|||||||
* KIND, either express or implied. See the License for the
|
* KIND, either express or implied. See the License for the
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Entgra (Pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.extensions.internal;
|
package org.wso2.carbon.device.mgt.extensions.internal;
|
||||||
@ -23,6 +40,8 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.osgi.service.component.ComponentContext;
|
import org.osgi.service.component.ComponentContext;
|
||||||
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
|
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
|
||||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeGeneratorServiceImpl;
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeGeneratorServiceImpl;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypePluginExtensionServiceImpl;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService;
|
||||||
import org.wso2.carbon.ndatasource.core.DataSourceService;
|
import org.wso2.carbon.ndatasource.core.DataSourceService;
|
||||||
import org.wso2.carbon.registry.core.service.RegistryService;
|
import org.wso2.carbon.registry.core.service.RegistryService;
|
||||||
|
|
||||||
@ -50,6 +69,8 @@ public class DeviceTypeExtensionServiceComponent {
|
|||||||
}
|
}
|
||||||
ctx.getBundleContext()
|
ctx.getBundleContext()
|
||||||
.registerService(DeviceTypeGeneratorService.class, new DeviceTypeGeneratorServiceImpl(), null);
|
.registerService(DeviceTypeGeneratorService.class, new DeviceTypeGeneratorServiceImpl(), null);
|
||||||
|
ctx.getBundleContext().registerService(DeviceTypePluginExtensionService.class,
|
||||||
|
new DeviceTypePluginExtensionServiceImpl(), null);
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Device Type Extension Service Component successfully activated");
|
log.debug("Device Type Extension Service Component successfully activated");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (Pvt) Ltd. (https://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. 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.mgt.extensions.spi;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager;
|
||||||
|
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents the device type plugin extension service which can be used by any device type plugin implementation
|
||||||
|
* intended to use the same plugin DAO instances to be used with its plugin level DAO components
|
||||||
|
*/
|
||||||
|
public interface DeviceTypePluginExtensionService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save device type specific DeviceTypePluginDAOManager in a HashMap againast tenant ID and device type
|
||||||
|
* @param deviceType - Type of the device (i.e; android, ios, windows)
|
||||||
|
* @param pluginDAOManager - Device type plugin DAO manager instance to be saved against device type
|
||||||
|
* @throws DeviceTypePluginExtensionException when pluginDAOManager is null
|
||||||
|
*/
|
||||||
|
void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager)
|
||||||
|
throws DeviceTypePluginExtensionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the DeviceTypePluginDAOManager instance against tenant ID and given device type
|
||||||
|
* @param deviceType - Type of the device (i.e; android, ios, windows)
|
||||||
|
* @return an Instance of {@link DeviceTypePluginDAOManager}
|
||||||
|
* @throws DeviceTypePluginExtensionException when pluginDAOManager cannot be found
|
||||||
|
*/
|
||||||
|
DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) throws DeviceTypePluginExtensionException;
|
||||||
|
}
|
||||||
@ -327,15 +327,6 @@ deviceModule = function () {
|
|||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
publicMethods.getDeviceTypesConfig = function () {
|
|
||||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types/config";
|
|
||||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
|
||||||
if (response.status == "success") {
|
|
||||||
response.content = parse(response.content);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Updated
|
@Updated
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -506,7 +506,7 @@ function loadDevices(searchType, searchParam) {
|
|||||||
|
|
||||||
$('#device-grid').datatables_extended_serverside_paging(
|
$('#device-grid').datatables_extended_serverside_paging(
|
||||||
null,
|
null,
|
||||||
serviceURL,
|
"/api/device-mgt/v1.0/devices/",
|
||||||
dataFilter,
|
dataFilter,
|
||||||
columns,
|
columns,
|
||||||
fnCreatedRow,
|
fnCreatedRow,
|
||||||
@ -525,7 +525,8 @@ function loadDevices(searchType, searchParam) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
"placeholder": "Top-Device-Name-Search",
|
"placeholder": "Top-Device-Name-Search",
|
||||||
"searchKey": "namePattern"
|
"searchKey": "namePattern",
|
||||||
|
"groupId": groupId
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ function onRequest(context) {
|
|||||||
var deviceType = request.getParameter("type");
|
var deviceType = request.getParameter("type");
|
||||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||||
var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
||||||
+ "/device-types/config/" + deviceType;
|
+ "/device-types/" + deviceType;
|
||||||
displayData.name = deviceType;
|
displayData.name = deviceType;
|
||||||
serviceInvokers.XMLHttp.get(
|
serviceInvokers.XMLHttp.get(
|
||||||
restAPIEndpoint,
|
restAPIEndpoint,
|
||||||
|
|||||||
@ -210,7 +210,7 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
deviceType.deviceTypeMetaDefinition.features = features;
|
deviceType.deviceTypeMetaDefinition.features = features;
|
||||||
|
|
||||||
var addRoleAPI = apiBasePath + "/admin/device-types";
|
var addRoleAPI = apiBasePath + "/admin/device-types/" + deviceType.name;
|
||||||
|
|
||||||
invokerUtil.put(
|
invokerUtil.put(
|
||||||
addRoleAPI,
|
addRoleAPI,
|
||||||
|
|||||||
@ -76,6 +76,9 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter
|
|||||||
searchParams[params.columns[i].data] = encodeURIComponent(params.columns[i].search.value);
|
searchParams[params.columns[i].data] = encodeURIComponent(params.columns[i].search.value);
|
||||||
}
|
}
|
||||||
if (options) {
|
if (options) {
|
||||||
|
if (options.groupId){
|
||||||
|
searchParams["groupId"] = options.groupId;
|
||||||
|
}
|
||||||
searchParams[options.searchKey] = encodeURIComponent(params.search.value);
|
searchParams[options.searchKey] = encodeURIComponent(params.search.value);
|
||||||
}
|
}
|
||||||
params.filter = JSON.stringify(searchParams);
|
params.filter = JSON.stringify(searchParams);
|
||||||
|
|||||||
@ -42,7 +42,7 @@ function onRequest(context) {
|
|||||||
var displayData = {};
|
var displayData = {};
|
||||||
|
|
||||||
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
||||||
+ "/device-types/config/" + deviceType;
|
+ "/device-types/" + deviceType;
|
||||||
displayData.deviceType = deviceType;
|
displayData.deviceType = deviceType;
|
||||||
displayData.tenantDomain = tenantDomain;
|
displayData.tenantDomain = tenantDomain;
|
||||||
serviceInvokers.XMLHttp.get(
|
serviceInvokers.XMLHttp.get(
|
||||||
|
|||||||
@ -32,7 +32,7 @@ function onRequest(context) {
|
|||||||
return opts.inverse(this);
|
return opts.inverse(this);
|
||||||
});
|
});
|
||||||
var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
||||||
+ "/device-types/config/" + deviceType;
|
+ "/device-types/" + deviceType;
|
||||||
displayData.deviceType = deviceType;
|
displayData.deviceType = deviceType;
|
||||||
displayData.tenantDomain = tenantDomain;
|
displayData.tenantDomain = tenantDomain;
|
||||||
serviceInvokers.XMLHttp.get(
|
serviceInvokers.XMLHttp.get(
|
||||||
|
|||||||
@ -41,6 +41,7 @@
|
|||||||
<module>org.wso2.carbon.device.mgt.analytics.data.publisher</module>
|
<module>org.wso2.carbon.device.mgt.analytics.data.publisher</module>
|
||||||
<module>org.wso2.carbon.device.mgt.url.printer</module>
|
<module>org.wso2.carbon.device.mgt.url.printer</module>
|
||||||
<module>org.wso2.carbon.device.mgt.analytics.wsproxy</module>
|
<module>org.wso2.carbon.device.mgt.analytics.wsproxy</module>
|
||||||
|
<module>io.entgra.device.mgt.ui</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -27,6 +27,10 @@
|
|||||||
<param-name>doAuthentication</param-name>
|
<param-name>doAuthentication</param-name>
|
||||||
<param-value>false</param-value>
|
<param-value>false</param-value>
|
||||||
</context-param>
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>basicAuth</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
<!--publish to apim-->
|
<!--publish to apim-->
|
||||||
<context-param>
|
<context-param>
|
||||||
|
|||||||
@ -115,7 +115,35 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
|
<artifactId>io.entgra.device.mgt.ui</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
<overWrite>true</overWrite>
|
||||||
|
<outputDirectory>
|
||||||
|
${project.build.directory}/maven-shared-archive-resources/webapps
|
||||||
|
</outputDirectory>
|
||||||
|
<destFileName>entgra.war</destFileName>
|
||||||
|
<includes>**/*</includes>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -3,4 +3,5 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../depl
|
|||||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggeryapps/devicemgt-cdmf,target:${installFolder}/../../deployment/server/jaggeryapps/devicemgt-cdmf,overwrite:true);\
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggeryapps/devicemgt-cdmf,target:${installFolder}/../../deployment/server/jaggeryapps/devicemgt-cdmf,overwrite:true);\
|
||||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/uuf-template-app);\
|
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/uuf-template-app);\
|
||||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggeryapps/uuf-template-app,target:${installFolder}/../../deployment/server/jaggeryapps/uuf-template-app,overwrite:true);\
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggeryapps/uuf-template-app,target:${installFolder}/../../deployment/server/jaggeryapps/uuf-template-app,overwrite:true);\
|
||||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggery-modules/utils/,target:${installFolder}/../../modules/utils,overwrite:true);\
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/jaggery-modules/utils/,target:${installFolder}/../../modules/utils,overwrite:true);\
|
||||||
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.ui_${feature.version}/webapps/entgra.war,target:${installFolder}/../../deployment/server/webapps/entgra.war,overwrite:true);\
|
||||||
|
|||||||
@ -2,3 +2,4 @@ instructions.configure = \
|
|||||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
|
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
|
||||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/publisher-ui-request-handler.war,overwrite:true);\
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/publisher-ui-request-handler.war,overwrite:true);\
|
||||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/store-ui-request-handler.war,overwrite:true);\
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/store-ui-request-handler.war,overwrite:true);\
|
||||||
|
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/entgra-ui-request-handler.war,overwrite:true);\
|
||||||
|
|||||||