Last active
August 1, 2026 06:35
-
-
Save hsayed21/45dfe751d552ea9ce44386439ae8a5dc to your computer and use it in GitHub Desktop.
Odoo Set Ticket to Open in a New Tab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Odoo Ticket Copy and Open New Tab | |
| // @namespace http://tampermonkey.net/ | |
| // @version 3.0 | |
| // @description Copies ticket reference and attempts to open tickets using Odoo native navigation in a new tab | |
| // @author @hsayed21 | |
| // @match https://www.posbank.me/web* | |
| // @match https://posbankf346f.odoo.com/odoo/my-tickets* | |
| // @grant none | |
| // ==/UserScript== | |
| (function () { | |
| 'use strict'; | |
| function copyText(text) { | |
| if (navigator.clipboard?.writeText) { | |
| return navigator.clipboard.writeText(text); | |
| } | |
| const textarea = document.createElement('textarea'); | |
| textarea.value = text; | |
| textarea.style.position = 'fixed'; | |
| textarea.style.opacity = '0'; | |
| document.body.appendChild(textarea); | |
| textarea.select(); | |
| document.execCommand('copy'); | |
| textarea.remove(); | |
| return Promise.resolve(); | |
| } | |
| function makeOdooCellOpenInNewTab(nameCell) { | |
| if (nameCell.dataset.blankClickEnabled === 'true') { | |
| return; | |
| } | |
| nameCell.dataset.blankClickEnabled = 'true'; | |
| nameCell.style.cursor = 'pointer'; | |
| nameCell.title = 'Open ticket in a new tab'; | |
| let allowNativeClick = false; | |
| nameCell.addEventListener( | |
| 'click', | |
| function (event) { | |
| if (allowNativeClick) { | |
| allowNativeClick = false; | |
| return; | |
| } | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| event.stopImmediatePropagation(); | |
| allowNativeClick = true; | |
| const newTabClick = new MouseEvent('click', { | |
| bubbles: true, | |
| cancelable: true, | |
| composed: true, | |
| view: window, | |
| ctrlKey: true, | |
| metaKey: true, | |
| button: 0 | |
| }); | |
| nameCell.dispatchEvent(newTabClick); | |
| // Safety reset in case Odoo does not receive the click. | |
| setTimeout(() => { | |
| allowNativeClick = false; | |
| }, 100); | |
| }, | |
| true | |
| ); | |
| } | |
| function processRows() { | |
| const rows = document.querySelectorAll( | |
| 'tr.o_data_row:not([data-script-processed="true"])' | |
| ); | |
| rows.forEach(row => { | |
| const idCell = row.querySelector('td[name="ticket_ref"]'); | |
| const nameCell = row.querySelector('td[name="name"]'); | |
| if (!idCell || !nameCell) { | |
| return; | |
| } | |
| row.dataset.scriptProcessed = 'true'; | |
| const ticketReference = idCell.textContent.trim(); | |
| /* | |
| * Ticket reference copy badge | |
| */ | |
| idCell.innerHTML = ''; | |
| idCell.style.display = 'flex'; | |
| idCell.style.alignItems = 'center'; | |
| idCell.style.justifyContent = 'center'; | |
| const idLabel = document.createElement('span'); | |
| // Preserve the displayed reference, including leading zeros. | |
| idLabel.textContent = `#${ticketReference}`; | |
| idLabel.title = 'Click to copy ticket reference'; | |
| Object.assign(idLabel.style, { | |
| fontWeight: 'bold', | |
| cursor: 'pointer', | |
| padding: '2px 6px', | |
| backgroundColor: '#e9ecef', | |
| border: '1px solid #dee2e6', | |
| borderRadius: '4px', | |
| fontSize: '0.9em', | |
| color: '#495057', | |
| transition: 'all 0.2s ease' | |
| }); | |
| idLabel.addEventListener('click', function (event) { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| event.stopImmediatePropagation(); | |
| copyText(ticketReference).then(() => { | |
| const originalText = idLabel.textContent; | |
| const originalBackground = idLabel.style.backgroundColor; | |
| const originalColor = idLabel.style.color; | |
| idLabel.textContent = 'Copied!'; | |
| idLabel.style.backgroundColor = '#28a745'; | |
| idLabel.style.color = '#ffffff'; | |
| setTimeout(() => { | |
| idLabel.textContent = originalText; | |
| idLabel.style.backgroundColor = originalBackground; | |
| idLabel.style.color = originalColor; | |
| }, 700); | |
| }); | |
| }); | |
| idCell.appendChild(idLabel); | |
| /* | |
| * Keep the original Odoo name cell. | |
| * Do not replace it with an incorrect generated URL. | |
| */ | |
| makeOdooCellOpenInNewTab(nameCell); | |
| }); | |
| } | |
| processRows(); | |
| const observer = new MutationObserver(() => { | |
| processRows(); | |
| }); | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment