Skip to content

Instantly share code, notes, and snippets.

@millerdev
Last active August 28, 2025 11:57
Show Gist options
  • Select an option

  • Save millerdev/571f894f7b71b55168fab694d636f125 to your computer and use it in GitHub Desktop.

Select an option

Save millerdev/571f894f7b71b55168fab694d636f125 to your computer and use it in GitHub Desktop.
Greasemonkey script to hide requested PTO from the Clockify time tracker view
// ==UserScript==
// @name Clockify - hide PTO
// @description Hides PTO cards in Clockify time tracker. Requested/future PTO takes up a lot of space at the top of the time tracker, which pushes today's time entries down in the list. This script hides PTO entries by default, and adds a button to toggle their visibility.
// @version 1.5
// @include https://dimagi.clockify.me/tracker*
// @grant none
// ==/UserScript==
//
// Mostly written by ChatGPT with minor modifications.
// Source: https://gist.github.com/millerdev/571f894f7b71b55168fab694d636f125
(() => {
const PTO_DESCRIPTION = "PTO - Annual Leave";
const ptoCards = [];
let shouldHide = true;
function main() {
if (shouldHide && hidePTOCards()) {
addPTOToggle();
}
}
function hidePTOCards() {
const cards = document.querySelectorAll('.cl-card');
let hid = 0;
cards.forEach(card => {
if (ptoCards.indexOf(card) >= 0) return;
const desc = card.querySelector('.cl-form-control.cl-fake-input[data-cy="time-entry-description"]');
if (desc && desc.textContent.includes(PTO_DESCRIPTION)) {
hid += 1;
card.style.display = "none";
ptoCards.push(card);
}
});
//console.log("Hid", hid, "of", ptoCards.length, "cards");
return hid;
}
function addPTOToggle() {
const submitLinks = Array.from(
document.querySelectorAll('a[data-cy="submit-approval"]')
).filter(a => a.textContent.includes('Submit for approval'));
//console.log("Found", submitLinks.length, "submit links");
if (!submitLinks.length || !ptoCards.length) return;
let link = submitLinks[0];
if (link.nextSibling
&& link.nextSibling.classList
&& link.nextSibling.classList.contains('toggle-pto-btn')
) return;
//console.log("Adding toggle button for", ptoCards.length, "PTO cards");
const btn = document.createElement('button');
btn.textContent = isHidden(ptoCards) ? "Show PTO" : "Hide PTO";
btn.className = 'toggle-pto-btn cl-small';
btn.style.marginLeft = '2em';
btn.addEventListener('click', () => {
const hidden = isHidden(ptoCards);
shouldHide = !hidden;
ptoCards.forEach(card => {
card.style.display = hidden ? "" : "none";
});
btn.textContent = hidden ? "Hide PTO" : "Show PTO";
});
link.parentNode.insertBefore(btn, link.nextSibling);
}
function isHidden(cards) {
return cards.length && cards[0].style.display === "none";
}
const observer = new MutationObserver(main);
observer.observe(document.body, { childList: true, subtree: true });
//main(); // for debugging in console (uncomment this line and paste entire script into console)
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment