Merge pull request #1 from charithag/master

Add Grouping
merge-requests/1/head
Rasika Perera 9 years ago
commit 770ce0f71e

@ -0,0 +1,252 @@
<%
/*
* 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 uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));
var log = new Log("api/group-api.jag");
var constants = require("/modules/constants.js");
var dcProps = require('/config/dc-props.js').config();
var carbon = require('carbon');
var carbonHttpsServletTransport = carbon.server.address('https');
var deviceCloudService = carbonHttpsServletTransport + "/devicecloud/group_manager";
var user = session.get(constants.USER_SESSION_KEY);
if (!user) {
response.sendRedirect(dcProps.appContext + "login?#login-required");
exit();//stop execution
}
var result;
var endPoint;
var data;
var groupId;
if (uriMatcher.match("/{context}/api/group/add")) {
var group = request.getContent();
var name = group["name"];
var description = group["description"];
//URL: POST https://localhost:9443/devicecloud/group_manager/group
endPoint = deviceCloudService + "/group";
data = {"name": name, "username": user.username, "description": description};
result = post(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/update")) {
groupId = uriMatcher.elements().groupId;
group = request.getContent();
name = group["name"];
description = group["description"];
//URL: PUT https://localhost:9443/devicecloud/group_manager/group/id/{groupId}
endPoint = deviceCloudService + "/group/id/" + groupId;
data = {"name": name, "username": user.username, "description": description};
result = put(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/remove")) {
groupId = uriMatcher.elements().groupId;
//URL: DELETE https://localhost:9443/devicecloud/group_manager/group/id/{groupId}
endPoint = deviceCloudService + "/group/id/" + groupId;
data = {"username": user.username};
result = del(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}")) {
groupId = uriMatcher.elements().groupId;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}
endPoint = deviceCloudService + "/group/id/" + groupId;
log.info(endPoint);
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/name/{groupName}")) {
//URL: GET https://localhost:9443/devicecloud/group_manager/group/name/{name}
endPoint = deviceCloudService + "/group/name/" + uriMatcher.elements().groupName;
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/all")) {
//URL: GET https://localhost:9443/devicecloud/group_manager/group/all
endPoint = deviceCloudService + "/group/all";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/all/count")) {
//URL: GET https://localhost:9443/devicecloud/group_manager/group/all/count
endPoint = deviceCloudService + "/group/all/count";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/share")) {
groupId = uriMatcher.elements().groupId;
var shareUser = request.getContent()["shareUser"];
role = request.getContent()["role"];
//URL: PUT https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/share
endPoint = deviceCloudService + "/group/id/" + groupId + "/share";
data = {"username": user.username, "shareUser": shareUser, "role": role};
result = post(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/unshare")) {
groupId = uriMatcher.elements().groupId;
var unShareUser = request.getContent()["unShareUser"];
role = request.getContent()["role"];
//URL: DELETE https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/unshare
endPoint = deviceCloudService + "/group/id/" + groupId + "/unshare";
data = {"username": user.username, "unShareUser": unShareUser, "role": role};
result = post(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/role/add")) {
groupId = uriMatcher.elements().groupId;
var permissions = request.getContent()["permissions"];
role = request.getContent()["role"];
//URL: POST https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/role
endPoint = deviceCloudService + "/group/id/" + groupId + "/role";
data = {"username": user.username, "permissions": permissions, "role": role};
result = post(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/role/delete")) {
groupId = uriMatcher.elements().groupId;
role = request.getContent()["role"];
//URL: DELETE https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/role
endPoint = deviceCloudService + "/group/id/" + groupId + "/role";
data = {"username": user.username, "role": role};
result = del(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/role/all")) {
groupId = uriMatcher.elements().groupId;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/role/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/role/all";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/{userId}/role/all")) {
groupId = uriMatcher.elements().groupId;
var userId = uriMatcher.elements().userId;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/{user}/role/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/" + userId + "/role/all";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/{userId}/rolemapping")) {
groupId = uriMatcher.elements().groupId;
userId = uriMatcher.elements().userId;
data = {"username": user.username};
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/role/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/role/all";
var allRoles = get(endPoint, data, "json").data;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/{user}/role/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/" + userId + "/role/all";
var userRolesObj = get(endPoint, data, "json");
var userRoles = userRolesObj.data;
var roleMap = [];
for (var role in allRoles) {
var objRole = {"role": allRoles[role], "assigned": false};
for (var usrRole in userRoles) {
if (allRoles[role] == userRoles[usrRole]) {
objRole.assigned = true;
break;
}
}
roleMap.push(objRole);
}
result = {};
result.data = roleMap;
result.xhr = userRolesObj.xhr;
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/{userId}/roleupdate")) {
groupId = uriMatcher.elements().groupId;
userId = uriMatcher.elements().userId;
roleMap = request.getContent();
for (role in roleMap) {
if (roleMap[role].assigned == true) {
//URL: POST https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/share
endPoint = deviceCloudService + "/group/id/" + groupId + "/share";
data = {"username": user.username, "shareUser": userId, "role": roleMap[role].role};
result = post(endPoint, data, "json");
} else {
//URL: DELETE https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/unshare
endPoint = deviceCloudService + "/group/id/" + groupId + "/unshare";
data = {"username": user.username, "unShareUser": userId, "role": roleMap[role].role};
result = post(endPoint, data, "json");
}
}
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/user/all")) {
groupId = uriMatcher.elements().groupId;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/user/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/user/all";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/device/all")) {
groupId = uriMatcher.elements().groupId;
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/device/all
endPoint = deviceCloudService + "/group/id/" + groupId + "/device/all";
data = {"username": user.username};
result = get(endPoint, data, "json");
} else if (uriMatcher.match("/{context}/api/group/id/{groupId}/assign")) {
groupId = uriMatcher.elements().groupId;
var deviceId = request.getContent()["deviceId"];
var deviceType = request.getContent()["deviceType"];
//URL: GET https://localhost:9443/devicecloud/group_manager/group/id/{groupId}/device/assign
endPoint = deviceCloudService + "/group/id/" + groupId + "/device/assign";
data = {"username": user.username, "deviceId": deviceId, "deviceType": deviceType};
result = put(endPoint, data, "json");
}
// returning the result.
if (result) {
response.status = result.xhr.status;
print(result.data);
}
%>

@ -137,6 +137,8 @@ if (uriMatcher.match("/{context}/api/user/login/")) {
result = 403;
}
} else if (uriMatcher.match("/{context}/api/users")) {
result = userModule.getUsers();
}
// returning the result.

@ -19,6 +19,10 @@
"url": "/api/devices/*",
"path": "/api/device-api.jag"
},
{
"url": "/api/group/*",
"path": "/api/group-api.jag"
},
{
"url": "/api/operation/*",
"path": "/api/operation-api.jag"

@ -56,6 +56,28 @@ utility = function () {
name: "Perform Operation"
}], "device-mgt/admin", type);
userModule.addPermissions([{key: "groups", name: "Groups"}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "groups/add_devices",
name: "Add Devices to Group"
}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "groups/remove_devices",
name: "Remove Devices from Group"
}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "groups/modify",
name: "Modify Group"
}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "groups/share",
name: "Change Group Sharing"
}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "groups/delete",
name: "Delete Group"
}], "device-mgt/admin", type);
userModule.addPermissions([{key: "users", name: "Users"}], "device-mgt/admin", type);
userModule.addPermissions([{
key: "users/add",
@ -83,6 +105,20 @@ utility = function () {
key: "devices/operation",
name: "Perform Operation"
}], "device-mgt/user", "init");
userModule.addPermissions([{key: "groups", name: "Groups"}], "device-mgt/user", type);
userModule.addPermissions([{
key: "groups/monitor",
name: "Monitor Devices in Group"
}], "device-mgt/user", type);
userModule.addPermissions([{
key: "groups/operation",
name: "Perform Device Operation"
}], "device-mgt/user", type);
userModule.addPermissions([{
key: "groups/list",
name: "List Groups of User"
}], "device-mgt/user", type);
};
return publicMethods;

@ -5,7 +5,7 @@
{{/zone}}
{{#zone "body"}}
{{unit "appbar" link="device-mgt" title="My Devices"}}
{{unit "extended-search-box"}}
{{unit "extended-search-box" item="Device"}}
{{unit "operation-mod"}}
<div class="wr-device-list row">
<div class="wr-hidden-operations wr-advance-operations">

@ -0,0 +1,12 @@
{{authorized}}
{{layout "fluid"}}
{{#zone "title"}}
Group Management
{{/zone}}
{{#zone "body"}}
{{unit "operation-mod"}}
{{unit "appbar" enableBack=true title="Group"}}
{{unit "group-detail"}}
{{/zone}}

@ -0,0 +1,23 @@
{{authorized}}
{{layout "fluid"}}
{{#zone "title"}}
Groups
{{/zone}}
{{#zone "body"}}
{{unit "appbar" link="group-mgt" title="My Groups"}}
{{unit "extended-search-box" item="Group"}}
{{unit "operation-mod"}}
<div class="wr-device-list row">
<div class="wr-hidden-operations wr-advance-operations">
</div>
<div class="col-md-12 wr-page-content">
<!-- content -->
<div>
{{unit "operation-bar"}}
{{unit "group-listing"}}
</div>
<!-- /content -->
</div>
</div>
{{/zone}}

@ -12,7 +12,7 @@
</a><a class="cu-btn page-title" href='javascript:location.reload();'>
<span class="fw-stack"></span>
{{title}}
</a>{{#each currentActions}}<a href="{{url}}" class="cu-btn">
</a>{{#each currentActions}}<a href="{{url}}" class="cu-btn {{class}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw {{icon}} fw-stack-1x"></i>
@ -41,7 +41,8 @@
<!-- common navigation -->
<div id="hiddenNav" class="wr-hidden-nav">
<ul>
<li><a href="/iotserver/devices"><i class="fw fw-mobile"></i>My Devices</a></li>
<li><a href="/iotserver/devices"><i class="fw fw-mobile"></i>My Devices</a></li>
<li><a href="/iotserver/groups"><i class="fw fw-group"></i>My Groups</a></li>
{{#if permissions.ADD_USER}}
<li><a href="/iotserver/users"><i class="fw fw-user"></i>User Management</a></li>
{{/if}}

@ -7,6 +7,7 @@ function onRequest(context) {
"policies": [],
"profiles": [],
"device-mgt": [],
"group-mgt": [],
"store": [],
"dashboard": [],
"analytics" : []
@ -37,6 +38,7 @@ function onRequest(context) {
links.store.push(storeLink);
links.analytics.push(deviceMgtLink);
links['device-mgt'].push(dashboardLink);
links['group-mgt'].push(dashboardLink);
if (!carbonUser) {
//user is not logged in
@ -74,6 +76,14 @@ function onRequest(context) {
url: "/iotserver/devices/add-device"
});
}
if (permissions.ADD_DEVICE) {
links["group-mgt"].push({
title: "Add Group",
icon: "fw-add",
url: "#",
class: "add-group-link"
});
}
}// end-if-user
context.currentActions = links[context.link];

@ -1,3 +1,4 @@
var log = new Log("modules/device-detail.js");
function onRequest(context) {
var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));

@ -1,5 +1,6 @@
{{#zone "main"}}
<span id="permission" data-permission="{{permissions}}"></span>
<span id="request-group-id" data-groupId="{{groupId}}"></span>
<!-- form content placeholder -->
<div id="ast-container" class="ast-container list-view">
<!-- no devices found -->
@ -16,6 +17,7 @@
<div class="container-fluid wr-content-alt">
<div class="ctrl-info-panel col-md-6 col-centered">
<h2>You don't have any Devices registered at the moment.</h2>
<p>
</a><a href="/iotserver/devices/add-device" class="cu-btn">
<span class="fw-stack">
@ -30,11 +32,32 @@
<!-- /no devices found -->
</div>
<div id="no-grouped-devices-div-content" class="hide">
<!-- no devices found -->
<div class="container-fluid wr-content-alt">
<div class="ctrl-info-panel col-md-6 col-centered">
<h2>You don't have any associated devices with this group.</h2>
<p>
</a><a href="/iotserver/devices" class="cu-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Associate Existing Device
</a>
</p>
</div>
</div>
<!-- /no devices found -->
</div>
<div id="remove-device-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to remove this device from your Devices List?</h3>
<div class="buttons">
<a href="#" id="remove-device-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Yes&nbsp;&nbsp;&nbsp;&nbsp;
@ -54,6 +77,7 @@
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device was successfully removed.</h3>
<div class="buttons">
<a href="#" id="remove-device-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -70,8 +94,10 @@
<div class="col-lg-5 col-md-6 col-centered">
<h3>Please enter new name for the device?</h3>
<br/>
<div>
<input id="edit-device-name" style="color:#3f3f3f;padding:5px" type="text" value="" placeholder="Type here" size="60">
<input id="edit-device-name" style="color:#3f3f3f;padding:5px" type="text" value=""
placeholder="Type here" size="60">
</div>
<div class="buttons">
<a href="#" id="edit-device-yes-link" class="btn-operations">
@ -92,6 +118,7 @@
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device was successfully updated.</h3>
<div class="buttons">
<a href="#" id="edit-device-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -102,11 +129,66 @@
</div>
</div>
<div id="group-device-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Please select group</h3>
<br/>
<div id="user-groups">Loading...</div>
<div class="buttons">
<a href="#" id="group-device-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="group-device-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Assign&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-associate-device-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device was successfully associated with group.</h3>
<div class="buttons">
<a href="#" id="group-associate-device-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-deassociate-device-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device was successfully removed from group.</h3>
<div class="buttons">
<a href="#" id="group-deassociate-device-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="device-400-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Exception at backend. Try Later.</h3>
<div class="buttons">
<a href="#" id="remove-user-400-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -122,6 +204,7 @@
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Action not permitted.</h3>
<div class="buttons">
<a href="#" id="remove-device-403-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -137,6 +220,7 @@
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device does not exist.</h3>
<div class="buttons">
<a href="#" id="remove-device-409-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -152,6 +236,7 @@
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Device does not exist.</h3>
<div class="buttons">
<a href="#" id="remove-device-unexpected-error-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
@ -163,6 +248,7 @@
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="device-listing" data-image-resource="{{self.publicURL}}/images/" src="{{self.publicURL}}/templates/device-listing.hbs" type="text/x-handlebars-template" ></script>
<script id="device-listing" data-image-resource="{{self.publicURL}}/images/"
src="{{self.publicURL}}/templates/device-listing.hbs" type="text/x-handlebars-template"></script>
<script src="{{self.publicURL}}/js/device-listing.js"></script>
{{/zone}}

@ -1,3 +1,5 @@
var log = new Log("modules/device-listing.js");
function onRequest(context){
var userModule = require("/modules/user.js").userModule;
var permissions = [];
@ -10,5 +12,13 @@ function onRequest(context){
}
permissions.push("LIST_OWN_DEVICES");
context.permissions = stringify(permissions);
var groupId = request.getParameter("groupId");
if (groupId){
context.groupId = groupId;
}else{
context.groupId = 0;
}
return context;
}

@ -53,6 +53,7 @@ var assetContainer = "#ast-container";
/*
* DOM ready functions.
*/
var groupId;
$(document).ready(function () {
/* Adding selected class for selected devices */
$(deviceCheckbox).each(function () {
@ -72,6 +73,9 @@ $(document).ready(function () {
return $("#content-filter-types").html();
}
});
groupId = $("#request-group-id").data("groupid");
loadDevices();
});
/*
@ -134,10 +138,18 @@ function loadDevices(searchType, searchParam) {
$.template("device-listing", deviceListingSrc, function (template) {
var serviceURL;
if ($.hasPermission("LIST_DEVICES")) {
serviceURL = "/iotserver/api/devices/all";
if (groupId && groupId != "0") {
serviceURL = "/iotserver/api/group/id/" + groupId + "/device/all";
} else {
serviceURL = "/iotserver/api/devices/all";
}
} else if ($.hasPermission("LIST_OWN_DEVICES")) {
//Get authenticated users devices
serviceURL = "/iotserver/api/devices/all";
if (groupId && groupId != "0") {
serviceURL = "/iotserver/api/group/id/" + groupId + "/device/all";
} else {
serviceURL = "/iotserver/api/devices/all";
}
} else {
$("#ast-container").html("Permission denied");
return;
@ -154,10 +166,17 @@ function loadDevices(searchType, searchParam) {
var successCallback = function (data) {
data = JSON.parse(data);
var viewModel = {};
if (groupId && groupId != "0") {
data.data = data;
}
viewModel.devices = data.data;
viewModel.imageLocation = imageResource;
if(!data.data || data.data.length <= 0){
$("#ast-container").html($("#no-devices-div-content").html());
if (!data.data || data.data.length <= 0) {
if (groupId && groupId != "0") {
$("#ast-container").html($("#no-grouped-devices-div-content").html());
} else {
$("#ast-container").html($("#no-devices-div-content").html());
}
} else {
var content = template(viewModel);
$("#ast-container").html(content);
@ -177,12 +196,9 @@ function loadDevices(searchType, searchParam) {
});
});
}
$(document).ready(function () {
loadDevices();
});
function formatDates(){
$(".formatDate").each(function(){
function formatDates() {
$(".formatDate").each(function () {
var timeStamp = $(this).html();
$(this).html(new Date(parseInt(timeStamp)).toUTCString());
});
@ -253,12 +269,12 @@ function attachEvents() {
$("a#remove-device-yes-link").click(function () {
invokerUtil.get(
removeDeviceAPI,
function (data,txtStatus,jqxhr) {
var status = jqxhr.status;
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
$(modalPopupContent).html($('#remove-device-200-content').html());
$('div[data-deviceid="' + deviceId + '"]').remove();
$("a#remove-device-200-link").click(function () {
$('div[data-deviceid="' + deviceId + '"]').remove();
$("a#remove-device-200-link").click(function () {
hidePopup();
});
} else if (status == 400) {
@ -310,38 +326,38 @@ function attachEvents() {
$("a#edit-device-yes-link").click(function () {
var newDeviceName = $('#edit-device-name').val();
var device={"device":{"name" : newDeviceName}};
var device = {"device": {"name": newDeviceName}};
invokerUtil.post(
editDeviceAPI,
device,
function (data,txtStatus,jqxhr) {
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
$(modalPopupContent).html($('#edit-device-200-content').html());
$("div[data-deviceid='"+deviceId+"'] .ast-name").html(newDeviceName);
$("div[data-deviceid='" + deviceId + "'] .ast-name").html(newDeviceName);
$("a#edit-device-200-link").click(function () {
hidePopup();
});
} else if (status == 400) {
$(modalPopupContent).html($('#edit-device-400-content').html());
$("a#edit-device-400-link").click(function () {
$(modalPopupContent).html($('#device-400-content').html());
$("a#device-400-link").click(function () {
hidePopup();
});
} else if (status == 403) {
$(modalPopupContent).html($('#edit-device-403-content').html());
$("a#edit-device-403-link").click(function () {
$(modalPopupContent).html($('#device-403-content').html());
$("a#device-403-link").click(function () {
hidePopup();
});
} else if (status == 409) {
$(modalPopupContent).html($('#edit-device-409-content').html());
$("a#edit-device-409-link").click(function () {
$(modalPopupContent).html($('#device-409-content').html());
$("a#device-409-link").click(function () {
hidePopup();
});
}
},
function () {
$(modalPopupContent).html($('#edit-device-unexpected-error-content').html());
$("a#edit-device-unexpected-error-link").click(function () {
$(modalPopupContent).html($('#device-unexpected-error-content').html());
$("a#device-unexpected-error-link").click(function () {
hidePopup();
});
}
@ -352,4 +368,87 @@ function attachEvents() {
hidePopup();
});
});
/**
* Following click function would execute
* when a user clicks on "Group" link
* on Device Management page in WSO2 MDM Console.
*/
$("a.group-device-link").click(function () {
var deviceId = $(this).data("deviceid");
var deviceType = $(this).data("devicetype");
var endPoint = "/iotserver/api/group/all";
$(modalPopupContent).html($('#group-device-modal-content').html());
$('#user-groups').html("Loading...");
$("a#group-device-yes-link").hide();
showPopup();
invokerUtil.get(endPoint,
function (data, txtStatus, jqxhr) {
var groups = JSON.parse(data);
var status = jqxhr.status;
if (status == 200) {
if (groups.length <= 0) {
$('#user-groups').html("There is no any groups available");
return;
}
var str = '<br /><select id="assign-group-selector" style="color:#3f3f3f;padding:5px;width:250px;">';
for (var group in groups) {
str += '<option value="' + groups[group].id + '">' + groups[group].name + '</option>';
}
str += '</select>';
$('#user-groups').html(str);
$("a#group-device-yes-link").show();
$("a#group-device-yes-link").click(function () {
var selectedGroupId = $('#assign-group-selector').val();
endPoint = "/iotserver/api/group/id/" + selectedGroupId + "/assign";
var device = {"deviceId": deviceId, "deviceType": deviceType};
invokerUtil.post(
endPoint,
device,
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
$(modalPopupContent).html($('#group-associate-device-200-content').html());
$("a#group-associate-device-200-link").click(function () {
hidePopup();
});
} else if (status == 400) {
$(modalPopupContent).html($('#device-400-content').html());
$("a#device-400-link").click(function () {
hidePopup();
});
} else if (status == 403) {
$(modalPopupContent).html($('#device-403-content').html());
$("a#device-403-link").click(function () {
hidePopup();
});
} else if (status == 409) {
$(modalPopupContent).html($('#device-409-content').html());
$("a#device-409-link").click(function () {
hidePopup();
});
}
},
function () {
$(modalPopupContent).html($('#device-unexpected-error-content').html());
$("a#device-unexpected-error-link").click(function () {
hidePopup();
});
});
});
}
},
function () {
$(modalPopupContent).html($('#device-unexpected-error-content').html());
$("a#device-unexpected-error-link").click(function () {
hidePopup();
});
});
$("a#group-device-cancel-link").click(function () {
hidePopup();
});
});
}

@ -28,6 +28,13 @@
</span>
<span class="lbl-action">View</span>
</a>
<a href="#" class="group-device-link" data-deviceid="{{deviceIdentifier}}" data-devicetype="{{type}}" data-devicename="{{name}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-group fw-stack-1x"></i>
</span>
<span class="lbl-action">Group</span>
</a>
<a href="#" class="edit-device-link" data-deviceid="{{deviceIdentifier}}" data-devicetype="{{type}}" data-devicename="{{name}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>

@ -71,7 +71,7 @@
</div>
<div class="wr-search-tags"></div>
<a href="#" class="btn-search"><i class="fw fw-search"></i></a>
<div class="input" id="search" data-value="" data-placeholder="Search devices ..." contenteditable="true"></div>
<div class="input" id="search" data-value="" data-placeholder="Search {{item}}s ..." contenteditable="true"></div>
<div class="clearfix"></div>
</div>
<!-- /asset filter -->
@ -79,9 +79,9 @@
<div class="wr-filters col-xs-12 col-sm-5 col-md-4 wr-filters-right">
<div class="wr-filter-sort pull-right">
<a href="javascript:void(0)" onclick="selectAllDevices(this)" class="wr-btn">Select All Devices</a>
<a href="javascript:void(0)" onclick="changeDeviceView('grid', this)" class="ico-filter ctrl-filter-grid view-toggle"><i class="fw fw-grid"></i></a>
<a href="javascript:void(0)" onclick="changeDeviceView('list', this)" class="ico-filter ctrl-filter-list view-toggle selected"><i class="fw fw-list"></i></a>
<a href="javascript:void(0)" onclick="selectAll{{item}}s(this)" class="wr-btn">Select All {{item}}s</a>
<a href="javascript:void(0)" onclick="change{{item}}View('grid', this)" class="ico-filter ctrl-filter-grid view-toggle"><i class="fw fw-grid"></i></a>
<a href="javascript:void(0)" onclick="change{{item}}View('list', this)" class="ico-filter ctrl-filter-list view-toggle selected"><i class="fw fw-list"></i></a>
<span class="wr-filter-type-switcher"><a href="#" class="ico-filter ctrl-filter-type-switcher" data-placement="bottom" data-trigger="focus"><i class="fw fw-list-sort"></i></a></span>
</div>
</div>

@ -51,7 +51,7 @@ $(document).ready(function(){
$(searchBtn).click(function(){
var input = $(searchField).html();
var searchType = $(searchField).data("search-type");
loadDevices(searchType, input);
loadGroups(searchType, input);
});
});
@ -123,7 +123,7 @@ function containerUpdate(asset){
function selectAsset(asset){
var platformType = $(asset).data("type");
loadOperationBar(platformType);
loadDevices("type", platformType);
loadGroups("type", platformType);
//$(tagsContainer +' span').each(function(){
// if($(this).attr('level') == $(asset).attr('level')){
// removeTags(this);
@ -218,5 +218,5 @@ function removeTags(tag){
$(this).remove();
});
unloadOperationBar();
loadDevices();
loadGroups();
}

@ -0,0 +1,116 @@
{{#zone "main"}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<label class="device-id device-select" data-groupid="{{group.id}}">
Group: {{group.name}}
</label>
</div>
</div>
<div class="wr-group-list row">
<div class="wr-hidden-operations wr-advance-operations">
</div>
<div class="col-md-12 wr-page-content">
{{unit "operation-bar"}}
<div class="row">
<div class="col-md-12 wr-stats-board">
<!-- content -->
<div class="col-lg-2 ast-desc-image">
<div class="row">
<div class="col-lg-12 col-sm-4">
<img src="{{self.publicURL}}/img/group-icon.png" style="width:200px"/>
</div>
<br/>
<div class="col-lg-12 col-sm-4 ast-desc">
<div class="ast-group-desc"><b>Description</b><br/> <span>{{group.description}}</span>
</div>
<br/>
<div class="ast-group-desc"><b>No. of Devices:</b> {{group.deviceCount}}</div>
<div class="ast-group-desc"><b>Users:</b> {{group.users}}</div>
<div class="ast-group-desc"><b>Created on:</b> <span
class="formatDate">{{group.dateOfCreation}}</span></div>
<div class="ast-group-desc"><b>Modified on:</b> <span
class="formatDate">{{group.dateOfLastUpdate}}</span></div>
</div>
</div>
</div>
<div class="col-lg-10 tiles">
<!-- group summary -->
<div class="row">
<div class="col-lg-6 col-md-6">
</div>
</div>
<!-- /group summary -->
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<!-- statistics -->
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingFour">
<h2 class="sub-title panel-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
href="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Group Statistics
</a>
</h2>
</div>
<div id="collapseFour" class="panel-collapse collapse" role="tabpanel"
aria-labelledby="headingFour">
<div class="panel-body">
<a href="/iotserver/groups/analytics?groupId={{group.id}}"><i class="fw fw-charts"></i>
Show Statistics</a>
</div>
</div>
</div>
<!-- devices -->
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingTwo">
<h2 class="sub-title panel-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Group Devices
</a>
</h2>
</div>
<div id="collapseTwo" class="panel-collapse collapse" role="tabpanel"
aria-labelledby="headingTwo">
<div class="panel-body">
<a href="/iotserver/devices?groupId={{group.id}}"><i class="fw fw-charts"></i> Show Devices
in Group</a>
</div>
</div>
</div>
</div>
</div>
<!-- /content -->
</div>
</div>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script src="{{self.publicURL}}/js/group-detail.js"></script>
{{/zone}}

@ -0,0 +1,21 @@
var log = new Log("modules/group-detail.js");
function onRequest(context) {
var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));
var isMatched = uriMatcher.match("/{context}/group/{groupId}");
if (isMatched) {
var group = {};
group.id = uriMatcher.elements().groupId;
group.name = request.getParameter("name");
group.deviceCount = request.getParameter("deviceCount");
group.dateOfCreation = request.getParameter("dateOfCreation");
group.dateOfLastUpdate = request.getParameter("dateOfLastUpdate");
group.description = request.getParameter("description");
group.users = request.getParameter("users");
context.group =group;
} else {
response.sendError(404);
}
return context;
}

