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>
311 function changeTargetResourceIdOther() {
312 if ($("#targetResourceId").val()==="Other:") {
313 $("#targetResourceIdOther").show();
315 $("#targetResourceIdOther").hide();
316 $("#targetResourceIdOther").val("");
319 //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
320 // css attribute display:none
321 $("#add_one_more").click(function(event) {
322 event.preventDefault();
323 var num = add_one_more();
326 loadPropertyWindow("policy")
328 // by default, parentPolicyConditions is disabled
329 //$("#parentPolicyConditions").prop('disabled', 'disabled');
336 //Grab saved values for dropdowns
337 var obj = elementMap[lastElementSelected];
339 if (!($.isEmptyObject(obj))){
340 allPolicies = jQuery.extend({}, obj);
341 for (var x in allPolicies){
342 $("#policyTable").prepend("<tr><td>"+x+"</td></tr>");
343 if (allPolicies[x][1]['value']){
344 allPolIds.push(parseInt(allPolicies[x][1]['value']));
350 //load recipes for a chosen policy
351 function disperseConfig(policyObj, id){
353 //remove old gui forms
354 for (var i=1; i<($(".formId").length + 1); i++){
355 $("#go_properties_tab"+i).parent().remove();
357 $(".formId").remove();
359 if (policyObj !== undefined) {
360 // Set all the Resource Invariant UUID in the target resource ID list (+Empty and other)
361 Object.keys(vf_Services["shared"]["byVf"]).forEach(function(key){
362 $('#targetResourceId').append($('<option></option>').val(key).html(key));
365 var el = policyObj[id][3]['policyConfigurations']
366 for (var i = 0; i < el.length; i++) {
368 var num = add_one_more();
370 for (var j = 0; j < el[i].length; j++) {
371 if(el[i][j].hasOwnProperty("name")){
372 $("#formId" + num + " #" + el[i][j].name).val(
374 if(el[i][j].name==="_id")
375 policy_ids["#formId" + num]=el[i][j].value
376 if(el[i][j].name==='parentPolicy')
377 parent_policy[num]=el[i][j].value
378 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
379 $("#go_properties_tab"+num).text(el[i][j].value)
381 if(el[i][j].name==="targetResourceIdOther" && el[i][j].value.toString()!=='') {
382 // Add the entry and set it
383 $('#targetResourceId').append($('<option></option>').val($('#targetResourceIdOther').val()).html($('#targetResourceIdOther').val()));
384 $('#targetResourceId').val($('#targetResourceIdOther').val());
391 //Adding all the ids for parent policy options
392 for(var i=1;i<=$(".formId").length;i++){
393 for(k in policy_ids){
394 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
395 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
400 for(k in parent_policy){
401 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
402 if($("#formId"+k+" #parentPolicy").val() ==""){
403 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
405 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
407 // force the change event
408 $("#formId"+k+" #parentPolicy").change();
411 // Now load all component with the right value defined in policyObj JSON
412 for (headInd in policyObj[id]){
413 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
414 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
422 $('select[multiple] option').each(function() {
423 var input = $('input[value="' + $(this).val() + '"]');
424 input.prop('disabled', true);
425 input.parent('li').addClass('disabled');
427 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
432 function addSelectListen(count) {
433 var onSelectChange = function() {
434 var opselected = this.selectedOptions[0].text;
436 if (this.id == "recipe"){
438 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
439 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
441 $(this).closest("[id^='go_properties_tab']").text("Policy");
445 if (this.id=="parentPolicy"){
446 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
448 ppCond.multiselect("clearSelection");
449 ppCond.multiselect("disable");
451 ppCond.multiselect("enable");
455 $("#formId"+count+" select").each( function () {
456 this.change = onSelectChange;
461 //This is ensure there are no repeated keys in the map
462 function noRepeats(form) {
463 //triggered per policy.
465 for (var i = 0; i < form.length; i++) {
466 if (select[form[i].name] === undefined)
467 select[form[i].name] = []
468 select[form[i].name].push(form[i].value);
480 $("#savePropsBtn").click(function(event) {
481 if($("#targetResourceIdOther").is(":visible")) {
482 $('#targetResourceId').append($('<option></option>').val($("#targetResourceIdOther").val()).html($("#targetResourceIdOther").val()))
483 $("#targetResourceId").val($("#targetResourceIdOther").val());
485 $(".idError").hide();
486 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
488 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
489 $("#repeatIdError").show();
491 } else { //not repeated
492 delete allPolicies[$("#policyTable .highlight td").html()];
495 if ($("#pname").val().trim() == "New_Policy"){
496 $("#newIdError").show();
501 /* if ($("#policyTable .highlight").length > 0){
502 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
506 //Removes outdated (deleted) policies by checking against left menu
507 var finalSaveList = {};
508 $("#policyTable td").each(function(){
509 var tableVal = $(this).text();
510 if (tableVal in allPolicies){
511 finalSaveList[tableVal] = allPolicies[tableVal];
515 saveProperties(finalSaveList);
516 $("#close_button").click();
519 function add_one_more() {
520 $("#nav_Tabs li").removeClass("active");
522 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
523 var form = $($("#formSpan").children()[0]).clone()
525 //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
526 if ($(".formId").length > 0) {
528 var s = $(".formId");
529 for (var i = 0; i < s.length; i++) {
530 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
531 greatest = parseInt($(s[i]).attr("id").substring(6))
534 count = greatest + 1;
535 $("#properties_tab").append(
536 ('<span class="formId" id="formId'+count+'"></span>'));
539 $("#properties_tab").append(
540 '<span class="formId" id="formId1"></span>');
543 //$(form).find("#policyName").val("Recipe "+makid(2))
544 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
545 //alert($(form).find("#_id").val())
546 //policyNameChangeListener(form)
550 ' <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>');
551 $("#formId" + count).append(form);
552 $(".formId").not($("#formId" + count)).css("display", "none")
554 //addTabListen(count)
555 addSelectListen(count);
556 // This is for when the process is not loading from map but being created
559 $(form).find("#_id").val(l)
560 policy_ids["#formId" + count]=l
563 for(var i=1;i<=greatestIdNum();i++){
564 if($("#formId"+i).length>0){
565 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
566 $("#formId"+i+" #parentPolicy").empty();
568 for(k in policy_ids){
569 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
570 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
573 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
577 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
579 //re-populate parent policy with chosen options
588 function add_new_policy(issueNewNames) {
589 //remove old gui forms
590 for (var i=1; i<($(".formId").length + 1); i++){
591 $("#go_properties_tab"+i).parent().remove();
593 $(".formId").remove();
596 //$("#pname").val("0");
597 $("#pname").val("New_Policy");
598 $("#timeout").val(defaults_props.policy.timeout);
600 $("#add_one_more").click();
604 //listener will change the tab name to the recipe
605 function addTabListen(count){
607 // disable parentPolicyConditions when a parentPolicy is not selected
608 //don't think this is used..
609 /* $("#formId"+count+" #parentPolicy").on("change",function(){
610 if($("#formId"+count+" #parentPolicy").val().toString()==""){
611 // deselect all options
612 $("#formId"+count+" #parentPolicyConditions option:selected").prop("selected", false);
613 // disable the select box
614 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
617 $("#formId"+count+" #parentPolicyConditions").multiselect("enable");
623 function addCustListen(count) {
624 $('#go_properties_tab' + count).click(function(event) {
625 $("#nav_Tabs li").removeClass("active");
626 $(this).parent().addClass("active");
627 $("#formId" + count).css("display", "")
628 $(".formId").not($("#formId" + count)).css("display", "none")
631 $('#tab_close' + count).click(function(event) {
632 if(document.getElementById("timeout").disabled){
635 $(this).parent().remove();
636 for(var i=1;i<=greatestIdNum();i++){
637 if( $("#formId"+i).length>0){
639 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
640 $("#formId"+i+" #parentPolicy").val("")
641 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
645 delete policy_ids["#formId" + count + " #_id"]
646 $("#formId" + count).remove();
651 function greatestIdNum() {
653 var s = $(".formId");
654 for (var i = 0; i < s.length; i++) {
655 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
656 greatest = parseInt($(s[i]).attr("id").substring(6))
662 //Generate random id for each policy
663 //Also made sure ids couldnt be repeated
664 function makeid(num) {
667 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
670 for (var i = 0; i < 7; i++)
671 text += possible.charAt(Math.floor(Math.random()
673 var hasValue = false;
674 for (k in policy_ids) {
675 if (text === policy_ids[k])
684 var ParentPolicy = function(id, name) {
689 //Policy table search filter
690 function searchPolicyList() {
691 var search = document.getElementById("policySearch");
692 var row = document.getElementsByTagName("td");
693 for (var i = 0; i < row.length; i++) {
694 if (row[i].innerHTML.toUpperCase().indexOf(
695 search.value.toUpperCase()) > -1) {
696 row[i].style.display = "";
698 row[i].style.display = "none";
703 function saveLastPolicyLocally(lastPolicyId) {
706 var properties = $(".saveProps").not("#formSpan .saveProps");
707 var timeoutForm = $("#Timeoutform").serializeArray();
709 for (var i = 0; i < timeoutForm.length; i++) {
710 polForm.push(timeoutForm[i]);
714 d["policyConfigurations"] = [];
715 for (var i = 0; i < properties.length; i++) {
716 var ser = $(properties[i]).serializeArray();
717 var s = noRepeats(ser)
718 d["policyConfigurations"].push(s);
721 allPolicies[lastPolicyId] = polForm;
724 function getNextId(){
727 if ((Math.min.apply(Math, allPolIds) == 0)
728 && (allPolIds.length > 0)) {
730 for (var i = 1; i < allPolIds.length; i++) {
731 if ((allPolIds[i] - allPolIds[i - 1]) != 1) {
732 newPolId = (allPolIds[i - 1] + 1);
737 newPolId = (Math.max.apply(Math, allPolIds)) + 1;
742 allPolIds.push(newPolId);
743 $("#pid").val(newPolId);
746 $("#deletePolicy").on('click', function() {
747 $(".idError").hide();
749 allPolIds.splice((allPolIds.indexOf(parseInt($("#pid").val()))),1);
752 var deleteId = $("#policyTable .highlight td").html();
753 delete allPolicies[deleteId];
754 $("#policyTable .highlight").remove();
759 $('#policyTable').on('click', 'tr', function(event) {
760 $(".idError").hide();
762 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
764 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
765 $("#repeatIdError").show();
767 } else { //not repeated
768 $("#repeatIdError").hide();
769 delete allPolicies[$("#policyTable .highlight td").html()];
772 //if (parseInt($("#pname").val()) == 0){
773 if ($("#pname").val().trim() == "New_Policy"){
774 $("#newIdError").show();
780 if ($("#policyTable .highlight").length == 0){
784 $(this).addClass('highlight').siblings().removeClass('highlight');
785 disperseConfig(allPolicies, $(this).find("td").html());
788 $('#createNewPolicy').on('click', function(){
789 $(".idError").hide();
791 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
793 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
794 $("#repeatIdError").show();
796 } else { //not repeated
797 $("#repeatIdError").hide();
798 delete allPolicies[$("#policyTable .highlight td").html()];
801 //if (parseInt($("#pname").val()) == 0){
802 if ($("#pname").val().trim() == "New_Policy"){
803 $("#newIdError").show();
808 if (("#policyTable .highlight").length > 0){
809 $('#policyTable tr.highlight').removeClass('highlight');
811 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
816 $('#pname').on('keypress', function(e){
817 /* var newVal = $(this).val() + String.fromCharCode(e.which);
818 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
821 if (e.keyCode == 32){
822 $("#spaceError").show();
827 function isNumberKey(event){
828 var charCode = (event.which) ? event.which : event.keyCode
829 if (charCode > 31 && (charCode < 48 || charCode > 57)){
835 function startNextItem() {
836 //save last item before transitioning
837 var lastItem = $("#policyTable .highlight");
838 if (lastItem.length > 0) {
839 saveLastPolicyLocally($("#pname").val());
840 //lastItem.attr("id", $("#pname").val());
841 lastItem.find("td").html($("#pname").val());
847 if ($("#deletePolicy").prop("disabled")) {
848 $("#deletePolicy").prop("disabled", false);
854 //load metrics dropdown
855 if (elementMap["global"]){
856 for (var i = 0; i < (elementMap["global"].length); i++){
857 if ((elementMap["global"][i]["name"]) == "actionSet"){
858 var asSel = elementMap["global"][i]["value"];
859 if (asSel == "vnfRecipe"){
860 if (vf_Services["policy"][asSel]){
861 $.each((vf_Services["policy"][asSel]), function(val, text) {
863 $('<option></option>').val(val).html(text)
873 //Show table panel only
874 function expandTable() {
875 $(".policyPanel").css("display", "none");
876 $(".leftPolicyPanel").removeClass("col-sm-3");
877 $(".modelSearchBox").css("padding", "25px 12px");
878 if (!($("#deletePolicy").prop("disabled"))) {
879 $("#deletePolicy").prop("disabled", true);
884 function collapseTable() {
885 $(".leftPolicyPanel").addClass("col-sm-3");
886 $(".modelSearchBox").css("padding", "10px 12px");
887 $(".policyPanel").css("display", "unset");