adminFooter.ftl

 1   <#--
 2   Macro: adminFooter
 3   
 4   Description: Generates the footer section, including documentation and source code links, a Lutece logo, and a version number.
 5   
 6   Parameters:
 7   - version : The version number
 8   -->
 9   <#macro adminFooter closeMain=true >
 10   <!-- footer menu -->
 11   <footer class="lutece-main-footer footer footer-transparent d-print-none">
 12   	<div class="container-fluid">
 13   		<div class="row text-center align-items-center flex-row-reverse">
 14   			<div class="col-lg-auto ms-lg-auto">
 15   				<ul class="list-inline mb-0">
 16   					<li class="list-inline-item nav-item "><a href="https://lutece.paris.fr/support/jsp/site/Portal.jsp?page=wiki" class="nav-link">Documentation</a></li>
 17   					<li class="list-inline-item nav-item "><a href="https://github.com/lutece-platform/" target="_blank" class="nav-link" rel="noopener">Source code</a></li>
 18   				</ul>
 19   			</div>
 20   			<div class="col-12 col-lg-auto mt-3 mt-lg-0">
 21   				<ul class="nav list-inline mb-0">
 22   					<li class="list-inline-item nav-item">
 23   						<a class="nav-link d-flex align-items-center" href="https://lutece.paris.fr" target="lutece" title="#i18n{portal.site.portal_footer.labelPortal}">
 24   							<span class="me-2">${site_name}</span>
 25   							<img src="themes/admin/shared/images/poweredby.svg" style="height:15px" class="img-fluid theme-invert" alt="#i18n{portal.site.portal_footer.labelMadeBy}">
 26   							<span class="visually-hidden">LUTECE</span>
 27   							<span class="text-muted ms-2" rel="noopener">version ${version}</span>
 28   						</a>
 29   					</li>
 30   				</ul>
 31   			</div>
 32   		</div>
 33   	</div>
 34   </footer>
 35   <!-- Included JS Files 												-->
 36   <!-- Le javascript 													-->
 37   <!-- ============================================================== -->
 38   <!-- Placed at the end of the document so the pages load faster 	-->
 39   <@coreAdminJSLinks />
 40   ${javascript_files}
 41   </div><!-- Close wrapper -->
 42   </#macro>
 43   <#--
 44   Macro: adminSiteFooter
 45   
 46   Description: Footer for site Admin
 47   Parameters:
 48   - 
 49   -->
 50   <#macro adminSiteFooter >
 51   <#assign siteFooter = .get_optional_template('../../../../../skin/site/portal_footer.html')>
 52   <#if siteFooter.exists><@siteFooter.include /></#if>
 53   <!-- A modal dialog containing a form -->
 54   <dialog id="addPortletDialog" class="lutece-dialog" aria-labelledby="portletModalLabel" aria-hidden="true" tabindex="-1">
 55       <div class="lutece-dialog lutece-dialog-fullscreen">
 56           <div class="lutece-dialog-content">
 57               <div class="lutece-dialog-header">
 58                   <h2 class="lutece-dialog-title h4 text-dark" id="portletModalLabel">#i18n{portal.site.portletType.labelCreate}</h2>
 59                   <button type="button" class="btn btn-link btn-cancel text-dark" aria-label="#i18n{portal.util.labelCancel}"><@icon style="x"/></button>
 60               </div>
 61               <div class="lutece-dialog-body">
 62                       <form action="jsp/admin/DoCreatePortlet.jsp" type="get">
 63                       <div class="container">
 64                           <div id='portlet_type_id' class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4"></div>
 65                       </div>
 66                       <div class="d-flex justify-content-center">
 67                           <button type="button" class="btn btn-secondary btn-cancel" value="cancel" >
 68                           <svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-x"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg> #i18n{portal.util.labelClose}</button>
 69                       </div>
 70                       </form>
 71                   </div>
 72               <div>
 73           </div>
 74       </div>
 75   </div>
 76   </dialog>
 77   <script type="module">
 78   document.addEventListener( "DOMContentLoaded", function(){
 79       const parentPortletTypeNodes = window.parent.document.querySelectorAll( '#offcanvas-body-portlet-type-wrapper ul li' );
 80       const dialogPortletTypes = document.getElementById( 'portlet_type_id' );
 81       const portletDialog = document.querySelector( '#addPortletDialog' );
 82   
 83       parentPortletTypeNodes.forEach( ( item ) => {
 84           const divType = document.createElement('div')
 85           divType.classList.add('col')
 86           const aType = document.createElement('a')
 87           aType.classList.add('btn', 'btn-secondary', 'btn-lg', 'btn-block', 'btn-new-portlet', 'py-5', 'px-0' , 'my-3', 'd-flex', 'align-items-center' )
 88           aType.setAttribute( 'href', item.dataset.portletTypeHref )
 89           const spanType = document.createElement('span')
 90           spanType.classList.add( 'px-2', 'text-left', 'truncate' )
 91           spanType.innerText = item.dataset.portletTypeName
 92           const iconType = document.createElement('i')
 93           iconType.classList.add('ti', <#noparse>`ti-${item.dataset.portletTypeIcon}`</#noparse> ,'fs-1','d-block','ps-2','pl-2')
 94           aType.appendChild( iconType );
 95           aType.appendChild( spanType );
 96           divType.appendChild( aType );
 97           dialogPortletTypes.appendChild( divType );
 98       })
 99   
 100       // 
 101       const columnList = document.querySelectorAll( '.lutece-admin-column' );
 102       columnList.forEach( ( col ) => {
 103           const colOutList = col.querySelectorAll( '.lutece-admin-column-outline' );
 104           colOutList.forEach( ( colOut ) => { 
 105               if( colOut.textContent.trim() === '' ){
 106                   colOut.textContent= '';
 107               }
 108           })
 109       })
 110   
 111       // "Show the dialog" button opens the <dialog> modally
 112       const btnPortletList = document.querySelectorAll( '[data-bs-toggle="modal"]' );
 113       btnPortletList.forEach( ( btnPortlet ) => {
 114           btnPortlet.addEventListener( 'click', ( event ) => {
 115               const portlet = event.currentTarget
 116               const portletColumn = portlet.dataset.portletColumn
 117               let portletOrder = portlet.dataset.portletOrder
 118               if( portletOrder === '' ){
 119                   const lastPortlet = document.querySelector(<#noparse>`#lutece-column-${portletColumn} .lutece-admin-column-outline .lutece-admin-portlet:last-child .lutece-admin-toolbar</#noparse>`)
 120                   if( lastPortlet != null ){
 121                       portletOrder = parseInt( document.querySelector(<#noparse>`#lutece-column-${portletColumn} .lutece-admin-column-outline .lutece-admin-portlet:last-child .lutece-admin-toolbar</#noparse>`).dataset.portletOrder ) + 1
 122                   } else {
 123                       portletOrder = 1
 124                   }
 125               }
 126               dialogPortletTypes.childNodes.forEach( ( item ) => {
 127                   let itemLnk = item.firstElementChild;
 128                   let itemHref = itemLnk.getAttribute('href');
 129                   <#noparse>itemLnk.setAttribute('href',`${itemHref}&portlet_column=${portletColumn}&portlet_order=${portletOrder}`)</#noparse>
 130               })  
 131               portletDialog.showModal()
 132           })
 133       })
 134   
 135       const btnCloseDialogList = document.querySelectorAll( '.btn-cancel' );
 136       btnCloseDialogList.forEach( ( btnCloseDialog ) => {
 137           btnCloseDialog.addEventListener( 'click', ( event ) => {
 138               portletDialog.close()
 139           })
 140       })
 141   
 142   }); 
 143   
 144   import {
 145       LuteceDraggable
 146   } from './themes/shared/modules/luteceDraggable.js';
 147   
 148   const root = document.querySelector(":root");
 149   root.style.setProperty("--column-empty-text", `"#i18n{portal.site.portletType.labelCreateColumn}"`);
 150   
 151   const containers = document.querySelectorAll('#main .lutece-admin-column-outline');
 152   const draggables = Array.from(containers).flatMap(container => [...container.children]);
 153   const AdminHomeDraggable = new LuteceDraggable( draggables, containers);
 154   
 155   async function updatePortlet( portletId, col, order ){
 156   <#noparse>const response = await fetch( `jsp/admin/site/DoModifyPortletPosition.jsp?portlet_id=${portletId}&column=${col}&order=${order}` );</#noparse>
 157   }
 158    
 159   AdminHomeDraggable.on('dragstart', (event) => {
 160      root.style.setProperty( "--column-empty-text", `"Drop moi ici !"` );
 161   });
 162    
 163   AdminHomeDraggable.on('dragover', (event) => {
 164       //event.currentTarget.style.setProperty( "opacity", ".5" );
 165   });
 166    
 167   AdminHomeDraggable.on( 'dragend', (event) => {
 168       root.style.setProperty("--column-empty-text", `"#i18n{portal.site.portletType.labelCreateColumn}"`);
 169       const dragContainer = event.target.closest( '.lutece-draggable-container' );
 170       const newCol = dragContainer.dataset.portletColumn;
 171       const portletId = event.currentTarget.firstElementChild.dataset.portletId
 172       let newOrder= 1
 173   	if ( event.currentTarget.nextSibling != null ){
 174   		newOrder = parseInt( event.currentTarget.nextSibling.firstElementChild.dataset.portletOrder )
 175   		if( newOrder > 1 ){ newOrder-- }
 176   	} else if ( event.currentTarget.previousSibling != null ){
 177   		newOrder = parseInt( event.currentTarget.previousSibling.previousSibling.firstElementChild.dataset.portletOrder )
 178   		newOrder++
 179       }
 180   
 181   	event.currentTarget.firstElementChild.firstElementChild.textContent = newOrder
 182   	event.currentTarget.firstElementChild.firstElementChild.dataset.portletOrder = newOrder
 183   	event.currentTarget.firstElementChild.firstElementChild.dataset.portletColumn = newCol
 184   
 185       if( dragContainer.textContent.trim() === '' ){ dragContainer.textContent = '' }
 186   
 187   	updatePortlet( portletId, newCol, newOrder )
 188   }); 
 189   </script> 
 190   </#macro>