Rev 1873 | Rev 1906 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1873 | Rev 1905 | ||
---|---|---|---|
Line 44... | Line 44... | ||
44 | width: 522 |
44 | width: 522 |
45 | }; |
45 | }; |
46 | // all coords and widths are in jsPDF instance's declared units |
46 | // all coords and widths are in jsPDF instance's declared units |
47 | // 'inches' in this case |
47 | // 'inches' in this case |
48 | pdf.fromHTML( |
48 | pdf.fromHTML( |
49 | source, // HTML string or DOM elem ref. |
49 | source, // HTML string or DOM elem ref. |
50 | margins.left, // x coord |
50 | margins.left, // x coord |
51 | margins.top, { // y coord |
51 | margins.top, { // y coord |
52 | 'width': margins.width, // max width of content on PDF |
52 | 'width': margins.width, // max width of content on PDF |
53 | 'elementHandlers': specialElementHandlers |
53 | 'elementHandlers': specialElementHandlers |
54 | }, |
54 | }, |
55 | - | ||
56 | function (dispose) { |
- | |
57 | // dispose: object with X, Y of the last line add to the PDF |
- | |
58 | // this allow the insertion of new lines after html |
- | |
59 | //var pdfDocument = pdf.save('Test.pdf'); |
- | |
60 | var pdfDocument = pdf.output(); |
- | |
61 | - | ||
62 | var boundary = '---------------------------'; |
- | |
63 | boundary += Math.floor(Math.random()*32768); |
- | |
64 | boundary += Math.floor(Math.random()*32768); |
- | |
65 | boundary += Math.floor(Math.random()*32768); |
- | |
66 | - | ||
67 | var body = ''; |
- | |
68 | body += '--' + boundary + '\r\n' + |
- | |
69 | 'Content-Disposition: form-data; name="filesInputId-UPLOAD[]"; filename="20170530_210340.pdf"' + '\r\n'; |
- | |
70 | body += 'Content-Type: application/pdf'; |
- | |
71 | body += '\r\n\r\n'; |
- | |
72 | body += pdfDocument; |
- | |
73 | body += '\r\n' |
- | |
74 | body += '--' + boundary + '--'; |
- | |
75 | - | ||
76 | - | ||
77 | 55 | ||
- | 56 | function (dispose) { |
|
- | 57 | // dispose: object with X, Y of the last line add to the PDF |
|
- | 58 | // this allow the insertion of new lines after html |
|
- | 59 | //var pdfDocument = pdf.save('Test.pdf'); |
|
- | 60 | var pdfDocument = pdf.output(); |
|
- | 61 | ||
- | 62 | var boundary = '---------------------------'; |
|
- | 63 | boundary += Math.floor(Math.random() * 32768); |
|
- | 64 | boundary += Math.floor(Math.random() * 32768); |
|
- | 65 | boundary += Math.floor(Math.random() * 32768); |
|
- | 66 | ||
- | 67 | var body = ''; |
|
- | 68 | body += '--' + boundary + '\r\n' + |
|
- | 69 | 'Content-Disposition: form-data; name="filesInputId-UPLOAD[]"; filename="20170530_210340.pdf"' + '\r\n'; |
|
- | 70 | body += 'Content-Type: application/pdf'; |
|
- | 71 | body += '\r\n\r\n'; |
|
- | 72 | body += pdfDocument; |
|
- | 73 | body += '\r\n' |
|
- | 74 | body += '--' + boundary + '--'; |
|
- | 75 | ||
- | 76 | ||
78 | $.ajax({ |
77 | $.ajax({ |
79 | type: "POST", |
78 | type: "POST", |
80 | cache: false, |
79 | cache: false, |
81 | url: "<%=request.getContextPath()%>/filesUpload", |
80 | url: "<%=request.getContextPath()%>/filesUpload", |
82 | data: body , |
81 | data: body, |
83 | processData: false, |
82 | processData: false, |
84 | contentType : 'multipart/form-data; boundary=' + boundary, |
83 | contentType: 'multipart/form-data; boundary=' + boundary, |
85 | success: function (data) { |
84 | success: function (data) { |
86 | alert('success'); |
85 | alert('success'); |
87 | return false; |
86 | return false; |
88 | } |
87 | } |
89 | }); |
88 | }); |
90 | }, margins |
89 | }, margins |
91 | ); |
90 | ); |
92 | } |
91 | } |
93 | </script> |
92 | </script> |
94 | 93 | ||
95 | <% |
94 | <% |
96 | 95 | ||
97 | String courseCode = request.getParameter("courseCode"); |
96 | String courseCode = request.getParameter("courseCode"); |
98 | String year = request.getParameter("year"); |
97 | String year = request.getParameter("year"); |
99 | AbstractDao.getCurrentSession().beginTransaction(); |
98 | AbstractDao.getCurrentSession().beginTransaction(); |
100 | CourseImpl courseImpl = DaoFactory.getCourseDaoImpl().findCourseByCode(courseCode); |
99 | CourseImpl courseImpl = DaoFactory.getCourseDaoImpl().findCourseByCode(courseCode); |
101 | request.setAttribute("course",courseImpl); |
100 | request.setAttribute("course", courseImpl); |
102 | CourseReportDocument courseReport = null; |
101 | CourseReportDocument courseReport = null; |
103 | try { |
102 | try { |
104 | courseReport = new CourseReportServices().createNewCourseReportDocument(courseCode, year); |
103 | courseReport = new CourseReportServices().createNewCourseReportDocument(courseCode, year); |
105 | } catch (Throwable e) { |
104 | } catch (Throwable e) { |
106 | System.out.println(e); |
105 | System.out.println(e); |
107 | e.printStackTrace(); |
106 | e.printStackTrace(); |
108 | } |
107 | } |
109 | String courseReportJson = courseReport.toJson(); |
108 | String courseReportJson = courseReport.toJson(); |
110 | request.setAttribute("courseDocumentJson",courseReportJson); |
109 | request.setAttribute("courseDocumentJson", courseReportJson); |
111 | request.setAttribute("courseDocument",courseReport); |
110 | request.setAttribute("courseDocument", courseReport); |
112 | 111 | ||
113 | %> |
112 | %> |
114 | <%--<a href="javascript:demoFromHTML()" class="button">Run Code</a>--%> |
113 | <%--<a href="javascript:demoFromHTML()" class="button">Run Code</a>--%> |
115 | 114 | ||
116 | <div class="container-fluid"> |
115 | <div class="container-fluid"> |
117 | 116 | ||
118 | <style> |
117 | <style> |
119 | .separatorSection |
118 | .separatorSection { |
120 | { |
- | |
121 | border: 1px solid #ddd; |
119 | border: 1px solid #ddd; |
122 | } |
120 | } |
123 | </style> |
121 | </style> |
124 | - | ||
125 | - | ||
126 | <!-- Apresentacao da Unidade --> |
- | |
127 | 122 | ||
128 | <div class="panel panel-default"> |
- | |
129 | <div class="panel-heading"> |
- | |
130 | Relatório Anual do curso: ${course.name} |
- | |
131 | </div> |
- | |
132 | <div class="panel-body"> |
- | |
133 | 123 | ||
134 | <p><b class="label-info">Tipo de Curso:</b> <bean:message key="course.${course.degree}"/></p> |
- | |
135 | <p><b class="label-info">Ano Lectivo:</b> ${course.importYear}</p> |
- | |
136 | <p><b class="label-info">Departamento:</b> ${course.department.name}</p> |
124 | <!-- Apresentacao da Unidade --> |
137 | <p><b class="label-info">Escola:</b> ${course.department.courseSchool.name}</p> |
- | |
138 | 125 | ||
- | 126 | <div class="panel panel-default"> |
|
- | 127 | <div class="panel-heading"> |
|
- | 128 | Relatório Anual do curso: ${course.name} |
|
- | 129 | </div> |
|
- | 130 | <div class="panel-body"> |
|
139 | 131 | ||
- | 132 | <p><b class="label-info">Tipo de Curso:</b> <bean:message key="course.${course.degree}"/></p> |
|
- | 133 | <p><b class="label-info">Ano Lectivo:</b> ${course.importYear}</p> |
|
- | 134 | <p><b class="label-info">Departamento:</b> ${course.department.name}</p> |
|
- | 135 | <p><b class="label-info">Escola:</b> ${course.department.courseSchool.name}</p> |
|
140 | 136 | ||
141 | 137 | ||
142 | <script> |
138 | <script> |
143 | 139 | ||
144 | //Especifico da aplicacao |
140 | //Especifico da aplicacao |
145 | var courseReportApp = angular.module('courseReportApp', ['ui.tree']); |
141 | var courseReportApp = angular.module('courseReportApp', ['ui.tree']); |
146 | GLOBAL_BacoAngularAppDependencies.push('courseReportApp'); |
142 | GLOBAL_BacoAngularAppDependencies.push('courseReportApp'); |
147 | 143 | ||
148 | 144 | ||
149 | courseReportApp.directive('resizable', function () { |
145 | courseReportApp.directive('resizable', function () { |
150 | return { |
146 | return { |
151 | restrict: 'A', |
147 | restrict: 'A', |
152 | scope: { |
148 | scope: { |
153 | callback: '&onResize' |
149 | callback: '&onResize' |
154 | }, |
150 | }, |
155 | link: function postLink(scope, elem, attrs) { |
151 | link: function postLink(scope, elem, attrs) { |
156 | elem.resizable(); |
152 | elem.resizable(); |
157 | elem.on('resize', function (evt, ui, comp) { |
153 | elem.on('resize', function (evt, ui, comp) { |
158 | scope.$apply(function() { |
154 | scope.$apply(function () { |
159 | if (scope.callback) { |
155 | if (scope.callback) { |
160 | scope.callback({$evt: evt, $ui: ui, $comp: comp }); |
156 | scope.callback({$evt: evt, $ui: ui, $comp: comp}); |
- | 157 | } |
|
- | 158 | }) |
|
- | 159 | }); |
|
161 | } |
160 | } |
162 | }) |
161 | }; |
163 | }); |
162 | }); |
164 | } |
- | |
165 | }; |
- | |
166 | }); |
- | |
167 | 163 | ||
168 | 164 | ||
169 | courseReportApp.controller('courseReportAppController', function($scope) |
165 | courseReportApp.controller('courseReportAppController', function ($scope) { |
170 | { |
- | |
171 | 166 | ||
172 | $scope.docAppSelector = "#courseReportApp"; |
167 | $scope.docAppSelector = "#courseReportApp"; |
173 | $scope.report = <%=courseReportJson%> |
168 | $scope.report = <%=courseReportJson%> |
174 | 169 | ||
175 | $scope.resize = function(evt,ui,comp) { |
170 | $scope.resize = function (evt, ui, comp) { |
176 | //console.log (evt,ui); |
171 | //console.log (evt,ui); |
177 | comp.width = ui.size.width; |
172 | comp.width = ui.size.width; |
178 | comp.height = ui.size.height; |
173 | comp.height = ui.size.height; |
179 | } |
- | |
180 | - | ||
181 | /** |
- | |
182 | * @classe class to match |
- | |
183 | * @superClasses array of strings |
- | |
184 | * */ |
- | |
185 | $scope.contains = function(obj,classe) |
- | |
186 | { |
- | |
187 | if(obj['@class'] && obj['@class'] == classe) |
- | |
188 | return true; |
- | |
189 | if(obj.allSuperClasses) |
- | |
190 | { |
- | |
191 | for(var i in obj.allSuperClasses) |
- | |
192 | { |
- | |
193 | if(classe == obj.allSuperClasses[i]) |
- | |
194 | return true; |
- | |
195 | } |
174 | } |
196 | } |
- | |
197 | return false; |
- | |
198 | } |
- | |
199 | - | ||
200 | $scope.showSep = function(section,subSection) |
- | |
201 | { |
- | |
202 | var s; |
- | |
203 | for(s in section.sections) |
- | |
204 | { |
- | |
205 | section.sections[s].active = false; |
- | |
206 | } |
- | |
207 | /*$(".separatorSectionNav").each(function() |
- | |
208 | { |
- | |
209 | angular.element($(this)).scope().section.active = false; |
- | |
210 | });*/ |
- | |
211 | subSection.active = true; |
- | |
212 | } |
- | |
213 | 175 | ||
214 | /** |
176 | /** |
215 | * Este metodo devolve o template mais profundo na hierarquia de classes |
- | |
216 | * permitindo emular o override, quanto mais especifica for a classe |
- | |
217 | * e caso exista template é esse o template devolvido |
- | |
218 | * procura um script com o id da classe e se nao existir |
177 | * @classe class to match |
219 | * vai subindo nas super classes |
178 | * @superClasses array of strings |
220 | * @param obj |
- | |
221 | * @returns {*} |
179 | * */ |
222 | */ |
- | |
223 | $scope.class2id = function(obj) |
180 | $scope.contains = function (obj, classe) { |
224 | { |
- | |
225 | var objClassId = obj["@class"].replaceAll(".","_"); |
181 | if (obj['@class'] && obj['@class'] == classe) |
226 | if($("script#" + objClassId).length > 0) |
- | |
227 | { |
- | |
228 | return objClassId; |
182 | return true; |
229 | } |
- | |
230 | if(obj.allSuperClasses) |
183 | if (obj.allSuperClasses) { |
231 | { |
- | |
232 | var s; |
- | |
233 | for(s in obj.allSuperClasses) |
184 | for (var i in obj.allSuperClasses) { |
234 | { |
- | |
235 | var superClass = obj.allSuperClasses[s]; |
185 | if (classe == obj.allSuperClasses[i]) |
236 | var superClassId = superClass.replaceAll(".","_"); |
186 | return true; |
237 | if($("script#" + superClassId).length > 0) |
187 | } |
238 | { |
188 | } |
239 | return superClassId; |
189 | return false; |
240 | } |
190 | } |
241 | } |
- | |
242 | } |
- | |
243 | return obj["@class"].replaceAll(".","_"); |
- | |
244 | } |
- | |
245 | 191 | ||
246 | $scope.addText = function(parentCustomPane) |
192 | $scope.showSep = function (section, subSection) { |
- | 193 | var s; |
|
- | 194 | for (s in section.sections) { |
|
- | 195 | section.sections[s].active = false; |
|
- | 196 | } |
|
- | 197 | /*$(".separatorSectionNav").each(function() |
|
247 | { |
198 | { |
248 | $scope.addSimpleDocComponent(parentCustomPane,"pt.estgp.estgweb.utils.documentBuilder.TextComponent") |
199 | angular.element($(this)).scope().section.active = false; |
- | 200 | });*/ |
|
- | 201 | subSection.active = true; |
|
249 | } |
202 | } |
250 | 203 | ||
- | 204 | /** |
|
- | 205 | * Este metodo devolve o template mais profundo na hierarquia de classes |
|
- | 206 | * permitindo emular o override, quanto mais especifica for a classe |
|
- | 207 | * e caso exista template é esse o template devolvido |
|
- | 208 | * procura um script com o id da classe e se nao existir |
|
- | 209 | * vai subindo nas super classes |
|
- | 210 | * @param obj |
|
- | 211 | * @returns {*} |
|
- | 212 | */ |
|
251 | $scope.addImage = function(parentCustomPane) |
213 | $scope.class2id = function (obj) { |
- | 214 | var objClassId = obj["@class"].replaceAll(".", "_"); |
|
- | 215 | if ($("script#" + objClassId).length > 0) { |
|
- | 216 | return objClassId; |
|
252 | { |
217 | } |
- | 218 | if (obj.allSuperClasses) { |
|
- | 219 | var s; |
|
- | 220 | for (s in obj.allSuperClasses) { |
|
- | 221 | var superClass = obj.allSuperClasses[s]; |
|
253 | $scope.addSimpleDocComponent(parentCustomPane,"pt.estgp.estgweb.utils.documentBuilder.ImageComponent") |
222 | var superClassId = superClass.replaceAll(".", "_"); |
- | 223 | if ($("script#" + superClassId).length > 0) { |
|
- | 224 | return superClassId; |
|
- | 225 | } |
|
- | 226 | } |
|
- | 227 | } |
|
- | 228 | return obj["@class"].replaceAll(".", "_"); |
|
254 | } |
229 | } |
255 | 230 | ||
256 | $scope.addSimpleDocComponent = function(parentCustomPane,classComponent) |
231 | $scope.addText = function (parentCustomPane) { |
257 | { |
- | |
258 | if(!parentCustomPane.components) |
- | |
259 | { |
- | |
260 | parentCustomPane.components = []; |
- | |
261 | } |
- | |
262 | parentCustomPane.components.push( |
- | |
263 | { |
- | |
264 | "@class" : classComponent |
232 | $scope.addSimpleDocComponent(parentCustomPane, "pt.estgp.estgweb.utils.documentBuilder.TextComponent") |
265 | } |
233 | } |
266 | ); |
- | |
267 | } |
- | |
268 | $scope.removeComponent = function(index,array) |
- | |
269 | { |
- | |
270 | array.splice(index,1); |
- | |
271 | } |
- | |
272 | 234 | ||
273 | $scope.callbackUploadedFiles = function(filesUploadResult,token,targetElement) |
- | |
274 | { |
- | |
275 | var modelObject = BacoAngularUtils.getAngularElementModel(targetElement); |
- | |
276 | - | ||
277 | if(modelObject.image && modelObject.image.identifier) |
- | |
278 | { |
- | |
279 | widgetCallWithActionParameters( |
- | |
280 | "<%=request.getContextPath()%>/user/json/repository.do", |
- | |
281 | "replaceRepositoryFileFromTempPrivateDomain", |
- | |
282 | { |
- | |
283 | "identifier" : modelObject.image.identifier, |
- | |
284 | "fileUploaded" : BacoJS.stringifyOrdered(filesUploadResult.uploadedFiles[0]) |
- | |
285 | }, |
- | |
286 | "#courseReportApp", |
- | |
287 | function(repositoryFile4JsonView) |
- | |
288 | { |
- | |
289 | modelObject.image = repositoryFile4JsonView; |
235 | $scope.addImage = function (parentCustomPane) { |
290 | //image URL is generated on reimport just to avoid caching |
- | |
291 | modelObject.imageUrl = "<%=request.getContextPath()%>/repositoryStream/" + modelObject.image.identifier + "?" + new Date().getTime(); |
- | |
292 | angular.element($("#courseReportApp")).scope().$apply(); |
- | |
293 | }, |
- | |
294 | function(){} |
- | |
295 | ); |
- | |
296 | } |
- | |
297 | else |
- | |
298 | { |
- | |
299 | widgetCallWithActionParameters( |
- | |
300 | "<%=request.getContextPath()%>/user/json/repository.do", |
- | |
301 | "saveRepositoryFileFromTempPrivateDomain", |
- | |
302 | { |
- | |
303 | "fileUploaded" : BacoJS.stringifyOrdered(filesUploadResult.uploadedFiles[0]) |
236 | $scope.addSimpleDocComponent(parentCustomPane, "pt.estgp.estgweb.utils.documentBuilder.ImageComponent") |
304 | }, |
- | |
305 | "#courseReportApp", |
- | |
306 | function(repositoryFile4JsonView) |
- | |
307 | { |
- | |
308 | modelObject.image = repositoryFile4JsonView; |
- | |
309 | modelObject.imageUrl = "<%=request.getContextPath()%>/repositoryStream/" + modelObject.image.identifier + "?" + new Date().getTime(); |
- | |
310 | angular.element($("#courseReportApp")).scope().$apply(); |
- | |
311 | }, |
237 | } |
312 | function(){} |
- | |
313 | ); |
- | |
314 | } |
- | |
315 | } |
- | |
316 | 238 | ||
- | 239 | $scope.addSimpleDocComponent = function (parentCustomPane, classComponent) { |
|
- | 240 | if (!parentCustomPane.components) { |
|
- | 241 | parentCustomPane.components = []; |
|
- | 242 | } |
|
- | 243 | parentCustomPane.components.push( |
|
- | 244 | { |
|
- | 245 | "@class": classComponent |
|
- | 246 | } |
|
- | 247 | ); |
|
- | 248 | } |
|
- | 249 | $scope.removeComponent = function (index, array) { |
|
- | 250 | array.splice(index, 1); |
|
- | 251 | } |
|
317 | 252 | ||
- | 253 | $scope.callbackUploadedFiles = function (filesUploadResult, token, targetElement) { |
|
- | 254 | var modelObject = BacoAngularUtils.getAngularElementModel(targetElement); |
|
318 | 255 | ||
- | 256 | if (modelObject.image && modelObject.image.identifier) { |
|
- | 257 | widgetCallWithActionParameters( |
|
- | 258 | "<%=request.getContextPath()%>/user/json/repository.do", |
|
- | 259 | "replaceRepositoryFileFromTempPrivateDomain", |
|
- | 260 | { |
|
- | 261 | "identifier": modelObject.image.identifier, |
|
- | 262 | "fileUploaded": BacoJS.stringifyOrdered(filesUploadResult.uploadedFiles[0]) |
|
- | 263 | }, |
|
- | 264 | "#courseReportApp", |
|
- | 265 | function (repositoryFile4JsonView) { |
|
- | 266 | modelObject.image = repositoryFile4JsonView; |
|
- | 267 | //image URL is generated on reimport just to avoid caching |
|
- | 268 | modelObject.imageUrl = "<%=request.getContextPath()%>/repositoryStream/" + modelObject.image.identifier + "?" + new Date().getTime(); |
|
- | 269 | angular.element($("#courseReportApp")).scope().$apply(); |
|
- | 270 | }, |
|
- | 271 | function () { |
|
- | 272 | } |
|
- | 273 | ); |
|
- | 274 | } |
|
- | 275 | else { |
|
- | 276 | widgetCallWithActionParameters( |
|
- | 277 | "<%=request.getContextPath()%>/user/json/repository.do", |
|
- | 278 | "saveRepositoryFileFromTempPrivateDomain", |
|
- | 279 | { |
|
- | 280 | "fileUploaded": BacoJS.stringifyOrdered(filesUploadResult.uploadedFiles[0]) |
|
- | 281 | }, |
|
- | 282 | "#courseReportApp", |
|
- | 283 | function (repositoryFile4JsonView) { |
|
- | 284 | modelObject.image = repositoryFile4JsonView; |
|
- | 285 | modelObject.imageUrl = "<%=request.getContextPath()%>/repositoryStream/" + modelObject.image.identifier + "?" + new Date().getTime(); |
|
- | 286 | angular.element($("#courseReportApp")).scope().$apply(); |
|
- | 287 | }, |
|
- | 288 | function () { |
|
- | 289 | } |
|
- | 290 | ); |
|
- | 291 | } |
|
- | 292 | } |
|
319 | 293 | ||
- | 294 | $scope.save = function () { |
|
- | 295 | widgetCallWithActionParameters( |
|
- | 296 | "<%=request.getContextPath()%>/user/courseReport.do", |
|
- | 297 | "save", |
|
- | 298 | { |
|
- | 299 | "courseReportDocument": BacoJS.stringifyOrdered($scope.report) |
|
- | 300 | }, |
|
- | 301 | "#courseReportApp", |
|
- | 302 | function (resposta) { |
|
- | 303 | ||
- | 304 | alert(resposta.courseName); |
|
- | 305 | $scope.$apply(); |
|
- | 306 | }, |
|
- | 307 | function () { |
|
- | 308 | } |
|
320 | }); |
309 | ); |
321 | </script> |
310 | } |
322 | 311 | ||
323 | <!--TEMPLATES FOR DOCUMENT BUILDER--> |
- | |
324 | <jsp:include page="../utils/documentsBuilder.jsp"/> |
- | |
325 | <jsp:include page="coursereport/templates.jsp"/> |
- | |
326 | 312 | ||
327 | <div class="form-vertical"> |
313 | }); |
328 | <div id="courseReportApp" ng-app="courseReportApp" ng-controller="courseReportAppController"> |
314 | </script> |
329 | 315 | ||
- | 316 | <!--TEMPLATES FOR DOCUMENT BUILDER--> |
|
330 | <div ng-init="section=report;" ng-include="'pt_estgp_estgweb_utils_documentBuilder_DocumentSection'"> |
317 | <jsp:include page="../utils/documentsBuilder.jsp"/> |
- | 318 | <jsp:include page="coursereport/templates.jsp"/> |
|
331 | 319 | ||
332 | </div> |
320 | <div class="form-vertical"> |
- | 321 | <div id="courseReportApp" ng-app="courseReportApp" ng-controller="courseReportAppController"> |
|
- | 322 | <div class="web-messages"></div> |
|
- | 323 | <button ng-click="save()" class="btn btn-success">Salvar</button> |
|
- | 324 | <div ng-init="section=report;" |
|
- | 325 | ng-include="'pt_estgp_estgweb_utils_documentBuilder_DocumentSection'"> |
|
333 | 326 | ||
334 | <!-- <pre class="code">{{ report | json }}</pre>--> |
327 | </div> |
335 | 328 | ||
- | 329 | <!-- <pre class="code">{{ report | json }}</pre>--> |
|
336 | 330 | ||
337 | 331 | ||
338 | </div><!--App--> |
332 | </div><!--App--> |
339 | </div> <!--form--> |
333 | </div> <!--form--> |
340 | 334 | ||
341 | </div><!--Panel Body--> |
335 | </div><!--Panel Body--> |
342 | 336 | ||
343 | </div><!--Panel--> |
337 | </div><!--Panel--> |
344 | 338 | ||
- | 339 | </div> |
|
345 | </div><!--container-fluid--> |
340 | <!--container-fluid--> |
346 | 341 | ||
347 | <% |
342 | <% |
348 | AbstractDao.getCurrentSession().getTransaction().commit(); |
343 | AbstractDao.getCurrentSession().getTransaction().commit(); |
349 | %> |
344 | %> |
350 | 345 |