-
Notifications
You must be signed in to change notification settings - Fork 568
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(asana): tags and projects selectors (#2320)
* feat(config): add prettier config * chore(asana): code style fixes apply * fix(asana): spreadsheet selector on projects and tags * fix(asana): tags & projects resolvers in board view closes: #2321 closes: #2317
- Loading branch information
Showing
4 changed files
with
545 additions
and
82 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('@toggl/prettier') |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,171 +1,193 @@ | ||
/** | ||
* @name Asana | ||
* @urlAlias app.asana.com | ||
* @urlAlias app.asana.com | ||
* @urlRegex *://app.asana.com/* | ||
*/ | ||
'use strict'; | ||
'use strict' | ||
|
||
const projectHeaderSelector = () => { | ||
// Try to look for for page project title instead. | ||
const projectHeader = document.querySelector( | ||
'.ProjectPageHeaderProjectTitle-container', | ||
); | ||
) | ||
|
||
if (!projectHeader) { | ||
return ''; | ||
return '' | ||
} | ||
return projectHeader.textContent | ||
.replace(/\u00a0/g, ' ') // There can be in Asana header content | ||
.trim(); | ||
}; | ||
.trim() | ||
} | ||
|
||
// Board view. Inserts button next to assignee/due date. | ||
togglbutton.render('.BoardCardLayout:not(.toggl)', { observe: true }, | ||
boadCardElem => { | ||
togglbutton.render( | ||
'.BoardCardLayout:not(.toggl)', | ||
{ observe: true }, | ||
(boadCardElem) => { | ||
if (boadCardElem.querySelector('.toggl-button')) { | ||
// Due to the way this UI is rendered, we must check for existence of old buttons manually. | ||
return; | ||
return | ||
} | ||
|
||
const descriptionSelector = () => boadCardElem.querySelector('.BoardCard-taskName').textContent.trim(); | ||
|
||
const descriptionSelector = () => | ||
boadCardElem.querySelector('.BoardCard-taskName').textContent.trim() | ||
|
||
const link = togglbutton.createTimerLink({ | ||
className: 'asana-board-view', | ||
description: descriptionSelector, | ||
buttonType: 'minimal', | ||
projectName: projectHeaderSelector, | ||
// N.B. Tags cannot be supported on board view as the information is not available. | ||
}); | ||
}) | ||
|
||
const injectContainer = boadCardElem.querySelector('.BoardCardLayout-actionButtons'); | ||
const injectContainer = boadCardElem.querySelector( | ||
'.BoardCardLayout-actionButtons', | ||
) | ||
if (injectContainer) { | ||
injectContainer.insertAdjacentElement('afterbegin', link); | ||
injectContainer.insertAdjacentElement('afterbegin', link) | ||
} | ||
} | ||
); | ||
}, | ||
) | ||
|
||
// Spreadsheet view. Inserts button next to to the task name. | ||
togglbutton.render('.SpreadsheetRow .SpreadsheetTaskName:not(.toggl)', { observe: true }, | ||
togglbutton.render( | ||
'.SpreadsheetRow .SpreadsheetTaskName:not(.toggl)', | ||
{ observe: true }, | ||
function (taskNameCell) { | ||
const container = taskNameCell.closest('.SpreadsheetRow'); | ||
const container = taskNameCell.closest('.SpreadsheetRow') | ||
|
||
if (container.querySelector('.toggl-button')) { | ||
// Due to the way this UI is rendered, we must check for existence of old buttons manually. | ||
return; | ||
return | ||
} | ||
|
||
const descriptionSelector = () => taskNameCell.querySelector('textarea').textContent.trim(); | ||
const descriptionSelector = () => | ||
taskNameCell.querySelector('textarea').textContent.trim() | ||
|
||
const projectSelector = () => { | ||
const projectCell = container.querySelector('.SpreadsheetTaskRow-projectsCell'); | ||
const projectCell = container.querySelector( | ||
'.SpreadsheetTaskRow-projectsCell', | ||
) | ||
if (!projectCell) { | ||
// Try to look for for page project title instead. | ||
return projectHeaderSelector(); | ||
return projectHeaderSelector() | ||
} | ||
|
||
// There can be multiple projects, but we can't support trying to match multiple yet. | ||
const firstProject = projectCell.querySelector('.Pill'); | ||
return firstProject ? firstProject.textContent.trim() : projectHeaderSelector(); | ||
}; | ||
const firstProject = projectCell.querySelector( | ||
'.SpreadsheetPotsCell-potPill', | ||
) | ||
return firstProject | ||
? firstProject.textContent.trim() | ||
: projectHeaderSelector() | ||
} | ||
|
||
const tagsSelector = () => { | ||
const tags = container.querySelectorAll('.SpreadsheetTaskRow-tagsCell .Pill'); | ||
return [...tags].map(tag => tag.textContent.trim()); | ||
}; | ||
const tags = container.querySelectorAll( | ||
'.SpreadsheetTaskRow-tagsCell .SpreadsheetPotsCell-potPill', | ||
) | ||
return [...tags].map((tag) => tag.textContent.trim()) | ||
} | ||
|
||
const link = togglbutton.createTimerLink({ | ||
className: 'asana-spreadsheet', | ||
description: descriptionSelector, | ||
projectName: projectSelector, | ||
tags: tagsSelector, | ||
buttonType: 'minimal' | ||
}); | ||
buttonType: 'minimal', | ||
}) | ||
|
||
taskNameCell.insertAdjacentElement('afterend', link); | ||
} | ||
); | ||
taskNameCell.insertAdjacentElement('afterend', link) | ||
}, | ||
) | ||
|
||
// 2020 My Tasks view, possibly other similar views. | ||
togglbutton.render('.MyTasksTaskRow:not(.toggl)', { observe: true }, | ||
togglbutton.render( | ||
'.MyTasksTaskRow:not(.toggl)', | ||
{ observe: true }, | ||
function (elem) { | ||
if (elem.querySelector('.toggl-button')) { | ||
// Due to the way this UI is rendered, we must check for existence of old buttons manually. | ||
return; | ||
return | ||
} | ||
const descriptionSelector = () => elem.querySelector('.TaskName textarea').textContent; | ||
const descriptionSelector = () => | ||
elem.querySelector('.TaskName textarea').textContent | ||
|
||
// attempt at separating projects and tags, which are not differentiated in the dom | ||
// assume first pill is a project and any others are tags | ||
// misses tags which are in the "..." overflow, and if there is a tag without a project | ||
const pillSelector = (type) => { | ||
const pills = [...elem.querySelectorAll('.Pill')] | ||
.map(pill => pill.textContent.trim()); | ||
const pills = [...elem.querySelectorAll('.Pill')].map((pill) => | ||
pill.textContent.trim(), | ||
) | ||
if (type === 'project') { | ||
return pills.length ? pills : ''; | ||
return pills.length ? pills : '' | ||
} else if (type === 'tags') { | ||
return pills.length > 1 ? pills.slice(1) : []; | ||
return pills.length > 1 ? pills.slice(1) : [] | ||
} | ||
}; | ||
} | ||
|
||
const projectSelector = () => { | ||
return pillSelector('project'); | ||
}; | ||
return pillSelector('project') | ||
} | ||
|
||
const tagsSelector = () => { | ||
return pillSelector('tags'); | ||
}; | ||
return pillSelector('tags') | ||
} | ||
|
||
const link = togglbutton.createTimerLink({ | ||
className: 'asana-new-ui', | ||
description: descriptionSelector, | ||
projectName: projectSelector, | ||
tags: tagsSelector, | ||
buttonType: 'minimal' | ||
}); | ||
buttonType: 'minimal', | ||
}) | ||
|
||
const wrapper = document.createElement('div'); | ||
wrapper.style.margin = '3px 0 0 4px'; | ||
wrapper.appendChild(link); | ||
const wrapper = document.createElement('div') | ||
wrapper.style.margin = '3px 0 0 4px' | ||
wrapper.appendChild(link) | ||
|
||
elem.appendChild(wrapper); | ||
} | ||
); | ||
elem.appendChild(wrapper) | ||
}, | ||
) | ||
|
||
// Task detail. My Tasks, Spreadsheet, Board, ... | ||
togglbutton.render('.TaskPane:not(.toggl)', { observe: true }, | ||
taskPaneEl => { | ||
if (taskPaneEl.querySelector('.toggl-button')) { | ||
// Due to the way this UI is rendered, we must check for existence of old buttons manually. | ||
return; | ||
} | ||
togglbutton.render('.TaskPane:not(.toggl)', { observe: true }, (taskPaneEl) => { | ||
if (taskPaneEl.querySelector('.toggl-button')) { | ||
// Due to the way this UI is rendered, we must check for existence of old buttons manually. | ||
return | ||
} | ||
|
||
const descriptionSelector = () => taskPaneEl.querySelector('.TaskPaneTitle textarea').textContent.trim(); | ||
const descriptionSelector = () => | ||
taskPaneEl.querySelector('.TaskPaneTitle textarea').textContent.trim() | ||
|
||
const projectSelector = () => { | ||
const projectElement = taskPaneEl.querySelector('.TokenizerPillBase-name'); | ||
if (!projectElement) return ''; | ||
const projectSelector = () => { | ||
const projectElement = taskPaneEl.querySelector( | ||
'.TaskProjectTokenPill-tokenPillWrapper .TaskProjects-projectTokenPill span', | ||
) | ||
if (!projectElement) return '' | ||
|
||
return projectElement.textContent.trim(); | ||
}; | ||
return projectElement.textContent.trim() | ||
} | ||
|
||
const tagsSelector = () => { | ||
const tags = taskPaneEl.querySelectorAll('.TokenizerPillBase-name'); | ||
return [...tags].map(tag => tag.textContent.trim()); | ||
} | ||
const tagsSelector = () => { | ||
const tags = taskPaneEl.querySelectorAll('.TaskTagTokenPills-potPill span') | ||
return [...tags].map((tag) => tag.textContent.trim()) | ||
} | ||
|
||
const link = togglbutton.createTimerLink({ | ||
className: 'TaskPaneToolbar-button', | ||
description: descriptionSelector, | ||
projectName: projectSelector, | ||
buttonType: 'minimal', | ||
tags: tagsSelector | ||
}); | ||
const link = togglbutton.createTimerLink({ | ||
className: 'TaskPaneToolbar-button', | ||
description: descriptionSelector, | ||
projectName: projectSelector, | ||
buttonType: 'minimal', | ||
tags: tagsSelector, | ||
}) | ||
|
||
const injectContainer = taskPaneEl.querySelector('.TaskPaneExtraActionsButton'); | ||
const injectContainer = taskPaneEl.querySelector( | ||
'.TaskPaneExtraActionsButton', | ||
) | ||
|
||
if (injectContainer) { | ||
injectContainer.parentNode.insertBefore(link, injectContainer.nextSibling); | ||
} | ||
if (injectContainer) { | ||
injectContainer.parentNode.insertBefore(link, injectContainer.nextSibling) | ||
} | ||
); | ||
}) |
Oops, something went wrong.