jondbras / More Header Buttons for ConnectWise Manage

// ==UserScript==
// @name         More Header Buttons for ConnectWise Manage
// @namespace    https://na.myconnectwise.net/
// @version      0.3
// @description  Adds "My Timesheet" and "Today" buttons to the Manage header
// @author       Jonathon Braswell <jonathon.braswell@twinoakstech.com>
// @match        https://na.myconnectwise.net/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @license      GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// ==/UserScript==
(() => {
    'use strict';

    // Main namespace
    window.MoreButtons = function () {
        // Button urls
        this.tsUrl = 'https://na.myconnectwise.net/v2021_1/connectwise.aspx?fullscreen=false&locale=en_US#startscreen=my_time_sheets';
        this.tdUrl = 'https://na.myconnectwise.net/v2021_1/connectwise.aspx?fullscreen=false&locale=en_US#startscreen=cw_today';

        // Things to help us locate where we are inserting buttons
        this.insertPos = 5;
        this.chatBtnClass = '.cw_ChatAssistButton';

        // Creates an <a> Element with the given properties and styles it
        // returns HTMLElement
        this.makeLink = function (text, url) {
            let link = document.createElement('a');
            link.setAttribute('style', 'font-family: "Roboto", sans-serif; text-decoration: unset; font-weight: 500;');
            link.setAttribute('href', url);
            link.setAttribute('target', '_blank');
            link.innerHTML = text;
            return link;
        };

        // Creates a <td> Element and styles it
        // returns HTMLElement
        this.makeCell = function () {
            let cell = document.createElement('td');
            cell.setAttribute('style', 'text-align: center; width: 100px;');
            return cell;
        };

        // Initialize!
        this.init = function () {
            // Make the links
            let todayLink = this.makeLink('Today', this.tdUrl);
            let timeLink = this.makeLink('My Timesheet', this.tsUrl);

            // Find the header
            let header = document.querySelector(this.chatBtnClass).parentElement.parentElement;

            // Make and insert the parent cells into the bar
            let todayBtn = header.insertBefore(this.makeCell(), header.childNodes[this.insertPos]);
            let timeBtn = header.insertBefore(this.makeCell(), header.childNodes[this.insertPos]);

            // Put the links in their cells
            todayBtn.appendChild(todayLink);
            timeBtn.appendChild(timeLink);
        };
    };

    // Invoke on load
    window.onload = event => {
        let mb = new window.MoreButtons();
        // The Web GUI is built asynchronously so we need to check every few millis
        // to see if our anchor element is present on the page before init
        let interval = setInterval(() => {
            if (document.querySelector(mb.chatBtnClass) !== null) {
                // Found it! Tear down the interval and init
                clearInterval(interval);
                mb.init();
            }
        }, 500);
    };

})();