@ -0,0 +1,30 @@
/*
* 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.
*/
function formatDates(){
$(".formatDate").each(function(){
var timeStamp = $(this).html();
$(this).html(new Date(parseInt(timeStamp)).toUTCString());
});
}
(function () {
$(document).ready(function(){
formatDates();
});
}());

@ -0,0 +1,289 @@
{{#zone "main"}}
<span id="permission" data-permission="{{permissions}}"></span>
<span id="user-details" data-username="{{user.username}}"></span>
<!-- form content placeholder -->
<div id="ast-container" class="ast-container list-view">
<!-- no devices found -->
<div class="container-fluid wr-content-alt">
<div class="ctrl-info-panel col-md-6 col-centered">
<h2>Loading...</h2>
</div>
</div>
<!-- /no groups found -->
</div>
<div id="no-groups-div-content" class="hide">
<!-- no groups found -->
<div class="container-fluid wr-content-alt">
<div class="ctrl-info-panel col-md-6 col-centered">
<h2>You don't have any Groups registered at the moment.</h2>
<p>
<a href="#" class="cu-btn add-group-link">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add New Group
</a>
</p>
</div>
</div>
<!-- /no groups found -->
</div>
<div id="share-group-w1-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Select user to manage group sharing</h3>
<div id="user-names">Loading...</div>
<div class="buttons">
<a href="#" id="share-group-w1-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="share-group-next-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Next&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="share-group-w2-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Select sharing roles</h3>
<br />
<div id="user-roles">Loading...</div>
<div class="buttons">
<a href="#" id="share-group-w2-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="share-group-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;OK&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="share-group-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group sharing updated successfully.</h3>
<div class="buttons">
<a href="#" id="share-group-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="remove-group-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to remove this group from your Group List?</h3>
<div class="buttons">
<a href="#" id="remove-group-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Yes&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="remove-group-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="remove-group-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group was successfully removed.</h3>
<div class="buttons">
<a href="#" id="remove-group-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="add-group-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Please enter name and description for new group</h3>
<br/>
<div>
<input id="add-group-name" style="color:#3f3f3f;padding:5px" type="text" value=""
placeholder="Group Name" size="60">
</div>
<br/>
<div>
<input id="add-group-description" style="color:#3f3f3f;padding:5px" type="text" value=""
placeholder="Group Description" size="60">
</div>
<div class="buttons">
<a href="#" id="add-group-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Add Group&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="add-group-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="add-group-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group successfully added.</h3>
<div class="buttons">
<a href="#" id="add-group-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="edit-group-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Please enter new name and description for the group</h3>
<br/>
<div>
<input id="edit-group-name" style="color:#3f3f3f;padding:5px" type="text" value=""
placeholder="Group Name" size="60">
</div>
<br/>
<div>
<input id="edit-group-description" style="color:#3f3f3f;padding:5px" type="text" value=""
placeholder="Group Description" size="60">
</div>
<div class="buttons">
<a href="#" id="edit-group-yes-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Update&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
<a href="#" id="edit-group-cancel-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="edit-group-200-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group was successfully updated.</h3>
<div class="buttons">
<a href="#" id="edit-group-200-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-400-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Exception at backend. Try Later.</h3>
<div class="buttons">
<a href="#" id="group-400-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-403-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Action not permitted.</h3>
<div class="buttons">
<a href="#" id="group-403-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-409-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group does not exist.</h3>
<div class="buttons">
<a href="#" id="group-409-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
<div id="group-unexpected-error-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group does not exist.</h3>
<div class="buttons">
<a href="#" id="group-unexpected-error-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;
</a>
</div>
</div>
</div>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script id="group-listing" data-image-resource="{{self.publicURL}}/images/"
src="{{self.publicURL}}/templates/group-listing.hbs" type="text/x-handlebars-template"></script>
<script src="{{self.publicURL}}/js/group-listing.js"></script>
{{/zone}}

@ -0,0 +1,21 @@
var log = new Log("modules/group-listing.js");
function onRequest(context){
var constants = require("/modules/constants.js");
var permissions = [];
//var userModule = require("/modules/user.js").userModule;
//if(userModule.isAuthorized("/permission/device-mgt/admin/groups/list")){
// permissions.push("LIST_GROUPS");
//}else if(userModule.isAuthorized("/permission/device-mgt/groups/remove")){
// permissions.push("REMOVE_GROUPS");
//}else if(userModule.isAuthorized("/permission/device-mgt/groups/share")){
// permissions.push("SHARE_GROUPS");
//}
permissions.push("LIST_GROUPS");
permissions.push("ADD_GROUPS");
permissions.push("SHARE_GROUPS");
context.permissions = stringify(permissions);
context.SHARE_GROUPS = true;
context.user = session.get(constants.USER_SESSION_KEY);
return context;
}

@ -0,0 +1,531 @@
/*
* 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.
*/
(function () {
var cache = {};
var permissionSet = {};
var validateAndReturn = function (value) {
return (value == undefined || value == null) ? "Unspecified" : value;
};
Handlebars.registerHelper("groupMap", function (group) {
group.ownerId = validateAndReturn(group.ownerId);
});
//This method is used to setup permission for device listing
$.setPermission = function (permission) {
permissionSet[permission] = true;
};
$.hasPermission = function (permission) {
return permissionSet[permission];
};
})();
/*
* Setting-up global variables.
*/
var groupCheckbox = "#ast-container .ctrl-wr-asset .itm-select input[type='checkbox']";
var assetContainer = "#ast-container";
/*
* DOM ready functions.
*/
$(document).ready(function () {
/* Adding selected class for selected devices */
$(groupCheckbox).each(function () {
addGroupSelectedClass(this);
});
var i;
var permissionList = $("#permission").data("permission");
for (i = 0; i < permissionList.length; i++) {
$.setPermission(permissionList[i]);
}
/* for device list sorting drop down */
$(".ctrl-filter-type-switcher").popover({
html: true,
content: function () {
return $("#content-filter-types").html();
}
});
changeGroupView('grid', this);
});
/*
* On Select All Group button click function.
*
* @param button: Select All Group button
*/
function selectAllGroups(button) {
if (!$(button).data('select')) {
$(groupCheckbox).each(function (index) {
$(this).prop('checked', true);
addGroupSelectedClass(this);
});
$(button).data('select', true);
$(button).html('Deselect All Groups');
} else {
$(groupCheckbox).each(function (index) {
$(this).prop('checked', false);
addGroupSelectedClass(this);
});
$(button).data('select', false);
$(button).html('Select All Groups');
}
}
/*
* On listing layout toggle buttons click function.
*
* @param view: Selected view type
* @param selection: Selection button
*/
function changeGroupView(view, selection) {
$(".view-toggle").each(function () {
$(this).removeClass("selected");
});
$(selection).addClass("selected");
if (view == "list") {
$(assetContainer).addClass("list-view");
} else {
$(assetContainer).removeClass("list-view");
}
}
/*
* Add selected style class to the parent element function.
*
* @param checkbox: Selected checkbox
*/
function addGroupSelectedClass(checkbox) {
if ($(checkbox).is(":checked")) {
$(checkbox).closest(".ctrl-wr-asset").addClass("selected device-select");
} else {
$(checkbox).closest(".ctrl-wr-asset").removeClass("selected device-select");
}
}
function loadGroups(searchType, searchParam) {
var groupListing = $("#group-listing");
var groupListingSrc = groupListing.attr("src");
var imageResource = groupListing.data("image-resource");
$.template("group-listing", groupListingSrc, function (template) {
var serviceURL;
if ($.hasPermission("LIST_GROUPS")) {
serviceURL = "/iotserver/api/group/all";
} else {
$("#ast-container").html("Permission denied");
return;
}
if (searchParam) {
if (searchType == "users") {
serviceURL = serviceURL + "?user=" + searchParam;
} else if (searchType == "user-roles") {
serviceURL = serviceURL + "?role=" + searchParam;
} else {
serviceURL = serviceURL + "?type=" + searchParam;
}
}
var successCallback = function (data) {
data = JSON.parse(data);
var viewModel = {};
viewModel.groups = data;
viewModel.imageLocation = imageResource;
if (!data || data.length <= 0) {
$("#ast-container").html($("#no-groups-div-content").html());
} else {
var content = template(viewModel);
$("#ast-container").html(content);
/*
* On group checkbox select add parent selected style class
*/
$(groupCheckbox).click(function () {
addGroupSelectedClass(this);
});
attachEvents();
formatDates();
}
attachGroupAdding();
};
invokerUtil.get(serviceURL,
successCallback, function (message) {
console.log(message);
});
});
}
$(document).ready(function () {
loadGroups();
});
function formatDates() {
$(".formatDate").each(function () {
var timeStamp = $(this).html();
$(this).html(new Date(parseInt(timeStamp)).toUTCString());
});
}
/**
* Sorting function of users
* listed on User Management page in WSO2 MDM Console.
*/
$(function () {
var sortableElem = '.wr-sortable';
$(sortableElem).sortable({
beforeStop: function () {
var sortedIDs = $(this).sortable('toArray');
console.log(sortedIDs);
}
});
$(sortableElem).disableSelection();
});
var modalPopup = ".wr-modalpopup";
var modalPopupContainer = modalPopup + " .modalpopup-container";
var modalPopupContent = modalPopup + " .modalpopup-content";
var body = "body";
/*
* 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).show();
setPopupMaxHeight();
}
/*
* hide popup function.
*/
function hidePopup() {
$(modalPopupContent).html('');
$(modalPopup).hide();
}
var errorHandler = function () {
$(modalPopupContent).html($('#add-group-unexpected-error-content').html());
$("a#group-unexpected-error-link").click(function () {
hidePopup();
});
};
function attachGroupAdding() {
/**
* Following click function would execute
* when a user clicks on "Remove" link
* on Group Management page in WSO2 IoT Server Console.
*/
$("a.add-group-link").click(function () {
var addGroupApi = "/iotserver/api/group/add";
$(modalPopupContent).html($('#add-group-modal-content').html());
showPopup();
$("a#add-group-yes-link").click(function () {
var newGroupName = $('#add-group-name').val();
var newGroupDescription = $('#add-group-description').val();
var group = {"name": newGroupName, "description": newGroupDescription};
invokerUtil.post(
addGroupApi,
group,
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
if (data != "false") {
$(modalPopupContent).html($('#add-group-200-content').html());
$("a#add-group-200-link").click(function () {
hidePopup();
location.reload();
});
} else {
$(modalPopupContent).html($('#group-400-content').html());
$("a#group-400-link").click(function () {
hidePopup();
});
}
} else if (status == 400) {
$(modalPopupContent).html($('#group-400-content').html());
$("a#group-400-link").click(function () {
hidePopup();
});
} else if (status == 403) {
$(modalPopupContent).html($('#agroup-403-content').html());
$("a#group-403-link").click(function () {
hidePopup();
});
} else if (status == 409) {
$(modalPopupContent).html($('#group-409-content').html());
$("a#group-409-link").click(function () {
hidePopup();
});
}
}, errorHandler
);
});
$("a#add-group-cancel-link").click(function () {
hidePopup();
});
});
}
/**
* Following functions should be triggered after AJAX request is made.
*/
function attachEvents() {
/**
* Following click function would execute
* when a user clicks on "Share" link
* on Group Management page in WSO2 IoT Server Console.
*/
$("a.view-group-link").click(function () {
$("#group_data").closest('form').submit();
});
/**
* Following click function would execute
* when a user clicks on "Share" link
* on Group Management page in WSO2 IoT Server Console.
*/
$("a.share-group-link").click(function () {
var groupId = $(this).data("groupid");
var username = $("#user-details").data("username");
$(modalPopupContent).html($('#share-group-w1-modal-content').html());
$('#user-names').html('Loading...');
showPopup();
$("a#share-group-next-link").hide();
invokerUtil.get("/iotserver/api/users",
function (data, txtStatus, jqxhr) {
var users = JSON.parse(data);
var status = jqxhr.status;
if (status == 200) {
var str = '<br /><select id="share-user-selector" style="color:#3f3f3f;padding:5px;width:250px;">';
var hasUsers = false;
for (var user in users) {
if (users[user].username != username) {
str += '<option value="' + users[user].username + '">' + users[user].username + '</option>';
hasUsers = true;
}
}
str += '</select>';
if (!hasUsers) {
str = "There is no any other users registered";
$('#user-names').html(str);
return;
}
$('#user-names').html(str);
$("a#share-group-next-link").show();
$("a#share-group-next-link").click(function () {
var selectedUser = $('#share-user-selector').val();
$(modalPopupContent).html($('#share-group-w2-modal-content').html());
$('#user-roles').html('Loading...');
$("a#share-group-yes-link").hide();
invokerUtil.get("/iotserver/api/group/id/" + groupId + "/" + selectedUser + "/rolemapping",
function (data, txtStatus, jqxhr) {
var roleMap = JSON.parse(data);
var status = jqxhr.status;
if (status == 200) {
var str = '';
var isChecked = '';
var hasRoles = false;
for (var role in roleMap) {
if (roleMap[role].assigned == true) {
isChecked = 'checked';
}
str += '<label class="checkbox-text"><input type="checkbox" id="user-role-' + roleMap[role].role + '" value="' + roleMap[role].role
+ '" ' + isChecked + '/>' + roleMap[role].role + '</label>&nbsp;&nbsp;&nbsp;&nbsp;';
hasRoles = true;
}
if (!hasRoles) {
str = "There is no any roles for this group";
return;
}
$('#user-roles').html(str);
$("a#share-group-yes-link").show();
$("a#share-group-yes-link").click(function () {
var updatedRoleMap = [];
for (var role in roleMap) {
if ($('#user-role-' + roleMap[role].role).is(':checked') != roleMap[role].assigned){
roleMap[role].assigned = $('#user-role-' + roleMap[role].role).is(':checked');
updatedRoleMap.push(roleMap[role]);
}
}
invokerUtil.post("/iotserver/api/group/id/" + groupId + "/" + selectedUser + "/roleupdate",
updatedRoleMap,
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
$(modalPopupContent).html($('#share-group-200-content').html());
$("a#share-group-200-link").click(function () {
hidePopup();
});
}else {
displayErrors(status);
}
}, errorHandler);
});
} else {
displayErrors(status);
}
}, errorHandler);
$("a#share-group-w2-cancel-link").click(function () {
hidePopup();
});
});
} else {
displayErrors(status);
}
}, errorHandler);
$("a#share-group-w1-cancel-link").click(function () {
hidePopup();
});
});
/**
* Following click function would execute
* when a user clicks on "Remove" link
* on Group Management page in WSO2 IoT Server Console.
*/
$("a.remove-group-link").click(function () {
var groupId = $(this).data("groupid");
var removeGroupApi = "/iotserver/api/group/id/" + groupId + "/remove";
$(modalPopupContent).html($('#remove-group-modal-content').html());
showPopup();
$("a#remove-group-yes-link").click(function () {
invokerUtil.delete(
removeGroupApi,
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
if (data != "false") {
$(modalPopupContent).html($('#remove-group-200-content').html());
$('div[data-group="' + groupId + '"]').remove();
$("a#remove-group-200-link").click(function () {
hidePopup();
location.reload();
});
} else {
$(modalPopupContent).html($('#group-409-content').html());
$("a#group-409-link").click(function () {
hidePopup();
});
}
} else {
displayErrors(status);
}
},
function () {
$(modalPopupContent).html($('#group-unexpected-error-content').html());
$("a#group-unexpected-error-link").click(function () {
hidePopup();
});
}
);
});
$("a#remove-group-cancel-link").click(function () {
hidePopup();
});
});
/**
* Following click function would execute
* when a user clicks on "Edit" link
* on Device Management page in WSO2 MDM Console.
*/
$("a.edit-group-link").click(function () {
var groupId = $(this).data("groupid");
var groupName = $(this).data("groupname");
var groupDescription = $(this).data("groupdescription");
var editGroupApi = "/iotserver/api/group/id/" + groupId + "/update";
$(modalPopupContent).html($('#edit-group-modal-content').html());
$('#edit-group-name').val(groupName);
$('#edit-group-description').val(groupDescription);
showPopup();
$("a#edit-group-yes-link").click(function () {
var newGroupName = $('#edit-group-name').val();
var newGroupDescription = $('#edit-group-description').val();
var group = {"name": newGroupName, "description": newGroupDescription};
invokerUtil.post(
editGroupApi,
group,
function (data, txtStatus, jqxhr) {
var status = jqxhr.status;
if (status == 200) {
if (data != "false") {
$(modalPopupContent).html($('#edit-group-200-content').html());
$("div[data-groupid='" + groupId + "'] .ast-name").html(newGroupName);
$("a#edit-group-200-link").click(function () {
hidePopup();
});
} else {
$(modalPopupContent).html($('#group-409-content').html());
$("a#group-409-link").click(function () {
hidePopup();
});
}
} else {
displayErrors(status);
}
},
function () {
$(modalPopupContent).html($('#group-unexpected-error-content').html());
$("a#group-unexpected-error-link").click(function () {
hidePopup();
});
}
);
});
$("a#edit-group-cancel-link").click(function () {
hidePopup();
});
});
}
function displayErrors(status) {
if (status == 400) {
$(modalPopupContent).html($('#group-400-content').html());
$("a#group-400-link").click(function () {
hidePopup();
});
} else if (status == 403) {
$(modalPopupContent).html($('#group-403-content').html());
$("a#group-403-link").click(function () {
hidePopup();
});
} else if (status == 409) {
$(modalPopupContent).html($('#group-409-content').html());
$("a#group-409-link").click(function () {
hidePopup();
});
}
}

