Skip to content
Snippets Groups Projects
Commit a31b0078 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Refactoring & amélioration du axios local & du flashMessenger

parent 367aa23b
Branches
Tags
No related merge requests found
Pipeline #20505 passed
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
function toasts(messages)
{
function toasts(messages) {
for (let s in messages) {
for (let m in messages[s]) {
toast(messages[s][m], s);
......@@ -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) {
......@@ -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();
}
......
import axios from 'axios';
import axios from './axios';
import flashMessenger from './flashMessenger';
const unicaenVue = {
axios: axios,
axios: axios.uvAxios,
flashMessenger: flashMessenger,
/**
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment