diff --git a/.gitignore b/.gitignore index d5482f52de..e00a660c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -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/package-lock.json 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/ diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index 8bad3de1a8..06d344a514 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -55,7 +55,7 @@ public class AuthenticationHandler extends AbstractHandler { private static final String X_JWT_ASSERTION = "X-JWT-Assertion"; private static final String JWTTOKEN = "JWTToken"; 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 IOTServerConfiguration iotServerConfiguration; @@ -95,7 +95,7 @@ public class AuthenticationHandler extends AbstractHandler { log.debug("Verify Cert:\n" + mdmSignature); } URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + "ios"); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(mdmSignature); @@ -127,7 +127,7 @@ public class AuthenticationHandler extends AbstractHandler { String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(subjectDN); certificate.setTenantId(tenantId); @@ -157,7 +157,7 @@ public class AuthenticationHandler extends AbstractHandler { } String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(encodedPem); @@ -184,9 +184,6 @@ public class AuthenticationHandler extends AbstractHandler { } catch (URISyntaxException e) { log.error("Error while processing certificate.", e); return false; - } catch (APIMCertificateMGTException e) { - log.error("Error while processing certificate.", e); - return false; } catch (CertificateException e) { log.error("Certificate issue occurred when generating converting PEM to x509Certificate", e); return false; @@ -212,9 +209,9 @@ public class AuthenticationHandler extends AbstractHandler { return null; } - private Map setHeaders(RESTInvoker restInvoker) throws APIMCertificateMGTException { + private Map setHeaders() { Map map = new HashMap<>(); - String accessToken = Utils.getAccessToken(iotServerConfiguration, restInvoker); + String accessToken = Utils.getBase64EncodedToken(iotServerConfiguration); map.put(AUTHORIZATION, BEARER + accessToken); map.put(CONTENT_TYPE, "application/json"); return map; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java index f149868e76..5be2c18705 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java @@ -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. * @return Access token will be returned. - * @throws APIMCertificateMGTException */ - public static String getAccessToken(IOTServerConfiguration iotServerConfiguration, RESTInvoker restInvoker) - throws APIMCertificateMGTException { - try { - 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 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); - } + public static String getBase64EncodedToken(IOTServerConfiguration iotServerConfiguration) { + return Base64.encode((iotServerConfiguration.getUsername() + ":" + iotServerConfiguration.getPassword()). + getBytes()); } /** diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java index b3b8cdac78..23e6b251fc 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java @@ -92,8 +92,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert"); setMockClient(); - this.mockClient.setResponse(getDCRResponse()); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice")); @@ -107,7 +105,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice")); @@ -121,7 +118,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -141,7 +137,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -156,7 +151,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getInvalidResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -185,7 +179,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(null); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/app/Test Android App b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/app/Test Android App deleted file mode 100644 index 10dfe26209..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/app/Test Android App and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/banner/My First Banner b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/banner/My First Banner deleted file mode 100644 index e8c57421c2..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/banner/My First Banner and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/icon/My First Icon b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/icon/My First Icon deleted file mode 100644 index df25ec4e45..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/icon/My First Icon and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot1/shot1 b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot1/shot1 deleted file mode 100644 index df25ec4e45..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot1/shot1 and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot2/shot3 b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot2/shot3 deleted file mode 100644 index df25ec4e45..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot2/shot3 and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot3/shot2 b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot3/shot2 deleted file mode 100644 index df25ec4e45..0000000000 Binary files a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/repository/resources/apps/d46b34e7ba08f0d45056e77b9c70f528/screenshot3/shot2 and /dev/null differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index dfde043ef5..1b6496db2c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -172,6 +172,10 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; } + if (filter.getLimit() == -1) { + sql = sql.replace("LIMIT ? OFFSET ?", ""); + } + String sortingOrder = "ASC"; if (!StringUtils.isEmpty(filter.getSortBy() )) { sortingOrder = filter.getSortBy(); @@ -182,12 +186,14 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql); ){ - if (filter.getLimit() == 0) { - stmt.setInt(paramIndex++, 100); - } else { - stmt.setInt(paramIndex++, filter.getLimit()); + if (filter.getLimit() != -1) { + if (filter.getLimit() == 0) { + stmt.setInt(paramIndex++, 100); + } else { + stmt.setInt(paramIndex++, filter.getLimit()); + } + stmt.setInt(paramIndex++, filter.getOffset()); } - stmt.setInt(paramIndex++, filter.getOffset()); stmt.setInt(paramIndex++, tenantId); if (filter.getAppType() != null && !filter.getAppType().isEmpty()) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index cc6938c934..5eb638a61d 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -147,9 +147,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc log.error(msg); throw new ApplicationManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "Error occurred when obtaining database connection for updating the device subscriptions of " - + "application. Updated by: " + updateBy + " and updating action triggered from " - + actionTriggeredFrom; + String msg = "Error occurred while executing SQL to update the device subscriptions of application. " + + "Updated by: " + updateBy + " and updating action triggered from " + actionTriggeredFrom; log.error(msg); throw new ApplicationManagementDAOException(msg, e); } @@ -356,7 +355,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc log.error(msg); throw new ApplicationManagementDAOException(msg, 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); throw new ApplicationManagementDAOException(msg, e); } @@ -618,12 +617,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc stmt.executeBatch(); } } catch (DBConnectionException e) { - String msg = "Error occurred while obtaining the DB connection to update the user subscriptions of " - + "application."; + String msg = "Error occurred while obtaining the DB connection to update the user/role/group subscriptions " + + "of application."; log.error(msg); throw new ApplicationManagementDAOException(msg, 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."; log.error(msg); throw new ApplicationManagementDAOException(msg, e); @@ -691,8 +690,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc log.error(msg); throw new ApplicationManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "Error occurred when obtaining database connection for updating the subscription status of the " - + "device subscription."; + String msg = "Error occurred when processing SQL to update the subscription status of the device " + + "subscription."; log.error(msg); throw new ApplicationManagementDAOException(msg, e); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml index 203e987a3c..ba772ea2e1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml @@ -37,7 +37,7 @@ org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl - repository/resources/apps/ + /tmp/apps/ 6 diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/admin/ReviewManagementPublisherAdminAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/admin/ReviewManagementPublisherAdminAPI.java index 1b649af7c5..f751d98a22 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/admin/ReviewManagementPublisherAdminAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/admin/ReviewManagementPublisherAdminAPI.java @@ -30,14 +30,8 @@ import org.wso2.carbon.apimgt.annotations.api.Scope; 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.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.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -69,13 +63,13 @@ tags = { scopes = { @Scope( name = "Update a Review", - description = "Update a Review of applications.", + description = "Update a Review of application.", key = "perm:admin:app:review:update", permissions = {"/app-mgt/publisher/admin/review/update"} ), @Scope( name = "Get Review Details", - description = "Get review details of applications.", + description = "Get review details of application.", key = "perm:admin:app:review:view", permissions = {"/app-mgt/publisher/admin/review/view"} ) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java index 60781d3881..2a163a5fb0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java @@ -49,11 +49,11 @@ import javax.ws.rs.core.Response; @SwaggerDefinition( info = @Info( version = "1.0.0", - title = "ApplicationDTO Storage Management Service", + title = "Application Storage Management Service", extensions = { @Extension(properties = { @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 = { @Scope( - name = "Get ApplicationDTO Details", + name = "Get Application Details", description = "Get application details", key = "perm:app:store:view", permissions = {"/app-mgt/store/application/view"} @@ -73,8 +73,8 @@ import javax.ws.rs.core.Response; } ) @Path("/applications") -@Api(value = "ApplicationDTO Management", description = "This API carries all app store management related operations " + - "such as get all the applications etc.") +@Api(value = "Application Management", description = "This API carries all app store management related operations such" + + " as get all the applications etc.") @Produces(MediaType.APPLICATION_JSON) public interface ApplicationManagementAPI { @@ -89,7 +89,7 @@ public interface ApplicationManagementAPI { httpMethod = "GET", value = "get all applications", notes = "This will get all applications", - tags = "ApplicationDTO Management", + tags = "Application Management", extensions = { @Extension(properties = { @ExtensionProperty(name = SCOPE, value = "perm:app:store:view") @@ -129,7 +129,7 @@ public interface ApplicationManagementAPI { httpMethod = "GET", value = "get the application of requesting application type", notes = "This will get the application identified by the application type and name, if exists", - tags = "ApplicationDTO Management", + tags = "Application Management", extensions = { @Extension(properties = { @ExtensionProperty(name = SCOPE, value = "perm:app:store:view") @@ -144,7 +144,7 @@ public interface ApplicationManagementAPI { response = ApplicationDTO.class), @ApiResponse( code = 404, - message = "ApplicationDTO not found"), + message = "Application not found"), @ApiResponse( code = 500, message = "Internal Server Error. \n Error occurred while getting relevant application.", diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml index 6fd45f33b3..9722ee843e 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -37,6 +37,10 @@ doAuthentication true + + basicAuth + true + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index 71ce11b6b1..b25837154f 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -324,9 +324,14 @@ public class CertificateGenerator { KeyStoreReader keyStoreReader = new KeyStoreReader(); if (distinguishedName != null && !distinguishedName.isEmpty()) { if (distinguishedName.contains("/CN=")) { - String[] dnSplits = distinguishedName.split("/CN="); - String commonNameExtracted = dnSplits[dnSplits.length - 1]; - lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); + String[] dnSplits = distinguishedName.split("/"); + for (String dnPart : dnSplits) { + if (dnPart.contains("CN=")) { + String commonNameExtracted = dnPart.replace("CN=", ""); + lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); + break; + } + } } else { LdapName ldapName; try { @@ -711,4 +716,4 @@ public class CertificateGenerator { return generateCertificateFromCSR(privateKeyCA, certificationRequest, certCA.getIssuerX500Principal().getName()); } -} \ No newline at end of file +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/pom.xml b/components/device-mgt/io.entgra.device.mgt.ui/pom.xml new file mode 100644 index 0000000000..c57e30dc4d --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/pom.xml @@ -0,0 +1,124 @@ + + + + 4.0.0 + + + org.wso2.carbon.devicemgt + application-mgt + 3.2.9-SNAPSHOT + + io.entgra.device.mgt.ui + 3.2.9-SNAPSHOT + war + WSO2 Carbon - Device Management UI Component + http://wso2.org + This Component contains Device Management UI + + + + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + entgra + + + ${npm.output.directory}/dist + + + ${npm.output.directory}/public + public + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend.mave.version} + + ${npm.working.dir} + + ${npm.install.dir} + + + + install node and npm + + install-node-and-npm + + generate-resources + + ${node.version} + ${npm.version} + + + + npm install + + npm + + + + install + + + + prod + + npm + + + run-script ${npm.build.command} + + generate-resources + + + + + + + + platform-windows + + + windows + + + + + npm.cmd + + + + + false + npm + build_prod + ./react-app + ./react-app/tmp + UTF-8 + react-app + + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/babel.config.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/babel.config.js new file mode 100644 index 0000000000..9da1223d92 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/babel.config.js @@ -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 + }; +}; \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json new file mode 100644 index 0000000000..33bc553aa9 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json @@ -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" + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json new file mode 100644 index 0000000000..43411cf4f8 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json @@ -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" + } + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/icons.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/icons.json new file mode 100644 index 0000000000..0bd52ef51e --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/icons.json @@ -0,0 +1,306 @@ +{ + "airplay": "", + "api": "", + "apn": "", + "vpn": "", + "apple": "", + "windows": "", + "android": "", + "wifi": "", + "application": "", + "configarations": "", + "battery": "", + "notification": "", + "blank-document": "", + "bookmark": "", + "bpel": "", + "bpmn": "", + "compare": "", + "bug": "", + "calendar": "", + "camera": "", + "contract": "", + "add": "", + "minus": "", + "check": "", + "cancel": "", + "checklist": "", + "circle": "", + "clear": "", + "expand": "", + "clock": "", + "cloud": "", + "circle-outline": "", + "contact": "", + "copy": "", + "dashboard": "", + "database": "", + "delete": "", + "deploy": "", + "display": "", + "dial-up": "", + "document": "", + "ellipsis": "", + "dss": "", + "ebook": "", + "edit": "", + "endpoint": "", + "folder": "", + "faq": "", + "error": "", + "export": "", + "factory-reset": "", + "file-browse": "", + "filter": "", + "message": "", + "forum": "", + "gadget": "", + "grid": "", + "hdd": "", + "home": "", + "hour-glass": "", + "import": "", + "incoming-call": "", + "info": "", + "invitation": "", + "jaggery": "", + "java": "", + "javaee": "", + "javascript": "", + "java-spring": "", + "jaxrs": "", + "jquery": "", + "key": "", + "laptop": "", + "ldap": "", + "lifecycle": "", + "sort-up": "", + "list": "", + "list-sort": "", + "lock": "", + "mail": "", + "map-location": "", + "menu": "", + "mobile": "", + "computer": "", + "ms-document": "", + "mute": "", + "nodejs": "", + "success": "", + "paste": "", + "pdf": "", + "pie-chart": "", + "chat": "", + "publish": "", + "redo": "", + "register": "", + "download": "", + "resource": "", + "rest-api": "", + "rest-service": "", + "sort-down": "", + "rules": "", + "save": "", + "scep": "", + "schema": "", + "search": "", + "security": "", + "send": "", + "sequence": "", + "server": "", + "service": "", + "service-provider": "", + "settings": "", + "share": "", + "sign-in": "", + "soap": "", + "sort": "", + "star": "", + "statistics": "", + "store": "", + "subscribe": "", + "fan": "", + "swagger": "", + "tag": "", + "task": "", + "text": "", + "policy": "", + "security-policy": "", + "throttling-policy": "", + "light": "", + "tiles": "", + "uncheck": "", + "undo": "", + "up": "", + "down": "", + "left": "", + "right": "", + "up-arrow": "", + "down-arrow": "", + "left-arrow": "", + "right-arrow": "", + "upload": "", + "uri": "", + "usb-drive": "", + "user": "", + "bar-chart": "", + "view": "", + "refresh": "", + "warning": "", + "ringing": "", + "block": "", + "web-app": "", + "globe": "", + "web-clip": "", + "proxy": "", + "web-service": "", + "website": "", + "xml": "", + "html": "\t\t\t\t", + "war": "", + "xacml": "", + "wsdl": "", + "wadl": "", + "xq": "", + "xsd": "", + "xslt": "", + "zoom-in": "", + "zoom-out": "", + "wso2-logo": "", + "wso2": "", + "hardware": "", + "raspberry": "", + "arduino": "", + "organization": "", + "public": "", + "unmute": "", + "group": "", + "question": "", + "square": "", + "square-outline": "", + "sync": "", + "loader": "", + "ungroup": "", + "enterprise": "", + "grip": "", + "sign-out": "", + "retweet": "", + "loader2": "", + "loader3": "", + "loader4": "", + "loader5": "", + "alert": "", + "layout": "", + "pages": "", + "build": "", + "alarm": "", + "heart": "", + "table": "", + "carbon": "", + "depend": "", + "jaxws": "", + "own": "", + "php": "", + "use": "", + "deprecate": "", + "prototype": "", + "retire": "", + "micro-services": "", + "activate": "", + "disabled": "", + "hide": "", + "facebook": "", + "github": "", + "google": "", + "google-docs": "", + "google-sheets": "", + "google-slides": "", + "google-plus": "", + "google-drive": "", + "instagram": "", + "linkedin": "", + "pinterest": "", + "skype": "", + "twitter": "", + "youtube": "", + "slash": "", + "analytics-extensions": "", + "esb-connector": "", + "extensions": "", + "is-connector": "", + "annotation": "", + "dgm-fork": "", + "dgm-header": "", + "dgm-if-else": "", + "dgm-lifeline": "", + "dgm-logger": "\t", + "dgm-try-catch": "", + "invoke": "", + "variable": "", + "worker": "", + "code": "", + "cut": "", + "type-converter": "", + "dgm-connector": "", + "dgm-constant-definition": "", + "dgm-resource": "", + "dgm-service": "", + "dgm-type-convertor": "", + "dgm-type": "", + "format": "", + "function": "", + "rename": "", + "package": "", + "action-invoke": "", + "assign": "", + "connector": "", + "constant": "", + "logical": "", + "try-catch": "", + "devices": "", + "http": "", + "main-function": "", + "dgm-while": "", + "run": "", + "action": "", + "image": "", + "folder-open": "", + "docker": "", + "polygon": "", + "code-view": "", + "design-view": "", + "comment": "", + "dgm-action": "", + "dgm-action-invoke": "", + "function-invoke": "", + "reply": "", + "return": "", + "struct": "", + "dgm-import": "", + "start": "", + "stepin": "", + "stepout": "", + "stepover": "", + "stop": "", + "console": "", + "resume": "", + "iterate": "", + "fork-join": "", + "break": "", + "throw": "", + "worker-invoke": "", + "worker-reply": "", + "shortcut": "", + "theme": "", + "pending": "", + "ballerina": "", + "ballerina-service": "", + "abort": "", + "transaction": "", + "android-logcat": "", + "android-sense": "", + "geo-fence-inbound": "", + "geo-fence-outbound": "", + "shell": "", + "speed-alert": "" +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/manifest.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/manifest.json new file mode 100644 index 0000000000..60f712111e --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/manifest.json @@ -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" +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.css new file mode 100644 index 0000000000..abb8cc1eb0 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.css @@ -0,0 +1,1506 @@ +/*! +~ Copyright (c) 2017 WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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:"font-wso2"; + src:local("font-wso2"), url("../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223"); + src:local("font-wso2"), + url("../fonts/font-wso2.eot?#iefix") format("embedded-opentype"), + url("../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223") format("woff2"), + url("../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223") format("woff"), + url("../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223") format("truetype"), + url("../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2") format("svg"); + font-weight:normal; + font-style:normal; +} + +.fw, [class^="fw-"], [class*=" fw-"] { + font: normal normal normal 14px/1 font-wso2; + display: inline-block; + font-weight: normal; + font-style: normal; + font-size: inherit; + font-variant: normal; + speak: none; + text-decoration: inherit; + + /* Better Font Rendering =========== */ + text-transform: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + + +/* ======================================================================== + * font options + * ======================================================================== */ + +.fw-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fw-2x { + font-size: 2em; +} +.fw-3x { + font-size: 3em; +} +.fw-4x { + font-size: 4em; +} +.fw-5x { + font-size: 5em; +} +.fw-fw { + width: 1.28571429em; + text-align: center; +} +.fw-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fw-ul > li { + position: relative; +} +.fw-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fw-li.fw-lg { + left: -1.85714286em; +} +.fw-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fw-background { + background: #888; + border-radius: .3em; + padding: .4em .50em .45em; +} +.fw-pull-left { + float: left; +} +.fw-pull-right { + float: right; +} +.fw.fw-pull-left { + margin-right: .3em; +} +.fw.fw-pull-right { + margin-left: .3em; +} +.fw-spin { + -webkit-animation: fw-spin 2s infinite linear; + animation: fw-spin 2s infinite linear; +} +@-webkit-keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fw-pulse { + -webkit-animation: fw-pulse 2s ease-out infinite; + animation: fw-pulse 2s ease-out infinite; +} +@-webkit-keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +@keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +.fw-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fw-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fw-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fw-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fw-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fw-rotate-90, +:root .fw-rotate-180, +:root .fw-rotate-270, +:root .fw-flip-horizontal, +:root .fw-flip-vertical { + filter: none; +} +.fw-stack, +.fw-helper { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 1.85em; + vertical-align: middle; +} +.fw-stack-1x, +.fw-stack-2x, +.fw-helper:before, +.fw-helper:after { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fw-stack-1x, +.fw-helper:before { + line-height: inherit; +} +.fw-stack-2x, +.fw-helper:after { + font-size: 1.9em; +} +.fw-helper-slash:before { + font-size: 1.4em; +} +.fw-helper-circle:before, +.fw-helper-square:before { + z-index: 1; +} +.fw-helper-circle-outline:after { + content: "\e61f"; +} +.fw-helper-circle:after { + content: "\e61a"; +} +.fw-helper-square-outline:after { + content: "\e6b2"; +} +.fw-helper-square:after { + content: "\e6b1"; +} +.fw-helper-slash:after { + content: "\e6e1"; +} +.fw-stack > .fw-stack { + position: absolute; + font-size: 0.5em; +} +.fw-stack > .fw-stack.fw-move-top { + top: -0.2em; +} +.fw-stack > .fw-stack.fw-move-bottom { + bottom: -0.2em; +} +.fw-stack > .fw.stack.fw-move-left { + left: -0.5em; +} +.fw-stack > .fw-stack.fw-move-right { + right: -0.5em; +} +.fw-inverse:before, +.fw-helper-inverse:after, +.fw-number { + color: #ffffff; +} +.fw-shadow:before, +.fw-helper-shadow:after { + text-shadow: #ffffff 1px 1px 0; +} +.fw-stroke:before, +.fw-helper-stroke:after { + text-shadow: -2px -2px 0 #ffffff, + 2px -2px 0 #ffffff, + -2px 2px 0 #ffffff, + 2px 2px 0 #ffffff; +} +.fw-number { + line-height: 2em; + font-family: Arial, Helvetica, sans-serif; +} + + +/* ======================================================================== + * font icons + * ======================================================================== */ + +.fw-abort:before { + content:"\e72a"; +} + +.fw-action-invoke:before { + content:"\e6fe"; +} + +.fw-action:before { + content:"\e709"; +} + +.fw-activate:before { + content:"\e6cf"; +} + +.fw-add:before { + content:"\e615"; +} + +.fw-airplay:before { + content:"\e600"; +} + +.fw-alarm:before { + content:"\e6c2"; +} + +.fw-alert:before { + content:"\e6be"; +} + +.fw-analytics-extensions:before { + content:"\e6e2"; +} + +.fw-android-logcat:before { + content:"\e72c"; +} + +.fw-android-sense:before { + content:"\e72d"; +} + +.fw-android:before { + content:"\e606"; +} + +.fw-annotation:before { + content:"\e6e6"; +} + +.fw-api:before { + content:"\e601"; +} + +.fw-apn:before { + content:"\e602"; +} + +.fw-apple:before { + content:"\e604"; +} + +.fw-application:before { + content:"\e608"; +} + +.fw-arduino:before { + content:"\e6ab"; +} + +.fw-assign:before { + content:"\e6ff"; +} + +.fw-ballerina-service:before { + content:"\e729"; +} + +.fw-ballerina:before { + content:"\e728"; +} + +.fw-bar-chart:before { + content:"\e690"; +} + +.fw-battery:before { + content:"\e60a"; +} + +.fw-blank-document:before { + content:"\e60c"; +} + +.fw-block:before { + content:"\e695"; +} + +.fw-bookmark:before { + content:"\e60d"; +} + +.fw-bpel:before { + content:"\e60e"; +} + +.fw-bpmn:before { + content:"\e60f"; +} + +.fw-break:before { + content:"\e721"; +} + +.fw-bug:before { + content:"\e611"; +} + +.fw-build:before { + content:"\e6c1"; +} + +.fw-calendar:before { + content:"\e612"; +} + +.fw-camera:before { + content:"\e613"; +} + +.fw-cancel:before { + content:"\e618"; +} + +.fw-carbon:before { + content:"\e6c5"; +} + +.fw-chat:before { + content:"\e65b"; +} + +.fw-check:before { + content:"\e617"; +} + +.fw-checklist:before { + content:"\e619"; +} + +.fw-circle-outline:before { + content:"\e61f"; +} + +.fw-circle:before { + content:"\e61a"; +} + +.fw-clear:before { + content:"\e61b"; +} + +.fw-clock:before { + content:"\e61d"; +} + +.fw-cloud:before { + content:"\e61e"; +} + +.fw-code-view:before { + content:"\e70e"; +} + +.fw-code:before { + content:"\e6f1"; +} + +.fw-comment:before { + content:"\e710"; +} + +.fw-compare:before { + content:"\e610"; +} + +.fw-computer:before { + content:"\e653"; +} + +.fw-configarations:before { + content:"\e609"; +} + +.fw-connector:before { + content:"\e700"; +} + +.fw-console:before { + content:"\e71d"; +} + +.fw-constant:before { + content:"\e701"; +} + +.fw-contact:before { + content:"\e620"; +} + +.fw-contract:before { + content:"\e614"; +} + +.fw-copy:before { + content:"\e621"; +} + +.fw-cut:before { + content:"\e6f2"; +} + +.fw-dashboard:before { + content:"\e622"; +} + +.fw-database:before { + content:"\e623"; +} + +.fw-delete:before { + content:"\e624"; +} + +.fw-depend:before { + content:"\e6c6"; +} + +.fw-deploy:before { + content:"\e625"; +} + +.fw-deprecate:before { + content:"\e6cb"; +} + +.fw-design-view:before { + content:"\e70f"; +} + +.fw-devices:before { + content:"\e704"; +} + +.fw-dgm-action-invoke:before { + content:"\e712"; +} + +.fw-dgm-action:before { + content:"\e711"; +} + +.fw-dgm-connector:before { + content:"\e6f4"; +} + +.fw-dgm-constant-definition:before { + content:"\e6f5"; +} + +.fw-dgm-fork:before { + content:"\e6e7"; +} + +.fw-dgm-header:before { + content:"\e6e8"; +} + +.fw-dgm-if-else:before { + content:"\e6e9"; +} + +.fw-dgm-import:before { + content:"\e717"; +} + +.fw-dgm-lifeline:before { + content:"\e6ea"; +} + +.fw-dgm-logger:before { + content:"\e6eb"; +} + +.fw-dgm-resource:before { + content:"\e6f6"; +} + +.fw-dgm-service:before { + content:"\e6f7"; +} + +.fw-dgm-try-catch:before { + content:"\e6ec"; +} + +.fw-dgm-type-convertor:before { + content:"\e6f8"; +} + +.fw-dgm-type:before { + content:"\e6f9"; +} + +.fw-dgm-while:before { + content:"\e707"; +} + +.fw-dial-up:before { + content:"\e627"; +} + +.fw-disabled:before { + content:"\e6d1"; +} + +.fw-display:before { + content:"\e626"; +} + +.fw-docker:before { + content:"\e70c"; +} + +.fw-document:before { + content:"\e628"; +} + +.fw-down-arrow:before { + content:"\e689"; +} + +.fw-down:before { + content:"\e685"; +} + +.fw-download:before { + content:"\e65f"; +} + +.fw-dss:before { + content:"\e62a"; +} + +.fw-ebook:before { + content:"\e62b"; +} + +.fw-edit:before { + content:"\e62c"; +} + +.fw-ellipsis:before { + content:"\e629"; +} + +.fw-endpoint:before { + content:"\e62d"; +} + +.fw-enterprise:before { + content:"\e6b6"; +} + +.fw-error:before { + content:"\e630"; +} + +.fw-esb-connector:before { + content:"\e6e3"; +} + +.fw-expand:before { + content:"\e61c"; +} + +.fw-export:before { + content:"\e631"; +} + +.fw-extensions:before { + content:"\e6e4"; +} + +.fw-facebook:before { + content:"\e6d3"; +} + +.fw-factory-reset:before { + content:"\e632"; +} + +.fw-fan:before { + content:"\e678"; +} + +.fw-faq:before { + content:"\e62f"; +} + +.fw-file-browse:before { + content:"\e633"; +} + +.fw-filter:before { + content:"\e634"; +} + +.fw-folder-open:before { + content:"\e70b"; +} + +.fw-folder:before { + content:"\e62e"; +} + +.fw-fork-join:before { + content:"\e720"; +} + +.fw-format:before { + content:"\e6fa"; +} + +.fw-forum:before { + content:"\e636"; +} + +.fw-function-invoke:before { + content:"\e713"; +} + +.fw-function:before { + content:"\e6fb"; +} + +.fw-gadget:before { + content:"\e637"; +} + +.fw-geo-fence-inbound:before { + content:"\e72e"; +} + +.fw-geo-fence-outbound:before { + content:"\e72f"; +} + +.fw-github:before { + content:"\e6d4"; +} + +.fw-globe:before { + content:"\e697"; +} + +.fw-google-docs:before { + content:"\e6d6"; +} + +.fw-google-drive:before { + content:"\e6da"; +} + +.fw-google-plus:before { + content:"\e6d9"; +} + +.fw-google-sheets:before { + content:"\e6d7"; +} + +.fw-google-slides:before { + content:"\e6d8"; +} + +.fw-google:before { + content:"\e6d5"; +} + +.fw-grid:before { + content:"\e638"; +} + +.fw-grip:before { + content:"\e6b7"; +} + +.fw-group:before { + content:"\e6af"; +} + +.fw-hardware:before { + content:"\e6a9"; +} + +.fw-hdd:before { + content:"\e639"; +} + +.fw-heart:before { + content:"\e6c3"; +} + +.fw-hide:before { + content:"\e6d2"; +} + +.fw-home:before { + content:"\e63a"; +} + +.fw-hour-glass:before { + content:"\e63b"; +} + +.fw-html:before { + content:"\e69d"; +} + +.fw-http:before { + content:"\e705"; +} + +.fw-image:before { + content:"\e70a"; +} + +.fw-import:before { + content:"\e63c"; +} + +.fw-incoming-call:before { + content:"\e63d"; +} + +.fw-info:before { + content:"\e63e"; +} + +.fw-instagram:before { + content:"\e6db"; +} + +.fw-invitation:before { + content:"\e63f"; +} + +.fw-invoke:before { + content:"\e6ed"; +} + +.fw-is-connector:before { + content:"\e6e5"; +} + +.fw-iterate:before { + content:"\e71f"; +} + +.fw-jaggery:before { + content:"\e640"; +} + +.fw-java-spring:before { + content:"\e644"; +} + +.fw-java:before { + content:"\e641"; +} + +.fw-javaee:before { + content:"\e642"; +} + +.fw-javascript:before { + content:"\e643"; +} + +.fw-jaxrs:before { + content:"\e645"; +} + +.fw-jaxws:before { + content:"\e6c7"; +} + +.fw-jquery:before { + content:"\e646"; +} + +.fw-key:before { + content:"\e647"; +} + +.fw-laptop:before { + content:"\e648"; +} + +.fw-layout:before { + content:"\e6bf"; +} + +.fw-ldap:before { + content:"\e649"; +} + +.fw-left-arrow:before { + content:"\e68a"; +} + +.fw-left:before { + content:"\e686"; +} + +.fw-lifecycle:before { + content:"\e64a"; +} + +.fw-light:before { + content:"\e680"; +} + +.fw-linkedin:before { + content:"\e6dc"; +} + +.fw-list-sort:before { + content:"\e64d"; +} + +.fw-list:before { + content:"\e64c"; +} + +.fw-loader:before { + content:"\e6b4"; +} + +.fw-loader2:before { + content:"\e6ba"; +} + +.fw-loader3:before { + content:"\e6bb"; +} + +.fw-loader4:before { + content:"\e6bc"; +} + +.fw-loader5:before { + content:"\e6bd"; +} + +.fw-lock:before { + content:"\e64e"; +} + +.fw-logical:before { + content:"\e702"; +} + +.fw-mail:before { + content:"\e64f"; +} + +.fw-main-function:before { + content:"\e706"; +} + +.fw-map-location:before { + content:"\e650"; +} + +.fw-menu:before { + content:"\e651"; +} + +.fw-message:before { + content:"\e635"; +} + +.fw-micro-services:before { + content:"\e6ce"; +} + +.fw-minus:before, .fw-hyphen:before, .fw-dash:before { + content:"\e616"; +} + +.fw-mobile:before { + content:"\e652"; +} + +.fw-ms-document:before { + content:"\e654"; +} + +.fw-mute:before { + content:"\e655"; +} + +.fw-nodejs:before { + content:"\e656"; +} + +.fw-notification:before { + content:"\e60b"; +} + +.fw-organization:before { + content:"\e6ac"; +} + +.fw-own:before { + content:"\e6c8"; +} + +.fw-package:before { + content:"\e6fd"; +} + +.fw-pages:before { + content:"\e6c0"; +} + +.fw-paste:before { + content:"\e658"; +} + +.fw-pdf:before { + content:"\e659"; +} + +.fw-pending:before { + content:"\e727"; +} + +.fw-php:before { + content:"\e6c9"; +} + +.fw-pie-chart:before { + content:"\e65a"; +} + +.fw-pinterest:before { + content:"\e6dd"; +} + +.fw-policy:before { + content:"\e67d"; +} + +.fw-polygon:before { + content:"\e70d"; +} + +.fw-prototype:before { + content:"\e6cc"; +} + +.fw-proxy:before { + content:"\e699"; +} + +.fw-public:before { + content:"\e6ad"; +} + +.fw-publish:before { + content:"\e65c"; +} + +.fw-question:before { + content:"\e6b0"; +} + +.fw-raspberry:before { + content:"\e6aa"; +} + +.fw-redo:before { + content:"\e65d"; +} + +.fw-refresh:before { + content:"\e692"; +} + +.fw-register:before { + content:"\e65e"; +} + +.fw-rename:before { + content:"\e6fc"; +} + +.fw-reply:before { + content:"\e714"; +} + +.fw-resource:before { + content:"\e660"; +} + +.fw-rest-api:before { + content:"\e661"; +} + +.fw-rest-service:before { + content:"\e662"; +} + +.fw-resume:before { + content:"\e71e"; +} + +.fw-retire:before { + content:"\e6cd"; +} + +.fw-return:before { + content:"\e715"; +} + +.fw-retweet:before { + content:"\e6b9"; +} + +.fw-right-arrow:before { + content:"\e68b"; +} + +.fw-right:before { + content:"\e687"; +} + +.fw-ringing:before { + content:"\e694"; +} + +.fw-rules:before { + content:"\e664"; +} + +.fw-run:before { + content:"\e708"; +} + +.fw-save:before { + content:"\e665"; +} + +.fw-scep:before { + content:"\e666"; +} + +.fw-schema:before { + content:"\e667"; +} + +.fw-search:before { + content:"\e668"; +} + +.fw-security-policy:before { + content:"\e67e"; +} + +.fw-security:before { + content:"\e669"; +} + +.fw-send:before, .fw-paper-rocket:before { + content:"\e66a"; +} + +.fw-sequence:before { + content:"\e66b"; +} + +.fw-server:before { + content:"\e66c"; +} + +.fw-service-provider:before { + content:"\e66e"; +} + +.fw-service:before, .fw-cogwheels:before, .fw-gears:before, .fw-sprockets:before { + content:"\e66d"; +} + +.fw-settings:before, .fw-cogwheel:before, .fw-gear:before, .fw-sprocket:before { + content:"\e66f"; +} + +.fw-share:before { + content:"\e670"; +} + +.fw-shell:before { + content:"\e730"; +} + +.fw-shortcut:before { + content:"\e725"; +} + +.fw-sign-in:before { + content:"\e671"; +} + +.fw-sign-out:before { + content:"\e6b8"; +} + +.fw-skype:before { + content:"\e6de"; +} + +.fw-slash:before { + content:"\e6e1"; +} + +.fw-soap:before { + content:"\e672"; +} + +.fw-sort-down:before { + content:"\e663"; +} + +.fw-sort-up:before { + content:"\e64b"; +} + +.fw-sort:before { + content:"\e673"; +} + +.fw-speed-alert:before { + content:"\e731"; +} + +.fw-square-outline:before { + content:"\e6b2"; +} + +.fw-square:before { + content:"\e6b1"; +} + +.fw-star:before { + content:"\e674"; +} + +.fw-start:before { + content:"\e718"; +} + +.fw-statistics:before { + content:"\e675"; +} + +.fw-stepin:before { + content:"\e719"; +} + +.fw-stepout:before { + content:"\e71a"; +} + +.fw-stepover:before { + content:"\e71b"; +} + +.fw-stop:before { + content:"\e71c"; +} + +.fw-store:before, .fw-cart:before { + content:"\e676"; +} + +.fw-struct:before { + content:"\e716"; +} + +.fw-subscribe:before { + content:"\e677"; +} + +.fw-success:before { + content:"\e657"; +} + +.fw-swagger:before { + content:"\e679"; +} + +.fw-sync:before { + content:"\e6b3"; +} + +.fw-table:before { + content:"\e6c4"; +} + +.fw-tag:before { + content:"\e67a"; +} + +.fw-task:before { + content:"\e67b"; +} + +.fw-text:before { + content:"\e67c"; +} + +.fw-theme:before { + content:"\e726"; +} + +.fw-throttling-policy:before { + content:"\e67f"; +} + +.fw-throw:before { + content:"\e722"; +} + +.fw-tiles:before { + content:"\e681"; +} + +.fw-transaction:before { + content:"\e72b"; +} + +.fw-try-catch:before { + content:"\e703"; +} + +.fw-twitter:before { + content:"\e6df"; +} + +.fw-type-converter:before { + content:"\e6f3"; +} + +.fw-uncheck:before { + content:"\e682"; +} + +.fw-undo:before { + content:"\e683"; +} + +.fw-ungroup:before { + content:"\e6b5"; +} + +.fw-unmute:before { + content:"\e6ae"; +} + +.fw-up-arrow:before { + content:"\e688"; +} + +.fw-up:before { + content:"\e684"; +} + +.fw-upload:before { + content:"\e68c"; +} + +.fw-uri:before { + content:"\e68d"; +} + +.fw-usb-drive:before { + content:"\e68e"; +} + +.fw-use:before { + content:"\e6ca"; +} + +.fw-user:before { + content:"\e68f"; +} + +.fw-variable:before { + content:"\e6ee"; +} + +.fw-view:before { + content:"\e691"; +} + +.fw-vpn:before { + content:"\e603"; +} + +.fw-wadl:before { + content:"\e6a1"; +} + +.fw-war:before { + content:"\e69e"; +} + +.fw-warning:before { + content:"\e693"; +} + +.fw-web-app:before { + content:"\e696"; +} + +.fw-web-clip:before { + content:"\e698"; +} + +.fw-web-service:before { + content:"\e69a"; +} + +.fw-website:before { + content:"\e69b"; +} + +.fw-wifi:before { + content:"\e607"; +} + +.fw-windows:before { + content:"\e605"; +} + +.fw-worker-invoke:before { + content:"\e723"; +} + +.fw-worker-reply:before { + content:"\e724"; +} + +.fw-worker:before { + content:"\e6ef"; +} + +.fw-wsdl:before { + content:"\e6a0"; +} + +.fw-wso2-logo:before { + content:"\e6a7"; +} + +.fw-wso2:before { + content:"\e6a8"; +} + +.fw-xacml:before { + content:"\e69f"; +} + +.fw-xml:before { + content:"\e69c"; +} + +.fw-xq:before { + content:"\e6a2"; +} + +.fw-xsd:before { + content:"\e6a3"; +} + +.fw-xslt:before { + content:"\e6a4"; +} + +.fw-youtube:before { + content:"\e6e0"; +} + +.fw-zoom-in:before { + content:"\e6a5"; +} + +.fw-zoom-out:before { + content:"\e6a6"; +} + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.min.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.min.css new file mode 100644 index 0000000000..6d229b71da --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/css/font-wso2.min.css @@ -0,0 +1,15 @@ +/*! +~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/.fw-fw,.fw-li{text-align:center}@font-face{font-family:font-wso2;src:local("font-wso2"),url(../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223);src:local("font-wso2"),url(../fonts/font-wso2.eot?#iefix) format("embedded-opentype"),url(../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223) format("woff2"),url(../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223) format("woff"),url(../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223) format("truetype"),url(../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-wso2;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}@keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}.fw-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-add:before{content:"\e615"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-apple:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configarations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.ttf b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000000..aa00de0ef9 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.ttf differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff new file mode 100644 index 0000000000..ced7907e94 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff2 b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff2 new file mode 100644 index 0000000000..723a32343b Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Medium.woff2 differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.ttf b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000000..3e6e2e7613 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.ttf differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff new file mode 100644 index 0000000000..e401bcf528 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff2 b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff2 new file mode 100644 index 0000000000..5bd7bd6500 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/Roboto-Regular.woff2 differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.svg b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.svg new file mode 100644 index 0000000000..91614ea75e --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.svg @@ -0,0 +1,2326 @@ + + + + + +Created by FontForge 20161004 at Wed Jun 21 08:31:03 2017 + By dimal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.ttf b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.ttf new file mode 100644 index 0000000000..27735b2820 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.ttf differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff new file mode 100644 index 0000000000..80fd5a7fc2 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff2 b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff2 new file mode 100644 index 0000000000..6087330889 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/fonts/font-wso2.woff2 differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-2.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-2.png new file mode 100644 index 0000000000..9467f5eb76 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-2.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-3.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-3.png new file mode 100644 index 0000000000..f1d980e55c Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar-3.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar.png new file mode 100644 index 0000000000..5fab5dee57 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/avatar.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/favicon.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/favicon.png new file mode 100644 index 0000000000..a1deab3581 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/favicon.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg new file mode 100644 index 0000000000..05742db887 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg @@ -0,0 +1,798 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/locales/en.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/locales/en.json new file mode 100644 index 0000000000..5be6f63bd4 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/locales/en.json @@ -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" +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/scss/_mixin.scss b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/scss/_mixin.scss new file mode 100644 index 0000000000..5b40942bef --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/scss/_mixin.scss @@ -0,0 +1,1252 @@ +/*! +~ Copyright (c) 2017 WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/ + +%icon-base { + &:before { + font-family: "font-wso2"; + -webkit-font-smoothing: antialiased; + } + b { + // hide text + height: 0; + display: block; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } +} + +@mixin font-wso2($icon) { + @extend %icon-base; + + + @if ($icon == "abort") { + content:"\e72a"; + } + + @else if ($icon == "action-invoke") { + content:"\e6fe"; + } + + @else if ($icon == "action") { + content:"\e709"; + } + + @else if ($icon == "activate") { + content:"\e6cf"; + } + + @else if ($icon == "add") { + content:"\e615"; + } + + @else if ($icon == "airplay") { + content:"\e600"; + } + + @else if ($icon == "alarm") { + content:"\e6c2"; + } + + @else if ($icon == "alert") { + content:"\e6be"; + } + + @else if ($icon == "analytics-extensions") { + content:"\e6e2"; + } + + @else if ($icon == "android-logcat") { + content:"\e72c"; + } + + @else if ($icon == "android-sense") { + content:"\e72d"; + } + + @else if ($icon == "android") { + content:"\e606"; + } + + @else if ($icon == "annotation") { + content:"\e6e6"; + } + + @else if ($icon == "api") { + content:"\e601"; + } + + @else if ($icon == "apn") { + content:"\e602"; + } + + @else if ($icon == "apple") { + content:"\e604"; + } + + @else if ($icon == "application") { + content:"\e608"; + } + + @else if ($icon == "arduino") { + content:"\e6ab"; + } + + @else if ($icon == "assign") { + content:"\e6ff"; + } + + @else if ($icon == "ballerina-service") { + content:"\e729"; + } + + @else if ($icon == "ballerina") { + content:"\e728"; + } + + @else if ($icon == "bar-chart") { + content:"\e690"; + } + + @else if ($icon == "battery") { + content:"\e60a"; + } + + @else if ($icon == "blank-document") { + content:"\e60c"; + } + + @else if ($icon == "block") { + content:"\e695"; + } + + @else if ($icon == "bookmark") { + content:"\e60d"; + } + + @else if ($icon == "bpel") { + content:"\e60e"; + } + + @else if ($icon == "bpmn") { + content:"\e60f"; + } + + @else if ($icon == "break") { + content:"\e721"; + } + + @else if ($icon == "bug") { + content:"\e611"; + } + + @else if ($icon == "build") { + content:"\e6c1"; + } + + @else if ($icon == "calendar") { + content:"\e612"; + } + + @else if ($icon == "camera") { + content:"\e613"; + } + + @else if ($icon == "cancel") { + content:"\e618"; + } + + @else if ($icon == "carbon") { + content:"\e6c5"; + } + + @else if ($icon == "chat") { + content:"\e65b"; + } + + @else if ($icon == "check") { + content:"\e617"; + } + + @else if ($icon == "checklist") { + content:"\e619"; + } + + @else if ($icon == "circle-outline") { + content:"\e61f"; + } + + @else if ($icon == "circle") { + content:"\e61a"; + } + + @else if ($icon == "clear") { + content:"\e61b"; + } + + @else if ($icon == "clock") { + content:"\e61d"; + } + + @else if ($icon == "cloud") { + content:"\e61e"; + } + + @else if ($icon == "code-view") { + content:"\e70e"; + } + + @else if ($icon == "code") { + content:"\e6f1"; + } + + @else if ($icon == "comment") { + content:"\e710"; + } + + @else if ($icon == "compare") { + content:"\e610"; + } + + @else if ($icon == "computer") { + content:"\e653"; + } + + @else if ($icon == "configarations") { + content:"\e609"; + } + + @else if ($icon == "connector") { + content:"\e700"; + } + + @else if ($icon == "console") { + content:"\e71d"; + } + + @else if ($icon == "constant") { + content:"\e701"; + } + + @else if ($icon == "contact") { + content:"\e620"; + } + + @else if ($icon == "contract") { + content:"\e614"; + } + + @else if ($icon == "copy") { + content:"\e621"; + } + + @else if ($icon == "cut") { + content:"\e6f2"; + } + + @else if ($icon == "dashboard") { + content:"\e622"; + } + + @else if ($icon == "database") { + content:"\e623"; + } + + @else if ($icon == "delete") { + content:"\e624"; + } + + @else if ($icon == "depend") { + content:"\e6c6"; + } + + @else if ($icon == "deploy") { + content:"\e625"; + } + + @else if ($icon == "deprecate") { + content:"\e6cb"; + } + + @else if ($icon == "design-view") { + content:"\e70f"; + } + + @else if ($icon == "devices") { + content:"\e704"; + } + + @else if ($icon == "dgm-action-invoke") { + content:"\e712"; + } + + @else if ($icon == "dgm-action") { + content:"\e711"; + } + + @else if ($icon == "dgm-connector") { + content:"\e6f4"; + } + + @else if ($icon == "dgm-constant-definition") { + content:"\e6f5"; + } + + @else if ($icon == "dgm-fork") { + content:"\e6e7"; + } + + @else if ($icon == "dgm-header") { + content:"\e6e8"; + } + + @else if ($icon == "dgm-if-else") { + content:"\e6e9"; + } + + @else if ($icon == "dgm-import") { + content:"\e717"; + } + + @else if ($icon == "dgm-lifeline") { + content:"\e6ea"; + } + + @else if ($icon == "dgm-logger") { + content:"\e6eb"; + } + + @else if ($icon == "dgm-resource") { + content:"\e6f6"; + } + + @else if ($icon == "dgm-service") { + content:"\e6f7"; + } + + @else if ($icon == "dgm-try-catch") { + content:"\e6ec"; + } + + @else if ($icon == "dgm-type-convertor") { + content:"\e6f8"; + } + + @else if ($icon == "dgm-type") { + content:"\e6f9"; + } + + @else if ($icon == "dgm-while") { + content:"\e707"; + } + + @else if ($icon == "dial-up") { + content:"\e627"; + } + + @else if ($icon == "disabled") { + content:"\e6d1"; + } + + @else if ($icon == "display") { + content:"\e626"; + } + + @else if ($icon == "docker") { + content:"\e70c"; + } + + @else if ($icon == "document") { + content:"\e628"; + } + + @else if ($icon == "down-arrow") { + content:"\e689"; + } + + @else if ($icon == "down") { + content:"\e685"; + } + + @else if ($icon == "download") { + content:"\e65f"; + } + + @else if ($icon == "dss") { + content:"\e62a"; + } + + @else if ($icon == "ebook") { + content:"\e62b"; + } + + @else if ($icon == "edit") { + content:"\e62c"; + } + + @else if ($icon == "ellipsis") { + content:"\e629"; + } + + @else if ($icon == "endpoint") { + content:"\e62d"; + } + + @else if ($icon == "enterprise") { + content:"\e6b6"; + } + + @else if ($icon == "error") { + content:"\e630"; + } + + @else if ($icon == "esb-connector") { + content:"\e6e3"; + } + + @else if ($icon == "expand") { + content:"\e61c"; + } + + @else if ($icon == "export") { + content:"\e631"; + } + + @else if ($icon == "extensions") { + content:"\e6e4"; + } + + @else if ($icon == "facebook") { + content:"\e6d3"; + } + + @else if ($icon == "factory-reset") { + content:"\e632"; + } + + @else if ($icon == "fan") { + content:"\e678"; + } + + @else if ($icon == "faq") { + content:"\e62f"; + } + + @else if ($icon == "file-browse") { + content:"\e633"; + } + + @else if ($icon == "filter") { + content:"\e634"; + } + + @else if ($icon == "folder-open") { + content:"\e70b"; + } + + @else if ($icon == "folder") { + content:"\e62e"; + } + + @else if ($icon == "fork-join") { + content:"\e720"; + } + + @else if ($icon == "format") { + content:"\e6fa"; + } + + @else if ($icon == "forum") { + content:"\e636"; + } + + @else if ($icon == "function-invoke") { + content:"\e713"; + } + + @else if ($icon == "function") { + content:"\e6fb"; + } + + @else if ($icon == "gadget") { + content:"\e637"; + } + + @else if ($icon == "geo-fence-inbound") { + content:"\e72e"; + } + + @else if ($icon == "geo-fence-outbound") { + content:"\e72f"; + } + + @else if ($icon == "github") { + content:"\e6d4"; + } + + @else if ($icon == "globe") { + content:"\e697"; + } + + @else if ($icon == "google-docs") { + content:"\e6d6"; + } + + @else if ($icon == "google-drive") { + content:"\e6da"; + } + + @else if ($icon == "google-plus") { + content:"\e6d9"; + } + + @else if ($icon == "google-sheets") { + content:"\e6d7"; + } + + @else if ($icon == "google-slides") { + content:"\e6d8"; + } + + @else if ($icon == "google") { + content:"\e6d5"; + } + + @else if ($icon == "grid") { + content:"\e638"; + } + + @else if ($icon == "grip") { + content:"\e6b7"; + } + + @else if ($icon == "group") { + content:"\e6af"; + } + + @else if ($icon == "hardware") { + content:"\e6a9"; + } + + @else if ($icon == "hdd") { + content:"\e639"; + } + + @else if ($icon == "heart") { + content:"\e6c3"; + } + + @else if ($icon == "hide") { + content:"\e6d2"; + } + + @else if ($icon == "home") { + content:"\e63a"; + } + + @else if ($icon == "hour-glass") { + content:"\e63b"; + } + + @else if ($icon == "html") { + content:"\e69d"; + } + + @else if ($icon == "http") { + content:"\e705"; + } + + @else if ($icon == "image") { + content:"\e70a"; + } + + @else if ($icon == "import") { + content:"\e63c"; + } + + @else if ($icon == "incoming-call") { + content:"\e63d"; + } + + @else if ($icon == "info") { + content:"\e63e"; + } + + @else if ($icon == "instagram") { + content:"\e6db"; + } + + @else if ($icon == "invitation") { + content:"\e63f"; + } + + @else if ($icon == "invoke") { + content:"\e6ed"; + } + + @else if ($icon == "is-connector") { + content:"\e6e5"; + } + + @else if ($icon == "iterate") { + content:"\e71f"; + } + + @else if ($icon == "jaggery") { + content:"\e640"; + } + + @else if ($icon == "java-spring") { + content:"\e644"; + } + + @else if ($icon == "java") { + content:"\e641"; + } + + @else if ($icon == "javaee") { + content:"\e642"; + } + + @else if ($icon == "javascript") { + content:"\e643"; + } + + @else if ($icon == "jaxrs") { + content:"\e645"; + } + + @else if ($icon == "jaxws") { + content:"\e6c7"; + } + + @else if ($icon == "jquery") { + content:"\e646"; + } + + @else if ($icon == "key") { + content:"\e647"; + } + + @else if ($icon == "laptop") { + content:"\e648"; + } + + @else if ($icon == "layout") { + content:"\e6bf"; + } + + @else if ($icon == "ldap") { + content:"\e649"; + } + + @else if ($icon == "left-arrow") { + content:"\e68a"; + } + + @else if ($icon == "left") { + content:"\e686"; + } + + @else if ($icon == "lifecycle") { + content:"\e64a"; + } + + @else if ($icon == "light") { + content:"\e680"; + } + + @else if ($icon == "linkedin") { + content:"\e6dc"; + } + + @else if ($icon == "list-sort") { + content:"\e64d"; + } + + @else if ($icon == "list") { + content:"\e64c"; + } + + @else if ($icon == "loader") { + content:"\e6b4"; + } + + @else if ($icon == "loader2") { + content:"\e6ba"; + } + + @else if ($icon == "loader3") { + content:"\e6bb"; + } + + @else if ($icon == "loader4") { + content:"\e6bc"; + } + + @else if ($icon == "loader5") { + content:"\e6bd"; + } + + @else if ($icon == "lock") { + content:"\e64e"; + } + + @else if ($icon == "logical") { + content:"\e702"; + } + + @else if ($icon == "mail") { + content:"\e64f"; + } + + @else if ($icon == "main-function") { + content:"\e706"; + } + + @else if ($icon == "map-location") { + content:"\e650"; + } + + @else if ($icon == "menu") { + content:"\e651"; + } + + @else if ($icon == "message") { + content:"\e635"; + } + + @else if ($icon == "micro-services") { + content:"\e6ce"; + } + + @else if ($icon == "minus") { + content:"\e616"; + } + + @else if ($icon == "mobile") { + content:"\e652"; + } + + @else if ($icon == "ms-document") { + content:"\e654"; + } + + @else if ($icon == "mute") { + content:"\e655"; + } + + @else if ($icon == "nodejs") { + content:"\e656"; + } + + @else if ($icon == "notification") { + content:"\e60b"; + } + + @else if ($icon == "organization") { + content:"\e6ac"; + } + + @else if ($icon == "own") { + content:"\e6c8"; + } + + @else if ($icon == "package") { + content:"\e6fd"; + } + + @else if ($icon == "pages") { + content:"\e6c0"; + } + + @else if ($icon == "paste") { + content:"\e658"; + } + + @else if ($icon == "pdf") { + content:"\e659"; + } + + @else if ($icon == "pending") { + content:"\e727"; + } + + @else if ($icon == "php") { + content:"\e6c9"; + } + + @else if ($icon == "pie-chart") { + content:"\e65a"; + } + + @else if ($icon == "pinterest") { + content:"\e6dd"; + } + + @else if ($icon == "policy") { + content:"\e67d"; + } + + @else if ($icon == "polygon") { + content:"\e70d"; + } + + @else if ($icon == "prototype") { + content:"\e6cc"; + } + + @else if ($icon == "proxy") { + content:"\e699"; + } + + @else if ($icon == "public") { + content:"\e6ad"; + } + + @else if ($icon == "publish") { + content:"\e65c"; + } + + @else if ($icon == "question") { + content:"\e6b0"; + } + + @else if ($icon == "raspberry") { + content:"\e6aa"; + } + + @else if ($icon == "redo") { + content:"\e65d"; + } + + @else if ($icon == "refresh") { + content:"\e692"; + } + + @else if ($icon == "register") { + content:"\e65e"; + } + + @else if ($icon == "rename") { + content:"\e6fc"; + } + + @else if ($icon == "reply") { + content:"\e714"; + } + + @else if ($icon == "resource") { + content:"\e660"; + } + + @else if ($icon == "rest-api") { + content:"\e661"; + } + + @else if ($icon == "rest-service") { + content:"\e662"; + } + + @else if ($icon == "resume") { + content:"\e71e"; + } + + @else if ($icon == "retire") { + content:"\e6cd"; + } + + @else if ($icon == "return") { + content:"\e715"; + } + + @else if ($icon == "retweet") { + content:"\e6b9"; + } + + @else if ($icon == "right-arrow") { + content:"\e68b"; + } + + @else if ($icon == "right") { + content:"\e687"; + } + + @else if ($icon == "ringing") { + content:"\e694"; + } + + @else if ($icon == "rules") { + content:"\e664"; + } + + @else if ($icon == "run") { + content:"\e708"; + } + + @else if ($icon == "save") { + content:"\e665"; + } + + @else if ($icon == "scep") { + content:"\e666"; + } + + @else if ($icon == "schema") { + content:"\e667"; + } + + @else if ($icon == "search") { + content:"\e668"; + } + + @else if ($icon == "security-policy") { + content:"\e67e"; + } + + @else if ($icon == "security") { + content:"\e669"; + } + + @else if ($icon == "send") { + content:"\e66a"; + } + + @else if ($icon == "sequence") { + content:"\e66b"; + } + + @else if ($icon == "server") { + content:"\e66c"; + } + + @else if ($icon == "service-provider") { + content:"\e66e"; + } + + @else if ($icon == "service") { + content:"\e66d"; + } + + @else if ($icon == "settings") { + content:"\e66f"; + } + + @else if ($icon == "share") { + content:"\e670"; + } + + @else if ($icon == "shell") { + content:"\e730"; + } + + @else if ($icon == "shortcut") { + content:"\e725"; + } + + @else if ($icon == "sign-in") { + content:"\e671"; + } + + @else if ($icon == "sign-out") { + content:"\e6b8"; + } + + @else if ($icon == "skype") { + content:"\e6de"; + } + + @else if ($icon == "slash") { + content:"\e6e1"; + } + + @else if ($icon == "soap") { + content:"\e672"; + } + + @else if ($icon == "sort-down") { + content:"\e663"; + } + + @else if ($icon == "sort-up") { + content:"\e64b"; + } + + @else if ($icon == "sort") { + content:"\e673"; + } + + @else if ($icon == "speed-alert") { + content:"\e731"; + } + + @else if ($icon == "square-outline") { + content:"\e6b2"; + } + + @else if ($icon == "square") { + content:"\e6b1"; + } + + @else if ($icon == "star") { + content:"\e674"; + } + + @else if ($icon == "start") { + content:"\e718"; + } + + @else if ($icon == "statistics") { + content:"\e675"; + } + + @else if ($icon == "stepin") { + content:"\e719"; + } + + @else if ($icon == "stepout") { + content:"\e71a"; + } + + @else if ($icon == "stepover") { + content:"\e71b"; + } + + @else if ($icon == "stop") { + content:"\e71c"; + } + + @else if ($icon == "store") { + content:"\e676"; + } + + @else if ($icon == "struct") { + content:"\e716"; + } + + @else if ($icon == "subscribe") { + content:"\e677"; + } + + @else if ($icon == "success") { + content:"\e657"; + } + + @else if ($icon == "swagger") { + content:"\e679"; + } + + @else if ($icon == "sync") { + content:"\e6b3"; + } + + @else if ($icon == "table") { + content:"\e6c4"; + } + + @else if ($icon == "tag") { + content:"\e67a"; + } + + @else if ($icon == "task") { + content:"\e67b"; + } + + @else if ($icon == "text") { + content:"\e67c"; + } + + @else if ($icon == "theme") { + content:"\e726"; + } + + @else if ($icon == "throttling-policy") { + content:"\e67f"; + } + + @else if ($icon == "throw") { + content:"\e722"; + } + + @else if ($icon == "tiles") { + content:"\e681"; + } + + @else if ($icon == "transaction") { + content:"\e72b"; + } + + @else if ($icon == "try-catch") { + content:"\e703"; + } + + @else if ($icon == "twitter") { + content:"\e6df"; + } + + @else if ($icon == "type-converter") { + content:"\e6f3"; + } + + @else if ($icon == "uncheck") { + content:"\e682"; + } + + @else if ($icon == "undo") { + content:"\e683"; + } + + @else if ($icon == "ungroup") { + content:"\e6b5"; + } + + @else if ($icon == "unmute") { + content:"\e6ae"; + } + + @else if ($icon == "up-arrow") { + content:"\e688"; + } + + @else if ($icon == "up") { + content:"\e684"; + } + + @else if ($icon == "upload") { + content:"\e68c"; + } + + @else if ($icon == "uri") { + content:"\e68d"; + } + + @else if ($icon == "usb-drive") { + content:"\e68e"; + } + + @else if ($icon == "use") { + content:"\e6ca"; + } + + @else if ($icon == "user") { + content:"\e68f"; + } + + @else if ($icon == "variable") { + content:"\e6ee"; + } + + @else if ($icon == "view") { + content:"\e691"; + } + + @else if ($icon == "vpn") { + content:"\e603"; + } + + @else if ($icon == "wadl") { + content:"\e6a1"; + } + + @else if ($icon == "war") { + content:"\e69e"; + } + + @else if ($icon == "warning") { + content:"\e693"; + } + + @else if ($icon == "web-app") { + content:"\e696"; + } + + @else if ($icon == "web-clip") { + content:"\e698"; + } + + @else if ($icon == "web-service") { + content:"\e69a"; + } + + @else if ($icon == "website") { + content:"\e69b"; + } + + @else if ($icon == "wifi") { + content:"\e607"; + } + + @else if ($icon == "windows") { + content:"\e605"; + } + + @else if ($icon == "worker-invoke") { + content:"\e723"; + } + + @else if ($icon == "worker-reply") { + content:"\e724"; + } + + @else if ($icon == "worker") { + content:"\e6ef"; + } + + @else if ($icon == "wsdl") { + content:"\e6a0"; + } + + @else if ($icon == "wso2-logo") { + content:"\e6a7"; + } + + @else if ($icon == "wso2") { + content:"\e6a8"; + } + + @else if ($icon == "xacml") { + content:"\e69f"; + } + + @else if ($icon == "xml") { + content:"\e69c"; + } + + @else if ($icon == "xq") { + content:"\e6a2"; + } + + @else if ($icon == "xsd") { + content:"\e6a3"; + } + + @else if ($icon == "xslt") { + content:"\e6a4"; + } + + @else if ($icon == "youtube") { + content:"\e6e0"; + } + + @else if ($icon == "zoom-in") { + content:"\e6a5"; + } + + @else if ($icon == "zoom-out") { + content:"\e6a6"; + } + +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/themes/default/default-theme.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/themes/default/default-theme.css new file mode 100644 index 0000000000..d6e82a6745 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/themes/default/default-theme.css @@ -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; +} +*/ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.css new file mode 100644 index 0000000000..d393e9ad68 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.css @@ -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; + } +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js new file mode 100644 index 0000000000..68f8823e1a --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js @@ -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 = ( + + + + + +); + +const errorView = ( + +); + +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 = ( + + +
+ + + {this.props.routes.map((route) => ( + + ))} + +
+
+
+ ); + + return ( +
+ {loading && loadingView} + {!loading && !error && applicationView} + {error && errorView} +
+ ); + } +} + +export default App; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.test.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.test.js new file mode 100644 index 0000000000..0b509e08c1 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.test.js @@ -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(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js new file mode 100644 index 0000000000..dc2a247f14 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js @@ -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 ( + + + + ); + } + // 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 {status}; + } + // todo add filtering options + }, + { + title: 'Last Updated', + dataIndex: 'enrolmentInfo', + key: 'dateOfLastUpdate', + render: (data) => { + const {dateOfLastUpdate} = data; + const timeAgoString = getTimeAgo(dateOfLastUpdate); + return {timeAgoString}; + } + // todo add filtering options + }, + { + title: 'Action', + key: 'action', + render: () => ( + + + + + + ), + }, +]; + +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 ( +
+ 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}} + /> + + ); + } +} + +export default withConfigContext(DeviceTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/RouteWithSubRoutes.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/RouteWithSubRoutes.js new file mode 100644 index 0000000000..f57ec331b0 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/RouteWithSubRoutes.js @@ -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( + ( + + )}/> + ); + } + +} + +export default RouteWithSubRoutes; \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/context/ConfigContext.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/context/ConfigContext.js new file mode 100644 index 0000000000..ea680a4cc5 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/context/ConfigContext.js @@ -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 => ( + + {context => { + return ; + }} + + ); +}; + +export default ConfigContext; + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.css new file mode 100644 index 0000000000..74dcd95a69 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.css @@ -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; +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.html b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.html new file mode 100644 index 0000000000..f2d81b221c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.html @@ -0,0 +1,26 @@ + + + + + + + Entgra Device Management + +
+ \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js new file mode 100644 index 0000000000..b8206d16d7 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -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( + , + 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(); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/logo.svg b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/logo.svg new file mode 100644 index 0000000000..6b60c1042f --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js new file mode 100644 index 0000000000..590c190a58 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js @@ -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 ( +
+ +
+
+ logo +
+ + Devices + Geo + Reports + + + + Profile + + } + > + + + + + +
+
+ + + + + {this.state.routes.map((route) => ( + + ))} + + +
+ ©2019 entgra.io +
+
+
+ ); + } +} + +export default withConfigContext(Dashboard); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js new file mode 100644 index 0000000000..e6e4807638 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js @@ -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 ( +
+ + + + Home + + Devices + +
+

Devices

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+
+
+ +
+
+
+ ); + } +} + +export default Devices; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Geo/Geo.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Geo/Geo.js new file mode 100644 index 0000000000..ad8b6a7756 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Geo/Geo.js @@ -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 ( +
+ + + + Home + + Geo + +
+

Geo

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+
+ +
+
+ ); + } +} + +export default Geo; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Logout/Logout.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Logout/Logout.js new file mode 100644 index 0000000000..3a011b9169 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Logout/Logout.js @@ -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 ( + + Logout + + ); + } +} + +export default withConfigContext(Logout); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Reports/Reports.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Reports/Reports.js new file mode 100644 index 0000000000..5449bf726b --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Reports/Reports.js @@ -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 ( +
+ + + + Home + + Reports + +
+

Reports

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+
+ +
+
+ ); + } +} + +export default Reports; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.css new file mode 100644 index 0000000000..debb603a35 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.css @@ -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; +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.js new file mode 100644 index 0000000000..19bbf40a27 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Login.js @@ -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 ( +
+
+
+
+ +
+ + + + + + + + + Login + + + + + + + + + + + + + ); + } +} + +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 = Invalid Login Details; + } + let loading = ""; + if (this.state.loading) { + loading = Loading..; + } + return ( + + + {getFieldDecorator('username', { + rules: [{required: true, message: 'Please input your username!'}], + })( + } + placeholder="Username"/> + )} + + + {getFieldDecorator('password', { + rules: [{required: true, message: 'Please input your Password!'}], + })( + } type="password" + placeholder="Password"/> + )} + + {loading} + {errorMsg} + + {getFieldDecorator('remember', { + valuePropName: 'checked', + initialValue: true, + })( + Remember me + )} +
+ Forgot password + +
+ + ); + } +} + +const WrappedNormalLoginForm = withConfigContext(Form.create({name: 'normal_login'})(NormalLoginForm)); + +export default withConfigContext(Login); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/dashboard/Dashboard.less b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/dashboard/Dashboard.less new file mode 100644 index 0000000000..0555e51efb --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/dashboard/Dashboard.less @@ -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; +} \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/serviceWorker.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/serviceWorker.js new file mode 100644 index 0000000000..249177c0b0 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/serviceWorker.js @@ -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(); + }); + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/webpack.config.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/webpack.config.js new file mode 100644 index 0000000000..116b83d79f --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/webpack.config.js @@ -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; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/io.entgra.device.mgt.ui/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..d9fcd747a0 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,25 @@ + + + + Entgra-Webapp + + 404 + /index.html + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 4cf332c0b8..aba6d9819c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -901,12 +901,7 @@ public interface DeviceManagementService { required = true) @PathParam("device-id") @Size(max = 45) - String deviceId, - @ApiParam( - name = "permanentDelete", - value = "Boolean flag indicating whether to permanently delete the device.", - required = false) - @QueryParam("permanentDelete") boolean permanentDelete); + String deviceId); @GET @Path("/{type}/{id}/features") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java index b96977adfb..4377c9d185 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java @@ -15,6 +15,22 @@ * specific language governing permissions and limitations * 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; @@ -76,6 +92,12 @@ import java.util.List; description = "Update the ownership of the device", key = "perm: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.", required = true) List 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); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index d87bfcd19a..9febec7ec3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -105,7 +105,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Map; @Path("/devices") @Produces(MediaType.APPLICATION_JSON) @@ -326,8 +325,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @Override @Path("/type/{device-type}/id/{device-id}") public Response deleteDevice(@PathParam("device-type") String deviceType, - @PathParam("device-id") String deviceId, - @QueryParam("permanentDelete") boolean permanentDelete) { + @PathParam("device-id") String deviceId) { DeviceManagementProviderService deviceManagementProviderService = DeviceMgtAPIUtils.getDeviceManagementService(); try { @@ -336,16 +334,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { if (persistedDevice == null) { return Response.status(Response.Status.NOT_FOUND).build(); } - - boolean response; - - if (permanentDelete) { - response = deviceManagementProviderService.deleteDevice(deviceIdentifier); - } else { - response = deviceManagementProviderService.disenrollDevice(deviceIdentifier); - } + boolean response = deviceManagementProviderService.disenrollDevice(deviceIdentifier); return Response.status(Response.Status.OK).entity(response).build(); - } catch (DeviceManagementException e) { String msg = "Error encountered while deleting device of type : " + deviceType + " and " + "ID : " + deviceId; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index 3864276fe8..031fd1c56a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -15,6 +15,22 @@ * specific language governing permissions and limitations * 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; @@ -24,10 +40,12 @@ import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; 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.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.PaginationRequest; 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.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceManagementAdminService; @@ -96,25 +114,53 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @QueryParam("owner") String owner, List deviceIdentifiers){ try { - if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)){ + if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)) { String msg = "Device owner is updated successfully."; return Response.status(Response.Status.OK).entity(msg).build(); } String msg = "Device owner updating is failed."; log.error(msg); 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."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); - }catch (DeviceManagementException e) { + } catch (DeviceManagementException e) { 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(); } catch (UserNotFoundException e) { 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(); } } + + @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(); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java index bdf1662687..edae86a311 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -140,7 +140,8 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen @Override @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.getName() == null || !deviceType.getName().equals(type)) { return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type + @@ -166,7 +167,10 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen } @Override - public Response addDeviceTypePlatformConfig(String type, PlatformConfiguration platformConfiguration) { + @POST + @Path("/{type}/configs") + public Response addDeviceTypePlatformConfig(@PathParam("type") String type, + PlatformConfiguration platformConfiguration) { boolean isSaved; if (platformConfiguration.getType() == null || !platformConfiguration.getType().equals(type)) { return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index b5bb8ce975..57f71d18a6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -481,8 +481,7 @@ public class DeviceManagementServiceImplTest { public void testDeleteDevice() { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -492,8 +491,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService .getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } @@ -504,8 +502,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class))) .thenThrow(new DeviceManagementException()); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index 5ea2a87b5b..f62d915d1b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -277,6 +277,17 @@ public interface DeviceDAO { */ List 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 searchDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException; + /** * 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 * fails. */ - List getDevicesByIdentifiers(List deviceIdentifiers, int tenantId) throws DeviceManagementDAOException; + List getDevicesByIdentifiers(List deviceIdentifiers, int tenantId) + throws DeviceManagementDAOException; /** * 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; } - diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 1cd83aa794..413e9bc56c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -1507,8 +1507,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } return devices; } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags", - e); + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to get devices for" + + " given device identifiers.", e); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java index 7bbb94bc89..77aab5bae9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java @@ -369,7 +369,11 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { try { Connection conn = this.getConnection(); 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)) { if (conn.getMetaData().supportsBatchUpdates()) { for (Device device : devices) { @@ -381,6 +385,7 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { for (int i : ps.executeBatch()) { if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { updateStatus = false; + break; } } } else { @@ -390,14 +395,15 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { ps.setInt(3, tenantId); if (ps.executeUpdate() == 0) { updateStatus = false; + break; } } } } return updateStatus; } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags", - e); + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to update the " + + "owner of the device enrollment.", e); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 872ea7c285..8f38bc9d73 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -153,6 +153,137 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List 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 public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index 33875fc9c7..2d568fed7e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -159,6 +159,137 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List 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 public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index f8bce9b286..e46d460bcb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -140,6 +140,136 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List 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 public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index ee60068fa8..12635fd1a1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -156,6 +156,136 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List 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 public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index d9d34f5fd4..2f6d4104cb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -827,7 +827,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } else { try { 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); } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving device list pertaining to the current tenant"; @@ -3090,12 +3094,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.rollbackTransaction(); return false; } catch (TransactionManagementException e) { - String msg = "Error occurred while initiating transaction"; + String msg = "Error occurred while initiating the transaction."; log.error(msg, e); throw new DeviceManagementException(msg, e); } catch (DeviceManagementDAOException e) { 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); } finally { DeviceManagementDAOFactory.closeConnection(); @@ -3118,7 +3122,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv return owner; } catch (UserStoreException e) { 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); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index edcb4f76e5..5cc28bc8ec 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -34,6 +34,7 @@ */ 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.LogFactory; 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.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.DeviceTypePluginExtensionException; 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.DeviceTypeUtils; 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.Resource; 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 @@ -307,15 +339,11 @@ public class DeviceTypeManager implements DeviceManager { deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException ex) { - String msg = "Error occurred while roll back the device enrol transaction :" + - device.toString(); - log.warn(msg, ex); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); String msg = "Error while enrolling the " + deviceType + " device : " + device.getDeviceIdentifier(); throw new DeviceManagementException(msg, e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -334,16 +362,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(device); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException mobileDAOEx) { - String msg = "Error occurred while roll back the update device transaction :" + - device.toString(); - log.warn(msg, mobileDAOEx); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); String msg = "Error while updating the enrollment of the " + deviceType + " device : " + device.getDeviceIdentifier(); throw new DeviceManagementException(msg, e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -378,13 +402,7 @@ public class DeviceTypeManager implements DeviceManager { deviceId.getId(); throw new DeviceManagementException(msg, e); } finally { - try { - 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); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return isEnrolled; } @@ -419,12 +437,7 @@ public class DeviceTypeManager implements DeviceManager { throw new DeviceManagementException( "Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e); } finally { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); - } catch (DeviceTypeMgtPluginException e) { - String msg = "Error occurred while closing the transaction to get device " + deviceId.getId(); - log.warn(msg, e); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return device; } @@ -447,14 +460,11 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(updatedDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException transactionException) { - String msg = "Error occurred while rolling back transaction for device: " + deviceId.getId(); - log.warn(msg, transactionException); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } } return status; @@ -544,15 +554,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(existingDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException e1) { - log.warn("Error occurred while roll back the update device info transaction : '" + - device.toString() + "'", e1); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while updating the " + deviceType + " device: '" + device.getDeviceIdentifier() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -572,12 +579,7 @@ public class DeviceTypeManager implements DeviceManager { } catch (DeviceTypeMgtPluginException e) { throw new DeviceManagementException("Error occurred while fetching all " + deviceType + " devices", e); } finally { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); - } catch (DeviceTypeMgtPluginException e) { - String msg = "Error occurred while closing the transaction to get all devices."; - log.warn(msg, e); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return devices; } @@ -600,15 +602,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().deleteDevice(existingDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException e1) { - log.warn("Error occurred while roll back the delete device info transaction : '" + - device.toString() + "'", e1); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while deleting the " + deviceType + " device: '" + device.getDeviceIdentifier() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java new file mode 100644 index 0000000000..e32c9e2d57 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java @@ -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 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); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java index e31149fafe..f6598ed5b1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java @@ -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; import org.apache.commons.logging.Log; 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.DeviceTypeMgtPluginException; @@ -31,7 +49,26 @@ public class DeviceTypeDAOHandler { Context ctx = new InitialContext(); dataSource = (DataSource) ctx.lookup(datasourceName); } 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); currentConnection.set(conn); } 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 { currentConnection.set(dataSource.getConnection()); } 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(); } - 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 { - Connection conn = currentConnection.get(); - 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"); - } - } + conn.commit(); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while committing the transaction", e); - } finally { - closeConnection(); + String msg = "Error occurred while committing the transaction."; + log.error(msg, e); } } - public void closeConnection() throws DeviceTypeMgtPluginException { - + public void closeConnection() { Connection con = currentConnection.get(); if (con != null) { try { con.close(); } 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(); } - 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 { - Connection conn = currentConnection.get(); - 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"); - } - } + conn.rollback(); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while rollback the transaction", e); - } finally { - closeConnection(); + String msg = "Error occurred while roll-backing the transaction."; + log.error(msg, e); } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java new file mode 100644 index 0000000000..b0603f43bf --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java @@ -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); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java index e29af46f12..36ae9b11dc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * 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; @@ -23,6 +40,8 @@ import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; 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.DeviceTypePluginExtensionServiceImpl; +import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; @@ -50,6 +69,8 @@ public class DeviceTypeExtensionServiceComponent { } ctx.getBundleContext() .registerService(DeviceTypeGeneratorService.class, new DeviceTypeGeneratorServiceImpl(), null); + ctx.getBundleContext().registerService(DeviceTypePluginExtensionService.class, + new DeviceTypePluginExtensionServiceImpl(), null); if (log.isDebugEnabled()) { log.debug("Device Type Extension Service Component successfully activated"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java new file mode 100644 index 0000000000..f91ed2e985 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java @@ -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; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index ca8fa6dbd8..c39e797bc2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -327,15 +327,6 @@ deviceModule = function () { 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 */ diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js index fbba497e09..2448a89f8f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js @@ -506,7 +506,7 @@ function loadDevices(searchType, searchParam) { $('#device-grid').datatables_extended_serverside_paging( null, - serviceURL, + "/api/device-mgt/v1.0/devices/", dataFilter, columns, fnCreatedRow, @@ -525,7 +525,8 @@ function loadDevices(searchType, searchParam) { }, { "placeholder": "Top-Device-Name-Search", - "searchKey": "namePattern" + "searchKey": "namePattern", + "groupId": groupId } ); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js index 94284ac016..692f692302 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js @@ -35,7 +35,7 @@ function onRequest(context) { var deviceType = request.getParameter("type"); var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.name = deviceType; serviceInvokers.XMLHttp.get( restAPIEndpoint, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js index 3fd2548a6f..320d630efe 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js @@ -210,7 +210,7 @@ $(document).ready(function () { }); deviceType.deviceTypeMetaDefinition.features = features; - var addRoleAPI = apiBasePath + "/admin/device-types"; + var addRoleAPI = apiBasePath + "/admin/device-types/" + deviceType.name; invokerUtil.put( addRoleAPI, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js index aff3ea3942..3f8e0a7b64 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js @@ -76,6 +76,9 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter searchParams[params.columns[i].data] = encodeURIComponent(params.columns[i].search.value); } if (options) { + if (options.groupId){ + searchParams["groupId"] = options.groupId; + } searchParams[options.searchKey] = encodeURIComponent(params.search.value); } params.filter = JSON.stringify(searchParams); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js index cf716ef35c..a431c66a71 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js @@ -42,7 +42,7 @@ function onRequest(context) { var displayData = {}; var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.deviceType = deviceType; displayData.tenantDomain = tenantDomain; serviceInvokers.XMLHttp.get( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js index 0f3563bad1..0f24173632 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js @@ -32,7 +32,7 @@ function onRequest(context) { return opts.inverse(this); }); var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.deviceType = deviceType; displayData.tenantDomain = tenantDomain; serviceInvokers.XMLHttp.get( diff --git a/components/device-mgt/pom.xml b/components/device-mgt/pom.xml index e73c1138bb..c17c4ab520 100644 --- a/components/device-mgt/pom.xml +++ b/components/device-mgt/pom.xml @@ -41,6 +41,7 @@ org.wso2.carbon.device.mgt.analytics.data.publisher org.wso2.carbon.device.mgt.url.printer org.wso2.carbon.device.mgt.analytics.wsproxy + io.entgra.device.mgt.ui diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/webapp/WEB-INF/web.xml b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/webapp/WEB-INF/web.xml index 066baa8fa6..f5ba0ae97a 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/webapp/WEB-INF/web.xml +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/webapp/WEB-INF/web.xml @@ -27,6 +27,10 @@ doAuthentication false + + basicAuth + true + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/pom.xml index 3fbc48358e..ff85f4c4fd 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/pom.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/pom.xml @@ -115,7 +115,35 @@ + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + package + + copy + + + + + org.wso2.carbon.devicemgt + io.entgra.device.mgt.ui + ${project.version} + war + true + + ${project.build.directory}/maven-shared-archive-resources/webapps + + entgra.war + **/* + + + + + + - diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/src/main/resources/p2.inf b/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/src/main/resources/p2.inf index 89445081ba..7d162718ff 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/src/main/resources/p2.inf +++ b/features/device-mgt/org.wso2.carbon.device.mgt.ui.feature/src/main/resources/p2.inf @@ -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.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}/jaggery-modules/utils/,target:${installFolder}/../../modules/utils,overwrite:true);\ \ No newline at end of file +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);\ diff --git a/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf b/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf index 968f20887a..6e7e6d01df 100644 --- a/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf +++ b/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf @@ -2,3 +2,4 @@ instructions.configure = \ 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/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);\