Last active
April 19, 2023 12:56
-
-
Save mtib/b64391657cab1cffdb6447e0de76caf1 to your computer and use it in GitHub Desktop.
Revisions
-
mtib revised this gist
Apr 19, 2023 . 1 changed file with 135 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,135 @@ // ==UserScript== // @name AsanaAdditions // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author [email protected] // @match https://app.asana.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=asana.com // @grant none // ==/UserScript== (function() { 'use strict'; /** * @param {object} options * @param {string} options.key * @param {({ title, taskId }: { title: string; taskId: string; }) => { label: string; value: string; onClick?: () => void; }} options.toRow */ const updateAsanaRow = (options) => { const { key } = options; const taskRegex = /^\/\d+(\/\S+)?\/(\d+|inbox)\/(\d+)/ const taskMatch = taskRegex.exec(window.location.pathname); if (!taskMatch) { return; } const taskId = taskMatch[3]; const tableElement = document.querySelector('.TaskPaneFields'); const titleElement = document.querySelector('div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); if (!tableElement) { throw new Error('Cannot find required DOM elements: tableElement'); } if (!titleElement) { throw new Error('Cannot find required DOM elements: titleElement'); } const title = titleElement.innerHTML; const { label, value, onClick } = options.toRow({ title, taskId }); const rootElementId = `boost-watched-${key}`; const existingRoot = document.getElementById(rootElementId); if (existingRoot && existingRoot.dataset.label === label && existingRoot.dataset.value === value) { return; } else if (existingRoot && existingRoot.parentElement) { existingRoot.parentElement.removeChild(existingRoot); } const addedRowElement = document.createElement('div'); addedRowElement.id = rootElementId; addedRowElement.dataset.value = value; addedRowElement.dataset.label = label; addedRowElement.classList.add('LabeledRowStructure'); const labelDiv1 = document.createElement('div'); labelDiv1.classList.add('LabeledRowStructure-left'); labelDiv1.style.width = '120px'; addedRowElement.appendChild(labelDiv1); const labelDiv2 = document.createElement('div'); labelDiv2.classList.add('LabeledRowStructure-labelContainer'); labelDiv1.appendChild(labelDiv2); const labelLabel = document.createElement('label'); labelLabel.classList.add('LabeledRowStructure-label'); labelLabel.innerHTML = label; labelDiv2.appendChild(labelLabel); const valueDiv1 = document.createElement('div'); valueDiv1.classList.add('LabeledRowStructure-right'); addedRowElement.appendChild(valueDiv1); const valueDiv2 = document.createElement('div'); valueDiv2.classList.add('LabeledRowStructure-content'); valueDiv2.style.display = 'flex'; valueDiv2.style.gap = '10px'; valueDiv1.appendChild(valueDiv2); const follower = document.createElement('span'); follower.style.color = '#272'; const clickableBranchNameElement = document.createElement('span'); clickableBranchNameElement.style.minWidth = '0px'; clickableBranchNameElement.style.flexShrink = '1'; clickableBranchNameElement.style.textOverflow = 'ellipsis'; clickableBranchNameElement.style.whiteSpace = 'nowrap'; clickableBranchNameElement.style.overflow = 'hidden'; clickableBranchNameElement.innerHTML = value; if (onClick) { clickableBranchNameElement.style.cursor = 'pointer'; clickableBranchNameElement.onclick = () => { onClick(); follower.innerHTML = 'clicked!'; } } valueDiv2.appendChild(clickableBranchNameElement); valueDiv2.appendChild(follower); tableElement.insertBefore(addedRowElement, tableElement.childNodes[tableElement.childNodes.length -1]); } const updateBranchName = () => { updateAsanaRow({ key: 'boost-branch-id', toRow: ({ title, taskId }) => { const branchName = [...(title.toLocaleLowerCase().replace(/[^a-z0-9 ]/ig, '').split(' ').slice(0, 8)), taskId].join('-'); return { label: 'Canonical branch', value: branchName, onClick: () => { navigator.clipboard.writeText(branchName); } } } }) } const updateCatsay = () => { updateAsanaRow({ key: 'cat', toRow: ({title}) => { const url = new URL(`https://cataas.com/cat/says/${encodeURIComponent(title)}`); const imgElement = document.createElement('img'); imgElement.src = url.href; imgElement.style.width = '100%'; console.log(imgElement.outerHTML); return { label: 'Cat', value: imgElement.outerHTML }; }}); } window.setInterval(() => { updateBranchName(); updateAsanaRow({ key: 'numberwang', toRow: () => ({ label: 'Numberwang', value: Math.random() })}); updateCatsay(); }, 1000); })(); -
mtib revised this gist
Apr 19, 2023 . 1 changed file with 57 additions and 20 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,9 +1,10 @@ /** * @param {object} options * @param {string} options.key * @param {({ title, taskId }: { title: string; taskId: string; }) => { label: string; value: string; onClick?: () => void; }} options.toRow */ const updateAsanaRow = (options) => { const { key } = options; const taskRegex = /^\/\d+(\/\S+)?\/(\d+|inbox)\/(\d+)/ const taskMatch = taskRegex.exec(window.location.pathname); @@ -24,19 +25,21 @@ const addBranchName = () => { } const title = titleElement.innerHTML; const { label, value, onClick } = options.toRow({ title, taskId }); const rootElementId = `boost-watched-${key}`; const existingRoot = document.getElementById(rootElementId); if (existingRoot && existingRoot.dataset.label === label && existingRoot.dataset.value === value) { return; } else if (existingRoot && existingRoot.parentElement) { existingRoot.parentElement.removeChild(existingRoot); } const addedRowElement = document.createElement('div'); addedRowElement.id = rootElementId; addedRowElement.dataset.value = value; addedRowElement.dataset.label = label; addedRowElement.classList.add('LabeledRowStructure'); const labelDiv1 = document.createElement('div'); @@ -48,7 +51,7 @@ const addBranchName = () => { labelDiv1.appendChild(labelDiv2); const labelLabel = document.createElement('label'); labelLabel.classList.add('LabeledRowStructure-label'); labelLabel.innerHTML = label; labelDiv2.appendChild(labelLabel); const valueDiv1 = document.createElement('div'); @@ -64,23 +67,57 @@ const addBranchName = () => { follower.style.color = '#272'; const clickableBranchNameElement = document.createElement('span'); clickableBranchNameElement.style.minWidth = '0px'; clickableBranchNameElement.style.flexShrink = '1'; clickableBranchNameElement.style.textOverflow = 'ellipsis'; clickableBranchNameElement.style.whiteSpace = 'nowrap'; clickableBranchNameElement.style.overflow = 'hidden'; clickableBranchNameElement.innerHTML = value; if (onClick) { clickableBranchNameElement.style.cursor = 'pointer'; clickableBranchNameElement.onclick = () => { onClick(); follower.innerHTML = 'clicked!'; } } valueDiv2.appendChild(clickableBranchNameElement); valueDiv2.appendChild(follower); tableElement.insertBefore(addedRowElement, tableElement.childNodes[tableElement.childNodes.length -1]); } const updateBranchName = () => { updateAsanaRow({ key: 'boost-branch-id', toRow: ({ title, taskId }) => { const branchName = [...(title.toLocaleLowerCase().replace(/[^a-z0-9 ]/ig, '').split(' ').slice(0, 8)), taskId].join('-'); return { label: 'Canonical branch', value: branchName, onClick: () => { navigator.clipboard.writeText(branchName); } } } }) } const updateCatsay = () => { updateAsanaRow({ key: 'cat', toRow: ({title}) => { const url = new URL(`https://cataas.com/cat/says/${encodeURIComponent(title)}`); const imgElement = document.createElement('img'); imgElement.src = url.href; imgElement.style.width = '100%'; console.log(imgElement.outerHTML); return { label: 'Cat', value: imgElement.outerHTML }; }}); } window.setInterval(() => { updateBranchName(); updateAsanaRow({ key: 'numberwang', toRow: () => ({ label: 'Numberwang', value: Math.random() })}); updateCatsay(); }, 1000); -
mtib revised this gist
Apr 18, 2023 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -4,14 +4,14 @@ const addBranchName = () => { // Example URL // https://app.asana.com/0/1201323259943344/1203874541847641 // https://app.asana.com/0/1201323259943344/1203874541847641/f const taskRegex = /^\/\d+(\/\S+)?\/(\d+|inbox)\/(\d+)/ const taskMatch = taskRegex.exec(window.location.pathname); if (!taskMatch) { return; } const taskId = taskMatch[3]; const tableElement = document.querySelector('.TaskPaneFields'); const titleElement = document.querySelector('div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); -
mtib revised this gist
Apr 18, 2023 . 1 changed file with 8 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -11,10 +11,6 @@ const addBranchName = () => { return; } const taskId = taskMatch[1]; const tableElement = document.querySelector('.TaskPaneFields'); const titleElement = document.querySelector('div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); @@ -28,7 +24,14 @@ const addBranchName = () => { } const title = titleElement.innerHTML; const branchName = [...(title.toLocaleLowerCase().replace(/[^a-z0-9 ]/ig, '').split(' ').slice(0, 8)), taskId].join('-'); const existingRoot = document.getElementById(addedElementRootIdentifier); if (existingRoot && existingRoot.dataset.title === title && existingRoot.dataset.branch === branchName) { return; } else if (existingRoot && existingRoot.parentElement) { existingRoot.parentElement.removeChild(existingRoot); } const addedRowElement = document.createElement('div'); addedRowElement.id = addedElementRootIdentifier; -
mtib revised this gist
Apr 18, 2023 . 1 changed file with 45 additions and 32 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -16,14 +16,11 @@ const addBranchName = () => { } const taskId = taskMatch[1]; const tableElement = document.querySelector('.TaskPaneFields'); const titleElement = document.querySelector('div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); if (!tableElement) { throw new Error('Cannot find required DOM elements: tableElement'); } if (!titleElement) { @@ -35,34 +32,50 @@ const addBranchName = () => { const addedRowElement = document.createElement('div'); addedRowElement.id = addedElementRootIdentifier; addedRowElement.dataset.title = title; addedRowElement.dataset.branch = branchName; addedRowElement.classList.add('LabeledRowStructure'); const labelDiv1 = document.createElement('div'); labelDiv1.classList.add('LabeledRowStructure-left'); labelDiv1.style.width = '120px'; addedRowElement.appendChild(labelDiv1); const labelDiv2 = document.createElement('div'); labelDiv2.classList.add('LabeledRowStructure-labelContainer'); labelDiv1.appendChild(labelDiv2); const labelLabel = document.createElement('label'); labelLabel.classList.add('LabeledRowStructure-label'); labelLabel.innerHTML = 'Canonical branch'; labelDiv2.appendChild(labelLabel); const valueDiv1 = document.createElement('div'); valueDiv1.classList.add('LabeledRowStructure-right'); addedRowElement.appendChild(valueDiv1); const valueDiv2 = document.createElement('div'); valueDiv2.classList.add('LabeledRowStructure-content'); valueDiv2.style.display = 'flex'; valueDiv2.style.gap = '10px'; valueDiv1.appendChild(valueDiv2); const follower = document.createElement('span'); follower.style.color = '#272'; const clickableBranchNameElement = document.createElement('span'); clickableBranchNameElement.style.cursor = 'pointer'; clickableBranchNameElement.style.minWidth = '0px'; clickableBranchNameElement.style.flexShrink = '1'; clickableBranchNameElement.style.textOverflow = 'ellipsis'; clickableBranchNameElement.style.whiteSpace = 'nowrap'; clickableBranchNameElement.style.overflow = 'hidden'; clickableBranchNameElement.innerHTML = branchName; clickableBranchNameElement.onclick = () => { navigator.clipboard.writeText(branchName); follower.innerHTML = 'copied!'; } valueDiv2.appendChild(clickableBranchNameElement); valueDiv2.appendChild(follower); tableElement.insertBefore(addedRowElement, tableElement.childNodes[tableElement.childNodes.length -1]); } window.setInterval(() => { -
mtib revised this gist
Apr 18, 2023 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -17,7 +17,8 @@ const addBranchName = () => { const taskId = taskMatch[1]; const titleElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea') || document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); const containerElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer') || document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer'); -
mtib revised this gist
Apr 18, 2023 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -19,8 +19,8 @@ const addBranchName = () => { const titleElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); const containerElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer') || document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer'); if (!containerElement) { throw new Error('Cannot find required DOM elements: containerElement'); } -
mtib created this gist
Apr 18, 2023 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ const addedElementRootIdentifier = 'boost-branch-id-row'; const addBranchName = () => { // Example URL // https://app.asana.com/0/1201323259943344/1203874541847641 // https://app.asana.com/0/1201323259943344/1203874541847641/f const taskRegex = /^\/\d+\/\d+\/(\d+)/ const taskMatch = taskRegex.exec(window.location.pathname); if (!taskMatch) { return; } if (document.getElementById(addedElementRootIdentifier)) { return; } const taskId = taskMatch[1]; const titleElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer > div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); const containerElement = document.querySelector('#asana_full_page > div.FocusModePage > div > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer') || document.querySelector('#asana_main_page > div.ProjectPage > div.ProjectPage-board > div > div > div > div.FullWidthPageStructureWithDetailsOverlay-detailsOverlay.FullWidthPageStructureWithDetailsOverlay-detailsOverlay--visible > article > div.UploadDropTargetAttachmentWrappingTextEditor.TaskPane-attachmentDropTarget > div.DynamicBorderScrollable.DynamicBorderScrollable--canScrollDown.TaskPane-scrollable > div > div > div.TaskPane-resizeListenerContainer'); if (!containerElement) { throw new Error('Cannot find required DOM elements: containerElement'); } if (!titleElement) { throw new Error('Cannot find required DOM elements: titleElement'); } const title = titleElement.innerHTML; const branchName = [...(title.toLocaleLowerCase().replace(/[^a-z0-9 ]/ig, '').split(' ')), taskId].join('-'); const addedRowElement = document.createElement('div'); addedRowElement.id = addedElementRootIdentifier; addedRowElement.style.marginBottom = '10px'; addedRowElement.style.display = 'flex'; addedRowElement.style.gap = '10px'; addedRowElement.style.alignItems = 'center'; const buttonElement = document.createElement('button'); const buttonElementBg = '#336'; buttonElement.onmouseenter = () => { buttonElement.style.backgroundColor = '#447'; } buttonElement.onmouseleave = () => { buttonElement.style.backgroundColor = buttonElementBg; } buttonElement.innerHTML = branchName; buttonElement.style.border = '1px solid #338'; buttonElement.style.borderRadius = '4px'; buttonElement.style.backgroundColor = buttonElementBg; buttonElement.style.padding = '3px 5px'; buttonElement.onclick = () => { navigator.clipboard.writeText(branchName); } const spanElement = document.createElement('span'); spanElement.innerHTML = 'Recommended branch name:'; addedRowElement.appendChild(spanElement); addedRowElement.appendChild(buttonElement); containerElement.appendChild(addedRowElement); } window.setInterval(() => { addBranchName(); }, 1000);