Der Microsoft Planner ist ein fantastisches Tool. Doch sind wir ehrlich: Einige praktische Funktionen fehlen ganz einfach! Vor einiger Zeit kam mein Kollege David Mehr mit einer Frage auf mich zu: Er wollte alle von ihm erstellten Planner Tasks sehen. Eine solche Ansicht ist in den Standardmitteln nicht vorhanden. Die Nachverfolgung ist mühsam, Tasks bleiben liegen. Er bat mich, eine solche Ansicht zu realisieren.
Kurzer Einschub: Wenn ihr euch näher für den Microsoft Planner interessiert, haben wir einen spannenden Beitrag für euch: «Aufgabenmanagement mit dem Microsoft Planner: Tutorial, Erfahrungsbericht und Empfehlungen | Productivity News vom 01.01.2024»
Die Frage
Geht das? Das habe ich mich auch gefragt, als David mich das fragte. Im Planner im Browser geht es nicht. Also müsste man hier ein SPFX-Webpart entwickeln, dass ich dann im SharePoint oder Teams einbinden kann. Aber gibts APIs dafür? Mein Bauchgefühl sagte ja, also rein in die Dokumentation der Planner API. Der Task-Endpoint bietet hier unter Get tasks for user schon mal 3 Möglichkeiten:
GET /me/planner/tasks
GET /users/{id}/planner/tasks
GET /drive/root/createdByUser/planner/tasks
Doch Obacht! Zuoberst in der Beschreibung steht «Retrieve a list of plannertask objects assigned to a User». Mist! Eben genau das, was wir nicht wollen.
Ich kann das nicht API-Seitig realisieren, also muss ich mir das selber Bauen. Ich brauche also eine Liste aller Tasks in meinem Tenant, die ich dann Client-seitig nach Autor filtern kann. Aber es scheint, als gäbe es keinen Endpoint für alle Tasks im aktuellen Tenant. Ich kann die einzelnen Tasks nur via Plan holen. Im Plan-Endpoint gibts List plan tasks:
GET /planner/plans/{plan-id}/tasks
Doch dieser will die Plan-ID. Ja wie komme ich denn nun an die Plan-ID? Ich sehe, dass es noch List plans for group gibt:
GET /groups/{group-id}/planner/plans
So komme ich nun an alle Plan-Ids einer Group. Doch dieser Endpoint verlangt nun die Group-ID. Aaargh! Das wird kompliziert.
Ich brauche nun noch alle Groups eines Users, dann sollte das klappen. Denn nur wenn ich Mitglied einer Gruppe bin, kann ich auch Planner Tasks erstellen. Auf dem User-Endpoint gibts List transitive member of, welcher mir alle meine Gruppen returniert. Super!
GET /me/transitiveMemberOf
GET /users/{id | userPrincipalName}/transitiveMemberOf
Der Plan
Ich brauche also:
- Den aktuellen User
- Eine Liste aller Gruppen, in denen der aktuelle User Mitglied ist.
- Alle Plans dieser jeweiligen Gruppen
- Alle Tasks dieser jeweiligen Plans, gefiltert nach Creator = Current User
- Eine gesammelte Liste all dieser Tasks, die ich dann darstellen kann
Das klingt nach vielen Requests. Wir sind oft Member in Dutzenden Teams. Und ich muss die Tasks alle clientseitig filtern, also dauert es lange, denn wir haben zum Teil Tausende Tasks in gewissen Gruppen.
Die Umsetzung
Dieses Freitagsnachmittagsprojekt wurde jetzt also doch aufregender als anfangs gedacht. Ein neues SPFX-Webpart erstellt und mit React die Cards programmiert, die wir in diesem Zug auch grade noch etwas erweitern können.
David wollte das Erstell- und das Enddatum angezeigt haben, die Priorität, sowie wem der Task aktuell gerade zugewiesen ist. Falls das Enddatum in der Vergangenheit liegt, soll dieses Rot markiert werden. Dann der Teil mit den Daten: Zuerst die Memberships des aktuellen Users geholt, diese geben mir aber alle, nicht nur Groups, deshalb diese Abfrage noch um einen Filter erweitert. Dann klappte es wie geplant und ich kriege alle Plans dieser Gruppen und alle Tasks dieser Plans. Et voila:
Das Fazit
Meine Befürchtungen bestätigen sich jedoch: Das Laden aller Tasks dauert etwas lange. Für David ist das jedoch eine tiptoppe Lösung. Dieses Webpart ruft man ja nicht mehrmals täglich auf, da kann man auch schnell beim Warten einen Kaffee holen gehen.
Hallo Reto,
besteht die Möglichkeit diesen SPFX-Webpart zu erhalten? Genau diese Funktion suche ich schon seit langer Zeit und habe bisher keine Lösung gefunden. Leider bin ich kein Programmierer und habe daher auch keine Kenntnisse, dies selbst anzulegen.
Freue mich auf deine Antwort