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']));
357 initTargetResourceId();
359 //load recipes for a chosen policy
360 function disperseConfig(policyObj, id){
362 //remove old gui forms
363 for (var i=1; i<($(".formId").length + 1); i++){
364 $("#go_properties_tab"+i).parent().remove();
366 $(".formId").remove();
368 if (policyObj !== undefined) {
369 var el = policyObj[id][3]['policyConfigurations']
370 for (var i = 0; i < el.length; i++) {
372 var num = add_one_more();
374 for (var j = 0; j < el[i].length; j++) {
375 if(el[i][j].hasOwnProperty("name")){
376 $("#formId" + num + " #" + el[i][j].name).val(
378 if(el[i][j].name==="_id")
379 policy_ids["#formId" + num]=el[i][j].value
380 if(el[i][j].name==='parentPolicy')
381 parent_policy[num]=el[i][j].value
382 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
383 $("#go_properties_tab"+num).text(el[i][j].value)
385 if(el[i][j].name==="targetResourceIdOther" && el[i][j].value.toString()!=='') {
386 // Add the entry and set it
387 $('#targetResourceId').append($('<option></option>').val($('#targetResourceIdOther').val()).html($('#targetResourceIdOther').val()));
388 $('#targetResourceId').val($('#targetResourceIdOther').val());
395 //Adding all the ids for parent policy options
396 for(var i=1;i<=$(".formId").length;i++){
397 for(k in policy_ids){
398 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
399 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
404 for(k in parent_policy){
405 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
406 if($("#formId"+k+" #parentPolicy").val() ==""){
407 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
409 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
411 // force the change event
412 $("#formId"+k+" #parentPolicy").change();
415 // Now load all component with the right value defined in policyObj JSON
416 for (headInd in policyObj[id]){
417 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
418 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
426 $('select[multiple] option').each(function() {
427 var input = $('input[value="' + $(this).val() + '"]');
428 input.prop('disabled', true);
429 input.parent('li').addClass('disabled');
431 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
436 function addSelectListen(count) {
437 var onSelectChange = function() {
438 var opselected = this.selectedOptions[0].text;
440 if (this.id == "recipe"){
442 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
443 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
445 $(this).closest("[id^='go_properties_tab']").text("Policy");
449 if (this.id=="parentPolicy"){
450 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
452 ppCond.multiselect("clearSelection");
453 ppCond.multiselect("disable");
455 ppCond.multiselect("enable");
459 $("#formId"+count+" select").each( function () {
460 this.change = onSelectChange;
465 //This is ensure there are no repeated keys in the map
466 function noRepeats(form) {
467 //triggered per policy.
469 for (var i = 0; i < form.length; i++) {
470 if (select[form[i].name] === undefined)
471 select[form[i].name] = []
472 select[form[i].name].push(form[i].value);
484 $("#savePropsBtn").click(function(event) {
485 if($("#targetResourceIdOther").is(":visible")) {
486 $('#targetResourceId').append($('<option></option>').val($("#targetResourceIdOther").val()).html($("#targetResourceIdOther").val()))
487 $("#targetResourceId").val($("#targetResourceIdOther").val());
489 $(".idError").hide();
490 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
492 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
493 $("#repeatIdError").show();
495 } else { //not repeated
496 delete allPolicies[$("#policyTable .highlight td").html()];
499 if ($("#pname").val().trim() == "New_Policy"){
500 $("#newIdError").show();
505 /* if ($("#policyTable .highlight").length > 0){
506 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
510 //Removes outdated (deleted) policies by checking against left menu
511 var finalSaveList = {};
512 $("#policyTable td").each(function(){
513 var tableVal = $(this).text();
514 if (tableVal in allPolicies){
515 finalSaveList[tableVal] = allPolicies[tableVal];
519 saveProperties(finalSaveList);
520 $("#close_button").click();
523 function add_one_more() {
524 $("#nav_Tabs li").removeClass("active");
526 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
527 var form = $($("#formSpan").children()[0]).clone()
529 //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
530 if ($(".formId").length > 0) {
532 var s = $(".formId");
533 for (var i = 0; i < s.length; i++) {
534 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
535 greatest = parseInt($(s[i]).attr("id").substring(6))
538 count = greatest + 1;
539 $("#properties_tab").append(
540 ('<span class="formId" id="formId'+count+'"></span>'));
543 $("#properties_tab").append(
544 '<span class="formId" id="formId1"></span>');
547 //$(form).find("#policyName").val("Recipe "+makid(2))
548 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
549 //alert($(form).find("#_id").val())
550 //policyNameChangeListener(form)
554 ' <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>');
555 $("#formId" + count).append(form);
556 $(".formId").not($("#formId" + count)).css("display", "none")
558 //addTabListen(count)
559 addSelectListen(count);
560 // This is for when the process is not loading from map but being created
563 $(form).find("#_id").val(l)
564 policy_ids["#formId" + count]=l
567 for(var i=1;i<=greatestIdNum();i++){
568 if($("#formId"+i).length>0){
569 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
570 $("#formId"+i+" #parentPolicy").empty();
572 for(k in policy_ids){
573 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
574 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
577 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
581 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
583 //re-populate parent policy with chosen options
592 function add_new_policy(issueNewNames) {
593 //remove old gui forms
594 for (var i=1; i<($(".formId").length + 1); i++){
595 $("#go_properties_tab"+i).parent().remove();
597 $(".formId").remove();
600 //$("#pname").val("0");
601 $("#pname").val("New_Policy");
602 $("#timeout").val(defaults_props.policy.timeout);
604 $("#add_one_more").click();
608 //listener will change the tab name to the recipe
609 function addTabListen(count){
611 // disable parentPolicyConditions when a parentPolicy is not selected
612 //don't think this is used..
613 /* $("#formId"+count+" #parentPolicy").on("change",function(){
614 if($("#formId"+count+" #parentPolicy").val().toString()==""){
615 // deselect all options
616 $("#formId"+count+" #parentPolicyConditions option:selected").prop("selected", false);
617 // disable the select box
618 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
621 $("#formId"+count+" #parentPolicyConditions").multiselect("enable");
627 function addCustListen(count) {
628 $('#go_properties_tab' + count).click(function(event) {
629 $("#nav_Tabs li").removeClass("active");
630 $(this).parent().addClass("active");
631 $("#formId" + count).css("display", "")
632 $(".formId").not($("#formId" + count)).css("display", "none")
635 $('#tab_close' + count).click(function(event) {
636 if(document.getElementById("timeout").disabled){
639 $(this).parent().remove();
640 for(var i=1;i<=greatestIdNum();i++){
641 if( $("#formId"+i).length>0){
643 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
644 $("#formId"+i+" #parentPolicy").val("")
645 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
649 delete policy_ids["#formId" + count + " #_id"]
650 $("#formId" + count).remove();
655 function greatestIdNum() {
657 var s = $(".formId");
658 for (var i = 0; i < s.length; i++) {
659 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
660 greatest = parseInt($(s[i]).attr("id").substring(6))
666 //Generate random id for each policy
667 //Also made sure ids couldnt be repeated
668 function makeid(num) {
671 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
674 for (var i = 0; i < 7; i++)
675 text += possible.charAt(Math.floor(Math.random()
677 var hasValue = false;
678 for (k in policy_ids) {
679 if (text === policy_ids[k])
688 var ParentPolicy = function(id, name) {
693 //Policy table search filter
694 function searchPolicyList() {
695 var search = document.getElementById("policySearch");
696 var row = document.getElementsByTagName("td");
697 for (var i = 0; i < row.length; i++) {
698 if (row[i].innerHTML.toUpperCase().indexOf(
699 search.value.toUpperCase()) > -1) {
700 row[i].style.display = "";
702 row[i].style.display = "none";
707 function saveLastPolicyLocally(lastPolicyId) {
710 var properties = $(".saveProps").not("#formSpan .saveProps");
711 var timeoutForm = $("#Timeoutform").serializeArray();
713 for (var i = 0; i < timeoutForm.length; i++) {
714 polForm.push(timeoutForm[i]);
718 d["policyConfigurations"] = [];
719 for (var i = 0; i < properties.length; i++) {
720 var ser = $(properties[i]).serializeArray();
721 var s = noRepeats(ser)
722 d["policyConfigurations"].push(s);
725 allPolicies[lastPolicyId] = polForm;
728 function getNextId(){
731 if ((Math.min.apply(Math, allPolIds) == 0)
732 && (allPolIds.length > 0)) {
734 for (var i = 1; i < allPolIds.length; i++) {
735 if ((allPolIds[i] - allPolIds[i - 1]) != 1) {
736 newPolId = (allPolIds[i - 1] + 1);
741 newPolId = (Math.max.apply(Math, allPolIds)) + 1;
746 allPolIds.push(newPolId);
747 $("#pid").val(newPolId);
750 $("#deletePolicy").on('click', function() {
751 $(".idError").hide();
753 allPolIds.splice((allPolIds.indexOf(parseInt($("#pid").val()))),1);
756 var deleteId = $("#policyTable .highlight td").html();
757 delete allPolicies[deleteId];
758 $("#policyTable .highlight").remove();
763 $('#policyTable').on('click', 'tr', function(event) {
764 $(".idError").hide();
766 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
768 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
769 $("#repeatIdError").show();
771 } else { //not repeated
772 $("#repeatIdError").hide();
773 delete allPolicies[$("#policyTable .highlight td").html()];
776 //if (parseInt($("#pname").val()) == 0){
777 if ($("#pname").val().trim() == "New_Policy"){
778 $("#newIdError").show();
784 if ($("#policyTable .highlight").length == 0){
788 $(this).addClass('highlight').siblings().removeClass('highlight');
789 disperseConfig(allPolicies, $(this).find("td").html());
792 $('#createNewPolicy').on('click', function(){
793 $(".idError").hide();
795 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
797 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
798 $("#repeatIdError").show();
800 } else { //not repeated
801 $("#repeatIdError").hide();
802 delete allPolicies[$("#policyTable .highlight td").html()];
805 //if (parseInt($("#pname").val()) == 0){
806 if ($("#pname").val().trim() == "New_Policy"){
807 $("#newIdError").show();
812 if (("#policyTable .highlight").length > 0){
813 $('#policyTable tr.highlight').removeClass('highlight');
815 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
820 $('#pname').on('keypress', function(e){
821 /* var newVal = $(this).val() + String.fromCharCode(e.which);
822 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
825 if (e.keyCode == 32){
826 $("#spaceError").show();
831 function isNumberKey(event){
832 var charCode = (event.which) ? event.which : event.keyCode
833 if (charCode > 31 && (charCode < 48 || charCode > 57)){
839 function startNextItem() {
840 //save last item before transitioning
841 var lastItem = $("#policyTable .highlight");
842 if (lastItem.length > 0) {
843 saveLastPolicyLocally($("#pname").val());
844 //lastItem.attr("id", $("#pname").val());
845 lastItem.find("td").html($("#pname").val());
851 if ($("#deletePolicy").prop("disabled")) {
852 $("#deletePolicy").prop("disabled", false);
858 //load metrics dropdown
859 if (elementMap["global"]){
860 for (var i = 0; i < (elementMap["global"].length); i++){
861 if ((elementMap["global"][i]["name"]) == "actionSet"){
862 var asSel = elementMap["global"][i]["value"];
863 if (asSel == "vnfRecipe"){
864 if (vf_Services["policy"][asSel]){
865 $.each((vf_Services["policy"][asSel]), function(val, text) {
867 $('<option></option>').val(val).html(text)
877 //Show table panel only
878 function expandTable() {
879 $(".policyPanel").css("display", "none");
880 $(".leftPolicyPanel").removeClass("col-sm-3");
881 $(".modelSearchBox").css("padding", "25px 12px");
882 if (!($("#deletePolicy").prop("disabled"))) {
883 $("#deletePolicy").prop("disabled", true);
888 function collapseTable() {
889 $(".leftPolicyPanel").addClass("col-sm-3");
890 $(".modelSearchBox").css("padding", "10px 12px");
891 $(".policyPanel").css("display", "unset");