Erstellt von: @ShunS
Die Originalversion des Beitrags auf Englisch ist unter folgendem Link verfügbar: Introduction to Asana bookmarklets
Alle Aufgaben eines Projekts als erledigt/unerledigt markieren, alle Abschnitte eines Projekts ein-/ausblenden, alle Kommentare einer Aufgabe anzeigen – all diese Massenaktionen können mit nur einem Klick durchgeführt werden.
0. Was sind Bookmarklets?
Bookmarklets sind in JavaScript programmierte Snippets, die als Browser-Lesezeichen hinzugefügt und durch Anklicken ausgeführt werden. Man kann JavaScript-Snippets mit Lesezeichen versehen, indem man sie mit javascript:(function() {
und })();
einschließt.
Das Frontend einer Website, darunter Asana, setzt sich hauptsächlich aus drei Sprachen zusammen: HTML (eine Markup-Sprache zur Markierung von Bestandteilen einer Seite), CSS (eine Programmiersprache zur Festlegung des Layouts und des Designs) und JavaScript (eine Programmiersprache).
Tag-Paare in HTML bilden strukturierte Einheiten (Knoten), die von JavaScript bedient werden können. Diese Interaktion nennt man DOM (Document Object Model).
1. Bookmarklets hinzufügen
Besuchen Sie Asana bookmarklets, und ziehen Sie die blauen Links in die Lesezeichenleiste des Browsers, um sie hinzuzufügen.
Ich empfehle, einen Ordner zu erstellen, damit die Bookmarklets nicht zu viel Platz in der Lesezeichenleiste einnehmen. Werden sie direkt in die Lesezeichenleiste eingefügt, empfiehlt es sich, den Namen zu bearbeiten und nur das Emoji beizubehalten.
Beim manuellen Hinzufügen der Bookmarklets gehen Sie wie folgt vor:
-
Fügen Sie eine beliebige Webseite als Lesezeichen hinzu.
-
Klicken Sie beim Hinzufügen auf „Mehr…“, wählen Sie den Ordner aus, und bearbeiten Sie anschließend den Namen und die URL.
-
Geben Sie unter „Name“ die Titel der Bookmarklets und unter „URL“ den mit „javascript:“ beginnenden Code ein.
Wenn Sie in der Liste der Bookmarklets einen Abschnitt erstellen möchten, empfehle ich die Verwendung von Chrome Bookmarks Separator.
Durch Anklicken der gespeicherten Bookmarklets auf einem Asana-Tab können Sie die automatischen Aktionen ausführen.
2. Derzeitige Bookmarklets
Der Quellcode und die Beschreibung der Bookmarklets sind hier aufgeführt: Asana-Bookmarklets
2-1. Vorgänge für eine Aufgabe
2-1-1.
Story-Bereinigung
Aktivieren Sie unten die Optionen „Kommentare ausklappen” und „Verknüpfte Arbeitslinks ausblenden”.
javascript:(function() {
const expandLink = document.querySelector('.TaskStoryFeed-expandLink');
if (expandLink && expandLink.textContent.match(/\d/)) expandLink.click();
document.querySelectorAll('.TruncatedRichText-expand').forEach(link => link.click());
document.querySelectorAll('.TaskStoryFeed-expandMiniStoriesLink').forEach(link => link.click());
document.querySelectorAll('.BacklinkMiniStory').forEach(line => {line.parentNode.style.display = 'none';});
})();
2-1-2.
Kommentare ausklappen
In den Aufgaben-Storys auf „7 weitere Kommentare” klicken und „Mehr anzeigen”.
javascript:(function() {
const expandLink = document.querySelector('.TaskStoryFeed-expandLink');
if (expandLink && expandLink.textContent.match(/\d/)) expandLink.click();
document.querySelectorAll('.TruncatedRichText-expand').forEach(link => link.click());
document.querySelectorAll('.TaskStoryFeed-expandMiniStoriesLink').forEach(link => link.click());
})();
2-1-3. ↔ Verknüpfte Arbeitslinks ausblenden
Ausblenden aller “<user_name> hat diese Aufgabe in einer anderen Aufgabe erwähnt: <task_link>” in Aufgaben-Storys. Diese Option ist dann sinnvoll, wenn eine Aufgabe in zu vielen Aufgaben erwähnt wird, so dass andere Kommentare und Anhänge schwer zu finden sind.
javascript:(function() {
document.querySelectorAll('.BacklinkMiniStory').forEach(line => {line.parentNode.style.display = 'none';});
})();
2-1-4. ⫚ Erledigte Aufgaben ausblenden
Alle erledigten Unteraufgaben im Aufgabenfenster rechts ausblenden. Durch erneutes Anklicken des Bookmarklets werden sie wieder angezeigt.
Bei vielen Unteraufgaben empfehle ich auch die Chrome-Erweiterung Asana Load More.
javascript:(function() {
const completedSubtaskRows = document.querySelectorAll('.SubtaskTaskRow--completed');
completedSubtaskRows.forEach(row => {
row.parentNode.parentNode.style.display = row.parentNode.parentNode.style.display? '': 'none';
});
})();
2-2. Vorgänge in einer Liste von Aufgaben (z. B. in einem Projekt)
**Hinweis: Wenn bei einer großen Anzahl von Aufgaben einige nicht im Fenster erscheinen, scrollen Sie einfach den Asana-Tab nach unten, um alle Aufgaben zu laden, bevor Sie diese Bookmarklets aufrufen. **
2-2-1.
︎ Zwischen Abschnitten hin- und herwechseln
Umschalten zwischen Ein- und Ausblenden von Abschnitten in der Listenansicht.
javascript:(function() {
const firstButtonIcon = document.querySelector('.TaskGroupHeader-toggleButton .Icon');
if (!firstButtonIcon) return;
const firstTriangleClassName = firstButtonIcon.classList.contains('DownTriangleIcon')? 'DownTriangleIcon': 'RightTriangleIcon';
document.querySelectorAll(`.TaskGroupHeader-toggleButton .${firstTriangleClassName}`).forEach(buttonIcon => buttonIcon.parentNode.click());
})();
2-2-2. ▷ Unteraufgaben ein- und ausblenden
Aktivieren Sie das Ein- und Ausblenden von Unteraufgaben in der Listenansicht, indem Sie auf die kleinen -Symbole klicken, die auf vorhandene Unteraufgaben hinweisen. Bei vielen Unteraufgaben muss das Bookmarklet auf jeden Link „Weitere Unteraufgaben laden” klicken, was einige Zeit in Anspruch nimmt.
javascript:(function() {
const firstSubtaskButton = document.querySelector('.ProjectSpreadsheetGridRow-subtaskToggleButton');
const firstTriangleClassName = firstSubtaskButton.firstElementChild.classList.contains('DownTriangleIcon')? 'DownTriangleIcon': 'RightTriangleIcon';
const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
const taskGroup = document.querySelector('.TaskGroup');
const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
setTimeout(function () {if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();}, 30);
setTimeout(function () {taskGroup.style.display = 'none';}, 60);
let monitorTaskStructure = setInterval(() => {
if (taskPlaceholderHTMLCollection.length == 0) {
document.querySelectorAll('.ProjectSpreadsheetGridRow-subtaskToggleButton').forEach(function (buttonIcon) {
if (buttonIcon.firstElementChild.classList.contains(firstTriangleClassName)) buttonIcon.click();
});
taskGroup.style.display = '';
clearInterval(monitorTaskStructure);
const loadMoreLinkHTMLCollection = document.getElementsByClassName('SpreadsheetTaskList-showMoreLink');
setTimeout(() => {
let clickingLoadMoreLinks = setInterval(function() {
if (!loadMoreLinkHTMLCollection.length) {
clearInterval(clickingLoadMoreLinks);
} else {
loadMoreLinkHTMLCollection[0].scrollIntoView();
loadMoreLinkHTMLCollection[0].click();
}
}, 100);
}, 200);
}
}, 100);
})();
2-2-3.
Alle Aufgaben erledigen
Alle sichtbaren, nicht erledigten Aufgaben in der Listenansicht als erledigt kennzeichnen. Bei einer Vielzahl von Aufgaben blendet das Bookmarklet vorübergehend alle Aufgaben aus und klickt jeweils 50 Aufgaben auf einmal an.
javascript:(function() {
const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
if (!taskPlaceholderHTMLCollection.length) {
document.querySelectorAll('.TaskRowCompletionStatus-taskCompletionIcon--incomplete').forEach(incompleteIcon => incompleteIcon.parentNode.click());
} else {
const taskGroup = document.querySelector('.TaskGroup');
const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
setTimeout(function () {if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();}, 30);
setTimeout(function () {
taskGroup.style.display = 'none';
const progressIndicator = document.createElement('span');
progressIndicator.setAttribute('id', 'progressIndicator');
progressIndicator.textContent = 'Wird ausgeführt';
taskGroup.parentNode.appendChild(progressIndicator);
}, 60);
let monitorTaskStructure = setInterval(() => {
if (taskPlaceholderHTMLCollection.length == 0) {
clearInterval(monitorTaskStructure);
const progressIndicator = document.querySelector('#progressIndicator');
const allTasks = Array.from(document.querySelectorAll('.TaskRowCompletionStatus-taskCompletionIcon--incomplete'));
const numProcesses = Math.floor(allTasks.length / 50) + 1;
let counter = 0;
let loopTasks = setInterval(() => {
progressIndicator.textContent = `Wird ausgeführt (${counter}/${numProcesses})`;
for (let i = 50 * counter; i < Math.min(allTasks.length, 50 * (counter + 1)); i++) {
allTasks[i].parentNode.click();
if (i == allTasks.length - 1) {
clearInterval(loopTasks);
progressIndicator.remove();
taskGroup.style.display = '';
}
}
counter += 1;
}, 500);
}
}, 100);
}
})();
2-2-4.
Alle Aufgaben als nicht erledigt kennzeichnen
Alle sichtbaren, erledigten Aufgaben in der Listenansicht wieder als nicht erledigt markieren. Bei einer großen Anzahl von Aufgaben blendet das Bookmarklet vorübergehend alle Aufgaben aus und klickt jeweils 50 Aufgaben auf einmal an.
javascript:(function() {
const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
if (!taskPlaceholderHTMLCollection.length) {
document.querySelectorAll('.TaskRowCompletionStatus-taskCompletionIcon--complete').forEach(incompleteIcon => incompleteIcon.parentNode.click());
} else {
const taskGroup = document.querySelector('.TaskGroup');
const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
setTimeout(function () {if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();}, 30);
setTimeout(function () {
taskGroup.style.display = 'none';
const progressIndicator = document.createElement('span');
progressIndicator.setAttribute('id', 'progressIndicator');
progressIndicator.textContent = 'Wird ausgeführt';
taskGroup.parentNode.appendChild(progressIndicator);
}, 60);
let monitorTaskStructure = setInterval(() => {
if (taskPlaceholderHTMLCollection.length == 0) {
clearInterval(monitorTaskStructure);
const progressIndicator = document.querySelector('#progressIndicator');
const allTasks = Array.from(document.querySelectorAll('.TaskRowCompletionStatus-taskCompletionIcon--complete'));
const numProcesses = Math.floor(allTasks.length / 50) + 1;
let counter = 0;
let loopTasks = setInterval(() => {
progressIndicator.textContent = `Wird ausgeführt (${counter}/${numProcesses})`;
for (let i = 50 * counter; i < Math.min(allTasks.length, 50 * (counter + 1)); i++) {
allTasks[i].parentNode.click();
if (i == allTasks.length - 1) {
clearInterval(loopTasks);
progressIndicator.remove();
taskGroup.style.display = '';
}
}
counter += 1;
}, 500);
}
}, 100);
}
})();
2-3. Andere Vorgänge
2-3-1.☰ Größe der Seitenleiste verändern
Durch Verdoppeln der Breite der Seitenleiste auf 480 Pixel werden lange Projektnamen besser lesbar. Klicken Sie erneut auf das Bookmarklet, um zur Standardbreite zurückzukehren.
Dieser Beitrag entstand in Anlehnung an @Ian_Housers Bookmarklet auf https://forum.asana.com/t/sidebar-adjust-size-width/27297/14!
javascript:(function() {
const widerWidth = '480px';
const asanaSidebar = document.querySelector('.AsanaMain-sidebar');
if (!asanaSidebar) return;
var newStyle = document.querySelector('#asanaSidebarBookmarkletStyle');
if (!newStyle) {
newStyle = document.createElement('style');
newStyle.id = 'asanaSidebarBookmarkletStyle';
document.head.appendChild(newStyle);
}
if (asanaSidebar.style.width == widerWidth) {
asanaSidebar.style.width = '240px';
newStyle.innerText = '';
} else {
asanaSidebar.style.width = widerWidth;
newStyle.innerText = `.AsanaMain-sidebar.AsanaMain-sidebar--isCollapsed {margin-left: -${widerWidth} !important}`;
}
})();
3. Herausforderungen
3-1. Aufgaben mit Platzhaltern
Bei einem Projekt mit vielen Aufgaben wandelt Asana einige der Aufgaben, die sich weit außerhalb des Ansichtsbereichs befinden, in vereinfachte Platzhalter um. Diese enthalten lediglich Aufgabennamen, um Ressourcen zu sparen (z. B. Speicher und Energieverbrauch). Beim Scrollen in der Nähe der Platzhalter-Aufgaben werden die Daten erneut geladen.
Beispiel: Beim Scrollen vom unteren Ende des Projekts aus werden die Aufgaben in der Nähe des oberen Endes für kurze Zeit nur mit Namen angezeigt. Weniger als eine Sekunde später werden sie vollständig angezeigt.
Wenn man wie in Abschnitt 2-2 sämtliche Aufgaben anvisiert, blendet man vorübergehend alle Aufgaben aus, wodurch Asana den Eindruck hat, dass genügend Platz vorhanden ist, um alle Aufgaben anzuzeigen. Nachdem Asana alle Platzhalteraufgaben als vollständige Aufgaben wiederhergestellt hat, läuft die Automatisierung. Danach können Sie das Ausblenden wieder rückgängig machen.
3-2. Minderung von Ladezeiten
Wenn Sie zu viele Vorgänge auf einmal ausführen, belasten Sie den Asana-Server. Bei der Verwendung der Asana-API oder bei der Durchführung von Massenaktionen für mehrfach ausgewählte Aufgaben gibt es Grenzen von etwa 50 Aufgaben. Daher habe ich beschlossen, in den oben aufgeführten Bookmarklets „Alle Aufgaben als erledigt/unerledigt markieren” jeweils 50 Aufgaben auf einmal zu verarbeiten.
4. Vergleich mit anderen Verfahren
4-1. Vergleich mit anderen JavaScript-Methoden
Vergleichen wir nun verschiedene Methoden, um bestimmte Vorgänge mit Asana zu automatisieren. Die Methoden links sind komplizierter und leistungsfähiger, während die Methoden rechts einfacher sind. Ein Bookmarklet ist eine ziemlich einfache Methode, da wir im Vergleich zur Entwicklung einer Chrome-Erweiterung nur 1/100 oder 1/10 der Zeilen programmieren müssen. Allerdings müssen wir immer noch eine gewisse Länge an Programmcode schreiben, wenn wir die in Abschnitt 3 beschriebenen Herausforderungen berücksichtigen.
Methoden: | OAuth | Personal Access Token (PAT) | Chrome-Erweiterungen | Bookmarklets | Browser-Adresszeile |
---|---|---|---|---|---|
Beispiele: | Melden Sie sich bei Asana Academy mit Ihrem Asana-Konto an. | Die offizielle Erweiterung von Asana | Zu diesem Thema aufgeführt | Abrufen der Liste der Arbeitsbereiche | |
Authentifizierung: | Einrichten eines Servers | PAT hartkodieren oder in Umgebungsvariablen speichern | Browser-Cookie mit Benutzeranmeldung verwenden | Cookie (ditto) | Cookie (ditto) |
Zugriff: | Zugriff gewähren | PAT verwenden | Installieren von Chrome Web Store | Zu Lesezeichen hinzufügen | URL in Adressleiste eingeben |
Kann Folgendes: | Operationen über API | Operationen über API | Operationen über API+DOM | Operationen über DOM | GET-Operationen über API (Informationen abrufen) |
Eignet sich gut für: | Groß angelegte Tools | Schreiben von Skripten für den persönlichen Gebrauch | Verteilung | Einfache Erstellung und Verteilung | Einfachste Nutzung |
Kann Folgendes nicht: | Operationen durch DOM | Operationen durch DOM | (einige Dinge natürlich) | Unsichtbare Aufgaben ausführen | POST/PUT/DELETE-Operationen (Informationen bearbeiten) |
Wie man große Daten verwaltet: | Paginierung | Paginierung | Paginierung | Platzhalteraufgaben | Paginierung (nicht automatisierbar) |
Example: Alle Aufgaben in einem Projekt erledigen
Ein Bookmarklet funktioniert einfacher und schneller.
-
Mit der API senden wir zunächst eine GET-Anforderung an den Endpunkt
/projects/<project_gid>/tasks
, um die Aufgaben im Projekt abzurufen. Dann durchlaufen wir die Aufgaben in einer Schleife und senden PUT-Anforderungen, um die jeweilige Aufgabe zu erledigen. Für den Abruf und die Aktualisierung von Informationen müssen wir zwei Runden von API-Aufrufen durchführen. -
Bei Bookmarklets werden die angezeigten Aufgaben direkt durchlaufen und angeklickt.
4-2. Vergleich von JavaScript und CSS
Mit CSS lässt sich das Design von Asana anpassen. Die wesentlichen Unterschiede von CSS sind folgende:
-
Authentifizierung nicht erforderlich, da keine Interaktion mit API
-
Kann „immer” das Design von HTML-Elementen ändern
-
Kann nicht dynamisch reagieren, wenn bestimmte Änderungen eintreten oder der Nutzer einen bestimmten Vorgang ausführt
Vorgehensweise bei der CSS-Anpassung: Installieren Sie Chrome-Erweiterungen wie Stylish oder User CSS. Sie können entweder benutzerdefinierte CSS-Einstellungen verwenden, die von anderen Nutzern aus Bibliotheken wie userstyles.org erstellt wurden, oder eigene CSS-Regeln erstellen.
Example: Breite der Seitenleiste ändern
-
Beim Anklicken des unter 2-3-1 erwähnten Bookmarklets wird die Seitenleiste vergrößert/verkleinert
-
Soll die Breite der Seitenleiste „immer” geändert werden, dann ist es sinnvoller, CSS anzupassen
5. Betrachtungen
5-1. Reverse Engineering
Die API-Bedingungen von Asana untersagen Reverse Engineering. Die Identifizierung von DOM-Elementen durch Rechtsklick und Auswahl von „Inspect” ist jedoch generell möglich. Ich glaube nicht, dass jemand dadurch in irgendeiner Weise auf geschützte Daten von Asana zugreift.
5-2. Mögliche Designänderungen
Asana kann jederzeit IDs und Klassennamen ändern, die wir zur Identifizierung von HTML-Elementen im Asana-Tool einsetzen. Einige der oben genannten Bookmarklets funktionieren dann nicht mehr. Ich werde den Code aktualisieren, wenn ich die Änderungen bemerke. Ich wäre Ihnen jedoch dankbar, wenn Sie mir in einem Kommentar zu diesem Thema Bescheid geben würden.
5-3. Haftungsausschluss
Ich habe die Bookmarklets mit Sorgfalt entwickelt und getestet, hafte allerdings nicht für Probleme, die sich daraus ergeben.
6. Mein besonderer Dank
-
Ich bin auf die Idee gekommen, Bookmarklets zu verwenden, nachdem ich "COLLAPSE (or re-expand) ALL SECTIONS" button needed - #4 by Tony_Tsui gelesen hatte und dachte, dass es ein einfaches und gutes Werkzeug ist. "COLLAPSE (or re-expand) ALL SECTIONS" button needed - #47 by Skyler präsentiert Bookmarklets, die von einem anderen Nutzer zusammengestellt wurden.
-
Forum Leader @Bastien_Siebman und Ambassador @Itay_Kurgan halfen mir freundlicherweise, einen Teil des Codes in realen Umgebungen zu testen, und gaben mir wertvolle Einblicke, insbesondere in die in Abschnitt 3 genannten Herausforderungen.
-
Vielen Dank, dass Sie diesen Artikel gelesen haben. Bitte hinterlassen Sie einen Kommentar, wenn Sie weitere Funktionen wünschen. Außerdem empfehle ich Ihnen, selbst Bookmarklets zu programmieren, wenn Sie JavaScript beherrschen.
Dieser Beitrag wurde ursprünglich auf Japanisch verfasst: Asanaブックマークレットのご紹介