NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Filter By Team Member
// @namespace https://github.com/TheBit/user-script-filter-by-team-member-in-confluence
// @version 0.1
// @description Adds custom filtering possibilities to Confluence (select team member to see only his/her task cards)
// @author TheBit
// @copyright 2018, TheBit
// @license MIT
// @match https://confluence.betlab.com/pages/*
// @match https://confluence.betlab.com/display/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const $ = selector => document.querySelector(selector);
const $$ = selector => document.querySelectorAll(selector);
const selectors = {
allPicker: `[data-all-picker='']`,
picker: `[data-macro-name='profile-picture']`,
memberPicker: (member) => `[data-macro-name='profile-picture'][data-username='${member}']`,
memberInTask: (member) => `[data-macro-name='panel'] [data-macro-name='profile-picture'][data-username='${member}']`,
taskContainer: `[data-macro-name='panel']`,
};
const teamContainer = $(selectors.picker).parentNode;
const team = [...teamContainer.children].
filter( member => member.dataset.username ).
map( member => member.dataset.username );
const selectedMembers = [];
const handlers = {
onAllPickerClick: (event, picker) => {
event.preventDefault();
highlight(picker);
selectedMembers.forEach( member => unhighlight($(selectors.memberPicker(member))) );
selectedMembers.length = 0;
$$(selectors.taskContainer).forEach( taskContainer => show(taskContainer) );
},
onMemberPickerClick: (event, member) => {
event.preventDefault();
unhighlight($(selectors.allPicker));
//Toggle selected member
if (selectedMembers.includes(member)) {
selectedMembers.splice( selectedMembers.indexOf(member), 1); //unselect already selected
unhighlight($(selectors.memberPicker(member)));
} else {
selectedMembers.push(member); //select new one
highlight($(selectors.memberPicker(member)));
}
//Hide all tasks
$$(selectors.taskContainer).forEach( taskContainer => hide(taskContainer) );
//Show only those tasks which corresponds to selected members
selectedMembers.forEach( member => {
let memberInTasks = $$(selectors.memberInTask(member));
memberInTasks.forEach( memberInTask => show(memberInTask.closest(selectors.taskContainer)) );
} );
},
}
//Let all member pickers become clickable
team.forEach( member => {
let memberPicker = $(selectors.memberPicker(member));
memberPicker.addEventListener('click', (event) => handlers.onMemberPickerClick(event, member));
} );
//Clones first member picker and transforms it to "All" picker
(function createAllPicker() {
let firstPicker = $(selectors.picker);
let clone = firstPicker.cloneNode(true);
clone.firstChild.src = 'https://image.ibb.co/bDXPnq/ALL.png';
clone.removeAttribute('data-username');
clone.setAttribute('data-all-picker', '');
highlight(clone);
clone.addEventListener('click', (event) => handlers.onAllPickerClick(event, clone));
firstPicker.parentNode.insertBefore(clone, firstPicker);
})();
//DOM utils:
function highlight(element) {
element.firstChild.style.boxShadow = '0px 0px 15px red';
}
function unhighlight(element) {
element.firstChild.style.boxShadow = '';
}
function show(element) {
element.style.display = 'block';
}
function hide(element) {
element.style.display = 'none';
}
})();