====== 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]].