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 ===================================================================
27 background-color: #dddd;
32 vertical-align: middle;
47 background-color: #f5f5f5;
48 padding: 15px 5px 0 5px;
51 .form-group.clearfix {
52 display: -webkit-flex;
67 border-bottom: 1px solid #ddd;
68 border-collapse: collapse;
78 #policyTable tr.highlight {
79 background-color: #f5f5f5;
92 <div attribute-test="policywindowproperties" id="configure-widgets"
93 class="disabled-block-container">
94 <div attribute-test="policywindowpropertiesh" class="modal-header">
95 <button type="button" class="close" ng-click="close(false)"
96 aria-hidden="true" style="margin-top: -3px">×</button>
97 <h4>Operational Policy</h4>
101 <div class="modal-body">
102 <div attribute-test="policywindowpropertiesb" class="modal-body row">
103 <div class="leftPolicyPanel" style="display: none;">
104 <div class="panel panel-default">
105 <div id="policyTableHolder">
106 <table id="policyTable"></table>
110 <div id="spaceError" class="idError">Error: Spaces are not
111 allowed in the ID.</div>
113 <div class="panel panel-default col-sm-9 policyPanel">
114 <form id="Timeoutform" class="form-horizontal">
116 <div class="form-group clearfix row">
117 <label class="col-sm-2">Name</label>
118 <div class="col-sm-3" style="padding: 0px;">
119 <input type="text" id="pname" name="pname" maxlength="48"
120 placeholder="Enter Unique Name" class="form-control">
123 <label class="col-sm-1">ID</label>
124 <div class="col-sm-1" style="padding: 0px;">
125 <input onkeydown="return false;" type="text" id="pid" name="pid"
126 class="form-control" readonly>
129 <label for="userID" class="col-sm-3"
130 style="padding-left: 5px; padding-right: 10px;">Overall
132 <div class="col-sm-2" style="padding-left: 0px;">
133 <input type="text" maxlength="10"
134 onkeypress="return isNumberKey(event)" class="form-control"
135 id="timeout" name="timeout">
140 <div class="panel-heading" style="background-color: white;">
141 <ul id="nav_Tabs" class="nav nav-tabs">
142 <li class><a id="add_one_more" href="#desc_tab"><span
143 class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
146 <div class="panel-body">
147 <div class="tab-content">
148 <div id="properties_tab" class="tab-pane fade in active"></div>
153 <span id="formSpan" style="display: none">
154 <form class="saveProps" class="form-horizontal">
156 <div class="form-group clearfix">
157 <label class="col-sm-4 control-label" for="recipe">Recipe</label>
158 <div class="col-sm-8">
159 <select class="form-control" name="recipe" id="recipe"
160 enableFilter="true"></select>
163 <div class="form-group clearfix">
164 <label for="maxRetries" class="col-sm-4 control-label">
166 <div class="col-sm-8">
167 <input type="text" maxlength="5" class="form-control"
168 id="maxRetries" onkeypress="return isNumberKey(event)"
169 name="maxRetries"> </input>
172 <div class="form-group clearfix">
173 <label for="retryTimeLimit" class="col-sm-4 control-label">
174 Retry Time Limit</label>
175 <div class="col-sm-8">
176 <input type="text" maxlength="5" class="form-control"
177 id="retryTimeLimit" onkeypress="return isNumberKey(event)"
178 name="retryTimeLimit"></input>
181 <div style="display: none;" class="form-group clearfix">
182 <label for="_id" class="col-sm-4 control-label"> PolicyID</label>
183 <div class="col-sm-8">
184 <input type="text" onkeydown="return false;"
185 class="form-control" id="_id" name="_id" value=""></input>
188 <div class="form-group clearfix">
189 <label for="parentPolicy" class="col-sm-4 control-label">
190 Parent Policy</label>
191 <div class="col-sm-8">
192 <select class="form-control" id="parentPolicy"
193 name="parentPolicy" enableFilter="true"><option
194 value=""></option></select>
197 <div class="form-group clearfix">
198 <label for="parentPolicyConditions"
199 class="col-sm-4 control-label"> Parent Policy Conditions</label>
200 <div class="col-sm-8">
201 <select class="form-control" id="parentPolicyConditions"
202 name="parentPolicyConditions" multiple></select>
205 <div class="form-group clearfix">
207 <label for="actor" class="col-sm-4 control-label"> Actor</label>
208 <div class="col-sm-8">
209 <select class="form-control" id="actor" name="actor"></select>
212 <label for="payload" class="col-sm-4 control-label">
213 Payload (YAML)</label>
214 <div class="col-sm-8">
215 <textarea class="form-control" id="recipePayload" name=recipePayload></textarea>
218 <div class="form-group clearfix">
219 <label for="targetType" class="col-sm-4 control-label">
221 <div class="col-sm-8">
222 <select class="form-control" name="recipeLevel" id="recipeLevel">
226 <label for="targetResourceId" class="col-sm-4 control-label">
227 Target ResourceId</label>
228 <div class="col-sm-8">
229 <select class="form-control" name="targetResourceId"
230 id="targetResourceId" enableFilter="true"
231 onchange="changeTargetResourceIdOther();">
232 <option value=""></option>
233 <option value="Other:">Other:</option>
236 <input type="text" style="display: none" class="form-control"
237 id="targetResourceIdOther" name="targetResourceIdOther" value=""></input>
239 <div style="border: 2px dotted gray;">
240 <div class="form-group clearfix">
241 <label for="enableGuardPolicy" class="col-sm-4 control-label">
242 Enable Guard Policy</label>
243 <div class="col-sm-8">
244 <input type="checkbox" class="form-control"
245 name="enableGuardPolicy" id="enableGuardPolicy">
247 <div class="col-sm-8">
248 <label for="guardPolicyType" class="col-sm-4 control-label">
249 Guard Policy Type</label> <select class="form-control"
250 name="guardPolicyType" id="guardPolicyType"
251 onchange="changeGuardPolicyType();">
252 <option value="GUARD_MIN_MAX">MinMax</option>
253 <option value="GUARD_YAML">FrequencyLimiter</option>
256 <label for="guardTargets" class="col-sm-4 control-label">Guard
258 <div class="col-sm-8">
259 <input class="form-control" name="guardTargets"
264 <div class="form-group clearfix" id="minMaxGuardPolicyDiv">
265 <label for="minGuard" class="col-sm-4 control-label">
267 <div class="col-sm-8">
268 <input class="form-control" name="minGuard" id="minGuard" />
270 <label for="maxGuard" class="col-sm-4 control-label">
272 <div class="col-sm-8">
273 <input class="form-control" name="maxGuard" id="maxGuard" />
276 <div class="form-group clearfix"
277 id="frequencyLimiterGuardPolicyDiv" style="display: none">
278 <label for="limitGuard" class="col-sm-4 control-label">Limit</label>
279 <div class="col-sm-8">
280 <input class="form-control" name="limitGuard" id="limitGuard" />
282 <div class="col-sm-8">
283 <select class="form-control" name="timeUnitsGuard"
284 id="timeUnitsGuard" /> <label for="timeWindowGuard"
285 class="col-sm-4 control-label">Time Window</label>
287 <div class="col-sm-8">
288 <input class="form-control" name="timeWindowGuard"
289 id="timeWindowGuard" />
292 <div class="form-group clearfix">
293 <label for="guardActiveStart" class="col-sm-4 control-label">
294 Guard Active Start</label>
295 <div class="col-sm-8">
296 <input class="form-control" name="guardActiveStart"
297 id="guardActiveStart" />
299 <label for="guardActiveEnd" class="col-sm-4 control-label">
300 Guard Active End</label>
301 <div class="col-sm-8">
302 <input class="form-control" name="guardActiveEnd"
303 id="guardActiveEnd" />
313 <div attribute-test="policywindowpropertiesf" class="modal-footer">
314 <button id="savePropsBtn" class="btn btn-primary">Close</button>
315 <button ng-click="close(true)" id="close_button"
316 class="btn btn-primary">Cancel</button>
320 function getAllFormId() {
321 return Array.from(document.getElementsByClassName("formId"));
324 function searchActiveFormId() {
325 var formArray = getAllFormId();
326 for (var i=0, max=formArray.length; i < max; i++) {
328 console.log("Search active FormId, current element "+formArray[i].id);
329 if (formArray[i].style.display !== "none") {
330 console.log("Active form is:"+formArray[i].id);
334 console.log("No active formId found !");
337 function initTargetResourceId() {
338 if (vf_Services !== null && vf_Services !== undefined) {
339 // Set all the Resource Invariant UUID in the target resource ID list (+Empty and other)
340 Object.keys(vf_Services["shared"]["byVf"]).forEach(function(key) {
341 $("#targetResourceId").append($('<option></option>').val(key).html(key));
346 function changeTargetResourceIdOther() {
347 var formItemActive = searchActiveFormId();
348 if ($("#"+formItemActive.id+" #targetResourceId").val()==="Other:") {
349 $("#"+formItemActive.id+" #targetResourceIdOther").show();
351 $("#"+formItemActive.id+" #targetResourceIdOther").hide();
352 $("#"+formItemActive.id+" #targetResourceIdOther").val("");
356 function changeGuardPolicyType() {
357 var formItemActive = searchActiveFormId();
358 if ($("#"+formItemActive.id+" #guardPolicyType").val()==="GUARD_MIN_MAX") {
359 $("#"+formItemActive.id+" #minMaxGuardPolicyDiv").show();
360 $("#"+formItemActive.id+" #frequencyLimiterGuardPolicyDiv").hide();
361 } else if ($("#"+formItemActive.id+" #guardPolicyType").val()==="GUARD_YAML") {
362 $("#"+formItemActive.id+" #minMaxGuardPolicyDiv").hide();
363 $("#"+formItemActive.id+" #frequencyLimiterGuardPolicyDiv").show();
366 //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
367 // css attribute display:none
368 $("#add_one_more").click(function(event) {
369 console.log("add one more");
370 event.preventDefault();
371 var num = add_one_more();
375 // by default, parentPolicyConditions is disabled
376 //$("#parentPolicyConditions").prop('disabled', 'disabled');
383 //Grab saved values for dropdowns
384 var obj = getOperationalPolicyProperty();
386 console.log("lastElementSelected :"+ lastElementSelected);
387 if (!($.isEmptyObject(obj))){
388 allPolicies = jQuery.extend({}, obj);
389 for (var x in allPolicies){
390 $("#policyTable").prepend("<tr><td>"+x+"</td></tr>");
391 if (allPolicies[x][1]['value']){
392 allPolIds.push(parseInt(allPolicies[x][1]['value']));
394 console.log("policies found :"+ x);
399 if (loadPolicy !== undefined && loadPolicy !== null) {
401 console.log("load properties");
402 disperseConfig(allPolicies,loadPolicy);
404 console.log("create new policy");
408 //load recipes for a chosen policy
409 function disperseConfig(policyObj, id){
410 console.log("disperseConfig with id:" + id);
412 //remove old gui forms
413 for (var i=1; i<($(".formId").length + 1); i++){
414 $("#go_properties_tab"+i).parent().remove();
416 $(".formId").remove();
418 if (policyObj !== undefined && policyObj[id] !== undefined) {
419 var el = policyObj[id][3]['policyConfigurations']
420 for (var i = 0; i < el.length; i++) {
422 var num = add_one_more();
423 console.log("number is=:" + num);
425 for (var j = 0; j < el[i].length; j++) {
426 console.log("attr:" + el[i][j].name + "; value is:" + el[i][j].value);
427 if(el[i][j].hasOwnProperty("name")){
428 $("#formId" + num + " #" + el[i][j].name).val(
430 if(el[i][j].name==="_id") {
431 console.log("formId num:" + num + "; value is:" + el[i][j].value);
432 policy_ids["#formId" + num]=el[i][j].value
434 if(el[i][j].name==='parentPolicy')
435 parent_policy[num]=el[i][j].value
436 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
437 $("#go_properties_tab"+num).text(el[i][j].value)
439 if(el[i][j].name==="targetResourceIdOther" && el[i][j].value.toString()!=='') {
440 // Add the entry and set it
441 $("#formId" + num + " #targetResourceId").append($('<option></option>').val($("#formId" + num + " #targetResourceIdOther").val()).html($("#formId" + num + " #targetResourceIdOther").val()));
442 $("#formId" + num + " #targetResourceId").val($("#formId" + num + " #targetResourceIdOther").val());
444 changeGuardPolicyType();
449 //Adding all the ids for parent policy options
450 for(var i=1;i<=$(".formId").length;i++){
451 for(k in policy_ids){
452 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
453 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
458 for(k in parent_policy){
459 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
460 if($("#formId"+k+" #parentPolicy").val() ==""){
461 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
463 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
465 // force the change event
466 $("#formId"+k+" #parentPolicy").change();
469 // Now load all component with the right value defined in policyObj JSON
470 for (headInd in policyObj[id]){
471 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
472 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
480 $('select[multiple] option').each(function() {
481 var input = $('input[value="' + $(this).val() + '"]');
482 input.prop('disabled', true);
483 input.parent('li').addClass('disabled');
485 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
490 function addSelectListen(count) {
491 var onSelectChange = function() {
492 var opselected = this.selectedOptions[0].text;
494 if (this.id == "recipe"){
496 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
497 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
499 $(this).closest("[id^='go_properties_tab']").text("Policy");
503 if (this.id=="parentPolicy"){
504 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
506 ppCond.multiselect("clearSelection");
507 ppCond.multiselect("disable");
509 ppCond.multiselect("enable");
513 $("#formId"+count+" select").each( function () {
514 this.change = onSelectChange;
519 //This is ensure there are no repeated keys in the map
520 function noRepeats(form) {
521 //triggered per policy.
523 for (var i = 0; i < form.length; i++) {
524 if (select[form[i].name] === undefined)
525 select[form[i].name] = []
526 select[form[i].name].push(form[i].value);
538 $("#savePropsBtn").click(function(event) {
539 console.log("save properties triggered");
540 if($("#targetResourceIdOther").is(":visible")) {
541 $('#targetResourceId').append($('<option></option>').val($("#targetResourceIdOther").val()).html($("#targetResourceIdOther").val()))
542 $("#targetResourceId").val($("#targetResourceIdOther").val());
544 $(".idError").hide();
546 console.log("save properties triggered2");
548 /* if ($("#policyTable .highlight").length > 0){
549 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
553 //Removes outdated (deleted) policies by checking against left menu
554 console.log("get all policies");
555 var finalSaveList = {};
556 $("#policyTable td").each(function(){
557 console.log("enter policy table each loop");
558 var tableVal = $(this).text();
559 if (tableVal in allPolicies){
560 finalSaveList[tableVal] = allPolicies[tableVal];
562 console.log("save properties; add tableVal to policies: "+ tableVal);
564 var scope = angular.element(document.getElementById('formSpan')).scope();
565 scope.submitForm(finalSaveList);
566 $("#close_button").click();
569 function add_one_more() {
570 console.log("add one more");
572 $("#nav_Tabs li").removeClass("active");
574 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
575 var form = $($("#formSpan").children()[0]).clone()
577 //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
578 if ($(".formId").length > 0) {
580 var s = $(".formId");
581 for (var i = 0; i < s.length; i++) {
582 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
583 greatest = parseInt($(s[i]).attr("id").substring(6))
586 count = greatest + 1;
587 $("#properties_tab").append(
588 ('<span class="formId" id="formId'+count+'"></span>'));
591 $("#properties_tab").append(
592 '<span class="formId" id="formId1"></span>');
595 //$(form).find("#policyName").val("Recipe "+makid(2))
596 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
597 //alert($(form).find("#_id").val())
598 //policyNameChangeListener(form)
602 ' <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>');
603 $("#formId" + count).append(form);
604 $(".formId").not($("#formId" + count)).css("display", "none")
607 addSelectListen(count);
608 // This is for when the process is not loading from map but being created
611 $(form).find("#_id").val(l)
612 policy_ids["#formId" + count]=l
615 for(var i=1;i<=greatestIdNum();i++){
616 if($("#formId"+i).length>0){
617 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
618 $("#formId"+i+" #parentPolicy").empty();
620 for(k in policy_ids){
621 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
622 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
625 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
629 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
631 //re-populate parent policy with chosen options
642 function addCustListen(count) {
643 $('#go_properties_tab' + count).click(function(event) {
644 $("#nav_Tabs li").removeClass("active");
645 $(this).parent().addClass("active");
646 $("#formId" + count).css("display", "")
647 $(".formId").not($("#formId" + count)).css("display", "none")
650 $('#tab_close' + count).click(function(event) {
651 if(document.getElementById("timeout").disabled){
654 $(this).parent().remove();
655 for(var i=1;i<=greatestIdNum();i++){
656 if( $("#formId"+i).length>0){
658 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
659 $("#formId"+i+" #parentPolicy").val("")
660 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
664 delete policy_ids["#formId" + count + " #_id"]
665 $("#formId" + count).remove();
670 function greatestIdNum() {
672 var s = $(".formId");
673 for (var i = 0; i < s.length; i++) {
674 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
675 greatest = parseInt($(s[i]).attr("id").substring(6))
681 //Generate random id for each policy
682 //Also made sure ids couldnt be repeated
683 function makeid(num) {
686 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
689 for (var i = 0; i < 7; i++)
690 text += possible.charAt(Math.floor(Math.random()
692 var hasValue = false;
693 for (k in policy_ids) {
694 if (text === policy_ids[k])
703 var ParentPolicy = function(id, name) {
708 function saveLastPolicyLocally(lastPolicyId) {
709 console.log("last policy id is:" + lastPolicyId);
712 var properties = $(".saveProps").not("#formSpan .saveProps");
713 var timeoutForm = $("#Timeoutform").serializeArray();
715 for (var i = 0; i < timeoutForm.length; i++) {
716 polForm.push(timeoutForm[i]);
720 d["policyConfigurations"] = [];
721 for (var i = 0; i < properties.length; i++) {
722 var ser = $(properties[i]).serializeArray();
723 var s = noRepeats(ser)
724 d["policyConfigurations"].push(s);
728 for (var x in allPolicies){
729 if (x !== lastPolicyId) {
730 delete allPolicies[x];
731 console.log("remove old policy"+ x);
735 allPolicies[lastPolicyId] = polForm;
738 $('#policyTable').on('click', 'tr', function(event) {
740 console.log("click on policyTable");
741 $(".idError").hide();
746 $(this).addClass('highlight').siblings().removeClass('highlight');
747 disperseConfig(allPolicies, $(this).find("td").html());
751 $('#pname').on('keypress', function(e){
752 /* var newVal = $(this).val() + String.fromCharCode(e.which);
753 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
756 if (e.keyCode == 32){
757 $("#spaceError").show();
762 function isNumberKey(event){
763 var charCode = (event.which) ? event.which : event.keyCode
764 if (charCode > 31 && (charCode < 48 || charCode > 57)){
770 function startNextItem() {
771 console.log("start next Item, policyname is:" + $("#pname").val());
772 //save last item before transitioning
773 var lastItem = $("#policyTable .highlight");
774 console.log("start next Item, lastitem is:" + lastItem);
775 if (lastItem.length > 0) {
776 console.log("start next Item length > 0");
777 saveLastPolicyLocally($("#pname").val());
778 //lastItem.attr("id", $("#pname").val());
779 lastItem.find("td").html($("#pname").val());
783 function add_new_policy(issueNewNames) {
784 console.log("add new policy");
785 //remove old gui forms
786 for (var i=1; i<($(".formId").length + 1); i++){
787 $("#go_properties_tab"+i).parent().remove();
789 $(".formId").remove();
790 $("#pname").val("New_Policy");
791 $("#timeout").val(getOperationalPolicyProperty().timeout);
793 $("#add_one_more").click();
795 console.log("start next Item on 796");
798 if (("#policyTable .highlight").length > 0){
799 $('#policyTable tr.highlight').removeClass('highlight');
801 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
805 initTargetResourceId();
806 //load metrics dropdown
807 if (elementMap["global"]) {
808 for (var i = 0; i < (elementMap["global"].length); i++){
809 if ((elementMap["global"][i]["name"]) == "actionSet"){
810 var asSel = elementMap["global"][i]["value"];
811 if (asSel == "vnfRecipe" && vf_Services !== null && vf_Services !== undefined){
812 if (vf_Services["policy"][asSel]){
813 $.each((vf_Services["policy"][asSel]), function(val, text) {
815 $('<option></option>').val(val).html(text)