Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bulletinmybeard/2b45fcb25fed0edbe97855e892b60b41 to your computer and use it in GitHub Desktop.
Save bulletinmybeard/2b45fcb25fed0edbe97855e892b60b41 to your computer and use it in GitHub Desktop.
Extend the team calendar on "selfservice.officient.io" with a button to filter by YOUR TEAM

This browser userscript will programmatically add a button to the team calendar at "selfservice.officient.io", allowing you to filter the list of employees to only your team under .../daysOff/coworkers => week-calendar. Simply add the names of your team members to TEAM_CONTACTS and you good.

Before

image

After

image
let lastUrl = ''
let calendar = null
let buttonGroup = null
let middleButton = null
let teamButton = null

const MATCHING_URL = 'https://selfservice.officient.io/daysOff/coworkers'
const TEAM_CONTACTS = [
    'John Doe',
    'Jane Dot',
    ...
]

const classGroup = {
    default: 'no-underline touch-area font-medium py-10px px-30px border-1px first_rounded-l-4px last_rounded-r-4px',
    active: 'bg-purple-10 text-purple-70 border-purple-70',
    inactive: 'bg-white text-blue-grey-50 border-blue-grey-20 hover_bg-purple-10',
}

const getStyleClasses = (isActive, classNames = '') =>
    `${classGroup.default} ${(isActive ? classGroup.active : classGroup.inactive)} ${classNames}`.trim()

const filterContacts = () => {
    const contacts = $('a.week-calendar-row .leading-none')
    if (!contacts || contacts.length === 0) {
        throw Error('No contacts found!')
    }
    contacts.each(function () {
        const name = $(this).text().trim()
        const parent = $(this).parent().parent().parent()
        if (TEAM_CONTACTS.map(item => item.toLowerCase()).indexOf(name.toLowerCase()) === -1) {
            parent.toggle()
        }
    })
}

const myTeamClickHandler = (event) => {
    event.preventDefault()

    teamButton.attr('class', getStyleClasses(true, 'team-filter-button'))
    middleButton.attr('class', getStyleClasses(false))

    teamButton.off('click', myTeamClickHandler)
    middleButton.on('click', middleButtonClickHandler)

    filterContacts()
}

const middleButtonClickHandler = (event) => {
    event.preventDefault()

    teamButton.attr('class', getStyleClasses(false, 'team-filter-button'))
    middleButton.attr('class', getStyleClasses(true))

    teamButton.on('click', myTeamClickHandler)
    middleButton.off('click', middleButtonClickHandler)

    $('a.week-calendar-row').show()
}

const initMyTeamFilter = () => {
    calendar = $('.content .page')
    if (!calendar) {
        throw Error('Calendar container not found!')
    }

    buttonGroup = $(calendar).children().eq(1)
    middleButton = $(buttonGroup).children().eq(1)

    middleButton.css('cursor', 'pointer')

    teamButton = $('<a/>', {
        'class': getStyleClasses(false, 'team-filter-button'),
        'text': 'My Team',
        'style': 'width: 7.5remcursor:pointer'
    })
        .appendTo(buttonGroup)

    $(teamButton).on('click', myTeamClickHandler)
    $(middleButton).off('click', middleButtonClickHandler)
}

const checkUrl = () => {
    if (window.location.href === MATCHING_URL) {
        lastUrl = MATCHING_URL
        initMyTeamFilter()
    } else {
        lastUrl = window.location.href
    }
}

(async () => {
    window.addEventListener('popstate', () => checkUrl())

    let targetFound = false
    new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            let element = mutation.target
            while (element && !element.classList.contains('week-calendar')) {
                if (element.classList && Array.from(element.classList).some(cls => cls.startsWith('week-calendar'))) {
                    if (!targetFound) {
                        targetFound = true
                        checkUrl()
                        setTimeout(() => {
                            targetFound = false
                        }, 1500)
                    }
                    break
                }
                element = element.parentElement
            }
        }
    })
        .observe(document.querySelector('div[class^="week-calendar"]') || document.body, {
            attributes: true,
            attributeFilter: ['class'],
            subtree: true,
        })
})().catch(err => {
    console.error(err)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment