0ec6f5d2f0e8ed49d40512019a48a0c3a3900c51
[vfc/nfvo/wfengine.git] /
1 <%--
2 /*******************************************************************************
3  * Copyright (c) 2012-2014 University of Stuttgart.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * and the Apache License 2.0 which both accompany this distribution,
7  * and are available at http://www.eclipse.org/legal/epl-v10.html
8  * and http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Contributors:
11  *    Oliver Kopp - initial API and implementation and/or initial documentation
12  *******************************************************************************/
13 --%>
14 <%@tag description="Dialog to change a req or cap. Offers function showEditDiagFor${shortName}(id)" pageEncoding="UTF-8"%>
15
16 <%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
17 <%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %>
18 <%@taglib prefix="o"  tagdir="/WEB-INF/tags/common/orioneditor"%>
19 <%@taglib prefix="w"  tagdir="/WEB-INF/tags"%>
20 <%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%>
21
22 <%@attribute name="headerLabel" required="true"%>
23 <%@attribute name="shortName" required="true" description="Used for diag id, function name suffix, Req|Cap"%>
24 <%@attribute name="requirementOrCapability" required="true" description="requirement|capability"%>
25 <%@attribute name="cssClassPrefix" required="true"%>
26 <%@attribute name="allTypes" required="true" type="java.util.Collection" description="Collection&lt;QName&gt; of all available types" %>
27 <%@attribute name="clazz" required="true" type="java.lang.Class" description="TRequirement.class or TCapability.class" %>
28 <%@attribute name="repositoryURL" required="true" %>
29
30 <div class="modal fade" id="AddOrUpdate${shortName}Diag">
31         <div class="modal-dialog">
32                 <div class="modal-content" style="width:660px;">
33                         <div class="modal-header">
34                                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
35                                 <h4 class="modal-title"><span id="headerAddOrUpdate"></span> ${headerLabel}</h4>
36                         </div>
37                         <div class="modal-body">
38                                 <form id="add${shortName}Form" enctype="multipart/form-data">
39                                         <fieldset>
40                                                 <w:idInput inputFieldId="${shortName}Id"/>
41
42                                                 <div class="form-group">
43                                                         <label for="${shortName}NameChooser" class="control-label">Definition Name:</label>
44                                                         <input  id="${shortName}NameChooser" class="form-control" type="text" required="required" />
45                                                 </div>
46
47                                                 <div class="form-group">
48                                                         <label for="${shortName}TypeDisplay" class="control-label">${shortName} Type:</label>
49                                                         <input  id="${shortName}TypeDisplay" class="form-control" type="text" required="required" disabled="disabled"/>
50                                                 </div>
51
52                                                 <div id="${shortName}PropertiesContainer">
53                                                 </div>
54                                         </fieldset>
55                                 </form>
56                         </div>
57                         <div class="modal-footer">
58                                 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
59                                 <button type="button" id="add${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(false);">Add</button>
60                                 <button type="button" id="delete${shortName}btn" class="btn btn-danger" onclick="deleteCurrent${shortName}();">Delete</button>
61                                 <button type="button" id="update${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(true);">Change</button>
62                         </div>
63                 </div>
64         </div>
65 </div>
66
67 <script>
68
69 /*
70  * The following variables are declared twice due to double inclusion of this .tag flie
71  * Due to JavaScript magic, it works nevertheless
72  */
73 var selectedNodeTemplateForReqCapAddition;
74
75 //global variable set by editPropertiesXML and read by save${shortName}Edits
76 var nodeTemplateEditedReqOrCap;
77
78
79 function deleteCurrent${shortName}() {
80         nodeTemplateEditedReqOrCap.remove();
81         $("#AddOrUpdate${shortName}Diag").modal("hide");
82 }
83
84 function update${shortName}PropertiesContainerWithClone(propertiesContainerToClone) {
85         var clone = propertiesContainerToClone.clone();
86         $("#${shortName}PropertiesContainer").empty().append(clone);
87         clone.find(".KVPropertyValue").editable({mode: "inline"});
88 }
89
90 function update${shortName}PropertiesFromSelectedType() {
91         var data = $("#${shortName}NameChooser").select2("data");
92         var name = data.text;
93         var type = data.id;
94
95         // fill in type
96         // TODO: use qname2href and store QName in data-qname for later consumption -- possibly qname2href should always store the qname in data-qname
97         $("#${shortName}TypeDisplay").val(type);
98
99         // fill in properties (derived from type)
100         var propertiesContainer= $(".skelettonPropertyEditorFor${shortName} > span:contains('" + type + "')").parent().children("div");
101         update${shortName}PropertiesContainerWithClone(propertiesContainer);
102 }
103
104 $("#${shortName}NameChooser").on("change", function(e) {
105         update${shortName}PropertiesFromSelectedType();
106 });
107
108 /**
109  * Called when a req/cap should be added or updated
110  * Update mode is triggered if reqOrCapIdtoUpdate is given
111  *
112  * @param nodeTemplateId the node template id to add a req/cap to. undefined in update mode
113  * @param reqOrCapIdtoUpdate
114  */
115 function showAddOrUpdateDiagFor${shortName}(nodeTemplateId, reqOrCapIdToUpdate) {
116         var update = (typeof reqOrCapIdToUpdate !== "undefined");
117
118         if (update) {
119                 nodeTemplateEditedReqOrCap = $("#" + reqOrCapIdToUpdate);
120                 // in update mode, nodeTemplateId is not provided, we have to search for the right shape
121                 selectedNodeTemplateForReqCapAddition = nodeTemplateEditedReqOrCap.closest(".NodeTemplateShape");
122         } else {
123                 selectedNodeTemplateForReqCapAddition = $("#" + nodeTemplateId);
124         }
125
126         require(["winery-support-common"], function(wsc) {
127                 var typeQName = selectedNodeTemplateForReqCapAddition.children("div.headerContainer").children("span.typeQName").text();
128                 var urlFragment = wsc.getURLFragmentOutOfFullQName(typeQName);
129                 var url = "${repositoryURL}/nodetypes/" + urlFragment + "/${requirementOrCapability}definitions/";
130                 $.ajax({
131                         url: url,
132                         dataType: "json"
133                 }).fail(function(jqXHR, textStatus, errorThrown) {
134                         vShowAJAXError("Could not fetch ${requirementOrCapability} definitions", jqXHR, errorThrown);
135                 }).done(function(data) {
136                         // now, we have all available requirement definitions
137                         // we have to ask each of it for the type
138                         // we use the type as key for the option and the name as displayed text
139                         // select2 perfectly handles duplicate keys
140
141                         var select2Data = [];
142
143                         $.each(data, function(i,e) {
144                                 var rqDefURL = url + e + "/type";
145                                 $.ajax({
146                                         url: rqDefURL,
147                                         async: false,
148                                         dataType: "text"
149                                 }).fail(function(jqXHR, textStatus, errorThrown) {
150                                         vShowAJAXError("Could not fetch type for " + e, jqXHR, errorThrown);
151                                 }).done(function(data) {
152                                         var item = {
153                                                 id: data,
154                                                 text: e
155                                         };
156                                         select2Data.push(item);
157                                 });
158                         });
159
160                         $("#${shortName}NameChooser").select2({
161                                 placeholder: "Select name",
162                                 data: select2Data
163                         });
164
165                         if (update) {
166                                 $("#add${shortName}btn").hide();
167                                 $("#update${shortName}btn").show();
168                                 $("#delete${shortName}btn").show();
169                                 $("#headerAddOrUpdate").text("Change");
170
171                                 // collect existing data in variables
172                                 var id = nodeTemplateEditedReqOrCap.children(".id").text();
173                                 var name = nodeTemplateEditedReqOrCap.children(".name").text();
174                                 var type = nodeTemplateEditedReqOrCap.children(".type").children("a").data("qname");
175                                 var propertiesContainer = nodeTemplateEditedReqOrCap.children(".propertiesContainer");
176
177                                 // update displays
178
179                                 // id
180                                 $("#${shortName}Id").val(id);
181
182                                 // name
183                                 // we use the type as key at NameChooser. We hope that there are no duplicates. Otherwise, update won't work.
184                                 $("#${shortName}NameChooser").select2("val", type);
185                                 // make consistency check
186                                 var data = $("#${shortName}NameChooser").select2("data");
187                                 if (data == null) {
188                                         vShowError("type " + type + " could not be selected.")
189                                 } else if (name != (data.text)) {
190                                         vShowError("There are two names for different types. That case is not handled in the UI.");
191                                 }
192
193                                 // type
194                                 $("#${shortName}TypeDisplay").val(type);
195
196                                 // properties
197                                 update${shortName}PropertiesContainerWithClone(propertiesContainer);
198                         } else {
199                                 $("#add${shortName}btn").show();
200                                 $("#update${shortName}btn").hide();
201                                 $("#delete${shortName}btn").hide();
202                                 $("#headerAddOrUpdate").text("Add");
203
204                                 // QUICK HACK if dialog has been shown before -> show properties of selected type
205                                 if ($("#${shortName}NameChooser").select2("data") != null) {
206                                         update${shortName}PropertiesFromSelectedType();
207                                 }
208                         }
209
210                         $("#AddOrUpdate${shortName}Diag").modal("show");
211                 });
212         });
213 }
214
215 /**
216  * Called at click on button "Add" or "Change"
217  */
218 function addOrUpdate${shortName}(update) {
219         if (highlightRequiredFields()) {
220                 vShowError("Please fill in all required fields");
221                 return;
222         }
223         require(["tmpl"], function(tmpl) {
224                 // Generate skeletton div
225                 var sel2data = $("#${shortName}NameChooser").select2("data");
226                 var data = {
227                         id: $("#${shortName}Id").val(),
228                         name: sel2data.text,
229                         type: sel2data.id
230                 }
231                 // tmpl-${shortName} is defined in reqsorcaps.tag
232                 var div = tmpl("tmpl-${shortName}", data);
233
234                 // Add the div to the node template
235                 if (update) {
236                         nodeTemplateEditedReqOrCap.replaceWith(div);
237                 } else {
238                         selectedNodeTemplateForReqCapAddition.children(".${cssClassPrefix}Container").children(".content").children(".addnewreqorcap").before(div);
239                 }
240
241                 // Put properties at the right place
242                 $("#toBeReplacedByProperties").replaceWith($("#${shortName}PropertiesContainer").children());
243
244                 $("#AddOrUpdate${shortName}Diag").modal("hide");
245         });
246 }
247
248 </script>