IOTS-296: Generalizing policy UI for policy edit

This commit removes device type specific  client side logic and UI components from the `cdmf.unit.policy.edit` unit.
4.x.x
Madawa Soysa 8 years ago
parent 7aada58472
commit a4ca74c6c0

@ -35,10 +35,10 @@
<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="/emm/policies/">
data-direct="{{@app.context}}/policies/">
View policy list
</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">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
@ -218,13 +218,17 @@
<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 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">
@ -252,15 +256,5 @@
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}
<!--suppress HtmlUnknownTarget -->
<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"}}
{{js "js/policy-edit.js"}}
{{/zone}}

@ -24,13 +24,17 @@ function onRequest(context) {
var rolesResult = userModule.getRoles();
if (rolesResult.status == "success") {
viewModel.roles = rolesResult.content;
context.roles = rolesResult.content;
}
var usersResult = userModule.getUsers();
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.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");
return context;
}

@ -0,0 +1,559 @@
/*
* 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");
}
};
/**
*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 actionInput = $("#action-input");
var policyNameInput = $("#policy-name-input");
var policyDescriptionInput = $("#policy-description-input");
currentlyEffected["roles"] = policyPayloadObj.roles;
currentlyEffected["users"] = policyPayloadObj.users;
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");
}
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["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"] = [];
}
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");
}
});
$("#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");
}
});
});
Loading…
Cancel
Save