templates/app-base.html.twig line 1

Open in your IDE?
  1. {# app-base.html.twig template base di app, include favicon, bootstrap, jquery, al momento non ancora google fonts e fontawesome #}
  2. {% extends "bsjq.html.twig" %}
  3. {% set loadBar = '<div class="w-100 text-center"><div class="spinner-border text-primary" role="status"><span class="sr-only">Caricamento...</span></div></div>' %}
  4. {% block pagejs %}
  5. {# Se l'utente è già loggato, importa la gestione di google del logout #}
  6. {#{% if datiUtente is defined %}
  7. <script nonce="S2GScr1pt" src="https://apis.google.com/js/platform.js" async defer></script>
  8. {% endif %}
  9. {# Fine Google Logout import #}
  10. {% endblock %}
  11. {% block body %}
  12. {# Topbar con logo di app, idealmente presente su qualsiasi pagina di app #}
  13. {#<div id="topbarWrapper" class="w-100 container gx-0 d-flex justify-content-center align-items-center">
  14. <div id="topbar" class="row w-100 justify-content-center align-items-center">#}
  15. <section id="topbarWrapper" class="sticky-top">
  16. <div id="topbar" class="container d-flex justify-content-center align-items-center">
  17. <div class="row w-100 justify-content-center align-items-center">
  18. <div class="col-12 col-md-3 d-flex justify-content-center justify-content-md-start align-items-center">
  19. <a class="navbar-brand text-dark" href="/" title="{{ APPNAME }} v.{{ APPVERSION }}">
  20. <img class="img-fluid" srcset="{{ asset("logo/Scan2Go-Logo-173x40.png")}} 1x {{ asset("logo/Scan2Go-Logo-346x80.png") }} 2x {{ asset("logo/Scan2Go-Logo-691x160.png") }} 3x" src={{ asset("logo/Scan2Go-Logo-173x40.png") }} alt="{{ APPNAME }} Logo">
  21. {#{% include "inc/logo.html.twig" %}{# svg del logo, incluso #}
  22. {#<img class="mr-1" src={{ asset("Scan2Go-Logo-300px.png") }} width="100" height="100" alt="{{ APPNAME }} Favicon">#}
  23. {#{{ APPNAME }}{% if titoloBrand is defined %} {{ titoloBrand }}{% endif %}#}</a>
  24. </div>
  25. {% block menuBlock %}
  26. <nav id="{{ APPNAME }}TopNavBar" class="navbar navbar-expand-lg navbar-light row col-12 col-md-9">
  27. {#<div class="container">#}
  28. <button class="navbar-toggler ml-auto" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
  29. <span class="navbar-toggler-icon "></span>
  30. {# aggiunge campanella notifiche se ce n'è almeno una da leggere #}
  31. {#{% if notifiche is defined and notifiche.daLeggere is defined and notifiche.daLeggere == true %}#}
  32. <i class="fas fa-bell text-warning d-none dispIcoNotif colIcoNotif float-end" id="iconaNotificheMobile"></i>
  33. {#{% endif %}#}
  34. </button>
  35. {% set route_name = app.request.attributes.get('_route') %}{# Per gestire il menu #}
  36. <div class="collapse navbar-collapse justify-content-center" id="navbarSupportedContent">
  37. {% block incmenu %}{% include "inc/app-menu.html.twig" %}{% endblock %}
  38. <div class="my-2 my-lg-0 d-flex flex-direction-column align-items-center justify-content-center">
  39. {% if datiUtente is defined %}
  40. {# Nome Utente - Ruolo - Lingua - Logout #}
  41. {# Soltanto se l'utente è loggato, prepara una navbar supplementare per la scelta del metodo di logout #}
  42. <nav id="logoutNav" class="navbar">
  43. <ul class="navbar-nav mr-auto">
  44. <li class="nav-item dropdown">
  45. <a class="dropdown-toggle nav-profile-link" href="#" id="logoutDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  46. <img class="s2g_icona ps-1 pe-1 pe-lg-3 s2g_icona_User" src="{{ asset("images/Scan2Go-User.png") }}" srcset="{{ asset("images/Scan2Go-User.png") }} 1x, {{ asset("images/Scan2Go-User2x.png") }} 2x" alt="{% trans %}Utente{% endtrans %}">
  47. {% if datiUtente['nomeutente'] is defined %} {# Se il nome utente è stato passato #}
  48. Utente
  49. {% endif %}
  50. {#{% if notifiche is defined and notifiche.daLeggere is defined and notifiche.daLeggere == true %}#}
  51. <i class="fas fa-bell text-warning d-none dispIcoNotif colIcoNotif ms-1" id="iconaNotifiche"></i>
  52. {#{% endif %}#}
  53. </a>
  54. <div class="dropdown-menu" aria-labelledby="logoutDropdown">
  55. <div class="d-flex justify-content-center">
  56. <span class="dropdown-item-text my-0 small badge bg-info" title="{{ datiUtente['nomeutentecompleto'] }}">{{ datiUtente['nomeutente']|u.split(' ')[0] }}</span>
  57. </div>
  58. <hr class="dropdown-divider">
  59. <a id="btnModalNotifiche" class="dropdown-item small"><i class="fas fa-bell iconaNotifiche colIcoNotif float-end"></i>{% trans %}Notifiche{% endtrans %}</a>
  60. {% if (is_granted('ROLE_ADMIN')) %}
  61. <a class="dropdown-item small" href="/admin">{% trans %}Impostazioni Sistema{% endtrans %}</a>
  62. <hr class="dropdown-divider">
  63. {% else %}
  64. {% endif %}
  65. <span class="dropdown-item-text my-0 small" href="#">{% trans %}Esci da...{% endtrans %}</span>
  66. <a class="dropdown-item small" href="/logout">{{ APPNAME }}</a>
  67. <a id="logoutGsuite"class="dropdown-item small" href="https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=https://{{ APPDOMAIN }}/logout">{{ APPNAME }} e GSuite</a>
  68. </div>
  69. </li>
  70. </ul>
  71. </nav>
  72. {% else %}
  73. <a href="/login/google" class="nav-link" title="{{ APPNAME }} login">{% trans %}Login{% endtrans %}</a>
  74. {% endif %}
  75. </div>
  76. </div>
  77. {#</div>#}{# /container #}
  78. </nav>
  79. {% endblock %}
  80. </div>
  81. </div>
  82. </section>
  83. {# Logo di Istituto #}
  84. {# Moduli #}
  85. {% block moduli %}
  86. <div class="container">
  87. <div class="row justify-content-center">
  88. {# #}
  89. </div>
  90. </div>
  91. {% endblock %}
  92. {# Modale per notifiche #}
  93. <div id="notificationModal" class="modal" tabindex="-1">
  94. <div class="modal-dialog modal-xl modal-fullscreen-sm-down">
  95. <div class="modal-content">
  96. <div class="modal-header">
  97. <h5 class="modal-title">{% trans %}Notifiche{% endtrans %}</h5>
  98. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  99. </div>
  100. <div class="modal-body">
  101. {{ loadBar|raw }}
  102. </div>
  103. <div class="modal-footer">
  104. <button id="btnAltreNotifiche" type="button" class="btn btn-primary w-100">Carica Altre...</button>
  105. </div>
  106. </div>
  107. </div>
  108. </div>
  109. {# FINE Modale per notifiche #}
  110. {# Modale per servizi (stampa etc) #}
  111. <div id="serviceModal" class="modal" tabindex="-1">
  112. <div class="modal-dialog modal-xl modal-fullscreen-sm-down">
  113. <div class="modal-content">
  114. <div class="modal-header">
  115. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  116. </div>
  117. <div class="modal-body">
  118. {{ loadBar|raw }}
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. {# FINE Modale per notifiche #}
  124. {# Aggiunta a fine Body, esterna ai moduli #}
  125. {% block aggiuntaFineBody %}{% endblock %}
  126. {# Porzione col footer pubblico #}
  127. {% include 'inc/public-footer.html.twig' %}
  128. {# /Porzione col footer pubblico #}
  129. {# chiusura body #}
  130. {% endblock %}
  131. {# Parte con il javascript utile di pagina #}
  132. {% block tailjs %}
  133. {% if datiUtente is defined and datiUtente is not null %}
  134. {# javascript notifiche #}
  135. var notificationModal = new bootstrap.Modal(document.getElementById('notificationModal'));
  136. {% include('js/notification.js.twig') %}
  137. {# javascript serviceModal #}
  138. var serviceModal = new bootstrap.Modal(document.getElementById('serviceModal'));
  139. {# Inclusione delle funzioni se l'utente ha ruolo >= admin #}
  140. {% if (is_granted('ROLE_ADMIN')) %}
  141. {# #}
  142. {% endif %}
  143. {# fine parte utente ha ruolo >= admin #}
  144. {# Definizioni trigger per funzionalità e funzione utente normale #}
  145. var freeAjax = true; {# definisco un check di controllo globale sulle funzioni ajax, va in false quando c'è un ajax in corso #}
  146. var triggersAccordion = {
  147. {% if bookmarks is defined and bookmarks|length > 0 %}
  148. 'apertoBook' : true, {# definisco un check di controllo sui Bookmarks, caso in cui i bookmarks sono preaperti #}
  149. {% else %}
  150. 'apertoBook' : false, {# definisco un check di controllo sui Bookmarks, caso in cui i bookmarks sono chiusi #}
  151. {% endif %}
  152. 'apertoBookMan' : false, {# definisco un check di controllo sul Manager Bookmarks #}
  153. 'apertoCPVLAN' : false, {# definisco un check di controllo sul Captive Portal VLAN manager #}
  154. 'apertoMT' : false, {# definisco un check di controllo sul Manager #}
  155. 'apertoDNS' : false,{# definisco un check di controllo sul Manager DNS #}
  156. 'apertoTask' : false{# definisco un check di controllo sul Task Scheduler #}
  157. };
  158. function turnOffTriggersExcept(trigger){ {# Funzione per mettere true sul trigger dell'accordion che si apre e false su tutti gli altri #}
  159. $.each(triggersAccordion,function(key,value){
  160. if(key != trigger){
  161. triggersAccordion[key] = false;
  162. }
  163. else {
  164. triggersAccordion[key] = true;
  165. }
  166. });
  167. return true;
  168. }
  169. {# Session ping per verifica validità sessione Utente #}
  170. function appSessionPing(){
  171. $.ajax({
  172. url:'/ajax/appSessionPing',
  173. type: "POST",
  174. dataType: "json",
  175. success: function(data){
  176. console.log("Session Ping Ok");
  177. return true;
  178. },
  179. error: function(data){
  180. console.log("sessione scaduta");
  181. if ( confirm('La sessione di {{ APPNAME }} è scaduta, al prossimo click dovrai rieffettuare il login.') ){
  182. location.reload();
  183. } else {
  184. //
  185. }
  186. return false;
  187. }
  188. });
  189. }
  190. {# Funzione per popolare l'anno #}
  191. function setCopyrightYear(){
  192. let thisYear = new Date().getFullYear();
  193. document.getElementById('copyrightYear').textContent = thisYear;
  194. return true;
  195. }
  196. {# /Funzione per popolare l'anno #}
  197. {% if (is_granted('ROLE_OPERATORE')) %}
  198. {# #}
  199. {% endif %}
  200. {# Nel caso in cui l'url includa il path /archive/ includo anche il seguente template javascript twig #}
  201. {% if '/archive' in app.request.uri %}
  202. {% include 'js/searchEnvironment.js.twig' %}
  203. console.log('Incluso searchEnvironment.js.twig per l\'ambiente di ricerca');
  204. $(function () {
  205. searchEnvironment.init();
  206. searchEnvironment.fetchData().then((data) => {
  207. console.log('Dati di ricerca caricati con successo:', data);
  208. }).catch((error) => {
  209. console.error('Errore nel caricamento dei dati di ricerca:', error);
  210. });
  211. });
  212. {% else %}
  213. console.log('Non incluso searchEnvironment.js.twig per l\'ambiente di ricerca');
  214. console.log ('{{ app.request.uri }}');
  215. {% endif %}
  216. {# Inizializzo l'ambiente di ricerca #}
  217. {# INIZIO DOCUMENT READY #}
  218. $(function () { //apertura document ready
  219. {% if datiUtente['nomeutentecompleto'] is defined %}
  220. $('#showUsername').tooltip();
  221. {# SESSION PING COUNTER #}
  222. var sessiontime = 1450; //il controllo parte 10 secondi dopo la scadenza della sessione
  223. var sessionpingid = setInterval(function() {
  224. sessiontime = sessiontime - 30;
  225. if(sessiontime > 0){
  226. {% if APPDEBUG is defined and APPDEBUG %}console.log('{{ APPNAME }} Session Check tempo residuo '+sessiontime);{% endif %}
  227. }
  228. else {
  229. if(!appSessionPing()){
  230. //alert('La sessione di {{ APPNAME }} è scaduta, al prossimo click dovrai rieffettuare il login.');
  231. }
  232. else {
  233. sessiontime = 1450; //reimposto il contatore all' inizio
  234. {% if APPDEBUG is defined and APPDEBUG %}console.log('{{ APPNAME }} SC verificata, ancora valida, tempo residuo '+sessiontime);{% endif %}
  235. }
  236. }
  237. }, 30 * 1000); // 60 * 1000 milsec
  238. {# FINE PARTE SESSION PING COUNTER #}
  239. {% endif %}
  240. {# Fine funzione per il signout di google dall'applicativo #}
  241. {# Inizializzazione Popovers #}
  242. var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
  243. var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
  244. return new bootstrap.Popover(popoverTriggerEl), { trigger:'focus' }
  245. });
  246. {# Fine inizializzazione Popovers #}
  247. setCopyrightYear();
  248. });
  249. {# FINE DOCUMENT READY #}
  250. {# INIZIO AJAXCOMPLETE Dopo il completamento qualsiasi chiamata AJAX viene eseguito questo ciclo di funzioni, prettamente il refresh degli event listeners #}
  251. $( document ).ajaxComplete(function() {
  252. freeAjax=true; {# Visto che la chiamata Ajax precedente è conclusa, rilibero il check ajax #}
  253. {# #}
  254. });
  255. {# Fine ciclo funzioni post chiamata Ajax #}
  256. {% endif %}
  257. {% block addtailjs %}{% endblock %}
  258. {% endblock %}