Loading js/Client/axios.js 0 → 100644 +77 −0 Original line number Diff line number Diff line import axios from 'axios'; import flashMessenger from './flashMessenger'; // uvAxios est un clone du axops standard let uvAxios = { ...axios}; /* Tunning d'Axios pour gérer l'interconnexion avec le serveur avec gestion des toasts */ // Permet d'afficher une animation de chargement dans un popover si l'objet submitter a été transmis uvAxios.interceptors.request.use(config => { if (config.submitter) { let msg = config.msg ? config.msg : 'Action en cours'; if (config.popover != undefined) { config.popover.dispose(); } config.popover = new bootstrap.Popover(config.submitter, { content: "<div class=\"spinner-border text-primary\" role=\"status\">\n" + " <span class=\"visually-hidden\">Loading...</span>\n" + "</div> " + msg, html: true, trigger: 'focus' }); config.popover.show(); } return config; }); // On capte la réponse pour afficher le résultat si on avait un submitter, sinon on affiche des toasts uvAxios.interceptors.response.use(response => { response.messages = response.data.messages; response.data = response.data.data; response.hasErrors = response.messages && response.messages.error && response.messages.error.length > 0 ? true : false; if (response.config.popover) { var popover = response.config.popover; let content = ''; for (ns in response.messages) { for (mid in response.messages[ns]) { content += '<div class="alert fade show alert-' + (ns == 'error' ? 'danger' : ns) + '" role="alert">' + response.messages[ns][mid] + '</div>'; } } // S'il y a un truc à afficher if (content) { popover._config.content = content; popover.setContent(); setTimeout(() => { popover.dispose(); }, 5000) } else { // la popover est masquée si tout est fini popover.dispose(); } } if (response.messages) { flashMessenger.toasts(response.messages); } return response; }, (error) => { let message = error.response.data; if (error.response.status == 403){ message = '<h4>403 - Accès interdit</h4><br />Vous n\'êtes pas autorisé(e) à faire cette action.'; }else{ message = error.response.data; } flashMessenger.toast(message, 'error'); }); uvAxios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; export default { uvAxios } No newline at end of file js/Client/flashMessenger.js +84 −25 Original line number Diff line number Diff line function toasts(messages) { function toasts(messages) { for (let s in messages) { for (let m in messages[s]) { toast(messages[s][m], s); Loading @@ -8,6 +7,50 @@ function toasts(messages) } function toastContainer() { let toastContainer = document.getElementById('unicaen-vue-toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'unicaen-vue-toast-container'; toastContainer.classList.add('toast-container', 'position-fixed', 'top-0', 'end-0', 'p-3'); document.body.appendChild(toastContainer); } return toastContainer; } function prepareMessage(message) { message = removeAlert(message); message = removeIcon(message); return message; } function removeAlert(message) { const el = document.createElement("div"); el.innerHTML = message; // Si on trouve une alert, alors on la retire pour éviter de faire double affichage const alert = el.querySelector('.alert'); if (alert) { return alert.innerHTML; } else { return el.innerHTML; } } function removeIcon(message) { const el = document.createElement("div"); el.innerHTML = message; // on masque l'icône /!\ qui fait doublon si on en trouve const fasIcons = el.querySelectorAll('i.fas'); fasIcons.forEach(icon => icon.style.display = "none"); return el.innerHTML; } function toast(message, severity) { Loading @@ -24,41 +67,57 @@ function toast(message, severity) { error: 'exclamation-triangle' }; let toastContainer = document.getElementById('unicaen-vue-toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'unicaen-vue-toast-container'; toastContainer.classList.add('toast-container', 'position-fixed', 'top-0', 'end-0', 'p-3'); document.body.appendChild(toastContainer); } // Crée le bouton de fermeture const closeButton = document.createElement('button'); closeButton.classList.add('btn-close', 'btn-close-white', 'h5'); closeButton.style.float = 'right'; closeButton.setAttribute('data-bs-dismiss', 'toast'); closeButton.setAttribute('aria-label', 'Close'); // Crée l'icône const icon = document.createElement('i'); icon.classList.add('icon', 'fas', `fa-${iconClasses[severity]}`); icon.style.float = 'left'; icon.style.fontSize = '26pt'; icon.style.paddingLeft = '.4rem'; icon.style.marginTop = '.4rem'; icon.style.paddingRight = '1rem'; // Crée le corps du toast const body = document.createElement('div'); body.classList.add('toast-body'); body.innerHTML = prepareMessage(message); // Crée le contenu du toast en ajoutant les éléments créés précédemment const content = document.createElement('div'); content.appendChild(closeButton); content.appendChild(icon); content.appendChild(body); // Création de l'élément HTML pour le toast const toast = document.createElement('div'); toast.classList.add('toast', 'show', 'text-white', bgClasses[severity] ? bgClasses[severity] : 'bg-secondary'); toast.classList.add('toast', 'text-white', bgClasses[severity] ? bgClasses[severity] : 'bg-secondary'); toast.setAttribute('role', 'alert'); toast.setAttribute('aria-live', 'assertive'); toast.setAttribute('aria-atomic', 'true'); // On élargit le toast pour ahhicher tout ça... if (severity === 'error' && message.length > 500) { toast.setAttribute('style', 'width:700px'); } const toastContent = '<button class="btn-close btn-close-white h5" style="float:right" data-bs-dismiss="toast" aria-label="Close"></button>' + '<i class="icon fas fa-' + iconClasses[severity] + '" style="float: left;font-size: 26pt;padding-left: .4rem;margin-top:.4rem;padding-right: 1rem;"></i>' + '<div class="toast-body">' + message + ' </div>'; toast.innerHTML = toastContent; toast.appendChild(content); // Ajout du toast à l'élément du conteneur de toasts toastContainer.appendChild(toast); toastContainer().appendChild(toast); // Masquage du toast si ce n'est pas une erreur if (severity !== 'error') { setTimeout(() => { toast.classList.remove('show'); }, 5000); } // Création et affichage du toast avec bootstrap const options = { animation: true, delay: 5000, autohide: severity !== 'error' }; let bsToast = new bootstrap.Toast(toast, options); bsToast.show(); } Loading js/Client/unicaenVue.js +2 −80 Original line number Diff line number Diff line import axios from 'axios'; import axios from './axios'; import flashMessenger from './flashMessenger'; const unicaenVue = { axios: axios, axios: axios.uvAxios, flashMessenger: flashMessenger, /** Loading Loading @@ -31,84 +31,6 @@ const unicaenVue = { }; /* Tunning d'Axios pour gérer l'interconnexion avec le serveur avec gestion des alertes */ unicaenVue.axios.interceptors.request.use(config => { if (config.submitter) { let msg = config.msg ? config.msg : 'Action en cours'; if (config.popover != undefined) { config.popover.dispose(); } config.popover = new bootstrap.Popover(config.submitter, { content: "<div class=\"spinner-border text-primary\" role=\"status\">\n" + " <span class=\"visually-hidden\">Loading...</span>\n" + "</div> " + msg, html: true, trigger: 'focus' }); config.popover.show(); } return config; }); unicaenVue.axios.interceptors.response.use(response => { response.messages = response.data.messages; response.data = response.data.data; response.hasErrors = response.messages && response.messages.error && response.messages.error.length > 0 ? true : false; if (response.config.popover) { var popover = response.config.popover; let content = ''; for (ns in response.messages) { for (mid in response.messages[ns]) { content += '<div class="alert fade show alert-' + (ns == 'error' ? 'danger' : ns) + '" role="alert">' + response.messages[ns][mid] + '</div>'; } } // S'il y a un truc à afficher if (content) { popover._config.content = content; popover.setContent(); setTimeout(() => { popover.dispose(); }, 3000) } else { // la popover est masquée si tout est fini popover.dispose(); } } if (response.messages) { flashMessenger.toasts(response.messages); } return response; }, (error) => { let message = error.response.data; if (error.response.status == 403){ message = '<h4>403 - Accès interdit</h4><br />Vous n\'êtes pas autorisé(e) à faire cette action.'; }else if (error.response.status == 500) { const text = document.createElement("div"); text.innerHTML = error.response.data; // on masque l'icône /!\ qui fait doublon si on en trouve const fasIcons = text.querySelectorAll('i.fas'); fasIcons.forEach(icon => icon.style.display = "none"); message = text.querySelector('.alert').innerHTML; if (message === undefined){ message = error.response.data; } }else{ message = error.response.data; } flashMessenger.toast(message, 'error'); }); unicaenVue.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // workaround pour rendre unicaenVue disponible de partout window.unicaenVue = unicaenVue; Loading Loading
js/Client/axios.js 0 → 100644 +77 −0 Original line number Diff line number Diff line import axios from 'axios'; import flashMessenger from './flashMessenger'; // uvAxios est un clone du axops standard let uvAxios = { ...axios}; /* Tunning d'Axios pour gérer l'interconnexion avec le serveur avec gestion des toasts */ // Permet d'afficher une animation de chargement dans un popover si l'objet submitter a été transmis uvAxios.interceptors.request.use(config => { if (config.submitter) { let msg = config.msg ? config.msg : 'Action en cours'; if (config.popover != undefined) { config.popover.dispose(); } config.popover = new bootstrap.Popover(config.submitter, { content: "<div class=\"spinner-border text-primary\" role=\"status\">\n" + " <span class=\"visually-hidden\">Loading...</span>\n" + "</div> " + msg, html: true, trigger: 'focus' }); config.popover.show(); } return config; }); // On capte la réponse pour afficher le résultat si on avait un submitter, sinon on affiche des toasts uvAxios.interceptors.response.use(response => { response.messages = response.data.messages; response.data = response.data.data; response.hasErrors = response.messages && response.messages.error && response.messages.error.length > 0 ? true : false; if (response.config.popover) { var popover = response.config.popover; let content = ''; for (ns in response.messages) { for (mid in response.messages[ns]) { content += '<div class="alert fade show alert-' + (ns == 'error' ? 'danger' : ns) + '" role="alert">' + response.messages[ns][mid] + '</div>'; } } // S'il y a un truc à afficher if (content) { popover._config.content = content; popover.setContent(); setTimeout(() => { popover.dispose(); }, 5000) } else { // la popover est masquée si tout est fini popover.dispose(); } } if (response.messages) { flashMessenger.toasts(response.messages); } return response; }, (error) => { let message = error.response.data; if (error.response.status == 403){ message = '<h4>403 - Accès interdit</h4><br />Vous n\'êtes pas autorisé(e) à faire cette action.'; }else{ message = error.response.data; } flashMessenger.toast(message, 'error'); }); uvAxios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; export default { uvAxios } No newline at end of file
js/Client/flashMessenger.js +84 −25 Original line number Diff line number Diff line function toasts(messages) { function toasts(messages) { for (let s in messages) { for (let m in messages[s]) { toast(messages[s][m], s); Loading @@ -8,6 +7,50 @@ function toasts(messages) } function toastContainer() { let toastContainer = document.getElementById('unicaen-vue-toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'unicaen-vue-toast-container'; toastContainer.classList.add('toast-container', 'position-fixed', 'top-0', 'end-0', 'p-3'); document.body.appendChild(toastContainer); } return toastContainer; } function prepareMessage(message) { message = removeAlert(message); message = removeIcon(message); return message; } function removeAlert(message) { const el = document.createElement("div"); el.innerHTML = message; // Si on trouve une alert, alors on la retire pour éviter de faire double affichage const alert = el.querySelector('.alert'); if (alert) { return alert.innerHTML; } else { return el.innerHTML; } } function removeIcon(message) { const el = document.createElement("div"); el.innerHTML = message; // on masque l'icône /!\ qui fait doublon si on en trouve const fasIcons = el.querySelectorAll('i.fas'); fasIcons.forEach(icon => icon.style.display = "none"); return el.innerHTML; } function toast(message, severity) { Loading @@ -24,41 +67,57 @@ function toast(message, severity) { error: 'exclamation-triangle' }; let toastContainer = document.getElementById('unicaen-vue-toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'unicaen-vue-toast-container'; toastContainer.classList.add('toast-container', 'position-fixed', 'top-0', 'end-0', 'p-3'); document.body.appendChild(toastContainer); } // Crée le bouton de fermeture const closeButton = document.createElement('button'); closeButton.classList.add('btn-close', 'btn-close-white', 'h5'); closeButton.style.float = 'right'; closeButton.setAttribute('data-bs-dismiss', 'toast'); closeButton.setAttribute('aria-label', 'Close'); // Crée l'icône const icon = document.createElement('i'); icon.classList.add('icon', 'fas', `fa-${iconClasses[severity]}`); icon.style.float = 'left'; icon.style.fontSize = '26pt'; icon.style.paddingLeft = '.4rem'; icon.style.marginTop = '.4rem'; icon.style.paddingRight = '1rem'; // Crée le corps du toast const body = document.createElement('div'); body.classList.add('toast-body'); body.innerHTML = prepareMessage(message); // Crée le contenu du toast en ajoutant les éléments créés précédemment const content = document.createElement('div'); content.appendChild(closeButton); content.appendChild(icon); content.appendChild(body); // Création de l'élément HTML pour le toast const toast = document.createElement('div'); toast.classList.add('toast', 'show', 'text-white', bgClasses[severity] ? bgClasses[severity] : 'bg-secondary'); toast.classList.add('toast', 'text-white', bgClasses[severity] ? bgClasses[severity] : 'bg-secondary'); toast.setAttribute('role', 'alert'); toast.setAttribute('aria-live', 'assertive'); toast.setAttribute('aria-atomic', 'true'); // On élargit le toast pour ahhicher tout ça... if (severity === 'error' && message.length > 500) { toast.setAttribute('style', 'width:700px'); } const toastContent = '<button class="btn-close btn-close-white h5" style="float:right" data-bs-dismiss="toast" aria-label="Close"></button>' + '<i class="icon fas fa-' + iconClasses[severity] + '" style="float: left;font-size: 26pt;padding-left: .4rem;margin-top:.4rem;padding-right: 1rem;"></i>' + '<div class="toast-body">' + message + ' </div>'; toast.innerHTML = toastContent; toast.appendChild(content); // Ajout du toast à l'élément du conteneur de toasts toastContainer.appendChild(toast); toastContainer().appendChild(toast); // Masquage du toast si ce n'est pas une erreur if (severity !== 'error') { setTimeout(() => { toast.classList.remove('show'); }, 5000); } // Création et affichage du toast avec bootstrap const options = { animation: true, delay: 5000, autohide: severity !== 'error' }; let bsToast = new bootstrap.Toast(toast, options); bsToast.show(); } Loading
js/Client/unicaenVue.js +2 −80 Original line number Diff line number Diff line import axios from 'axios'; import axios from './axios'; import flashMessenger from './flashMessenger'; const unicaenVue = { axios: axios, axios: axios.uvAxios, flashMessenger: flashMessenger, /** Loading Loading @@ -31,84 +31,6 @@ const unicaenVue = { }; /* Tunning d'Axios pour gérer l'interconnexion avec le serveur avec gestion des alertes */ unicaenVue.axios.interceptors.request.use(config => { if (config.submitter) { let msg = config.msg ? config.msg : 'Action en cours'; if (config.popover != undefined) { config.popover.dispose(); } config.popover = new bootstrap.Popover(config.submitter, { content: "<div class=\"spinner-border text-primary\" role=\"status\">\n" + " <span class=\"visually-hidden\">Loading...</span>\n" + "</div> " + msg, html: true, trigger: 'focus' }); config.popover.show(); } return config; }); unicaenVue.axios.interceptors.response.use(response => { response.messages = response.data.messages; response.data = response.data.data; response.hasErrors = response.messages && response.messages.error && response.messages.error.length > 0 ? true : false; if (response.config.popover) { var popover = response.config.popover; let content = ''; for (ns in response.messages) { for (mid in response.messages[ns]) { content += '<div class="alert fade show alert-' + (ns == 'error' ? 'danger' : ns) + '" role="alert">' + response.messages[ns][mid] + '</div>'; } } // S'il y a un truc à afficher if (content) { popover._config.content = content; popover.setContent(); setTimeout(() => { popover.dispose(); }, 3000) } else { // la popover est masquée si tout est fini popover.dispose(); } } if (response.messages) { flashMessenger.toasts(response.messages); } return response; }, (error) => { let message = error.response.data; if (error.response.status == 403){ message = '<h4>403 - Accès interdit</h4><br />Vous n\'êtes pas autorisé(e) à faire cette action.'; }else if (error.response.status == 500) { const text = document.createElement("div"); text.innerHTML = error.response.data; // on masque l'icône /!\ qui fait doublon si on en trouve const fasIcons = text.querySelectorAll('i.fas'); fasIcons.forEach(icon => icon.style.display = "none"); message = text.querySelector('.alert').innerHTML; if (message === undefined){ message = error.response.data; } }else{ message = error.response.data; } flashMessenger.toast(message, 'error'); }); unicaenVue.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // workaround pour rendre unicaenVue disponible de partout window.unicaenVue = unicaenVue; Loading