2 ============LICENSE_START=======================================================
4 ================================================================================
5 Copyright (C) 2017 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 ===================================================================
21 ECOMP is a trademark and service mark of AT&T Intellectual Property.
28 background-color:#dddd;
32 background-color: #dddd;
40 .fileUpload input.upload {
49 filter: alpha(opacity = 0);
54 display: inline-block;
70 vertical-align:middle;
80 background-color:#f2bfab;
91 background-color: #f5f5f5;
92 padding: 15px 5px 0 5px;
108 padding: 2px 2px 2px 30px;
118 border-bottom: 1px solid #ddd;
119 border-collapse: collapse;
129 #policyTable tr.highlight{
130 background-color: #f5f5f5;
143 <script type="text/javascript">
144 function disablefile() {
146 document.getElementById("fileUpload").disabled = true;
150 function disableSVN() {
151 var selectLength = document.querySelectorAll(".disabled-block-container .tab-close-popup");
152 if(selectLength && selectLength.length>0){
153 for(var i = 0; i< selectLength.length ; i++){
154 selectLength[i].disabled = true;
158 document.getElementById("schemaLocation").disabled = true;
159 document.getElementById("userID").disabled = true;
160 document.getElementById("password").disabled = true;
166 <div attribute-test="policywindowproperties" id="configure-widgets"
167 class="disabled-block-container">
168 <div attribute-test="policywindowpropertiesh" class="modal-header">
169 <button type="button" class="close" ng-click="close(false)"
170 aria-hidden="true" style="margin-top: -3px">×</button>
171 <h4>Operational Policy</h4>
175 <div class="modal-body">
176 <div attribute-test="policywindowpropertiesb" class="modal-body row">
178 <div class="leftPolicyPanel">
179 <div class="panel panel-default">
180 <i class="glyphicon glyphicon-search modelSearchBox"></i>
181 <input type="text" id="policySearch" onkeyup="searchPolicyList()"
182 placeholder="Search ...">
183 <div id="policyTableHolder">
184 <table id="policyTable"></table>
187 <div style="float:left">
188 <button type="button" id="createNewPolicy" class="btn btn-sm">New Policy</button></span>
190 <div style="float:right">
191 <button type="button" id="deletePolicy" class="btn btn-sm glyphicon glyphicon-trash" disabled></button></span>
193 <div id="repeatIdError" class="idError">Error: This Policy name is already taken.</div>
194 <div id="newIdError" class="idError">Error: Please rename your new Policy.</div>
195 <div id="spaceError" class="idError">Error: Spaces are not allowed in the ID.</div>
198 <div class="panel panel-default col-sm-9 policyPanel" style="display:none;">
199 <form id="Timeoutform" class="form-horizontal">
201 <div class="form-group clearfix row">
202 <label class="col-sm-2">Name</label>
203 <div class="col-sm-3" style="padding:0px;">
204 <input type="text" id="pname" name="pname" maxlength="48" placeholder="Enter Unique Name" class="form-control">
207 <label class="col-sm-1">ID</label>
208 <div class="col-sm-1" style="padding:0px;">
209 <input onkeydown="return false;" type="text" id="pid" name="pid" class="form-control" readonly>
212 <label for="userID" class="col-sm-3" style="padding-left:5px;padding-right:10px;">Overall Time Limit</label>
213 <div class="col-sm-2" style="padding-left:0px;">
214 <input type="text" maxlength="10" onkeypress="return isNumberKey(event)"
215 class="form-control" id="timeout" name="timeout">
220 <div class="panel-heading" style="background-color: white;">
221 <ul id="nav_Tabs" class="nav nav-tabs">
222 <li class><a id="add_one_more" href="#desc_tab"><span
223 class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
226 <div class="panel-body">
227 <div class="tab-content">
228 <div id="properties_tab" class="tab-pane fade in active"></div>
233 <span id="formSpan" style="display: none">
234 <form class="saveProps" class="form-horizontal">
236 <div class="form-group clearfix" >
237 <label class="col-sm-4 control-label" for="recipe">Recipe</label>
238 <div class="col-sm-8">
239 <select class="form-control" name="recipe" id="recipe" enableFilter="true"></select>
242 <div class="form-group clearfix">
243 <label for="maxRetries" class="col-sm-4 control-label">
245 <div class="col-sm-8">
246 <input type="text" maxlength="5" class="form-control" id="maxRetries"
247 onkeypress="return isNumberKey(event)"
248 name="maxRetries"> </input>
251 <div class="form-group clearfix" >
252 <label for="retryTimeLimit" class="col-sm-4 control-label" >
253 Retry Time Limit</label>
254 <div class="col-sm-8">
255 <input type="text" maxlength="5" class="form-control" id="retryTimeLimit"
256 onkeypress="return isNumberKey(event)"
257 name="retryTimeLimit"></input>
260 <div style="display:none;" class="form-group clearfix">
261 <label for="_id" class="col-sm-4 control-label">
263 <div class="col-sm-8">
264 <input type="text" onkeydown="return false;" class="form-control" id="_id"
265 name="_id" value=""></input>
268 <div class="form-group clearfix">
269 <label for="parentPolicy" class="col-sm-4 control-label">
270 Parent Policy</label>
271 <div class="col-sm-8">
272 <select class="form-control" id="parentPolicy"
273 name="parentPolicy" enableFilter="true"><option value=""></option></select>
276 <div class="form-group clearfix">
277 <label for="parentPolicyConditions" class="col-sm-4 control-label">
278 Parent Policy Conditions</label>
279 <div class="col-sm-8">
280 <select class="form-control" id="parentPolicyConditions"
281 name="parentPolicyConditions" multiple></select>
290 <div attribute-test="policywindowpropertiesf" class="modal-footer">
291 <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
292 <button id="savePropsBtn" class="btn btn-primary">Close</button>
293 <button ng-click="close(true)" id="close_button"
294 class="btn btn-primary">Cancel</button>
298 //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
299 // css attribute display:none
300 $("#add_one_more").click(function(event) {
301 event.preventDefault();
302 var num = add_one_more();
305 loadPropertyWindow("policy")
307 // by default, parentPolicyConditions is disabled
308 //$("#parentPolicyConditions").prop('disabled', 'disabled');
315 //Grab saved values for dropdowns
316 var obj = elementMap[lastElementSelected];
318 if (!($.isEmptyObject(obj))){
319 allPolicies = jQuery.extend({}, obj);
320 for (var x in allPolicies){
321 $("#policyTable").prepend("<tr><td>"+x+"</td></tr>");
322 if (allPolicies[x][1]['value']){
323 allPolIds.push(parseInt(allPolicies[x][1]['value']));
329 //load recipes for a chosen policy
330 function disperseConfig(policyObj, id){
332 //remove old gui forms
333 for (var i=1; i<($(".formId").length + 1); i++){
334 $("#go_properties_tab"+i).parent().remove();
336 $(".formId").remove();
338 if (policyObj !== undefined) {
339 var el = policyObj[id][3]['policyConfigurations']
340 for (var i = 0; i < el.length; i++) {
342 var num = add_one_more();
344 for (var j = 0; j < el[i].length; j++) {
345 if(el[i][j].hasOwnProperty("name")){
346 $("#formId" + num + " #" + el[i][j].name).val(
348 if(el[i][j].name==="_id")
349 policy_ids["#formId" + num]=el[i][j].value
350 if(el[i][j].name==='parentPolicy')
351 parent_policy[num]=el[i][j].value
352 if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
353 $("#go_properties_tab"+num).text(el[i][j].value)
359 //Adding all the ids for parent policy options
360 for(var i=1;i<=$(".formId").length;i++){
361 for(k in policy_ids){
362 if($("#formId"+i+" #_id").val()!==policy_ids[k].toString() && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
363 $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
368 for(k in parent_policy){
369 $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
370 if($("#formId"+k+" #parentPolicy").val() ==""){
371 $("#formId" +k+ " #parentPolicyConditions").multiselect("disable");
373 $("#formId" +k+ " #parentPolicyConditions").multiselect("enable");
375 // force the change event
376 $("#formId"+k+" #parentPolicy").change();
379 for (headInd in policyObj[id]){
380 if (!(policyObj[id][headInd].hasOwnProperty("policyConfigurations"))){
381 $("#" + policyObj[id][headInd].name).val(policyObj[id][headInd].value);
388 if (readOnly||readMOnly){
389 $('select[multiple] option').each(function() {
390 var input = $('input[value="' + $(this).val() + '"]');
391 input.prop('disabled', true);
392 input.parent('li').addClass('disabled');
394 $('input[value="multiselect-all"]').prop('disabled', true).parent('li').addClass('disabled');
399 function addSelectListen(count) {
400 var onSelectChange = function() {
401 var opselected = this.selectedOptions[0].text;
403 if (this.id == "recipe"){
405 var polCount = $(this).closest("[id^='formId']").attr("id").substring(6);
406 $(this).closest(".policyPanel").find("#go_properties_tab"+polCount).text(opselected);
408 $(this).closest("[id^='go_properties_tab']").text("Policy");
412 if (this.id=="parentPolicy"){
413 var ppCond = $(this).closest("[id^='formId']").find("#parentPolicyConditions");
415 ppCond.multiselect("clearSelection");
416 ppCond.multiselect("disable");
418 ppCond.multiselect("enable");
422 $("#formId"+count+" select").each( function () {
423 this.change = onSelectChange;
428 //This is ensure there are no repeated keys in the map
429 function noRepeats(form) {
430 //triggered per policy.
432 for (var i = 0; i < form.length; i++) {
433 if (select[form[i].name] === undefined)
434 select[form[i].name] = []
435 select[form[i].name].push(form[i].value);
447 $("#savePropsBtn").click(function(event) {
448 $(".idError").hide();
449 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
451 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
452 $("#repeatIdError").show();
454 } else { //not repeated
455 delete allPolicies[$("#policyTable .highlight td").html()];
458 if ($("#pname").val().trim() == "New_Policy"){
459 $("#newIdError").show();
464 /* if ($("#policyTable .highlight").length > 0){
465 saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
469 //Removes outdated (deleted) policies by checking against left menu
470 var finalSaveList = {};
471 $("#policyTable td").each(function(){
472 var tableVal = $(this).text();
473 if (tableVal in allPolicies){
474 finalSaveList[tableVal] = allPolicies[tableVal];
478 saveProperties(finalSaveList);
479 $("#close_button").click();
482 function add_one_more() {
483 $("#nav_Tabs li").removeClass("active");
485 //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
486 var form = $($("#formSpan").children()[0]).clone()
488 //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
489 if ($(".formId").length > 0) {
491 var s = $(".formId");
492 for (var i = 0; i < s.length; i++) {
493 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
494 greatest = parseInt($(s[i]).attr("id").substring(6))
497 count = greatest + 1;
498 $("#properties_tab").append(
499 ('<span class="formId" id="formId'+count+'"></span>'));
502 $("#properties_tab").append(
503 '<span class="formId" id="formId1"></span>');
506 //$(form).find("#policyName").val("Recipe "+makid(2))
507 //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
508 //alert($(form).find("#_id").val())
509 //policyNameChangeListener(form)
513 ' <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>');
514 $("#formId" + count).append(form);
515 $(".formId").not($("#formId" + count)).css("display", "none")
517 //addTabListen(count)
518 addSelectListen(count);
519 // This is for when the process is not loading from map but being created
522 $(form).find("#_id").val(l)
523 policy_ids["#formId" + count]=l
526 for(var i=1;i<=greatestIdNum();i++){
527 if($("#formId"+i).length>0){
528 answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val();
529 $("#formId"+i+" #parentPolicy").empty();
531 for(k in policy_ids){
532 if(($("#formId"+i+" #_id").val()!==policy_ids[k].toString()) && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
533 $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"'>"+$(k+" #recipe").val()+"</option>")
536 $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
540 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
542 //re-populate parent policy with chosen options
551 function add_new_policy(issueNewNames) {
552 //remove old gui forms
553 for (var i=1; i<($(".formId").length + 1); i++){
554 $("#go_properties_tab"+i).parent().remove();
556 $(".formId").remove();
559 //$("#pname").val("0");
560 $("#pname").val("New_Policy");
561 $("#timeout").val(defaults_props.policy.timeout);
563 $("#add_one_more").click();
567 //listener will change the tab name to the recipe
568 function addTabListen(count){
570 // disable parentPolicyConditions when a parentPolicy is not selected
571 //don't think this is used..
572 /* $("#formId"+count+" #parentPolicy").on("change",function(){
573 if($("#formId"+count+" #parentPolicy").val().toString()==""){
574 // deselect all options
575 $("#formId"+count+" #parentPolicyConditions option:selected").prop("selected", false);
576 // disable the select box
577 $("#formId"+count+" #parentPolicyConditions").multiselect("disable");
580 $("#formId"+count+" #parentPolicyConditions").multiselect("enable");
586 function addCustListen(count) {
587 $('#go_properties_tab' + count).click(function(event) {
588 $("#nav_Tabs li").removeClass("active");
589 $(this).parent().addClass("active");
590 $("#formId" + count).css("display", "")
591 $(".formId").not($("#formId" + count)).css("display", "none")
594 $('#tab_close' + count).click(function(event) {
595 if(document.getElementById("timeout").disabled){
598 $(this).parent().remove();
599 for(var i=1;i<=greatestIdNum();i++){
600 if( $("#formId"+i).length>0){
602 if( $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
603 $("#formId"+i+" #parentPolicy").val("")
604 $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
608 delete policy_ids["#formId" + count + " #_id"]
609 $("#formId" + count).remove();
614 function greatestIdNum() {
616 var s = $(".formId");
617 for (var i = 0; i < s.length; i++) {
618 if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
619 greatest = parseInt($(s[i]).attr("id").substring(6))
625 //Generate random id for each policy
626 //Also made sure ids couldnt be repeated
627 function makeid(num) {
630 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
633 for (var i = 0; i < 7; i++)
634 text += possible.charAt(Math.floor(Math.random()
636 var hasValue = false;
637 for (k in policy_ids) {
638 if (text === policy_ids[k])
647 var ParentPolicy = function(id, name) {
652 //Policy table search filter
653 function searchPolicyList() {
654 var search = document.getElementById("policySearch");
655 var row = document.getElementsByTagName("td");
656 for (var i = 0; i < row.length; i++) {
657 if (row[i].innerHTML.toUpperCase().indexOf(
658 search.value.toUpperCase()) > -1) {
659 row[i].style.display = "";
661 row[i].style.display = "none";
666 function saveLastPolicyLocally(lastPolicyId) {
669 var properties = $(".saveProps").not("#formSpan .saveProps");
670 var timeoutForm = $("#Timeoutform").serializeArray();
672 for (var i = 0; i < timeoutForm.length; i++) {
673 polForm.push(timeoutForm[i]);
677 d["policyConfigurations"] = [];
678 for (var i = 0; i < properties.length; i++) {
679 var ser = $(properties[i]).serializeArray();
680 var s = noRepeats(ser)
681 d["policyConfigurations"].push(s);
684 allPolicies[lastPolicyId] = polForm;
687 function getNextId(){
690 if ((Math.min.apply(Math, allPolIds) == 0)
691 && (allPolIds.length > 0)) {
693 for (var i = 1; i < allPolIds.length; i++) {
694 if ((allPolIds[i] - allPolIds[i - 1]) != 1) {
695 newPolId = (allPolIds[i - 1] + 1);
700 newPolId = (Math.max.apply(Math, allPolIds)) + 1;
705 allPolIds.push(newPolId);
706 $("#pid").val(newPolId);
709 $("#deletePolicy").on('click', function() {
710 $(".idError").hide();
712 allPolIds.splice((allPolIds.indexOf(parseInt($("#pid").val()))),1);
715 var deleteId = $("#policyTable .highlight td").html();
716 delete allPolicies[deleteId];
717 $("#policyTable .highlight").remove();
722 $('#policyTable').on('click', 'tr', function(event) {
723 $(".idError").hide();
725 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
727 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
728 $("#repeatIdError").show();
730 } else { //not repeated
731 $("#repeatIdError").hide();
732 delete allPolicies[$("#policyTable .highlight td").html()];
735 //if (parseInt($("#pname").val()) == 0){
736 if ($("#pname").val().trim() == "New_Policy"){
737 $("#newIdError").show();
740 if (!(readOnly||readMOnly)){
743 if ($("#policyTable .highlight").length == 0){
747 $(this).addClass('highlight').siblings().removeClass('highlight');
748 disperseConfig(allPolicies, $(this).find("td").html());
751 $('#createNewPolicy').on('click', function(){
752 $(".idError").hide();
754 if ($("#policyTable .highlight td").html() !== $("#pname").val()){
756 if ($.inArray($("#pname").val(), Object.keys(allPolicies)) > -1){
757 $("#repeatIdError").show();
759 } else { //not repeated
760 $("#repeatIdError").hide();
761 delete allPolicies[$("#policyTable .highlight td").html()];
764 //if (parseInt($("#pname").val()) == 0){
765 if ($("#pname").val().trim() == "New_Policy"){
766 $("#newIdError").show();
771 if (("#policyTable .highlight").length > 0){
772 $('#policyTable tr.highlight').removeClass('highlight');
774 $("#policyTable").prepend("<tr class='highlight'><td>New_Policy</td></tr>");
779 $('#pname').on('keypress', function(e){
780 /* var newVal = $(this).val() + String.fromCharCode(e.which);
781 if ((newVal>99) || (($(this).val().length>2) && e.keyCode != 46 && e.keyCode !=8)){
784 if (e.keyCode == 32){
785 $("#spaceError").show();
790 function isNumberKey(event){
791 var charCode = (event.which) ? event.which : event.keyCode
792 if (charCode > 31 && (charCode < 48 || charCode > 57)){
798 function startNextItem() {
799 //save last item before transitioning
800 var lastItem = $("#policyTable .highlight");
801 if (lastItem.length > 0) {
802 saveLastPolicyLocally($("#pname").val());
803 //lastItem.attr("id", $("#pname").val());
804 lastItem.find("td").html($("#pname").val());
810 if ($("#deletePolicy").prop("disabled")) {
811 $("#deletePolicy").prop("disabled", false);
817 //load metrics dropdown
818 if (elementMap["global"]){
819 for (var i = 0; i < (elementMap["global"].length); i++){
820 if ((elementMap["global"][i]["name"]) == "actionSet"){
821 var asSel = elementMap["global"][i]["value"];
822 if (asSel == "vnfRecipe"){
823 if (vf_Services["policy"][asSel]){
824 $.each((vf_Services["policy"][asSel]), function(val, text) {
826 $('<option></option>').val(val).html(text)
831 } else if (asSel == "enbRecipe"){
832 if (vf_Services["policy"][asSel]){
833 $.each((vf_Services["policy"][asSel]), function(val, text) {
835 $('<option></option>').val(val).html(text)
845 //Show table panel only
846 function expandTable() {
847 $(".policyPanel").css("display", "none");
848 $(".leftPolicyPanel").removeClass("col-sm-3");
849 $(".modelSearchBox").css("padding", "25px 12px");
850 if (!($("#deletePolicy").prop("disabled"))) {
851 $("#deletePolicy").prop("disabled", true);
856 function collapseTable() {
857 $(".leftPolicyPanel").addClass("col-sm-3");
858 $(".modelSearchBox").css("padding", "10px 12px");
859 $(".policyPanel").css("display", "unset");