2 ============LICENSE_START=======================================================
4 ================================================================================
5 Copyright (C) 2017-2018 AT&T Intellectual Property. All rights
7 ================================================================================
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
12 http://www.apache.org/licenses/LICENSE-2.0
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19 ============LICENSE_END============================================
20 ===================================================================
28 background-color: #dddd;
32 background-color: #dddd;
41 .fileUpload input.upload {
50 filter: alpha(opacity = 0);
55 display: inline-block;
71 vertical-align: middle;
81 background-color: #f2bfab;
92 background-color: #f5f5f5;
93 padding: 15px 5px 0 5px;
96 .form-group.clearfix {
97 display: -webkit-flex;
109 padding: 2px 2px 2px 30px;
120 border-bottom: 1px solid #ddd;
121 border-collapse: collapse;
131 #policyTable tr.highlight {
132 background-color: #f5f5f5;
144 <script type="text/javascript">
145 function disablefile() {
147 document.getElementById("fileUpload").disabled = true;
151 function disableSVN() {
152 var selectLength = document.querySelectorAll(".disabled-block-container .tab-close-popup");
153 if(selectLength && selectLength.length>0){
154 for(var i = 0; i< selectLength.length ; i++){
155 selectLength[i].disabled = true;
159 document.getElementById("schemaLocation").disabled = true;
160 document.getElementById("userID").disabled = true;
161 document.getElementById("password").disabled = true;
167 <div attribute-test="policywindowproperties" id="configure-widgets"
168 class="disabled-block-container">
169 <div attribute-test="policywindowpropertiesh" class="modal-header">
170 <button type="button" class="close" ng-click="close(false)"
171 aria-hidden="true" style="margin-top: -3px">×</button>
172 <h4>Operational Policy</h4>
176 <div class="modal-body">
177 <div attribute-test="policywindowpropertiesb" class="modal-body row">
179 <div class="leftPolicyPanel">
180 <div class="panel panel-default">
181 <i class="glyphicon glyphicon-search modelSearchBox"></i>
182 <input type="text" id="policySearch" onkeyup="searchPolicyList()"
183 placeholder="Search ...">
184 <div id="policyTableHolder">
185 <table id="policyTable"></table>
188 <div style="float: left">
189 <button type="button" id="createNewPolicy" class="btn btn-sm">New Policy</button></span>
191 <div style="float: right">
192 <button type="button" id="deletePolicy" class="btn btn-sm glyphicon glyphicon-trash" disabled></button></span>
194 <div id="repeatIdError" class="idError">Error: This Policy name is already taken.</div>
195 <div id="newIdError" class="idError">Error: Please rename your new Policy.</div>
196 <div id="spaceError" class="idError">Error: Spaces are not allowed in the ID.</div>
199 <div class="panel panel-default col-sm-9 policyPanel" style="display:none;">
200 <form id="Timeoutform" class="form-horizontal">
202 <div class="form-group clearfix row">
203 <label class="col-sm-2">Name</label>
204 <div class="col-sm-3" style="padding: 0px;">
205 <input type="text" id="pname" name="pname" maxlength="48" placeholder="Enter Unique Name" class="form-control">
208 <label class="col-sm-1">ID</label>
209 <div class="col-sm-1" style="padding: 0px;">
210 <input onkeydown="return false;" type="text" id="pid" name="pid" class="form-control" readonly>
213 <label for="userID" class="col-sm-3" style="padding-left:5px;padding-right:10px;">Overall Time Limit</label>
214 <div class="col-sm-2" style="padding-left: 0px;">
215 <input type="text" maxlength="10" onkeypress="return isNumberKey(event)"
216 class="form-control" id="timeout" name="timeout">
221 <div class="panel-heading" style="background-color: white;">
222 <ul id="nav_Tabs" class="nav nav-tabs">
223 <li class><a id="add_one_more" href="#desc_tab"><span
224 class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
227 <div class="panel-body">
228 <div class="tab-content">
229 <div id="properties_tab" class="tab-pane fade in active"></div>
234 <span id="formSpan" style="display: none">
235 <form class="saveProps" class="form-horizontal">
237 <div class="form-group clearfix">
238 <label class="col-sm-4 control-label" for="recipe">Recipe</label>
239 <div class="col-sm-8">
240 <select class="form-control" name="recipe" id="recipe" enableFilter="true"></select>
243 <div class="form-group clearfix">
244 <label for="maxRetries" class="col-sm-4 control-label">
246 <div class="col-sm-8">
247 <input type="text" maxlength="5" class="form-control" id="maxRetries"
248 onkeypress="return isNumberKey(event)"
249 name="maxRetries"> </input>
252 <div class="form-group clearfix">
253 <label for="retryTimeLimit" class="col-sm-4 control-label">
254 Retry Time Limit</label>
255 <div class="col-sm-8">
256 <input type="text" maxlength="5" class="form-control" id="retryTimeLimit"
257 onkeypress="return isNumberKey(event)"
258 name="retryTimeLimit"></input>
261 <div style="display: none;" class="form-group clearfix">
262 <label for="_id" class="col-sm-4 control-label">
264 <div class="col-sm-8">
265 <input type="text" onkeydown="return false;" class="form-control" id="_id"
266 name="_id" value=""></input>
269 <div class="form-group clearfix">
270 <label for="parentPolicy" class="col-sm-4 control-label">
271 Parent Policy</label>
272 <div class="col-sm-8">
273 <select class="form-control" id="parentPolicy"
274 name="parentPolicy" enableFilter="true"><option value=""></option></select>
277 <div class="form-group clearfix">
278 <label for="parentPolicyConditions" class="col-sm-4 control-label">
279 Parent Policy Conditions</label>
280 <div class="col-sm-8">
281 <select class="form-control" id="parentPolicyConditions"
282 name="parentPolicyConditions" multiple></select>
285 <div class="form-group clearfix">
286 <label for="targetResourceId" class="col-sm-4 control-label">
287 Target ResourceId</label>
288 <div class="col-sm-8">
289 <select class="form-control" name="targetResourceId" id="targetResourceId" enableFilter="true" onchange="changeTargetResourceIdOther();" >
290 <option value=""></option>
291 <option value="Other:">Other:</option>
294 <input type="text" style="display:none" class="form-control" id="targetResourceIdOther"
295 name="targetResourceIdOther" value=""></input>
303 <div attribute-test="policywindowpropertiesf" class="modal-footer">
304 <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
305 <button id="savePropsBtn" class="btn btn-primary">Close</button>
306 <button ng-click="close(true)" id="close_button"
307 class="btn btn-primary">Cancel</button>
312 function initTargetResourceId() {
313 // Set all the Resource Invariant UUID in the target resource ID list (+Empty and other)
314 Object.keys(vf_Services["shared"]["byVf"]).forEach(function(key){
315 $('#targetResourceId').append($('<option></option>').val(key).html(key));
319 function changeTargetResourceIdOther() {
320 if ($("#targetResourceId").val()==="Other:") {
321 $("#targetResourceIdOther").show();
323 $("#targetResourceIdOther").hide();
324 $("#targetResourceIdOther").val("");
327 //Basically this method will add a new form. All forms share the same class. When you want one form to show(active form) the other forms get the
328 // css attribute display:none
329 $("#add_one_more").click(function(event) {
330 event.preventDefault();
331 var num = add_one_more();
334 loadPropertyWindow("policy")
336 // by default, parentPolicyConditions is disabled
337 //$("#parentPolicyConditions").prop('disabled', 'disabled');
344 //Grab saved values for dropdowns
345 var obj = elementMap[lastElementSelected];
347 if (!($.isEmptyObject(obj))){
348 allPolicies = jQuery.extend({}, obj);
349 for (var x in allPolicies){
350 $("#policyTable").prepend("<tr><td>"+x+"</td></tr>");
351 if (allPolicies[x][1]['value']){
352 allPolIds.push(parseInt(allPolicies[x][1]['value']));
358 //load recipes for a chosen policy
359 function disperseConfig(policyObj, id){
361 //remove old gui forms
362 for (var i=1; i<($(".formId").length + 1); i++){
363 $("#go_properties_tab"+i).parent().remove();
365 $(".formId").remove();
367 if (policyObj !== undefined) {
368 var el = policyObj[id][3]['policyConfigurations']
369 for (var i = 0; i < el.length; i++) {
371 var num = add_one_more();
373 for (var j = 0; j < el[i].length; j++) {
374 if(el[i][j].hasOwnProperty("name")){
375 $("#formId" + num + " #" + el[i][j].name).val(
377 if(el[i][j].name==="_id")
378 policy_ids["#formId" + num]=el[i][j].value
379 if(el[i][j].name==='parentPolicy')
380 parent_policy[num]=el[i][j].value
381 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
382 $("#go_properties_tab"+num).text(el[i][j].value)
384 if(el[i][j].name==="targetResourceIdOther" && el[i][j].value.toString()!=='') {
385 // Add the entry and set it
386 $('#targetResourceId').append($('<option></option>').val($('#targetResourceIdOther').val()).html($('#targetResourceIdOther').val()));
387 $('#targetResourceId').val($('#targetResourceIdOther').val());
394 //Adding all the ids for parent policy options
395 for(var i=1;i<=$(".formId").length;i++){
396 for(k in policy_ids){
397 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
398 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
403 for(k in parent_policy){
404 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
405 if($("#formId"+k+" #parentPolicy").val() ==""){
406 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
408 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
410 // force the change event
411 $("#formId"+k+" #parentPolicy").change();
414 // Now load all component with the right value defined in policyObj JSON
415 for (headInd in policyObj[id]){
416 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
417 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
425 $('select[multiple] option').each(function() {
426 var input = $('input[value="' + $(this).val() + '"]');
427 input.prop('disabled', true);
428 input.parent('li').addClass('disabled');
430 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
435 function addSelectListen(count) {
436 var onSelectChange = function() {
437 var opselected = this.selectedOptions[0].text;
439 if (this.id == "recipe"){
441 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
442 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
444 $(this).closest("[id^='go_properties_tab']").text("Policy");
448 if (this.id=="parentPolicy"){
449 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
451 ppCond.multiselect("clearSelection");
452 ppCond.multiselect("disable");
454 ppCond.multiselect("enable");
458 $("#formId"+count+" select").each( function () {
459 this.change = onSelectChange;
464 //This is ensure there are no repeated keys in the map
465 function noRepeats(form) {
466 //triggered per policy.
468 for (var i = 0; i < form.length; i++) {
469 if (select[form[i].name] === undefined)
470 select[form[i].name] = []
471 select[form[i].name].push(form[i].value);
483 $("#savePropsBtn").click(function(event) {
484 if($("#targetResourceIdOther").is(":visible")) {
485 $('#targetResourceId').append($('<option></option>').val($("#targetResourceIdOther").val()).html($("#targetResourceIdOther").val()))
486 $("#targetResourceId").val($("#targetResourceIdOther").val());
488 $(".idError").hide();
489 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
491 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
492 $("#repeatIdError").show();
494 } else { //not repeated
495 delete allPolicies[$("#policyTable .highlight td").html()];
498 if ($("#pname").val().trim() == "New_Policy"){
499 $("#newIdError").show();
504 /* if ($("#policyTable .highlight").length > 0){
505 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
509 //Removes outdated (deleted) policies by checking against left menu
510 var finalSaveList = {};
511 $("#policyTable td").each(function(){
512 var tableVal = $(this).text();
513 if (tableVal in allPolicies){
514 finalSaveList[tableVal] = allPolicies[tableVal];
518 saveProperties(finalSaveList);
519 $("#close_button").click();
522 function add_one_more() {
523 $("#nav_Tabs li").removeClass("active");
525 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
526 var form = $($("#formSpan").children()[0]).clone()
528 //Each new tab will have the formId class attached to it. This way we can track how many forms we currently have out there and assign listeners to them
529 if ($(".formId").length > 0) {
531 var s = $(".formId");
532 for (var i = 0; i < s.length; i++) {
533 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
534 greatest = parseInt($(s[i]).attr("id").substring(6))
537 count = greatest + 1;
538 $("#properties_tab").append(
539 ('<span class="formId" id="formId'+count+'"></span>'));
542 $("#properties_tab").append(
543 '<span class="formId" id="formId1"></span>');
546 //$(form).find("#policyName").val("Recipe "+makid(2))
547 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
548 //alert($(form).find("#_id").val())
549 //policyNameChangeListener(form)
553 ' <li class="active"><a id="go_properties_tab'+count+'">Policy</a><button id="tab_close'+count+'" type="button" class="close tab-close-popup" aria-hidden="true" style="margin-top: -30px;margin-right: 5px">×</button></li>');
554 $("#formId" + count).append(form);
555 $(".formId").not($("#formId" + count)).css("display", "none")
558 addSelectListen(count);
559 // This is for when the process is not loading from map but being created
562 $(form).find("#_id").val(l)
563 policy_ids["#formId" + count]=l
566 for(var i=1;i<=greatestIdNum();i++){
567 if($("#formId"+i).length>0){
568 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
569 $("#formId"+i+" #parentPolicy").empty();
571 for(k in policy_ids){
572 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
573 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
576 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
580 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
582 //re-populate parent policy with chosen options
591 function add_new_policy(issueNewNames) {
592 //remove old gui forms
593 for (var i=1; i<($(".formId").length + 1); i++){
594 $("#go_properties_tab"+i).parent().remove();
596 $(".formId").remove();
599 //$("#pname").val("0");
600 $("#pname").val("New_Policy");
601 $("#timeout").val(defaults_props.policy.timeout);
603 $("#add_one_more").click();
606 function addCustListen(count) {
607 $('#go_properties_tab' + count).click(function(event) {
608 $("#nav_Tabs li").removeClass("active");
609 $(this).parent().addClass("active");
610 $("#formId" + count).css("display", "")
611 $(".formId").not($("#formId" + count)).css("display", "none")
614 $('#tab_close' + count).click(function(event) {
615 if(document.getElementById("timeout").disabled){
618 $(this).parent().remove();
619 for(var i=1;i<=greatestIdNum();i++){
620 if( $("#formId"+i).length>0){
622 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
623 $("#formId"+i+" #parentPolicy").val("")
624 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
628 delete policy_ids["#formId" + count + " #_id"]
629 $("#formId" + count).remove();
634 function greatestIdNum() {
636 var s = $(".formId");
637 for (var i = 0; i < s.length; i++) {
638 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
639 greatest = parseInt($(s[i]).attr("id").substring(6))
645 //Generate random id for each policy
646 //Also made sure ids couldnt be repeated
647 function makeid(num) {
650 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
653 for (var i = 0; i < 7; i++)
654 text += possible.charAt(Math.floor(Math.random()
656 var hasValue = false;
657 for (k in policy_ids) {
658 if (text === policy_ids[k])
667 var ParentPolicy = function(id, name) {
672 //Policy table search filter
673 function searchPolicyList() {
674 var search = document.getElementById("policySearch");
675 var row = document.getElementsByTagName("td");
676 for (var i = 0; i < row.length; i++) {
677 if (row[i].innerHTML.toUpperCase().indexOf(
678 search.value.toUpperCase()) > -1) {
679 row[i].style.display = "";
681 row[i].style.display = "none";
686 function saveLastPolicyLocally(lastPolicyId) {
689 var properties = $(".saveProps").not("#formSpan .saveProps");
690 var timeoutForm = $("#Timeoutform").serializeArray();
692 for (var i = 0; i < timeoutForm.length; i++) {
693 polForm.push(timeoutForm[i]);
697 d["policyConfigurations"] = [];
698 for (var i = 0; i < properties.length; i++) {
699 var ser = $(properties[i]).serializeArray();
700 var s = noRepeats(ser)
701 d["policyConfigurations"].push(s);
704 allPolicies[lastPolicyId] = polForm;
707 function getNextId(){
710 if ((Math.min.apply(Math, allPolIds) == 0)
711 && (allPolIds.length > 0)) {
713 for (var i = 1; i < allPolIds.length; i++) {
714 if ((allPolIds[i] - allPolIds[i - 1]) != 1) {
715 newPolId = (allPolIds[i - 1] + 1);
720 newPolId = (Math.max.apply(Math, allPolIds)) + 1;
725 allPolIds.push(newPolId);
726 $("#pid").val(newPolId);
729 $("#deletePolicy").on('click', function() {
730 $(".idError").hide();
732 allPolIds.splice((allPolIds.indexOf(parseInt($("#pid").val()))),1);
735 var deleteId = $("#policyTable .highlight td").html();
736 delete allPolicies[deleteId];
737 $("#policyTable .highlight").remove();
742 $('#policyTable').on('click', 'tr', function(event) {
743 $(".idError").hide();
745 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
747 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
748 $("#repeatIdError").show();
750 } else { //not repeated
751 $("#repeatIdError").hide();
752 delete allPolicies[$("#policyTable .highlight td").html()];
755 //if (parseInt($("#pname").val()) == 0){
756 if ($("#pname").val().trim() == "New_Policy"){
757 $("#newIdError").show();
763 if ($("#policyTable .highlight").length == 0){
767 $(this).addClass('highlight').siblings().removeClass('highlight');
768 disperseConfig(allPolicies, $(this).find("td").html());
771 $('#createNewPolicy').on('click', function(){
772 $(".idError").hide();
774 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
776 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
777 $("#repeatIdError").show();
779 } else { //not repeated
780 $("#repeatIdError").hide();
781 delete allPolicies[$("#policyTable .highlight td").html()];
784 //if (parseInt($("#pname").val()) == 0){
785 if ($("#pname").val().trim() == "New_Policy"){
786 $("#newIdError").show();
791 if (("#policyTable .highlight").length > 0){
792 $('#policyTable tr.highlight').removeClass('highlight');
794 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
799 $('#pname').on('keypress', function(e){
800 /* var newVal = $(this).val() + String.fromCharCode(e.which);
801 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
804 if (e.keyCode == 32){
805 $("#spaceError").show();
810 function isNumberKey(event){
811 var charCode = (event.which) ? event.which : event.keyCode
812 if (charCode > 31 && (charCode < 48 || charCode > 57)){
818 function startNextItem() {
819 //save last item before transitioning
820 var lastItem = $("#policyTable .highlight");
821 if (lastItem.length > 0) {
822 saveLastPolicyLocally($("#pname").val());
823 //lastItem.attr("id", $("#pname").val());
824 lastItem.find("td").html($("#pname").val());
830 if ($("#deletePolicy").prop("disabled")) {
831 $("#deletePolicy").prop("disabled", false);
836 initTargetResourceId();
837 //load metrics dropdown
838 if (elementMap["global"]){
839 for (var i = 0; i < (elementMap["global"].length); i++){
840 if ((elementMap["global"][i]["name"]) == "actionSet"){
841 var asSel = elementMap["global"][i]["value"];
842 if (asSel == "vnfRecipe"){
843 if (vf_Services["policy"][asSel]){
844 $.each((vf_Services["policy"][asSel]), function(val, text) {
846 $('<option></option>').val(val).html(text)
856 //Show table panel only
857 function expandTable() {
858 $(".policyPanel").css("display", "none");
859 $(".leftPolicyPanel").removeClass("col-sm-3");
860 $(".modelSearchBox").css("padding", "25px 12px");
861 if (!($("#deletePolicy").prop("disabled"))) {
862 $("#deletePolicy").prop("disabled", true);
867 function collapseTable() {
868 $(".leftPolicyPanel").addClass("col-sm-3");
869 $(".modelSearchBox").css("padding", "10px 12px");
870 $(".policyPanel").css("display", "unset");