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")
557 //addTabListen(count)
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();
607 //listener will change the tab name to the recipe
608 function addTabListen(count){
610 // disable parentPolicyConditions when a parentPolicy is not selected
611 //don't think this is used..
612 /* $("#formId"+count+" #parentPolicy").on("change",function(){
613 if($("#formId"+count+" #parentPolicy").val().toString()==""){
614 // deselect all options
615 $("#formId"+count+" #parentPolicyConditions option:selected").prop("selected", false);
616 // disable the select box
617 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
620 $("#formId"+count+" #parentPolicyConditions").multiselect("enable");
626 function addCustListen(count) {
627 $('#go_properties_tab' + count).click(function(event) {
628 $("#nav_Tabs li").removeClass("active");
629 $(this).parent().addClass("active");
630 $("#formId" + count).css("display", "")
631 $(".formId").not($("#formId" + count)).css("display", "none")
634 $('#tab_close' + count).click(function(event) {
635 if(document.getElementById("timeout").disabled){
638 $(this).parent().remove();
639 for(var i=1;i<=greatestIdNum();i++){
640 if( $("#formId"+i).length>0){
642 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
643 $("#formId"+i+" #parentPolicy").val("")
644 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
648 delete policy_ids["#formId" + count + " #_id"]
649 $("#formId" + count).remove();
654 function greatestIdNum() {
656 var s = $(".formId");
657 for (var i = 0; i < s.length; i++) {
658 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
659 greatest = parseInt($(s[i]).attr("id").substring(6))
665 //Generate random id for each policy
666 //Also made sure ids couldnt be repeated
667 function makeid(num) {
670 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
673 for (var i = 0; i < 7; i++)
674 text += possible.charAt(Math.floor(Math.random()
676 var hasValue = false;
677 for (k in policy_ids) {
678 if (text === policy_ids[k])
687 var ParentPolicy = function(id, name) {
692 //Policy table search filter
693 function searchPolicyList() {
694 var search = document.getElementById("policySearch");
695 var row = document.getElementsByTagName("td");
696 for (var i = 0; i < row.length; i++) {
697 if (row[i].innerHTML.toUpperCase().indexOf(
698 search.value.toUpperCase()) > -1) {
699 row[i].style.display = "";
701 row[i].style.display = "none";
706 function saveLastPolicyLocally(lastPolicyId) {
709 var properties = $(".saveProps").not("#formSpan .saveProps");
710 var timeoutForm = $("#Timeoutform").serializeArray();
712 for (var i = 0; i < timeoutForm.length; i++) {
713 polForm.push(timeoutForm[i]);
717 d["policyConfigurations"] = [];
718 for (var i = 0; i < properties.length; i++) {
719 var ser = $(properties[i]).serializeArray();
720 var s = noRepeats(ser)
721 d["policyConfigurations"].push(s);
724 allPolicies[lastPolicyId] = polForm;
727 function getNextId(){
730 if ((Math.min.apply(Math, allPolIds) == 0)
731 && (allPolIds.length > 0)) {
733 for (var i = 1; i < allPolIds.length; i++) {
734 if ((allPolIds[i] - allPolIds[i - 1]) != 1) {
735 newPolId = (allPolIds[i - 1] + 1);
740 newPolId = (Math.max.apply(Math, allPolIds)) + 1;
745 allPolIds.push(newPolId);
746 $("#pid").val(newPolId);
749 $("#deletePolicy").on('click', function() {
750 $(".idError").hide();
752 allPolIds.splice((allPolIds.indexOf(parseInt($("#pid").val()))),1);
755 var deleteId = $("#policyTable .highlight td").html();
756 delete allPolicies[deleteId];
757 $("#policyTable .highlight").remove();
762 $('#policyTable').on('click', 'tr', function(event) {
763 $(".idError").hide();
765 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
767 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
768 $("#repeatIdError").show();
770 } else { //not repeated
771 $("#repeatIdError").hide();
772 delete allPolicies[$("#policyTable .highlight td").html()];
775 //if (parseInt($("#pname").val()) == 0){
776 if ($("#pname").val().trim() == "New_Policy"){
777 $("#newIdError").show();
783 if ($("#policyTable .highlight").length == 0){
787 $(this).addClass('highlight').siblings().removeClass('highlight');
788 disperseConfig(allPolicies, $(this).find("td").html());
791 $('#createNewPolicy').on('click', function(){
792 $(".idError").hide();
794 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
796 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
797 $("#repeatIdError").show();
799 } else { //not repeated
800 $("#repeatIdError").hide();
801 delete allPolicies[$("#policyTable .highlight td").html()];
804 //if (parseInt($("#pname").val()) == 0){
805 if ($("#pname").val().trim() == "New_Policy"){
806 $("#newIdError").show();
811 if (("#policyTable .highlight").length > 0){
812 $('#policyTable tr.highlight').removeClass('highlight');
814 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
819 $('#pname').on('keypress', function(e){
820 /* var newVal = $(this).val() + String.fromCharCode(e.which);
821 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
824 if (e.keyCode == 32){
825 $("#spaceError").show();
830 function isNumberKey(event){
831 var charCode = (event.which) ? event.which : event.keyCode
832 if (charCode > 31 && (charCode < 48 || charCode > 57)){
838 function startNextItem() {
839 //save last item before transitioning
840 var lastItem = $("#policyTable .highlight");
841 if (lastItem.length > 0) {
842 saveLastPolicyLocally($("#pname").val());
843 //lastItem.attr("id", $("#pname").val());
844 lastItem.find("td").html($("#pname").val());
850 if ($("#deletePolicy").prop("disabled")) {
851 $("#deletePolicy").prop("disabled", false);
856 initTargetResourceId();
857 //load metrics dropdown
858 if (elementMap["global"]){
859 for (var i = 0; i < (elementMap["global"].length); i++){
860 if ((elementMap["global"][i]["name"]) == "actionSet"){
861 var asSel = elementMap["global"][i]["value"];
862 if (asSel == "vnfRecipe"){
863 if (vf_Services["policy"][asSel]){
864 $.each((vf_Services["policy"][asSel]), function(val, text) {
866 $('<option></option>').val(val).html(text)
876 //Show table panel only
877 function expandTable() {
878 $(".policyPanel").css("display", "none");
879 $(".leftPolicyPanel").removeClass("col-sm-3");
880 $(".modelSearchBox").css("padding", "25px 12px");
881 if (!($("#deletePolicy").prop("disabled"))) {
882 $("#deletePolicy").prop("disabled", true);
887 function collapseTable() {
888 $(".leftPolicyPanel").addClass("col-sm-3");
889 $(".modelSearchBox").css("padding", "10px 12px");
890 $(".policyPanel").css("display", "unset");