@ -0,0 +1,69 @@
{{#each groups}}
{{groupMap this}}
<form action="/iotserver/group/{{id}}" method="POST" id="group_data" >
<input type="hidden" name="name" value="{{name}}">
<input type="hidden" name="deviceCount" value="{{deviceCount}}">
<input type="hidden" name="dateOfCreation" value="{{dateOfCreation}}">
<input type="hidden" name="dateOfLastUpdate" value="{{dateOfLastUpdate}}">
<input type="hidden" name="description" value="{{description}}">
<input type="hidden" name="users" value="{{users}}">
</form>
<div class="ctrl-wr-asset" data-groupid="{{id}}">
<div class="itm-select">
<label class="wr-input-control checkbox">
<input type="checkbox"/>
<span class="helper"></span>
</label>
</div>
<div class="itm-ast">
<div class="ast-img"><img src="{{../imageLocation}}group-icon.png"/></div>
<div class="ast-desc">
<div class="ast-title">
<h3 class="ast-name">{{name}}</h3>
<span class="ast-auth">Device Count: {{deviceCount}}</span>
<span class="ast-auth">Created On: <span class="formatDate">{{dateOfCreation}}</span></span>
</div>
<div class="ast-model">
<span class="ast-ver">Shared with: {{users}}</span>
<div href="#" class="ast-btn-group">
<a class="view-group-link" data-group="{{this}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-view fw-stack-1x"></i>
</span>
<span class="lbl-action">View</span>
</a>
<a href="#" class="share-group-link" data-groupid="{{id}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-share fw-stack-1x"></i>
</span>
<span class="lbl-action">Share</span>
</a>
<a href="#" class="edit-group-link" data-groupid="{{id}}" data-groupname="{{name}}"
data-groupdescription="{{description}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-edit fw-stack-1x"></i>
</span>
<span class="lbl-action">Edit</span>
</a>
<a href="#" class="remove-group-link" data-groupid="{{id}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
<span class="lbl-action">Delete</span>
</a>
</div>
</div>
</div>
<br class="c-both"/>
</div>
</div>
{{/each}}
<br class="c-both"/>

@ -1,4 +1,3 @@
function onRequest(context){
var log = new Log();
return context;
}

@ -250,23 +250,23 @@ a.ast-type-item:hover {
}
@media (min-width: 768px){
.ctrl-wr-asset { width: 24%; }
.ctrl-wr-asset { width: 30%; }
}
@media (min-width: 992px){
.ctrl-wr-asset { width: 19%; }
.ctrl-wr-asset { width: 25%; }
}
@media (min-width:1300px){
.ctrl-wr-asset { width: 13%; }
.ctrl-wr-asset { width: 19%; }
}
@media (min-width:1500px){
.ctrl-wr-asset { width: 11.5%; }
.ctrl-wr-asset { width: 17.5%; }
}
@media (min-width:1800px){
.ctrl-wr-asset { width: 9%; }
.ctrl-wr-asset { width: 15%; }
}
.ctrl-wr-asset.selected {
@ -358,7 +358,7 @@ a.ast-type-item:hover {
}
.ast-title {
height: 70px;
/*height: 70px;*/
overflow: hidden;
}

@ -67,6 +67,10 @@
content: "\e656";
}
.fw-group:before {
content: "\e611";
}
.fw-dots:before {
content: "\e615";
}

@ -596,3 +596,38 @@ header{background-color: #2a2a2a;}
padding-top:0px;
display:inline-block;
}
::-webkit-input-placeholder { /* WebKit browsers */
color: #b2b2b2;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #b2b2b2;
opacity: 1;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #b2b2b2;
opacity: 1;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #b2b2b2;
}
input[type=checkbox] {
width: 13px;
height: 13px;
padding: 0;
margin:0;
vertical-align: bottom;
position: relative;
top: -1px;
*overflow: hidden;
}
.checkbox-text
{
/* Checkbox text */
display: inline;
padding-left: 15px;
text-indent: -15px;
}

@ -108,6 +108,9 @@
<featureArtifactDef>
org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.server.feature:${carbon.device.mgt.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.group.server.feature:${carbon.device.mgt.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.carbon.devicemgt:org.wso2.carbon.policy.mgt.server.feature:${carbon.device.mgt.version}
</featureArtifactDef>
@ -335,6 +338,10 @@
<id>org.wso2.carbon.policy.mgt.server.feature.group</id>
<version>${carbon.device.mgt.version}</version>
</feature>
<feature>
<id>org.wso2.carbon.device.mgt.group.server.feature.group</id>
<version>${carbon.device.mgt.version}</version>
</feature>
<feature>
<id>org.wso2.carbon.webapp.authenticator.framework.server.feature.group</id>
<version>${carbon.device.mgt.version}</version>

@ -331,6 +331,16 @@
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.group.core</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.group.common</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.mgt.common</artifactId>

Loading…
Cancel
Save