Merge pull request #442 from madawas/IOTS-296

Generalizing policy UI for windows device type
revert-dabc3590
Madawa Soysa 8 years ago committed by GitHub
commit c4ac1db382

@ -55,6 +55,13 @@ var updateGroupedInputVisibility = function (domElement) {
}
};
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param configuredOperations selected configurations.
*/
var polulateProfileOperations = function (configuredOperations) {
$(".wr-advance-operations li.grouped-input").each(function () {
updateGroupedInputVisibility(this);
@ -80,6 +87,13 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
@ -528,6 +542,30 @@ var validatePolicyProfile = function () {
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
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]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');

@ -67,6 +67,13 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
@ -515,6 +522,30 @@ var validatePolicyProfile = function () {
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
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]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');

@ -0,0 +1,578 @@
/*
* 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.
*/
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION": "passcode-policy",
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION": "camera",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION": "encrypt-storage",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE"
};
/**
* Method to update the visibility of grouped input.
* @param domElement HTML grouped-input element with class name "grouped-input"
*/
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).removeClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false);
});
} 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);
});
}
};
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param configuredOperations selected configurations.
*/
var polulateProfileOperations = function (configuredOperations) {
$(".wr-advance-operations li.grouped-input").each(function () {
updateGroupedInputVisibility(this);
});
for (var i = 0; i < configuredOperations.length; ++i) {
var configuredOperation = configuredOperations[i];
$(".operation-data").filterByData("operation-code", configuredOperation)
.find(".panel-title .wr-input-control.switch input[type=checkbox]").each(function () {
$(this).click();
});
}
};
/**
* Checks if provided number is valid against a range.
*
* @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) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
var operation;
// starting validation process and updating validationStatus
if (configuredOperations.length == 0) {
// updating validationStatus
validationStatus = {
"error": true,
"mainErrorMsg": "You cannot continue. Zero configured features."
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
} else {
// validating each and every configured Operation
// Validating PASSCODE_POLICY
if ($.inArray(windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) {
// if PASSCODE_POLICY is configured
operation = windowsOperationConstants["PASSCODE_POLICY_OPERATION"];
// initializing continueToCheckNextInputs to true
var continueToCheckNextInputs = true;
// validating first input: passcodePolicyMaxPasscodeAgeInDays
var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val();
if (passcodePolicyMaxPasscodeAgeInDays) {
if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
// validating second and last input: passcodePolicyPasscodeHistory
if (continueToCheckNextInputs) {
var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val();
if (passcodePolicyPasscodeHistory) {
if (!$.isNumeric(passcodePolicyPasscodeHistory)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
}
// at-last, if the value of continueToCheckNextInputs is still true
// this means that no error is found
if (continueToCheckNextInputs) {
validationStatus = {
"error": false,
"okFeature": operation
};
}
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating CAMERA
if ($.inArray(windowsOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) {
// if CAMERA is configured
operation = windowsOperationConstants["CAMERA_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating ENCRYPT_STORAGE
if ($.inArray(windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) {
// if ENCRYPT_STORAGE is configured
operation = windowsOperationConstants["ENCRYPT_STORAGE_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
}
// ending validation process
// start taking specific notifying actions upon validation
var wizardIsToBeContinued;
var errorCount = 0;
var mainErrorMsgWrapper, mainErrorMsg,
subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon;
var i;
for (i = 0; i < validationStatusArray.length; i++) {
validationStatus = validationStatusArray[i];
if (validationStatus["error"]) {
errorCount++;
if (validationStatus["mainErrorMsg"]) {
mainErrorMsgWrapper = "#policy-profile-main-error-msg";
mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else if (validationStatus["subErrorMsg"]) {
subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg";
subErrorMsg = subErrorMsgWrapper + " span";
subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error";
subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating error state and corresponding messages
$(subErrorMsg).text(validationStatus["subErrorMsg"]);
if ($(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).removeClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if ($(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).removeClass("hidden");
}
}
} else {
if (validationStatus["okFeature"]) {
subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg";
subErrorIcon = "#" + validationStatus["okFeature"] + "-error";
subOkIcon = "#" + validationStatus["okFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating success state and corresponding messages
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if ($(subOkIcon).hasClass("hidden")) {
$(subOkIcon).removeClass("hidden");
}
}
}
}
wizardIsToBeContinued = (errorCount == 0);
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (key == windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]) {
policy["profile"][key].enablePassword = true;
}
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');
$(button).siblings().removeClass('selected');
var hiddenOperation = ".wr-hidden-operations-content > div";
$(hiddenOperation + '[data-operation="' + operation + '"]').show();
$(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide();
};
/**
* Method to slide down a provided pane upon provided value set.
*
* @param selectElement Select HTML Element to consider
* @param paneID HTML ID of div element to slide down
* @param valueSet Applicable Value Set
*/
var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) {
var selectedValueOnChange = $(selectElement).find("option:selected").val();
if ($(selectElement).is("input:checkbox")) {
selectedValueOnChange = $(selectElement).is(":checked").toString();
}
var i, slideDownVotes = 0;
for (i = 0; i < valueSet.length; i++) {
if (selectedValueOnChange == valueSet[i]) {
slideDownVotes++;
}
}
var paneSelector = "#" + paneID;
if (slideDownVotes > 0) {
if (!$(paneSelector).hasClass("expanded")) {
$(paneSelector).addClass("expanded");
}
$(paneSelector).slideDown();
} else {
if ($(paneSelector).hasClass("expanded")) {
$(paneSelector).removeClass("expanded");
}
$(paneSelector).slideUp();
/* now follows the code to reinitialize all inputs of the slidable pane */
// reinitializing input fields into the defaults
$(paneSelector + " 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
$(paneSelector + " 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
$(paneSelector + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(paneSelector + " .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();
}
}
);
}
};
// End of HTML embedded invoke methods
// 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();
}
};
$(document).ready(function () {
// Maintains an array of configured features of the profile
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();
}
}
);
}
}
});
// <start - fixing feature-configuring switch double-click issue>
$(advanceOperations).on('hidden.bs.collapse', function (event) {
var collapsedFeatureBody = event.target.id;
var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == true) {
$(featureConfiguringSwitch).prop("checked", false);
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
});
$(advanceOperations).on('shown.bs.collapse', function (event) {
var expandedFeatureBody = event.target.id;
var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == false) {
$(featureConfiguringSwitch).prop("checked", true);
}
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
});
// <end - fixing feature-configuring switch double-click issue>
// 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);
});
});

