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 ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
315 <button id="savePropsBtn" class="btn btn-primary">Close</button>
316 <button ng-click="close(true)" id="close_button"
317 class="btn btn-primary">Cancel</button>
321 function getAllFormId() {
322 return Array.from(document.getElementsByClassName("formId"));
325 function searchActiveFormId() {
326 var formArray = getAllFormId();
327 for (var i=0, max=formArray.length; i < max; i++) {
329 console.log("Search active FormId, current element "+formArray[i].id);
330 if (formArray[i].style.display !== "none") {
331 console.log("Active form is:"+formArray[i].id);
335 console.log("No active formId found !");
338 function initTargetResourceId() {
339 if (vf_Services !== null && vf_Services !== undefined) {
340 // Set all the Resource Invariant UUID in the target resource ID list (+Empty and other)
341 Object.keys(vf_Services["shared"]["byVf"]).forEach(function(key) {
342 $("#targetResourceId").append($('<option></option>').val(key).html(key));
347 function changeTargetResourceIdOther() {
348 var formItemActive = searchActiveFormId();
349 if ($("#"+formItemActive.id+" #targetResourceId").val()==="Other:") {
350 $("#"+formItemActive.id+" #targetResourceIdOther").show();
352 $("#"+formItemActive.id+" #targetResourceIdOther").hide();
353 $("#"+formItemActive.id+" #targetResourceIdOther").val("");
357 function changeGuardPolicyType() {
358 var formItemActive = searchActiveFormId();
359 if ($("#"+formItemActive.id+" #guardPolicyType").val()==="GUARD_MIN_MAX") {
360 $("#"+formItemActive.id+" #minMaxGuardPolicyDiv").show();
361 $("#"+formItemActive.id+" #frequencyLimiterGuardPolicyDiv").hide();
362 } else if ($("#"+formItemActive.id+" #guardPolicyType").val()==="GUARD_YAML") {
363 $("#"+formItemActive.id+" #minMaxGuardPolicyDiv").hide();
364 $("#"+formItemActive.id+" #frequencyLimiterGuardPolicyDiv").show();
367 //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
368 // css attribute display:none
369 $("#add_one_more").click(function(event) {
370 console.log("add one more");
371 event.preventDefault();
372 var num = add_one_more();
376 // by default, parentPolicyConditions is disabled
377 //$("#parentPolicyConditions").prop('disabled', 'disabled');
384 //Grab saved values for dropdowns
385 var obj = getOperationalPolicyProperty();
387 console.log("lastElementSelected :"+ lastElementSelected);
388 if (!($.isEmptyObject(obj))){
389 allPolicies = jQuery.extend({}, obj);
390 for (var x in allPolicies){
391 $("#policyTable").prepend("<tr><td>"+x+"</td></tr>");
392 if (allPolicies[x][1]['value']){
393 allPolIds.push(parseInt(allPolicies[x][1]['value']));
395 console.log("policies found :"+ x);
400 if (loadPolicy !== undefined && loadPolicy !== null) {
402 console.log("load properties");
403 disperseConfig(allPolicies,loadPolicy);
405 console.log("create new policy");
409 //load recipes for a chosen policy
410 function disperseConfig(policyObj, id){
411 console.log("disperseConfig with id:" + id);
413 //remove old gui forms
414 for (var i=1; i<($(".formId").length + 1); i++){
415 $("#go_properties_tab"+i).parent().remove();
417 $(".formId").remove();
419 if (policyObj !== undefined && policyObj[id] !== undefined) {
420 var el = policyObj[id][3]['policyConfigurations']
421 for (var i = 0; i < el.length; i++) {
423 var num = add_one_more();
424 console.log("number is=:" + num);
426 for (var j = 0; j < el[i].length; j++) {
427 console.log("attr:" + el[i][j].name + "; value is:" + el[i][j].value);
428 if(el[i][j].hasOwnProperty("name")){
429 $("#formId" + num + " #" + el[i][j].name).val(
431 if(el[i][j].name==="_id") {
432 console.log("formId num:" + num + "; value is:" + el[i][j].value);
433 policy_ids["#formId" + num]=el[i][j].value
435 if(el[i][j].name==='parentPolicy')
436 parent_policy[num]=el[i][j].value
437 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
438 $("#go_properties_tab"+num).text(el[i][j].value)
440 if(el[i][j].name==="targetResourceIdOther" && el[i][j].value.toString()!=='') {
441 // Add the entry and set it
442 $("#formId" + num + " #targetResourceId").append($('<option></option>').val($("#formId" + num + " #targetResourceIdOther").val()).html($("#formId" + num + " #targetResourceIdOther").val()));
443 $("#formId" + num + " #targetResourceId").val($("#formId" + num + " #targetResourceIdOther").val());
445 changeGuardPolicyType();
450 //Adding all the ids for parent policy options
451 for(var i=1;i<=$(".formId").length;i++){
452 for(k in policy_ids){
453 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
454 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
459 for(k in parent_policy){
460 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
461 if($("#formId"+k+" #parentPolicy").val() ==""){
462 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
464 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
466 // force the change event
467 $("#formId"+k+" #parentPolicy").change();
470 // Now load all component with the right value defined in policyObj JSON
471 for (headInd in policyObj[id]){
472 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
473 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
481 $('select[multiple] option').each(function() {
482 var input = $('input[value="' + $(this).val() + '"]');
483 input.prop('disabled', true);
484 input.parent('li').addClass('disabled');
486 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
491 function addSelectListen(count) {
492 var onSelectChange = function() {
493 var opselected = this.selectedOptions[0].text;
495 if (this.id == "recipe"){
497 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
498 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
500 $(this).closest("[id^='go_properties_tab']").text("Policy");
504 if (this.id=="parentPolicy"){
505 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
507 ppCond.multiselect("clearSelection");
508 ppCond.multiselect("disable");
510 ppCond.multiselect("enable");
514 $("#formId"+count+" select").each( function () {
515 this.change = onSelectChange;
520 //This is ensure there are no repeated keys in the map
521 function noRepeats(form) {
522 //triggered per policy.
524 for (var i = 0; i < form.length; i++) {
525 if (select[form[i].name] === undefined)
526 select[form[i].name] = []
527 select[form[i].name].push(form[i].value);
539 $("#savePropsBtn").click(function(event) {
540 console.log("save properties triggered");
541 if($("#targetResourceIdOther").is(":visible")) {
542 $('#targetResourceId').append($('<option></option>').val($("#targetResourceIdOther").val()).html($("#targetResourceIdOther").val()))
543 $("#targetResourceId").val($("#targetResourceIdOther").val());
545 $(".idError").hide();
547 console.log("save properties triggered2");
549 /* if ($("#policyTable .highlight").length > 0){
550 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
554 //Removes outdated (deleted) policies by checking against left menu
555 console.log("get all policies");
556 var finalSaveList = {};
557 $("#policyTable td").each(function(){
558 console.log("enter policy table each loop");
559 var tableVal = $(this).text();
560 if (tableVal in allPolicies){
561 finalSaveList[tableVal] = allPolicies[tableVal];
563 console.log("save properties; add tableVal to policies: "+ tableVal);
565 var scope = angular.element(document.getElementById('formSpan')).scope();
566 scope.submitForm(finalSaveList);
567 $("#close_button").click();
570 function add_one_more() {
571 console.log("add one more");
573 $("#nav_Tabs li").removeClass("active");
575 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
576 var form = $($("#formSpan").children()[0]).clone()
578 //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
579 if ($(".formId").length > 0) {
581 var s = $(".formId");
582 for (var i = 0; i < s.length; i++) {
583 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
584 greatest = parseInt($(s[i]).attr("id").substring(6))
587 count = greatest + 1;
588 $("#properties_tab").append(
589 ('<span class="formId" id="formId'+count+'"></span>'));
592 $("#properties_tab").append(
593 '<span class="formId" id="formId1"></span>');
596 //$(form).find("#policyName").val("Recipe "+makid(2))
597 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
598 //alert($(form).find("#_id").val())
599 //policyNameChangeListener(form)
603 ' <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>');
604 $("#formId" + count).append(form);
605 $(".formId").not($("#formId" + count)).css("display", "none")
608 addSelectListen(count);
609 // This is for when the process is not loading from map but being created
612 $(form).find("#_id").val(l)
613 policy_ids["#formId" + count]=l
616 for(var i=1;i<=greatestIdNum();i++){
617 if($("#formId"+i).length>0){
618 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
619 $("#formId"+i+" #parentPolicy").empty();
621 for(k in policy_ids){
622 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
623 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
626 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
630 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
632 //re-populate parent policy with chosen options
643 function addCustListen(count) {
644 $('#go_properties_tab' + count).click(function(event) {
645 $("#nav_Tabs li").removeClass("active");
646 $(this).parent().addClass("active");
647 $("#formId" + count).css("display", "")
648 $(".formId").not($("#formId" + count)).css("display", "none")
651 $('#tab_close' + count).click(function(event) {
652 if(document.getElementById("timeout").disabled){
655 $(this).parent().remove();
656 for(var i=1;i<=greatestIdNum();i++){
657 if( $("#formId"+i).length>0){
659 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
660 $("#formId"+i+" #parentPolicy").val("")
661 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
665 delete policy_ids["#formId" + count + " #_id"]
666 $("#formId" + count).remove();
671 function greatestIdNum() {
673 var s = $(".formId");
674 for (var i = 0; i < s.length; i++) {
675 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
676 greatest = parseInt($(s[i]).attr("id").substring(6))
682 //Generate random id for each policy
683 //Also made sure ids couldnt be repeated
684 function makeid(num) {
687 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
690 for (var i = 0; i < 7; i++)
691 text += possible.charAt(Math.floor(Math.random()
693 var hasValue = false;
694 for (k in policy_ids) {
695 if (text === policy_ids[k])
704 var ParentPolicy = function(id, name) {
709 function saveLastPolicyLocally(lastPolicyId) {
710 console.log("last policy id is:" + lastPolicyId);
713 var properties = $(".saveProps").not("#formSpan .saveProps");
714 var timeoutForm = $("#Timeoutform").serializeArray();
716 for (var i = 0; i < timeoutForm.length; i++) {
717 polForm.push(timeoutForm[i]);
721 d["policyConfigurations"] = [];
722 for (var i = 0; i < properties.length; i++) {
723 var ser = $(properties[i]).serializeArray();
724 var s = noRepeats(ser)
725 d["policyConfigurations"].push(s);
729 for (var x in allPolicies){
730 if (x !== lastPolicyId) {
731 delete allPolicies[x];
732 console.log("remove old policy"+ x);
736 allPolicies[lastPolicyId] = polForm;
739 $('#policyTable').on('click', 'tr', function(event) {
741 console.log("click on policyTable");
742 $(".idError").hide();
747 $(this).addClass('highlight').siblings().removeClass('highlight');
748 disperseConfig(allPolicies, $(this).find("td").html());
752 $('#pname').on('keypress', function(e){
753 /* var newVal = $(this).val() + String.fromCharCode(e.which);
754 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
757 if (e.keyCode == 32){
758 $("#spaceError").show();
763 function isNumberKey(event){
764 var charCode = (event.which) ? event.which : event.keyCode
765 if (charCode > 31 && (charCode < 48 || charCode > 57)){
771 function startNextItem() {
772 console.log("start next Item, policyname is:" + $("#pname").val());
773 //save last item before transitioning
774 var lastItem = $("#policyTable .highlight");
775 console.log("start next Item, lastitem is:" + lastItem);
776 if (lastItem.length > 0) {
777 console.log("start next Item length > 0");
778 saveLastPolicyLocally($("#pname").val());
779 //lastItem.attr("id", $("#pname").val());
780 lastItem.find("td").html($("#pname").val());
784 function add_new_policy(issueNewNames) {
785 console.log("add new policy");
786 //remove old gui forms
787 for (var i=1; i<($(".formId").length + 1); i++){
788 $("#go_properties_tab"+i).parent().remove();
790 $(".formId").remove();
791 $("#pname").val("New_Policy");
792 $("#timeout").val(getOperationalPolicyProperty().timeout);
794 $("#add_one_more").click();
796 console.log("start next Item on 796");
799 if (("#policyTable .highlight").length > 0){
800 $('#policyTable tr.highlight').removeClass('highlight');
802 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
806 initTargetResourceId();
807 //load metrics dropdown
808 if (elementMap["global"]) {
809 for (var i = 0; i < (elementMap["global"].length); i++){
810 if ((elementMap["global"][i]["name"]) == "actionSet"){
811 var asSel = elementMap["global"][i]["value"];
812 if (asSel == "vnfRecipe" && vf_Services !== null && vf_Services !== undefined){
813 if (vf_Services["policy"][asSel]){
814 $.each((vf_Services["policy"][asSel]), function(val, text) {
816 $('<option></option>').val(val).html(text)