# ExpiryIndicator – Vorgehen ## Ziel Eine SharePoint-Framework-Solution für SharePoint Server Subscription Edition auf Basis von SPFx 1.4.1. Die App stellt für moderne Listen und Dokumentbibliotheken Folgendes bereit: - farbliche Kennzeichnung einer frei konfigurierbaren vorhandenen Datumsspalte, - Berechnung eines effektiven Ablaufdatums aus `Created`, wenn `ExpiryDate` leer ist, - frei konfigurierbare Laufzeit-, Schwellenwert- und Farbregeln pro Liste/Bibliothek, - einen Befehl **„Ablaufdatum +1 Jahr“** für ein oder mehrere ausgewählte Elemente, - einen unsichtbar laufenden Application Customizer, der den Einstellungsdialog per URL-Parameter für Listenverwalter öffnet. ## Wichtige Randbedingung Die fachliche Ablaufdatumsspalte wird **nicht** durch diese Solution angelegt oder geändert. Sie stammt aus dem Content Type Hub und kann bei jedem Kunden einen anderen internen Namen besitzen. Der interne Name wird pro Liste/Bibliothek konfiguriert und beim Aktivieren an das Skript übergeben. Falls das konfigurierte Feld fehlt, bleibt der Verlängerungsbefehl deaktiviert beziehungsweise verborgen; der Einstellungsbefehl bleibt für Listenverwalter verfügbar. ## Technischer Aufbau ### 1. Field Customizer `ExpiryIndicatorFieldCustomizer` wird an die vorhandene Spalte `ExpiryDate` gebunden und rendert deren Zelle. Berechnung des effektiven Ablaufdatums: 1. Ist das konfigurierte Ablaufdatumsfeld gesetzt, wird dieser Wert verwendet. 2. Ist es leer, werden die fachlichen `rules` in ihrer konfigurierten Reihenfolge ausgewertet. 3. Vor jeder Wertprüfung wird geprüft, ob `columnName` in der aktuellen Liste/Bibliothek existiert. Ein fehlendes Feld kann die Regel nicht erfüllen. 4. Existiert das Feld und entspricht sein Wert `columnValue`, werden `lifeTime` und `columnRule` dieser Regel verwendet. 5. Passt keine Regel oder existiert keines der Regelfelder, werden `default.lifeTime` und `default.columnRule` verwendet. 6. Die erste passende `columnRule` bestimmt den Zeilenverlauf vom Standardhintergrund zur Regel-Hintergrundfarbe, die Textfarbe und die optionale Beschriftung; die Auswahlspalte bleibt ungefärbt. Die Berechnung arbeitet mit Kalenderjahren/-monaten/-tagen, nicht mit pauschalen 365-Tage-Jahren. ### 2. ListView Command Set `ExpiryIndicatorCommandSet` stellt in der modernen Befehlsleiste eine fachliche Aktion bereit: - **Ablaufdatum +1 Jahr** - sichtbar, wenn mindestens ein Element gewählt wurde und `ExpiryDate` vorhanden ist, - unterstützt Einzel- und Mehrfachauswahl, - liest `Created` und `ExpiryDate` serverseitig über REST, - verwendet bei leerem `ExpiryDate` zunächst das berechnete effektive Ablaufdatum, - addiert ein Kalenderjahr und schreibt das Ergebnis nach `ExpiryDate`, - zeigt eine Zusammenfassung über erfolgreiche und fehlgeschlagene Änderungen. ### 3. Application Customizer `ExpiryIndicatorApplicationCustomizer` läuft ohne permanente Oberfläche. Auf einer modernen Listen- oder Bibliotheksansicht öffnet `expiryIndicatorSettings=1` den Konfigurationsdialog für Benutzer mit `ManageLists`-Berechtigung. Die Befehlsleiste enthält dadurch keinen Einstellungsbefehl. ### 4. Konfiguration Die Konfiguration wird pro Liste als JSON in `ClientSideComponentProperties` des gebundenen lokalen Listenfeldes gespeichert. Eine zusätzliche Konfigurationsliste wird bei neuen Installationen nicht erzeugt. Für Upgrades darf eine bestehende `_ExpiryIndicatorConfiguration` ausschließlich als Lese-Fallback verwendet werden, bis die Konfiguration beim nächsten Speichern in die Component Properties migriert wurde. Die fachliche Spalte `ExpiryDate` bleibt davon unberührt. Konfigurierbar sind mindestens: - interner Name des Erstellungsfeldes, Standard `Created`, - interner Name des Ablaufdatums, Standard `ExpiryDate`, - Standardlaufzeit unter `default.lifeTime` als Wert und Einheit (`days`, `months`, `years`), - Standard-Farbregeln unter `default.columnRule`, - priorisierte fachliche Regeln mit `columnName`, `columnValue`, eigener `lifeTime` und eigenen `columnRule`-Einträgen, - beliebig viele Farbregeln mit Operator, Tagesgrenze, Hintergrundfarbe, Textfarbe und Beschriftung, - Darstellung bei fehlenden oder ungültigen Datumswerten, - Bestätigungsdialog vor der Verlängerung. Regeln werden deklarativ gespeichert. Es wird kein JavaScript aus der Konfiguration mit `eval` oder ähnlichen Mechanismen ausgeführt. Beispiel einer Laufzeitkonfiguration: ```json { "baseField": "Created", "expiryField": "ExpiryDate", "default": { "lifeTime": { "value": 3, "unit": "years" }, "columnRule": [] }, "rules": [ { "columnName": "DataPrivacy", "columnValue": "PersDat1", "lifeTime": { "value": 1, "unit": "years" }, "columnRule": [] }, { "columnName": "DataPrivacy", "columnValue": "PersDat2", "lifeTime": { "value": 3, "unit": "years" }, "columnRule": [] } ] } ``` ### 5. Aktivierung und Deployment - Erstellung eines `.sppkg`-Pakets mit eingebetteten Client-Side Assets. - Registrierung des Command Sets und des Settings-Application-Customizers. - Keine Provisionierung fachlicher Ablaufdatumsspalten, Site Columns oder Content Types. - Bereitstellung eines PowerShell-/CSOM-Aktivierungsskripts, das den Field Customizer mit einer als Parameter angegebenen vorhandenen Ablaufdatumsspalte verknüpft. - Bereitstellung eines entsprechenden Deaktivierungsskripts, das nur diese Verknüpfung und App-Custom-Actions entfernt, nicht aber fachliche Daten oder Spalten. ## Umsetzungsschritte - [x] Architektur und Randbedingungen dokumentieren. - [x] SPFx-1.4.1-Projektstruktur anlegen. - [x] gemeinsame Modelle, Datumsberechnung und Regel-Auswertung implementieren. - [x] Regel-Engine für feldwertabhängige Laufzeiten und Farbschwellen implementieren. - [x] REST-Service für Konfiguration und Elementaktualisierungen implementieren. - [x] Field Customizer implementieren. - [x] ListView Command Set und Einstellungsdialog implementieren. - [x] Settings-Application-Customizer mit URL-Aktivierung implementieren. - [x] Feature-XML für Command-Bar-Registrierung erstellen. - [x] CSOM-Aktivierungs- und Deaktivierungsskripte für die vorhandene `ExpiryDate`-Spalte erstellen. - [x] Lokalisierung Deutsch/Englisch ergänzen. - [x] Build mit der SPFx-1.4.1-kompatiblen Legacy-Toolchain ausführen. - [x] `.sppkg` erzeugen und Installationsanleitung ergänzen. - [x] Tests für Kalenderarithmetik, Schwellwerte und leere Ablaufdaten durchführen. ## Roadmap Version 2.0 ### Logische Verkettung von Regeln - [x] Konfigurationsschema für mehrere Bedingungen innerhalb einer Regel definieren. - [x] Bedingungen mit den logischen Operatoren `AND` und `OR` verknüpfen können. - [x] Verschachtelte Bedingungsgruppen und eine eindeutige Auswertungsreihenfolge festlegen. - [x] Regel-Engine um die Auswertung verketteter Bedingungen erweitern. - [x] Bestehende Version-1-Regeln mit `columnName` und `columnValue` abwärtskompatibel weiter unterstützen. - [x] Einstellungsdialog um verkettete Regeln erweitern. - [x] Optionale PortalSettings-Integration um einen zentralen Editor für verkettete Regeln erweitern. - [x] Konfiguration validieren und verständliche Fehlermeldungen für ungültige Regelgruppen ausgeben. - [x] Tests für `AND`, `OR`, gemischte Gruppen, fehlende Felder und Fallback auf die Standardregel ergänzen. ### Unterstützung klassischer SharePoint-Ansichten - [x] Technisches Konzept für klassische Listen und Bibliotheken erstellen, da SPFx Field Customizer und ListView Command Sets dort nicht ausgeführt werden. - [x] Darstellung und Zeilenverlauf für die klassische Ansicht über CSR/JSLink realisieren. - [x] Die Aktion **„Ablaufdatum +1 Jahr“** in der klassischen Ribbon-/Listenoberfläche bereitstellen. - [x] Zugriff auf die ExpiryIndicator-Einstellungen auch aus klassischen Ansichten ermöglichen. - [x] Aktivierungs-, Deaktivierungs- und Upgrade-Skripte um die Classic-Registrierungen erweitern. - [x] Dieselbe Konfiguration und dasselbe Regelverhalten in moderner und klassischer Ansicht verwenden. - [ ] Funktions-, Berechtigungs- und Darstellungstests für klassische Listen und Dokumentbibliotheken ergänzen. ### Release 2.0 - [x] Versionsstände von Solution, Feature und SPFx-Komponenten auf `2.0.0` anheben. - [x] README um V2-Regeln, Classic-Aktivierung und Deaktivierung ergänzen. - [x] Pakete mit Node.js 8.17.0 erstellen und lokale Package-Validierung erfolgreich ausführen. - [ ] Feature-Upgrade in SharePoint Server Subscription Edition testen. - [ ] Modern-/Classic-Abnahmetest auf einer Testliste und einer Test-Dokumentbibliothek durchführen. ## Abnahmekriterien - Die Solution enthält und provisioniert keine Definition für eine fachliche Ablaufdatumsspalte. - Erstellungsfeld, Ablaufdatumsfeld und Bedingungsfelder sind über interne Feldnamen konfigurierbar. - Unterschiedliche Laufzeiten und Farbschwellen können anhand priorisierter Feldwertregeln bestimmt werden. - Die Anzeige funktioniert in modernen Ansichten von Listen und Dokumentbibliotheken. - Regeln und Farben sind pro Liste/Bibliothek ohne Codeänderung konfigurierbar. - Leere Ablaufdaten werden aus `Created` und der Grundlaufzeit berechnet. - Der Verlängerungsbefehl erhöht das effektive Ablaufdatum um genau ein Kalenderjahr. - Mehrfachauswahl führt nicht zum vollständigen Abbruch, wenn einzelne Elemente nicht aktualisiert werden können. - Benutzer ohne Bearbeitungsrechte können keine Elemente verlängern. - Nur Listenverwalter können die Konfiguration ändern.