@ -0,0 +1,402 @@
<div class="row no-gutter">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('passcode-policy', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-key fw-stack-2x"></i>
</span>Passcode Policy
<span id="passcode-policy-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="passcode-policy-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('camera', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-block fw-stack-2x"></i>
</span>
Restrictions on Camera
<span id="camera-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="camera-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span class="camera-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('encrypt-storage', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security fw-stack-2x"></i>
</span>
Encryption Settings
<span id="encrypt-storage-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="encrypt-storage-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-error" class="encryption-error status-icon hidden"><i
class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('app-restriction', this)">
<span class="fw-stack fw-lg">
<i class="fw fw-application fw-stack-1x"></i>
<i class="fw fw-block fw-stack-2x"></i>
</span>
Applications Restrictions
<span id="app-restriction-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="app-restriction-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
</div>
<div class="wr-hidden-operations-content col-lg-8">
<!-- passcode-policy -->
<div class="wr-hidden-operation" data-operation="passcode-policy" style="display: block">
<div class="panel panel-default operation-data" data-operation="passcode-policy"
data-operation-code="PASSCODE_POLICY">
<div id="passcode-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Passcode Policy
<label id="passcode-policy-lbl" class="wr-input-control switch" data-toggle="collapse"
data-target="#passcode-policy-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to set a passcode policy to an Windows Device.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</div>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="passcode-policy-body">
<hr/>
<div id="passcode-policy-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-allow-simple" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyAllowSimple"
checked="checked"/>
<span class="helper"
title="Permit the use of repeating, ascending and descending character sequences">
Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-require-alphanumeric" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyRequireAlphanumeric"
checked="checked"/>
<span class="helper" title="Require passcode to contain both letters and numbers">
Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-length" class="form-control operationDataKeys"
data-key="passcodePolicyMinLength" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper"
title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-complex-chars" class="form-control operationDataKeys"
data-key="passcodePolicyMinComplexChars" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or none )
</label>
<input id="passcode-policy-max-passcode-age-in-days" type="text"
class="form-control operationDataKeys" data-key="passcodePolicyMaxPasscodeAgeInDays"
maxlength="3" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-passcode-history">
Passcode history
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or none )
</label>
<input id="passcode-policy-passcode-history" type="text" class="form-control operationDataKeys"
data-key="passcodePolicyPasscodeHistory" maxlength="2"
placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcodePolicyMaxFailedAttempts">
Maximum number of failed attempts
<span class="helper" title="Maximum number of passcode entry attempts allowed before all
data on a device will be erased">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-max-failed-attempts" class="form-control operationDataKeys"
data-key="passcodePolicyMaxFailedAttempts" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
<!-- /passcode-policy -->
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
<div id="camera-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Restrictions on Camera
<label class="wr-input-control switch" data-toggle="collapse" data-target="#camera-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to restrict the usage of camera on an Windows device together
with all the applications using the camera.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</div>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="camera-body">
<hr/>
<div id="camera-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable camera.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="camera-enabled" type="checkbox" class="operationDataKeys"
data-key="cameraEnabled" checked="checked"/>
<span class="helper" title="Having this checked would enable Usage of phone camera in
the device.">
Allow use of camera
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /camera -->
<!-- encrypt-storage -->
<div class="wr-hidden-operation" data-operation="encrypt-storage">
<div class="panel panel-default operation-data" data-operation="encrypt-storage"
data-operation-code="ENCRYPT_STORAGE">
<div id="encrypt-storage-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Encryption Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#encrypt-storage-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to encrypt data on an Windows device, when the device is locked
and
make it readable when the passcode is entered. Once this configuration profile is installed on a
device, corresponding users will not be able to modify these settings on their devices.
</div>
</div>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="encrypt-storage-body">
<hr/>
<div id="encrypt-storage-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable storage-encryption.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="encrypt-storage-enabled" type="checkbox" class="operationDataKeys"
data-key="encryptStorageEnabled" checked="checked"/>
<span class="helper"
title="Having this checked would enable Storage-encryption in the device">
Enable storage-encryption
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /encrypt-storage -->
<!--app-restriction-->
<div class="wr-hidden-operation" data-operation="app-restriction">
<div class="panel panel-default operation-data" data-operation="app-restriction"
data-operation-code="APP-RESTRICTION">
<div id="app-restriction-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Application Restriction Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#app-restriction-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="app-restriction-body">
<hr/>
<div id="app-restriction-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<select id="app-restriction-type" class="form-control operationDataKeys" data-key="restrictionType">
<option value="" selected="selected">
None
</option>
<option value="black-list">Black List</option>
<option value="white-list">White List</option>
</select>
<div class="wr-input-control">
<label class="wr-input-label" for="restricted-applications">
Restricted Application List
<span class="helper" title="Add an application to restrict.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<a href="#restricted-applications-grid" class="btn btn-secondary grid-input-add"
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Add Application
</a>
</label>
<div id="restricted-applications"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="restrictedApplications" data-column-count="2">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Application Name/Description</th>
<th>Package Name</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#restricted-applications-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#restricted-applications-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="App Name">
<input type="text" class="form-control grid-input-text"
data-child-key="appName" maxlength="100" data-default=""
placeholder="[ Application Name or Description ]"/>
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text"
data-child-key="packageName" maxlength="100" data-default=""
placeholder="[ Package Name of Application ]"/>
</td>
<td>
<span class="list-group-item-actions">
<a href="#restricted-applications-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,590 @@
/*
* 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.
*/
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION": "passcode-policy",
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION": "camera",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION": "encrypt-storage",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE"
};
/**
* Method to update the visibility of grouped input.
* @param domElement HTML grouped-input element with class name "grouped-input"
*/
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).removeClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false);
});
} 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);
});
}
};
/**
* Checks if provided number is valid against a range.
*
* @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) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
/**
* Validates policy profile operations for the windows platform.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {boolean} whether validation is successful.
*/
var validatePolicyProfile = function () {
var validationStatusArray = [];
var validationStatus;
var operation;
// starting validation process and updating validationStatus
if (configuredOperations.length == 0) {
// updating validationStatus
validationStatus = {
"error": true,
"mainErrorMsg": "You cannot continue. Zero configured features."
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
} else {
// validating each and every configured Operation
// Validating PASSCODE_POLICY
if ($.inArray(windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) {
// if PASSCODE_POLICY is configured
operation = windowsOperationConstants["PASSCODE_POLICY_OPERATION"];
// initializing continueToCheckNextInputs to true
var continueToCheckNextInputs = true;
// validating first input: passcodePolicyMaxPasscodeAgeInDays
var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val();
if (passcodePolicyMaxPasscodeAgeInDays) {
if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
// validating second and last input: passcodePolicyPasscodeHistory
if (continueToCheckNextInputs) {
var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val();
if (passcodePolicyPasscodeHistory) {
if (!$.isNumeric(passcodePolicyPasscodeHistory)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not a number.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
} else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) {
validationStatus = {
"error": true,
"subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.",
"erroneousFeature": operation
};
continueToCheckNextInputs = false;
}
}
}
// at-last, if the value of continueToCheckNextInputs is still true
// this means that no error is found
if (continueToCheckNextInputs) {
validationStatus = {
"error": false,
"okFeature": operation
};
}
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating CAMERA
if ($.inArray(windowsOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) {
// if CAMERA is configured
operation = windowsOperationConstants["CAMERA_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
// Validating ENCRYPT_STORAGE
if ($.inArray(windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) {
// if ENCRYPT_STORAGE is configured
operation = windowsOperationConstants["ENCRYPT_STORAGE_OPERATION"];
// updating validationStatus
validationStatus = {
"error": false,
"okFeature": operation
};
// updating validationStatusArray with validationStatus
validationStatusArray.push(validationStatus);
}
}
// ending validation process
// start taking specific notifying actions upon validation
var wizardIsToBeContinued;
var errorCount = 0;
var mainErrorMsgWrapper, mainErrorMsg,
subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon;
var i;
for (i = 0; i < validationStatusArray.length; i++) {
validationStatus = validationStatusArray[i];
if (validationStatus["error"]) {
errorCount++;
if (validationStatus["mainErrorMsg"]) {
mainErrorMsgWrapper = "#policy-profile-main-error-msg";
mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else if (validationStatus["subErrorMsg"]) {
subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg";
subErrorMsg = subErrorMsgWrapper + " span";
subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error";
subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating error state and corresponding messages
$(subErrorMsg).text(validationStatus["subErrorMsg"]);
if ($(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).removeClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if ($(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).removeClass("hidden");
}
}
} else {
if (validationStatus["okFeature"]) {
subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg";
subErrorIcon = "#" + validationStatus["okFeature"] + "-error";
subOkIcon = "#" + validationStatus["okFeature"] + "-ok";
featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured";
// hiding featureConfiguredState as the first step
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// updating success state and corresponding messages
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if ($(subOkIcon).hasClass("hidden")) {
$(subOkIcon).removeClass("hidden");
}
}
}
}
wizardIsToBeContinued = (errorCount == 0);
return wizardIsToBeContinued;
};
/**
* Generates policy profile object which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generatePolicyProfile = function () {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (key == windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]) {
policy["profile"][key].enablePassword = true;
}
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
return profilePayloads;
};
// Start of HTML embedded invoke methods
var showAdvanceOperation = function (operation, button) {
$(button).addClass('selected');
$(button).siblings().removeClass('selected');
var hiddenOperation = ".wr-hidden-operations-content > div";
$(hiddenOperation + '[data-operation="' + operation + '"]').show();
$(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide();
};
/**
* This method will display appropriate fields based on wifi type
* @param select
*/
var changeAndroidWifiPolicy = function (select) {
slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['wep', 'wpa', '802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-eap', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['802eap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['802eap']);
};
/**
* This method will display appropriate fields based on wifi EAP type
* @param select
* @param superSelect
*/
var changeAndroidWifiPolicyEAP = function (select, superSelect) {
slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['peap', 'ttls', 'pwd', 'fast', 'leap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['peap', 'ttls', 'fast']);
slideDownPaneAgainstValueSet(select, 'control-wifi-provisioning', ['fast']);
slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['peap', 'tls', 'ttls', 'pwd', 'fast', 'leap']);
slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['peap', 'ttls']);
slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['peap', 'tls', 'ttls']);
if (superSelect.value != '802eap') {
changeAndroidWifiPolicy(superSelect);
}
};
/**
* Method to slide down a provided pane upon provided value set.
*
* @param selectElement Select HTML Element to consider
* @param paneID HTML ID of div element to slide down
* @param valueSet Applicable Value Set
*/
var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) {
var selectedValueOnChange = $(selectElement).find("option:selected").val();
if ($(selectElement).is("input:checkbox")) {
selectedValueOnChange = $(selectElement).is(":checked").toString();
}
var i, slideDownVotes = 0;
for (i = 0; i < valueSet.length; i++) {
if (selectedValueOnChange == valueSet[i]) {
slideDownVotes++;
}
}
var paneSelector = "#" + paneID;
if (slideDownVotes > 0) {
if (!$(paneSelector).hasClass("expanded")) {
$(paneSelector).addClass("expanded");
}
$(paneSelector).slideDown();
} else {
if ($(paneSelector).hasClass("expanded")) {
$(paneSelector).removeClass("expanded");
}
$(paneSelector).slideUp();
/** now follows the code to reinitialize all inputs of the slidable pane */
// reinitializing input fields into the defaults
$(paneSelector + " 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
$(paneSelector + " 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
$(paneSelector + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(paneSelector + " .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();
}
}
);
}
};
// End of HTML embedded invoke methods
// 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();
}
};
$(document).ready(function () {
// Maintains an array of configured features of the profile
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();
}
}
);
}
}
});
// <start - fixing feature-configuring switch double-click issue>
$(advanceOperations).on('hidden.bs.collapse', function (event) {
var collapsedFeatureBody = event.target.id;
var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == true) {
$(featureConfiguringSwitch).prop("checked", false);
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
});
$(advanceOperations).on('shown.bs.collapse', function (event) {
var expandedFeatureBody = event.target.id;
var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-"));
var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]";
var featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguringSwitch).prop("checked") == false) {
$(featureConfiguringSwitch).prop("checked", true);
}
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
});
// <end - fixing feature-configuring switch double-click issue>
// 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);
});
});

