layout.html.twig 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. {# layout.html.twig #}
  2. {# Base layout #}
  3. {% if app['combodo.current_user'] is defined and app['combodo.current_user'] is not null %}
  4. {% set bUserConnected = true %}
  5. {% set sUserFullname = app['combodo.current_user'].Get('first_name') ~ ' ' ~ app['combodo.current_user'].Get('last_name') %}
  6. {% set sUserEmail = app['combodo.current_user'].Get('email') %}
  7. {% set sUserPhotoUrl = app['combodo.current_contact.photo_url'] %}
  8. {% else %}
  9. {% set bUserConnected = false %}
  10. {% set sUserFullname = '' %}
  11. {% set sUserEmail = '' %}
  12. {% set sUserPhotoUrl = app['combodo.portal.base.absolute_url'] ~ 'img/user-profile-default-256px.png' %}
  13. {% endif %}
  14. <!doctype html>
  15. <html>
  16. <head>
  17. <meta charset="utf-8">
  18. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  19. <meta name="viewport" content="width=device-width, initial-scale=1">
  20. {# This block can be used to add your own meta tags by extending the default template #}
  21. {% block pPageExtraMetas %}
  22. {% endblock %}
  23. <title>{% block pPageTitle %}{% if sPageTitle is defined and sPageTitle is not null %}{{ sPageTitle }} - {{ constant('ITOP_APPLICATION') }}{% else %}{{ 'Page:DefaultTitle'|dict_s }}{% endif %}{% endblock %}</title>
  24. <link rel="shortcut icon" href="{{ app['combodo.absolute_url'] ~ 'images/favicon.ico'|add_itop_version }}" />
  25. {% block pPageStylesheets %}
  26. {# First bootstrap core, lib themes, then bootstrap theme, portal adjustements #}
  27. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/bootstrap/css/bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  28. {# - Bootstrap Datetime picker #}
  29. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css'|add_itop_version }}" rel="stylesheet">
  30. {# - Datatables #}
  31. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/dataTables.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  32. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/fixedHeader.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  33. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/responsive.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  34. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/scroller.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  35. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/select.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
  36. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/select.dataTables.min.css'|add_itop_version }}" rel="stylesheet">
  37. {# - Font Combodo #}
  38. <link href="{{ app['combodo.absolute_url'] ~ 'css/font-combodo/font-combodo.css'|add_itop_version }}" rel="stylesheet">
  39. {# - Font awesome #}
  40. <link href="{{ app['combodo.absolute_url'] ~ 'css/font-awesome/css/font-awesome.min.css'|add_itop_version }}" rel="stylesheet">
  41. {# - Misc libs #}
  42. <link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/css/typeaheadjs.bootstrap.css'|add_itop_version }}" rel="stylesheet">
  43. <link href="{{ app['combodo.absolute_url'] ~ 'css/magnific-popup.css'|add_itop_version }}" rel="stylesheet">
  44. {# - Bootstrap theme #}
  45. <link href="{{ app['combodo.portal.instance.conf'].properties.themes.bootstrap|add_itop_version }}" rel="stylesheet" id="css_bootstrap_theme">
  46. {# - Portal adjustments for BS theme #}
  47. <link href="{{ app['combodo.portal.instance.conf'].properties.themes.portal|add_itop_version }}" rel="stylesheet" id="css_portal">
  48. {# Custom CSS that is supposed to do adjustments to the portal #}
  49. {% if app['combodo.portal.instance.conf'].properties.themes.custom is defined %}
  50. <link href="{{ app['combodo.portal.instance.conf'].properties.themes.custom|add_itop_version }}" rel="stylesheet">
  51. {% endif %}
  52. {# Others CSS that will come after the theme/portal/custom, in an undefined order #}
  53. {% if app['combodo.portal.instance.conf'].properties.themes.others is defined %}
  54. {% for theme in app['combodo.portal.instance.conf'].properties.themes.others %}
  55. <link href="{{ theme|add_itop_version }}" rel="stylesheet">
  56. {% endfor %}
  57. {% endif %}
  58. {% endblock %}
  59. {% block pPageScripts %}
  60. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/jquery/jquery-1.11.3.min.js'|add_itop_version }}"></script>
  61. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/jquery-ui/jquery-ui-1.11.4.min.js'|add_itop_version }}"></script>
  62. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/jquery.magnific-popup.min.js'|add_itop_version }}"></script>
  63. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/jquery.iframe-transport.js'|add_itop_version }}"></script>
  64. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/jquery.fileupload.js'|add_itop_version }}"></script>
  65. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/bootstrap/js/bootstrap.min.js'|add_itop_version }}"></script>
  66. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/latinise/latinise.min.js'|add_itop_version }}"></script>
  67. {# Visible.js to check if an element is visible on screen #}
  68. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/jquery-visible/js/jquery.visible.min.js'|add_itop_version }}"></script>
  69. {# Base64.js #}
  70. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/jquery-base64/js/jquery.base64.min.js'|add_itop_version }}"></script>
  71. {# Moment.js #}
  72. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/moment/js/moment.min.js'|add_itop_version }}"></script>
  73. {# Datatables #}
  74. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/jquery.dataTables.min.js'|add_itop_version }}"></script>
  75. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/dataTables.bootstrap.min.js'|add_itop_version }}"></script>
  76. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/dataTables.fixedHeader.min.js'|add_itop_version }}"></script>
  77. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/dataTables.responsive.min.js'|add_itop_version }}"></script>
  78. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/dataTables.scroller.min.js'|add_itop_version }}"></script>
  79. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/dataTables.select.min.js'|add_itop_version }}"></script>
  80. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/js/datetime-moment.js'|add_itop_version }}"></script>
  81. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'js/dataTables.accentNeutraliseForFilter.js'|add_itop_version }}"></script>
  82. {# CKEditor files for HTML WYSIWYG #}
  83. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/ckeditor/ckeditor.js'|add_itop_version }}"></script>
  84. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/ckeditor/adapters/jquery.js'|add_itop_version }}"></script>
  85. {# Date-time picker for Bootstrap #}
  86. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js'|add_itop_version }}"></script>
  87. {# Typeahead files for autocomplete #}
  88. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/bloodhound.min.js'|add_itop_version }}"></script>
  89. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/typeahead.bundle.min.js'|add_itop_version }}"></script>
  90. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/typeahead.jquery.min.js'|add_itop_version }}"></script>
  91. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/handlebars/js/handlebars.min-768ddbd.js'|add_itop_version }}"></script>
  92. {# Form files #}
  93. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/form_handler.js'|add_itop_version }}"></script>
  94. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/form_field.js'|add_itop_version }}"></script>
  95. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/subform_field.js'|add_itop_version }}"></script>
  96. <script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/field_set.js'|add_itop_version }}"></script>
  97. {# Form files for portal #}
  98. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'js/portal_form_handler.js'|add_itop_version }}"></script>
  99. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'js/portal_form_field.js'|add_itop_version }}"></script>
  100. <script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'js/portal_form_field_html.js'|add_itop_version }}"></script>
  101. {% endblock %}
  102. </head>
  103. <body class="{% block pPageBodyClass %}{% endblock %}">
  104. {% block pPageBodyWrapper %}
  105. {% block pEnvBannerWrapper %}
  106. {% if app['combodo.current_environment'] != 'production' %}
  107. <div id="envbanner" class="alert alert-danger" role="alert">
  108. {{ 'Portal:EnvironmentBanner:Title'|dict_format( app['combodo.current_environment']|upper )|raw }}
  109. <button type="button" onclick="window;location.href='{{ app['url_generator'].generate('p_home', {'switch_env': 'production'}) }}'">
  110. {{ 'Portal:EnvironmentBanner:GoToProduction'|dict_s|raw }}
  111. </button>
  112. </div>
  113. {% endif %}
  114. {% endblock %}
  115. {% block pNavigationWrapper %}
  116. {# Topbar navigation menu for mobile screens #}
  117. {% block pNavigationTopMenuWrapper %}
  118. <nav class="navbar navbar-fixed-top navbar-default visible-xs" id="topbar" role="navigation">
  119. <div class="container-fluid">
  120. <div class="navbar-header">
  121. <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
  122. <span class="icon-bar"></span>
  123. <span class="icon-bar"></span>
  124. <span class="icon-bar"></span>
  125. </button>
  126. <a class="navbar-brand pull-right" href="{{ app.url_generator.generate('p_home') }}">
  127. {% if app['combodo.portal.instance.conf'].properties.logo is not null %}
  128. <img src="{{ app['combodo.portal.instance.conf'].properties.logo }}" alt="{{ app['combodo.portal.instance.conf'].properties.name|dict_s }}" />
  129. {% else %}
  130. iTop
  131. {% endif %}
  132. </a>
  133. <p class="navbar-text">
  134. <a class="navbar-link user_infos" href="{{ app.url_generator.generate('p_user_profile_brick') }}">
  135. <span class="user_photo" style="background-image: url('{{ sUserPhotoUrl }}');"></span>
  136. <span class="user_fullname">{{ sUserFullname }}</span>
  137. </a>
  138. </p>
  139. </div>
  140. <div class="collapse navbar-collapse" id="navbar">
  141. <ul class="nav navbar-nav">
  142. {% block pNavigationTopBricks %}
  143. <li class="{% if oBrick is not defined %}active{% endif %}">
  144. <a href="{{ app.url_generator.generate('p_home') }}">
  145. <span class="brick_icon fa fa-home fa-2x"></span>
  146. {{ 'Page:Home'|dict_s }}
  147. </a>
  148. </li>
  149. {% for brick in app['combodo.portal.instance.conf'].bricks_ordering.navigation_menu %}
  150. {% if brick.GetActive and brick.GetVisibleNavigationMenu and brick.GetRouteName is not null %}
  151. <li class="{% if oBrick is defined and brick.id == oBrick.id %}active{% endif %}">
  152. <a href="{{ app.url_generator.generate(brick.GetRouteName, {sBrickId: brick.GetId}) }}{% if app['combodo.portal.instance.routes'][brick.GetRouteName]['hash'] is defined %}#{{ app['combodo.portal.instance.routes'][brick.GetRouteName]['hash'] }}{% endif %}" {% if app['combodo.portal.instance.routes'][brick.GetRouteName]['navigation_menu_attr'] is defined %}{% for key, value in app['combodo.portal.instance.routes'][brick.GetRouteName]['navigation_menu_attr'] %} {{ key }}="{{ value }}"{% endfor %}{% endif %} {% if brick.GetModal %}data-toggle="modal" data-target="#modal-for-all"{% endif %}>
  153. <span class="brick_icon {{ brick.GetDecorationClassNavigationMenu }}"></span>
  154. {{ brick.GetTitleNavigationMenu|dict_s }}
  155. </a>
  156. </li>
  157. {% endif %}
  158. {% endfor %}
  159. {% endblock %}
  160. {% if bUserConnected %}
  161. <li role="separator" class="divider"></li>
  162. <li><a href="{{ app.url_generator.generate('p_user_profile_brick') }}"><span class="brick_icon fa fa-user fa-2x fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil'|dict_s }}</a></li>
  163. {% for aPortal in app['combodo.portal.instance.conf'].portals %}
  164. {% if aPortal.id != app['combodo.portal.instance.conf'].properties.id %}
  165. {% set sIconClass = (aPortal.id == 'backoffice') ? 'fa-list-alt' : 'fa-external-link' %}
  166. <li><a href="{{ aPortal.url }}" target="_blank"><span class="brick_icon fa {{ sIconClass }} fa-2x fa-fw"></span>{{ aPortal.label|dict_s }}</a></li>
  167. {% endif %}
  168. {% endfor %}
  169. {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
  170. {% if app['combodo.portal.instance.conf'].portals|length > 1 %}
  171. <li role="separator" class="divider"></li>
  172. {% endif %}
  173. <li><a href="{{ app['combodo.absolute_url'] }}pages/logoff.php"><span class="brick_icon fa fa-sign-out fa-2x fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}</a></li>
  174. {% endif %}
  175. </ul>
  176. </div>
  177. </div>
  178. </nav>
  179. {% endblock %}
  180. {# Sidebar navigation menu for normal screens #}
  181. {% block pNavigationSideMenuWrapper %}
  182. <nav class="navbar-default hidden-xs col-sm-3 col-md-2" id="sidebar" role="navigation">
  183. <div class="user_card bg-primary">
  184. <div class="user_photo" style="background-image: url('{{ sUserPhotoUrl }}');">
  185. </div>
  186. <div class="user_infos">
  187. <div class="user_fullname">{{ sUserFullname }}</div>
  188. <div class="user_email dropdown">
  189. <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="user_options">
  190. {{ sUserEmail }}
  191. <span class="caret"></span>
  192. </a>
  193. <ul class="dropdown-menu user_options" aria-labelledby="user_options">
  194. <li><a href="{{ app.url_generator.generate('p_user_profile_brick') }}"><span class="brick_icon fa fa-user fa-lg fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil'|dict_s }}</a></li>
  195. {% for aPortal in app['combodo.portal.instance.conf'].portals %}
  196. {% if aPortal.id != app['combodo.portal.instance.conf'].properties.id %}
  197. {% set sGlyphiconClass = (aPortal.id == 'backoffice') ? 'fa-list-alt' : 'fa-external-link' %}
  198. <li><a href="{{ aPortal.url }}" {% if app['combodo.portal.instance.conf'].properties.allowed_portals.opening_mode == 'tab' %}target="_blank"{% endif %} title="{{ aPortal.label|dict_s }}"><span class="brick_icon fa {{ sGlyphiconClass }} fa-lg fa-fw"></span>{{ aPortal.label|dict_s }}</a></li>
  199. {% endif %}
  200. {% endfor %}
  201. {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
  202. {% if app['combodo.portal.instance.conf'].portals|length > 1 %}
  203. <li role="separator" class="divider"></li>
  204. {% endif %}
  205. <li><a href="{{ app['combodo.absolute_url'] }}pages/logoff.php"><span class="brick_icon fa fa-sign-out fa-lg fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}</a></li>
  206. </ul>
  207. </div>
  208. </div>
  209. </div>
  210. <div class="menu">
  211. {% block pNavigationSideMenu %}
  212. <ul class="nav navbar-nav">
  213. <li class="{% if oBrick is not defined %}active{% endif %}">
  214. <a href="{{ app.url_generator.generate('p_home') }}">
  215. <span class="brick_icon fa fa-home fa-2x"></span>
  216. {{ 'Page:Home'|dict_s }}
  217. </a>
  218. </li>
  219. {% for brick in app['combodo.portal.instance.conf'].bricks_ordering.navigation_menu %}
  220. {% if brick.GetActive and brick.GetVisibleNavigationMenu and brick.GetRouteName is not null %}
  221. <li class="{% if oBrick is defined and brick.id == oBrick.id %}active{% endif %}">
  222. <a href="{{ app.url_generator.generate(brick.GetRouteName, {sBrickId: brick.GetId}) }}{% if app['combodo.portal.instance.routes'][brick.GetRouteName]['hash'] is defined %}#{{ app['combodo.portal.instance.routes'][brick.GetRouteName]['hash'] }}{% endif %}" {% if app['combodo.portal.instance.routes'][brick.GetRouteName]['navigation_menu_attr'] is defined %}{% for key, value in app['combodo.portal.instance.routes'][brick.GetRouteName]['navigation_menu_attr'] %} {{ key }}="{{ value }}"{% endfor %}{% endif %} {% if brick.GetModal %}data-toggle="modal" data-target="#modal-for-all"{% endif %}>
  223. <span class="brick_icon {{ brick.GetDecorationClassNavigationMenu }}"></span>
  224. {{ brick.GetTitleNavigationMenu|dict_s }}
  225. </a>
  226. </li>
  227. {% endif %}
  228. {% endfor %}
  229. </ul>
  230. {% endblock %}
  231. </div>
  232. {% if app['combodo.portal.instance.conf'].properties.logo is not null %}
  233. <div class="logo">
  234. {# This is a debug helper to know in which screen size we are #}
  235. {% if app['debug'] %}
  236. <div style="position: fixed; bottom: 0px; left: 0px; z-index: 9999;">Debug : Taille <span class="hidden-sm hidden-md hidden-lg">XS</span><span class="hidden-xs hidden-md hidden-lg">SM</span><span class="hidden-xs hidden-sm hidden-lg">MD</span><span class="hidden-xs hidden-sm hidden-md">LG</span></div>
  237. {% endif %}
  238. <a href="{{ app.url_generator.generate('p_home') }}" title="{{ app['combodo.portal.instance.conf'].properties.name|dict_s }}">
  239. <img src="{{ app['combodo.portal.instance.conf'].properties.logo }}" alt="{{ app['combodo.portal.instance.conf'].properties.name|dict_s }}" />
  240. </a>
  241. </div>
  242. {% endif %}
  243. </nav>
  244. {% endblock %}
  245. {% endblock %}
  246. {% block pMainWrapper %}
  247. <div class="container-fluid" id="main-wrapper">
  248. <div class="row">
  249. <div class="col-xs-12 col-sm-9 col-md-10 col-sm-offset-3 col-md-offset-2">
  250. <section class="row" id="main-header">
  251. {% block pMainHeader %}
  252. {% endblock %}
  253. </section>
  254. <section class="row" id="main-content">
  255. {% block pMainContent %}
  256. {% endblock %}
  257. </section>
  258. </div>
  259. </div>
  260. </div>
  261. {% endblock %}
  262. <footer id="footer-wrapper">
  263. {% block pPageFooter%}
  264. <a href="http://www.combodo.com">iTop &copy; {{ "now"|date('Y') }}</a>
  265. {% endblock %}
  266. </footer>
  267. {% block pModalForAllWrapper %}
  268. <div class="modal fade" id="modal-for-all" role="dialog">
  269. <div class="modal-dialog modal-lg" role="document">
  270. <div class="modal-content">
  271. {% include 'itop-portal-base/portal/src/views/helpers/loader.html.twig' %}
  272. </div>
  273. </div>
  274. </div>
  275. {% endblock %}
  276. {% block pModalForAlert %}
  277. <div class="modal fade" id="modal-for-alert" role="dialog">
  278. <div class="modal-dialog" role="document">
  279. <div class="modal-content">
  280. <div class="modal-header">
  281. <button type="button" class="close" data-dismiss="modal" aria-label="{{ 'Portal:Button:Close'|dict_s }}"><span aria-hidden="true">&times;</span></button>
  282. <h4 class="modal-title"></h4>
  283. </div>
  284. <div class="modal-body">
  285. <div class="alert">
  286. </div>
  287. <div class="text-right">
  288. <button type="button" class="btn btn-primary" data-dismiss="modal">{{ 'Portal:Button:Close'|dict_s }}</button>
  289. </div>
  290. </div>
  291. </div>
  292. </div>
  293. </div>
  294. {% endblock %}
  295. {% block pPageOverlay %}
  296. <div id="page_overlay" class="global_overlay">
  297. <div class="overlay_content">
  298. {% include 'itop-portal-base/portal/src/views/helpers/loader.html.twig' %}
  299. </div>
  300. </div>
  301. {% endblock %}
  302. {% endblock %}
  303. {% block pPageLiveScripts %}
  304. <script type="text/javascript">
  305. {% block pPageLiveScriptHelpers %}
  306. // Helper to get the application root url
  307. var GetAbsoluteUrlAppRoot = function()
  308. {
  309. return '{{ app['combodo.absolute_url'] }}';
  310. };
  311. // Helper to add a parameter to an url
  312. var AddParameterToUrl = function(sUrl, sParamName, sParamValue)
  313. {
  314. sUrl += (sUrl.split('?')[1] ? '&':'?') + sParamName + '=' + sParamValue;
  315. return sUrl;
  316. };
  317. var GetContentLoaderTemplate = function()
  318. {
  319. return '<div class="content_loader"><div class="icon glyphicon glyphicon-refresh"></div><div class="message">{{ 'Page:PleaseWait'|dict_s }}</div></div>';
  320. }
  321. var ShowLoginDialog = function()
  322. {
  323. var oModalElem = $('#modal-for-alert').clone();
  324. oModalElem.attr('id', '');
  325. oModalElem.find('.modal-content .modal-header .modal-title').html('{{ 'Error:HTTP:401'|dict_s|escape('js') }}');
  326. oModalElem.find('.modal-content .modal-body .alert').addClass('alert-danger').html('{{ 'Portal:ErrorUserLoggedOut'|dict_s|escape('js') }}');
  327. oModalElem.find('.modal-content .modal-body button').replaceWith( $('<button type="button" class="btn btn-primary" onclick="javascript:window.location.reload();">{{ 'UI:LogOff:ClickHereToLoginAgain'|dict_s|escape('js') }}</button>') );
  328. oModalElem.appendTo('body');
  329. oModalElem.modal('show');
  330. };
  331. var ShowErrorDialog = function(sBody, sTitle)
  332. {
  333. if(sTitle === undefined)
  334. {
  335. sTitle = '{{ 'Error:HTTP:500'|dict_s|escape('js') }}';
  336. }
  337. if(sBody === undefined)
  338. {
  339. sBody = '{{ 'Error:XHR:Fail'|dict_s|escape('js') }}';
  340. }
  341. var oModalElem = $('#modal-for-alert');
  342. oModalElem.find('.modal-content .modal-header .modal-title').html(sTitle);
  343. oModalElem.find('.modal-content .modal-body .alert').addClass('alert-danger').html(sBody);
  344. oModalElem.modal('show');
  345. };
  346. {% endblock %}
  347. $(document).ready(function(){
  348. {% block pPageReadyScripts %}
  349. // Hack to enable a same modal to load content from different urls
  350. $('body').on('hidden.bs.modal', '.modal#modal-for-all', function () {
  351. $(this).removeData('bs.modal');
  352. $(this).find('.modal-content').html(GetContentLoaderTemplate());
  353. });
  354. // Hack to enable multiple modals by making sure the .modal-open class is set to the <body> when there is at least one modal open left
  355. $('body').on('hidden.bs.modal', function () {
  356. if($('.modal.in').length > 0)
  357. {
  358. $('body').addClass('modal-open');
  359. }
  360. });
  361. // Hide tooltips when a modal is opening, otherwise it might be overlapping it
  362. $('body').on('show.bs.modal', function () {
  363. $(this).find('.tooltip.in').tooltip('hide');
  364. });
  365. // Display a error message on modal if the content could not be loaded.
  366. // Note : As of now, we can't display a more detailled message based on the response because Bootstrap doesn't pass response data with the loaded event.
  367. $('body').on('loaded.bs.modal', function (oEvent) {
  368. var sModalContent = $(oEvent.target).find('.modal-content').html();
  369. if( (sModalContent === '') || (sModalContent.replace(/[\n\r\t]+/g, '') === GetContentLoaderTemplate()) )
  370. {
  371. $(oEvent.target).modal('hide');
  372. }
  373. });
  374. // Handle AJAX errors (exceptions (500), logout (401), ...)
  375. $(document).ajaxError(function(oEvent, oXHR, oSettings, sError){
  376. if(oXHR.status === 401)
  377. {
  378. ShowLoginDialog();
  379. }
  380. else if(oXHR.status === 404)
  381. {
  382. ShowErrorDialog('{{ 'UI:ObjectDoesNotExist'|dict_s|escape('js') }}', '{{ 'Error:HTTP:404'|dict_s|escape('js') }}');
  383. }
  384. else
  385. {
  386. ShowErrorDialog();
  387. }
  388. });
  389. {% endblock %}
  390. });
  391. </script>
  392. {% endblock %}
  393. </body>
  394. </html>