mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Added few fixes after testing and added default UI for device type management
This commit is contained in:
parent
6004ee7264
commit
dd1c2e4338
@ -257,7 +257,7 @@ public interface DeviceEventManagementService {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully fetched the event defintion.",
|
||||
response = EventAttributeList.class,
|
||||
response = DeviceTypeEvent.class,
|
||||
responseHeaders = {
|
||||
@ResponseHeader(
|
||||
name = "Content-Type",
|
||||
|
||||
@ -33,6 +33,7 @@ import org.wso2.carbon.apimgt.annotations.api.Scope;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
|
||||
|
||||
@ -81,6 +82,57 @@ import javax.ws.rs.core.Response;
|
||||
)
|
||||
public interface DeviceTypeManagementAdminService {
|
||||
|
||||
@GET
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Getting the Supported Device Type with Meta Definition",
|
||||
notes = "Get the list of device types supported by WSO2 IoT.",
|
||||
tags = "Device Type Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully fetched the list of supported device types.",
|
||||
response = DeviceTypeList.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 was last modified.\n" +
|
||||
"Used by caches, or in conditional requests."),
|
||||
}
|
||||
),
|
||||
@ApiResponse(
|
||||
code = 304,
|
||||
message =
|
||||
"Not Modified. \n Empty body because the client already has the latest version " +
|
||||
"of the requested resource.\n"),
|
||||
@ApiResponse(
|
||||
code = 406,
|
||||
message = "Not Acceptable.\n The requested media type is not supported"),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Server error occurred while fetching the " +
|
||||
"list of supported device types.",
|
||||
response = ErrorResponse.class)
|
||||
}
|
||||
)
|
||||
Response getDeviceTypes();
|
||||
|
||||
@POST
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
|
||||
@ -40,16 +40,17 @@ import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceEventManagementService
|
||||
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
|
||||
import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceCallbackHandler;
|
||||
import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub;
|
||||
import org.wso2.carbon.event.receiver.stub.types.EventMappingPropertyDto;
|
||||
import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceCallbackHandler;
|
||||
import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub;
|
||||
import org.wso2.carbon.event.receiver.stub.types.BasicInputAdapterPropertyDto;
|
||||
import org.wso2.carbon.event.receiver.stub.types.EventReceiverConfigurationDto;
|
||||
import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub;
|
||||
import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto;
|
||||
import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.analytics.datasource.commons.Record;
|
||||
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
@ -107,6 +108,8 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
private static final String DEFAULT_STREAM_VERSION = "1.0.0";
|
||||
private static final String DEFAULT_EVENT_STORE_NAME = "EVENT_STORE";
|
||||
private static final String DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE = "secured-websocket";
|
||||
private static final String OAUTH_MQTT_ADAPTER_TYPE = "oauth-mqtt";
|
||||
private static final String OAUTH_HTTP_ADAPTER_TYPE = "oauth-http";
|
||||
|
||||
private static KeyStore keyStore;
|
||||
private static KeyStore trustStore;
|
||||
@ -140,6 +143,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
public Response getDeviceTypeEventDefinition(@PathParam("type") String deviceType) {
|
||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
|
||||
EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null;
|
||||
try {
|
||||
if (deviceType == null ||
|
||||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
|
||||
@ -162,7 +166,18 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
, AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase())));
|
||||
}
|
||||
eventAttributeList.setList(attributes);
|
||||
return Response.ok().entity(eventAttributeList).build();
|
||||
DeviceTypeEvent deviceTypeEvent = new DeviceTypeEvent();
|
||||
deviceTypeEvent.setEventAttributeList(eventAttributeList);
|
||||
deviceTypeEvent.setTransportType(TransportType.HTTP);
|
||||
eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub();
|
||||
EventReceiverConfigurationDto eventReceiverConfigurationDto = eventReceiverAdminServiceStub
|
||||
.getActiveEventReceiverConfiguration(getReceiverName(deviceType, tenantDomain));
|
||||
String eventAdapterType = eventReceiverConfigurationDto.getFromAdapterConfigurationDto()
|
||||
.getEventAdapterType();
|
||||
if (OAUTH_MQTT_ADAPTER_TYPE.equals(eventAdapterType)) {
|
||||
deviceTypeEvent.setTransportType(TransportType.MQTT);
|
||||
}
|
||||
return Response.ok().entity(deviceTypeEvent).build();
|
||||
} catch (AxisFault e) {
|
||||
log.error("failed to retrieve event definitions for tenantDomain:" + tenantDomain, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
@ -180,6 +195,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
} finally {
|
||||
cleanup(eventStreamAdminServiceStub);
|
||||
cleanup(eventReceiverAdminServiceStub);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,8 +309,8 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
|
||||
tenantBasedEventReceiverAdminServiceStub = getEventReceiverAdminServiceStub();
|
||||
tenantBasedEventStreamAdminServiceStub = getEventStreamAdminServiceStub();
|
||||
eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION);
|
||||
eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName
|
||||
tenantBasedEventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION);
|
||||
tenantBasedEventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName
|
||||
, eventReceiverAdminServiceCallbackHandler);
|
||||
|
||||
}
|
||||
@ -323,6 +339,8 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
cleanup(eventReceiverAdminServiceStub);
|
||||
cleanup(eventReceiverAdminServiceStub);
|
||||
cleanup(eventStreamAdminServiceStub);
|
||||
cleanup(tenantBasedEventReceiverAdminServiceStub);
|
||||
cleanup(tenantBasedEventStreamAdminServiceStub);
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,7 +391,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
throws RemoteException, UserStoreException, JWTClientException {
|
||||
EventReceiverAdminServiceStub receiverAdminServiceStub = getEventReceiverAdminServiceStub();
|
||||
try {
|
||||
String adapterType = "oauth-mqtt";
|
||||
String adapterType = OAUTH_MQTT_ADAPTER_TYPE;
|
||||
BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[];
|
||||
if (transportType == TransportType.MQTT) {
|
||||
basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[4];
|
||||
@ -383,7 +401,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
|
||||
basicInputAdapterPropertyDtos[2] = getBasicInputAdapterPropertyDto("cleanSession", "true");
|
||||
basicInputAdapterPropertyDtos[3] = getBasicInputAdapterPropertyDto("clientId", generateUUID());
|
||||
} else {
|
||||
adapterType = "oauth-http";
|
||||
adapterType = OAUTH_HTTP_ADAPTER_TYPE;
|
||||
basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[1];
|
||||
basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("contentValidator", "iot-mqtt");
|
||||
}
|
||||
|
||||
@ -23,16 +23,21 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
|
||||
import org.wso2.carbon.device.mgt.extensions.device.type.template.HTTPDeviceTypeManagerService;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypeManagementAdminService;
|
||||
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/admin/device-types")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -41,10 +46,24 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
|
||||
|
||||
private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminServiceImpl.class);
|
||||
|
||||
@GET
|
||||
@Override
|
||||
public Response getDeviceTypes() {
|
||||
try {
|
||||
List<DeviceType> deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes();
|
||||
return Response.status(Response.Status.OK).entity(deviceTypes).build();
|
||||
} catch (DeviceManagementException e) {
|
||||
String msg = "Error occurred while fetching the list of device types.";
|
||||
log.error(msg, e);
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@POST
|
||||
public Response addDeviceType(DeviceType deviceType) {
|
||||
if (deviceType != null) {
|
||||
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
|
||||
try {
|
||||
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) != null) {
|
||||
String msg = "Device type already available, " + deviceType.getName();
|
||||
@ -67,7 +86,7 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
|
||||
@Override
|
||||
@PUT
|
||||
public Response updateDeviceType(DeviceType deviceType) {
|
||||
if (deviceType != null) {
|
||||
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
|
||||
try {
|
||||
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) == null) {
|
||||
String msg = "Device type does not exist, " + deviceType.getName();
|
||||
|
||||
@ -18,6 +18,15 @@ public class DeviceTypeMetaDefinition {
|
||||
private OperationMonitoringTaskConfig taskConfig;
|
||||
private InitialOperationConfig initialOperationConfig;
|
||||
private License license;
|
||||
private String description;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
|
||||
@ -22,7 +22,8 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceManagementServiceHolder;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
|
||||
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
|
||||
@ -50,8 +51,7 @@ import java.util.Map;
|
||||
|
||||
public class DeviceManagementPluginRepository implements DeviceManagerStartupListener {
|
||||
|
||||
private Map<DeviceTypeServiceIdentifier, DeviceManagementService> providers;
|
||||
private Map<DeviceTypeServiceIdentifier, Long> dynamicProviderTimestamp;
|
||||
private Map<DeviceTypeServiceIdentifier, DeviceManagementServiceHolder> providers;
|
||||
private boolean isInited;
|
||||
private static final Log log = LogFactory.getLog(DeviceManagementPluginRepository.class);
|
||||
private OperationManagerRepository operationManagerRepository;
|
||||
@ -59,8 +59,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
|
||||
public DeviceManagementPluginRepository() {
|
||||
this.operationManagerRepository = new OperationManagerRepository();
|
||||
providers = Collections.synchronizedMap(new HashMap<DeviceTypeServiceIdentifier, DeviceManagementService>());
|
||||
dynamicProviderTimestamp = Collections.synchronizedMap(new HashMap<DeviceTypeServiceIdentifier, Long>());
|
||||
providers = Collections.synchronizedMap(new HashMap<DeviceTypeServiceIdentifier, DeviceManagementServiceHolder>());
|
||||
DeviceManagementServiceComponent.registerStartupListener(this);
|
||||
}
|
||||
|
||||
@ -81,15 +80,23 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
provider.init();
|
||||
DeviceTypeMetaDefinition deviceTypeDefinition = null;
|
||||
if (provider instanceof DeviceTypeDefinitionProvider) {
|
||||
deviceTypeDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMeta();
|
||||
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(
|
||||
provider.getType().toLowerCase(), tenantId);
|
||||
DeviceManagementService existingProvider = providers.get(deviceTypeIdentifier);
|
||||
provider.getType());
|
||||
DeviceManagementServiceHolder existingProvider = providers.get(deviceTypeIdentifier);
|
||||
deviceTypeDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMeta();
|
||||
if (existingProvider != null && !(existingProvider.getDeviceManagementService()
|
||||
instanceof DeviceTypeDefinitionProvider)) {
|
||||
throw new DeviceManagementException("Definition of device type " + provider.getType()
|
||||
+ " is already available through sharing.");
|
||||
}
|
||||
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(provider.getType(), tenantId);
|
||||
existingProvider = providers.get(deviceTypeIdentifier);
|
||||
if (existingProvider != null) {
|
||||
removeDeviceManagementProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants, deviceTypeDefinition);
|
||||
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType,
|
||||
provider.getDeviceManager()
|
||||
@ -101,15 +108,13 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
throw new DeviceManagementException("Error occurred while adding device management provider '" +
|
||||
deviceType + "'", e);
|
||||
}
|
||||
DeviceManagementServiceHolder deviceManagementServiceHolder = new DeviceManagementServiceHolder(provider);
|
||||
if (isSharedWithAllTenants) {
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType);
|
||||
providers.put(deviceTypeIdentifier, provider);
|
||||
providers.put(deviceTypeIdentifier, deviceManagementServiceHolder);
|
||||
} else {
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType, tenantId);
|
||||
providers.put(deviceTypeIdentifier, provider);
|
||||
if (provider instanceof DeviceTypeDefinitionProvider) {
|
||||
dynamicProviderTimestamp.put(deviceTypeIdentifier, System.currentTimeMillis());
|
||||
}
|
||||
providers.put(deviceTypeIdentifier, deviceManagementServiceHolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,9 +131,6 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName, providerTenantId);
|
||||
providers.remove(deviceTypeIdentifier);
|
||||
if (provider instanceof DeviceTypeDefinitionProvider) {
|
||||
dynamicProviderTimestamp.remove(deviceTypeIdentifier);
|
||||
}
|
||||
}
|
||||
unregisterPushNotificationStrategy(deviceTypeIdentifier);
|
||||
unregisterMonitoringTask(provider);
|
||||
@ -148,30 +150,39 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
|
||||
public DeviceManagementService getDeviceManagementService(String type, int tenantId) {
|
||||
//Priority need to be given to the tenant before public.
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type.toLowerCase(), tenantId);
|
||||
DeviceManagementService provider = providers.get(deviceTypeIdentifier);
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type, tenantId);
|
||||
DeviceManagementServiceHolder provider = providers.get(deviceTypeIdentifier);
|
||||
if (provider == null) {
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type.toLowerCase());
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type);
|
||||
provider = providers.get(deviceTypeIdentifier);
|
||||
if (provider == null) {
|
||||
try {
|
||||
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type,tenantId);
|
||||
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type, tenantId);
|
||||
if (deviceType == null) {
|
||||
return null;
|
||||
}
|
||||
DeviceTypeMetaDefinition deviceTypeMetaDefinition = deviceType.getDeviceTypeMetaDefinition();
|
||||
if (deviceTypeMetaDefinition != null) {
|
||||
HTTPDeviceTypeManagerService deviceTypeManagerService = new HTTPDeviceTypeManagerService
|
||||
(type, deviceTypeMetaDefinition);
|
||||
addDeviceManagementProvider(deviceTypeManagerService);
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type, tenantId);
|
||||
provider = providers.get(deviceTypeIdentifier);
|
||||
}
|
||||
} catch (DeviceManagementException e) {
|
||||
log.error("Failing to retrieve the device type service for " + type, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (provider == null) {
|
||||
log.error("Device Type Definition not found for " + type);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// retrieves per tenant device type management service
|
||||
if (provider instanceof DeviceTypeDefinitionProvider) {
|
||||
if (provider.getDeviceManagementService() instanceof DeviceTypeDefinitionProvider) {
|
||||
//handle updates.
|
||||
long updatedTimestamp = dynamicProviderTimestamp.get(deviceTypeIdentifier);
|
||||
long updatedTimestamp = provider.getTimestamp();
|
||||
if (System.currentTimeMillis() - updatedTimestamp > DEFAULT_UPDATE_TIMESTAMP) {
|
||||
try {
|
||||
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type,tenantId);
|
||||
@ -179,7 +190,8 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
if (deviceTypeMetaDefinition != null) {
|
||||
Gson gson = new Gson();
|
||||
String dbStoredDefinition = gson.toJson(deviceTypeMetaDefinition);
|
||||
deviceTypeMetaDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMeta();
|
||||
deviceTypeMetaDefinition = ((DeviceTypeDefinitionProvider)
|
||||
provider.getDeviceManagementService()).getDeviceTypeMeta();
|
||||
String cachedDefinition = gson.toJson(deviceTypeMetaDefinition);
|
||||
if (!cachedDefinition.equals(dbStoredDefinition)) {
|
||||
HTTPDeviceTypeManagerService deviceTypeManagerService = new HTTPDeviceTypeManagerService
|
||||
@ -196,14 +208,14 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
}
|
||||
}
|
||||
}
|
||||
return provider;
|
||||
return provider.getDeviceManagementService();
|
||||
}
|
||||
|
||||
public Map<DeviceTypeServiceIdentifier, DeviceManagementService> getAllDeviceManagementServices(int tenantId) {
|
||||
Map<DeviceTypeServiceIdentifier, DeviceManagementService> tenantProviders = new HashMap<>();
|
||||
for (DeviceTypeServiceIdentifier identifier : providers.keySet()) {
|
||||
if (identifier.getTenantId() == tenantId || identifier.isSharedWithAllTenant()) {
|
||||
tenantProviders.put(identifier, providers.get(identifier));
|
||||
tenantProviders.put(identifier, providers.get(identifier).getDeviceManagementService());
|
||||
}
|
||||
}
|
||||
return tenantProviders;
|
||||
@ -289,10 +301,10 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
|
||||
public OperationManager getOperationManager(String deviceType, int tenantId) {
|
||||
//Priority need to be given to the tenant before public.
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType.toLowerCase(), tenantId);
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType, tenantId);
|
||||
OperationManager operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
|
||||
if (operationManager == null) {
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType.toLowerCase());
|
||||
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType);
|
||||
operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
|
||||
}
|
||||
return operationManager;
|
||||
@ -302,10 +314,11 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
public void notifyObserver() {
|
||||
String deviceTypeName;
|
||||
synchronized (providers) {
|
||||
for (DeviceManagementService provider : providers.values()) {
|
||||
for (DeviceManagementServiceHolder deviceManagementServiceHolder : providers.values()) {
|
||||
DeviceManagementService provider= deviceManagementServiceHolder.getDeviceManagementService();
|
||||
try {
|
||||
provider.init();
|
||||
deviceTypeName = provider.getType().toLowerCase();
|
||||
deviceTypeName = provider.getType();
|
||||
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
|
||||
int tenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
|
||||
DeviceTypeMetaDefinition deviceTypeDefinition = null;
|
||||
@ -313,8 +326,8 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
|
||||
deviceTypeDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMeta();
|
||||
|
||||
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(
|
||||
provider.getType().toLowerCase(), tenantId);
|
||||
DeviceManagementService existingProvider = providers.get(deviceTypeIdentifier);
|
||||
provider.getType(), tenantId);
|
||||
DeviceManagementServiceHolder existingProvider = providers.get(deviceTypeIdentifier);
|
||||
if (existingProvider == null) {
|
||||
removeDeviceManagementProvider(provider);
|
||||
}
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.core.dto;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
|
||||
|
||||
/**
|
||||
* This holds the information of the registered device management service against the device type
|
||||
* definition loaded timestamp. This is used to handle device type update scenario.
|
||||
*/
|
||||
public class DeviceManagementServiceHolder {
|
||||
|
||||
private DeviceManagementService deviceManagementService;
|
||||
private long timestamp;
|
||||
|
||||
public DeviceManagementServiceHolder(DeviceManagementService deviceManagementService) {
|
||||
this.deviceManagementService = deviceManagementService;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public DeviceManagementService getDeviceManagementService() {
|
||||
return deviceManagementService;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.common;
|
||||
package org.wso2.carbon.device.mgt.core.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.core.operation.mgt;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -343,4 +343,10 @@ public interface DeviceManagementProviderService {
|
||||
* @throws DeviceManagementException
|
||||
*/
|
||||
DeviceType getDeviceType(String deviceType) throws DeviceManagementException;
|
||||
|
||||
/**
|
||||
* This retrieves the device type info for the given type
|
||||
* @throws DeviceManagementException
|
||||
*/
|
||||
List<DeviceType> getDeviceTypes() throws DeviceManagementException;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManager;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||
import org.wso2.carbon.device.mgt.common.FeatureManager;
|
||||
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
|
||||
@ -2174,7 +2174,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
||||
|
||||
@Override
|
||||
public DeviceType getDeviceType(String deviceType) throws DeviceManagementException {
|
||||
HashMap<Integer, Device> deviceHashMap;
|
||||
try {
|
||||
DeviceManagementDAOFactory.openConnection();
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
@ -2187,4 +2186,20 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
||||
DeviceManagementDAOFactory.closeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceType> getDeviceTypes() throws DeviceManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
try {
|
||||
DeviceManagementDAOFactory.openConnection();
|
||||
return deviceTypeDAO.getDeviceTypes(tenantId);
|
||||
} catch (DeviceManagementDAOException e) {
|
||||
throw new DeviceManagementException("Error occurred while obtaining the device types for tenant "
|
||||
+ tenantId, e);
|
||||
} catch (SQLException e) {
|
||||
throw new DeviceManagementException("Error occurred while opening a connection to the data source", e);
|
||||
} finally {
|
||||
DeviceManagementDAOFactory.closeConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
|
||||
ID INT AUTO_INCREMENT NOT NULL,
|
||||
NAME VARCHAR(300) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) NULL DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
@ -72,7 +72,8 @@ public class DeviceTypeManagerService implements DeviceManagementService {
|
||||
this.setOperationMonitoringConfig(deviceTypeConfiguration);
|
||||
this.initialOperationConfig = new InitialOperationConfig();
|
||||
this.setInitialOperationConfig(deviceTypeConfiguration);
|
||||
if (deviceTypeConfiguration.getPolicyMonitoring() != null ) {
|
||||
if (deviceTypeConfiguration.getPolicyMonitoring() != null
|
||||
&& deviceTypeConfiguration.getPolicyMonitoring().isEnabled()) {
|
||||
this.policyMonitoringManager = new DefaultPolicyMonitoringManager();
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,17 +81,19 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple
|
||||
for (Feature feature : deviceTypeMetaDefinition.getFeatures()) {
|
||||
org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature configFeature = new org
|
||||
.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature();
|
||||
configFeature.setCode(feature.getCode());
|
||||
configFeature.setDescription(feature.getDescription());
|
||||
configFeature.setName(feature.getName());
|
||||
if (feature.getMetadataEntries() != null && feature.getMetadataEntries().size() > 0) {
|
||||
List<String> metaValues = new ArrayList<>();
|
||||
for (Feature.MetadataEntry metadataEntry : feature.getMetadataEntries()) {
|
||||
metadataEntry.getValue();
|
||||
if (feature.getCode() != null && feature.getName() != null) {
|
||||
configFeature.setCode(feature.getCode());
|
||||
configFeature.setDescription(feature.getDescription());
|
||||
configFeature.setName(feature.getName());
|
||||
if (feature.getMetadataEntries() != null && feature.getMetadataEntries().size() > 0) {
|
||||
List<String> metaValues = new ArrayList<>();
|
||||
for (Feature.MetadataEntry metadataEntry : feature.getMetadataEntries()) {
|
||||
metadataEntry.getValue();
|
||||
}
|
||||
configFeature.setMetaData(metaValues);
|
||||
}
|
||||
configFeature.setMetaData(metaValues);
|
||||
featureList.add(configFeature);
|
||||
}
|
||||
featureList.add(configFeature);
|
||||
}
|
||||
features.addFeatures(featureList);
|
||||
deviceTypeConfiguration.setFeatures(features);
|
||||
@ -117,7 +119,8 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple
|
||||
if (pushNotificationConfig != null) {
|
||||
PushNotificationProvider pushNotificationProvider = new PushNotificationProvider();
|
||||
pushNotificationProvider.setType(pushNotificationConfig.getType());
|
||||
pushNotificationProvider.setScheduled(pushNotificationConfig.isScheduled());
|
||||
//default schedule value will be true.
|
||||
pushNotificationProvider.setScheduled(true);
|
||||
if (pushNotificationConfig.getProperties() != null &&
|
||||
pushNotificationConfig.getProperties().size() > 0) {
|
||||
ConfigProperties configProperties = new ConfigProperties();
|
||||
|
||||
@ -178,7 +178,8 @@
|
||||
"perm:admin",
|
||||
"perm:devicetype:deployment",
|
||||
"perm:device-types:events",
|
||||
"perm:device-types:events:view"
|
||||
"perm:device-types:events:view",
|
||||
"perm:admin:device-type"
|
||||
],
|
||||
"isOAuthEnabled": true,
|
||||
"backendRestEndpoints": {
|
||||
|
||||
@ -268,6 +268,34 @@ deviceModule = function () {
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getDeviceTypeCount = function () {
|
||||
var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
if (carbonUser) {
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var uiPermissions = userModule.getUIPermissions();
|
||||
var url;
|
||||
if (uiPermissions.LIST_OWN_DEVICES) {
|
||||
url = devicemgtProps["httpsURL"] +
|
||||
devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types";
|
||||
} else {
|
||||
log.error("Access denied for user: " + carbonUser.username);
|
||||
return -1;
|
||||
}
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
return parse(responsePayload["responseText"])["count"];
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload["responseText"]);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getDeviceTypes = function () {
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types";
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
|
||||
@ -191,6 +191,40 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if permissions.IS_ADMIN}}
|
||||
<div class="col-md-3 wr-stats-board">
|
||||
<div class="wr-stats-board-tile">
|
||||
<div class="tile-name">Device Types</div>
|
||||
<div>
|
||||
<div class="tile-icon"><i class="fw fw-devices"></i></div>
|
||||
<div class="tile-stats">
|
||||
<span id="device-types-count">{{deviceTypeCount}}</span>
|
||||
<span class="tile-stats-free">
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
{{#if deviceTypeCount}}
|
||||
<a href="{{@app.context}}/device-types">
|
||||
<span class="fw-stack">
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
<i class="fw fw-view fw-stack-1x"></i>
|
||||
</span>
|
||||
View
|
||||
</a>
|
||||
{{/if}}
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-type/add">
|
||||
<span class="fw-stack">
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
<i class="fw fw-add fw-stack-1x"></i>
|
||||
</span>
|
||||
Add
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
<h1 class="page-sub-title">
|
||||
Permitted None
|
||||
|
||||
@ -44,6 +44,7 @@ function onRequest(context) {
|
||||
viewModel.groupCount = groupModule.getGroupCount();
|
||||
viewModel.userCount = userModule.getUsersCount();
|
||||
viewModel.policyCount = policyModule.getPoliciesCount();
|
||||
viewModel.deviceTypeCount = deviceModule.getDeviceTypeCount();
|
||||
viewModel.isCloud = devicemgtProps.isCloud;
|
||||
if (devicemgtProps.isCloud) {
|
||||
viewModel.roleCount = userModule.getFilteredRoles("devicemgt").content.count;
|
||||
|
||||
@ -0,0 +1,226 @@
|
||||
{{!
|
||||
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.
|
||||
}}
|
||||
{{unit "cdmf.unit.ui.title" pageTitle="Device Type Management"}}
|
||||
|
||||
{{#zone "topCss"}}
|
||||
{{css "css/devicetype.css"}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "breadcrumbs"}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/">
|
||||
<i class="icon fw fw-home"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-types">
|
||||
Device Types
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-type/add">
|
||||
Add
|
||||
</a>
|
||||
</li>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{#if canManage}}
|
||||
<!-- content/body -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- content -->
|
||||
<div id="devicetype-create-form" class="container col-centered wr-content">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">Create Device Type</p>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="wr-steps">
|
||||
<div class="col-md-6 col-xs-6">
|
||||
<div class="itm-wiz itm-wiz-current" data-step="policy-platform">
|
||||
<div class="wiz-no">1</div>
|
||||
<div class="wiz-lbl hidden-xs"><span>Create A Device Type</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xs-6">
|
||||
<div class="itm-wiz" data-step="policy-profile">
|
||||
<div class="wiz-no">2</div>
|
||||
<div class="wiz-lbl hidden-xs"><span>Create Device Event</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<br class="c-both"/>
|
||||
</div>
|
||||
<br/><br/>
|
||||
<hr/>
|
||||
<div id="devicetype-create-error-msg" class="alert alert-danger hidden" role="alert">
|
||||
<i class="icon fw fw-error"></i><span></span>
|
||||
</div>
|
||||
<label class="wr-input-label">
|
||||
Device Type Name *
|
||||
</label>
|
||||
<br>
|
||||
<input aria-describedby="basic-addon1" type="text" id="deviceTypeName"
|
||||
data-error-msg="invalid device type name" class="form-control"/>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Device Type Description *
|
||||
</label>
|
||||
<br>
|
||||
<textarea aria-describedby="basic-addon1" type="text" id="deviceTypeDescription"
|
||||
data-error-msg="invalid device type description"
|
||||
class="form-control" rows="3" cols="70"></textarea>
|
||||
|
||||
<label class="wr-input-label">Push Notification Transport</label>
|
||||
<div class="wr-input-control">
|
||||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<select id="pushNotification" class="form-control select">
|
||||
<option>NONE</option>
|
||||
<option>MQTT</option>
|
||||
<option>FCM</option>
|
||||
<option>APNS</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Features
|
||||
</label>
|
||||
<br>
|
||||
|
||||
<div class="form-group feature_field_wrapper">
|
||||
<div class="dontfloat" name="deviceFeature">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" id="feature-name" placeholder="name"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" class="form-control" id="feature-code" placeholder="code"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<textarea aria-describedby="basic-addon1" type="text" id="feature-description"
|
||||
placeholder="description"
|
||||
data-error-msg="invalid feature description"
|
||||
class="form-control" rows="1" cols="30"></textarea>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_feature_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
<label class="wr-input-label">
|
||||
Device Attributes
|
||||
</label>
|
||||
<br>
|
||||
|
||||
<div class="form-group attribute_field_wrapper">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="attribute[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden-div">
|
||||
<div id="add-attribute-field" name="add-attribute-field">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="attribute[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Initial Operation(Feature Code, Trigger operation when device enrolls)
|
||||
</label>
|
||||
<br>
|
||||
|
||||
<div class="form-group operation_field_wrapper">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="operation[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_operation_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="hidden-div">
|
||||
<div id="add-operation-field" name="add-operation-field">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="operation[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_operation_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="wr-input-label">Claimable</label>
|
||||
<input aria-describedby="basic-addon1" type="checkbox" id="deviceClaimable"/>
|
||||
</br>
|
||||
|
||||
<label class="wr-input-label">Policy Monitoring</label>
|
||||
<input aria-describedby="basic-addon1" type="checkbox" id="policyMonitoring"/>
|
||||
</br>
|
||||
|
||||
|
||||
<span class="roleNameError hidden glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
<label class="error roleNameEmpty hidden" for="summary">
|
||||
Device Type Name is required, should be in minimum 3 characters long and not include any
|
||||
whitespaces or "@" character or "/" character.
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br>
|
||||
<button id="add-devicetype-btn" class="wr-btn">Add Device Type</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="devicetype-created-msg" class="container col-centered wr-content hidden">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">Devicetype was added successfully.</p>
|
||||
<b>"View Device Type List"</b> to complete the process and go back to the devie type list.
|
||||
<hr/>
|
||||
<button class="wr-btn" onclick="window.location.href='{{@app.context}}/device-types'">
|
||||
View Device Type List
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content -->
|
||||
<div id="app-context" data-app-context="{{@app.context}}" class="hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content/body -->
|
||||
{{else}}
|
||||
<h1 class="page-sub-title">
|
||||
Permission Denied
|
||||
</h1>
|
||||
<br>
|
||||
You not authorized to create device type.
|
||||
<br>
|
||||
{{/if}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "js/bottomJs.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var displayData = {};
|
||||
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/device-type")) {
|
||||
displayData.canManage = true;
|
||||
}
|
||||
|
||||
return displayData;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/device-type/add",
|
||||
"layout": "cdmf.layout.default"
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
.dontfloat {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.hidden-div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if provided input is valid against RegEx input.
|
||||
*
|
||||
* @param regExp Regular expression
|
||||
* @param inputString Input string to check
|
||||
* @returns {boolean} Returns true if input matches RegEx
|
||||
*/
|
||||
function inputIsValid(regExp, inputString) {
|
||||
regExp = new RegExp(regExp);
|
||||
return regExp.test(inputString);
|
||||
}
|
||||
|
||||
var validateInline = {};
|
||||
var clearInline = {};
|
||||
|
||||
var apiBasePath = "/api/device-mgt/v1.0";
|
||||
|
||||
|
||||
var enableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).addClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).removeClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).removeClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
var disableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).removeClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).addClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).addClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function formatRepo(user) {
|
||||
if (user.loading) {
|
||||
return user.text
|
||||
}
|
||||
if (!user.username) {
|
||||
return;
|
||||
}
|
||||
var markup = '<div class="clearfix">' +
|
||||
'<div class="col-sm-8">' +
|
||||
'<div class="clearfix">' +
|
||||
'<div class="col-sm-4">' + user.username + '</div>';
|
||||
if (user.name || user.name != undefined) {
|
||||
markup += '<div class="col-sm-8"> ( ' + user.name + ' )</div>';
|
||||
}
|
||||
markup += '</div></div></div>';
|
||||
return markup;
|
||||
}
|
||||
|
||||
function formatRepoSelection(user) {
|
||||
return user.username || user.text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var appContext = $("#app-context").data("app-context");
|
||||
|
||||
var maxField = 100; //Input fields increment limitation
|
||||
var addButton = $('.add_button'); //Add button selector
|
||||
var wrapper = $('.attribute_field_wrapper'); //Input field wrapper
|
||||
var fieldHTML = $('#add-attribute-field').html(); //New input field html
|
||||
$(addButton).click(function(){ //Once add button is clicked
|
||||
$(wrapper).append(fieldHTML); // Add field html
|
||||
});
|
||||
$(wrapper).on('click', '.remove_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove();
|
||||
});
|
||||
|
||||
var addOperationButton = $('.add_operation_button'); //Add button selector
|
||||
var operationWrapper = $('.operation_field_wrapper'); //Input field wrapper
|
||||
var operationFieldHTML = $('#add-operation-field').html(); //New input field html
|
||||
$(addOperationButton).click(function(){ //Once add button is clicked
|
||||
$(operationWrapper).append(operationFieldHTML); // Add field html
|
||||
});
|
||||
$(operationWrapper).on('click', '.remove_operation_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove();
|
||||
});
|
||||
|
||||
|
||||
var addFeatureButton = $('.add_feature_button'); //Add button selector
|
||||
var featureWrapper = $('.feature_field_wrapper'); //Input field wrapper
|
||||
$(addFeatureButton).click(function(){ //Once add button is clicked
|
||||
var featureFieldHtml = ' <div class="dontfloat" name ="deviceFeature"> <div class="col-xs-3"> <input type="text"' +
|
||||
' class="form-control" id="feature-name" placeholder="name"/> </div> <div class="col-xs-4"> ' +
|
||||
'<input type="text" class="form-control" id="feature-code" placeholder="code"/> </div> ' +
|
||||
'<div class="col-xs-4"> <textarea aria-describedby="basic-addon1" type="text" ' +
|
||||
'id="feature-description" placeholder="description"data-error-msg="invalid ' +
|
||||
'feature description"class="form-control" rows="1" cols="30"></textarea> </div> ' +
|
||||
'<button type="button" class="btn btn-default remove_feature_button"><i class="fa fa-minus"></i></button> </div>'
|
||||
$(featureWrapper).append(featureFieldHtml); // Add field html
|
||||
});
|
||||
$(featureWrapper).on('click', '.remove_feature_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove(); //Remove field html
|
||||
});
|
||||
|
||||
/**
|
||||
* Following click function would execute
|
||||
* when a user clicks on "Add Device type" button.
|
||||
*/
|
||||
$("button#add-devicetype-btn").click(function () {
|
||||
|
||||
var errorMsgWrapper = "#devicetype-create-error-msg";
|
||||
var errorMsg = "#devicetype-create-error-msg span";
|
||||
var deviceType = {};
|
||||
var deviceTypeName = $("#deviceTypeName").val();
|
||||
var deviceTypeDescription = $("#deviceTypeDescription").val();
|
||||
if (!deviceTypeName || deviceTypeName.trim() == "" ) {
|
||||
$(errorMsg).text("Device Type Name Cannot be empty.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!deviceTypeDescription || deviceTypeDescription.trim() == "" ) {
|
||||
$(errorMsg).text("Device Type Description Cannot be empty.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
return
|
||||
}
|
||||
|
||||
deviceType.name = deviceTypeName.trim();
|
||||
deviceType.deviceTypeMetaDefinition = {}
|
||||
deviceType.deviceTypeMetaDefinition.description = deviceTypeDescription.trim();
|
||||
|
||||
var pushNotification = $("#pushNotification").val();
|
||||
if (pushNotification != "NONE") {
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig = {};
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig.scheduled = true;
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig.type = pushNotification;
|
||||
}
|
||||
|
||||
var propertyValues = [];
|
||||
$('input[name^="attribute"]').each(function() {
|
||||
var propertyValue = $(this).val();
|
||||
if (propertyValue.trim() != "") {
|
||||
propertyValues.push(propertyValue.trim());
|
||||
}
|
||||
});
|
||||
deviceType.deviceTypeMetaDefinition.properties = propertyValues;
|
||||
|
||||
var operationValues = [];
|
||||
$('input[name^="operation"]').each(function() {
|
||||
var operationValue = $(this).val();
|
||||
if (operationValue.trim() != "") {
|
||||
operationValues.push(operationValue.trim());
|
||||
}
|
||||
});
|
||||
if (operationValues.length > 0) {
|
||||
deviceType.deviceTypeMetaDefinition.initialOperationConfig = {};
|
||||
deviceType.deviceTypeMetaDefinition.initialOperationConfig.operations = operationValues;
|
||||
}
|
||||
|
||||
deviceType.deviceTypeMetaDefinition.policyMonitoringEnabled = $("#policyMonitoring").is(":checked");
|
||||
deviceType.deviceTypeMetaDefinition.claimable = $("#deviceClaimable").is(":checked");;
|
||||
|
||||
var features = [];
|
||||
$('div[name^="deviceFeature"]').each(function() {
|
||||
var featureName = $(this).find("#feature-name").val();
|
||||
var featureCode = $(this).find("#feature-code").val();
|
||||
if (featureName && featureName.trim() != "" && featureCode && featureCode.trim() != "") {
|
||||
var feature = {};
|
||||
feature.name = featureName.trim();
|
||||
feature.code = featureCode.trim();
|
||||
feature.description = $("#feature-description").val();
|
||||
features.push(feature);
|
||||
}
|
||||
});
|
||||
deviceType.deviceTypeMetaDefinition.features = features;
|
||||
|
||||
var addRoleAPI = apiBasePath + "/admin/device-types";
|
||||
|
||||
invokerUtil.post(
|
||||
addRoleAPI,
|
||||
deviceType,
|
||||
function (data, textStatus, jqXHR) {
|
||||
if (jqXHR.status == 200) {
|
||||
window.location.href = appContext + "/device-type/edit-event?type=" +
|
||||
encodeURIComponent(deviceTypeName);
|
||||
}
|
||||
},
|
||||
function (jqXHR) {
|
||||
if (jqXHR.status == 500) {
|
||||
$(errorMsg).text("Unexpected error.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
|
||||
if (jqXHR.status == 409) {
|
||||
$(errorMsg).text("Device type already exists");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
@ -0,0 +1,273 @@
|
||||
{{!
|
||||
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.
|
||||
}}
|
||||
{{unit "cdmf.unit.ui.title" pageTitle="Device Type Management"}}
|
||||
|
||||
{{#zone "topCss"}}
|
||||
{{css "css/devicetype.css"}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "breadcrumbs"}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/">
|
||||
<i class="icon fw fw-home"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-types">
|
||||
Device Types
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-type/edit?type={{name}}">
|
||||
Edit
|
||||
</a>
|
||||
</li>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{#if canManage}}
|
||||
<!-- content/body -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- content -->
|
||||
<div id="devicetype-create-form" class="container col-centered wr-content">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">{{name}}</p>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div id="devicetype-create-error-msg" class="alert alert-danger hidden" role="alert">
|
||||
<i class="icon fw fw-error"></i><span></span>
|
||||
</div>
|
||||
<br>
|
||||
<input aria-describedby="basic-addon1" type="text" id="deviceTypeName"
|
||||
data-error-msg="invalid device type name" class="form-control hidden-input" value="{{name}}"/>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Device Type Description *
|
||||
</label>
|
||||
<br>
|
||||
<textarea aria-describedby="basic-addon1" type="text" id="deviceTypeDescription"
|
||||
data-error-msg="invalid device type description"
|
||||
class="form-control" rows="3" cols="70">{{type.deviceTypeMetaDefinition.description}}</textarea>
|
||||
|
||||
<label class="wr-input-label">Push Notification Transport</label>
|
||||
<div class="wr-input-control">
|
||||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<select id="pushNotification" class="form-control select">
|
||||
{{#if type.deviceTypeMetaDefinition.pushNotificationConfig}}
|
||||
<option>NONE</option>
|
||||
{{#if_eq type.deviceTypeMetaDefinition.pushNotificationConfig.type "MQTT"}}
|
||||
<option selected>MQTT</option>
|
||||
<option>FCM</option>
|
||||
<option>APNS</option>
|
||||
{{/if_eq}}
|
||||
{{#if_eq type.deviceTypeMetaDefinition.pushNotificationConfig.type "FCM"}}
|
||||
<option>MQTT</option>
|
||||
<option selected>FCM</option>
|
||||
<option>APNS</option>
|
||||
{{/if_eq}}
|
||||
{{#if_eq type.deviceTypeMetaDefinition.pushNotificationConfig.type "APNS"}}
|
||||
<option>MQTT</option>
|
||||
<option>FCM</option>
|
||||
<option selected>APNS</option>
|
||||
{{/if_eq}}
|
||||
{{else}}
|
||||
<option selected>NONE</option>
|
||||
<option>MQTT</option>
|
||||
<option>FCM</option>
|
||||
<option>APNS</option>
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Features
|
||||
</label>
|
||||
<br>
|
||||
<div class="form-group feature_field_wrapper">
|
||||
{{#if type.deviceTypeMetaDefinition.features}}
|
||||
{{#each type.deviceTypeMetaDefinition.features}}
|
||||
<div class="dontfloat" name ="deviceFeature">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" id="feature-name" placeholder="name" value="{{this.name}}"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" class="form-control" id="feature-code" placeholder="code" value="{{this.code}}"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<textarea aria-describedby="basic-addon1" type="text" id="feature-description"
|
||||
placeholder="description"data-error-msg="invalid feature description"class="form-control" rows="1" cols="30">
|
||||
{{this.description}}
|
||||
</textarea>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_feature_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="dontfloat" name="deviceFeature">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" id="feature-name" placeholder="name"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<input type="text" class="form-control" id="feature-code" placeholder="code"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<textarea aria-describedby="basic-addon1" type="text" id="feature-description"
|
||||
placeholder="description"
|
||||
data-error-msg="invalid feature description"
|
||||
class="form-control" rows="1" cols="30"></textarea>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_feature_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<label class="wr-input-label">
|
||||
Device Attributes
|
||||
</label>
|
||||
<br>
|
||||
<div class="form-group attribute_field_wrapper">
|
||||
{{#if type.deviceTypeMetaDefinition.properties}}
|
||||
{{#each type.deviceTypeMetaDefinition.properties}}
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="attribute[]" value="{{this}}" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="attribute[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden-div">
|
||||
<div id="add-attribute-field" name="add-attribute-field">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="attribute[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Initial Operation(Feature Code, Trigger operation when device enrolls)
|
||||
</label>
|
||||
<br>
|
||||
|
||||
<div class="form-group operation_field_wrapper">
|
||||
{{#if type.deviceTypeMetaDefinition.initialOperationConfig}}
|
||||
{{#each type.deviceTypeMetaDefinition.initialOperationConfig.operations}}
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="operation[]" value="{{this}}"/>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_operation_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="operation[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_operation_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="hidden-div">
|
||||
<div id="add-operation-field" name="add-operation-field">
|
||||
<div class="dontfloat">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" name="operation[]" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_operation_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="wr-input-label">Claimable</label>
|
||||
<input aria-describedby="basic-addon1" type="checkbox" id="deviceClaimable"
|
||||
{{#if type.deviceTypeMetaDefinition.claimable}}
|
||||
checked
|
||||
{{/if}}/>
|
||||
</br>
|
||||
|
||||
<label class="wr-input-label">Policy Monitoring</label>
|
||||
<input aria-describedby="basic-addon1" type="checkbox" id="policyMonitoring"
|
||||
{{#if type.deviceTypeMetaDefinition.policyMonitoringEnabled}}
|
||||
checked
|
||||
{{/if}}/>
|
||||
</br>
|
||||
|
||||
|
||||
<span class="roleNameError hidden glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
<label class="error roleNameEmpty hidden" for="summary">
|
||||
Device Type Name is required, should be in minimum 3 characters long and not include any
|
||||
whitespaces or "@" character or "/" character.
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br>
|
||||
<button id="add-devicetype-btn" class="wr-btn">Update</button>
|
||||
<div id="devicetype-create-success-msg" class="alert hidden" role="alert">
|
||||
<i class="icon fw fw-success"></i><span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="devicetype-created-msg" class="container col-centered wr-content hidden">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">Devicetype was added successfully.</p>
|
||||
<b>"View Device Type List"</b> to complete the process and go back to the devie type list.
|
||||
<hr/>
|
||||
<button class="wr-btn" onclick="window.location.href='{{@app.context}}/device-types'">
|
||||
View Device Type List
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content -->
|
||||
<div id="app-context" data-app-context="{{@app.context}}" class="hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content/body -->
|
||||
{{else}}
|
||||
<h1 class="page-sub-title">
|
||||
Permission Denied
|
||||
</h1>
|
||||
<br>
|
||||
You not authorized to edit device type.
|
||||
<br>
|
||||
{{/if}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "js/bottomJs.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var displayData = {};
|
||||
|
||||
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/device-type")) {
|
||||
displayData.canManage = true;
|
||||
}
|
||||
context.handlebars.registerHelper('if_eq', function(a, b, opts) {
|
||||
if(a == b) // Or === depending on your needs
|
||||
return opts.fn(this);
|
||||
else
|
||||
return opts.inverse(this);
|
||||
});
|
||||
|
||||
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/all/" + deviceType;
|
||||
displayData.name = deviceType;
|
||||
serviceInvokers.XMLHttp.get(
|
||||
restAPIEndpoint,
|
||||
function (restAPIResponse) {
|
||||
if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) {
|
||||
var typeData = parse(restAPIResponse["responseText"]);
|
||||
displayData.type = typeData;
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return displayData;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/device-type/edit",
|
||||
"layout": "cdmf.layout.default"
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
.dontfloat {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.hidden-div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
display: none;
|
||||
}
|
||||
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if provided input is valid against RegEx input.
|
||||
*
|
||||
* @param regExp Regular expression
|
||||
* @param inputString Input string to check
|
||||
* @returns {boolean} Returns true if input matches RegEx
|
||||
*/
|
||||
function inputIsValid(regExp, inputString) {
|
||||
regExp = new RegExp(regExp);
|
||||
return regExp.test(inputString);
|
||||
}
|
||||
|
||||
var validateInline = {};
|
||||
var clearInline = {};
|
||||
|
||||
var apiBasePath = "/api/device-mgt/v1.0";
|
||||
var domain = $("#domain").val();
|
||||
|
||||
|
||||
var enableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).addClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).removeClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).removeClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
var disableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).removeClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).addClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).addClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
function formatRepo(user) {
|
||||
if (user.loading) {
|
||||
return user.text
|
||||
}
|
||||
if (!user.username) {
|
||||
return;
|
||||
}
|
||||
var markup = '<div class="clearfix">' +
|
||||
'<div class="col-sm-8">' +
|
||||
'<div class="clearfix">' +
|
||||
'<div class="col-sm-4">' + user.username + '</div>';
|
||||
if (user.name || user.name != undefined) {
|
||||
markup += '<div class="col-sm-8"> ( ' + user.name + ' )</div>';
|
||||
}
|
||||
markup += '</div></div></div>';
|
||||
return markup;
|
||||
}
|
||||
|
||||
function formatRepoSelection(user) {
|
||||
return user.username || user.text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var appContext = $("#app-context").data("app-context");
|
||||
|
||||
var addButton = $('.add_button'); //Add button selector
|
||||
var wrapper = $('.attribute_field_wrapper'); //Input field wrapper
|
||||
var fieldHTML = $('#add-attribute-field').html(); //New input field html
|
||||
$(addButton).click(function(){ //Once add button is clicked
|
||||
$(wrapper).append(fieldHTML); // Add field html
|
||||
});
|
||||
$(wrapper).on('click', '.remove_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove(); //Remove field html
|
||||
});
|
||||
|
||||
var addOperationButton = $('.add_operation_button'); //Add button selector
|
||||
var operationWrapper = $('.operation_field_wrapper'); //Input field wrapper
|
||||
var operationFieldHTML = $('#add-operation-field').html(); //New input field html
|
||||
$(addOperationButton).click(function(){ //Once add button is clicked
|
||||
$(operationWrapper).append(operationFieldHTML); // Add field html
|
||||
});
|
||||
$(operationWrapper).on('click', '.remove_operation_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove();
|
||||
});
|
||||
|
||||
|
||||
var addFeatureButton = $('.add_feature_button'); //Add button selector
|
||||
var featureWrapper = $('.feature_field_wrapper'); //Input field wrapper
|
||||
$(addFeatureButton).click(function(){ //Once add button is clicked
|
||||
var featureFieldHtml = ' <div class="dontfloat" name ="deviceFeature"> <div class="col-xs-3"> <input type="text"' +
|
||||
' class="form-control" id="feature-name" placeholder="name"/> </div> <div class="col-xs-4"> ' +
|
||||
'<input type="text" class="form-control" id="feature-code" placeholder="code"/> </div> ' +
|
||||
'<div class="col-xs-4"> <textarea aria-describedby="basic-addon1" type="text" ' +
|
||||
'id="feature-description" placeholder="description"data-error-msg="invalid ' +
|
||||
'feature description"class="form-control" rows="1" cols="30"></textarea> </div> ' +
|
||||
'<button type="button" class="btn btn-default remove_feature_button"><i class="fa fa-minus"></i></button> </div>'
|
||||
$(featureWrapper).append(featureFieldHtml); // Add field html
|
||||
|
||||
});
|
||||
$(featureWrapper).on('click', '.remove_feature_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove(); //Remove field html
|
||||
op--; //Decrement field counter
|
||||
});
|
||||
|
||||
/**
|
||||
* Following click function would execute
|
||||
* when a user clicks on "Add Device type" button.
|
||||
*/
|
||||
$("button#add-devicetype-btn").click(function () {
|
||||
|
||||
var errorMsgWrapper = "#devicetype-create-error-msg";
|
||||
var errorMsg = "#devicetype-create-error-msg span";
|
||||
var successMsgWrapper = "#devicetype-create-success-msg";
|
||||
var successMsg = "#devicetype-create-success-msg span";
|
||||
var deviceType = {};
|
||||
var deviceTypeName = $("#deviceTypeName").val();
|
||||
var deviceTypeDescription = $("#deviceTypeDescription").val();
|
||||
if (!deviceTypeName || deviceTypeName.trim() == "" ) {
|
||||
$(errorMsg).text("Device Type Name Cannot be empty.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!deviceTypeDescription || deviceTypeDescription.trim() == "" ) {
|
||||
$(errorMsg).text("Device Type Description Cannot be empty.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
return
|
||||
}
|
||||
|
||||
deviceType.name = deviceTypeName.trim();
|
||||
deviceType.deviceTypeMetaDefinition = {}
|
||||
deviceType.deviceTypeMetaDefinition.description = deviceTypeDescription.trim();
|
||||
|
||||
var pushNotification = $("#pushNotification").val();
|
||||
if (pushNotification != "NONE") {
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig = {};
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig.scheduled = true;
|
||||
deviceType.deviceTypeMetaDefinition.pushNotificationConfig.type = pushNotification;
|
||||
}
|
||||
|
||||
var propertyValues = [];
|
||||
$('input[name^="attribute"]').each(function() {
|
||||
var propertyValue = $(this).val();
|
||||
if (propertyValue.trim() != "") {
|
||||
propertyValues.push(propertyValue.trim());
|
||||
}
|
||||
});
|
||||
deviceType.deviceTypeMetaDefinition.properties = propertyValues;
|
||||
|
||||
var operationValues = [];
|
||||
$('input[name^="operation"]').each(function() {
|
||||
var operationValue = $(this).val();
|
||||
if (operationValue.trim() != "") {
|
||||
operationValues.push(operationValue.trim());
|
||||
}
|
||||
});
|
||||
if (operationValues.length > 0) {
|
||||
deviceType.deviceTypeMetaDefinition.initialOperationConfig = {};
|
||||
deviceType.deviceTypeMetaDefinition.initialOperationConfig.operations = operationValues;
|
||||
}
|
||||
|
||||
deviceType.deviceTypeMetaDefinition.policyMonitoringEnabled = $("#policyMonitoring").is(":checked");
|
||||
deviceType.deviceTypeMetaDefinition.claimable = $("#deviceClaimable").is(":checked");;
|
||||
|
||||
var features = [];
|
||||
$('div[name^="deviceFeature"]').each(function() {
|
||||
var featureName = $(this).find("#feature-name").val();
|
||||
var featureCode = $(this).find("#feature-code").val();
|
||||
if (featureName && featureName.trim() != "" && featureCode && featureCode.trim() != "") {
|
||||
var feature = {};
|
||||
feature.name = featureName.trim();
|
||||
feature.code = featureCode.trim();
|
||||
feature.description = $("#feature-description").val();
|
||||
features.push(feature);
|
||||
}
|
||||
});
|
||||
deviceType.deviceTypeMetaDefinition.features = features;
|
||||
|
||||
var addRoleAPI = apiBasePath + "/admin/device-types";
|
||||
|
||||
invokerUtil.put(
|
||||
addRoleAPI,
|
||||
deviceType,
|
||||
function (data, textStatus, jqXHR) {
|
||||
if (jqXHR.status == 200) {
|
||||
$(successMsg).text("Device type updated.");
|
||||
$(successMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
},
|
||||
function (jqXHR) {
|
||||
if (jqXHR.status == 500) {
|
||||
$(errorMsg).text("Unexpected error.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
|
||||
if (jqXHR.status == 409) {
|
||||
$(errorMsg).text("Device type already exists");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
@ -0,0 +1,160 @@
|
||||
{{!
|
||||
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.
|
||||
}}
|
||||
{{unit "cdmf.unit.ui.title" pageTitle="Device Type Management"}}
|
||||
|
||||
{{#zone "topCss"}}
|
||||
{{css "css/devicetype.css"}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "breadcrumbs"}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/">
|
||||
<i class="icon fw fw-home"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-types">
|
||||
Device Types
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-type/edit-event?type={{name}}">
|
||||
Event
|
||||
</a>
|
||||
</li>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{#if canManage}}
|
||||
<!-- content/body -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- content -->
|
||||
<div id="devicetype-create-form" class="container col-centered wr-content">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">{{name}}</p>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div id="devicetype-create-error-msg" class="alert alert-danger hidden" role="alert">
|
||||
<i class="icon fw fw-error"></i><span></span>
|
||||
</div>
|
||||
<br>
|
||||
<input aria-describedby="basic-addon1" type="text" id="deviceTypeName"
|
||||
data-error-msg="invalid device type name" class="form-control hidden-input" value="{{name}}"/>
|
||||
|
||||
<label class="wr-input-label">Transport</label>
|
||||
<div class="wr-input-control">
|
||||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<select id="transport" class="form-control select">
|
||||
{{#if event}}
|
||||
<option {{selected event.transport "MQTT"}}>MQTT</option>
|
||||
<option {{selected event.transport "HTTP"}}>HTTP</option>
|
||||
{{else}}
|
||||
<option>MQTT</option>
|
||||
<option>HTTP</option>
|
||||
{{/if}}
|
||||
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="wr-input-label">
|
||||
Event Attributes
|
||||
</label>
|
||||
<br>
|
||||
<div class="form-group event_field_wrapper">
|
||||
{{#if event.eventAttributes}}
|
||||
{{#each event.eventAttributes.attributes}}
|
||||
<div class="dontfloat" name="deviceEvent">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" id="event-name" placeholder="name" value="{{this.name}}"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<select class="form-control select" id="event-type">
|
||||
<option {{selected this.type "STRING"}}>STRING</option>
|
||||
<option {{selected this.type "LONG"}}>LONG</option>
|
||||
<option {{selected this.type "BOOL"}}>BOOL</option>
|
||||
<option {{selected this.type "INT"}}>INT</option>
|
||||
<option {{selected this.type "FLOAT"}}>FLOAT</option>
|
||||
<option {{selected this.type "DOUBLE"}}>DOUBLE</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default remove_event_button"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="dontfloat" name="deviceEvent">
|
||||
<div class="col-xs-3">
|
||||
<input type="text" class="form-control" id="event-name" placeholder="name"/>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<select class="form-control select" id="event-type">
|
||||
<option>STRING</option>
|
||||
<option>LONG</option>
|
||||
<option>BOOL</option>
|
||||
<option>INT</option>
|
||||
<option>FLOAT</option>
|
||||
<option>DOUBLE</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default add_event_button"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
{{#if event}}
|
||||
<button id="add-event-btn" class="wr-btn">Update</button>
|
||||
{{else}}
|
||||
<button id="add-event-btn" class="wr-btn">Add</button>
|
||||
{{/if}}
|
||||
|
||||
<div id="devicetype-create-success-msg" class="alert hidden" role="alert">
|
||||
<i class="icon fw fw-success"></i><span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="devicetype-created-msg" class="container col-centered wr-content hidden">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">Device Type Event was added successfully.</p>
|
||||
<b>"View Device Type List"</b> to complete the process and go back to the devie type list.
|
||||
<hr/>
|
||||
<button class="wr-btn" onclick="window.location.href='{{@app.context}}/device-types'">
|
||||
View Device Type List
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content -->
|
||||
<div id="app-context" data-app-context="{{@app.context}}" class="hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /content/body -->
|
||||
{{else}}
|
||||
<h1 class="page-sub-title">
|
||||
Permission Denied
|
||||
</h1>
|
||||
<br>
|
||||
You not authorized to edit device type.
|
||||
<br>
|
||||
{{/if}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "js/bottomJs.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var displayData = {};
|
||||
|
||||
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/device-type")) {
|
||||
displayData.canManage = true;
|
||||
}
|
||||
context.handlebars.registerHelper('selected', function(a, b, opts) {
|
||||
if(a == b) // Or === depending on your needs
|
||||
return "selected";
|
||||
else
|
||||
return "";
|
||||
});
|
||||
|
||||
var deviceType = request.getParameter("type");
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
|
||||
+ "/events/" + deviceType;
|
||||
displayData.name = deviceType;
|
||||
serviceInvokers.XMLHttp.get(
|
||||
restAPIEndpoint,
|
||||
function (restAPIResponse) {
|
||||
if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) {
|
||||
var typeData = parse(restAPIResponse["responseText"]);
|
||||
displayData.event = typeData;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return displayData;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/device-type/edit-event",
|
||||
"layout": "cdmf.layout.default"
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
.dontfloat {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.hidden-div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
display: none;
|
||||
}
|
||||
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if provided input is valid against RegEx input.
|
||||
*
|
||||
* @param regExp Regular expression
|
||||
* @param inputString Input string to check
|
||||
* @returns {boolean} Returns true if input matches RegEx
|
||||
*/
|
||||
function inputIsValid(regExp, inputString) {
|
||||
regExp = new RegExp(regExp);
|
||||
return regExp.test(inputString);
|
||||
}
|
||||
|
||||
var validateInline = {};
|
||||
var clearInline = {};
|
||||
|
||||
var apiBasePath = "/api/device-mgt/v1.0";
|
||||
var domain = $("#domain").val();
|
||||
|
||||
|
||||
var enableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).addClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).removeClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).removeClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
var disableInlineError = function (inputField, errorMsg, errorSign) {
|
||||
var fieldIdentifier = "#" + inputField;
|
||||
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
|
||||
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
|
||||
|
||||
if (inputField) {
|
||||
$(fieldIdentifier).removeClass(" has-error has-feedback");
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
$(errorMsgIdentifier).addClass(" hidden");
|
||||
}
|
||||
|
||||
if (errorSign) {
|
||||
$(errorSignIdentifier).addClass(" hidden");
|
||||
}
|
||||
};
|
||||
|
||||
function formatRepo(user) {
|
||||
if (user.loading) {
|
||||
return user.text
|
||||
}
|
||||
if (!user.username) {
|
||||
return;
|
||||
}
|
||||
var markup = '<div class="clearfix">' +
|
||||
'<div class="col-sm-8">' +
|
||||
'<div class="clearfix">' +
|
||||
'<div class="col-sm-4">' + user.username + '</div>';
|
||||
if (user.name || user.name != undefined) {
|
||||
markup += '<div class="col-sm-8"> ( ' + user.name + ' )</div>';
|
||||
}
|
||||
markup += '</div></div></div>';
|
||||
return markup;
|
||||
}
|
||||
|
||||
function formatRepoSelection(user) {
|
||||
return user.username || user.text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var appContext = $("#app-context").data("app-context");
|
||||
var addEventButton = $('.add_event_button'); //Add button selector
|
||||
var eventWrapper = $('.event_field_wrapper'); //Input field wrapper
|
||||
$(addEventButton).click(function(){ //Once add button is clicked
|
||||
var eventFieldHtml = ' <div class="dontfloat" name="deviceEvent"> ' +
|
||||
'<div class="col-xs-3"> <input type="text" class="form-control" id="event-name" placeholder="name"/> ' +
|
||||
'</div> <div class="col-xs-4"> <select class="form-control select" id="event-type"> ' +
|
||||
'<option>STRING</option> <option>LONG</option> <option>BOOL</option> <option>INT</option> <option>FLOAT</option> ' +
|
||||
'<option>DOUBLE</option> </select> </div> ' +
|
||||
'<button type="button" class="btn btn-default remove_event_button"><i class="fa fa-minus"></i></button> </div>'
|
||||
$(eventWrapper).append(eventFieldHtml); // Add field html
|
||||
|
||||
});
|
||||
$(eventWrapper).on('click', '.remove_event_button', function(e){ //Once remove button is clicked
|
||||
e.preventDefault();
|
||||
$(this).parent('div').remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Following click function would execute
|
||||
* when a user clicks on "Add Device type" button.
|
||||
*/
|
||||
$("button#add-event-btn").click(function () {
|
||||
|
||||
var errorMsgWrapper = "#devicetype-create-error-msg";
|
||||
var errorMsg = "#devicetype-create-error-msg span";
|
||||
var successMsgWrapper = "#devicetype-create-success-msg";
|
||||
var successMsg = "#devicetype-create-success-msg span";
|
||||
var deviceTypeEvent = {};
|
||||
var deviceTypeName = $("#deviceTypeName").val();
|
||||
var deviceTypeDescription = $("#deviceTypeDescription").val();
|
||||
if (!deviceTypeName || deviceTypeName.trim() == "" ) {
|
||||
$(errorMsg).text("Device Type Name Cannot be empty.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
deviceTypeEvent.eventAttributes = {};
|
||||
|
||||
deviceTypeEvent.transport = $("#transport").val();
|
||||
|
||||
var attributes = [];
|
||||
$('div[name^="deviceEvent"]').each(function() {
|
||||
var eventName = $(this).find("#event-name").val();
|
||||
var eventType = $(this).find("#event-type").val();
|
||||
if (eventName && eventName.trim() != "" && eventType && eventType.trim() != "" && eventName != "deviceId") {
|
||||
var attribute = {};
|
||||
attribute.name = eventName.trim();
|
||||
attribute.type = eventType.trim();
|
||||
attributes.push(attribute);
|
||||
}
|
||||
});
|
||||
deviceTypeEvent.eventAttributes.attributes = attributes;
|
||||
|
||||
var addEventsAPI = apiBasePath + "/events/" + deviceTypeName;
|
||||
|
||||
invokerUtil.post(
|
||||
addEventsAPI,
|
||||
deviceTypeEvent,
|
||||
function (data, textStatus, jqXHR) {
|
||||
if (jqXHR.status == 200) {
|
||||
$(successMsg).text("Device Event Definition added.");
|
||||
$(successMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
},
|
||||
function (jqXHR) {
|
||||
if (jqXHR.status == 500) {
|
||||
$(errorMsg).text("Unexpected error.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
|
||||
if (jqXHR.status == 409) {
|
||||
$(errorMsg).text("Device type already exists");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
@ -0,0 +1,110 @@
|
||||
{{!
|
||||
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. licenses this file to you under the Apache License,
|
||||
Version 2.0 (the "License"); you may not use this file except
|
||||
in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
}}
|
||||
|
||||
{{unit "cdmf.unit.ui.title" pageTitle="Device Type Management"}}
|
||||
{{unit "cdmf.unit.data-tables-extended"}}
|
||||
{{unit "cdmf.unit.ui.modal"}}
|
||||
|
||||
{{#zone "breadcrumbs"}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/">
|
||||
<i class="icon fw fw-home"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-types">
|
||||
Device Types
|
||||
</a>
|
||||
</li>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "navbarActions"}}
|
||||
{{#unless isCloud}}
|
||||
<li>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<a href="{{@app.context}}/device-type/add" class="cu-btn">
|
||||
<span class="icon fw-stack">
|
||||
<i class="fw fw-add fw-stack-1x"></i>
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
</span>
|
||||
Create Device Type
|
||||
</a>
|
||||
</li>
|
||||
{{/unless}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{#if hasDeviceTypes}}
|
||||
<div id="loading-content" class="col-centered">
|
||||
<input type="hidden" id="can-edit" value="true"/>
|
||||
<i class="fw fw-settings fw-spin fw-2x"></i>
|
||||
Loading device types . . .
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="devicetype-table">
|
||||
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view"
|
||||
id="devicetype-grid">
|
||||
<thead>
|
||||
<tr class="sort-row">
|
||||
<th>By Device Type Name</th>
|
||||
</tr>
|
||||
<tr class="bulk-action-row">
|
||||
<th colspan="3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="ast-container" data-app-context="{{@app.context}}/"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="content-filter-types" style="display: none">
|
||||
<div class="sort-title">Sort By</div>
|
||||
<div class="sort-options">
|
||||
<!--suppress HtmlUnknownTag -->
|
||||
<th>By Device Type name</th>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
|
||||
<div id="user-created-msg" class="container col-centered wr-content">
|
||||
<div class="wr-form">
|
||||
<p class="page-sub-title">You Haven't created device types yet.</p>
|
||||
<br>Please click <b>"Create a Device Type"</b>, if you wish to create a device type.
|
||||
<hr/>
|
||||
|
||||
<a href="{{@app.context}}/device-type/add" class="cu-btn-inner">
|
||||
<span class="fw-stack">
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
<i class="fw fw-add fw-stack-1x"></i>
|
||||
</span>
|
||||
Create Device Type
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{/if}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<script id="devicetype-listing" data-current-user="{{@user.username}}"
|
||||
src="{{@page.publicUri}}/templates/devicetype-listing.hbs" type="text/x-handlebars-template"></script>
|
||||
{{js "js/devicetype-listing.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
|
||||
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
|
||||
context["permissions"] = userModule.getUIPermissions();
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/device-type")) {
|
||||
context["editPermitted"] = true;
|
||||
}
|
||||
var deviceTypeCount = deviceModule.getDeviceTypeCount();
|
||||
|
||||
if (deviceTypeCount > 0) {
|
||||
context["hasDeviceTypes"] = true;
|
||||
} else {
|
||||
context["hasDeviceTypes"] = false;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/device-types",
|
||||
"layout": "cdmf.layout.default"
|
||||
}
|
||||
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
var loadDeviceTypeBasedActionURL = function (action, deviceTypeName) {
|
||||
href = $("#ast-container").data("app-context") + "device-type/" + action + "?type=" + encodeURIComponent(deviceTypeName);
|
||||
$(location).attr('href', href);
|
||||
};
|
||||
|
||||
$(function () {
|
||||
var sortableElem = '.wr-sortable';
|
||||
$(sortableElem).sortable({
|
||||
beforeStop: function () {
|
||||
$(this).sortable('toArray');
|
||||
}
|
||||
});
|
||||
$(sortableElem).disableSelection();
|
||||
});
|
||||
|
||||
var apiBasePath = "/api/device-mgt/v1.0";
|
||||
var modalPopup = ".modal";
|
||||
var modalPopupContainer = modalPopup + " .modal-content";
|
||||
var modalPopupContent = modalPopup + " .modal-content";
|
||||
var body = "body";
|
||||
var isInit = true;
|
||||
var isCloud = false;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Fires the res_text when ever a data table redraw occurs making
|
||||
* the font icons change the size to respective screen resolution.
|
||||
*
|
||||
*/
|
||||
$(document).on('draw.dt', function () {
|
||||
$(".icon .text").res_text(0.2);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* set popup maximum height function.
|
||||
*/
|
||||
function setPopupMaxHeight() {
|
||||
$(modalPopupContent).css('max-height', ($(body).height() - ($(body).height() / 100 * 30)));
|
||||
$(modalPopupContainer).css('margin-top', (-($(modalPopupContainer).height() / 2)));
|
||||
}
|
||||
|
||||
/*
|
||||
* show popup function.
|
||||
*/
|
||||
function showPopup() {
|
||||
$(modalPopup).modal('show');
|
||||
//setPopupMaxHeight();
|
||||
}
|
||||
|
||||
/*
|
||||
* hide popup function.
|
||||
*/
|
||||
function hidePopup() {
|
||||
$(modalPopupContent).html('');
|
||||
$(modalPopup).modal('hide');
|
||||
$('body').removeClass('modal-open').css('padding-right', '0px');
|
||||
$('.modal-backdrop').remove();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Following function would execute
|
||||
* when a user clicks on the list item
|
||||
* initial mode and with out select mode.
|
||||
*/
|
||||
function InitiateViewOption() {
|
||||
// $(location).attr('href', $(this).data("url"));
|
||||
}
|
||||
|
||||
function htmlspecialchars(text) {
|
||||
return jQuery('<div/>').text(text).html();
|
||||
}
|
||||
|
||||
function loadDeviceTypes() {
|
||||
var loadingContent = $("#loading-content");
|
||||
loadingContent.show();
|
||||
|
||||
var dataFilter = function (data) {
|
||||
data = JSON.parse(data);
|
||||
var objects = [];
|
||||
$(data).each(function (index) {
|
||||
objects.push(
|
||||
{
|
||||
name: htmlspecialchars(data[index].name),
|
||||
DT_RowId: "devicetype-" + htmlspecialchars(data[index].name),
|
||||
metaDefinition: (data[index].deviceTypeMetaDefinition ? true : false)
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
var json = {
|
||||
"recordsTotal": data.length,
|
||||
"recordsFiltered": data.length,
|
||||
"data": objects
|
||||
};
|
||||
|
||||
return JSON.stringify(json);
|
||||
};
|
||||
|
||||
//noinspection JSUnusedLocalSymbols
|
||||
var fnCreatedRow = function (nRow, aData, iDataIndex) {
|
||||
$(nRow).attr('data-type', 'selectable');
|
||||
};
|
||||
|
||||
//noinspection JSUnusedLocalSymbols
|
||||
var columns = [
|
||||
{
|
||||
class: "remove-padding icon-only content-fill",
|
||||
data: null,
|
||||
defaultContent: "<div class='thumbnail icon'>" +
|
||||
"<i class='square-element text fw fw-devices' style='font-size: 74px;'></i>" +
|
||||
"</div>"
|
||||
},
|
||||
{
|
||||
class: "",
|
||||
data: "name",
|
||||
render: function (name, type, row, meta) {
|
||||
return '<h4>' + name.replace("devicemgt", ""); + '</h4>';
|
||||
}
|
||||
},
|
||||
{
|
||||
class: "text-right content-fill text-left-on-grid-view no-wrap",
|
||||
data: null,
|
||||
render: function (data, type, row, meta) {
|
||||
var isCloud = false;
|
||||
if ($('#is-cloud').length > 0) {
|
||||
isCloud = true;
|
||||
}
|
||||
|
||||
var innerhtml = '';
|
||||
if (data.metaDefinition) {
|
||||
|
||||
var editLink = '<a onclick="javascript:loadDeviceTypeBasedActionURL(\'edit\', \'' + data.name + '\')" ' +
|
||||
'data-devicetype="' + data.name + '" ' +
|
||||
'data-click-event="edit-form" ' +
|
||||
'class="btn padding-reduce-on-grid-view edit-devicetype-link">' +
|
||||
'<span class="fw-stack">' +
|
||||
'<i class="fw fw-circle-outline fw-stack-2x"></i>' +
|
||||
'<i class="fw fw-devices fw-stack-1x"></i>' +
|
||||
'<span class="fw-stack fw-move-right fw-move-bottom">' +
|
||||
'<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>' +
|
||||
'<i class="fw fw-circle fw-stack-2x"></i><i class="fw fw-edit fw-stack-1x fw-inverse"></i>' +
|
||||
'</span>' +
|
||||
'</span>' +
|
||||
'<span class="hidden-xs hidden-on-grid-view">Edit</span>' +
|
||||
'</a>';
|
||||
|
||||
var editEventLink = '<a onclick="javascript:loadDeviceTypeBasedActionURL(\'edit-event\', \'' + data.name + '\')" ' +
|
||||
'data-devicetype="' + data.name + '" ' +
|
||||
'data-click-event="edit-form" ' +
|
||||
'class="btn padding-reduce-on-grid-view edit-event-link">' +
|
||||
'<span class="fw-stack">' +
|
||||
'<i class="fw fw-circle-outline fw-stack-2x"></i>' +
|
||||
'<i class="fw fw-document fw-stack-1x"></i>' +
|
||||
'<span class="fw-stack fw-move-right fw-move-bottom">' +
|
||||
'<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>' +
|
||||
'<i class="fw fw-circle fw-stack-2x"></i><i class="fw fw-edit fw-stack-1x fw-inverse"></i>' +
|
||||
'</span>' +
|
||||
'</span>' +
|
||||
'<span class="hidden-xs hidden-on-grid-view">Edit Event</span>' +
|
||||
'</a>';
|
||||
|
||||
innerhtml = editLink + editEventLink;
|
||||
}
|
||||
return innerhtml;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var options = {
|
||||
"placeholder": "Search By Device Type Name",
|
||||
"searchKey": "filter"
|
||||
};
|
||||
var settings = {
|
||||
"sorting": false
|
||||
};
|
||||
var deviceTypeApiUrl = '/api/device-mgt/v1.0/admin/device-types';
|
||||
|
||||
$('#devicetype-grid').datatables_extended_serverside_paging(settings, deviceTypeApiUrl, dataFilter, columns, fnCreatedRow, null, options);
|
||||
loadingContent.hide();
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
loadDeviceTypes();
|
||||
});
|
||||
@ -0,0 +1,44 @@
|
||||
{{#each deviceTypes}}
|
||||
<tr data-type="selectable" id="devicetype-{{deviceTypeName}}">
|
||||
<td class="remove-padding icon-only content-fill">
|
||||
<div class="thumbnail icon">
|
||||
<i class="square-element text fw fw-user"></i>
|
||||
</div>
|
||||
</td>
|
||||
<td class="remove-padding-top">{{deviceTypeName}}</td>
|
||||
<td class="text-right content-fill text-left-on-grid-view no-wrap">
|
||||
|
||||
{{#if canEdit}}
|
||||
<a onclick="javascript:loadDeviceTypeBasedActionURL('edit', '{{deviceTypeName}}')" data-devicetype="{{deviceTypeName}}"
|
||||
data-click-event="edit-form"
|
||||
class="btn padding-reduce-on-grid-view edit-devicetype-link" title="Edit Device Type">
|
||||
<span class="fw-stack fw-lg">
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
<i class="fw fw-user fw-stack-1x"></i>
|
||||
<span class="fw-stack fw-move-right fw-move-bottom">
|
||||
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
|
||||
<i class="fw fw-circle fw-stack-2x"></i>
|
||||
<i class="fw fw-edit fw-stack-1x fw-inverse"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-on-grid-view">Edit</span>
|
||||
</a>
|
||||
<a onclick="javascript:loadDeviceTypeBasedActionURL('edit-event', '{{deviceTypeName}}')"
|
||||
data-devicetype="{{deviceTypeName}}"
|
||||
data-click-event="edit-form" class="btn padding-reduce-on-grid-view edit-permission-link"
|
||||
title="Edit Device Event">
|
||||
<span class="fw-stack fw-lg">
|
||||
<i class="fw fw-circle-outline fw-stack-2x"></i>
|
||||
<i class="fw fw-security-policy fw-stack-1x"></i>
|
||||
<span class="fw-stack fw-move-right fw-move-bottom">
|
||||
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
|
||||
<i class="fw fw-circle fw-stack-2x"></i>
|
||||
<i class="fw fw-edit fw-stack-1x fw-inverse"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-on-grid-view">Edit Event</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
@ -30,7 +30,14 @@
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if permissions.IS_ADMIN}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/device-types">
|
||||
<i class="fw fw-devices"></i>
|
||||
Device Type Management
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#unless isCloud}}
|
||||
{{#if permissions.VIEW_DASHBOARD}}
|
||||
<li>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
|
||||
ID INT AUTO_INCREMENT NOT NULL,
|
||||
NAME VARCHAR(300) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) NULL DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
|
||||
ID INT AUTO_INCREMENT NOT NULL,
|
||||
NAME VARCHAR(300) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) NULL DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) NULL DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
@ -2,7 +2,7 @@ IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[D
|
||||
CREATE TABLE DM_DEVICE_TYPE (
|
||||
ID INTEGER IDENTITY(1,1) NOT NULL,
|
||||
NAME VARCHAR(300) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP DATETIME2 NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER NULL,
|
||||
SHARED_WITH_ALL_TENANTS BIT NOT NULL DEFAULT 0,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
|
||||
ID INTEGER AUTO_INCREMENT NOT NULL,
|
||||
NAME VARCHAR(300) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE DM_DEVICE_TYPE (
|
||||
ID NUMBER(10) NOT NULL,
|
||||
NAME VARCHAR2(300) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR2(2000) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR2(20000) DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS NUMBER(1) DEFAULT 0 NOT NULL,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
|
||||
ID BIGSERIAL PRIMARY KEY,
|
||||
NAME VARCHAR(300) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(2000) DEFAULT NULL,
|
||||
DEVICE_TYPE_META VARCHAR(20000) DEFAULT NULL,
|
||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
|
||||
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user