@ -0,0 +1,402 @@
<div class="row no-gutter">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('passcode-policy', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-key fw-stack-2x"></i>
</span>Passcode Policy
<span id="passcode-policy-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="passcode-policy-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="passcode-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('camera', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-block fw-stack-2x"></i>
</span>
Restrictions on Camera
<span id="camera-configured" class="has-configured status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="camera-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span class="camera-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('encrypt-storage', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security fw-stack-2x"></i>
</span>
Encryption Settings
<span id="encrypt-storage-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="encrypt-storage-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="encrypt-storage-error" class="encryption-error status-icon hidden"><i
class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('app-restriction', this)">
<span class="fw-stack fw-lg">
<i class="fw fw-application fw-stack-1x"></i>
<i class="fw fw-block fw-stack-2x"></i>
</span>
Applications Restrictions
<span id="app-restriction-configured" class="has-configured status-icon hidden"><i
class="fw fw-ok"></i></span>
<span id="app-restriction-ok" class="has-success status-icon hidden"><i class="fw fw-ok"></i></span>
<span id="app-restriction-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
</div>
<div class="wr-hidden-operations-content col-lg-8">
<!-- passcode-policy -->
<div class="wr-hidden-operation" data-operation="passcode-policy" style="display: block">
<div class="panel panel-default operation-data" data-operation="passcode-policy"
data-operation-code="PASSCODE_POLICY">
<div id="passcode-policy-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Passcode Policy
<label id="passcode-policy-lbl" class="wr-input-control switch" data-toggle="collapse"
data-target="#passcode-policy-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to set a passcode policy to an Windows Device.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</div>
<div id="passcode-policy-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="passcode-policy-body">
<hr/>
<div id="passcode-policy-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-allow-simple" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyAllowSimple"
checked="checked"/>
<span class="helper"
title="Permit the use of repeating, ascending and descending character sequences">
Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="passcode-policy-require-alphanumeric" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyRequireAlphanumeric"
checked="checked"/>
<span class="helper" title="Require passcode to contain both letters and numbers">
Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-length" class="form-control operationDataKeys"
data-key="passcodePolicyMinLength" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper"
title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-min-complex-chars" class="form-control operationDataKeys"
data-key="passcodePolicyMinComplexChars" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or none )
</label>
<input id="passcode-policy-max-passcode-age-in-days" type="text"
class="form-control operationDataKeys" data-key="passcodePolicyMaxPasscodeAgeInDays"
maxlength="3" placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcode-policy-passcode-history">
Passcode history
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or none )
</label>
<input id="passcode-policy-passcode-history" type="text" class="form-control operationDataKeys"
data-key="passcodePolicyPasscodeHistory" maxlength="2"
placeholder="[ Requires Number Input ]">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="passcodePolicyMaxFailedAttempts">
Maximum number of failed attempts
<span class="helper" title="Maximum number of passcode entry attempts allowed before all
data on a device will be erased">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="passcode-policy-max-failed-attempts" class="form-control operationDataKeys"
data-key="passcodePolicyMaxFailedAttempts" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
<!-- /passcode-policy -->
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
<div id="camera-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Restrictions on Camera
<label class="wr-input-control switch" data-toggle="collapse" data-target="#camera-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to restrict the usage of camera on an Windows device together
with all the applications using the camera.
Once this configuration profile is installed on a device, corresponding users will not be able
to modify these settings on their devices.
</div>
</div>
<div id="camera-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="camera-body">
<hr/>
<div id="camera-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable camera.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="camera-enabled" type="checkbox" class="operationDataKeys"
data-key="cameraEnabled" checked="checked"/>
<span class="helper" title="Having this checked would enable Usage of phone camera in
the device.">
Allow use of camera
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /camera -->
<!-- encrypt-storage -->
<div class="wr-hidden-operation" data-operation="encrypt-storage">
<div class="panel panel-default operation-data" data-operation="encrypt-storage"
data-operation-code="ENCRYPT_STORAGE">
<div id="encrypt-storage-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Encryption Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#encrypt-storage-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to encrypt data on an Windows device, when the device is locked
and
make it readable when the passcode is entered. Once this configuration profile is installed on a
device, corresponding users will not be able to modify these settings on their devices.
</div>
</div>
<div id="encrypt-storage-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="encrypt-storage-body">
<hr/>
<div id="encrypt-storage-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
Un-check following checkbox in case you need to disable storage-encryption.
<br>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="encrypt-storage-enabled" type="checkbox" class="operationDataKeys"
data-key="encryptStorageEnabled" checked="checked"/>
<span class="helper"
title="Having this checked would enable Storage-encryption in the device">
Enable storage-encryption
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
</div>
</div>
</div>
<!-- /encrypt-storage -->
<!--app-restriction-->
<div class="wr-hidden-operation" data-operation="app-restriction">
<div class="panel panel-default operation-data" data-operation="app-restriction"
data-operation-code="APP-RESTRICTION">
<div id="app-restriction-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Application Restriction Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#app-restriction-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="app-restriction-body">
<hr/>
<div id="app-restriction-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<select id="app-restriction-type" class="form-control operationDataKeys" data-key="restrictionType">
<option value="" selected="selected">
None
</option>
<option value="black-list">Black List</option>
<option value="white-list">White List</option>
</select>
<div class="wr-input-control">
<label class="wr-input-label" for="restricted-applications">
Restricted Application List
<span class="helper" title="Add an application to restrict.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<a href="#restricted-applications-grid" class="btn btn-secondary grid-input-add"
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Add Application
</a>
</label>
<div id="restricted-applications"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="restrictedApplications" data-column-count="2">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Application Name/Description</th>
<th>Package Name</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#restricted-applications-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#restricted-applications-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="App Name">
<input type="text" class="form-control grid-input-text"
data-child-key="appName" maxlength="100" data-default=""
placeholder="[ Application Name or Description ]"/>
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text"
data-child-key="packageName" maxlength="100" data-default=""
placeholder="[ Package Name of Application ]"/>
</td>
<td>
<span class="list-group-item-actions">
<a href="#restricted-applications-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Loading…
Cancel
Save