Améliore l'interface Zendesk et ajoute des fonctionnalités supplémentaires
// ==UserScript==
// @name Zendesk Enhancements
// @namespace http://tampermonkey.net/
// @version 1.3.3
// @description Améliore l'interface Zendesk et ajoute des fonctionnalités supplémentaires
// @author Morgan & gann
// @match https://*.zendesk.com/*
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Définition d'un style commun pour les éléments personnalisés
var customCSS = `
.custom-button, .djm-task-link, .copy-conversation-button {
padding: 5px 10px;
background-color: limegreen;
font-size: 16px;
color: black;
border: 1px solid transparent;
border-radius: 4px;
cursor: pointer;
text-align: center;
text-decoration: none;
display: inline-block;
margin: 5px;
transition: background-color 0.15s ease, color 0.15s ease;
&:hover {
background-color: darkgreen; /* Couleur de fond au survol */
color: white; /* Couleur du texte au survol */
}
}
.sc-1oduqug-0.jdCBDY {
margin-top: 30px;
}
iframe#web-messenger-container {
display: none;
}
.app_view.app-1019154.apps_ticket_sidebar iframe {
height: 80vh!important;
}
/* Enhence copy conversation btn */
.sc-1nvv38f-3.cjpyOe {
flex: unset;
}
/*Enhence next conversation btn */
.jGrowl-notification {
top: 30px;
}
`;
GM_addStyle(customCSS);
// Initialisation des fonctions personnalisées
setTimeout(function() {
customFunction()
}, 500);
function customFunction(message) {
setTimeout(function() {
checkUrlAndRunScriptInitializeInputLinks();
checkUrlAndRunScriptTransformUrlsToLinks();
}, 500);
}
// Écoute les changements de navigation
window.addEventListener('popstate', function() {
customFunction('Chemin changé: ' + window.location.pathname);
});
// Surcharge des méthodes d'historique
function overrideHistoryMethod(methodName) {
var originalMethod = history[methodName];
history[methodName] = function(state) {
if (typeof history['on' + methodName] == "function") {
history['on' + methodName]({state: state});
}
customFunction('Chemin changé par ' + methodName + ': ' + window.location.pathname);
return originalMethod.apply(history, arguments);
};
}
overrideHistoryMethod('pushState');
overrideHistoryMethod('replaceState');
window.history.onpushstate = function(e) {
window.dispatchEvent(new CustomEvent('pushstate', e));
};
window.history.onreplacestate = function(e) {
window.dispatchEvent(new CustomEvent('replacestate', e));
};
// Événements sur les en-têtes de tableau
var theads = document.querySelectorAll('thead');
theads.forEach(function(thead) {
thead.addEventListener('click', function(event) {
customFunction('Un thead a été cliqué' + event.target);
});
});
function transformUrlsToLinks() {
const cells = document.querySelectorAll('.beWvMU');
const urlRegex = /(https?:\/\/[^\s]+)/g;
if (cells.length > 0) {
cells.forEach((cell, index) => {
const textContent = cell.textContent;
if (urlRegex.test(textContent)) {
const link = document.createElement('a');
link.setAttribute('href', textContent.match(urlRegex)[0]);
link.textContent = textContent.match(urlRegex)[0];
link.classList.add('custom-button');
cell.textContent = '';
cell.appendChild(link);
}
});
}
}
function checkUrlAndRunScriptTransformUrlsToLinks() {
if (window.location.pathname.startsWith('/agent/filters/')) {
transformUrlsToLinks();
}
}
function initializeInputLinks() {
var inputElements = document.querySelectorAll('.custom_field_14504424601628 input');
inputElements.forEach(function(inputElement) {
var existingLink = inputElement.parentNode.parentNode.querySelector('.djm-task-link');
if (existingLink) {
existingLink.remove();
}
var linkElement = document.createElement('a');
linkElement.textContent = 'Tâche';
linkElement.style.display = 'none';
linkElement.classList.add('djm-task-link');
inputElement.parentNode.parentNode.insertBefore(linkElement, inputElement.nextSibling);
checkForUrl(inputElement, linkElement);
inputElement.addEventListener('input', function() {
console.log('Événement input détecté.');
checkForUrl(inputElement, linkElement);
});
});
}
function checkForUrl(inputElement, linkElement) {
if (inputElement.value.match(/(https?:\/\/[^\s]+)/g)) {
linkElement.href = inputElement.value;
linkElement.style.display = 'inline-block';
} else {
linkElement.style.display = 'none';
}
}
function checkUrlAndRunScriptInitializeInputLinks() {
if (window.location.pathname.startsWith('/agent/tickets/')) {
initializeInputLinks();
}
}
// Fonction pour fermer tous les onglets inactifs
function closeInactiveTabs() {
const closeButtons = [...document.querySelectorAll('div[role="tab"][data-selected="false"] button[data-test-id="close-button"]')];
closeButtons.forEach(btn => btn.click());
}
// Fonction pour ajouter le bouton "Close All"
function addCloseAllButton() {
const toolbar = document.querySelector('div[data-test-id="header-tablist"] > div.sc-19uji9v-0');
if (toolbar && !document.getElementById('close-all-button')) {
const closeButton = document.createElement('button');
closeButton.id = 'close-all-button';
closeButton.textContent = 'X Close all';
closeButton.className = 'custom-button';
closeButton.addEventListener('click', closeInactiveTabs);
toolbar.appendChild(closeButton);
}
}
// Ajout du bouton "Close All" au chargement de la page
window.addEventListener('load', addCloseAllButton);
// Observer les changements dans le DOM pour charger dynamiquement le bouton
const observer = new MutationObserver(addCloseAllButton);
observer.observe(document.body, { childList: true, subtree: true });
function addCopyButtons() {
// Get all 'ember-view workspace has-play' elements
const workspaces = document.querySelectorAll('.ember-view.workspace');
workspaces.forEach((workspace, index) => {
// Find the 'sc-1nvv38f-3 cjpyOe' element within each workspace
const headerElement = workspace.querySelector('.sc-1nvv38f-3.cjpyOe');
if (headerElement) {
// Check if the button already exists to avoid duplicates
if (!headerElement.querySelector('.copy-conversation-button')) {
// Create a new button
const button = document.createElement('button');
button.innerText = 'Copy Conversation';
button.style.marginLeft = '10px';
button.classList.add('copy-conversation-button'); // Add a class for easy selection
// Add the click event to copy conversation text
button.addEventListener('click', () => {
// Find the conversation text container
const conversationContainer = workspace.querySelector('.sc-175iuw8-0.ecaNtR.conversation-polaris.polaris-react-component.rich_text');
if (conversationContainer) {
const textToCopy = conversationContainer.innerText;
// Append "[Ma réponse au client]" to the text
const modifiedText = textToCopy + '\n[Ma réponse au client]\n';
// Copy the modified text to clipboard
copyToClipboard(modifiedText);
}
});
// Append the button to the header element
headerElement.appendChild(button);
}
}
});
}
// Function to copy text to clipboard
function copyToClipboard(text) {
navigator.clipboard.writeText(text).catch(err => {
console.error('Failed to copy text: ', err);
});
}
// Run the function every second
setInterval(addCopyButtons, 1000);
})();