commons_bs5_tabler.html
1 <#-- WARNING : be careful to white-space and lines break in FreeMarker macros.
2 # This macro template can be used to output white-space-sensitive formats (like RSS files).
3 # See http://dev.lutece.paris.fr/jira/browse/LUTECE-765
4 -->
5 <#-- Do not remove this comment -->
6 <#-- Information about this commons file -->
7 <#macro commonsFile>commons_bs5_tabler.html</#macro>
8 <#macro commonsName>Commons Bootstrap 5 + Tabler 1.0</#macro>
9 <#macro commonsDescription>Freemarker Commons macros powered by Bootstrap CSS Framework 5 + Tabler 1</#macro>
10 <#macro coreAdminCSSLinks>
11 <link href="css/admin/style/tabler/tabler.min.css" rel="stylesheet"><!-- Tabler main -->
12 <link href="css/admin/style/tabler/tabler-flags.min.css" rel="stylesheet"><!-- Tabler flags -->
13 <link href="css/admin/style/tabler/tabler-payments.min.css" rel="stylesheet"><!-- Tabler payment -->
14 <link href="css/admin/style/tabler/tabler-vendors.min.css" rel="stylesheet"><!-- Tabler Vendors -->
15 <link href="css/admin/style/tabler/all.min.css" rel="stylesheet"> <!-- Font-Awesome 5.8.1 -->
16 <link href="css/admin/bootstrap-icons.css" rel="stylesheet" > <!-- Bootstrap Icons -->
17 <link href="css/admin/style/tabler/tabler-icons.min.css" rel="stylesheet"><!-- Tabler icons -->
18 <link href="css/admin/style/tabler/bootstrap-colorpicker.min.css" rel="stylesheet"><!-- BS colorpicker -->
19 <link href="css/admin/jquery-ui.min.css" rel="stylesheet" > <!-- provided by core -->
20 <link href="css/admin/jquery-ui.structure.min.css" rel="stylesheet" > <!-- provided by core -->
21 <link href="css/admin/jquery-ui.theme.min.css" rel="stylesheet" > <!-- provided by core -->
22 <link href="js/admin/lib/polipop/css/polipop.core.min.css" rel="stylesheet">
23 <link href="js/admin/lib/polipop/css/polipop.default.min.css" rel="stylesheet">
24 <link href="js/admin/jquery/plugins/ui/css/jquery-ui-1.10.0.custom.css" rel="stylesheet"><!-- Ui Library -->
25 <link href="css/admin/style/tabler/portal_admin.css" rel="stylesheet"><!-- Lutece main admin CSS -->
26 <link href="css/admin/portal_admin_site.css" rel="stylesheet"><!-- Site override admin CSS -Empty by default- -->
27 <script src="js/admin/jquery/jquery-3.6.0.min.js"></script> <!-- main JQuery file -->
28 </#macro>
29 <#macro coreAdminJSLinks>
30 <script src="js/admin/jquery/jquery-migrate-3.4.0.min.js"></script> <!-- Compat JQuery file -->
31 <script src="js/admin/jquery/jquery-ui.min.js"></script>
32 <script src="js/admin/style/tabler/Sortable.min.js"></script>
33 <script src="js/admin/lib/polipop/polipop.min.js"></script>
34 <script src="js/admin/style/tabler/bootstrap-filestyle.min.js"></script>
35 <script src="js/admin/style/tabler/bootstrap-colorpicker.js"></script>
36 <script src="js/util/progress-manager.js"></script>
37 <script src="js/admin/style/tabler/bootstrap.bundle.min.js"></script>
38 <script src="js/admin/style/tabler/admin.js"></script>
39 </#macro>
40 <#global gClassActive='active' />
41 <#-- PAGINATION -->
42 <#macro pagination paginator>
43 <#assign nbLinkPagesToDisplay = 10 />
44 <#assign offsetPrev = nbLinkPagesToDisplay / 2 />
45 <#assign offsetNext = nbLinkPagesToDisplay / 2 />
46 <#if ( paginator.pageCurrent <= nbLinkPagesToDisplay - offsetPrev )>
47 <#assign offsetPrev = paginator.pageCurrent - 1 />
48 <#assign offsetNext = nbLinkPagesToDisplay - offsetPrev />
49 <#elseif ( paginator.pageCurrent + offsetNext > paginator.pagesCount )>
50 <#assign offsetNext = paginator.pagesCount - paginator.pageCurrent />
51 <#assign offsetPrev = nbLinkPagesToDisplay - offsetNext />
52 </#if>
53 <#if ( paginator.pagesCount > 1 )>
54 <#if ( paginator.pageCurrent - offsetPrev > 1 )>
55 <@link href='${paginator.firstPageLink?xhtml}'>
56 <@icon style='double-left' /> #i18n{portal.util.labelFirst}
57 </@link>
58 </#if>
59 <#if ( paginator.pageCurrent > 1 )>
60 <@link href='${paginator.previousPageLink?xhtml}'>
61 <@icon style='angle-left' /> #i18n{portal.util.labelPrevious}
62 </@link>
63 <#else>
64 </#if>
65 <#if ( paginator.pageCurrent - offsetPrev > 1 )>
66 <strong>...</strong>
67 </#if>
68 <#list paginator.pagesLinks as link>
69 <#if link.index == paginator.pageCurrent>
70 <strong>${link.name}</strong>
71 <#else>
72 <@link href='${link.url?xhtml}'>${link.name}</@link>
73 </#if>
74 </#list>
75 <#if ( paginator.pageCurrent + offsetNext < paginator.pagesCount )>
76 <strong>...</strong>
77 </#if>
78 <#if ( paginator.pageCurrent < paginator.pagesCount )>
79 <@link href='${paginator.nextPageLink?xhtml}'>
80 <@icon style='angle-right' /> #i18n{portal.util.labelNext}
81 </@link>
82 <#if ( paginator.pageCurrent + offsetNext < paginator.pagesCount )>
83 <@link href='${paginator.lastPageLink?xhtml}'>
84 <@icon style='angle-double-right' /> #i18n{portal.util.labelLast}
85 </@link>
86 </#if>
87 </#if>
88 </#if>
89 </#macro>
90 <#-- PAGINATION ADMIN -->
91 <#macro paginationAdmin paginator combo=0 form=1 nb_items_per_page=nb_items_per_page showcount=1 showall=0>
92 <@div class='d-flex is-flex justify-content-between is-justify-content-space-between'>
93 <@div align='right'>
94 <#if (paginator.pagesCount > 1) >
95 <@paginationPageLinks paginator=paginator />
96 </#if>
97 </@div>
98 <@div align='right'>
99 <#if form == 1 >
100 <@tform type=''>
101 <@paginationItemCount paginator=paginator combo=combo nb_items_per_page=nb_items_per_page showcount=showcount showall=showall/>
102 </@tform>
103 <#else>
104 <@paginationItemCount paginator=paginator combo=combo nb_items_per_page=nb_items_per_page showcount=showcount showall=showall/>
105 </#if>
106 </@div>
107 </@div>
108 </#macro>
109 <#-- PAGINATION LINKS -->
110 <#macro paginationPageLinks paginator >
111 <#assign nbLinkPagesToDisplay = 10 />
112 <#assign offsetPrev = nbLinkPagesToDisplay / 2 />
113 <#assign offsetNext = nbLinkPagesToDisplay / 2 />
114 <#if ( paginator.pageCurrent <= nbLinkPagesToDisplay - offsetPrev )>
115 <#assign offsetPrev = paginator.pageCurrent - 1 />
116 <#assign offsetNext = nbLinkPagesToDisplay - offsetPrev />
117 <#elseif ( paginator.pageCurrent + offsetNext > paginator.pagesCount )>
118 <#assign offsetNext = paginator.pagesCount - paginator.pageCurrent />
119 <#assign offsetPrev = nbLinkPagesToDisplay - offsetNext />
120 </#if>
121 <@ul class='pagination'>
122 <#if ( paginator.pageCurrent - offsetPrev > 1 )>
123 <@li class='page-item'>
124 <@link href='${paginator.firstPageLink?xhtml}' class='page-link'>
125 ${paginator.labelFirst}
126 </@link>
127 </@li>
128 </#if>
129 <#if (paginator.pageCurrent > 1) >
130 <@li class='page-item'>
131 <@link href='${paginator.previousPageLink?xhtml}' class='page-link'>
132 ${paginator.labelPrevious}
133 </@link>
134 </@li>
135 <#else>
136 <@li class='page-item disabled'>
137 <@link href='${paginator.firstPageLink?xhtml}' class='page-link'>${paginator.labelPrevious}</@link>
138 </@li>
139 </#if>
140 <#if ( paginator.pageCurrent - offsetPrev > 1 )>
141 <@li class='page-item'>
142 <@link href='${(paginator.pagesLinks?first).url?xhtml}' class='page-link'><strong>...</strong></@link>
143 </@li>
144 </#if>
145 <#list paginator.pagesLinks as pageLink>
146 <#if ( pageLink.index == paginator.pageCurrent )>
147 <@li class='page-item active'>
148 <@link href='${pageLink.url?xhtml}' class='page-link'>${pageLink.name}</@link>
149 </@li>
150 <#else>
151 <@li class='page-item'>
152 <@link href='${pageLink.url?xhtml}' class='page-link'>${pageLink.name}</@link>
153 </@li>
154 </#if>
155 </#list>
156 <#if ( paginator.pageCurrent + offsetNext < paginator.pagesCount )>
157 <@li class='page-item'>
158 <@link href='${(paginator.pagesLinks?last).url?xhtml}' class='page-link'><strong>...</strong></@link>
159 </@li>
160 </#if>
161 <#if (paginator.pageCurrent < paginator.pagesCount) >
162 <@li class='page-item next'>
163 <@link href="${paginator.nextPageLink?xhtml}" class='page-link'>
164 ${paginator.labelNext}
165 </@link>
166 </@li>
167 <#if ( paginator.pageCurrent + offsetNext < paginator.pagesCount )>
168 <@li class='page-item next'>
169 <@link href='${paginator.lastPageLink?xhtml}' class='page-link'>
170 ${paginator.labelLast}
171 </@link>
172 </@li>
173 </#if>
174 <#else>
175 <@li class='page-item disabled'>
176 <@link href='${paginator.lastPageLink?xhtml}' class='page-link'>${paginator.labelNext}</@link>
177 </@li>
178 </#if>
179 </@ul>
180 </#macro>
181 <#-- PAGINATION COMBO -->
182 <#macro paginationCombo paginator nb_items_per_page=nb_items_per_page showall=0>
183 <@formGroup labelFor='${paginator.itemsPerPageParameterName}' labelKey='${paginator.labelItemCountPerPage}' labelClass='small mr-3' formStyle='inline'>
184 <@inputGroup size='sm'>
185 <@select params='data-max-item="${paginator.itemsCount}"' size='sm' name='${paginator.itemsPerPageParameterName}' id='${paginator.itemsPerPageParameterName}' title='${paginator.labelItemCountPerPage}'>
186 <#list [ "10" , "20" , "50" , "100" ] as nb>
187 <#if nb_items_per_page = nb >
188 <option selected="selected" value="${nb}">${nb}</option>
189 <#else>
190 <option value="${nb}">${nb}</option>
191 </#if>
192 </#list>
193 <#if showall ==1>
194 <#if paginator.itemsCount > 100 >
195 <option <#if nb_items_per_page?number = paginator.itemsCount?number >selected="selected"</#if> value="${paginator.itemsCount}" class="${nb_items_per_page}">#i18n{portal.util.labelAll}</option>
196 </#if>
197 </#if>
198 </@select>
199 <@inputGroupItem type='btn'>
200 <@button type='submit' color='oultine' size='xs' title='#i18n{portal.util.labelRefresh}' buttonIcon='check' hideTitle=['all'] />
201 </@inputGroupItem>
202 </@inputGroup>
203 </@formGroup>
204 </#macro>
205 <#-- PAGINATION COUNT -->
206 <#macro paginationItemCount paginator combo=0 nb_items_per_page=nb_items_per_page showcount=1 showall=0>
207 <#-- Display combo -->
208 <#if combo == 1 >
209 <@paginationCombo paginator=paginator nb_items_per_page=nb_items_per_page showall=showall />
210 </#if>
211 <#-- Display item count -->
212 <#if showcount == 1 >
213 <span class="showcount small">
214 <#if (paginator.labelItemCount)?? && paginator.labelItemCount?has_content> ${paginator.labelItemCount} : </#if> ${paginator.itemsCount}
215 </span>
216 </#if>
217 </#macro>
218 <#-- NAVIGATION -->
219 <#macro item_navigation item_navigator id='item-navigator' align='' hideButtonTitle=[] buttonColor='info' buttonSize='sm'>
220 <#local class = alignmentSettings(align,'') />
221 <nav id="${id}" class="${class}">
222 <#if (item_navigator.currentItemId > 0)>
223 <@aButton href='${item_navigator.previousPageLink?xhtml}' title='#i18n{portal.util.labelPrevious}' buttonIcon='arrow-left' color='${buttonColor}' hideTitle=hideButtonTitle size='${buttonSize}' />
224 </#if>
225 <#if (item_navigator.currentItemId < item_navigator.listItemSize - 1) >
226 <@aButton href='${item_navigator.nextPageLink?xhtml}' title='#i18n{portal.util.labelNext}' buttonIcon='arrow-right' color='${buttonColor}' hideTitle=hideButtonTitle size='${buttonSize}' />
227 </#if>
228 </nav>
229 </#macro>
230 <#-- MESSAGES -->
231 <#macro messages errors=[] infos=[] warnings=[] errors_class="alert alert-danger" infos_class="alert alert-info" warnings_class="alert alert-warning">
232 <#if errors??>
233 <#if errors?size gt 0 >
234 <#list errors as error >
235 <#local errorMessage=error.message />
236 </#list>
237 <@alert color='danger' title=errorMessage iconTitle='exclamation-circle' dismissible=true id='messages_errors_div'> </@alert>
238 </#if>
239 </#if>
240 <#if infos??>
241 <#if infos?size gt 0 >
242 <#list infos as info >
243 <#local infoMessage=info.message />
244 </#list>
245 <@alert color='info' title=infoMessage iconTitle='info-circle' dismissible=true id='messages_infos_div'></@alert>
246 </#if>
247 </#if>
248 <#if warnings??>
249 <#if warnings?size gt 0 >
250 <#list warnings as warning >
251 <#local warningMessage=warning.message />
252 </#list>
253 <@alert color='warning' title=warningMessage iconTitle='exclamation-circle' dismissible=true id='messages_warnings_div'></@alert>>
254 </#if>
255 </#if>
256 </#macro>
257 <#-- TABLE -->
258 <#-- class: -->
259 <#macro table id='' class='' responsive=true condensed=true hover=true striped=false headBody=false bordered=false narrow=false collapsed=false caption='' params='' deprecated...>
260 <@deprecatedWarning args=deprecated />
261 <#local class = class />
262 <#if condensed> <#local class += ' table-condensed' /> </#if>
263 <#if hover> <#local class += ' table-hover' /> </#if>
264 <#if striped> <#local class += ' table-striped' /> </#if>
265 <#if bordered> <#local class += ' table-bordered' /> </#if>
266 <#if collapsed> <#local class += ' collapse' /> </#if>
267 <#if responsive><div class="table-responsive"></#if>
268 <table class="table ${class?trim}" <#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
269 <#if caption!=''><caption>${caption}</caption></#if>
270 <#if headBody><thead></#if>
271 <#nested>
272 <#if headBody></tbody></#if>
273 </table>
274 <#if responsive></div></#if>
275 </#macro>
276 <#macro tableHead id='' class='' params=''>
277 <thead<#if id!=''> id="${id}"</#if><#if class!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if>>
278 <#nested>
279 </thead>
280 </#macro>
281 <#macro tableBody id='' class='' params=''>
282 <tbody<#if id!=''> id="${id}"</#if><#if class!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if>>
283 <#nested>
284 </tbody>
285 </#macro>
286 <#macro tableFoot id='' class='' params=''>
287 <tfoot <#if id!=''> id="${id}"</#if><#if class!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if>>
288 <#nested>
289 </tfoot>
290 </#macro>
291 <#macro tableHeadBodySeparator id='' class='' params=''>
292 </thead>
293 <tbody<#if id!=''> id="${id}"</#if><#if class!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if>>
294 </#macro>
295 <#-- MACRO TR -->
296 <#macro tr id='' class='' hide=[] params=''>
297 <#local class += ' ' + displaySettings(hide,'table-cell') + ' ' + alignmentSettings(align) />
298 <tr<#if id!=''> id="${id}"</#if><#if class?trim!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if>>
299 <#nested>
300 </tr>
301 </#macro>
302 <#-- MACRO TH -->
303 <#-- valign: baseline|top|middle|bottom|bottom|text-top -->
304 <#macro th id='' title='' scope='' class='' align='' valign='' hide=[] cols=0 xs=0 sm=0 md=0 lg=0 xl=0 colspan=0 rowspan=0 flex=false params=''>
305 <#local class += ' ' + displaySettings(hide,'table-cell') + ' ' + alignmentSettings(align,'text') />
306 <#if cols!=0>
307 <#local class += ' col-${cols}' />
308 </#if>
309 <#local breakpoints = {'xs':xs, 'sm':sm, 'md':md, 'lg':lg, 'xl':xl}>
310 <#list breakpoints as breakpointkey,breakpointvalue>
311 <#if breakpointvalue!=0>
312 <#local class += ' col-${breakpointkey}-${breakpointvalue}' />
313 </#if>
314 </#list>
315 <#if valign!=''><#local class += ' align-' + valign /></#if>
316 <#if flex><#local class += ' d-flex' /></#if>
317 <th<#if class?trim != ''> class="${class?trim}"</#if><#if id!=''> id="${id}"</#if><#if title!=''> title="${title}"</#if><#if scope!=''> scope="${scope}"</#if><#if colspan gt 0> colspan="${colspan}"</#if><#if rowspan gt 0> rowspan="${rowspan}"</#if><#if params!=''> ${params}</#if>>
318 <#nested>
319 </th>
320 </#macro>
321 <#-- MACRO TD -->
322 <#macro td id='' class='' hide=[] align='' valign='' cols=0 xs=0 sm=0 md=0 lg=0 xl=0 colspan=0 rowspan=0 flex=false params='' deprecated...>
323 <@deprecatedWarning args=deprecated />
324 <#local class += ' ' + displaySettings(hide,'table-cell') + ' ' + alignmentSettings(align,'') />
325 <#if cols!=0>
326 <#local class += ' col-${cols}' />
327 </#if>
328 <#local breakpoints = {'xs':xs, 'sm':sm, 'md':md, 'lg':lg, 'xl':xl}>
329 <#list breakpoints as breakpointkey,breakpointvalue>
330 <#if breakpointvalue!=0>
331 <#local class += ' col-${breakpointkey}-${breakpointvalue}' />
332 </#if>
333 </#list>
334 <#if valign!=''><#local class += ' align-' + valign /></#if>
335 <#if flex><#local class += ' d-flex' /></#if>
336 <td<#if class?trim != ''> class="${class?trim}"</#if><#if id!=''> id="${id}"</#if><#if colspan gt 0> colspan="${colspan}"</#if><#if rowspan gt 0> rowspan="${rowspan}"</#if><#if params!=''> ${params}</#if>>
337 <#nested>
338 </td>
339 </#macro>
340 <#-- SORT -->
341 <#macro sort jsp_url attribute id="" >
342 <#if jsp_url?contains("?")>
343 <#assign sort_url = jsp_url + "&sorted_attribute_name=" + attribute + "&asc_sort=" />
344 <#else>
345 <#assign sort_url = jsp_url + "?sorted_attribute_name=" + attribute + "&asc_sort=" />
346 </#if>
347 <@btnGroup ariaLabel='sortButton'>
348 <@aButton color='default' size='sm' id='sort${id!}_${attribute!}' href='${sort_url}true#sort${id!}_${attribute!}' title='#i18n{portal.util.sort.asc}' buttonIcon='chevron-up' hideTitle=['all'] />
349 <@aButton color='default' size='sm' href='${sort_url}false#sort${id!}_${attribute!}' title='#i18n{portal.util.sort.desc}' buttonIcon='chevron-down' hideTitle=['all'] />
350 </@btnGroup>
351 </#macro>
352 <#-- ICONS -->
353 <#-- Icons from FontAwesome 5.8.1 -->
354 <#macro icon prefix='fa-' style='fa-lg' class='' title='' id='' params=''>
355 <#if style='docker' || style = 'github' || style='gitlab' || style='java' || style='jira' || style='jenkins' || style = 'twitter' >
356 <#local prefix = 'fab ' + prefix />
357 <#elseif prefix='fa-'>
358 <#local prefix = 'fas ' + prefix />
359 <#else>
360 <#local prefix = prefix />
361 </#if>
362 <#switch style>
363 <#case 'arrows'>
364 <#local iconStyle = 'arrows-alt' />
365 <#break>
366 <#case 'arrows-h'>
367 <#local iconStyle = 'arrows-alt-h' />
368 <#break>
369 <#case 'arrows-v'>
370 <#local iconStyle = 'arrows-alt-v' />
371 <#break>
372 <#case 'clock-o'>
373 <#local iconStyle = 'clock' />
374 <#break>
375 <#case 'close'>
376 <#local iconStyle = 'times' />
377 <#break>
378 <#case 'external-link'>
379 <#local iconStyle = 'external-link-alt' />
380 <#break>
381 <#case 'file-pdf-o'>
382 <#local iconStyle = 'file-pdf' />
383 <#break>
384 <#case 'pencil'>
385 <#local iconStyle = 'edit' />
386 <#break>
387 <#case 'refresh'>
388 <#local iconStyle = 'sync' />
389 <#break>
390 <#default>
391 <#local iconStyle = style />
392 </#switch>
393 <i class="${prefix}${iconStyle}<#if class!=''> ${class}</#if>" aria-hidden="true"<#if title!=''> title='${title}'</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>></i>
394 </#macro>
395 <#-- ICONSTACK -->
396 <#-- iconStack -->
397 <#-- class: par défaut 2x peut être tout autre taille voir doc FontAwesome -->
398 <#-- nested: 2 macro @icon une class fa-stack-2x , autre avec class fa-stack-1x dans l'ordre -->
399 <#macro iconStack class='fa-2x' id='' params=''>
400 <span class="fa-stack ${class}"<#if id!=''> ${id}</#if><#if params!=''> ${params}</#if>>
401 <#nested>
402 </span>
403 </#macro>
404 <#-- FORM -->
405 <#-- type: inline/horizontal/form -->
406 <#-- enctype: multipart/form-data | text/plain -->
407 <#macro tform type='' class='' align='' hide=[] action='' method='post' name='' id='' role='' collapsed=false enctype='' params='' deprecated...>
408 <@deprecatedWarning args=deprecated />
409 <#local class = class />
410 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
411 <#if hide??><#local class += ' ' + displaySettings(hide,'block') /></#if>
412 <#if collapsed><#local class += ' collapse' /></#if>
413 <#switch type>
414 <#case 'horizontal'>
415 <#local class += ''>
416 <#break>
417 <#case 'inline'>
418 <#local class += ' d-inline-flex'>
419 <#break>
420 <#default>
421 <#local class += ''>
422 </#switch>
423 <form <#if class!=''>class="${class?trim}"</#if><#if id!=''> id="${id}"</#if><#if action!=''> action="${action}"</#if><#if method!=''> method="${method}"</#if><#if name!=''> name="${name}"</#if><#if role!=''> role="${role}"</#if><#if method='post' && enctype!=''> enctype='${enctype}'</#if><#if params!=''> ${params}</#if>>
424 <#nested>
425 </form>
426 </#macro>
427 <#-- FORM ELEMENT STRUCTURE -->
428 <#-- formStyle values: horizontal/empty/inline Default is horizontal -->
429 <#-- class: -->
430 <#-- groupStyle: success/error -->
431 <#macro formGroup id='' formStyle='horizontal' groupStyle='' class='' rows=1 labelKey='' labelFor='' labelId='' labelClass='' helpKey='' mandatory=false htmlRequired=true hideLabel=[] collapsed=false params='' deprecated...>
432 <@deprecatedWarning args=deprecated />
433 <#if groupStyle = 'success'>
434 <#local validation = 'is-valid'>
435 <#elseif groupStyle='error'>
436 <#local validation = 'is-invalid'>
437 </#if>
438 <#if collapsed><#local class += ' collapse' /></#if>
439 <div class="form-group<#if formStyle='horizontal'> mb-3 row</#if><#if class!=''> ${class?trim}</#if><#if validation?? && validation!=''> ${validation}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
440 <#local displayLabelClass = displaySettings(hideLabel,'inline-flex') />
441 <#if rows=1>
442 <#if labelKey!='' && formStyle='horizontal'>
443 <#local labelClass += ' col-sm-12 col-lg-3 col-form-label text-right'>
444 <#if displayLabelClass?contains('d-none')>
445 <#local divClass='col'>
446 <#else>
447 <#local divClass = 'col-lg-6'>
448 </#if>
449 <#elseif formStyle = 'inline'>
450 <#local divClass = 'mb-2 mr-sm-2'>
451 <#local labelClass += ' mr-2' />
452 <#else>
453 <#local divClass='col-sm-12 offset-lg-3 col-lg-6'>
454 </#if>
455 <#else>
456 <#local labelClass += ' col-sm-12 col-form-label'>
457 <#local divClass = 'col-sm-12'>
458 </#if>
459 <#if labelKey!=''>
460 <@formLabel class=labelClass?trim labelFor=labelFor labelId=labelId labelKey=labelKey hideLabel=hideLabel mandatory=mandatory />
461 </#if>
462 <#if formStyle !='inline'>
463 <div class="${divClass}">
464 </#if>
465 <#assign propagateMandatory = mandatory>
466 <#assign propagateHtmlRequired = htmlRequired>
467 <#nested>
468 <#assign propagateMandatory = false>
469 <#assign propagateHtmlRequired = true>
470 <#if helpKey!=''><small class="text-muted<#if formStyle!='inline'> form-text</#if>" <#if labelFor!=''>aria-describedby="${labelFor}"</#if>>${helpKey}</small></#if>
471 <#if formStyle !='inline'>
472 </div>
473 </#if>
474 </div>
475 </#macro>
476 <#macro formField class=''>
477 <div class="form-row mb-3<#if class!=''> ${class}</#if>">
478 <#nested>
479 </div>
480 </#macro>
481 <#macro formLabel class='' labelFor='' labelId='' labelKey='' hideLabel=[] mandatory=true deprecated...>
482 <@deprecatedWarning args=deprecated />
483 <#local labelClass = ' ' + displaySettings(hideLabel,'') />
484 <label class="form-label<#if mandatory=true> required</#if><#if class !=''> ${class?trim}</#if><#if hideLabel?seq_contains('all')> sr-only</#if> " for="${labelFor}" <#if labelId!=''> id="${labelId}"</#if><#if mandatory=true>ariaLabel="${labelKey} [#i18n{portal.users.modify_attribute.labelMandatory}]"</#if>>
485 <#if labelKey !=''><span class="${labelClass}">${labelKey} </span><#else><#nested></#if>
486 </label>
487 </#macro>
488 <#macro formHelp style='inline' class='' labelFor=''>
489 <#if style='inline'>
490 <small class="text-muted<#if style!='inline'> form-text</#if><#if class!=''> ${class}</#if>" <#if labelFor!=''>aria-describedby="${labelFor}"</#if>>
491 <#nested>
492 </small>
493 <#else>
494 <span class="form-help" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-trigger="hover" data-bs-html="true" data-bs-content="<#nested>">?</span>
495 </#if>
496 </#macro>
497 <#-- ------------------------------------------------------------------------------------------------------------------------------------------ -->
498 <#-- INPUTS & TEXTAREA -->
499 <#-- ------------------------------------------------------------------------------------------------------------------------------------------ -->
500 <#-- name : Mandatory : Name for field -->
501 <#-- type : text/textarea/password/email/file/number/range/color/hidden/tel. Default : text -->
502 <#-- value: '' -->
503 <#-- class: '' -->
504 <#-- id: '' -->
505 <#-- title: '' -->
506 <#-- size: '' -->
507 <#-- inputSize: 0 -->
508 <#-- maxlength: 0 -->
509 <#-- placeHolder: '' -->
510 <#-- rows: 4 Textarea specific -->
511 <#-- cols: 40 Textarea specific -->
512 <#-- pattern: '' [A-F][0-9]{5} -->
513 <#-- tabIndex: '' -->
514 <#-- disabled: false -->
515 <#-- readonly: false -->
516 <#-- min: 0 -->
517 <#-- max: 0 -->
518 <#-- min: 0 -->
519 <#-- params: '' -->
520 <#-- mandatory: false -->
521 <#-- language: for input type DATE and datepickers -->
522 <#-- defaultDate: Format must be "yyyy-MM-dd hh:mm" -->
523 <#-- minDate: Format must be "yyyy-MM-dd hh:mm" -->
524 <#-- maxDate: Format must be "yyyy-MM-dd hh:mm" -->
525 <#-- defaultHour: Format must be "hh" -->
526 <#-- defaultMinute: Format must be "mm" -->
527 <#-- minTime : Format must be "hh:mm" -->
528 <#-- maxTime : Format must be "hh:mm" -->
529 <#-- format='' : Format for DB -->
530 <#-- showFormat='' Format for User -->
531 <#-- dateRangeEndId='' Id for date range date end -->
532 <#-- dateParams : [] https://flatpickr.js.org/options/ for options list | Example : dateParams=[{'inline': 'true'},{'hourIncrement': '4'}] -->
533 <#-- showFileUrl=false -->
534 <#-- fileURL='' -->
535 <#-- fileName='' -->
536 <#-- datalist='' To comma separated list of values Example : datalist='titi,tata' -->
537 <#-- ------------------------------------------------------------------------------------------------------------------------------------------ -->
538 <#macro input name id='' type='text' value='' class='' size='' inputSize=0 maxlength=0 placeHolder='' rows=4 cols=40 richtext=false tabIndex='' disabled=false readonly=false pattern='' title='' min=0 max=0 params='' mandatory=false language=.locale minDate='' maxDate='' defaultDate='' defaultTime='' time_24hr=true minTime='' maxTime='' format='' showFormat='' dateRangeEndId='' dateParams=[] showFileUrl=false fileURL='' fileName='' datalist=''>
539 <#if propagateMandatory?? && propagateMandatory && propagateHtmlRequired ><#local mandatory = true /></#if>
540 <#if type='textarea'>
541 <textarea name="${name}" class="form-control<#if size!=''> input-${size}</#if><#if class!=''> ${class}</#if><#if richtext> richtext</#if>" rows="${rows}" cols="${cols}"<#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if placeHolder!=''> placeholder="${placeHolder}"</#if><#if title!=''> title="${title}"</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if><#if pattern!=''>pattern=${pattern}</#if><#if (mandatory && !richtext)> required</#if><#if labelFor?? && labelFor!='' && helpKey?? && helpKey!=''> aria-describedby="${labelFor}_help"</#if>><#if value!='' >${value}<#else><#nested></#if></textarea>
542 <#elseif type='text' || type='search' || type='password' || type='email' || type='file' || type='number' || type='color' || type='range' || type='tel' || type='datalist'>
543 <input class="form-control<#if size!=''> input-${size}</#if><#if type='color'> input-color</#if><#if class!=''> ${class}</#if>" type="${type}" name="${name}" value="${value}"<#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if placeHolder!=''> placeholder="${placeHolder}"</#if><#if title!=''> title="${title}"</#if><#if maxlength > 0> maxlength="${maxlength}"</#if><#if inputSize!=0> size="${inputSize}"</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if><#if pattern!=''>pattern=${pattern}</#if><#if min!=max> min="${min}"</#if><#if max!=0> max="${max}"</#if><#if mandatory> required </#if><#if labelFor?? && labelFor!='' && helpkey?? && helpKey!=''> aria-describedby="${labelFor}_help"</#if><#if type='datalist'> list="${name}_list"</#if>>
544 <#if type='file'>
545 <input type="hidden" id=${id}Key name="${name}Key" value="${value}" />
546 <#if showFileUrl && fileURL?? && fileName??><@link href="${fileURL}">${fileName}</@link></#if>
547 </#if>
548 <#if type='datalist'>
549 <#if id !='' && datalist !='' >
550 <datalist id="${name}_list">
551 <#assign options = datalist?split(',')>
552 <#list options as opt>
553 <option value="${opt!}">
554 </#list>
555 </datalist>
556 <#else>
557 <!-- Missing id or params attribute for macro @input for type "datalist" -->
558 </#if>
559 </#if>
560 <#elseif type='date' || type='datetime' || type='daterange' || type='datetimerange' || type='time'>
561 <input class="form-control<#if size!=''> input-${size}</#if><#if class!=''> ${class}</#if>" type="text" name="${name}" value="${value}"<#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if placeHolder!=''> placeholder="${placeHolder}"</#if><#if title!=''> title="${title}"</#if><#if maxlength > 0> maxlength="${maxlength}"</#if><#if inputSize!=0> size="${inputSize}"</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if><#if pattern!=''>pattern=${pattern}</#if><#if min!=max> min="${min}"</#if><#if max!=0> max="${max}"</#if><#if mandatory> required </#if><#if labelFor?? && labelFor!='' && helpkey?? && helpKey!=''> aria-describedby="${labelFor}_help"</#if> />
562 <#if type='date'>
563 <@getDate idField='${id}' language=language format=format showFormat=showFormat minDate=minDate maxDate=maxDate defaultDate=defaultDate dateOptions=dateParams />
564 <#elseif type='datetime'>
565 <@getDateTime idField='${id}' language=language format=format showFormat=showFormat minDate=minDate maxDate=maxDate defaultDate=defaultDate defaultTime=defaultTime minTime=minTime maxTime=maxTime dateOptions=dateParams />
566 <#elseif type='daterange'>
567 <#if dateRangeEndId != ''>
568 <@getDateRange idField='${id}' idEndField='${dateRangeEndId}' language=language format=format showFormat=showFormat minDate=minDate maxDate=maxDate defaultDate=defaultDate dateOptions=dateParams />
569 <#else>
570 <@alert class='danger'>${i18n("portal.util.datepicker.rangeEndId.mandatory")}</@alert>
571 </#if>
572 <#elseif type='datetimerange'>
573 <#if dateRangeEndId != ''>
574 <@getDateTimeRange idField='${id}' idEndField='${dateRangeEndId}' language=language format=format showFormat=showFormat minDate=minDate maxDate=maxDate defaultDate=defaultDate defaultTime=defaultTime minTime=minTime maxTime=maxTime dateOptions=dateParams />
575 <#else>
576 <@alert class='danger'>${i18n("portal.util.datepicker.rangeEndId.mandatory")}</@alert>
577 </#if>
578 <#elseif type='time'>
579 <@getTime idField='${id}' language=language format='H:i' showFormat='H:i' minTime=minTime maxTime=maxTime time_24hr=time_24hr defaultDate=defaultDate dateOptions=dateParams />
580 </#if>
581 <#if id=''><@alert class='danger'>${i18n("portal.util.datepicker.id.mandatory")}</@alert></#if>
582 <#elseif type='hidden'>
583 <input type="hidden" name="${name}" <#if id!=''>id="${id}"</#if> value="${value}" />
584 <#else><@alert class='danger'>${i18n("portal.util.message.unsupportedType")}</@alert>
585 </#if>
586 </#macro>
587 <#-- STATIC TEXT -->
588 <#-- Bootstrap colors: primary/secondary/success/info/warning/danger/light/black/muted/white/text-black-50/text-white-50 -->
589 <#macro staticText inForm=true color='' id='' params=''>
590 <p class="<#if inForm>form-control-plaintext</#if><#if color!=''> text-${color}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
591 <#nested>
592 </p>
593 </#macro>
594 <#--- MACRO SELECT (TO REPLACE "COMBO" MACROS) --->
595 <#macro select name id=name class='' items='' default_value='' size='' sort=false multiple=0 params='' title='' disabled=false tabIndex=0 maxLength=0 mandatory=false>
596 <#if propagateMandatory?? && propagateMandatory && propagateHtmlRequired ><#local mandatory = true /></#if>
597 <select id="${id}" name="${name}" class="form-select<#if size!=''> form-control form-control-${size}</#if><#if class!=''> ${class}</#if>" <#if (multiple > 0)>multiple size="${multiple}"</#if><#if (tabIndex > 0)> tabindex="${tabIndex}"</#if><#if params!=''> ${params}</#if><#if title!=''> title="${title}"</#if><#if mandatory> required</#if><#if disabled> disabled</#if>>
598 <#if items?has_content>
599 <#if sort=true>
600 <#list items?sort_by("name") as item>
601 <#if default_value="${item.code}">
602 <option selected="selected" title="${item.name}" value="${item.code}" <#if !item.name?has_content>label="${i18n("portal.util.labelEmpty")}"</#if>>${item.name}</option>
603 <#else>
604 <option value="${item.code}" title="${item.name}" <#if !item.name?has_content>label="${i18n("portal.util.labelEmpty")}"</#if>>${item.name}</option>
605 </#if>
606 </#list>
607 <#else>
608 <#if maxLength gt 0>
609 <#list items as item>
610 <#if maxLength < item.name?length >
611 <#assign item_new = "..." + "${item.name?substring(item.name?length-maxLength+3)}" >
612 <#else>
613 <#assign item_new = "${item.name}">
614 </#if>
615 <#if default_value="${item.code}">
616 <option selected="selected" title="${item.name}" value="${item.code}" >${item_new}</option>
617 <#else>
618 <option title="${item.name}" value="${item.code}" >${item_new}</option>
619 </#if>
620 </#list>
621 <#else>
622 <#list items as item>
623 <#if default_value="${item.code}">
624 <option selected="selected" title="${item.name}" value="${item.code}" <#if !item.name?has_content>label="${i18n("portal.util.labelEmpty")}"</#if>>${item.name}</option>
625 <#else>
626 <option title="${item.name}" value="${item.code}" <#if !item.name?has_content>label="${i18n("portal.util.labelEmpty")}"</#if>>${item.name}</option>
627 </#if>
628 </#list>
629 </#if>
630 </#if>
631 <#else>
632 <#nested>
633 </#if>
634 </select>
635 </#macro>
636 <#--- MACRO OPTIONS --->
637 <#--- items : list with label, value, selected values --->
638 <#macro options items selected='' id=false class='' params=''>
639 <#if items??>
640 <#list items as item>
641 <#local idItem><#if id>${item.code}_${item?index}<#else></#if></#local>
642 <#local selectedItem><#if selected !=''><#if item.code?string=selected>true<#else>false</#if><#else>${item.selected?c}</#if></#local>
643 <@option label=item.name value=item.code id=idItem class=class selected=selectedItem?boolean disabled=item.disabled params=params />
644 </#list>
645 </#if>
646 </#macro>
647 <#macro option label value id='' class='' selected=false disabled=false params=''>
648 <option<#if id!=''>id="${id}</#if><#if class!=''> class="${class}"</#if> value="${value!}"<#if selected> selected</#if><#if disabled> disabled</#if><#if params!=''> ${params}</#if>>${label!} <#nested></option>
649 </#macro>
650 <#-- CHECKBOX -->
651 <#-- orientation: vertical/inline. Default is vertical -->
652 <#-- TODO -->
653 <#macro checkBox name id='' class='' labelKey='' orientation='vertical' value='' tabIndex='' title='' disabled=false readonly=false checked=false params='' mandatory=false deprecated...>
654 <@deprecatedWarning args=deprecated />
655 <#if id = ''><#local id = name /></#if>
656 <#if orientation!='switch'>
657 <#if orientation='vertical'><div class="custom-control custom-checkbox"></#if>
658 <input type="checkbox" class="custom-control-input<#if class!=''> ${class}</#if>" id="${id}" name="${name}"<#if value!=''> value="${value}"</#if><#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if checked> checked</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if params!=''> ${params}</#if><#if mandatory> required</#if> />
659 <label class="custom-control-label<#if orientation!='vertical'> checkbox-inline</#if>" for="${id}" <#if title!=''> title="${title}"</#if>>
660 <#if labelKey!=''>${labelKey}<#else><#nested></#if>
661 </label>
662 <#if orientation='vertical'></div></#if>
663 <#else>
664 <label class="form-check form-switch" for="${id}" <#if title!=''> title="${title}"</#if>>
665 <input class="form-check-input<#if class!=''> ${class}</#if>" type="checkbox" id="${id}" name="${name}"<#if value!=''> value="${value}"</#if><#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if checked> checked</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if params!=''> ${params}</#if><#if mandatory> required</#if>>
666 <span class="form-check-label"><#if labelKey!=''>${labelKey}<#else><#nested></#if></span>
667 </label>
668 </#if>
669 </#macro>
670 <#-- RADIO BUTTON -->
671 <#-- orientation: vertical/inline. Default is vertical -->
672 <#macro radioButton name id='' labelKey='' labelFor='' orientation='vertical' value='' tabIndex='' title='' disabled=false readonly=false checked=false params='' mandatory=false >
673 <#if propagateMandatory?? && propagateMandatory && propagateHtmlRequired ><#local mandatory = true /></#if>
674 <#if orientation='vertical'><div class="radio"> </#if>
675 <label class="form-check<#if orientation!='vertical'> form-check-inline</#if>" for="${labelFor}">
676 <input class="form-check-input" type="radio" id="${id}" name="${name}"<#if value!=''> value="${value}"</#if><#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if checked> checked</#if><#if disabled> disabled</#if><#if readonly> readonly</#if><#if mandatory> required</#if><#if params!=''> ${params}</#if> />
677 <span class="form-check-label"><#if labelKey!=''>${labelKey}<#else><#nested></#if></span>
678 </label>
679 <#if orientation='vertical'></div></#if>
680 </#macro>
681 <#-- INPUT-GROUP -->
682 <#-- size: sm/lg/no size-->
683 <#macro inputGroup id='' class='' size='' params=''>
684 <div class="input-group<#if size!=''> input-group-${size}</#if><#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
685 <#nested>
686 </div>
687 </#macro>
688 <#macro inputGroupItem id='' pos='append' type='text' params=''>
689 <#-- pos: append / prepend | Default append -->
690 <#-- type: btn/text. default is btn -->
691 <span class="input-group-${type}"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
692 <#nested>
693 </span>
694 </#macro>
695 <#-- DROPDOWN MENU -->
696 <#-- class: dropdown-menu-right -->
697 <#-- Expected content : <li><a>Your link here</a></li> -->
698 <#macro dropdownMenu class='' id='' params=''>
699 <ul class="dropdown-menu ${class}"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
700 <#nested>
701 </ul>
702 </#macro>
703 <#-- ROW -->
704 <#macro row class='' id='' collapsed=false align='' params=''>
705 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
706 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
707 <div class="row<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
708 <#nested>
709 </div>
710 </#macro>
711 <#-- COLUMNS -->
712 <#-- cols = col-(<544px)/ col-sm-(>=544px)/ col-md-(>=768px)/ col-lg-(>=992px)/ col-xl-(>=1200px) -->
713 <#-- Push and Pull are deprecated in Bootstrap 4 -->
714 <#-- offsetXs, offsetSm, offsetMd, offsetLg and offsetXl are deprecated. Use offset={} instead where the values are listed as following: offset={'xs':int, 'sm':int, 'md':int, 'lg':int, 'xl':int} -->
715 <#-- Order uses flexbox. Use Order for xs/all breakpoints this way: order=int, or for other breakpoints this way: order={'sm':int, 'md':int, 'lg':int, 'xl':int} -->
716 <#macro columns tag='div' offsetXs=0 offsetSm=0 offsetMd=0 offsetLg=0 offsetXl=0 offset={} pushXs=0 pushSm=0 pushMd=0 pushLg=0 pushXl=0 pullXs=0 pullSm=0 pullMd=0 pullLg=0 pullXl=0 xs=0 sm=0 md=0 lg=0 xl=0 order={} id='' class='' align='' collapsed=false params=''>
717 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
718 <#if align!=''><#local class+= ' ' + alignmentSettings(align,'') /></#if>
719 <#local class += ' ' + responsiveDisplay('col',{'xs':xs, 'sm':sm, 'md':md, 'lg':lg, 'xl':xl}) />
720 <#if offset?has_content>
721 <#local class += ' ' + responsiveDisplay('offset',offset) />
722 <#elseif offsetXs > 0 || offsetSm > 0 || offsetMd > 0 || offsetLg > 0 || offsetXl > 0>
723 <#local class += ' ' + responsiveDisplay('offset',{'xs':offsetXs, 'sm':offsetSm, 'md':offsetMd, 'lg':offsetLg, 'xl':offsetXl}) />
724 </#if>
725 <#if order?has_content>
726 <#if order?is_number>
727 <#local class += ' order-${order}' />
728 <#elseif order?is_hash>
729 <#local class += ' ' + responsiveDisplay('order',order) />
730 </#if>
731 </#if>
732 <${tag} class="<#if class?trim!=''>${class?trim}<#else>col</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
733 <#nested>
734 </${tag}>
735 </#macro>
736 <#-- LISTS -->
737 <#macro ul id='' class='' align='' hide=[] collapsed=false params=''>
738 <#local class += ' ' + alignmentSettings(align,'') + ' ' + displaySettings(hide,'block') />
739 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
740 <ul<#if class?trim!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if><#if id!=''> ${id}</#if>>
741 <#nested>
742 </ul>
743 </#macro>
744 <#macro li id='' params='' class='' hide=[] align=''>
745 <#local class += ' ' + alignmentSettings(align,'') + ' ' + displaySettings(hide,'block') />
746 <li<#if class?trim!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if><#if id!=''> ${id}</#if>>
747 <#nested>
748 </li>
749 </#macro>
750 <#-- DIV -->
751 <#macro div id='' class='' hide=[] collapsed=false align='' params=''>
752 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
753 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
754 <#if hide??><#local class += ' ' + displaySettings(hide,'block') /></#if>
755 <div<#if class?trim!=''> class="${class?trim}"</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
756 <#nested>
757 </div>
758 </#macro>
759 <#-- PARAGRAPH -->
760 <#macro p id='' params='' class='' hide=[] collapsed=false align=''>
761 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
762 <#local class += ' ' + displaySettings(hide,'block') + ' ' + alignmentSettings(align,'') />
763 <p<#if class?trim!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if><#if id!=''> ${id}</#if>>
764 <#nested>
765 </p>
766 </#macro>
767 <#-- SPAN -->
768 <#macro span id='' class='' hide=[] collapsed=false align='' params=''>
769 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
770 <#local class += ' ' + alignmentSettings(align,'') + ' ' + displaySettings(hide,'inline-flex') />
771 <span<#if class?trim!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if><#if id!=''> ${id}</#if>>
772 <#nested>
773 </span>
774 </#macro>
775 <#-- PRE -->
776 <#macro pre id='' class='' hide=[] collapsed=false align='' params=''>
777 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
778 <#local class += ' ' + alignmentSettings(align,'') + ' ' + displaySettings(hide,'block') />
779 <pre<#if class!=''> class="${class?trim}"</#if><#if params!=''> ${params}</#if><#if id!=''> ${id}</#if>>
780 <#nested>
781 </pre>
782 </#macro>
783 <#-- TABS -->
784 <#-- Tab Container -->
785 <#-- style: tabs/tabs nav-justified/pills/pills nav-stacked/pills nav-justified -->
786 <#macro tabs color='' style='tabs' class='' id='' hide=[] collapsed=false params=''>
787 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
788 <#if hide??><#local class += ' ' + displaySettings(hide,'block') /></#if>
789 <#assign propagateTabStyle = style />
790 <div class="card<#if color!=''> ${color}</#if><#if class?trim!=''> ${class?trim}</#if>" <#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
791 <#nested>
792 </div>
793 </#macro>
794 <#-- Tabs List -->
795 <#-- type is deprecated -->
796 <#macro tabList style='tabs' vertical=false id='' params='' color=''>
797 <#if propagateTabStyle?? ><#local style = propagateTabStyle /></#if>
798 <ul class="nav nav-${style}<#if vertical> flex-column mb-3</#if>" data-bs-toggle="tabs"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if> role="tablist">
799 <#nested>
800 </ul>
801 </#macro>
802 <#-- Tabs -->
803 <#-- type: -->
804 <#macro tabLink class='' hide=[] id='' active=false href='' title=''tabLabel='' tabIcon='' tabClass='' params=''>
805 <li class="nav-item<#if tabClass!=''> ${tabClass}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
806 <#local tabLinkClass = class + ' nav-link' />
807 <#if active><#local tabLinkClass += ' active' /></#if>
808 <#local tabLinkSettings = 'role="tab" aria-expanded="${active?c}" aria-controls="${href?remove_beginning("#")}"' />
809 <#if href?contains('#') && href?contains('.jsp') == false>
810 <#local tabLinkSettings += ' data-bs-toggle="tab"' />
811 <#local tabLinkId = '${href?remove_beginning("#")}-tab' />
812 <#else>
813 <#local tabLinkId = href?keep_after_last('/')?keep_before('.')?lower_case />
814 </#if>
815 <#if href=''>
816 <#nested>
817 <#else>
818 <@link class=tabLinkClass?trim href=href id=tabLinkId title=title params=tabLinkSettings>
819 <#if tabIcon!=''><@icon style=tabIcon class='mr-1 me-1'/></#if> <#if tabLabel !=''>${tabLabel!}<#else>${title!}</#if>
820 <#nested>
821 </@link>
822 </#if>
823 </li>
824 </#macro>
825 <#-- TAB Content -->
826 <#macro tabContent id='' params=''>
827 <div class="card-body">
828 <div class="tab-content"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
829 <#nested>
830 </div>
831 </div>
832 </#macro>
833 <#-- Tab Panel BS4 -->
834 <#macro tabPanel id params='' active=false>
835 <div class="tab-pane mt-2 fade<#if active> show active</#if>" role="tabpanel" id="${id}" aria-labelledby="${id}-tab"<#if params!=''> ${params}</#if>>
836 <#nested>
837 </div>
838 </#macro>
839 <#-- ACCORDION -->
840 <#-- The accordionContainer is the container for accordionPanel, which itself is the container for accordionHeader and accordionBody -->
841 <#-- The childId argument in accordionPanel is meant to be used in the two sub-macros: accordionHeader and accordionBody -->
842 <#macro accordionContainer id='' params=''>
843 <#if id = '' >
844 <#if accordionContainerId?? == false><#assign accordionContainerId = 1 ><#else><#assign accordionContainerId = accordionContainerId + 1 ></#if>
845 <#local id = 'accCont_'+ accordionContainerId >
846 </#if>
847 <div class="accordion" id="${id}"<#if params!=''> ${params}</#if>>
848 <#assign parentId = id>
849 <#nested>
850 </div>
851 </#macro>
852 <#macro accordionPanel color='' collapsed=true childId='' id='' params=''>
853 <div class="card<#if color!=''> bg-${color}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
854 <#if collapsed>
855 <#assign aClass = 'collapsed'>
856 <#assign expanded = 'false'>
857 <#assign childClass = 'collapse'>
858 <#else>
859 <#assign aClass = ''>
860 <#assign expanded = 'true'>
861 <#assign childClass = 'collapse show'>
862 </#if>
863 <#assign childId = childId />
864 <#nested>
865 </div>
866 </#macro>
867 <#-- ACCORDION ELEMENT -->
868 <#-- The boxTools parameter is unused, kept for backwards compatibility -->
869 <#macro accordionHeader id='' title='' parentId=parentId childId=childId boxTools=false params='' headerIcon='' >
870 <div class="accordion-item">
871 <h2 class="accordion-header" id="${childId}-header"<#if params!=''> ${params}</#if>>
872 <button class="accordion-button<#if aClass!=''> ${aClass}</#if>" type="button" data-bs-toggle="collapse" data-bs-target="#${childId}" aria-expanded="${expanded}" aria-controls="${childId}">
873 <#if headerIcon!=''><@icon style=headerIcon /></#if><span class="ms-2">${title}</span>
874 </h2>
875 <#local nested><#nested></#local>
876 <#if nested?has_content><#if boxTools><div class="box-tools"></#if>${nested}<#if boxTools></div></#if></#if>
877 </div>
878 <#assign parentId = parentId />
879 </#macro>
880 <#macro accordionBody id=childId class=childClass expanded=expanded params=''>
881 <div id="${id}" class="accordion-collapse ${class}" aria-labelledby="${childId}-header" data-bs-parent="#${parentId}" <#if params!=''> ${params}</#if>>
882 <@boxBody>
883 <#nested>
884 </@boxBody>
885 </div>
886 </#macro>
887 <#macro progressBar description='' id='' params=''>
888 <div class="progress"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
889 <div id="progressbar" class="progress-bar progress-bar-striped" role="progressbar">
890 <div id="complexity">0%</div>
891 </div>
892 </div>
893 <#if description!=''>
894 <span class="progress-description">${description}</span>
895 </#if>
896 </#macro>
897 <#-- Progress macro
898 token : the progress manager Feed Token
899 interval : refresh period in milli seconds (if the feed token is provided)
900 showReport : display the messages report (if the feed token is provided) -->
901 <#macro progress color='primary' id='' params='' value=0 min=0 max=100 text='' progressId='progressbar' token='' label='' showReport=false intervalTime=2000 >
902 <#if label!='' >
903 <div id="${progressId}-label" >${label}</div>
904 </#if>
905 <div class="progress"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
906 <div id="${progressId}" class="progress-bar progress-bar-${color}<#if token!=''> progressmanager</#if>" role="progressbar" style="width: ${value}%;" aria-valuenow="${value}" aria-valuemin="${min}" aria-valuemax="${max}" <#if token!=''>token="${token}" intervalTime=${intervalTime} showReport=${showReport?c}</#if> >
907 <#if text=''>${value}%<#else>${text}</#if>
908 </div>
909 </div>
910 <#if showReport >
911 <div id="${progressId}-report" class="progress-bar-report" lastline=0></div>
912 </#if>
913 </#macro>
914 <#-- INFO-BOX AdminTLE (widget) -->
915 <#-- color: only for the left side showing the icon. -->
916 <#-- bgColor: for the right side containing the text -->
917 <#macro infoBox color='' boxText='' boxIcon='' boxNumber='' unit='' bgColor='' progressBar='' progressDescription='' id='' params=''>
918 <div class="card m-2 box-widget<#if bgColor!=''> ${bgColor}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
919 <div class="card-body">
920 <span class="info-box-icon<#if color!=''> ${color}</#if>"><@icon style=boxIcon /></span><#if boxText !=''><span class="info-box-text ml-2">${boxText}</span></#if>
921 <div class="info-box-content">
922 <#if boxNumber!='0'><span class="info-box-number">${boxNumber?trim}<#if unit!=''> <small>${unit}</small></#if></span></#if>
923 <#if bgColor!='' && progressBar!=''><div class="progress"><div class="progress-bar" style="width: ${(boxNumber?trim?number/progressBar?trim?number*100)?string.computer}%"></div></div></#if>
924 <#if progressDescription!=''><span class="progress-description">${progressDescription}</span></#if>
925 <#nested />
926 </div>
927 </div>
928 </div>
929 </#macro>
930 <#-- TAG -->
931 <#-- color: default/primary/success/info/warning/danger/ -->
932 <#macro tag color='blue' class='' size='' title='' tagIcon='' id='' params='' deprecated...>
933 <@deprecatedWarning args=deprecated />
934 <span class="badge bg-${color}<#if class!=''> ${class}</#if>"<#if title!=''> title='${title}'</#if><#if id!=''>id='${id}'</#if><#if params!=''>${params}</#if>>
935 <#if tagIcon !=''>
936 <@icon style=tagIcon />
937 </#if>
938 <#nested>
939 </span>
940 </#macro>
941 <#-- NAVBAR -->
942 <#macro navBar tag='nav' class='' id='' params=''>
943 <${tag} class="navbar<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
944 <#nested>
945 </${tag}>
946 </#macro>
947 <#-- NAV -->
948 <#macro nav tag='nav' type='tab' class='' id='' params=''>
949 <${tag} class="nav nav-${type!}<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
950 <#nested>
951 </${tag}>
952 </#macro>
953 <#-- NAVITEM -->
954 <#macro navItem href='' name='' active=false title='' alt='' target='' tag='li' class='' id='' params=''>
955 <${tag} class="nav-link<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
956 <#if href !='' >
957 <@link class='nav-link' href=href name=name title=title alt=alt target=target active=active />
958 </#if>
959 <#nested>
960 </#${tag}>
961 </#macro>
962 <#-- BUTTON -->
963 <#-- bootstrap 3 : size: btn-xs/btn-sm/btn-lg -->
964 <#-- upcoming bootstrap 4 : size: btn-sm for small buttons/empty for medium buttons/btn-lg for large buttons -->
965 <#-- color: default[bootstrap4 : secondary]/primary/success/warning/danger/info -->
966 <#-- color (upcoming bootstrap 4): btn-outline-default/btn-outline-primary/btn-outline-success/btn-outline-warning/btn-outline-danger/btn-outline-info/ -->
967 <#-- style: btn-block/btn-flat/close/navbar-toggle/collapsed... -->
968 <#-- type: button/submit/reset -->
969 <#-- params: data-toggle/data-target/data-dismiss... -->
970 <#-- buttonIcon: icon name ex: info/check/comment/envelope... -->
971 <#-- iconPosition: left/right -->
972 <#-- cancel: switch to true for a cancellation form button. Adds the "formnovalidate" attribute to the button, as well as the right class -->
973 <#-- formId: contains the form ID if the button is outside of the form -->
974 <#-- buttonTargetId: contains the target element ID -->
975 <#-- buttonNested=false : If true add content inside the button else -default- outside -->
976 <#-- showTitle, showTitleXs, showTitleSm, showTitleMd, showTitleLg are deprecated in Lutece v7 -->
977 <#macro button name='' id='' type='button' size='xs' color='' style='' class='' params='' value='' title='' tabIndex='' hideTitle=[] showTitle=true showTitleXs=true showTitleSm=true showTitleMd=true showTitleLg=true buttonIcon='' disabled=false iconPosition='left' dropdownMenu=false cancel=false formId='' buttonTargetId='' deprecated...>
978 <@deprecatedWarning args=deprecated />
979 <#if cancel || color = 'default' || color='btn-default' || color='btn-secondary' || color='secondary'>
980 <#local buttonColor = 'default' />
981 <#elseif !cancel && color=''>
982 <#local buttonColor = 'primary' />
983 <#else>
984 <#local buttonColor = color />
985 </#if>
986 <#-- Visibility of button title -->
987 <#local displayTitleClass = displaySettings( hideTitle,'inline-flex') />
988 <#-- Visibility of button title: backwards compatibility with Lutece v6, BS3 only -->
989 <#local showTitleClass = '' />
990 <#if style != ''>
991 <#if style?contains('card-control')>
992 <#if style?contains('collapse')>
993 <#local widgetAction = 'collapse' />
994 <script>
995 $( function() {
996 <#if buttonIcon = 'minus'>
997 $("${buttonTargetId}").addClass("show");
998 <#else>
999 $("${buttonTargetId}").addClass("collapse");
1000 </#if>
1001 });
1002 </script>
1003 <#elseif style?contains('remove')>
1004 <#local widgetAction = 'remove' />
1005 </#if>
1006 <#local btnStyle = style?replace('collapse|remove', '', 'r')?trim />
1007 <#elseif style?contains('modal')>
1008 <#local widgetAction = 'modal' />
1009 <#local btnStyle = style?replace('modal', '', 'r')?trim />
1010 <#else>
1011 <#local btnStyle = style />
1012 </#if>
1013 </#if>
1014 <#-- Size class -->
1015 <#if size == 'xs'>
1016 <#local buttonSize = 'sm' />
1017 <#elseif size == 'sm' || size == ''>
1018 <#local buttonSize = '' />
1019 <#elseif size == 'lg'>
1020 <#local buttonSize = size />
1021 <#else>
1022 <#local buttonSize = '' />
1023 </#if>
1024 <button class="<#if style!='close'>btn</#if><#if buttonSize!=''> btn-${buttonSize}</#if><#if buttonColor!=''> btn-${buttonColor}</#if><#if btnStyle?? && btnStyle!=''> ${btnStyle}</#if><#if dropdownMenu> dropdown-toggle</#if><#if class!=''> ${class}</#if>" type="${type}"<#if title!=''> title="${title}"</#if><#if name!=''> name="${name}"</#if><#if id!=''> id="${id}"</#if><#if value!=''> value="${value}"</#if><#if params!=''> ${params}</#if><#if disabled> disabled</#if><#if dropdownMenu> data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"</#if><#if widgetAction?? && widgetAction!=''><#if widgetAction = 'collapse' || widgetAction = 'modal'> data-bs-toggle="${widgetAction}"<#elseif widgetAction = 'remove'> data-bs-dismiss="alert"</#if></#if><#if buttonTargetId!=''> data-bs-target="${buttonTargetId}"</#if><#if cancel> formnovalidate</#if><#if formId!=''> form="${formId}"</#if>>
1025 <#if buttonIcon!='' && iconPosition='left'>
1026 <#if hideTitle?size > 0 || title == ''>
1027 <@icon style=buttonIcon />
1028 <#else>
1029 <@icon style=buttonIcon class='me-1 mr-1' />
1030 </#if>
1031 </#if>
1032 <#local nestedContent><#nested /></#local>
1033 <#local nestedContent = nestedContent?trim />
1034 <#if nestedContent=''>
1035 <#if displayTitleClass!=''><span class="${displayTitleClass}"></#if>
1036 ${title}
1037 <#if displayTitleClass!=''></span></#if>
1038 </#if>
1039 <#if nestedContent!='' && !dropdownMenu><#if displayTitleClass!=''><span class="${displayTitleClass}"></#if><#nested><#if displayTitleClass!=''></span></#if></#if>
1040 <#if buttonIcon!='' && iconPosition='right'>
1041 <#if hideTitle?size > 0 || title == ''>
1042 <@icon style=buttonIcon />
1043 <#else>
1044 <@icon style=buttonIcon class='ms-1 ml-1' />
1045 </#if>
1046 </#if>
1047 </button>
1048 <#if dropdownMenu>
1049 <ul class="dropdown-menu"<#if id!=''> id="${id}-content" aria-labelledby="${id}-content"</#if>>
1050 <#nested>
1051 </ul>
1052 </#if>
1053 </#macro>
1054 <#-- ANCHOR BUTTON (LINK STYLED AS A BUTTON) -->
1055 <#-- size: sm/lg/or EMPTY for medium size-->
1056 <#-- Bootstrap colors: default/primary/success/warning/danger/info -->
1057 <#-- AdminLTE colors: black/gray-dark/gray/light/indigo/navy/purple/fuchsia/pink/maroon/orange/lime/teal/olive -->
1058 <#-- style: btn-block/btn-flat/btn-app -->
1059 <#-- icon: icon name ex: info/check/comment/envelope... -->
1060 <#-- ShowTitleXs is UNUSED in Bootstrap 4. -->
1061 <#macro aButton name='' id='' href='' target='' size='xs' color='primary' style='btn' align='' class='' params='' title='' tabIndex='' hideTitle=[] buttonIcon='' disabled=false iconPosition='left' dropdownMenu=false deprecated...>
1062 <@deprecatedWarning args=deprecated />
1063 <#-- Visibility of button title -->
1064 <#local displayTitleClass = displaySettings(hideTitle,'inline') />
1065 <#if color = 'default' || color='btn-default' || color='btn-secondary' || color='secondary'>
1066 <#local buttonColor = 'btn-default' />
1067 <#elseif color=''>
1068 <#local buttonColor = 'btn-primary' />
1069 <#else>
1070 <#if color == 'primary' || color == 'secondary' || color == 'success' || color == 'info' || color == 'warning' || color == 'danger'>
1071 <#local buttonColor = 'btn-' + color />
1072 <#else>
1073 <#local buttonColor = 'bg-' + color />
1074 </#if>
1075 </#if>
1076 <#if style='card-control'>
1077 <#assign style='text-right btn-link' />
1078 </#if>
1079 <#local class += alignmentSettings(align,'') />
1080 <#-- Size class -->
1081 <#if size == 'xs'>
1082 <#local buttonSize = 'sm' />
1083 <#elseif size == 'sm' || size == ''>
1084 <#local buttonSize = '' />
1085 <#elseif size == 'lg'>
1086 <#local buttonSize = size />
1087 <#else>
1088 <#local buttonSize = '' />
1089 </#if>
1090 <#if dropdownMenu>
1091 <div class="btn-group">
1092 </#if>
1093 <a class="${style}<#if buttonSize!=''> btn-${buttonSize}</#if><#if color!=''> ${buttonColor}</#if><#if class!=''> ${class}</#if>"<#if name!=''> name="${name}"</#if><#if id!=''> id="${id}"</#if> href="${href}" title="${title}"<#if target!=''> target="${target}"</#if><#if params!=''> ${params}</#if><#if disabled> disabled</#if><#if dropdownMenu> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"</#if>>
1094 <#if buttonIcon!='' && iconPosition='left'>
1095 <@icon style=buttonIcon class='me-1 mr-1' />
1096 </#if>
1097 <span class="${displayTitleClass}">${title}</span>
1098 <#if buttonIcon!='' && iconPosition='right'>
1099 <@icon style=buttonIcon class='ms-1 ml-1' />
1100 </#if>
1101 <#if !dropdownMenu>
1102 <#nested>
1103 </#if>
1104 </a>
1105 <#if dropdownMenu>
1106 <div class="dropdown-menu"<#if id!=''> id="${id}" aria-labelledby="${id}"</#if>>
1107 <#nested>
1108 </div>
1109 </div>
1110 </#if>
1111 </#macro>
1112 <#-- BTN TOOLBAR -->
1113 <#macro btnToolbar id='' class='' align='' ariaLabel='' params=''>
1114 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
1115 <div class="btn-toolbar<#if class!=''> ${class?trim}</#if>" role="toolbar"<#if ariaLabel!=''> aria-label="${ariaLabel}"</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1116 <#nested>
1117 </div>
1118 </#macro>
1119 <#-- BTN GROUP -->
1120 <#-- size: sm/empty/lg -->
1121 <#-- align: left/center/right -->
1122 <#macro btnGroup id='' class='' align='' size='' params='' ariaLabel='' hide=[] deprecated...>
1123 <@deprecatedWarning args=deprecated />
1124 <#local class += ' ' + displaySettings(hide,'inline-flex') + ' ' + alignmentSettings(align,'') />
1125 <div class="btn-group<#if size!=''> btn-group-${size}</#if><#if class!=''> ${class?trim}</#if>" role="group"<#if ariaLabel!=''> aria-label="${ariaLabel}"</#if><#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1126 <#nested>
1127 </div>
1128 </#macro>
1129 <#macro actionButtons button1Name='' button2Name='' i18nValue1Key='portal.admin.message.buttonValidate' i18nValue2Key='portal.admin.message.buttonCancel' url1='' url2='' icon1='save' icon2='times' offset=3 >
1130 <@formGroup rows=2>
1131 <#if url1 != ''>
1132 <@aButton href='${url1}' buttonIcon='${icon1}' title='#i18n{${i18nValue1Key}}' size=''/>
1133 <#else>
1134 <@button type='submit' name='${button1Name}' buttonIcon='${icon1}' title='#i18n{${i18nValue1Key}}' size='' />
1135 </#if>
1136 <#if url2 != ''>
1137 <@aButton href='${url2}' buttonIcon='${icon2}' title='#i18n{${i18nValue2Key}}' color='secondary' cancel=true size=''/>
1138 <#else>
1139 <#if button2Name != ''>
1140 <@button type='submit' name='${button2Name}' buttonIcon='${icon2}' title='#i18n{${i18nValue2Key}}' color='secondary' cancel=true size='' />
1141 </#if>
1142 </#if>
1143 </@formGroup>
1144 </#macro>
1145 <#-- Radio button/Checkbox as buttons (to use with btnGroup) -->
1146 <#-- type: radio/checkbox -->
1147 <#macro btnGroupRadioCheckbox type='checkbox' color='primary' size='' name='' id='' params='' ariaLabel='' labelFor='' labelKey='' labelParams='' tabIndex='' value='' checked=false>
1148 <label class="btn btn-${color}<#if size!=''> btn-${size}</#if>" for="${labelFor}"<#if labelParams!=''> ${labelParams}</#if>>
1149 <input type="${type}" name="${name}" id="${id}" autocomplete="off"<#if value!=''> value="${value}"</#if><#if params!=''> ${params}</#if><#if tabIndex!=''> tabindex="${tabIndex}"</#if><#if checked> checked</#if> /><#if labelKey!=''>${labelKey}</#if>
1150 </label>
1151 </#macro>
1152 <#-- Simple links a href, anchors -->
1153 <#macro link href='' class='' id='' name='' title='' alt='' target='' params=''>
1154 <a href="${href}"<#if class!=''> class="${class}"</#if><#if id!=''> id="${id}"</#if><#if name!=''> name="${name}"</#if><#if target!=''> target="${target}"</#if><#if title!=''> title="${title}"</#if><#if alt!=''> alt="${alt}"</#if><#if params!=''> ${params}</#if>>
1155 <#nested>
1156 </a>
1157 </#macro>
1158 <#-- MODAL -->
1159 <#-- bgColor: modal-default/modal-primary/modal-info/modal-warning/modal-danger -->
1160 <#macro modal id params='' bgColor='' size=''>
1161 <div class="modal ${bgColor} fade" id="${id}" data-bs-toggle="modal"<#if params!=''> ${params}</#if>>
1162 <div class="modal-dialog<#if size!=''> modal-${size}</#if>" role="document">
1163 <div class="modal-content">
1164 <#nested>
1165 </div>
1166 </div>
1167 </div>
1168 </#macro>
1169 <#macro modalHeader titleLevel='h4' modalTitle='' id='' params=''>
1170 <div class="modal-header"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1171 <${titleLevel} class="modal-title">${modalTitle}</${titleLevel}>
1172 <#nested>
1173 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="#i18n{portal.admin_page.buttonClosed}"></button>
1174 </div>
1175 </#macro>
1176 <#macro modalBody id='' params=''>
1177 <div class="modal-body"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1178 <#nested>
1179 </div>
1180 </#macro>
1181 <#macro modalFooter id='' params=''>
1182 <div class="modal-footer"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1183 <#nested>
1184 </div>
1185 </#macro>
1186 <#-- BREADCRUMBS -->
1187 <#macro breadcrumbs id='' class='' params=''>
1188 <nav aria-label="breadcrumb">
1189 <ol class="breadcrumb<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1190 <#nested>
1191 </ol>
1192 </nav>
1193 </#macro>
1194 <#macro breadcrumbItem class='' id='' params=''>
1195 <li class="breadcrumb-item<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1196 <#nested>
1197 </li>
1198 </#macro>
1199 <#-- CALLOUT -->
1200 <#-- AdminLTE classes: info/warning/danger/success -->
1201 <#macro callOut color='' titleLevel='h3' title='' callOutIcon='' id='' params=''>
1202 <div class="alert alert-important alert-${color}"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1203 <#if title!=''><${titleLevel}><@icon style=callOutIcon /> ${title}</${titleLevel}></#if>
1204 <#nested>
1205 </div>
1206 </#macro>
1207 <#-- ALERT -->
1208 <#-- classes: alert-success/alert-info/alert-warning/alert-danger + alert-dismissible -->
1209 <#-- color: primary/success/info/warning/danger -->
1210 <#macro alert class='' color='' titleLevel='h4' title='' iconTitle='' dismissible=false id='' params=''>
1211 <div class="alert alert-<#if class!=''>${class}</#if><#if color!=''> alert-${color}</#if><#if dismissible> alert-dismissible</#if>"<#if id!=''> id="${id}"</#if>>
1212 <div class="d-flex align-items-center <#if params!=''> ${params}</#if>">
1213 <#if color!=''><#assign txtColor> text-${color}</#assign></#if>
1214 <#if iconTitle!=''><@icon style=iconTitle class='mx-2${txtColor}' /></#if>
1215 <#if title!=''>
1216 <${titleLevel} class="alert-title">
1217 ${title}
1218 </${titleLevel}>
1219 </#if>
1220 <#nested>
1221 </div>
1222 <#if dismissible><a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a></#if>
1223 </div>
1224 </#macro>
1225 <#-- ----------------------------------------------------- -->
1226 <#-- Card as Box -->
1227 <#-- color: default/primary/info/success/warning/danger -->
1228 <#-- style: solid (no top border) -->
1229 <#-- collapsed: true/false -->
1230 <#-------------------------------------------------------- -->
1231 <#macro box color='' id='' style='' class='' title='' params='' collapsed=false>
1232 <div class="card mb-3<#if color!=''> card-${color}<#else> card-transparent</#if> card-outline<#if style!=''> text-${style}</#if><#if class!=''> ${class}</#if><#if collapsed> collapsed-box</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1233 <#if title =''>
1234 <#nested>
1235 <#else>
1236 <@boxHeader title=title params=params skipHeader=true />
1237 <@boxBody>
1238 <#nested>
1239 </@boxBody>
1240 </#if>
1241 </div>
1242 </#macro>
1243 <#-- The boxTools parameter is unused, kept for backwards compatibility -->
1244 <#macro boxHeader title='' i18nTitleKey='' hideTitle=[] showTitle=true id='' class='' params='' boxTools=false titleLevel='h3' skipHeader=false>
1245 <div class="card-header<#if class!=''> ${class}</#if><#if skipHeader> skip-header</#if>"<#if id!=''> id="${id}"</#if><#if params !=''> ${params}</#if>>
1246 <${titleLevel} class="card-title<#if showTitle=false> sr-only</#if>"><#if title!=''>${title}</#if><#if i18nTitleKey!=''>#i18n{${i18nTitleKey}}</#if></${titleLevel}>
1247 <#local nested><#nested></#local>
1248 <#if nested?has_content>
1249 <div class="ms-auto">
1250 <#nested>
1251 </div>
1252 </#if>
1253 </div>
1254 </#macro>
1255 <#macro boxBody class='' collapsed=false align='' id='' params=''>
1256 <#if collapsed><#local class += ' ' + 'collapse' /></#if>
1257 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
1258 <div class="card-body bg-white<#if class!=''> ${class}</#if>" <#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1259 <#nested>
1260 </div>
1261 </#macro>
1262 <#macro boxFooter class='' align='' id='' params=''>
1263 <#if align!=''><#local class += ' ' + alignmentSettings(align,'') /></#if>
1264 <div class="card-footer<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1265 <#nested>
1266 </div>
1267 </#macro>
1268 <#---------------------------------------->
1269 <#-- color: Bootstrap + -->
1270 <#-- unit: %,... -->
1271 <#macro smallBox color='' title='' text='' boxIcon='' titleLevel='div' unit='' url='' urlText='' id='' params='' fontSize='40px'>
1272 <div class="card card-sm mb-3 box-widget"<#if id!=''> id="${id}" data-id="${id}"</#if><#if params!=''> ${params}</#if>>
1273 <div class="card-body">
1274 <div class="row align-items-center">
1275 <div class="col-auto">
1276 <#if color !=''><span class="bg-${color} text-white avatar"></#if>
1277 <@icon style=boxIcon />
1278 <#if color !=''></span></#if>
1279 </div>
1280 <div class="col">
1281 <#if url!=''><a class="card-link" href="${url}"></#if>
1282 <${titleLevel} class="font-weight-medium"><span class="counter">${title}</span><#if unit!=''> ${unit}</#if></${titleLevel}>
1283 <div class="text-muted">${text}</div>
1284 <#if url!=''></a></#if>
1285 </div>
1286 </div>
1287 </div>
1288 </div>
1289 </#macro>
1290 <#-- Error Type: 500,404... -->
1291 <#-- Color: primary/blue/navy/aqua/teal/green/orange/yellow/red/purple/maroon/gray/black... -->
1292 <#macro errorPage color='' errorType='' id='' params=''>
1293 <div class="error-page"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1294 <h2 class="headline text-${color}">${errorType}</h2>
1295 <div class="error-content">
1296 <h3>
1297 <@icon style='warning' class='text-${color}' />
1298 <#if errorType=='404'>
1299 #i18n{portal.util.error404.title}
1300 <#elseif errorType='500'>
1301 #i18n{portal.util.error500.title}
1302 <#else>...
1303 </#if>
1304 </h3>
1305 <p>
1306 <#if errorType=='404'>
1307 #i18n{portal.util.error404.text}
1308 <#elseif errorType='500'>
1309 #i18n{portal.util.error500.text}
1310 <#else>...
1311 </#if>
1312 </p>
1313 <@aButton href='' size='' color='bg-${color}' style='btn-flat'>
1314 <@icon style='home' />
1315 #i18n{portal.util.labelBackHome}
1316 </@aButton>
1317 </div>
1318 </div>
1319 </#macro>
1320 <#-- CONTEXTUAL BACKGROUND P-->
1321 <#-- Bootstrap colors: primary/success/info/warning/danger -->
1322 <#-- colors: gray/gray-light/black/red/yellow/aqua/blue/light-blue/green/navy/teal/olive/lime/orange/fuchsia/purple/maroon -->
1323 <#macro coloredBg color='' type='p' id='' params=''>
1324 <${type} class="bg-${color}"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1325 <#nested>
1326 </${type}>
1327 </#macro>
1328 <#macro listGroup id='' class='' params=''>
1329 <ul class="list-group<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1330 <#nested>
1331 </ul>
1332 </#macro>
1333 <#macro listGroupItem id='' class='' params=''>
1334 <li class="list-group-item list-group-item-action<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1335 <#nested>
1336 </li>
1337 </#macro>
1338 <#macro unstyledList id='' params=''>
1339 <ul class="unstyled"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1340 <#assign liClass = "margin">
1341 <#nested>
1342 </ul>
1343 </#macro>
1344 <#-- DROPDOWN MENU LIST -->
1345 <#macro dropdownList id='' params=''>
1346 <div class="dropdown-menu"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if>>
1347 <#nested>
1348 </div>
1349 </#macro>
1350 <#macro dropdownItem class='' href='' target='' title='' id='' params=''>
1351 <li>
1352 <a href="${href}" class="dropdown-item<#if class!=''> ${class}</#if>" title="${title}"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if><#if target!=''> target="${target}"</#if>>${title}</a>
1353 </li>
1354 </#macro>
1355 <#-- CARDS -->
1356 <#macro card header=false headerTitle='' headerIcon=false headerTitleIcon=''>
1357 <div class="card mb-3">
1358 <#if header><div class="card-header bg-info"><#if headerIcon><@icon style='${headerTitleIcon}' /> </#if>${headerTitle}</div></#if>
1359 <div class="card-body">
1360 <#nested>
1361 </div>
1362 </div>
1363 </#macro>
1364 <#-- FUNCTION: DISPLAY -->
1365 <#-- This function returns a "visible" or "hidden" class for any component -->
1366 <#-- breakpoints: "all" || "xs"/"sm"/"md"/"lg"/"xl" -->
1367 <#-- display: inline/inline-block/block/table/table-cell/table-row/flex/inline-flex -->
1368 <#function displaySettings breakPoints=[] display=''>
1369 <#local breakPointsOrdered = [] />
1370 <#if breakPoints?seq_contains('all')>
1371 <#local breakPointsOrdered += ['all'] />
1372 </#if>
1373 <#if breakPoints?seq_contains('xs')>
1374 <#local breakPointsOrdered += ['xs'] />
1375 </#if>
1376 <#if breakPoints?seq_contains('sm')>
1377 <#local breakPointsOrdered += ['sm'] />
1378 </#if>
1379 <#if breakPoints?seq_contains('md')>
1380 <#local breakPointsOrdered += ['md'] />
1381 </#if>
1382 <#if breakPoints?seq_contains('lg')>
1383 <#local breakPointsOrdered += ['lg'] />
1384 </#if>
1385 <#if breakPoints?seq_contains('xl')>
1386 <#local breakPointsOrdered += ['xl'] />
1387 </#if>
1388 <#local displayClass = '' />
1389 <#if breakPointsOrdered?? && breakPointsOrdered?size > 0>
1390 <#list breakPointsOrdered as breakPoint>
1391 <#if breakPoint = 'xs' || breakPoint = 'all'>
1392 <#local displayClass += 'd-none' />
1393 <#if breakPoint = 'xs'>
1394 <#if !breakPointsOrdered?seq_contains('sm')>
1395 <#local displayClass += ' d-sm-${display}' />
1396 </#if>
1397 </#if>
1398 <#elseif breakPoint = 'sm' || breakPoint = 'md' || breakPoint = 'lg' || breakPoint = 'xl'>
1399 <#if breakPoint = 'sm'>
1400 <#if displayClass = ''>
1401 <#local displayClass += ' d-' + breakPoint + '-none' />
1402 <#elseif displayClass = 'd-none' && !breakPointsOrdered?seq_contains('md')>
1403 <#local displayClass += ' d-md-${display}' />
1404 </#if>
1405 <#elseif breakPoint = 'md'>
1406 <#if !breakPointsOrdered?seq_contains('sm')>
1407 <#local displayClass += ' d-' + breakPoint + '-none' />
1408 </#if>
1409 <#if !breakPointsOrdered?seq_contains('lg')>
1410 <#local displayClass += ' d-lg-${display}' />
1411 </#if>
1412 <#elseif breakPoint = 'lg'>
1413 <#if !breakPointsOrdered?seq_contains('md')>
1414 <#local displayClass += ' d-' + breakPoint + '-none' />
1415 </#if>
1416 <#if !breakPointsOrdered?seq_contains('xl')>
1417 <#local displayClass += ' d-xl-${display}' />
1418 </#if>
1419 <#elseif breakPoint = 'xl'>
1420 <#if !breakPointsOrdered?seq_contains('lg')>
1421 <#local displayClass += ' d-' + breakPoint + '-none' />
1422 </#if>
1423 </#if>
1424 <#else>
1425 <#local displayClass += ' undefined_breakpoint' />
1426 </#if>
1427 </#list>
1428 </#if>
1429 <#return displayClass?trim>
1430 </#function>
1431 <#-- This function returns responsive classes or flex order classes -->
1432 <#-- type: col|offset|order -->
1433 <#function responsiveDisplay type='' breakpoints={}>
1434 <#local responsiveDisplayClass = '' />
1435 <#list breakpoints as breakpointkey,breakpointvalue>
1436 <#if breakpointvalue!=0>
1437 <#if breakpointkey = 'xs'>
1438 <#local responsiveDisplayClass += ' ${type}-${breakpointvalue}' />
1439 <#else>
1440 <#local responsiveDisplayClass += ' ${type}-${breakpointkey}-${breakpointvalue}' />
1441 </#if>
1442 </#if>
1443 </#list>
1444 <#return responsiveDisplayClass?trim>
1445 </#function>
1446 <#function alignmentSettings align='' style=''>
1447 <#local x = ''>
1448 <#if align !=''>
1449 <#if align = 'left'>
1450 <#if style = 'text'>
1451 <#local x = 'text-left' />
1452 <#elseif style = ''>
1453 <#local x = 'd-flex justify-content-start' />
1454 </#if>
1455 <#elseif align = 'right'>
1456 <#if style = 'text'>
1457 <#local x = 'text-right' />
1458 <#elseif style = ''>
1459 <#local x = 'd-flex justify-content-end' />
1460 </#if>
1461 <#elseif align = 'center'>
1462 <#if style = 'text'>
1463 <#local x = 'text-center' />
1464 <#elseif style = ''>
1465 <#local x = 'd-flex justify-content-center' />
1466 </#if>
1467 </#if>
1468 </#if>
1469 <#return x>
1470 </#function>
1471 <#-- -------------------------------------------------
1472 -- MACRO ADMIN STRUCTURE - HEADER + NAVBAR + FOOTER --
1473 -------------------------------------------------- -->
1474 <#-- MACRO adminHeader -->
1475 <#macro adminHeader site_name=site_name>
1476 <script>
1477 $(".wrapper").hide();
1478 </script>
1479 </head>
1480 <body class="antialiased<#if false> theme-dark</#if>">
1481 <div class="wrapper">
1482 <header class="navbar navbar-expand-md navbar-dark d-print-none">
1483 <div class="container-fluid">
1484 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu">
1485 <span class="navbar-toggler-icon"></span>
1486 </button>
1487 <h1 class="navbar-brand d-none-navbar-horizontal pe-0 pe-md-3">
1488 <a href="jsp/site/Portal.jsp" title="#i18n{portal.users.admin_header.title.viewSite} ${site_name}" target="_blank" title="#i18n{portal.site.portal_footer.newWindow}">
1489 <img src="#dskey{portal.site.site_property.logo_url}" height="30" alt="Tabler" class="navbar-brand-image">
1490 </a>
1491 <span class="ml-2 ms-2">${site_name}</span>
1492 </h1>
1493 <div class="navbar-nav flex-row order-md-last">
1494 <div class="nav-item dropdown d-none d-md-flex me-3">
1495 <a class="nav-link" href="${admin_url}" title="#i18n{portal.users.admin_header.homePage}">
1496 <i class="fas fa-home"></i>
1497 </a>
1498 </div>
1499 <#if user.userLevel == 0>
1500 <#assign hasIcon=false />
1501 <#if listLoggersInfo?has_content>
1502 <#list listLoggersInfo?filter( logInfo -> ( logInfo.level = 'DEBUG' || logInfo.level = 'TRACE' ) ) as logInfo>
1503 <#if logInfo?size gt 0>
1504 <#if hasIcon=false >
1505 <div class="nav-item d-none d-md-flex me-3">
1506 <a href="#" class="nav-link px-0" data-bs-toggle="dropdown" tabindex="-1" aria-label="Show notifications" aria-expanded="false">
1507 <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10 5a2 2 0 0 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6"></path><path d="M9 17v1a3 3 0 0 0 6 0v-1"></path></svg>
1508 <span class="badge bg-red"></span>
1509 </a>
1510 <div class="dropdown-menu dropdown-menu-arrow dropdown-menu-end dropdown-menu-card">
1511 <div class="card">
1512 <div class="card-header">
1513 <h3 class="card-title">Notifications</h3>
1514 </div>
1515 <div class="list-group list-group-flush list-group-hoverable">
1516 <div class="list-group-item logger">
1517 <div class="row align-items-start">
1518 <div class="col-auto pt-2">
1519 <span class="badge bg-red d-block"></span>
1520 </div>
1521 <div class="col text-truncate">
1522 <h3><a href="#" class="text-body d-block">#i18n{portal.util.log.warningLevel}</a></h3>
1523 <#assign hasIcon = true />
1524 </#if>
1525 <div class="d-block text-truncate mt-1" title="${logInfo.path!}"><strong>${logInfo.name!} - ${logInfo.level!}</strong> ${logInfo.path!}</div>
1526 </#if>
1527 </#list>
1528 </#if>
1529 <#if hasIcon == true >
1530 </div>
1531 </div>
1532 </div>
1533 </div>
1534 </div>
1535 </div>
1536 </div>
1537 </#if>
1538 <div class="nav-item d-none d-md-flex me-3">
1539 <a class="nav-link px-0" href="jsp/admin/AdminTechnicalMenu.jsp" title="#i18n{portal.admindashboard.view_dashboards.title}">
1540 <i class="fa fa-cog"></i>
1541 </a>
1542 </div>
1543 </#if>
1544 <div class="nav-item dropdown">
1545 <a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu">
1546 <span class="avatar avatar-sm" style="background-image:url(<#if adminAvatar>servlet/plugins/adminavatar/avatar?id_user=${user.userId}<#else>#dskey{portal.site.site_property.avatar_default}</#if>)"></span>
1547 <div class="d-none d-xl-block ps-2">
1548 <div>${dashboard_zone_4!}</div>
1549 <div class="mt-1 small text-muted" title="#i18n{portal.users.admin_header.labelLastLogin}">${user.dateLastLogin!}</div>
1550 </div>
1551 </a>
1552 <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
1553 <#if userMenuItems?has_content>
1554 <#list userMenuItems as item>
1555 ${item.content}
1556 </#list>
1557 </#if>
1558 <div class="dropdown-divider"></div>
1559 <div class="mt-1 ps-2" id="switch-darkmode"><i class="ti ti-moon"></i> #i18n{portal.users.admin_header.labelMode} <span>#i18n{portal.users.admin_header.labelDarkMode}</span></div>
1560 <div class="dropdown-divider"></div>
1561 <#if admin_logout_url?has_content>
1562 <a class="dropdown-item" href="${admin_logout_url}" title="#i18n{portal.users.admin_header.deconnectionLink}">
1563 <i class="fa fa-power-off fa-fw"></i> #i18n{portal.users.admin_header.deconnectionLink}
1564 </a>
1565 </#if>
1566 </div>
1567 </div>
1568 </div>
1569 </header>
1570 <div class="navbar-expand-md">
1571 <div class="collapse navbar-collapse" id="navbar-menu">
1572 <div class="navbar navbar-light">
1573 <div class="container-fluid">
1574 <ul class="navbar-nav">
1575 <#list feature_group_list as feature_group>
1576 <#if feature_group.features?size > 1>
1577 <li class="nav-item dropdown">
1578 <a class="nav-link dropdown-toggle" id="dLabel${feature_group.id}Header" role="button" data-bs-toggle="dropdown" role="button" aria-expanded="false" href="${admin_url}#${feature_group.id}">
1579 ${feature_group.label}
1580 </a>
1581 <div class="dropdown-menu" aria-labelledby="dLabel${feature_group.id}Header">
1582 <div class="dropdown-menu-columns">
1583 <div class="dropdown-menu-column">
1584 <#list feature_group.features as feature>
1585 <#if !feature.externalFeature>
1586 <a class="dropdown-item" href="${feature.url}?plugin_name=${feature.pluginName}">${feature.name}</a>
1587 <#else>
1588 <a class="dropdown-item" href="${feature.url}">
1589 <#if feature.iconUrl?has_content><i class="${feature.iconUrl}"></i></#if> ${feature.name}
1590 </a>
1591 </#if>
1592 </#list>
1593 </div>
1594 </div>
1595 </div>
1596 </li>
1597 <#else>
1598 <#list feature_group.features as feature>
1599 <li class="nav-item">
1600 <#if !feature.externalFeature>
1601 <a class="nav-link" href="${feature.url}?plugin_name=${feature.pluginName}">${feature.name}</a>
1602 <#else>
1603 <a class="nav-link" href="${feature.url}"><#if feature.iconUrl?has_content><i class="${feature.iconUrl}"></i></#if>${feature.name}</a>
1604 </#if>
1605 </li>
1606 </#list>
1607 </#if>
1608 </#list>
1609 </ul>
1610 </div>
1611 </div>
1612 </div>
1613 </div>
1614 <#if user.userLevel == 0>
1615 <script>
1616 document.addEventListener( 'DOMContentLoaded', () => {
1617 const loggers = document.querySelector('.logger') ;
1618 if( loggers.childElementCount > 0 ){
1619 if( !sessionStorage.getItem('lutece-debug-modal') ){
1620 sessionStorage.setItem('lutece-debug-modal', false )
1621 }
1622 var modalContent = '<h3>#i18n{portal.util.log.warningLevel}</h3><p><strong>#i18n{portal.util.log.modalWarningMessage}</strong></p><p class="text-center"><button class="btn btn-sm btn-danger" data-toggle="collapse" data-target="#info-log" aria-expanded="false" aria-controls="info-log" type="button">#i18n{portal.util.log.modalLabelButton}</button></p><blockquote class="collapse" id="info-log">' + loggers.querySelector('.col.text-truncate').innerHTML + '</blockquote>';
1623 var adminModal = document.getElementById('adminModal');
1624 var adminModalLabel = document.getElementById('adminModalLabel');
1625 var adminModalBody = document.querySelector('#adminModal .modal-body');
1626 adminModalBody.insertAdjacentHTML( 'beforeEnd', modalContent);
1627 var adminModalHeader = document.querySelector('#adminModal .modal-header');
1628 var adminModalHeaderBtn = document.querySelector('#adminModal .modal-header button');
1629 var myAdminModal = new bootstrap.Modal( adminModal, {} );
1630 adminModalLabel.insertAdjacentHTML( 'beforeEnd', '#i18n{portal.util.log.modalWarningTitle}' );
1631 adminModalHeader.classList.add('text-white');
1632 adminModalHeaderBtn.setAttribute( 'style', 'background: transparent url("data:image/svg+xml,%3csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 16 16\' fill=\'%23ffffff\'%3e%3cpath d=\'M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z\'/%3e%3c/svg%3e") center/.75rem auto no-repeat;');
1633 adminModalHeader.classList.add('bg-danger');
1634 adminModalBody.classList.add('text-danger');
1635 adminModal.addEventListener('hide.bs.modal', function () {
1636 sessionStorage.setItem('lutece-debug-modal',true);
1637 })
1638 if( sessionStorage.getItem('lutece-debug-modal') === 'false' ){
1639 myAdminModal.show();
1640 }
1641 }
1642 });
1643 </script>
1644 </#if>
1645 <!-- Begin page content -->
1646 <main role="main" class="page-wrapper">
1647 <div class="container-fluid">
1648 <!-- Close in footer -->
1649 </#macro>
1650 <#-- MACRO adminFooter -->
1651 <#macro adminFooter >
1652 <!-- end content section -->
1653 </div>
1654 </main>
1655 <!-- footer menu -->
1656 <footer class="footer footer-transparent d-print-none">
1657 <div class="container-fluid">
1658 <div class="row text-center align-items-center flex-row-reverse">
1659 <div class="col-lg-auto ms-lg-auto">
1660 <ul class="list-inline list-inline-dots mb-0">
1661 <li class="list-inline-item"><a href="https://lutece.paris.fr/support/jsp/site/Portal.jsp?page=wiki" class="link-secondary">Documentation</a></li>
1662 <li class="list-inline-item"><a href="https://github.com/lutece-platform/" target="_blank" class="link-secondary" rel="noopener">Source code</a></li>
1663 </ul>
1664 </div>
1665 <div class="col-12 col-lg-auto mt-3 mt-lg-0">
1666 <ul class="list-inline list-inline-dots mb-0">
1667 <li class="list-inline-item">
1668 <a class="link-secondary" href="https://lutece.paris.fr" target="lutece" title="#i18n{portal.site.portal_footer.labelPortal}">
1669 <img src="images/poweredby.png" alt="#i18n{portal.site.portal_footer.labelMadeBy}">
1670 <small></small>
1671 </a>
1672 </li>
1673 <li class="list-inline-item">
1674 <span class="text-muted" rel="noopener">version ${version}</span>
1675 </li>
1676 </ul>
1677 </div>
1678 </div>
1679 </div>
1680 </footer>
1681 <!-- Admin Modal -->
1682 <div class="modal fade" id="adminModal" tabindex="-1" aria-labelledby="adminModalLabel" aria-hidden="true">
1683 <div class="modal-dialog modal-dialog-centered">
1684 <div class="modal-content">
1685 <div class="modal-header">
1686 <h5 class="modal-title" id="adminModalLabel"></h5>
1687 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="#i18n{portal.site.admin_page.buttonClosed}"></button>
1688 </div>
1689 <div class="modal-body"></div>
1690 <div class="modal-footer">
1691 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">#i18n{portal.site.admin_page.buttonClosed}</button>
1692 </div>
1693 </div>
1694 </div>
1695 </div>
1696 <!-- Included JS Files -->
1697 <!-- Le javascript -->
1698 <!-- ============================================================== -->
1699 <!-- Placed at the end of the document so the pages load faster -->
1700 <@coreAdminJSLinks />
1701 ${javascript_files}
1702 </div><!-- Close wrapper -->
1703 </#macro>
1704 <#-- MACRO adminHome -->
1705 <#macro adminHome >
1706 <@div class="dashboard-widgets pt-3 min-vh-100">
1707 <@row>
1708 <@columns sm=12 md=4 class='widget-col'>
1709 ${dashboard_zone_1!}
1710 <div> </div>
1711 </@columns>
1712 <@columns sm=12 md=4 class='widget-col'>
1713 ${dashboard_zone_2!}
1714 <div> </div>
1715 </@columns>
1716 <@columns sm=12 md=4 class='widget-col'>
1717 ${dashboard_zone_3!}
1718 <div> </div>
1719 </@columns>
1720 </@row>
1721 </@div>
1722 </#macro>
1723 <#-- MACRO adminDashboardWidget -->
1724 <#macro adminDashboardWidget id title color='primary' url='' class='' bodyClass='table-responsive no-padding' params='' >
1725 <@box style='solid' color='${color}' id='${id}_dashboard_card' class='box-widget' params=' data-id="${id}"'>
1726 <@boxHeader titleLevel='h5' title='${title}'>
1727 <#if url!=''><@aButton color="link" class='card-control' href='${url!}' title='${title!}' size='sm' buttonIcon='cog' hideTitle=['all'] /></#if>
1728 <@button style='card-control collapse' buttonTargetId='#${id}_dashboard_card_body' buttonIcon='minus' size='sm' />
1729 <@button style='card-control remove' buttonTargetId='#${id}_dashboard_card' buttonIcon='times' size='sm' />
1730 </@boxHeader>
1731 <@boxBody class=bodyClass id='${id}_dashboard_card_body'>
1732 <#nested>
1733 </@boxBody>
1734 </@box>
1735 </#macro>
1736 <#-- MACRO adminContentHeader -->
1737 <#macro adminContentHeader>
1738 <header class="page-header d-print-none">
1739 <@div class="row align-items-center admin-site-toolbar">
1740 <@div class="col">
1741 <@div class="page-pretitle" id="feature-title">
1742 <#if feature_url?? >
1743 <@link href='${feature_url}' title='${feature_title!""}'>${feature_title!''}</@link>
1744 <#else>
1745 ${feature_title!''}
1746 </#if>
1747 </@div>
1748 <#if page_title?has_content><h2>${page_title}</h2></#if>
1749 </@div>
1750 <@div id="page-header-buttons" class="col-auto ms-auto d-print-none">
1751 <@adminHeaderDocumentationLink />
1752 </@div>
1753 </@div>
1754 </header>
1755 <section class="content <#if feature_url?? && feature_url?ends_with('AdminSite.jsp')>no-padding</#if> min-vh-100">
1756 </#macro>
1757 <#-- MACRO adminLoginPage -->
1758 <#macro adminLoginPage title='' site_name='LUTECE'>
1759 <script src="js/admin/jquery/jquery-3.5.1.min.js"></script>
1760 </head>
1761 <body class="antialiased border-top-wide border-primary d-flex flex-column">
1762 <@div id="login-page" class="page page-center">
1763 <@div class="container container-tight py-4">
1764 <@div class="text-center mb-4">
1765 <@link href='.'>
1766 <@img url='#dskey{portal.site.site_property.logo_url}' alt='${site_name!}' title='${site_name!}' params=' height="36"' />
1767 <span class="sr-only">${site_name!'Lutece'}</span>
1768 </@link>
1769 </@div>
1770 <@div class="card card-md">
1771 <@div class="card-body bg-white">
1772 <h2 class="card-title text-center mb-4">#i18n{portal.admin.admin_login.welcome}<br> ${site_name!}</h2>
1773 <#nested>
1774 </@div>
1775 </@div>
1776 </@div>
1777 </@div>
1778 <script>
1779 $(function() {
1780 var randomImages = [#dskey{portal.site.site_property.back_images}];
1781 var rndNum = Math.floor(Math.random()*(randomImages.length));
1782 var bgImg = 'url(' + randomImages[rndNum] + ')';
1783 $("#login-page").css('background-image', bgImg );
1784 });
1785 </script>
1786 </#macro>
1787 <#-- MACRO adminHeaderDocumentationLink -->
1788 <#macro adminHeaderDocumentationLink >
1789 <#if feature_documentation?has_content >
1790 <#if feature_documentation?exists>
1791 <@div id="lutece-doc-link" class="bg-light p-1">
1792 <@link target="_blank" href="${feature_documentation}" title="#i18n{portal.features.documentation.help} [Nouvelle fenêtre]">
1793 <@icon class="fa-life-ring" /> <small>#i18n{portal.features.documentation.help}</small>
1794 </@link>
1795 </@div>
1796 </#if>
1797 </#if>
1798 </#macro>
1799 <#-- MACRO adminLanguage -->
1800 <#macro adminLanguage languages lang action='jsp/admin/DoChangeLanguage.jsp' >
1801 <@tform method='post' action=action class='form-inline'>
1802 <@input type='hidden' name='token' value='${token}' />
1803 <@row>
1804 <@columns class='mx-2'>
1805 <@icon style='language' /> #i18n{portal.admin.admin_home.language}
1806 <#list languages as language>
1807 <#if lang=language.code>
1808 <#assign islocale='check-circle text-success pl-4'>
1809 <#assign title=' Selectionné '>
1810 <#else>
1811 <#assign islocale=''>
1812 <#assign title=''>
1813 </#if>
1814 <@button color='' class='${language.code}' type='submit' name='language' value='${language.code}' title='${language.name?capitalize}${title}' buttonIcon='${islocale}' hideTitle=['all'] />
1815 </#list>
1816 </@columns>
1817 </@row>
1818 </@tform>
1819 </#macro>
1820 <#-- MACRO adminAccessibilityMode -->
1821 <#macro adminAccessibilityMode>
1822 <@tform method='post' action='jsp/admin/DoModifyAccessibilityMode.jsp' class="ml-2">
1823 <@input type='hidden' name='token' value='${token}' />
1824 <#if user.accessibilityMode>
1825 <@button color='link ' type='submit' buttonIcon='eye' title='#i18n{portal.users.admin_header.labelDeactivateAccessibilityMode}'/>
1826 <#else>
1827 <@button color='link text-dark' type='submit' buttonIcon='eye-slash' title='#i18n{portal.users.admin_header.labelActivateAccessibilityMode}'/>
1828 </#if>
1829 </@tform>
1830 </#macro>
1831 <#-- MACRO adminSiteColumnOutline -->
1832 <#macro adminSiteColumnOutline columnid=''>
1833 <@div class="admin_column_outline">
1834 <span class="admin_column_id">${i18n("portal.site.columnId",columnid)}</span>
1835 <@div><#nested></@div>
1836 </@div>
1837 </#macro>
1838 <#-- MACRO adminSiteToolbar -->
1839 <#macro adminSiteToolbar >
1840 <@btnToolbar>
1841 <@btnGroup>
1842 <@tform type='inline' action='jsp/admin/site/AdminSite.jsp' role='search'>
1843 <@input type='number' name='page_id' id='page_id' title='${i18n("portal.site.admin_page.buttonSearchPage")}' placeHolder='22' params=' style="width:4rem;"' />
1844 <@button type='submit' color='primary' title='${i18n("portal.site.admin_page.buttonSearchPage")}' hideTitle=['all'] buttonIcon='search' />
1845 </@tform>
1846 </@btnGroup>
1847 <@btnGroup class='ms-1 ml-1'>
1848 <@aButton href='' id='display-full' title='#i18n{portal.site.admin_page.buttonLargeScreen}' buttonIcon='desktop' color='primary'hideTitle=['all'] />
1849 <@aButton href='' id='display-940' title='#i18n{portal.site.admin_page.buttonTablet}' buttonIcon='tablet' color='primary' hideTitle=['all'] />
1850 <@aButton href='' id='display-480' title='#i18n{portal.site.admin_page.buttonSmartphone}' buttonIcon='mobile' color='primary' hideTitle=['all'] />
1851 </@btnGroup>
1852 <#if page.id != 1>
1853 <@btnGroup class='ms-1 ml-1'>
1854 <@aButton href='jsp/admin/site/AdminSite.jsp?page_id=${page.parentPageId}' color='success' buttonIcon='arrow-up' title='#i18n{portal.site.admin_page.buttonUpToParentPage}' hideTitle=['all'] />
1855 <@aButton href='jsp/admin/site/RemovePage.jsp?page_id=${page.id}' color='danger btn-icon' buttonIcon='trash text-white' title='#i18n{portal.site.admin_page.buttonDeletePage}' hideTitle=['all'] />
1856 </@btnGroup>
1857 </#if>
1858 <@btnGroup class='ms-1 ml-1'>
1859 <#if portlet_types_list?has_content>
1860 <@aButton class='dropdown-toggle' size='sm' id='portlet-type' dropdownMenu=true href='#' title='#i18n{portal.site.admin_page.labelPortletPage}' buttonIcon='th-large me-1' hideTitle=['xs','sm','md']>
1861 <#list portlet_types_list?sort_by("name") as portlet_type>
1862 <@dropdownItem class='portlet-type-ref' href='jsp/admin/DoCreatePortlet.jsp?portlet_type_id=${portlet_type.id}&page_id=${page.id}' target='preview' title='${portlet_type.name}'>
1863 ${portlet_type.name}
1864 </@dropdownItem>
1865 </#list>
1866 </@aButton>
1867 </#if>
1868 <#if extendableResourceActionsHtml?? && extendableResourceActionsHtml?has_content>
1869 ${extendableResourceActionsHtml!}
1870 </#if>
1871 </@btnGroup>
1872 <@btnGroup class='ms-1 ml-1'>
1873 <@aButton href='jsp/admin/site/AdminSite.jsp?page_id=${page.id}&param_block=2' buttonIcon='wrench' title='#i18n{portal.site.admin_page.labelPageProperty}' hideTitle=['xs','sm','md'] />
1874 </@btnGroup>
1875 <@btnGroup class='ms-1 ml-1'>
1876 <@aButton href='jsp/admin/site/AdminSite.jsp?page_id=${page.id}&param_block=5' buttonIcon='plus' title='#i18n{portal.site.admin_page.labelChildPagePage}' hideTitle=['xs','sm','md'] />
1877 </@btnGroup>
1878 <@btnGroup class='ms-1 ml-1'>
1879 <@aButton href='jsp/admin/site/AdminMap.jsp?page_id=${page.id }' buttonIcon='sitemap' title='Page ${page.name} - Id ${page.id}' hideTitle=['all'] ><@span hide=['all']>#i18n{portal.site.admin_page.tabAdminMapSite}</@span></@aButton>
1880 </@btnGroup>
1881 <@btnGroup class='ms-1 ml-1'>
1882 <@aButton href='' id='fullscreen' title='#i18n{portal.site.admin_page.buttonFullscreen}' buttonIcon='arrows-alt' color='secondary' hideTitle=['all'] />
1883 </@btnGroup>
1884 </@btnToolbar>
1885 </#macro>
1886 <#-- MACRO adminMessagePage -->
1887 <#macro adminMessagePage title=''>
1888 <#assign title=title />
1889 <#assign alerttype="primary" />
1890 <#assign icontype="fa-info-circle" />
1891 <#if title??>
1892 <#if title?trim='' >
1893 <#assign title="Information" />
1894 </#if>
1895 </#if>
1896 <#if message.type == 2 >
1897 <#assign alerttype="danger" />
1898 <#assign icontype="fa-question-circle" />
1899 <#elseif message.type == 3 >
1900 <#assign alerttype="warning" />
1901 <#assign icontype="fa-exclamation-circle" />
1902 <#elseif message.type == 4 >
1903 <#assign alerttype="warning" />
1904 <#assign icontype="fa-question-circle" />
1905 <#elseif message.type == 5 >
1906 <#assign alerttype="danger" />
1907 <#assign icontype="fa-ban" />
1908 </#if>
1909 <script src="js/admin/jquery/jquery-3.5.1.min.js"></script>
1910 </head>
1911 <body class="antialiased border-top-wide border-primary d-flex flex-column">
1912 <div class="page page-center">
1913 <@div class="container-sm">
1914 <@div class="text-center mb-4">
1915 <@link href=".">
1916 <@img url="#dskey{portal.site.site_property.logo_url}" alt='LUTECE' title='Lutece' params=' height="36"' />
1917 </@link>
1918 </@div>
1919 <@row class='justify-content-center align-items-center'>
1920 <@columns md=6>
1921 <@alert color=alerttype titleLevel='h1' title=title iconTitle=icontype params='flex-column'>
1922 <@p class="text-center">${text!}</@p>
1923 <#nested>
1924 </@alert>
1925 </@columns>
1926 </@row>
1927 </@div>
1928 </#macro>
1929 <#-- MACRO fieldSet -->
1930 <#macro fieldSet class='' fieldsetId='' fieldsetParams='' legend='' legendClass='' legendId='' legendIcon='' legendParams='' hideLegend=[] disabled=false>
1931 <fieldset<#if class!=''> class="${class}"</#if><#if fieldsetId!=''> id="${fieldsetId}"</#if><#if fieldsetParams!=''> ${fieldsetParams}</#if><#if disabled> disabled</#if>>
1932 <#if legend!=''>
1933 <#local legendClass += ' ' + displaySettings(hideLegend,'block') />
1934 <legend<#if legendClass!=''> class="${legendClass?trim}"</#if><#if legendId!=''> id="${legendId}"</#if><#if legendParams!=''> ${legendParams}</#if>><#if legendIcon!=''><@icon style=legendIcon /> </#if>${legend}</legend>
1935 </#if>
1936 <#nested>
1937 </fieldset>
1938 </#macro>
1939 <#-- RESPONSIVE -->
1940 <#-- HTML ELEMENTS -->
1941 <#-- MACRO img -->
1942 <#macro img url='' alt='' title='' class='' id='' params=''>
1943 <img src="${url}" alt="<#if alt!=''>${alt!}<#else>${title!}</#if>" title="${title}" class="thumbnails thumb-list<#if class!=''> ${class}</#if>"<#if id!=''> id="${id}"</#if><#if params!=''> ${params}</#if> />
1944 </#macro>
1945 <#-- Email Default Template -->
1946 <#macro emailTemplate title='Lutece' footer_link='https://fr.lutece.paris.fr'>
1947 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1948 <html xmlns="http://www.w3.org/1999/xhtml">
1949 <head>
1950 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1951 <meta name="viewport" content="width=device-width"/>
1952 <style type="text/css">
1953 * { margin: 0; padding: 0; font-size: 100%; font-family: 'Avenir Next', "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; line-height: 1.65; }
1954 img { max-width: 100%; margin: 0 auto; display: block; }
1955 body, .body-wrap { width: 100% !important; height: 100%; background: #f8f8f8; }
1956 a { color: #007bff; text-decoration: none; }
1957 a:hover { text-decoration: underline; }
1958 .text-center { text-align: center; }
1959 .text-right { text-align: right; }
1960 .text-left { text-align: left; }
1961 .button { display: inline-block; color: white; background: #007bff; border: solid #007bff; border-width: 10px 20px 8px; font-weight: bold; border-radius: 4px; }
1962 .button:hover { text-decoration: none; }
1963 h1, h2, h3, h4, h5, h6 { margin-bottom: 20px; line-height: 1.25; }
1964 h1 { font-size: 32px }
1965 h2 { font-size: 28px }
1966 h3 { font-size: 24px }
1967 h4 { font-size: 20px }
1968 h5 { font-size: 16px }
1969 p, ul, ol { font-size: 16px; font-weight: normal; margin-bottom: 20px; }
1970 .container { display: block !important; clear: both !important; margin: 0 auto !important; max-width: 580px !important; }
1971 .container table { width: 100% !important; border-collapse: collapse; }
1972 .container .masthead { padding: 80px 0; background: #007bff; color: white; }
1973 .container .masthead h1 { margin: 0 auto !important; max-width: 90%; text-transform: uppercase; }
1974 .container .content { background: white; padding: 30px 35px; }
1975 .container .content.footer { background: none; }
1976 .container .content.footer p { margin-bottom: 0; color: #888; text-align: center; font-size: 14px; }
1977 .container .content.footer a { color: #888; text-decoration: none; font-weight: bold; }
1978 .container .content.footer a:hover { text-decoration: underline; }
1979 </style>
1980 </head>
1981 <body>
1982 <table class="body-wrap">
1983 <tr>
1984 <td class="container">
1985 <!-- Message start -->
1986 <table>
1987 <tr>
1988 <td align="center" class="masthead"> <h1>${title}</h1> </td>
1989 </tr>
1990 <tr>
1991 <td class="content"><#nested></td>
1992 </tr>
1993 </table>
1994 </td>
1995 </tr>
1996 <tr>
1997 <td class="container">
1998 <!-- Message start -->
1999 <table>
2000 <tr>
2001 <td class="content footer" align="center">
2002 <p><a href="${footer_link}">Lutece</a></p>
2003 </td>
2004 </tr>
2005 </table>
2006 </td>
2007 </tr>
2008 </table>
2009 </body>
2010 </html>
2011 </#macro>
2012 <#macro empty title='' subtitle='' iconName='mood-empty' img='' actionTitle='' actionBtn='primary' actionIcon='plus' actionUrl='#'>
2013 <div class="empty">
2014 <#if img=''>
2015 <div class="empty-icon"><@icon prefix='ti ti-' style='${iconName}' params='style="font-size:48px"' /></div>
2016 <#else>
2017 <div class="empty-img"><img src="${img}" height="128" alt=""></div>
2018 </#if>
2019 <p class="empty-title"><#if title=''>#i18n{portal.util.message.emptyTitle}<#else>${title}</#if></p>
2020 <#if subtitle !=''>
2021 <p class="empty-subtitle text-muted">${subtitle}</p>
2022 <#else>
2023 <p class="empty-subtitle text-muted">#i18n{portal.util.message.emptySubTitle}</p>
2024 </#if>
2025 <#if actionTitle !=''>
2026 <div class="empty-action">
2027 <a href="${actionUrl}" class="btn btn-${actionBtn}"><#if actionIcon !=''><@icon prefix='ti ti-' style='${actionIcon}' /></#if> ${actionTitle}</a>
2028 </div>
2029 </#if>
2030 </div>
2031 </#macro>
2032 <#macro timeline class='' id='' params=''>
2033 <ul class="list list-timeline<#if class !=''> ${class}</#if>"<#if id !=''> id="${id}"</#if><#if params !=''> ${params}</#if>>
2034 <#nested>
2035 </ul>
2036 </#macro>
2037 <#macro timelineLabel bg='primary' label='' class='' id='' params=''>
2038 <!-- no label -->
2039 </#macro>
2040 <#macro timelineItem iconFace='check' iconBg='bg-primary' time='' label='' footer='' class='' id='' params=''>
2041 <li<#if class !=''> class="${class}"</#if><#if id !=''> id="${id}"</#if><#if params !=''> ${params}</#if>>
2042 <#if iconFace !=''><div class="list-timeline-icon ${iconBg}"><@icon style=iconFace /></div></#if>
2043 <div class="list-timeline-content">
2044 <#if time !=''><div class="list-timeline-time">${time}</div></#if>
2045 <p class="list-timeline-title">${label}</p>
2046 <div class="list-timeline-body"><#nested></div>
2047 <#if footer !=''><div class="timeline-footer">${footer}</div></#if>
2048 </div>
2049 </li>
2050 </#macro>
2051 <#-- scroll to top button -->
2052 <#macro scrollTopBtn>
2053 <a href="#" id="scroll" style="display: none;"><span></span></a>
2054 <script>
2055 $( function(){
2056 $(window).scroll(function(){
2057 if ( $(this).scrollTop() > 100) {
2058 $('#scroll').fadeIn();
2059 } else {
2060 $('#scroll').fadeOut();
2061 }
2062 });
2063 $('#scroll').click(function(){
2064 $("html, body").animate({ scrollTop: 0 }, 600);
2065 return false;
2066 });
2067 });
2068 </script>
2069 </#macro>
2070 <#-- copyElementToClipboard a set of elements designed by a selector - param "selector" -->
2071 <#-- Params -->
2072 <#-- selector : Any CSS selector expression -->
2073 <#-- class : Default '' : List of class with double quote with comma separator -->
2074 <#-- Possible values : "no-hover" No icon on hover - .no-hover portal_admin.css -->
2075 <#-- Possible values : "copy-icon" Icon always shown - . see portal_admin.css -->
2076 <#-- Possible values : "copy-btn" Icon and Button styles - -->
2077 <#-- Ex for multiple classes : "class1","class2" -->
2078 <#-- showMsg : Default false : If true a message is show after copy -->
2079 <#-- msgDone : Default "Copied" : Success message -->
2080 <#-- msgError : Default "Error : not copied" : Error message -->
2081 <#-- Usage -->
2082 <#-- Basic : <@copyElementToClipboard selector='.copy-content' /> -->
2083 <#-- No message : <@copyElementToClipboard selector='.copy-content' showMsg=false /> -->
2084 <#-- No Hover : <@copyElementToClipboard selector='.copy-content' class='"no-hover"' /> -->
2085 <#-- With icon shown : <@copyElementToClipboard selector='.copy-content' class='"copy-icon"' /> -->
2086 <#macro copyElementToClipboard selector class='' showMsg=true msgDone='#i18n{portal.util.copy.done}' msgError='#i18n{portal.util.copy.error}'>
2087 <script>
2088 const elems = document.querySelectorAll('${selector!}');
2089 elems.forEach(elem => {
2090 <#if class !=''>elem.classList.add( ${class!} );</#if>
2091 elem.setAttribute('title', '#i18n{portal.util.labelCopy}');
2092 elem.addEventListener('click', () => {
2093 const selection = window.getSelection();
2094 const range = document.createRange();
2095 range.selectNodeContents(elem);
2096 selection.removeAllRanges();
2097 selection.addRange(range);
2098 try {
2099 document.execCommand('copy');
2100 selection.removeAllRanges();
2101 <#if showMsg>
2102 const original = elem.textContent;
2103 elem.textContent = '${msgDone}';
2104 elem.classList.add('msg-success');
2105 setTimeout(() => {
2106 elem.textContent = original;
2107 elem.classList.remove('msg-success');
2108 }, 1200);
2109 </#if>
2110 } catch(e) {
2111 <#if showMsg>
2112 const original = elem.textContent;
2113 elem.textContent = '${msgError}';
2114 elem.classList.add('msg-error');
2115 setTimeout(() => {
2116 elem.textContent = original;
2117 elem.classList.remove('msg-danger');
2118 }, 1200);
2119 </#if>
2120 }
2121 });
2122 });
2123 </script>
2124 </#macro>
2125 <#-- initToast -->
2126 <#-- Params -->
2127 <#-- layout='popups' -->
2128 <#-- position='top-right' -->
2129 <#-- closer=false -->
2130 <#-- sticky=false -->
2131 <#-- progressbar=true -->
2132 <#-- theme='default' -->
2133 <#-- duration=3000 -->
2134 <#-- pool=5 -->
2135 <#macro initToast layout='popups' position='top-right' closer=true sticky=false progressbar=true insert='before' theme='default' duration=3000 pool=5 >
2136 <script>
2137 $( function(){
2138 var lutecepolipop = new Polipop('lutecepop', {
2139 layout: '${layout}',
2140 position: '${position}',
2141 theme: '${theme}',
2142 life: ${duration?c},
2143 insert: '${insert}',
2144 closer: ${closer?c},
2145 closeText : '#i18n{portal.util.labelClose}',
2146 sticky: ${sticky?c},
2147 progressbar: ${progressbar?c},
2148 pool: ${pool},
2149 });
2150 <#-- Add addToast macro in your template -->
2151 <#nested>
2152 });
2153 </script>
2154 </#macro>
2155 <#-- addToast -->
2156 <#-- Params -->
2157 <#-- title : Default "Error : not copied" : Error message -->
2158 <#-- msg : Default "Copied" : Success message -->
2159 <#-- type : Default "default" ['info', 'danger', 'success' 'warning'] -->
2160 <#macro addToast title content type='default' >
2161 lutecepolipop.add({
2162 content: '${content}',
2163 title: '${title}',
2164 type: '${type}',
2165 });
2166 </#macro>
2167 <#-- selectIconFont -->
2168 <#-- Params -->
2169 <#-- id : Default "selectIcon" : Id for select -->
2170 <#-- class : Default '' : List of class for select -->
2171 <#-- name : Default "resource-icon" : Name for submit -->
2172 <#-- showListLabel : Default true : Show icons' label -->
2173 <#-- showListIcon : Default true : Show icons' icon -->
2174 <#-- searchShow : Default true : Show search field in select -->
2175 <#-- searchFocus : Default false : It true set focus in search fiedl -->
2176 <#-- searchHighlight : Default true : Highlight searched chars in list -->
2177 <#-- type : Default 'yaml' : Possible values : ['yaml','json'] -->
2178 <#-- prefix : Default 'fa' : ['fa','bi-', [ti ti-],...] Prefix for icon family -->
2179 <#-- iconsUrl : Default 'css/admin/font-awesome-icons.yml' : File url to retrieve icon name list -->
2180 <#-- resources : Default true : If true load slimselect js lib and css. -->
2181 <#-- Only needed once, so set to false if you user this macro more than once -->
2182 <#-- FontAwesome icons yaml dowloaded from https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/metadata/icons.yml -->
2183 <#macro selectIconFont id='selectIcon' class='' name='resource-icon' showListLabel=true showListIcon=true searchShow=true searchFocus=false searchHighlight=true type='yaml' prefix='fa-' iconsUrl='css/admin/font-awesome-icons.yml' resources=true defaultValue=''>
2184 <@select name='${name}' id='${id}' />
2185 <#if resources>
2186 <link rel="stylesheet" href="js/admin/lib/slimselect/slimselect.min.css">
2187 <script src="js/admin/lib/slimselect/slimselect.min.js"></script>
2188 <#if type='yaml'>
2189 <!-- js yaml parser -->
2190 <script src="js/admin/lib/slimselect/js-yaml.min.js"></script>
2191 </#if>
2192 </#if>
2193 <script>
2194 $.get('${iconsUrl}', function(data) {
2195 <#if type='yaml'>
2196 let parsedIcons = jsyaml.load(data)
2197 <#else>
2198 <#-- Json / Object -->
2199 let parsedIcons='';
2200 if( typeof data === 'object' ){
2201 parsedIcons = data;
2202 } else {
2203 parsedIcons = JSON.parse( data )
2204 }
2205 </#if>
2206 $.each( parsedIcons, function(index, icon){
2207 let i=0, prefix='${prefix}';
2208 let selected = '${defaultValue}' == index ? 'selected' : '';
2209 <#if type='yaml'>
2210 <#-- FontAwesome specific / Other lib add another test/treatment -->
2211 while( i < icon.styles.length ){
2212 switch ( icon.styles[i] ) {
2213 case 'regular':
2214 prefix = 'far'
2215 break;
2216 case 'solid':
2217 prefix = 'fas'
2218 break;
2219 case 'light':
2220 prefix = 'fal'
2221 break;
2222 case 'brands':
2223 prefix = 'fab'
2224 break;
2225 }
2226 $('#${id}').append('<option value="' + index + '"' + selected + '> <#if showListIcon><span class="' + prefix + ' fa-'+ index + ' mr-1" ' + selected + ' ></span> </#if>' <#if showListLabel>+ icon.label + ' [' + icon.styles[i] + ']'</#if>+ '</option>');
2227 i++;
2228 }
2229 <#else>
2230 <#-- Json / Object -->
2231 $('#${id}').append('<option value="' + index + '" ' + selected + ' > <#if showListIcon><span class="' + prefix + ' fa-'+ index + '"></span> </#if>' <#if showListLabel>+ index </#if>+ '</option>');
2232 </#if>
2233 });
2234 new SlimSelect({
2235 select: '#${id}',
2236 showSearch: ${searchShow?c},
2237 searchText: "#i18n{portal.util.labelNoItem}",
2238 searchPlaceholder: '#i18n{portal.util.labelSearch}',
2239 searchFocus: ${searchFocus?c}, // Whether or not to focus on the search input field
2240 searchHighlight: ${searchHighlight?c}
2241 })
2242 });
2243 </script>
2244 </#macro>
2245 <#macro adminDashboardPanel title='' parentId='' childId='' icon='' color=''>
2246 <#assign parentId = parentId />
2247 <@accordionPanel color=color collapsed=true childId=childId>
2248 <@accordionHeader id=id title=title headerIcon=icon></@accordionHeader>
2249 <@accordionBody>
2250 <#nested>
2251 </@accordionBody>
2252 </@accordionPanel>
2253 <script>
2254 $( function(){
2255 const urlHash = document.location.hash;
2256 if ( urlHash != undefined ){
2257 $( urlHash ).addClass('show')
2258 }
2259 })
2260 </script>
2261 </#macro>
2262 <#-- JStree Macro -->
2263 <#macro jsTreeInit id='tree' btntreeSearch='treesearch' multiple=false plugins=[] style='proton/style.min.css'>
2264 <link rel="stylesheet" href="js/admin/lib/jstree/themes/proton/style.min.css" >
2265 <script src="js/admin/lib/jstree/jstree.min.js"></script>
2266 <script>
2267 $(function(){
2268 let selectedTree=jsTreeId=localStorage.getItem('jsTreeSelectedId' );
2269
2270 $('#tree').jstree({
2271 'core': {
2272 'multiple' : false,
2273 'themes': {
2274 'name': 'proton',
2275 'responsive': true
2276 }
2277 },
2278 'plugins' : [ 'search' , 'wholerow' ,'changed' ]
2279 }).on('click', function( e ){
2280 window.location.replace( e.target.getAttributeNode('href').value );
2281 }).on("changed.jstree", function (e, data) {
2282 localStorage.setItem( 'jsTreeSelectedId', data.changed.selected );
2283 });
2284
2285 $('#tree').jstree( 'select_node', jsTreeId );
2286
2287 var to = false;
2288 $('#treesearch').keyup(function () {
2289 if(to) { clearTimeout(to); }
2290 to = setTimeout(function () {
2291 var v = $('#treesearch').val();
2292 $('#tree').jstree(true).search(v);
2293 }, 250);
2294 });
2295
2296 });
2297 </script>
2298 </#macro>
2299 <#macro jsTreeSearch >
2300 <@formGroup formStyle='inline' labelKey='#i18n{portal.site.admin_page.buttonSearchPage}' hideLabel=['all']>
2301 <@inputGroup size='sm'>
2302 <@input type='text' id='tree_search' name='tree_search' placeHolder='#i18n{portal.site.admin_page.buttonSearchPage}' />
2303 <@inputGroupItem>
2304 <@button id='btn-tree_search' color='link' type='button' title='#i18n{portal.site.admin_page.buttonSearchPage}' buttonIcon='search' hideTitle=['all'] />
2305 </@inputGroupItem>
2306 </@inputGroup>
2307 </@formGroup>
2308 </#macro>
2309 <#-- Display wrong or deprecated macro arguments -->
2310 <#macro deprecatedWarning args=[] >
2311 <#if args?size != 0 ><!-- Warning : wrong or deprecated argument(s) : <#list args?keys as key >${key}, </#list> ... --></#if>
2312 </#macro>
2313 <#macro codeHighLight >
2314 <link rel="stylesheet" href="js/admin/lib/prism/prism.css">
2315 <link rel="stylesheet" href="js/admin/lib/prism/prism-live.css">
2316 <script src="js/admin/lib/prism/prism.js"></script>
2317 <script src="js/admin/lib/prism/prism-live.js"></script>
2318 </#macro>