Merge pull request #441 from madawas/IOTS-296

Generalizing Policy UI
4.x.x
Madawa Soysa 8 years ago committed by GitHub
commit 20dee2ec44

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.beans;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.policy.mgt.common.DeviceGroupWrapper;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.util.List; import java.util.List;
@ -75,6 +76,10 @@ public class PolicyWrapper {
required = true) required = true)
private List<String> users; private List<String> users;
@ApiModelProperty(name = "deviceGroups", value = "Lists out the groups on whose devices the policy is enforced",
required = true)
private List<DeviceGroupWrapper> deviceGroups;
public Profile getProfile() { public Profile getProfile() {
return profile; return profile;
} }
@ -147,4 +152,12 @@ public class PolicyWrapper {
this.users = users; this.users = users;
} }
public List<DeviceGroupWrapper> getDeviceGroups() {
return deviceGroups;
}
public void setDeviceGroups(List<DeviceGroupWrapper> deviceGroups) {
this.deviceGroups = deviceGroups;
}
} }

@ -122,6 +122,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
policy.setRoles(policyWrapper.getRoles()); policy.setRoles(policyWrapper.getRoles());
policy.setUsers(policyWrapper.getUsers()); policy.setUsers(policyWrapper.getUsers());
policy.setCompliance(policyWrapper.getCompliance()); policy.setCompliance(policyWrapper.getCompliance());
policy.setDeviceGroups(policyWrapper.getDeviceGroups());
//TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here. //TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here.
List<Device> devices = new ArrayList<Device>(); List<Device> devices = new ArrayList<Device>();
List<DeviceIdentifier> deviceIdentifiers = policyWrapper.getDeviceIdentifiers(); List<DeviceIdentifier> deviceIdentifiers = policyWrapper.getDeviceIdentifiers();

@ -79,4 +79,30 @@ var groupModule = {};
); );
}; };
groupModule.getGroups = function () {
var permissions = userModule.getUIPermissions();
if (permissions.LIST_ALL_GROUPS) {
endPoint = deviceServiceEndpoint + "/admin/groups";
} else if (permissions.LIST_GROUPS) {
endPoint = deviceServiceEndpoint + "/groups";
} else {
log.error("Access denied for user: " + carbonUser.username);
return -1;
}
return serviceInvokers.XMLHttp.get(
endPoint, function (responsePayload) {
var data = JSON.parse(responsePayload.responseText);
if(data) {
return data.deviceGroups;
} else {
return [];
}
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
}(groupModule)); }(groupModule));

@ -34,6 +34,7 @@
</a> </a>
</li> </li>
<li> <li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policies"> <a href="{{@app.context}}/policies">
Policies Policies
</a> </a>
@ -41,18 +42,24 @@
{{/zone}} {{/zone}}
{{#zone "navbarActions"}} {{#zone "navbarActions"}}
{{#if managePermitted}} {{#if permissions.ADD_ADMIN_POLICY}}
{{#equal noPolicy false}}
<li> <li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="cu-btn"> <a href="{{@app.context}}/policy/add" class="cu-btn">
<span class="icon fw-stack"> <span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i> <i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
</span> </span>
Add Policy Add New Policy
</a> </a>
</li> </li>
{{/equal}}
{{/if}}
{{#if permissions.CHANGE_POLICY_PRIORITY}}
{{#equal noPolicy false}} {{#equal noPolicy false}}
<li> <li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/priority" class="cu-btn"> <a href="{{@app.context}}/policy/priority" class="cu-btn">
<span class="icon fw-stack"> <span class="icon fw-stack">
<i class="fw fw-throttling-policy fw-stack-1x"></i> <i class="fw fw-throttling-policy fw-stack-1x"></i>
@ -75,44 +82,37 @@
{{/zone}} {{/zone}}
{{#zone "content"}} {{#zone "content"}}
{{#equal isUpdated true}}
<input type="hidden" id="is-updated" value="UPDATED">
{{/equal}}
{{#equal noPolicy true}} {{#equal noPolicy true}}
<div id="ast-container" class="ast-container list-view"> <div id="ast-container" class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login"> <div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any policy at the moment.</h2> <h3 class="text-muted">
<br/> <i class="fw fw-policy fw-3x"></i>
{{#if managePermitted}} </h3>
<p class="text-center"> <h3 class="text-muted">You do not have any device policy at the moment</h3>
<a href="{{@app.context}}/policy/add" class="wr-btn"> {{#if permissions.ADD_ADMIN_POLICY}}
<h3>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="btn-operations btn-default">
<span class="fw-stack"> <span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i> <i class="fw fw-add fw-stack-1x"></i>
</span> </span>
Add New Policy Add New Policy
</a> </a>
</p> </h3>
{{/if}} {{/if}}
</div> </div>
</div> </div>
{{/equal}} {{/equal}}
{{#equal noPolicy false}} {{#equal noPolicy false}}
{{#equal isUpdated true}}
<input type="hidden" id="is-updated" name="country" value="UPDATED">
{{/equal}}
<div id="loading-content" class="col-centered"> <div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i> <i class="fw fw-settings fw-spin fw-2x"></i>
Loading policies . . . Loading policies . . .
<br> <br>
</div> </div>
<div id="policy-listing-status" class="raw hidden">
<ul style="list-style-type: none;">
<li class="message message-info">
<h4>
<i class="icon fw fw-info"></i>
<a id="policy-listing-status-msg">{{policyListingStatusMsg}}</a>
</h4>
</li>
</ul>
</div>
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view hidden" <table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view hidden"
id="policy-grid"> id="policy-grid">
<thead> <thead>
@ -141,10 +141,9 @@
<tr class="bulk-action-row"> <tr class="bulk-action-row">
<th colspan="9"> <th colspan="9">
<ul class="tiles"> <ul class="tiles">
{{#if managePermitted}} {{#if removePermitted}}
<li class="square"> <li class="square">
<a href="#" data-click-event="remove-form" <a href="#" data-click-event="remove-form" class="btn square-element policy-remove-link"
class="btn square-element policy-remove-link"
data-toggle="modal" data-target="#modalDemo"> data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack"> <span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
@ -155,8 +154,7 @@
</li> </li>
{{/if}} {{/if}}
<li class="square"> <li class="square">
<a href="#" data-click-event="remove-form" <a href="#" data-click-event="remove-form" class="btn square-element policy-publish-link"
class="btn square-element policy-publish-link"
data-toggle="modal" data-target="#modalDemo"> data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack"> <span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
@ -166,8 +164,7 @@
</a> </a>
</li> </li>
<li class="square"> <li class="square">
<a href="#" data-click-event="remove-form" <a href="#" data-click-event="remove-form" class="btn square-element policy-unpublish-link"
class="btn square-element policy-unpublish-link"
data-toggle="modal" data-target="#modalDemo"> data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack"> <span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
@ -185,46 +182,64 @@
{{#each policyListToView}} {{#each policyListToView}}
<tr data-type="selectable" data-id="{{id}}" data-status="{{status}}"> <tr data-type="selectable" data-id="{{id}}" data-status="{{status}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon" <td class="remove-padding icon-only content-fill viewEnabledIcon"
data-url="{{@app.context}}/policy/view?id={{id}}&type={{platform}}" data-url="{{@app.context}}/policy/view?id={{id}}" data-id="{{id}}">
data-id="{{id}}"> <div class="thumbnail icon" style="padding-top: 30px; padding-bottom: 30px;">
<div class="thumbnail icon"> <i class="fw fw-{{deviceTypeIcon}}" style="font-size: 59px"></i>
<img src="{{icon}}"/>
</div> </div>
</td> </td>
<td class="fade-edge" data-search="{{name}}" data-display="{{name}}"> <td class="fade-edge"
data-search="{{name}}"
data-display="{{name}}">
<h4>{{name}}</h4> <h4>{{name}}</h4>
<div>({{platform}})</div> <div>({{platform}})</div>
{{#equal status "Active/Updated"}} {{#equal status "Active/Updated"}}
<i class="fw fw-warning icon-success"></i> Active/Updated</span> <span><i class="fw fw-warning icon-success"></i> Active/Updated</span>
{{/equal}} {{/equal}}
{{#equal status "Active"}} {{#equal status "Active"}}
<i class="fw fw-ok icon-success"></i> Active</span> <span><i class="fw fw-ok icon-success"></i> Active</span>
{{/equal}} {{/equal}}
{{#equal status "Inactive/Updated"}} {{#equal status "Inactive/Updated"}}
<i class="fw fw-warning icon-warning"></i> Inactive/Updated</span> <span><i class="fw fw-warning icon-warning"></i> Inactive/Updated</span>
{{/equal}} {{/equal}}
{{#equal status "Inactive"}} {{#equal status "Inactive"}}
<i class="fw fw-error icon-danger"></i> Inactive</span> <span><i class="fw fw-error icon-danger"></i> Inactive</span>
{{/equal}} {{/equal}}
</td> </td>
<td class="fade-edge remove-padding-top" data-search="{{platform}}" <td class="fade-edge remove-padding-top"
data-display="{{platform}}"></td> data-search="{{platform}}"
<td class="fade-edge remove-padding-top" data-search="{{ownershipType}}" data-display="{{platform}}">
</td>
<td class="fade-edge remove-padding-top"
data-search="{{ownershipType}}"
data-display="{{ownershipType}}" data-display="{{ownershipType}}"
data-grid-label="Ownership">{{ownershipType}}</td> data-grid-label="Ownership">
<td id="policy-roles" class="fade-edge remove-padding-top" data-search="{{roles}}" {{ownershipType}}
</td>
<td id="policy-roles" class="fade-edge remove-padding-top"
data-search="{{roles}}"
data-display="{{roles}}" data-display="{{roles}}"
data-grid-label="Role(s)">{{roles}}</td> data-grid-label="Role(s)">
<td id="policy-users" class="fade-edge remove-padding-top" data-search="{{users}}" {{roles}}
data-display="{{users}}" data-grid-label="User(s)">{{users}}</td> </td>
<td class="fade-edge remove-padding-top" data-search="{{compliance}}" <td id="policy-users" class="fade-edge remove-padding-top"
data-display="{{compliance}}" data-grid-label="Compliance">{{compliance}}</td> data-search="{{users}}"
<td id="policy-status" class="fade-edge remove-padding-top" data-search="{{status}}" data-display="{{users}}"
data-grid-label="User(s)">
{{users}}
</td>
<td class="fade-edge remove-padding-top"
data-search="{{compliance}}"
data-display="{{compliance}}"
data-grid-label="Compliance">
{{compliance}}
</td>
<td id="policy-status" class="fade-edge remove-padding-top"
data-search="{{status}}"
data-display="{{status}}"> data-display="{{status}}">
</td> </td>
<td class="text-right content-fill text-left-on-grid-view no-wrap"> <td class="text-right content-fill text-left-on-grid-view no-wrap">
<a href="{{@app.context}}/policy/edit?id={{id}}&type={{platform}}" <!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/edit?id={{id}}"
data-id="{{id}}" data-id="{{id}}"
data-click-event="remove-form" data-click-event="remove-form"
class="btn padding-reduce-on-grid-view policy-update-link"> class="btn padding-reduce-on-grid-view policy-update-link">
@ -234,7 +249,6 @@
</span> </span>
<span class="hidden-xs hidden-on-grid-view">Re-Configure</span> <span class="hidden-xs hidden-on-grid-view">Re-Configure</span>
</a> </a>
</td> </td>
</tr> </tr>
{{/each}} {{/each}}

@ -10,8 +10,8 @@
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* KIND, either express or implied. See the License for the * either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
@ -37,27 +37,23 @@ function onRequest(context) {
var policyCount = policyListToView.length; var policyCount = policyListToView.length;
if (policyCount == 0) { if (policyCount == 0) {
page["policyListingStatusMsg"] = "No policy is available to be displayed."; page["policyListingStatusMsg"] = "No policy is available to be displayed.";
page["saveNewPrioritiesButtonEnabled"] = false;
page["noPolicy"] = true; page["noPolicy"] = true;
} else if (policyCount == 1) {
page["saveNewPrioritiesButtonEnabled"] = false;
page["noPolicy"] = false;
page["isUpdated"] = response["updated"];
} else { } else {
page["saveNewPrioritiesButtonEnabled"] = true;
page["noPolicy"] = false; page["noPolicy"] = false;
page["isUpdated"] = response["updated"]; page["isUpdated"] = response["updated"];
} }
} else { } else {
// here, response["status"] == "error" // here, response["status"] == "error"
page["policyListToView"] = []; page["policyListingStatusMsg"] = "An unexpected error occurred. Please try again later.";
page["policyListingStatusMsg"] = "An unexpected error occurred @ backend. Please try again later.";
page["saveNewPrioritiesButtonEnabled"] = false;
page["noPolicy"] = true; page["noPolicy"] = true;
} }
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/manage")) { if (userModule.isAuthorized("/permission/admin/device-mgt/policies/remove")) {
page.managePermitted = true; page["removePermitted"] = true;
}
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/update")) {
page["editPermitted"] = true;
} }
page.permissions = userModule.getUIPermissions();
return page; return page;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * Copyright (c) 2015-2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* *
* WSO2 Inc. licenses this file to you under the Apache License, * WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except * Version 2.0 (the "License"); you may not use this file except
@ -10,21 +10,21 @@
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* KIND, either express or implied. See the License for the * either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
/* sorting function */ /* sorting function */
var sortUpdateBtn = "#sortUpdateBtn"; var sortUpdateBtn = "#sortUpdateBtn";
var sortedIDs; // var sortedIDs;
var dataTableSelection = '.DTTT_selected'; // var dataTableSelection = ".DTTT_selected";
var settings = { var settings = {
"sorting": false "sorting": false
}; };
$('#policy-grid').datatables_extended(settings); $('#policy-grid').datatables_extended(settings);
$(".icon .text").res_text(0.2); // $(".icon .text").res_text(0.2);
var saveNewPrioritiesButton = "#save-new-priorities-button"; var saveNewPrioritiesButton = "#save-new-priorities-button";
var saveNewPrioritiesButtonEnabled = Boolean($(saveNewPrioritiesButton).data("enabled")); var saveNewPrioritiesButtonEnabled = Boolean($(saveNewPrioritiesButton).data("enabled"));
@ -41,25 +41,6 @@ function InitiateViewOption() {
$(location).attr('href', $(this).data("url")); $(location).attr('href', $(this).data("url"));
} }
var addSortableIndexNumbers = function () {
$(".wr-sortable .list-group-item").not(".ui-sortable-placeholder").each(function (i) {
$(".wr-sort-index", this).html(i + 1);
});
};
var sortElements = function () {
addSortableIndexNumbers();
var sortableElem = ".wr-sortable";
$(sortableElem).sortable({
beforeStop: function () {
sortedIDs = $(this).sortable("toArray");
addSortableIndexNumbers();
$(sortUpdateBtn).prop("disabled", false);
}
});
$(sortableElem).disableSelection();
};
/** /**
* Modal related stuff are as follows. * Modal related stuff are as follows.
*/ */
@ -129,31 +110,29 @@ function getSelectedPolicies() {
} }
$(document).ready(function () { $(document).ready(function () {
sortElements();
$("#loading-content").remove();
var policyRoles = $("#policy-roles").text(); /**
var policyUsers = $("#policy-users").text(); * ********************************************
* Click functions related to Policy Listing
* ********************************************
*/
if (!policyRoles) { // [1] logic for running apply-changes-for-devices use-case
$("#policy-roles").hide();
}
if (!policyUsers) {
$("#policy-users").hide();
}
if ($("#policy-listing-status-msg").text()) { var applyChangesButtonId = "#appbar-btn-apply-changes";
$("#policy-listing-status").removeClass("hidden");
}
// Click functions related to Policy Listing var isUpdated = $("#is-updated").val();
var isUpdated = $('#is-updated').val();
if (!isUpdated) { if (!isUpdated) {
$('#appbar-btn-apply-changes').addClass('hidden'); // if no updated policies found, hide button from app bar
$(applyChangesButtonId).addClass("hidden");
} else {
// if updated policies found, show button from app bar
$(applyChangesButtonId).removeClass("hidden");
} }
$("#appbar-btn-apply-changes").click(function () { // click-event function for applyChangesButton
var applyPolicyChangesAPI = "/devicemgt_admin/policies/apply-changes"; $(applyChangesButtonId).click(function () {
var serviceURL = "/api/device-mgt/v1.0/policies/apply-changes";
modalDialog.header('Do you really want to apply changes to all policies?'); modalDialog.header('Do you really want to apply changes to all policies?');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-yes-link" class="btn-operations">Yes' + modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-yes-link" class="btn-operations">Yes' +
'</a><a href="#" id="change-policy-cancel-link" class="btn-operations btn-default">No</a></div>'); '</a><a href="#" id="change-policy-cancel-link" class="btn-operations btn-default">No</a></div>');
@ -161,10 +140,11 @@ $(document).ready(function () {
$("a#change-policy-yes-link").click(function () { $("a#change-policy-yes-link").click(function () {
invokerUtil.put( invokerUtil.put(
applyPolicyChangesAPI, serviceURL,
null, null,
// on success // on success
function () { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
modalDialog.header('Done. Changes applied successfully.'); modalDialog.header('Done. Changes applied successfully.');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-success-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-success-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -172,9 +152,11 @@ $(document).ready(function () {
modalDialog.hide(); modalDialog.hide();
location.reload(); location.reload();
}); });
}
}, },
// on error // on error
function () { function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.'); modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-error-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-error-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -191,61 +173,26 @@ $(document).ready(function () {
}); });
}); });
$(sortUpdateBtn).click(function () { // [2] logic for un-publishing a selected set of Active, Active/Updated policies
$(sortUpdateBtn).prop("disabled", true);
var newPolicyPriorityList = [];
var policy;
var i;
for (i = 0; i < sortedIDs.length; i++) {
policy = {};
policy.id = parseInt(sortedIDs[i]);
policy.priority = i + 1;
newPolicyPriorityList.push(policy);
}
var updatePolicyAPI = "/devicemgt_admin/policies/priorities";
invokerUtil.put(
updatePolicyAPI,
newPolicyPriorityList,
function () {
modalDialog.header('Done. New Policy priorities were successfully updated.');
modalDialog.footer('<a href="#" id="save-policy-priorities-success-link" class="btn-operations">Ok' +
'</a>');
modalDialog.show();
$("a#save-policy-priorities-success-link").click(function () {
modalDialog.hide();
});
},
function () {
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.content(html("Message From Server : " + data["statusText"]));
modalDialog.footer('<div class="buttons"><a href="#" id="save-policy-priorities-error-link" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#save-policy-priorities-error-link").click(function () {
modalDialog.hide();
});
}
);
});
$(".policy-unpublish-link").click(function () { $(".policy-unpublish-link").click(function () {
var policyList = getSelectedPolicies(); var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates(); var statusList = getSelectedPolicyStates();
if (($.inArray('Inactive/Updated', statusList) > -1) || ($.inArray('Inactive', statusList) > -1)) { if (($.inArray("Inactive/Updated", statusList) > -1) || ($.inArray("Inactive", statusList) > -1)) {
modalDialog.header('Operation cannot be performed !'); // if policies found in Inactive or Inactive/Updated states with in the selection,
modalDialog.content('You cannot select already inactive policies. Please deselect inactive policies and ' + // pop-up an error saying
'try again.'); // "You cannot select already inactive policies. Please deselect inactive policies and try again."
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' + modalDialog.header('Action cannot be performed !');
'class="btn-operations">Ok</a></div>'); modalDialog.content('You cannot select already inactive policies to be unpublished. Please deselect ' +
'inactive policies and try again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">Ok</a>' +
'</div>');
modalDialog.showAsAWarning(); modalDialog.showAsAWarning();
} else { } else {
var serviceURL = "/devicemgt_admin/policies/inactivate"; var serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
if (policyList == 0) { if (policyList.length == 0) {
modalDialog.header('Operation cannot be performed !'); modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to unpublish.'); modalDialog.content('Please select a policy or a list of policies to un-publish.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' + modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning(); modalDialog.showAsAWarning();
@ -257,12 +204,14 @@ $(document).ready(function () {
modalDialog.show(); modalDialog.show();
} }
// on-click function for policy un-publishing "yes" button
$("a#unpublish-policy-yes-link").click(function () { $("a#unpublish-policy-yes-link").click(function () {
invokerUtil.put( invokerUtil.post(
serviceURL, serviceURL,
policyList, policyList,
// on success // on success
function () { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
modalDialog.header('Done. Selected policy was successfully unpublished.'); modalDialog.header('Done. Selected policy was successfully unpublished.');
modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-success-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -270,9 +219,11 @@ $(document).ready(function () {
modalDialog.hide(); modalDialog.hide();
location.reload(); location.reload();
}); });
}
}, },
// on error // on error
function () { function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.'); modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-error-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-error-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -284,30 +235,35 @@ $(document).ready(function () {
); );
}); });
// on-click function for policy un-publishing "cancel" button
$("a#unpublish-policy-cancel-link").click(function () { $("a#unpublish-policy-cancel-link").click(function () {
modalDialog.hide(); modalDialog.hide();
}); });
} }
}); });
// [3] logic for publishing a selected set of Inactive, Inactive/Updated policies
$(".policy-publish-link").click(function () { $(".policy-publish-link").click(function () {
var policyList = getSelectedPolicies(); var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates(); var statusList = getSelectedPolicyStates();
if (($.inArray('Active/Updated', statusList) > -1) || ($.inArray('Active', statusList) > -1)) { if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
modalDialog.header('Operation cannot be performed !'); // if policies found in Active or Active/Updated states with in the selection,
// pop-up an error saying
// "You cannot select already active policies. Please deselect active policies and try again."
modalDialog.header('Action cannot be performed !');
modalDialog.content('You cannot select already active policies. Please deselect active policies and try ' + modalDialog.content('You cannot select already active policies. Please deselect active policies and try ' +
'again.'); 'again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' + modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' +
'Ok</a></div>'); 'Ok</a></div>');
modalDialog.showAsAWarning(); modalDialog.showAsAWarning();
} else { } else {
var serviceURL = "/devicemgt_admin/policies/activate"; var serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
if (policyList == 0) { if (policyList.length == 0) {
modalDialog.header('Operation cannot be performed !'); modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to publish.'); modalDialog.content('Please select a policy or a list of policies to publish.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' + modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning(); modalDialog.showAsAWarning();
} else { } else {
modalDialog.header('Do you really want to publish the selected policy(s)?'); modalDialog.header('Do you really want to publish the selected policy(s)?');
@ -316,13 +272,14 @@ $(document).ready(function () {
'class="btn-operations btn-default">No</a></div>'); 'class="btn-operations btn-default">No</a></div>');
modalDialog.show(); modalDialog.show();
} }
// on-click function for policy removing "yes" button
$("a#publish-policy-yes-link").click(function () { $("a#publish-policy-yes-link").click(function () {
invokerUtil.put( invokerUtil.post(
serviceURL, serviceURL,
policyList, policyList,
// on success // on success
function () { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
modalDialog.header('Done. Selected policy was successfully published.'); modalDialog.header('Done. Selected policy was successfully published.');
modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-success-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -330,9 +287,11 @@ $(document).ready(function () {
modalDialog.hide(); modalDialog.hide();
location.reload(); location.reload();
}); });
}
}, },
// on error // on error
function () { function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.'); modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-error-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-error-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -344,21 +303,36 @@ $(document).ready(function () {
); );
}); });
// on-click function for policy removing "cancel" button
$("a#publish-policy-cancel-link").click(function () { $("a#publish-policy-cancel-link").click(function () {
modalDialog.hide(); modalDialog.hide();
}); });
} }
}); });
// [4] logic for removing a selected set of policies
$(".policy-remove-link").click(function () { $(".policy-remove-link").click(function () {
var policyList = getSelectedPolicies(); var policyList = getSelectedPolicies();
var deletePolicyAPI = "/devicemgt_admin/policies/bulk-remove"; var statusList = getSelectedPolicyStates();
if (policyList == 0) { if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
modalDialog.header('Operation cannot be performed !'); // if policies found in Active or Active/Updated states with in the selection,
modalDialog.content('Please select a policy or a list of policies to remove.'); // pop-up an error saying
// "You cannot remove already active policies. Please deselect active policies and try again."
modalDialog.header('Action cannot be performed !');
modalDialog.content('You cannot select already active policies. Please deselect active policies and try ' +
'again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' + modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' +
'Ok</a></div>'); 'Ok</a></div>');
modalDialog.showAsAWarning(); modalDialog.showAsAWarning();
} else {
var serviceURL = "/api/device-mgt/v1.0/policies/remove-policy";
if (policyList.length == 0) {
modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to remove.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning();
} else { } else {
modalDialog.header('Do you really want to remove the selected policy(s)?'); modalDialog.header('Do you really want to remove the selected policy(s)?');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-yes-link" class=' + modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-yes-link" class=' +
@ -367,43 +341,26 @@ $(document).ready(function () {
modalDialog.show(); modalDialog.show();
} }
// on-click function for policy removing "yes" button
$("a#remove-policy-yes-link").click(function () { $("a#remove-policy-yes-link").click(function () {
invokerUtil.post( invokerUtil.post(
deletePolicyAPI, serviceURL,
policyList, policyList,
// on success // on success
function (data) { function (data, textStatus, jqXHR) {
data = JSON.parse(data); if (jqXHR.status == 200 && data) {
if (data.errorMessage) {
modalDialog.header('Cannot Remove Policies.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-devices" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#remove-policy-error-devices").click(function () {
modalDialog.hide();
});
} else {
modalDialog.header('Done. Selected policy was successfully removed.'); modalDialog.header('Done. Selected policy was successfully removed.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-success-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-success-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
$("a#remove-policy-success-link").click(function () { $("a#remove-policy-success-link").click(function () {
var thisTable = $(".DTTT_selected").closest('.dataTables_wrapper').find('.dataTable').dataTable();
thisTable.api().rows('.DTTT_selected').remove().draw(false);
modalDialog.hide(); modalDialog.hide();
location.reload();
}); });
} }
}, },
// on error // on error
function (data) { function (jqXHR) {
if (JSON.parse(data.responseText).errorMessage) { console.log(stringify(jqXHR.data));
modalDialog.header('Cannot Remove Policies.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-devices" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#remove-policy-error-devices").click(function () {
modalDialog.hide();
});
} else {
modalDialog.header('An unexpected error occurred. Please try again later.'); modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-link" ' + modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-link" ' +
'class="btn-operations">Ok</a></div>'); 'class="btn-operations">Ok</a></div>');
@ -412,15 +369,19 @@ $(document).ready(function () {
modalDialog.hide(); modalDialog.hide();
}); });
} }
}
); );
}); });
// on-click function for policy removing "cancel" button
$("a#remove-policy-cancel-link").click(function () { $("a#remove-policy-cancel-link").click(function () {
modalDialog.hide(); modalDialog.hide();
}); });
}
}); });
$("#loading-content").remove(); $("#loading-content").remove();
if ($("#policy-listing-status-msg").text()) {
$("#policy-listing-status").removeClass("hidden");
}
$("#policy-grid").removeClass("hidden"); $("#policy-grid").removeClass("hidden");
$(".icon .text").res_text(0.2);
}); });

@ -0,0 +1,14 @@
{{#zone "topCss"}}
{{css "css/codemirror.css"}}
{{/zone}}
<div class="wr-input-control">
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"></textarea>
</div>
<br class="c-both"/>
</div>
{{#zone "bottomJs"}}
{{js "js/codemirror.js"}}
{{js "js/sql.js"}}
{{js "js/editor.js"}}
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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.
*/
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: MIME_TYPE_SIDDHI_QL,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true,
extraKeys: {
"Shift-2": function (cm) {
insertStr(cm, cm.getCursor(), '@');
CodeMirror.showHint(cm, getAnnotationHints);
},
"Ctrl-Space": "autocomplete"
}
});
var validatePolicyProfile = function () {
return true;
};

@ -33,9 +33,23 @@
callback(template); callback(template);
} }
}; };
$.isResourceExists = function (location, callback) {
$.ajax({
url: location,
type: 'HEAD',
success: function () {
callback(true);
},
error: function () {
callback(false);
}
});
};
$.registerPartial = function (name, location, callback) { $.registerPartial = function (name, location, callback) {
$.get(location, function (data) { $.get(location, function (data) {
Handlebars.registerPartial( name, data); Handlebars.registerPartial(name, data);
console.log("Partial " + name + " has been registered"); console.log("Partial " + name + " has been registered");
callback(); callback();
}); });

@ -1,29 +1,11 @@
{{!
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.
}}
{{#zone "content"}} {{#zone "content"}}
{{#if isAuthorized}} {{#if isAuthorized}}
<span id="logged-in-user" class="hidden" data-username="{{user.username}}" data-domain="{{user.domain}}"
data-tenant-id="{{user.tenantId}}"></span>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="container col-centered wr-content policy-platform">
<div class="wr-form"> <div class="wr-steps hidden">
<h1 id="policy-platform-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-platform-wizard-steps" class="row wr-wizard">
<div class="col-md-3 col-xs-3"> <div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-platform"> <div class="itm-wiz itm-wiz-current" data-step="policy-platform">
<div class="wiz-no">1</div> <div class="wiz-no">1</div>
@ -41,7 +23,7 @@
<div class="col-md-3 col-xs-3"> <div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria"> <div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div> <div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign</span></div> <div class="wiz-lbl hidden-xs"><span>Assign to groups</span></div>
</div> </div>
<br class="c-both"/> <br class="c-both"/>
</div> </div>
@ -53,22 +35,281 @@
<br class="c-both"/> <br class="c-both"/>
</div> </div>
</div> </div>
<div class="col-centered policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is
successful.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message"
data-direct="{{@app.context}}/policies/">
View policy list
</button>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add another policy
</a>
</div>
</div>
<div class="col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-naming-wizard-steps" class="row wr-wizard"></div>
<hr> <hr>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<h4>Step 1: Select a platform</h4> <h4 class="hidden-xs">Step 4: Publish to devices</h4>
<br>
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="clearfix">
<label class="wr-input-label">Set a Name for your Policy *</label>
<br/>
<label class="wr-input-label">
(Policy name should be 1-to-30 characters long)
</label>
<div id="policyNameField" class="wr-input-control">
<div class="cus-col-50 form-group wr-input-control">
<!--suppress HtmlFormInputWithoutLabel -->
<input id="policy-name-input" class="form-control" type="text" value=""/>
<label class="error nameEmpty hidden" for="summary">Policy name is required
&
Should be be 1-to-30
characters long.</label>
</div>
<br class="c-both"/>
</div>
<br class="c-both"/>
<label class="wr-input-label">
Add a description
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<textarea id="policy-description-input" class="form-control" rows="10"
placeholder="[ Summary about the policy ]"></textarea>
</div>
<br class="c-both"/>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-naming" data-next="policy-criteria">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-naming-publish" data-next="policy-message"
data-validate="true">Publish</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-naming"
data-next="policy-message" data-validate="true">Save</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-criteria-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs">Step 3: Assign to groups</h4>
<br>
<div id="policy-criteria-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set device ownership type
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="ownership-input" class="form-control">
<option value="ANY" selected>ANY</option>
<option value="BYOD">BYOD (Bring Your Own Device)</option>
<option value="COPE">COPE (Corporate-Owned, Personally Enabled)</option>
</select>
</div>
<br class="c-both"/>
</div>
<div class="wr-input-control">
{{#if isAuthorizedViewRoles}}
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio"
name="select-users-radio-btn"
class="select-users-radio" checked/>
<span class="helper">Set user role(s)</span>
</label>
{{/if}}
{{#if isAuthorizedViewUsers}}
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio"/>
<span class="helper">Set user(s)</span>
</label>
{{/if}}
</div>
{{#if isAuthorizedViewRoles}}
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="user-roles-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
{{#if isAuthorizedViewUsers}}
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="users-input" class="form-control select2"
multiple="multiple">
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
{{#if isAuthorizedViewGroups}}
<label class="wr-input-label">
Select Groups
</label>
<div id="groups-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="groups-input" class="form-control select2"
multiple="multiple">
<option value="NONE" selected>NONE</option>
{{#each groups}}
<option>{{this.name}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
<br> <br>
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="action-input" class="form-control">
<option data-action="enforce" selected>Enforce</option>
<option data-action="warn">Warn</option>
<option data-action="monitor">Monitor</option>
</select>
</div>
<br class="c-both"/>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-criteria" data-next="policy-profile">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-criteria" data-next="policy-naming" data-validate="true">Continue</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-centered wr-content policy-profile hidden">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs">Step 2: Configure profile</h4>
<br>
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class='wr-advance-operations-init'>
<br/>
<i class='fw fw-settings fw-spin fw-2x'></i>
Loading Platform Features . . .
<br/>
<br/>
</div>
<div id="device-type-policy-operations" class="hidden">
</div>
<div id="generic-policy-operations" class="hidden">
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-profile" data-next="policy-platform">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-profile"
data-next="policy-criteria" data-validate="true">Continue</a>
</div>
</div>
</div>
</div>
</div>
<div id="loading-content" class="col-centered">
<br><br>
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading policy creation wizard . . .
<br><br>
</div>
<div class=" col-centered wr-content policy-platform hidden">
<div class="wr-form">
<h1 id="policy-platform-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-platform-wizard-steps" class="row wr-wizard"></div>
<hr>
<!--<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs"> Step 1: Select a platform</h4>
<br>
<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="row wr-tile-buttons-list"> <div class="row wr-tile-buttons-list">
<div class="wr-input-control"> <div class="wr-input-control">
<ul class="tile-buttons row"> <ul class="tile-buttons row">
{{#each types}} {{#each types}}
<li class="col-lg-4" <li class="col-xs-12 col-sm-12 col-md-4 col-lg-4"
style="margin-top: 5px;margin-bottom: 5px;"> style="margin-top: 5px; margin-bottom: 5px;">
<a href="{{@app.context}}/policy/add/{{name}}" <a href="javascript:void(0)"
class="wizard-stepper"> class="{{name}}-platform wizard-stepper"
<img src="{{icon}}" width="50px" data-current="policy-platform"
height="50px"><br><br> data-next="policy-profile"
data-platform="{{name}}"
data-validate="false">
<img src="{{icon}}" width="50px" height="50px"><br><br>
<b>{{label}}</b> <b>{{label}}</b>
</a> </a>
</li> </li>
@ -83,12 +324,8 @@
<!-- content --> <!-- content -->
</div> </div>
</div> </div>
{{else}}
<h1 class="page-sub-title">
Permission Denied
</h1>
<br>
You not authorized to enter Policy Management Section.
<br>
{{/if}} {{/if}}
{{/zone}} {{/zone}}
{{#zone "bottomJs"}}
{{js "/js/policy-create.js"}}
{{/zone}}

@ -23,12 +23,15 @@ function onRequest(context) {
var utility = require("/app/modules/utility.js").utility; var utility = require("/app/modules/utility.js").utility;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"]; var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var groupModule = require("/app/modules/business-controllers/group.js")["groupModule"];
var types = {}; var types = {};
types.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage"); types.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
types.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view"); types.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
types.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view"); types.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
types.isAuthorizedViewGroups = userModule.isAuthorized("/permission/admin/device-mgt/groups/view");
types["types"] = []; types["types"] = [];
var typesListResponse = deviceModule.getDeviceTypes(); var typesListResponse = deviceModule.getDeviceTypes();
if (typesListResponse["status"] == "success") { if (typesListResponse["status"] == "success") {
for (var type in typesListResponse["content"]["deviceTypes"]) { for (var type in typesListResponse["content"]["deviceTypes"]) {
@ -48,5 +51,14 @@ function onRequest(context) {
} }
} }
} }
var user = userModule.getCarbonUser();
types["user"] = {username: user.username, domain: user.domain, tenantId: user.tenantId};
var roles = userModule.getRoles();
if (roles["status"] == "success") {
types["roles"] = roles["content"];
}
types["groups"] = groupModule.getGroups();
return types; return types;
} }

@ -0,0 +1,580 @@
/*
*
* 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 stepForwardFrom = {};
var stepBackFrom = {};
var policy = {};
var configuredOperations = [];
var validateInline = {};
var clearInline = {};
var validateStep = {};
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 loadGroups(callback) {
invokerUtil.get(
"/api/device-mgt/v1.0/groups",
function (data) {
data = JSON.parse(data);
callback(data.deviceGroups);
});
}
var createDeviceGroupWrapper = function (selectedGroups) {
var groupObjects = [];
loadGroups(function (deviceGroups) {
var tenantId = $("#logged-in-user").data("tenant-id");
for (var index in deviceGroups) {
if(deviceGroups.hasOwnProperty(index)) {
var deviceGroupWrapper = {};
if (selectedGroups.indexOf(deviceGroups[index].name) > -1) {
deviceGroupWrapper.id = deviceGroups[index].id;
deviceGroupWrapper.name = deviceGroups[index].name;
deviceGroupWrapper.owner = deviceGroups[index].owner;
deviceGroupWrapper.tenantId = tenantId;
groupObjects.push(deviceGroupWrapper);
}
}
}
});
return groupObjects;
};
/**
*clear inline validation messages.
*/
clearInline["policy-name"] = function () {
disableInlineError("policyNameField", "nameEmpty", "nameError");
};
/**
* Validate if provided policy name is valid against RegEx configures.
*/
validateInline["policy-name"] = function () {
var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policyNameField", "nameEmpty", "nameError");
} else {
enableInlineError("policyNameField", "nameEmpty", "nameError");
}
};
$("#policy-name-input").focus(function(){
clearInline["policy-name"]();
}).blur(function(){
validateInline["policy-name"]();
});
stepForwardFrom["policy-platform"] = function (actionButton) {
$("#device-type-policy-operations").html("").addClass("hidden");
$("#generic-policy-operations").addClass("hidden");
policy["platform"] = $(actionButton).data("platform");
policy["platformId"] = $(actionButton).data("platform-type");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/templates/' + deviceType + '-policy-operations.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/js/' + deviceType + '-policy-operations.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/css/' + deviceType + '-policy-operations.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) {
if (status) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$("#device-type-policy-operations").html(content).removeClass("hidden");
// $("#device-type-policy-operations").removeClass("hidden");
$(".policy-platform").addClass("hidden");
});
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
$(".wr-advance-operations").prepend(script);
}
});
$.isResourceExists(policyOperationsStylesSrc, function (status) {
if (status) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = policyOperationsStylesSrc;
$(".wr-advance-operations").prepend(style);
}
});
} else {
$("#generic-policy-operations").removeClass("hidden");
}
$(".wr-advance-operations-init").addClass("hidden");
});
};
stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
stepBackFrom["policy-profile"] = function () {
// reinitialize configuredOperations
configuredOperations = [];
};
stepForwardFrom["policy-criteria"] = function () {
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(':radio')) {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val();
}
}
}
});
policy["selectedGroups"] = $("#groups-input").val();
if (policy["selectedGroups"].length > 1 || policy["selectedGroups"][0] !== "NONE") {
policy["selectedGroups"] = createDeviceGroupWrapper(policy["selectedGroups"]);
}
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
policy["selectedOwnership"] = $("#ownership-input").val();
//updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
/**
* Checks if provided input is valid against provided length range.
*
* @param input Alphanumeric or non-alphanumeric input
* @param minLength Minimum Required Length
* @param maxLength Maximum Required Length
* @returns {boolean} Returns true if input matches the provided minimum length and maximum length
*/
var inputIsValidAgainstLength = function (input, minLength, maxLength) {
var length = input.length;
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
};
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-platform"] = function () {
return false;
};
validateStep["policy-naming-publish"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, true, "/api/device-mgt/v1.0/policies/");
};
stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, false, "/api/device-mgt/v1.0/policies/");
};
var savePolicy = function (policy, isActive, serviceURL) {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.each(profilePayloads, function (i, item) {
$.each(item.content, function (key, value) {
//cannot add a true check since it will catch value = false as well
if (value === null || value === undefined || value === "") {
item.content[key] = null;
}
});
});
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": policy["selectedOwnership"],
"active": isActive,
"profile": {
"profileName": policy["policyName"],
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
if (policy["selectedUsers"]) {
payload["users"] = policy["selectedUsers"];
} else if (policy["selectedUserRoles"]) {
payload["roles"] = policy["selectedUserRoles"];
} else {
payload["users"] = [];
payload["roles"] = [];
}
if(policy["selectedGroups"]) {
payload["deviceGroups"] = policy["selectedGroups"];
}
invokerUtil.post(
serviceURL,
payload,
function () {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
},
function (data) {
}
);
};
function formatRepo(user) {
if (user.loading) {
return user.text;
}
if (!user.username) {
return;
}
var markup = '<div class="clearfix">' +
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + user.username + '</div>';
if (user.firstname) {
markup += '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + user.firstname + '</div>';
}
if (user.emailAddress) {
markup += '<div class="col-sm-2"><i class="fa fa-star"></i> ' + user.emailAddress + '</div></div>';
}
markup += '</div></div>';
return markup;
}
function formatRepoSelection(user) {
return user.username || user.text;
}
// End of functions related to grid-input-view
$(document).ready(function () {
$("#users-input").select2({
multiple: true,
tags: false,
ajax: {
url: context + "/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (user) {
return user.username;
},
data: function (params) {
var postData = {};
postData.requestMethod = "GET";
postData.requestURL = "/api/device-mgt/v1.0/users/search/usernames?filter=" + params.term;
postData.requestPayload = null;
return JSON.stringify(postData);
},
processResults: function (data) {
var newData = [];
$.each(data, function (index, value) {
value.id = value.username;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
$("#loading-content").remove();
$(".policy-platform").removeClass("hidden");
// Adding initial state of wizard-steps.
$("#policy-platform-wizard-steps").html($(".wr-steps").html());
$("select.select2[multiple=multiple]").select2({
"tags": false
});
$("#users-select-field").hide();
$("#user-roles-select-field").show();
$("input[type='radio'].select-users-radio").change(function () {
if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").show();
}
if ($("#user-roles-radio-btn").is(":checked")) {
$("#users-select-field").hide();
$("#user-roles-select-field").show();
}
});
// Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#groups-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "NONE") {
$(this).val("NONE").trigger("change");
} else {
$("option[value=NONE]", this).prop("selected", false).parent().trigger("change");
}
});
//Policy wizard stepper
$(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current");
var validationIsRequired = $(this).data("validate");
var wizardIsToBeContinued;
if (validationIsRequired) {
if (currentStep == "policy-profile") {
wizardIsToBeContinued = validatePolicyProfile();
} else {
wizardIsToBeContinued = validateStep[currentStep]();
}
} else {
wizardIsToBeContinued = true;
}
if (wizardIsToBeContinued) {
// When moving back and forth, following code segment will
// remove if there are any visible error-messages.
var errorMsgWrappers = ".alert.alert-danger";
$(errorMsgWrappers).each(
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
}
);
var nextStep = $(this).data("next");
var isBackBtn = $(this).data("is-back-btn");
// if current button is a continuation...
if (!isBackBtn) {
// initiate stepForwardFrom[*] functions to gather form data.
if (stepForwardFrom[currentStep]) {
stepForwardFrom[currentStep](this);
}
} else {
// initiate stepBackFrom[*] functions to rollback.
if (stepBackFrom[currentStep]) {
stepBackFrom[currentStep]();
}
}
// following step occurs only at the last stage of the wizard.
if (!nextStep) {
window.location.href = $(this).data("direct");
}
// updating next wizard step as current.
$(".itm-wiz").each(function () {
var step = $(this).data("step");
if (step == nextStep) {
$(this).addClass("itm-wiz-current");
} else {
$(this).removeClass("itm-wiz-current");
}
});
// adding next update of wizard-steps.
$("#" + nextStep + "-wizard-steps").html($(".wr-steps").html());
// hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden");
$("." + nextStep).removeClass("hidden");
}
});
});

@ -1,5 +1,7 @@
{{#zone "content"}} {{#zone "content"}}
{{#if isAuthorized }} {{#if isAuthorized }}
<span id="logged-in-user" class="hidden" data-username="{{user.username}}" data-domain="{{user.domain}}"
data-tenant-id="{{user.tenantId}}"></span>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
@ -35,10 +37,10 @@
<b>"View policy list"</b> to complete the process and go back to the policy list. <b>"View policy list"</b> to complete the process and go back to the policy list.
<hr> <hr>
<button class="wr-btn wizard-stepper" data-current="policy-message" <button class="wr-btn wizard-stepper" data-current="policy-message"
data-direct="/emm/policies/"> data-direct="{{@app.context}}/policies/">
View policy list View policy list
</button> </button>
<a href="/emm/policies/add-policy" class="cu-btn-inner"> <a href="{{@app.context}}/policies/add" class="cu-btn-inner">
<span class="fw-stack"> <span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i> <i class="fw fw-add fw-stack-1x"></i>
@ -135,20 +137,27 @@
<br class="c-both"/> <br class="c-both"/>
</div> </div>
<div class="wr-input-control"> <div class="wr-input-control">
{{#if isAuthorizedViewRoles}}
<label class="wr-input-control radio light"> <label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio" name="select-users-radio-btn" <input id="user-roles-radio-btn" type="radio"
name="select-users-radio-btn"
class="select-users-radio" checked/> class="select-users-radio" checked/>
<span class="helper">Set user role(s)</span> <span class="helper">Set user role(s)</span>
</label> </label>
{{/if}}
{{#if isAuthorizedViewUsers}}
<label class="wr-input-control radio light" rel="assetfilter"> <label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn" <input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio"/> class="select-users-radio"/>
<span class="helper">Set user(s)</span> <span class="helper">Set user(s)</span>
</label> </label>
{{/if}}
</div> </div>
{{#if isAuthorizedViewRoles}}
<div id="user-roles-select-field" class="select-users"> <div id="user-roles-select-field" class="select-users">
<div class="wr-input-control"> <div class="wr-input-control">
<div class="cus-col-50"> <div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="user-roles-input" class="form-control select2" <select id="user-roles-input" class="form-control select2"
multiple="multiple"> multiple="multiple">
<option value="ANY" selected>ANY</option> <option value="ANY" selected>ANY</option>
@ -160,21 +169,40 @@
<br class="c-both"/> <br class="c-both"/>
</div> </div>
</div> </div>
{{/if}}
{{#if isAuthorizedViewUsers}}
<div id="users-select-field" class="select-users"> <div id="users-select-field" class="select-users">
<div class="wr-input-control"> <div class="wr-input-control">
<div class="cus-col-50"> <div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="users-input" class="form-control select2" <select id="users-input" class="form-control select2"
multiple="multiple"> multiple="multiple">
<option value="ANY" selected>ANY</option> </select>
{{#each users}} </div>
<option>{{username}}</option> <br class="c-both"/>
</div>
</div>
{{/if}}
{{#if isAuthorizedViewGroups}}
<label class="wr-input-label">
Select Groups
</label>
<div id="groups-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="groups-input" class="form-control select2"
multiple="multiple">
<option value="NONE" selected>NONE</option>
{{#each groups}}
<option>{{this.name}}</option>
{{/each}} {{/each}}
</select> </select>
</div> </div>
<br class="c-both"/> <br class="c-both"/>
</div> </div>
</div> </div>
<br> {{/if}}
<label class="wr-input-label" title=""> <label class="wr-input-label" title="">
Set an action upon non-compliance Set an action upon non-compliance
</label> </label>
@ -218,13 +246,17 @@
<i class="icon fw fw-error"></i><span></span> <i class="icon fw fw-error"></i><span></span>
</div> </div>
<div class="wr-advance-operations"> <div class="wr-advance-operations">
<div class="wr-advance-operations-init"> <div class='wr-advance-operations-init'>
<br> <br/>
<i class='fw fw-settings fw-spin fw-2x'></i>
<i class="fw fw-settings fw-spin fw-2x"></i> Loading Platform Features . . .
Loading platform features . . . <br/>
<br> <br/>
<br> </div>
<div id="device-type-policy-operations" class="hidden">
</div>
<div id="generic-policy-operations" class="hidden">
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
</div> </div>
</div> </div>
<div class="wr-input-control wr-btn-grp"> <div class="wr-input-control wr-btn-grp">
@ -252,15 +284,5 @@
{{/if}} {{/if}}
{{/zone}} {{/zone}}
{{#zone "bottomJs"}} {{#zone "bottomJs"}}
<!--suppress HtmlUnknownTarget --> {{js "js/policy-edit.js"}}
<script id="hidden-operations-ios" src="{{@unit.publicUri}}/templates/hidden-operations-ios.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-android" src="{{@unit.publicUri}}/templates/hidden-operations-android.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-windows" src="{{@unit.publicUri}}/templates/hidden-operations-windows.hbs"
type="text/x-handlebars-template"></script>
{{js "js/edit.js"}}
{{/zone}} {{/zone}}

@ -18,19 +18,29 @@
function onRequest(context) { function onRequest(context) {
var log = new Log("policy-view-edit-unit backend js"); var log = new Log("policy-view-edit-unit backend js");
log.debug("calling policy-view-edit-unit");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"]; var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var groupModule = require("/app/modules/business-controllers/group.js")["groupModule"];
var rolesResult = userModule.getRoles(); var rolesResult = userModule.getRoles();
if (rolesResult.status == "success") { if (rolesResult.status == "success") {
viewModel.roles = rolesResult.content; context.roles = rolesResult.content;
} }
var usersResult = userModule.getUsers(); var usersResult = userModule.getUsers();
if (usersResult.status == "success") { if (usersResult.status == "success") {
viewModel.users = usersResult.content; context.users = usersResult.content;
} }
viewModel.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
return viewModel; context["groups"] = groupModule.getGroups();
var user = userModule.getCarbonUser();
context["user"] = {username: user.username, domain: user.domain, tenantId: user.tenantId};
context.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
context.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
context.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
context.isAuthorizedViewGroups = userModule.isAuthorized("/permission/admin/device-mgt/groups/view");
return context;
} }

@ -0,0 +1,613 @@
/*
* 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 validateStep = {};
var skipStep = {};
var stepForwardFrom = {};
var stepBackFrom = {};
var configuredOperations = [];
var policy = {};
var currentlyEffected = {};
var validateInline = {};
var clearInline = {};
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 loadGroups(callback) {
invokerUtil.get(
"/api/device-mgt/v1.0/groups",
function (data) {
data = JSON.parse(data);
callback(data.deviceGroups);
});
}
var createDeviceGroupWrapper = function (selectedGroups) {
var groupObjects = [];
loadGroups(function (deviceGroups) {
var tenantId = $("#logged-in-user").data("tenant-id");
for (var index in deviceGroups) {
if(deviceGroups.hasOwnProperty(index)) {
var deviceGroupWrapper = {};
if (selectedGroups.indexOf(deviceGroups[index].name) > -1) {
deviceGroupWrapper.id = deviceGroups[index].id;
deviceGroupWrapper.name = deviceGroups[index].name;
deviceGroupWrapper.owner = deviceGroups[index].owner;
deviceGroupWrapper.tenantId = tenantId;
groupObjects.push(deviceGroupWrapper);
}
}
}
});
return groupObjects;
};
/**
*clear inline validation messages.
*/
clearInline["policy-name"] = function () {
disableInlineError("policy-name-field", "nameEmpty", "nameError");
};
/**
* Validate if provided policy name is valid against RegEx configures.
*/
validateInline["policy-name"] = function () {
var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policy-name-field", "nameEmpty", "nameError");
} else {
enableInlineError("policy-name-field", "nameEmpty", "nameError");
}
};
$("#policy-name-input").focus(function () {
clearInline["policy-name"]();
}).blur(function () {
validateInline["policy-name"]();
});
skipStep["policy-platform"] = function (policyPayloadObj) {
policy["name"] = policyPayloadObj["policyName"];
policy["platform"] = policyPayloadObj["profile"]["deviceType"];
var userRoleInput = $("#user-roles-input");
var ownershipInput = $("#ownership-input");
var userInput = $("#users-input");
var groupsInput = $("#groups-input");
var actionInput = $("#action-input");
var policyNameInput = $("#policy-name-input");
var policyDescriptionInput = $("#policy-description-input");
currentlyEffected["roles"] = policyPayloadObj.roles;
currentlyEffected["users"] = policyPayloadObj.users;
currentlyEffected["groups"] = policyPayloadObj.deviceGroups;
if (currentlyEffected["roles"].length > 0) {
$("#user-roles-radio-btn").prop("checked", true);
$("#user-roles-select-field").show();
$("#users-select-field").hide();
userRoleInput.val(currentlyEffected["roles"]).trigger("change");
} else if (currentlyEffected["users"].length > 0) {
$("#users-radio-btn").prop("checked", true);
$("#users-select-field").show();
$("#user-roles-select-field").hide();
userInput.val(currentlyEffected["users"]).trigger("change");
}
if(currentlyEffected["groups"].length > 0) {
groupsInput.val(currentlyEffected["groups"]).trigger("change");
}
ownershipInput.val(policyPayloadObj.ownershipType);
actionInput.val(policyPayloadObj.compliance);
policyNameInput.val(policyPayloadObj["policyName"]);
policyDescriptionInput.val(policyPayloadObj["description"]);
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/templates/' + deviceType + '-policy-edit.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/js/' + deviceType + '-policy-edit.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/css/' + deviceType + '-policy-edit.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) {
if (status) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$("#device-type-policy-operations").html(content).removeClass("hidden");
$(".policy-platform").addClass("hidden");
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
$(".wr-advance-operations").prepend(script);
var configuredOperations = operationModule.
populateProfile(policy["platform"], policyPayloadObj["profile"]["profileFeaturesList"]);
polulateProfileOperations(configuredOperations);
}
});
});
$.isResourceExists(policyOperationsStylesSrc, function (status) {
if (status) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = policyOperationsStylesSrc;
$(".wr-advance-operations").prepend(style);
}
});
} else {
$("#generic-policy-operations").removeClass("hidden");
}
$(".wr-advance-operations-init").addClass("hidden");
});
};
stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
};
stepForwardFrom["policy-criteria"] = function () {
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(':radio')) {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val();
}
}
}
});
policy["selectedGroups"] = $("#groups-input").val();
if (policy["selectedGroups"].length > 1 || policy["selectedGroups"][0] !== "NONE") {
policy["selectedGroups"] = createDeviceGroupWrapper(policy["selectedGroups"]);
}
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
policy["selectedOwnership"] = $("#ownership-input").val();
// updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
};
/**
* Checks if provided input is valid against provided length range.
*
* @param input Alphanumeric or non-alphanumeric input
* @param minLength Minimum Required Length
* @param maxLength Maximum Required Length
* @returns {boolean} Returns true if input matches the provided minimum length and maximum length
*/
var inputIsValidAgainstLength = function (input, minLength, maxLength) {
var length = input.length;
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
};
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming-publish"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
updatePolicy(policy, "publish");
};
stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
updatePolicy(policy, "save");
};
// End of functions related to grid-input-view
/**
* This method will return query parameter value given its name.
* @param name Query parameter name
* @returns {string} Query parameter value
*/
var getParameterByName = function (name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
};
var updatePolicy = function (policy, state) {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.each(profilePayloads, function (i, item) {
$.each(item.content, function (key, value) {
if (value === null || value === undefined || value === "") {
item.content[key] = null;
}
});
});
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": policy["selectedOwnership"],
"profile": {
"profileName": policy["policyName"],
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
if (policy["selectedUsers"]) {
payload["users"] = policy["selectedUsers"];
payload["roles"] = [];
} else if (policy["selectedUserRoles"]) {
payload["users"] = [];
payload["roles"] = policy["selectedUserRoles"];
} else {
payload["users"] = [];
payload["roles"] = [];
}
if(policy["selectedGroups"]) {
payload["deviceGroups"] = policy["selectedGroups"];
}
var serviceURL = "/api/device-mgt/v1.0/policies/" + getParameterByName("id");
invokerUtil.put(
serviceURL,
payload,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
var policyList = [];
policyList.push(getParameterByName("id"));
if (state == "save") {
serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
$(".add-policy").addClass("hidden");
$(".policy-message").removeClass("hidden");
}
},
// on error
function (jqXHR) {
console.log("error in saving policy. Received error code : " + jqXHR.status);
}
);
} else if (state == "publish") {
serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
}
},
// on error
function (jqXHR) {
console.log("error in publishing policy. Received error code : " + jqXHR.status);
}
);
}
}
},
// on error
function (jqXHR) {
console.log("error in updating policy. Received error code : " + jqXHR.status);
}
);
};
$(document).ready(function () {
// Adding initial state of wizard-steps.
invokerUtil.get(
"/api/device-mgt/v1.0/policies/" + getParameterByName("id"),
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
var policy = JSON.parse(data);
skipStep["policy-platform"](policy);
}
},
// on error
function (jqXHR) {
console.log(jqXHR);
// should be redirected to an error page
}
);
$("input[type='radio'].select-users-radio").change(function () {
if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").show();
}
if ($("#user-roles-radio-btn").is(":checked")) {
$("#users-select-field").hide();
$("#user-roles-select-field").show();
}
});
// Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#groups-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "NONE") {
$(this).val("NONE").trigger("change");
} else {
$("option[value=NONE]", this).prop("selected", false).parent().trigger("change");
}
});
$("#users-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#policy-profile-wizard-steps").html($(".wr-steps").html());
$(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current");
var validationIsRequired = $(this).data("validate");
var wizardIsToBeContinued;
if (validationIsRequired) {
if (currentStep == "policy-profile") {
wizardIsToBeContinued = validatePolicyProfile();
} else {
wizardIsToBeContinued = validateStep[currentStep]();
}
} else {
wizardIsToBeContinued = true;
}
if (wizardIsToBeContinued) {
// When moving back and forth, following code segment will
// remove if there are any visible error-messages.
var errorMsgWrappers = ".alert.alert-danger";
$(errorMsgWrappers).each(
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
}
);
var nextStep = $(this).data("next");
var isBackBtn = $(this).data("is-back-btn");
// if current button is a continuation...
if (!isBackBtn) {
// initiate stepForwardFrom[*] functions to gather form data.
if (stepForwardFrom[currentStep]) {
stepForwardFrom[currentStep](this);
}
} else {
// initiate stepBackFrom[*] functions to rollback.
if (stepBackFrom[currentStep]) {
stepBackFrom[currentStep]();
}
}
// following step occurs only at the last stage of the wizard.
if (!nextStep) {
window.location.href = $(this).data("direct");
}
// updating next wizard step as current.
$(".itm-wiz").each(function () {
var step = $(this).data("step");
if (step == nextStep) {
$(this).addClass("itm-wiz-current");
} else {
$(this).removeClass("itm-wiz-current");
}
});
// adding next update of wizard-steps.
$("#" + nextStep + "-wizard-steps").html($(".wr-steps").html());
// hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden");
$("." + nextStep).removeClass("hidden");
}
});
});

@ -1,5 +1,4 @@
/* /*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* *
* WSO2 Inc. licenses this file to you under the Apache License, * WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except * Version 2.0 (the "License"); you may not use this file except
@ -10,8 +9,8 @@
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* KIND, either express or implied. See the License for the * either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
@ -21,60 +20,120 @@ var stepForwardFrom = {};
var stepBackFrom = {}; var stepBackFrom = {};
var policy = {}; var policy = {};
var configuredOperations = []; var configuredOperations = [];
var deviceTypeLabel; var validateInline = {};
var clearInline = {};
/** var enableInlineError = function (inputField, errorMsg, errorSign) {
* Method to update the visibility of grouped input. var fieldIdentifier = "#" + inputField;
* @param domElement HTML grouped-input element with class name "grouped-input" var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
*/ var errorSignIdentifier = "#" + inputField + " ." + errorSign;
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) { if (inputField) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) { $(fieldIdentifier).addClass(" has-error has-feedback");
$(".grouped-child-input:first", domElement).removeClass("disabled");
} }
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false); if (errorMsg) {
}); $(errorMsgIdentifier).removeClass(" hidden");
} else {
if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).addClass("disabled");
} }
$(".child-input", domElement).each(function () {
$(this).prop('disabled', true); 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");
} }
}; };
/** /**
* Checks if provided number is valid against a range. *clear inline validation messages.
*
* @param numberInput Number Input
* @param min Minimum Limit
* @param max Maximum Limit
* @returns {boolean} Returns true if input is within the specified range
*/ */
var inputIsValidAgainstRange = function (numberInput, min, max) { clearInline["policy-name"] = function () {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max); disableInlineError("policyNameField", "nameEmpty", "nameError");
}; };
/** /**
* Checks if provided input is valid against RegEx input. * Validate if provided policy name is valid against RegEx configures.
*
* @param regExp Regular expression
* @param input Input string to check
* @returns {boolean} Returns true if input matches RegEx
*/ */
var inputIsValidAgainstRegExp = function (regExp, input) { validateInline["policy-name"] = function () {
return regExp.test(input); var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policyNameField", "nameEmpty", "nameError");
} else {
enableInlineError("policyNameField", "nameEmpty", "nameError");
}
}; };
validateStep["policy-profile"] = function () { $("#policy-name-input").focus(function(){
return true; clearInline["policy-name"]();
}).blur(function(){
validateInline["policy-name"]();
});
stepForwardFrom["policy-platform"] = function (actionButton) {
policy["platform"] = $(actionButton).data("platform");
policy["platformId"] = $(actionButton).data("platform-type");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/templates/' + deviceType + '-policy-operations.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/js/' + deviceType + '-policy-operations.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/css/' + deviceType + '-policy-operations.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) {
if (status) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$(".wr-advance-operations").html(content);
$(".policy-platform").addClass("hidden");
});
}
});
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
$(".wr-advance-operations").prepend(script);
}
});
$.isResourceExists(policyOperationsStylesSrc, function (status) {
if (status) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = policyOperationsStylesSrc;
$(".wr-advance-operations").prepend(style);
}
});
}; };
stepForwardFrom["policy-profile"] = function () { stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform // updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY"); $("#policy-criteria-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
}; };
stepBackFrom["policy-profile"] = function () { stepBackFrom["policy-profile"] = function () {
@ -86,9 +145,7 @@ stepBackFrom["policy-profile"] = function () {
$(".wr-advance-operations").html( $(".wr-advance-operations").html(
"<div class='wr-advance-operations-init'>" + "<div class='wr-advance-operations-init'>" +
"<br>" + "<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
"<i class='fw fw-settings fw-spin fw-2x'></i>" + "<i class='fw fw-settings fw-spin fw-2x'></i>" +
"&nbsp;&nbsp;&nbsp;&nbsp;" +
"Loading Platform Features . . ." + "Loading Platform Features . . ." +
"<br>" + "<br>" +
"<br>" + "<br>" +
@ -102,18 +159,18 @@ stepForwardFrom["policy-criteria"] = function () {
if ($(this).is(":checked")) { if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") { if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val(); policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") { } else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val(); policy["selectedUserRoles"] = $("#user-roles-input").val();
} else if ($(this).attr("id") == "groups-radio-btn") {
policy["selectedUserGroups"] = $("#groups-input").val();
} }
} }
} }
}); });
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action"); policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
policy["selectedOwnership"] = $("#ownership-input").val(); policy["selectedOwnership"] = $("#ownership-input").val();
// updating next-page wizard title with selected platform //updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY"); $("#policy-naming-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
}; };
/** /**
@ -129,6 +186,44 @@ var inputIsValidAgainstLength = function (input, minLength, maxLength) {
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength); return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
}; };
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming"] = function () { validateStep["policy-naming"] = function () {
var validationStatus = {}; var validationStatus = {};
@ -141,7 +236,7 @@ validateStep["policy-naming"] = function () {
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) { } else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true; validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length. Please check."; "Policy name exceeds maximum allowed length.";
} else { } else {
validationStatus["error"] = false; validationStatus["error"] = false;
} }
@ -162,6 +257,10 @@ validateStep["policy-naming"] = function () {
return wizardIsToBeContinued; return wizardIsToBeContinued;
}; };
validateStep["policy-platform"] = function () {
return false;
};
validateStep["policy-naming-publish"] = function () { validateStep["policy-naming-publish"] = function () {
var validationStatus = {}; var validationStatus = {};
@ -174,7 +273,7 @@ validateStep["policy-naming-publish"] = function () {
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) { } else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true; validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length. Please check."; "Policy name exceeds maximum allowed length.";
} else { } else {
validationStatus["error"] = false; validationStatus["error"] = false;
} }
@ -199,34 +298,48 @@ stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val(); policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val(); policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated. //All data is collected. Policy can now be updated.
savePolicy(policy, "publish"); savePolicy(policy, true, "/api/device-mgt/v1.0/policies/");
}; };
stepForwardFrom["policy-naming"] = function () { stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val(); policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val(); policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated. //All data is collected. Policy can now be updated.
savePolicy(policy, "save"); savePolicy(policy, false, "/api/device-mgt/v1.0/policies/");
}; };
var savePolicy = function (policy, state) { var savePolicy = function (policy, isActive, serviceURL) {
var profilePayloads = [{ var profilePayloads = [];
"featureCode": "CONFIG", // traverses key by key in policy["profile"]
"deviceTypeId": policy["platformId"], var key;
"content": {"policyDefinition": window.queryEditor.getValue()} for (key in policy["profile"]) {
}]; if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.each(profilePayloads, function (i, item) {
$.each(item.content, function (key, value) {
//cannot add a true check since it will catch value = false as well
if (value === null || value === undefined || value === "") {
item.content[key] = null;
}
});
});
var payload = { var payload = {
"policyName": policy["policyName"], "policyName": policy["policyName"],
"description": policy["description"], "description": policy["description"],
"compliance": policy["selectedNonCompliantAction"], "compliance": policy["selectedNonCompliantAction"],
"ownershipType": "ANY", "ownershipType": policy["selectedOwnership"],
"active": (state != "save"), "active": isActive,
"profile": { "profile": {
"profileName": policy["policyName"], "profileName": policy["policyName"],
"deviceType": { "deviceType": policy["platform"],
"id": policy["platformId"],
"name": policy["platform"]
},
"profileFeaturesList": profilePayloads "profileFeaturesList": profilePayloads
} }
}; };
@ -241,93 +354,21 @@ var savePolicy = function (policy, state) {
} }
invokerUtil.post( invokerUtil.post(
"/api/device-mgt/v1.0/policies", serviceURL,
payload, payload,
function (response) { function () {
response = JSON.parse(response);
if (response["statusCode"] == 201) {
$(".add-policy").addClass("hidden"); $(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden"); $(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden"); $(".policy-message").removeClass("hidden");
if (state == "publish") {
publishToDevice();
}
}
}, },
function (err) { function (data) {
console.log(err);
} }
); );
}; };
function publishToDevice() {
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": "ANY",
"deviceId": getParameterByName('deviceId'),
"profile": {
"profileName": policy["policyName"],
"deviceType": {
"id": policy["platformId"],
"name": policy["platform"]
},
"policyDefinition": window.queryEditor.getValue(),
"policyDescription": policy["description"]
}
};
var successCallback = function (data, status) {
console.log("Data: " + data + "\nStatus: " + status);
};
var data = {
url: "/devicemgt/api/policies/add",
type: "POST",
contentType: "application/json",
accept: "application/json",
success: successCallback,
data: JSON.stringify(payload)
};
$.ajax(data).fail(function (jqXHR) {
console.log("Error: " + jqXHR);
});
}
// Start of functions related to grid-input-view
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var setId = function (addFormContainer) {
$(addFormContainer).find("[data-add-form-clone]").each(function (i) {
$(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1));
if ($(this).find(".index").length > 0) {
$(this).find(".index").html(i + 1);
}
});
};
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var showHideHelpText = function (addFormContainer) {
var helpText = "[data-help-text=add-form]";
if ($(addFormContainer).find("[data-add-form-clone]").length > 0) {
$(addFormContainer).find(helpText).hide();
} else {
$(addFormContainer).find(helpText).show();
}
};
function formatRepo(user) { function formatRepo(user) {
if (user.loading) { if (user.loading) {
return user.text return user.text;
} }
if (!user.username) { if (!user.username) {
return; return;
@ -350,56 +391,15 @@ function formatRepoSelection(user) {
return user.username || user.text; return user.username || user.text;
} }
function formatGroupRepo(group) {
if (group.loading) {
return group.text
}
if (!group.name) {
return;
}
var markup = '<div class="clearfix">' +
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + group.name + '</div>';
if (group.name) {
markup += '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + group.name + '</div>';
}
if (group.owner) {
markup += '<div class="col-sm-2"><i class="fa fa-star"></i> ' + group.owner + '</div></div>';
}
markup += '</div></div>';
return markup;
}
function formatGroupRepoSelection(group) {
return group.name || group.text;
}
// End of functions related to grid-input-view // End of functions related to grid-input-view
$(document).ready(function () { $(document).ready(function () {
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: MIME_TYPE_SIDDHI_QL,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true,
extraKeys: {
"Shift-2": function (cm) {
insertStr(cm, cm.getCursor(), '@');
CodeMirror.showHint(cm, getAnnotationHints);
},
"Ctrl-Space": "autocomplete"
}
});
$("#users-input").select2({ $("#users-input").select2({
multiple: true, multiple: true,
tags: true, tags: false,
ajax: { ajax: {
url: window.location.origin + "/devicemgt/api/invoker/execute/", url: context + "/api/invoker/execute/",
method: "POST", method: "POST",
dataType: 'json', dataType: 'json',
delay: 250, delay: 250,
@ -408,18 +408,14 @@ $(document).ready(function () {
}, },
data: function (params) { data: function (params) {
var postData = {}; var postData = {};
postData.actionMethod = "GET"; postData.requestMethod = "GET";
postData.actionUrl = "/devicemgt_admin/users"; postData.requestURL = "/api/device-mgt/v1.0/users/search/usernames?filter=" + params.term;
postData.actionPayload = JSON.stringify({ postData.requestPayload = null;
q: params.term, // search term
page: params.page
});
return JSON.stringify(postData); return JSON.stringify(postData);
}, },
processResults: function (data, page) { processResults: function (data) {
var newData = []; var newData = [];
$.each(data.responseContent, function (index, value) { $.each(data, function (index, value) {
value.id = value.username; value.id = value.username;
newData.push(value); newData.push(value);
}); });
@ -437,83 +433,32 @@ $(document).ready(function () {
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
}); });
$("#groups-input").select2({ $("#loading-content").remove();
multiple: true, $(".policy-platform").removeClass("hidden");
tags: true,
ajax: {
url: window.location.origin + "/devicemgt/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (group) {
return group.name;
},
data: function (params) {
var postData = {};
postData.actionMethod = "GET";
var username = $("#platform").data("username");
postData.actionUrl = "/devicemgt_admin/groups/user/" + username +
"/search?groupName=" + params.term;
return JSON.stringify(postData);
},
processResults: function (data, page) {
var newData = [];
$.each(data, function (index, value) {
value.id = value.name;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatGroupRepo, // omitted for brevity, see the source of this page
templateSelection: formatGroupRepoSelection // omitted for brevity, see the source of this page
});
// Adding initial state of wizard-steps. // Adding initial state of wizard-steps.
$("#policy-profile-wizard-steps").html($(".wr-steps").html()); $("#policy-platform-wizard-steps").html($(".wr-steps").html());
policy["platform"] = $("#platform").data("platform");
policy["platformId"] = $("#platform").data("platform-id");
deviceTypeLabel = $("#platform").data("platform-label");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY");
$("select.select2[multiple=multiple]").select2({ $("select.select2[multiple=multiple]").select2({
"tags": true "tags": false
}); });
$("#users-select-field").hide(); $("#users-select-field").hide();
$("#groups-select-field").hide();
$("#user-roles-select-field").show(); $("#user-roles-select-field").show();
$("input[type='radio'].select-users-radio").change(function () { $("input[type='radio'].select-users-radio").change(function () {
if ($("#user-roles-radio-btn").is(":checked")) {
$("#user-roles-select-field").show();
$("#users-select-field").hide();
$("#groups-select-field").hide();
}
if ($("#users-radio-btn").is(":checked")) { if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide(); $("#user-roles-select-field").hide();
$("#users-select-field").show(); $("#users-select-field").show();
$("#groups-select-field").hide();
} }
if ($("#groups-radio-btn").is(":checked")) { if ($("#user-roles-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").hide(); $("#users-select-field").hide();
$("#groups-select-field").show(); $("#user-roles-select-field").show();
} }
}); });
// Support for special input type "ANY" on user(s) & user-role(s) selection // Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({ $("#user-roles-input").select2({
"tags": true "tags": false
}).on("select2:select", function (e) { }).on("select2:select", function (e) {
if (e.params.data.id == "ANY") { if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change"); $(this).val("ANY").trigger("change");
@ -522,152 +467,7 @@ $(document).ready(function () {
} }
}); });
// Maintains an array of configured features of the profile //Policy wizard stepper
var advanceOperations = ".wr-advance-operations";
$(advanceOperations).on("click", ".wr-input-control.switch", function (event) {
var operationCode = $(this).parents(".operation-data").data("operation-code");
var operation = $(this).parents(".operation-data").data("operation");
var operationDataWrapper = $(this).data("target");
// prevents event bubbling by figuring out what element it's being called from.
if (event.target.tagName == "INPUT") {
var featureConfiguredIcon;
if ($("input[type='checkbox']", this).is(":checked")) {
configuredOperations.push(operationCode);
// when a feature is enabled, if "zero-configured-features" msg is available, hide that.
var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg";
if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) {
$(zeroConfiguredOperationsErrorMsg).addClass("hidden");
}
// add configured-state-icon to the feature
featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
} else {
//splicing the array if operation is present.
var index = $.inArray(operationCode, configuredOperations);
if (index != -1) {
configuredOperations.splice(index, 1);
}
// when a feature is disabled, clearing all its current configured, error or success states
var subErrorMsgWrapper = "#" + operation + "-feature-error-msg";
var subErrorIcon = "#" + operation + "-error";
var subOkIcon = "#" + operation + "-ok";
featureConfiguredIcon = "#" + operation + "-configured";
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// reinitializing input fields into the defaults
$(operationDataWrapper + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(operationDataWrapper + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(operationDataWrapper + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(operationDataWrapper + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
}
});
// adding support for cloning multiple profiles per feature with cloneable class definitions
$(advanceOperations).on("click", ".multi-view.add.enabled", function () {
// get a copy of .cloneable and create new .cloned div element
var cloned = "<div class='cloned'><hr>" + $(".cloneable", $(this).parent().parent()).html() + "</div>";
// append newly created .cloned div element to panel-body
$(this).parent().parent().append(cloned);
// enable remove action of newly cloned div element
$(".cloned", $(this).parent().parent()).each(
function () {
if ($(".multi-view.remove", this).hasClass("disabled")) {
$(".multi-view.remove", this).removeClass("disabled");
}
if (!$(".multi-view.remove", this).hasClass("enabled")) {
$(".multi-view.remove", this).addClass("enabled");
}
}
);
});
$(advanceOperations).on("click", ".multi-view.remove.enabled", function () {
$(this).parent().remove();
});
// enabling or disabling grouped-input based on the status of a parent check-box
$(advanceOperations).on("click", ".grouped-input", function () {
updateGroupedInputVisibility(this);
});
// add form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=add-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().
find("[data-add-form-element=clone]").attr("data-add-form-clone", $(this).attr("href"));
// adding class .child-input to capture text-input-array-values
$("input, select", clonedForm).addClass("child-input");
$(addFormContainer).append(clonedForm);
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// remove form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=remove-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
$(this).closest("[data-add-form-element=clone]").remove();
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
$(".wizard-stepper").click(function () { $(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button. // button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current"); var currentStep = $(this).data("current");
@ -728,16 +528,7 @@ $(document).ready(function () {
// hiding current section of the wizard and showing next section. // hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden"); $("." + currentStep).addClass("hidden");
if (nextStep !== "policy-message") {
$("." + nextStep).removeClass("hidden"); $("." + nextStep).removeClass("hidden");
} }
}
}); });
}); });
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

@ -1,41 +1,7 @@
{{#zone "topCss"}} <span id="platform" class="hidden" data-platform="{{type.name}}" data-platform-label="{{type.label}}"
{{css "css/codemirror.css"}} data-username="{{username}}"></span>
{{/zone}}
<span id="platform" class="hidden" data-platform="{{type.name}}" data-platform-id="{{type.id}}"
data-platform-label="{{type.label}}" data-username="{{username}}"></span>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-platform">
<div class="wiz-no">1</div>
<div class="wiz-lbl hidden-xs"><span>Select a platform</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-profile">
<div class="wiz-no">2</div>
<div class="wiz-lbl hidden-xs"><span>Configure profile</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming">
<div class="wiz-no">4</div>
<div class="wiz-lbl hidden-xs"><span>Publish to devices</span></div>
</div>
<br class="c-both"/>
</div>
</div>
<div class="container col-centered wr-content policy-message hidden"> <div class="container col-centered wr-content policy-message hidden">
<div class="wr-form"> <div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is <h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is
@ -247,18 +213,11 @@
<div class="col-lg-12"> <div class="col-lg-12">
<h4>Step 2: Configure profile</h4> <h4>Step 2: Configure profile</h4>
<br> <br>
<label class="wr-input-label"> <label class="wr-input-label">
Set device specific configuration instructions Set device specific configuration instructions
</label> </label>
<div class="wr-advance-operations"> <div class="wr-advance-operations">
<div class="wr-input-control"> {{unit "cdmf.unit.device.type.generic.policy-wizard"}}
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"
style="width: 100%;" required></textarea>
</div>
<br class="c-both"/>
</div>
</div> </div>
<div class="wr-input-control wr-btn-grp"> <div class="wr-input-control wr-btn-grp">
<a href="javascript:window.history.back()" <a href="javascript:window.history.back()"
@ -281,7 +240,5 @@
</div> </div>
</div> </div>
{{#zone "bottomJs"}} {{#zone "bottomJs"}}
{{js "js/codemirror.js"}}
{{js "js/sql.js"}}
{{js "js/policy-create.js"}} {{js "js/policy-create.js"}}
{{/zone}} {{/zone}}

@ -17,7 +17,7 @@
*/ */
function onRequest(context) { function onRequest(context) {
//var log = new Log("wizard.js"); // var log = new Log("wizard.js");
var constants = require("/app/modules/constants.js"); var constants = require("/app/modules/constants.js");
var DTYPE_CONF_DEVICE_TYPE_KEY = "deviceType"; var DTYPE_CONF_DEVICE_TYPE_KEY = "deviceType";
var DTYPE_CONF_DEVICE_TYPE_LABEL_KEY = "label"; var DTYPE_CONF_DEVICE_TYPE_LABEL_KEY = "label";
@ -32,15 +32,11 @@ function onRequest(context) {
var deviceType = context.uriParams.deviceType; var deviceType = context.uriParams.deviceType;
var typesListResponse = userModule.getPlatforms(); var typesListResponse = userModule.getPlatforms();
if (typesListResponse["status"] == "success") { if (typesListResponse["status"] == "success") {
for (var type in typesListResponse["content"]) { wizardPage["type"] = {};
if (deviceType == typesListResponse["content"][type]["name"]) { for (var type in typesListResponse["content"]["deviceTypes"]) {
wizardPage["type"] = typesListResponse["content"][type]; if (deviceType == typesListResponse["content"]["deviceTypes"][type]) {
var deviceTypeLabel = deviceType; wizardPage["type"]["name"] = deviceType;
var configs = utility.getDeviceTypeConfig(deviceType); wizardPage["type"]["label"] = deviceType;
if (configs && configs[DTYPE_CONF_DEVICE_TYPE_KEY][DTYPE_CONF_DEVICE_TYPE_LABEL_KEY]) {
deviceTypeLabel = configs[DTYPE_CONF_DEVICE_TYPE_KEY][DTYPE_CONF_DEVICE_TYPE_LABEL_KEY];
}
wizardPage["type"]["label"] = deviceTypeLabel;
} }
} }
} }

Loading…
Cancel
Save