3748bd690aaab5b3d812dc875c4133a0e593b5b0
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.repository / src / main / webapp / WEB-INF / tags / entitytypes / nodetypes / reqandcapdefs / reqandcapdefs.tag
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  *    Yves Schubert - switch to bootstrap 3, integration with spinnerwithinphty
13  *******************************************************************************/
14 --%>
15 <%@tag description="Models Requirement and Capability Definitions" pageEncoding="UTF-8"%>
16
17 <%@attribute name="labelForSingleItem" required="true" %>
18 <%@attribute name="url" required="true"%>
19 <%@attribute name="allSubResources" required="true" type="java.util.List" description="All available req-/cap-defs" %>
20 <%@attribute name="allTypes" required="true" type="java.util.Collection" description="All available types of req-/cap-def" %>
21 <%@attribute name="typeClass" required="true" type="java.lang.Class" description="The class of the type" %>
22
23 <%@taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core"%>
24 <%@taglib prefix="ct"  tagdir="/WEB-INF/tags/common" %>
25 <%@taglib prefix="con" tagdir="/WEB-INF/tags/constraints" %>
26 <%@taglib prefix="o"   tagdir="/WEB-INF/tags/common/orioneditor"%>
27 <%@taglib prefix="t"   tagdir="/WEB-INF/tags" %>
28 <%@taglib prefix="w"   uri="http://www.eclipse.org/winery/repository/functions"%>
29 <%@taglib prefix="wc"  uri="http://www.eclipse.org/winery/functions"%>
30
31 <button class="rightbutton btn btn-danger btn-xs" type="button" onclick="deleteOnServerAndInTable(reqCapTableInfo, '${labelForSingleItem}', '${url}');">Remove</button>
32 <button class="rightbutton btn btn-primary btn-xs" type="button" onclick="$('#addReqOrCapDefDiag').modal('show');">Add</button>
33
34 <div class="modal fade" id="addReqOrCapDefDiag">
35 <div class="modal-dialog">
36 <div class="modal-content" style="width:660px;">
37         <div class="modal-header">
38                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
39                 <h4 class="modal-title">Add ${labelForSingleItem}</h4>
40         </div>
41         <div class="modal-body">
42                 <form id="addReqOrCapDefForm" enctype="multipart/form-data"><fieldset>
43                         <div class="form-group">
44                                 <label for="reqorcapname">Name</label>
45                                 <input class="form-control" name="name" id="reqorcapname" type="text" required="required" />
46                         </div>
47                         <ct:QNameChooser allQNames="${allTypes}" idOfSelectField="type" labelOfSelectField="Type" />
48                         <ct:spinnerwithinphty label="Lower Bound" id="lowerbound" min="0" value="1" />
49                         <ct:spinnerwithinphty label="Upper Bound" id="upperbound" min="1" value="1" withinphty="true" />
50                 </fieldset></form>
51         </div>
52         <div class="modal-footer">
53                 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
54                 <button type="button" class="btn btn-primary" onclick="createReqOrCapDef();">Add</button>
55         </div>
56 </div>
57 </div>
58 </div>
59
60 <table id="reqorcapdefs">
61
62 <thead>
63         <tr>
64                 <th>name</th>
65                 <th>type</th>
66                 <th>lower bound</th>
67                 <th>upper bound</th>
68                 <th>constraints</th>
69         </tr>
70 </thead>
71
72 <tbody>
73
74 <c:forEach var="r" items="${allSubResources}">
75         <tr>
76                 <td>${r.def.name}</td>
77                 <td>${wc:qname2href(pageContext.request.contextPath, typeClass, r.type)}</td>
78                 <td>${w:renderMinInstances(r.def.lowerBound)}</td>
79                 <td>${w:renderMaxInstances(r.def.upperBound)}</td>
80                 <td><button class="btn btn-xs" onclick="editConstraints('${r.def.name}');">Constraints...</button></td>
81         </tr>
82 </c:forEach>
83
84 </tbody>
85
86 </table>
87
88 <%-- Editing a set of constraints --%>
89
90 <div class="modal fade" id="constraints-dialog">
91 <div class="modal-dialog">
92 <div class="modal-content">
93         <div class="modal-header">
94                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
95                 <h4 class="modal-title">Constraints</h4>
96         </div>
97         <div class="modal-body">
98                 <div id="noconstraintsexisting" style="display:none;">No constraints defined</div>
99                 <ol id="constraintlist" style="display:none;">
100                 </ol>
101         </div>
102         <div class="modal-footer">
103                 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
104                 <button type="button" class="btn btn-primary" onclick="editConstraint();">Add new</button>
105         </div>
106 </div>
107 </div>
108 </div>
109
110 <script>
111 function deleteConstraint(id) {
112         $.ajax({
113                 url: "${url}" + currentReqCapName + "/constraints/" + id,
114                 method: "DELETE",
115                 error: function(jqXHR, textStatus, errorThrown) {
116                         vShowAJAXError("Could not delete constraint", jqXHR, errorThrown);
117                 },
118                 success: function(data, textStatus, jqXHR) {
119                         $("#"+id).remove();
120
121                         // quick hack
122                         var constraintListIsEmpty = $("#constraintlist").children().length == 0;
123                         if (constraintListIsEmpty) {
124                                 // last item was removed -> show empty message
125                                 $("#noconstraintsexisting").show();
126                                 $("#constraintlist").hide();
127                         }
128                 }
129         });
130 }
131
132 function getLiForConstraint(id) {
133         return '<li id="' + id + '"><span onclick="editConstraint(\'' + id + '\');">constraint</span> <button class="btn btn-danger btn-xs" style="margin-left:10px;" onclick="deleteConstraint(\'' + id + '\')">Delete</button></li>';
134 }
135 /**
136  * @param id the id of the constraint
137  */
138 function addConstraintToList(id) {
139         var constraintList = $("#constraintlist");
140
141         var li = getLiForConstraint(id);
142         constraintList.append(li);
143
144         // ensure that "no constraints existing" is hidden and the list is shown
145         $("#noconstraintsexisting").hide();
146         constraintList.show();
147 }
148
149 var currentReqCapName;
150
151 function editConstraints(reqCapName) {
152         currentReqCapName = reqCapName;
153         $.ajax({
154                 url: "${url}" + currentReqCapName + "/constraints/",
155                 dataType: "json",
156                 error: function(jqXHR, textStatus, errorThrown) {
157                         vShowAJAXError("Could not fetch constraints data", jqXHR, errorThrown);
158                 },
159                 success: function(data, textStatus, jqXHR) {
160                         if (data.length == 0) {
161                                 $("#noconstraintsexisting").show();
162                                 $("#constraintlist").hide();
163                         } else {
164                                 $("#noconstraintsexisting").hide();
165                                 var constraintList = $("#constraintlist");
166                                 constraintList.empty();
167                                 $(data).each(function(i,id) {
168                                         addConstraintToList(id);
169                                 });
170                                 $("#constraintlist").show();
171                         };
172                         $("#constraints-dialog").modal("show");
173                 }
174         });
175 }
176 </script>
177
178
179 <%-- Editing a single constraint --%>
180
181 <con:constraint />
182
183 <script>
184 var currentConstraintId;
185
186 /**
187  * @param constraintId (optional) If not given, enable editing of a newly created constraint
188  */
189 function editConstraint(constraintId) {
190         currentConstraintId = constraintId;
191
192         // Adjust Create/Update button
193         if (currentConstraintId === undefined) {
194                 $("#createConstraintBtn").show();
195                 $("#updateConstraintBtn").hide();
196
197                 $("#createConstraintBtn").off("click");
198                 $("#createConstraintBtn").on("click", function() {
199                         getXMLOfConstraint(function(xmlString) {
200                                 $.ajax({
201                                         type: "POST",
202                                         url: "${url}" + currentReqCapName + "/constraints/",
203                                         contentType: "text/xml",
204                                         async: true,
205                                         data: xmlString,
206                                         dataType: "text",
207                                         error: function(jqXHR, textStatus, errorThrown) {
208                                                 vShowAJAXError("Could not add constraint", jqXHR, errorThrown);
209                                         },
210                                         success: function(resData, textStatus, jqXHR) {
211                                                 addConstraintToList(resData);
212                                                 $("#constraint-dialog").modal("hide");
213                                         }
214                                 });
215                         });
216                 });
217         } else {
218                 // updating an existing constraint
219                 $("#createConstraintBtn").hide();
220                 $("#updateConstraintBtn").show();
221
222                 $("#updateConstraintBtn").off("click");
223                 $("#updateConstraintBtn").on("click", function() {
224                         getXMLOfConstraint(function(xmlString) {
225                                 $.ajax({
226                                         type: "PUT",
227                                         url: "${url}" + currentReqCapName + "/constraints/" + currentConstraintId + "/",
228                                         contentType: "text/xml",
229                                         async: true,
230                                         data: xmlString,
231                                         dataType: "text",
232                                         error: function(jqXHR, textStatus, errorThrown) {
233                                                 vShowAJAXError("Could not update constraint", jqXHR, errorThrown);
234                                         },
235                                         success: function(newId, textStatus, jqXHR) {
236                                                 $("#constraint-dialog").modal("hide");
237                                                 var newLi = getLiForConstraint(newId);
238                                                 var oldLi = $("#" + currentConstraintId);
239                                                 oldLi.before(newLi);
240                                                 oldLi.remove();
241                                         }
242                                 });
243                         });
244                 });
245         };
246
247         // fill textarea
248         if (currentConstraintId === undefined) {
249                 $("#constraint-dialog").modal("show");
250                 // setting content only works if dialog is fully shown
251                 window.setTimeout(function() {
252                         window.winery.orionareas["constrainttextarea"].editor.setText($("#emptyconstraint").val());
253                 }, window.winery.BOOTSTRAP_ANIMATION_DURATION);
254         } else {
255                 $.ajax({
256                         type: "GET",
257                         url: "${url}" + currentReqCapName + "/constraints/" + currentConstraintId + "/",
258                         dataType: "xml",
259                         async: true,
260                         error: function(jqXHR, textStatus, errorThrown) {
261                                 vShowAJAXError("Could get constraint information", jqXHR, errorThrown);
262                         },
263                         success: function(xmlData, textStatus, jqXHR) {
264                                 // xmlDoc contains an XML document and not just a string
265                                 // We let jQuery parse the XML as we need to parse the type attribute
266
267                                 // *move* type information to input field
268                                 var type = xmlData.documentElement.getAttribute("constraintType");
269                                 $("#typenameinput").val(type);
270                                 xmlData.documentElement.removeAttribute("constraintType");
271
272                                 $("#constraint-dialog").modal("show");
273
274                                 // the XML document cannot be put directly as content. It has to be converted to a String
275                                 // TODO: add nice formatting
276                                 var xmlString = (new XMLSerializer()).serializeToString(xmlData);
277                                 window.setTimeout(function() {
278                                         window.winery.orionareas["constrainttextarea"].editor.setText(xmlString);
279                                 }, window.winery.BOOTSTRAP_ANIMATION_DURATION);
280                         }
281                 });
282         }
283 }
284 </script>
285
286
287 <script>
288 // TODO: this variable is available after switching tabs.
289 // One could cache this information without requiring reloading all the content
290 var reqCapTableInfo = {
291         id : '#reqorcapdefs'
292 };
293
294 require(["winery-support"], function(ws) {
295         ws.initTable(reqCapTableInfo);
296 });
297
298 function createReqOrCapDef() {
299         if (highlightRequiredFields()) {
300                 vShowError("Please fill out all required fields.");
301                 return;
302         }
303
304         var data = $('#addReqOrCapDefForm').serialize();
305
306         // replace &inphty; by TOSCA's "unbounded"
307         data = data.replace("∞", "unbounded");
308         // %E2%88%9E is the HTML encoding of &inphty;
309         data = data.replace("%E2%88%9E", "unbounded");
310
311         $.ajax({
312                 url: "${url}",
313                 type: "POST",
314                 async: false,
315                 data: data,
316                 error: function(jqXHR, textStatus, errorThrown) {
317                         vShowError("Could not add ${labelForSingleItem}: " + errorThrown + "<br/>" + jqXHR.responseText);
318                 },
319                 success: function(data, textStatus, jqXHR) {
320                         // Data has been validated at the server
321                         // We can just add the local data
322                         var name = $('#reqorcapname').val();
323                         var type = $('#type').select2("data").text; // TODO: make href to be consistent with other lines
324                         var lbound = $('#lowerbound').val();
325                         var ubound = $('#upperbound').val();
326                         var constraints = "<button class=\"btn btn-xs\" onclick=\"editConstraints('" + name + "');\">Constraints...</button>";
327                         var dataToAdd = [name, type, lbound, ubound, constraints];
328                         reqCapTableInfo.table.fnAddData(dataToAdd);
329                         $('#addReqOrCapDefDiag').modal('hide');
330                 }
331         });
332 }
333
334 </script>