templates/base.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="UTF-8">
  5.         <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.         <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
  7.         <title>{% block title %}Welcome!{% endblock %}</title>
  8.         <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/favicon/apple-touch-icon.png">
  9.         <link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon/favicon-32x32.png">
  10.         <link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon/favicon-16x16.png">
  11.         <link rel="manifest" href="/assets/images/favicon/site.webmanifest">
  12.         <!-- BEGIN GLOBAL MANDATORY STYLES -->
  13.         <link href="https://fonts.googleapis.com/css?family=Nunito:400,600,700" rel="stylesheet">
  14.         <link href="{{ asset('assets/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css" />
  15.         <link href="{{ asset('assets/css/plugins.css') }}" rel="stylesheet" type="text/css" />
  16.         <link href="{{ asset('assets/plugins/notification/toastr/toastr.min.css') }}" rel="stylesheet" type="text/css" />
  17.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/select2/select2.min.css') }}">
  18.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/flatpickr/flatpickr.css') }}">
  19.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/flatpickr/custom-flatpickr.css') }}">
  20.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/fancybox/fancybox.css') }}"/>
  21.         <!-- END GLOBAL MANDATORY STYLES -->
  22.         <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM STYLES -->
  23.         <link rel="stylesheet" href="{{ asset('assets/css/custom.css') }}">
  24.         {% block stylesheets %}{% endblock %}
  25.         <link rel="stylesheet" media="print" href="{{ asset('assets/css/print.css') }}" />
  26.         <!-- END PAGE LEVEL PLUGINS/CUSTOM STYLES -->
  27.         {% if app.user %}
  28.         <style>
  29.         :root {
  30.             --primary: {{ app.user.company.color }}!important;
  31.             --primary_15l: {{ app.user.company.color }}33!important;/* 0.15 opacity */
  32.             --secondary: {{ app.user.company.color2 }}!important;
  33.         }
  34.         </style>
  35.         {% endif %}
  36.     </head>
  37.     <body class="alt-menu sidebar-noneoverflow {% block bodyClass %}{% endblock %}">
  38.     {% if app.user %}
  39.     {{ include('navbar.html.twig') }}
  40.     <!--  BEGIN MAIN CONTAINER  -->
  41.     <div class="main-container sidebar-closed sbar-open" id="container">
  42.         <div class="overlay"></div>
  43.         <div class="cs-overlay"></div>
  44.         <div class="search-overlay"></div>
  45.         {{ include('sidebar.html.twig') }}
  46.         
  47.         <!--  BEGIN CONTENT AREA  -->
  48.         <div id="content" class="main-content">
  49.             <div class="layout-px-spacing">
  50.                 <div class="page-header">
  51.                     <div class="page-title">
  52.                         <h3>{% block pageHeader %}{% endblock %}</h3>
  53.                     </div>
  54.                 </div>
  55.                 <!-- CONTENT AREA -->
  56.                 
  57.                 {% block pageContent %}{% endblock %}
  58.                 <!-- CONTENT AREA -->
  59.             </div>
  60.         </div>
  61.         <!--  END CONTENT AREA  -->
  62.     </div>
  63.     <!-- END MAIN CONTAINER -->
  64.     {{ include('footer.html.twig')}}
  65.     {% endif %}
  66.     {% block login %}{% endblock %}
  67.     <!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
  68.     <script src="{{ asset('assets/js/libs/jquery-3.1.1.min.js') }}"></script>
  69.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
  70.     <script src="{{ asset('assets/bootstrap/js/popper.min.js') }}"></script>
  71.     <script src="{{ asset('assets/bootstrap/js/bootstrap.min.js') }}"></script>
  72.     <script src="{{ asset('assets/plugins/perfect-scrollbar/perfect-scrollbar.min.js') }}"></script>
  73.     <script src="{{ asset('assets/plugins/notification/toastr/toastr.min.js') }}"></script>
  74.     <script src="{{ asset('assets/plugins/select2/select2.min.js') }}"></script>
  75.     <script src="{{ asset('assets/plugins/flatpickr/flatpickr.js') }}"></script>
  76.     <script src="{{ asset('assets/plugins/flatpickr/fr.js') }}"></script>
  77.     <script src="{{ asset('assets/js/jquery.collection.js') }}"></script>
  78.     <script src="{{ asset('assets/plugins/fancybox/fancybox.umd.js') }}"></script>
  79.     <script src="{{ asset('assets/js/jquery.tagsinput.js') }}"></script>
  80.     <script src="{{ asset('assets/js/app.js') }}"></script>
  81.     <script>
  82.     flatpickr.localize(flatpickr.l10ns.fr);
  83.     toastr.options = {
  84.         "closeButton": true,
  85.         "debug": false,
  86.         "newestOnTop": true,
  87.         "progressBar": true,
  88.         "positionClass": "toast-bottom-left",
  89.         "preventDuplicates": false,
  90.         "onclick": null,
  91.         "showDuration": "300",
  92.         "hideDuration": "1000",
  93.         "timeOut": "10000",
  94.         "extendedTimeOut": "1000",
  95.         "showEasing": "swing",
  96.         "hideEasing": "linear",
  97.         "showMethod": "fadeIn",
  98.         "hideMethod": "fadeOut"
  99.     }
  100.     jQuery(document).ready(function() {
  101.         App.init();
  102.         if ($.fn.DataTable) {
  103.             $('.table-data').DataTable({
  104.                 "select": "true",
  105.                 "aaSorting": [],
  106.                 "oLanguage": {
  107.                     select: {
  108.                         rows: {
  109.                             _: "%d lignes sélectionnées",
  110.                             1: "1 ligne sélectionnée"
  111.                         }
  112.                     },
  113.                     "oPaginate": { "sPrevious": '<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="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<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="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
  114.                     "sInfo": "Page _PAGE_ de _PAGES_",
  115.                     "sSearch": '<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="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
  116.                     "sSearchPlaceholder": "Recherche...",
  117.                     "sLengthMenu": "Résultats :  _MENU_",
  118.                     "sInfo":          "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
  119.                     "sInfoEmpty":     "Affichage de 0 à 0 sur 0 entrées",
  120.                     "sInfoFiltered":  "(filtrées depuis un total de _MAX_ entrées)",
  121.                 },
  122.                 "stripeClasses": [],
  123.             });
  124.             const selectTable = $('.table-data-select').DataTable({
  125.                 "columnDefs": [
  126.                     // These are the column name variables that will be sent to the server
  127.                     { 
  128.                         "name": "id",'targets': 0,
  129.                         'checkboxes': {
  130.                         'selectRow': true,
  131.                         'selectAll': false
  132.                         }  
  133.                     }
  134.                 
  135.                 ],
  136.                 'select': {
  137.                     'style': 'multi'
  138.                 },
  139.                 "oLanguage": {
  140.                     select: {
  141.                         rows: {
  142.                             _: "%d lignes sélectionnées",
  143.                             1: "1 ligne sélectionnée"
  144.                         }
  145.                     },
  146.                     "oPaginate": { "sPrevious": '<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="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<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="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
  147.                     "sInfo": "Page _PAGE_ de _PAGES_",
  148.                     "sSearch": '<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="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
  149.                     "sSearchPlaceholder": "Recherche...",
  150.                     "sLengthMenu": "Résultats :  _MENU_",
  151.                     "sInfo":          "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
  152.                     "sInfoEmpty":     "Affichage de 0 à 0 sur 0 entrées",
  153.                     "sInfoFiltered":  "(filtrées depuis un total de _MAX_ entrées)",
  154.                 },
  155.             });
  156.             
  157.             // Event listener to the filtering select to redraw on change
  158.             $('#content').on('change','.data-filter',function ()  { 
  159.                     selectTable.draw();
  160.             } );
  161.             $('.table-data-select thead input[name="select_all"]').on('click', function (e) {
  162.             var checked = $('#selectall').prop('checked');
  163.                 // get all filtered rows
  164.                 var allRowsCount = selectTable.rows().count()
  165.                 var filteredRowsCount = selectTable.rows({ search: 'applied' }).count();
  166.                 var visibleRowsCount = selectTable.rows({ page: 'current' }).count();
  167.                 //console.log(allRowsCount, filteredRowsCount, visibleRowsCount)
  168.                 var rows = (allRowsCount == filteredRowsCount) ? { page: 'current' } : { search: 'applied' };
  169.                 if (this.checked) {
  170.                     selectTable.rows(rows).select();
  171.                 } else {
  172.                     //selectTable.rows(rows).deselect();
  173.                     selectTable.rows({ selected: true }).deselect();
  174.                 }
  175.             });
  176.             selectTable.on('length.dt', function () {
  177.                 selectTable.rows({ selected: true }).deselect();
  178.                 $('.table-data-select thead input[name="select_all"]').prop('checked', false);
  179.             });
  180.             $('body').on('click', 'a#table-data-select-export', function(e){
  181.                 //alert();
  182.                 var rows_selected = selectTable.column(0).checkboxes.selected();
  183.                 //console.log(rows_selected);
  184.                 if (typeof rows_selected !== 'undefined' && rows_selected.length > 1  && rows_selected.length < 51) {
  185.                     var url = $(this).attr("href");
  186.                     // Iterate over all selected checkboxes
  187.                     $.each(rows_selected, function(index, row){
  188.                         rowId = row.replace(/[^0-9]/g,'');
  189.                         if (url.indexOf('?') === -1) {
  190.                             url = url + '?a[]=' + rowId;  
  191.                         }else {
  192.                             url = url + '&a[]=' + rowId;
  193.                         }
  194.                     });
  195.                     window.open(url, "_blank");
  196.                 } else if (rows_selected.length > 50) {
  197.                     toastr["error"]('Merci de ne pas selectionner plus que 50 documents ... ');
  198.                 } else {
  199.                     toastr["warning"]('Merci de selectionner au moins deux éléments ...');
  200.                 }
  201.                 return false;
  202.                 
  203.             }); 
  204.         }
  205.         $('.emails-tags').tagsInput({
  206.             'unique': true,
  207.             'validationPattern': new RegExp('(.+)@(.+){2,}\.(.+){2,}'),
  208.             'delimiter': [' ']
  209.         });
  210.         
  211.         flatpickr($('.flatpickr'), {
  212.             enableTime: true,
  213.             dateFormat: "Y-m-d H:i",
  214.             disableMobile: "true",
  215.             "locale": {
  216.                 "firstDayOfWeek": 7 // start week on Sunday
  217.             },
  218.             minDate: new Date(),
  219.             allowInput: true,
  220.             onOpen: function(selectedDates, dateStr, instance) {
  221.             $(instance.altInput).prop('readonly', true);
  222.             },
  223.             onClose: function(selectedDates, dateStr, instance) {
  224.                 $(instance.altInput).prop('readonly', false);
  225.                 $(instance.altInput).blur();
  226.             },
  227.             onChange: function(selectedDates, dateStr, instance) {
  228.                 validateInput(dateStr, $('.flatpickr')[0]);
  229.             }
  230.         });
  231.         // Add an additional event listener to the date input field
  232.         $('.flatpickr').on('change', function() {
  233.             validateInput(this.value, $(this)[0]);
  234.         });
  235.         flatpickr($('.flatpickr_date'), {
  236.             enableTime: false,
  237.             dateFormat: "Y-m-d",
  238.             disableMobile: "true",
  239.             "locale": {
  240.                 "firstDayOfWeek": 7 // start week on Sunday
  241.             },
  242.             defaultDate: new Date(),
  243.             allowInput: true,
  244.             onOpen: function(selectedDates, dateStr, instance) {
  245.             $(instance.altInput).prop('readonly', true);
  246.             },
  247.             onClose: function(selectedDates, dateStr, instance) {
  248.                 $(instance.altInput).prop('readonly', false);
  249.                 $(instance.altInput).blur();
  250.             },
  251.             onChange: function(selectedDates, dateStr, instance) {
  252.                 validateInput(dateStr, $('.flatpickr_date')[0]);
  253.             }
  254.         });
  255.         // Add an additional event listener to the date input field
  256.         $('.flatpickr_date').on('change', function() {
  257.             validateInput(this.value, $(this)[0]);
  258.         });
  259.         flatpickr($('.flatpickr_date_nodefault'), {
  260.             enableTime: false,
  261.             dateFormat: "Y-m-d",
  262.             disableMobile: "true",
  263.             "locale": {
  264.                 "firstDayOfWeek": 7 // start week on Sunday
  265.             },
  266.             allowInput: true,
  267.             onOpen: function(selectedDates, dateStr, instance) {
  268.             $(instance.altInput).prop('readonly', true);
  269.             },
  270.             onClose: function(selectedDates, dateStr, instance) {
  271.                 $(instance.altInput).prop('readonly', false);
  272.                 $(instance.altInput).blur();
  273.             },
  274.             onChange: function(selectedDates, dateStr, instance) {
  275.                 validateInput(dateStr, $('.flatpickr_date_nodefault')[0]);
  276.             }
  277.         });
  278.         // Add an additional event listener to the date input field
  279.         $('.flatpickr_date_nodefault').on('change', function() {
  280.             validateInput(this.value, $(this)[0]);
  281.         });
  282.         function validateInput(dateValue, input) {
  283.             var date = new Date(dateValue);
  284.             console.log(date, input);
  285.             if (!isNaN(date.getTime())) {
  286.                 // If the date is valid, clear the error message
  287.                 input.setCustomValidity(''); 
  288.             } else {
  289.                 // If the date is not valid, set a custom error message on the field
  290.                 input.setCustomValidity('Merci de choisir une date valide !');
  291.             }
  292.         }
  293.         flatpickr($('.flatpickr_time'), {
  294.             enableTime: true,
  295.             noCalendar: true,
  296.             dateFormat: "H:i",
  297.             //defaultDate: new Date(),
  298.             disableMobile: "true",
  299.         });
  300.         $('.collections').collection({
  301.             allow_down: false,
  302.             allow_up: false,
  303.             add: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>',
  304.             remove: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>'
  305.             });
  306.         $('.select2_collections').collection({
  307.             after_add: function(collection, element) { initializeSelect2(element.find('.select2')) },
  308.             allow_down: false,
  309.             allow_up: false,
  310.             add: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>',
  311.             remove: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>'
  312.             });
  313.         function initializeSelect2(selectElementObj) {
  314.             selectElementObj.select2({
  315.             });
  316.             return true;
  317.         }
  318.         
  319.         {% for message in app.flashes('notice') %}
  320.             toastr["warning"]("{{ message }}");
  321.         {% endfor %}
  322.         {% for message in app.flashes('success') %}
  323.             toastr["success"]("{{ message }}");
  324.         {% endfor %}
  325.         {% for message in app.flashes('error') %}
  326.             toastr["error"]("{{ message }}");
  327.         {% endfor %}
  328.         {% for message in app.flashes('critical') %}
  329.             toastr.options.closeButton = true;
  330.             toastr.options.tapToDismiss = false;
  331.             toastr.options.timeOut = 0;
  332.             toastr.options.extendedTimeOut = 0;
  333.             toastr.options.showDuration = 0;
  334.             toastr.options.hideDuration = 0;
  335.             toastr.options.escapeHtml = false;
  336.             toastr.options.preventDuplicates = true;
  337.             toastr["error"]("{{ message|raw }}");
  338.         {% endfor %}
  339.         {% for message in app.flashes('error_action') %}
  340.             //toastr.options = {onclick: function () {document.location.href='{{app.request.get("action")}}'; }}
  341.             toastr.options.onclick = function () {document.location.href='{{app.request.get("action")}}'; }
  342.             toastr["error"]("{{ message }}<br /><button type="button" class="btn clear">Éditer</button>");
  343.             });
  344.         {% endfor %}
  345.         /*
  346.         ================================================
  347.         |   navbar inbox / send photo / input file     |
  348.         ================================================
  349.         */
  350.         $.ajax({
  351.             type: "GET",
  352.             url: "{{ path('message_unread_index') }}",
  353.         })
  354.         .done(function(data){ 
  355.             if (data.length > 0) {
  356.                 var elem = "";
  357.                 for (i = 0; i < data.length; i++) {
  358.                     elem += "<a href='{{ path('message_index') }}' class='dropdown-item'><div><div class='media notification-new'><div class='usr-profile-img mr-3'><div class='user-profile'><div>"+data[i]["initials"]+"</div>";
  359.                     elem += "</div></div><div class='media-body'><p class='meta-user-name mr-3'>"+data[i]["sender"]+"</p><p class='message-text'>"+data[i]["subject"]+"</p><p class='meta-time align-self-center mb-0'>"+data[i]["time"]+"</p></div></div></div></a>";    
  360.                 }
  361.                 $('#message-dropdown').html(elem);
  362.                 $('li.message-dropdown span.badge').html(data.length)
  363.             }    else {
  364.                 $('#message-dropdown').html("<p class='m-3 text-center'>Aucun nouveau message!<br><a class='btn btn-primary mt-3' href='/message'>Boîte de Réception</a></p>");
  365.             }
  366.         });
  367.         $('#send-photos').off('click').on('click', function(event) {
  368.             $( "#sendPictureModal form[name='message']" ).submit();
  369.             event.preventDefault();
  370.         });
  371.         $("input[type=file]").each(function (index, inputFile) {
  372.             if($(inputFile).data("filename"))
  373.             {
  374.                 var label = $("label[for='" + $(inputFile).attr('id') + "']")[0];
  375.                 label.innerHTML = $(inputFile).data("filename");
  376.             }
  377.         });
  378.         $(document).on('change', "input[type='file']", function(){
  379.             //get the file name
  380.             var fileName = $(this).val().replace('C:\\fakepath\\', " ");
  381.             //replace the "Choose a file" label
  382.             $(this).next('.custom-file-label').html(fileName);
  383.         });
  384.          /*
  385.         ================================================
  386.         |               submit button loader            |
  387.         ================================================
  388.         */
  389.          $("button[data-spinning-button]").click(function(e) {
  390.             var $this = $(this);
  391.             let $form  = $this.parents("form");
  392.             $this
  393.                 .addClass("button-loading")
  394.                 .attr("disabled", "");
  395.             //return true;
  396.             if ($form.length) {
  397.                 //form.valid() will be applicable If you are using jQuery validate https://jqueryvalidation.org/
  398.                 //asp.net mvc used it by default with jQuery Unobtrusive Validation
  399.                 //you need to check the form before it goes into the if statement
  400.                 if ($form[0].checkValidity()) {
  401.                     $form.submit();
  402.                 } else {
  403.                     $this
  404.                         .removeClass("button-loading")
  405.                         .removeAttr("disabled", "");
  406.                 }
  407.             }
  408.         });
  409.         $("a[data-spinning-link]").click(function(e) {
  410.             var $this = $(this);
  411.             $this
  412.                 .addClass("button-loading")
  413.                 .attr("disabled", "");
  414.             return true;
  415.         });
  416.         /*
  417.         ================================================
  418.         |                  Fancybox                  |
  419.         ================================================
  420.         */
  421.             Fancybox.defaults.l10n = {
  422.                 CLOSE: "Fermer",
  423.                 NEXT: "Suivant",
  424.                 PREV: "Précédent",
  425.                 MODAL: "Vous pouvez fermer ce contenu modal avec la touche ESC",
  426.                 ERROR: "Quelque chose s'est mal passé, veuillez réessayer plus tard",
  427.                 IMAGE_ERROR: "Image non trouvée",
  428.                 ELEMENT_NOT_FOUND: "Élément HTML introuvable",
  429.                 AJAX_NOT_FOUND: "Erreur lors du chargement d'AJAX : introuvable",
  430.                 AJAX_FORBIDDEN: "Erreur lors du chargement d'AJAX : Interdit",
  431.                 IFRAME_ERROR: "Erreur de chargement de la page",
  432.                 TOGGLE_ZOOM: "Zoomer et dézoomer",
  433.                 ROTATE_LEFT: "Faire tourner à gauche",
  434.                 ROTATE_RIGHT: "Faire tourner à droite",
  435.                 TOGGLE_FULLSCREEN: "Basculer en plein écran",
  436.             };
  437.             Fancybox.Plugins.Toolbar.defaults.items.rotateRight = {
  438.                 type: "button",
  439.                 class: "fancybox__button--rotateRight",
  440.                 label: "ROTATE_RIGHT",
  441.                 html:
  442.                     '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>',
  443.                 click: function (event) {
  444.                     event.preventDefault();
  445.                     console.log(event.target.className);
  446.                     var orientation = event.target.classList.contains("fancybox__button--rotateRight") ? "cw" : "acw";
  447.                     var fancybox = this.fancybox;
  448.                     rotatingFunction (fancybox, orientation);
  449.                 },
  450.             };
  451.             Fancybox.Plugins.Toolbar.defaults.items.rotateLeft = {
  452.                 type: "button",
  453.                 class: "fancybox__button--rotateLeft",
  454.                 label: "ROTATE_LEFT",
  455.                 html:
  456.                     '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>',
  457.                 click: function (event) {
  458.                     event.preventDefault();
  459.                     console.log(event.target.className);
  460.                     var orientation = event.target.classList.contains("fancybox__button--rotateRight") ? "cw" : "acw";
  461.                     var fancybox = this.fancybox;
  462.                     rotatingFunction (fancybox, orientation);
  463.                 },
  464.             };
  465.             Fancybox.bind("[data-fancybox]" , {
  466.                 Toolbar: {
  467.                     display: [
  468.                         "counter",
  469.                         "rotateRight",
  470.                         "rotateLeft",
  471.                         "zoom",
  472.                         "slideshow",
  473.                         "fullscreen",
  474.                         "close",
  475.                     ],
  476.                     fullScreen: {
  477.                         autoStart: true
  478.                     }
  479.                 },
  480.                 on: {
  481.                     load: (fancybox, slide) => {
  482.                         console.log(`#${slide.type} slide is loaded!`);
  483.                         //console.log(
  484.                         //    `This slide is selected: ${fancybox.getSlide().index === slide.index}`
  485.                         //);
  486.                         for (const $el of document.querySelectorAll(".fancybox__button--rotateLeft, .fancybox__button--rotateRight")) {
  487.                                 if (slide.type === "image") {
  488.                                     $el.removeAttribute("disabled");
  489.                                 } else {
  490.                                     $el.setAttribute("disabled", "");
  491.                                 }
  492.                         }
  493.                     },
  494.                 },
  495.             });
  496.             function rotatingFunction (fancybox, orientation) {
  497.                 $.ajax({
  498.                     type: 'POST',
  499.                     url: "{{ path('images_rotate') }}",
  500.                     data: { "file": fancybox.getSlide().src, 'orientation': orientation },
  501.                     beforeSend: function( xhr ) {
  502.                         var slide = fancybox.getSlide();
  503.                         fancybox.showLoading(slide);
  504.                     }
  505.                 }).done(function( data ) {
  506.                     //var slide = fancybox.getSlide();
  507.                     //fancybox.hideLoading(slide);
  508.                     
  509.                     //console.log(src);
  510.                     
  511.                     //Image rortated
  512.                     if (data["message"] == "ok") { 
  513.                         /*var thisImg = slide.$el.querySelector("img");
  514.                         var src = $(thisImg).attr("src");
  515.                         degrees = orientation == "cw" ? 90 : -90;
  516.                         $("img[src='"+src+"']").css({
  517.                             'transform': 'rotate(' + degrees + 'deg)',
  518.                             '-ms-transform': 'rotate(' + degrees + 'deg)',
  519.                             '-moz-transform': 'rotate(' + degrees + 'deg)',
  520.                             '-webkit-transform': 'rotate(' + degrees + 'deg)',
  521.                             '-o-transform': 'rotate(' + degrees + 'deg)'
  522.                          });*/
  523.                         
  524.                         var slide = fancybox.getSlide();
  525.                         var actualUrl = slide.src;
  526.                         var newUrl = slide.src + "?" + new Date().getTime();
  527.                         var thisImg = slide.$el.querySelector("img");
  528.                         
  529.                         //creating an xmlHTTP in order to show a loader while of the new rotated img is loaded
  530.                         var xmlHTTP = new XMLHttpRequest();
  531.                         xmlHTTP.open('GET', newUrl, true);
  532.                         //xmlHTTP.withCredentials = true;
  533.                         xmlHTTP.responseType = 'arraybuffer';
  534.                         xmlHTTP.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
  535.                         xmlHTTP.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
  536.                         xmlHTTP.setRequestHeader("Pragma", "no-cache"); 
  537.                         xmlHTTP.onload = function(e) {
  538.                             var blob = new Blob([this.response]);
  539.                             thisImg.src = window.URL.createObjectURL(blob);
  540.                             slide.src = newUrl;
  541.                             fancybox.hideLoading(slide);
  542.                         };
  543.                         xmlHTTP.onloadstart = function() {
  544.                             //fancybox.showLoading(slide);
  545.                             //updating the intial triggers
  546.                             var x =document.querySelectorAll("a.fancybox[href='"+actualUrl+"'], a.fancybox img[src='"+actualUrl+"']")
  547.                             var i;
  548.                             for (i = 0; i < x.length; i++) {
  549.                                 if (x[i].hasAttribute("src")) {      
  550.                                     x[i].src = newUrl;
  551.                                 } else {
  552.                                     x[i].href = newUrl;
  553.                                 }
  554.                                 
  555.                             }
  556.                         };
  557.                         //fancybox.showLoading(slide);
  558.                         xmlHTTP.send();   
  559.                         
  560.                     } else {
  561.                         toastr["error"]("Une erreur s'est produite. Veuillez réessayer ultérieurement...");
  562.                     }
  563.                 });
  564.             }
  565.         
  566.     } );
  567.     </script>
  568.     <script src="{{ asset('assets/js/custom.js') }}"></script>
  569.     <script src="{{ asset('assets/js/image-crop.js') }}"></script>
  570.     <!-- END GLOBAL MANDATORY SCRIPTS -->
  571.     <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM SCRIPTS -->
  572.     {% block javascripts %}{% endblock %}
  573.     <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM SCRIPTS -->
  574.     </body>
  575. </html>