====== Tutorial: Sidebar an Dokument-Tabs binden ====== Dieses Tutorial zeigt, wie ein Add-in seine Sidebar-Views deklarativ an Dokumenttypen bindet. Der Host blendet die richtigen Panels automatisch ein, wenn der Benutzer zwischen Tabs wechselt. Ziel ist es, manuellen ''ShowPanel''/''HidePanel''-Code vollständig durch Manifest-Konfiguration zu ersetzen. Im Unterschied zu manueller Sidebar-Steuerung in ''DoActivated''/''DoDeactivated'' entfällt jeder Boilerplate-Code im Plugin. Der Vorteil besteht darin, dass der Host die Konsistenz garantiert: Beim Wechsel von einem WIS-Tab zu einem Settings-Tab oder zur Willkommensseite werden die WIS-Panels automatisch ausgeblendet und die passenden Settings-Panels eingeblendet. Zurück zur [[..:start|Übersicht]]. ===== Ausgangslage ===== Ein Plugin namens "WIS" hat drei Dokumenttypen und mehrere Sidebar-Panels: | **Dokumenttyp** | **Sidebar-Panel** | **Seite** | | ''wis.proofPlan'' | Organisationsbaum, Filter | Primär | | ''wis.proofExec'' | Organisationsbaum, Filter | Primär | | ''wis.proofExec'' | Aufgaben-Detail | Sekundär | | ''wis.proofForecast'' | Filter | Primär | Das Ziel: Wenn der Benutzer den Tab "Prüfausführung" aktiviert, erscheinen Organisationsbaum und Filter links und das Aufgaben-Detail rechts. Wechselt er zur "Prüfvorschau", bleibt nur der Filter links sichtbar. ===== Schritt 1: Manifest mit documentAffinity ===== Öffne die ''plugin.json'' des WIS-Plugins und ergänze die ''documentAffinity''-Arrays in den View-Deklarationen: { "name": "wis", "displayName": "WIS Prüfungen", "version": "1.0.0", "publisher": "wvds", "kind": "native", "main": "bin/wis.plugin.dll", "activationEvents": [ "onCommand:wis.proofPlan.open", "onCommand:wis.proofExec.open", "onCommand:wis.proofForecast.open" ], "contributes": { "views": { "sidebar": [ { "id": "wis.orgTree", "title": "%nls.orgTree.title%", "icon": "codicon-list-tree", "containerId": "wis.navigation", "documentAffinity": ["wis.proofPlan", "wis.proofExec"] }, { "id": "wis.filter", "title": "%nls.filter.title%", "containerId": "wis.navigation", "documentAffinity": [ "wis.proofPlan", "wis.proofExec", "wis.proofForecast" ] } ], "secondary": [ { "id": "wis.taskDetail", "title": "%nls.taskDetail.title%", "documentAffinity": ["wis.proofExec"], "autoShow": true }, { "id": "wis.ruleDetail", "title": "%nls.ruleDetail.title%", "documentAffinity": ["wis.proofPlan"] } ] } } } Einige Dinge fallen hier auf: * **Geteilte Affinität** — ''wis.filter'' ist an alle drei Dokumenttypen gebunden: Prüfplan, Prüfausführung und Prüfvorschau. Egal welchen Tab der Benutzer aktiviert, der Filter ist immer sichtbar. * **Eingeschränkte Affinität** — ''wis.orgTree'' ist nur an Plan und Exec gebunden. Bei der Vorschau verschwindet der Organisationsbaum. * **Sekundäre Sidebar mit autoShow** — ''wis.taskDetail'' wird nur bei der Prüfausführung angezeigt, und ''autoShow: true'' sorgt dafür, dass die sekundäre Seitenleiste automatisch aufklappt. * **Accordion-Gruppierung** — ''wis.orgTree'' und ''wis.filter'' teilen sich die ''containerId'' ''wis.navigation''. Sie erscheinen als Accordion in der Seitenleiste. ===== Schritt 2: Plugin-Code vereinfachen ===== Entferne den manuellen Sidebar-Code aus den Dokument-Frames: // VORHER — manueller Sidebar-Code (entfernen!): procedure TWISProofExecFrame.DoActivated; begin inherited; FHost.SideBar.ShowPanel('wis.orgTree'); FHost.SideBar.ShowPanel('wis.filter'); end; procedure TWISProofExecFrame.DoDeactivated; begin inherited; FHost.SideBar.HidePanel('wis.orgTree'); FHost.SideBar.HidePanel('wis.filter'); end; // NACHHER — kein Sidebar-Code mehr nötig: procedure TWISProofExecFrame.DoActivated; begin inherited; // Sidebar wird automatisch vom Host gesteuert. // Hier nur noch fachliche Logik (z.B. Daten laden). end; ===== Schritt 3: Verhalten verstehen ===== Der Host führt bei jedem Tab-Wechsel folgende Schritte aus: - **Dokumenttyp bestimmen** — Der aktive Tab liefert seinen Dokumenttyp (z.B. ''wis.proofExec''). - **Affinitäten auswerten** — Der Host prüft alle registrierten Views: Ist der Dokumenttyp in der ''documentAffinity''-Liste enthalten? - **Primäre Sidebar** — Affine Views werden über die ActivityBar aktiviert. Der Benutzer sieht das korrekte Icon und das passende Accordion. - **Sekundäre Sidebar** — Affine Views werden aktiviert. Bei ''autoShow: true'' wird die sekundäre Seitenleiste automatisch sichtbar. - **Optimierung** — Wechselt der Benutzer zwischen zwei Tabs desselben Typs, passiert nichts (kein unnötiges Neuzeichnen). ===== Schritt 4: Testen ===== - Öffne den Tab "Prüfausführung" → Organisationsbaum + Filter links, Aufgaben-Detail rechts. - Öffne den Tab "Prüfvorschau" → Nur Filter links, Aufgaben-Detail verschwindet. - Öffne den Tab "Prüfplan" → Organisationsbaum + Filter links, Regularium-Detail rechts. - Öffne die Willkommensseite → Keine WIS-Panels sichtbar. - Wechsle zurück zum "Prüfausführung"-Tab → Alles erscheint wieder. ===== Erweiterte Szenarien ===== ==== Globale Views ==== Eine View ohne ''documentAffinity'' ist immer sichtbar: { "id": "wis.globalStatus", "title": "Status", "icon": "codicon-info" } Diese View bleibt in der Seitenleiste, egal welcher Tab aktiv ist. ==== Mehrere Plugins, geteilte Sidebar ==== Plugin A und Plugin B können Views mit ''documentAffinity'' deklarieren, die auf ihre jeweiligen Dokumenttypen verweisen. Der Host verwaltet alle Affinities zentral. Beim Tab-Wechsel werden genau die Views des passenden Plugins angezeigt. ==== Benutzer-Override ==== Wenn der Benutzer ein Panel manuell schließt, merkt sich der Host diese Entscheidung. Das Panel wird nicht bei jedem Tab-Wechsel erneut aufgeklappt. Ein Layout-Reset (''workbench.action.resetLayout'') setzt alle Overrides zurück. ===== Zusammenfassung ===== | **Aspekt** | **Ergebnis** | | Manifest-Feld | ''documentAffinity: string[]'' auf View-Ebene | | Plugin-Code | Kein ''ShowPanel''/''HidePanel'' mehr nötig | | Host-Verhalten | Automatisches Show/Hide bei Tab-Wechsel | | Benutzer-Freiheit | Manuelle Overrides werden respektiert | | Kompatibilität | Bestehende Views ohne ''documentAffinity'' bleiben unverändert | Weiter zum [[script-command|Script-Command Tutorial]] oder zurück zur [[..:start|Übersicht]].