From bc611662675ddb2adccc48269b893579b10c9847 Mon Sep 17 00:00:00 2001 From: Torsten Brendgen Date: Mon, 20 Jul 2026 20:37:32 +0200 Subject: [PATCH] feat: Add support for flyout menu mode in MegaMenu - Introduced `MegaMenuMode` type and `normalizeMegaMenuMode` function to handle menu modes. - Updated `MegaMenuApplicationCustomizer` to accept `menuMode` property. - Enhanced `MegaMenuRenderer` to render flyout menus based on the selected mode. - Created new HTML previews for both flyout and mega menu modes. - Removed unused mock services and user custom action service interfaces. --- README.md | 369 ++++---- build-classic.ps1 | 280 +----- classic/classic-deployment.md | 230 +---- classic/megamenu-classic.css | 309 ++++++- classic/megamenu-classic.js | 51 +- classic/megamenu-services-standalone.js | 190 ++-- config/deploy-azure-storage.json | 7 - config/package-solution.json | 2 +- config/serve.json | 9 +- deployment/add-megamenu.ps1 | 140 ++- deployment/test-megamenu-site-scope.ps1 | 136 --- gulpfile.js | 3 +- package-lock.json | 2 +- package.json | 7 +- preview/flyout-menu-preview.html | 90 ++ preview/mega-menu-preview.html | 98 +++ sharepoint/assets/elements.xml | 8 - src/extensions/megaMenu/MegaMenu.module.scss | 812 ++++++++---------- .../megaMenu/MegaMenuApplicationCustomizer.ts | 14 +- src/extensions/megaMenu/MegaMenuMode.ts | 5 + src/extensions/megaMenu/MegaMenuRenderer.ts | 97 ++- src/index.ts | 16 +- src/services/MockTaxonomyNavigationService.ts | 106 --- .../IUserCustomActionProps.ts | 21 - .../IUserCustomActionService.ts | 12 - .../UserCustomActionScope.ts | 5 - .../UserCustomActionService.ts | 134 --- 27 files changed, 1320 insertions(+), 1833 deletions(-) delete mode 100644 config/deploy-azure-storage.json delete mode 100644 deployment/test-megamenu-site-scope.ps1 create mode 100644 preview/flyout-menu-preview.html create mode 100644 preview/mega-menu-preview.html delete mode 100644 sharepoint/assets/elements.xml create mode 100644 src/extensions/megaMenu/MegaMenuMode.ts delete mode 100644 src/services/MockTaxonomyNavigationService.ts delete mode 100644 src/services/UserCustomActionService/IUserCustomActionProps.ts delete mode 100644 src/services/UserCustomActionService/IUserCustomActionService.ts delete mode 100644 src/services/UserCustomActionService/UserCustomActionScope.ts delete mode 100644 src/services/UserCustomActionService/UserCustomActionService.ts diff --git a/README.md b/README.md index a561214..a42fa9b 100644 --- a/README.md +++ b/README.md @@ -1,312 +1,253 @@ # SharePoint MegaMenu -Barrierearme, dreistufige Portalnavigation auf Basis von SharePoint Managed Metadata für SharePoint Server Subscription Edition und SharePoint Server 2019. +Zentrale, barrierearme Portalnavigation aus SharePoint Managed Metadata für SharePoint Server Subscription Edition und SharePoint Server 2019. | Eigenschaft | Wert | |---|---| -| Version | 2.0.1 | -| SharePoint Framework | SPFx 1.4.1 | -| Node.js | 8.17.0 | -| Zieloberfläche | Moderne SharePoint-Seiten | +| Version | 2.1.0 | +| SharePoint Framework | 1.4.1 | +| Node.js für den Build | 8.17.0 | +| Moderne Seiten | SPFx Application Customizer | +| Klassische Seiten | separate ScriptLink-Variante | | Paket | `sharepoint/solution/mega-menu.sppkg` | ## Funktionen -- Dreistufige Navigation aus einem Managed-Metadata-Termset -- Auswahl des Termsets per GUID oder, abwärtskompatibel, per Name -- Benutzerdefinierte Sortierung aus dem Term Store -- Unterstützung der Navigations-Eigenschaften `_Sys_Nav_SimpleLinkUrl`, `_Sys_Nav_TargetUrl` und `_Sys_Nav_HoverText` -- Auflösung von `~sitecollection` in Navigations-URLs -- Markierung des aktuellen Menüpunktes und seiner übergeordneten Einträge -- Bedienung mit Maus, Tastatur und Touch -- Responsive Darstellung -- Optionales zusätzliches Stylesheet -- Taxonomy-Cache mit konfigurierbarer Ablaufzeit -- Bereinigter SPFx-Lifecycle ohne verbleibende globale Event Listener -- Deutsche und englische Statusmeldungen +- zentrale Konfiguration pro Site Collection +- Termset-Auswahl bevorzugt per GUID, alternativ per Name +- drei Navigationsebenen +- zwei Darstellungsmodi: SharePoint-ähnliches Mega Menu und strukturelles Flyout +- benutzerdefinierte Sortierung aus dem Term Store +- Unterstützung für `_Sys_Nav_SimpleLinkUrl`, `_Sys_Nav_TargetUrl` und `_Sys_Nav_HoverText` +- Auflösung von `~sitecollection` +- Markierung des aktuellen Navigationspfads +- Tastatur-, Fokus-, Maus- und Touch-Bedienung +- responsive Darstellung und Unterstützung reduzierter Bewegung +- Session-Cache mit konfigurierbarer Laufzeit +- Debug-Protokollierung ohne Ausgabe im Normalbetrieb +- Unterstützung moderner und klassischer SharePoint-Seiten ## Architektur ```text -UserCustomAction.ClientSideComponentProperties - │ - ▼ -MegaMenuApplicationCustomizer - │ - ├── TaxonomyNavigationService - │ └── SPTermStorePickerService - │ └── Default Site Collection Term Store - │ - └── MegaMenuRenderer - ├── semantische Navigation - ├── Fokus- und Tastatursteuerung - └── responsive Darstellung +App Catalog +└── zentral bereitgestelltes MegaMenu-SPFx-Bundle + +Site Collection +└── SPSite.UserCustomAction + ├── ComponentId + └── ClientSideComponentProperties + ├── termSetId / termSetName + ├── cacheMinutes + ├── menuMode + └── debug + +Moderne Seite Klassische Seite +└── Application Customizer └── ScriptLink + Classic-Runtime ``` -Das MegaMenu wird einmal pro Site Collection konfiguriert. Das Paket wird mit `skipFeatureDeployment: true` zentral über den App Catalog bereitgestellt, damit das SPFx-Bundle ohne eine App-Installation in jedem einzelnen Web verfügbar ist. PortalSettings speichert die zentrale Konfiguration im Property Bag des Root Webs. Eine Site-Collection-Action aktiviert das MegaMenu auf dem Root Web sowie auf vorhandenen und zukünftigen Unterwebs. Das MegaMenu selbst enthält keine eigene Administrationsoberfläche. +Die Site-Collection-Action ist die einzige Konfigurationsquelle. Es gibt keine versteckte Konfigurationsliste, keine MegaMenu-Konfiguration im Property Bag und keine Web-scoped Kopien. PortalSettings kann diese Action zentral lesen und aktualisieren. -## Voraussetzungen - -- SharePoint Server Subscription Edition oder SharePoint Server 2019 -- konfigurierter App Catalog -- konfigurierter App Management Service -- ein Termset im Standard-Term-Store der Site Collection -- Leseberechtigung der Benutzer auf den Managed-Metadata-Service -- für Entwicklung und Build: Node.js 8.17.0 und eine zu SPFx 1.4.1 passende npm-Version +Das SPFx-Paket verwendet `skipFeatureDeployment: true`. Es wird im App Catalog zentral bereitgestellt und nicht in Root Web oder Unterwebs über „App hinzufügen“ installiert. ## Konfiguration -Die UserCustomAction unterstützt folgende `ClientSideComponentProperties`: - ```json { - "termSetId": "6f36a1a8-7bd8-4ed0-a22f-e219f4d2eacc", + "termSetId": "7948e6f9-7af4-431e-b6fe-328122f2746c", "termSetName": "Global Navigation", "cacheMinutes": 15, + "menuMode": "megaMenu", "debug": false } ``` -| Eigenschaft | Typ | Standard | Beschreibung | -|---|---:|---:|---| -| `termSetId` | GUID | leer | Bevorzugte, eindeutige Identifikation des Termsets | -| `termSetName` | String | leer | Rückwärtskompatibler Fallback, wenn keine gültige `termSetId` vorhanden ist | -| `cacheMinutes` | Zahl | `15` | Gültigkeit des Session-Caches, zulässig sind 1 bis 1440 Minuten | -| `debug` | Boolean | `false` | Aktiviert zusätzliche Konsolenausgaben | +| Property | Typ | Standard | Beschreibung | +|---|---|---|---| +| `termSetId` | String | leer | GUID des Termsets; hat Vorrang vor dem Namen | +| `termSetName` | String | leer | Fallback für bestehende Konfigurationen | +| `cacheMinutes` | Number | `15` | Cachezeit von 1 bis 1440 Minuten | +| `menuMode` | String | `megaMenu` | `megaMenu` oder `flyout` | +| `debug` | Boolean | `false` | ausführliche Browser-Konsolenausgaben | -`termSetId` hat Vorrang vor `termSetName`. Für neue Installationen wird die GUID empfohlen, weil Termset-Namen nicht zwingend eindeutig sind. +### Mega Menu -### Kompatibilität mit PortalSettings +`"menuMode": "megaMenu"` zeigt die zweite Ebene als breites, spaltenbasiertes Panel. Die dritte Ebene wird als Linkliste unter der jeweiligen Kategorie dargestellt. -PortalSettings verwaltet `termSetId`, `termSetName`, `cacheMinutes` und `debug`. Individuelle Gestaltung wird nicht vom MegaMenu selbst geladen, sondern zentral über die Solution Custom Branding bereitgestellt. +### Flyout -## Termset-Aufbau - -Die Darstellung unterstützt drei Ebenen: - -```text -Ebene 1: Hauptnavigation -├── Ebene 2: Kategorie -│ ├── Ebene 3: Link -│ └── Ebene 3: Link -└── Ebene 2: Kategorie -``` - -Für Zieladressen werden die lokalen benutzerdefinierten Eigenschaften des Terms ausgewertet: - -1. `_Sys_Nav_SimpleLinkUrl` -2. `_Sys_Nav_TargetUrl` - -Optional kann `_Sys_Nav_HoverText` als ergänzender Hilfetext verwendet werden. Veraltete Terms werden nicht angezeigt. Terms, die nicht für Tagging verfügbar sind, bleiben für Navigationsszenarien sichtbar. +`"menuMode": "flyout"` zeigt die zweite Ebene als kompaktes Dropdown. Die dritte Ebene öffnet sich seitlich als strukturelles Flyout. ## Build -SPFx 1.4.1 verwendet die Legacy-Gulp-Toolchain. Neuere Node-Versionen sind nicht kompatibel. - ```powershell npm install npm run package ``` -Alternativ einzeln: +`npm run package` erstellt automatisch beide Ausgaben: + +- das SPFx-Paket für moderne Seiten +- das Classic-Paket unter `classic/dist/` + +Nur die Classic-Dateien neu erzeugen: ```powershell -gulp clean -gulp bundle --ship -gulp package-solution --ship +npm run build:classic ``` -Das fertige Paket befindet sich anschließend unter: +Erwartete Umgebung: + +```text +Node.js 8.17.0 +npm 6.x +lokales Gulp 3.9.1 +``` + +Das Ergebnis liegt unter: ```text sharepoint/solution/mega-menu.sppkg ``` -## Deployment +## Moderne Bereitstellung -1. `mega-menu.sppkg` in den App Catalog laden. -2. Die Solution freigeben. -3. Die App im Root Web der gewünschten Site Collection installieren. Der MegaMenu Application Customizer wird dort zunächst web-scoped registriert und von PortalSettings erkannt. -4. Das Termset in PortalSettings konfigurieren. +1. `mega-menu.sppkg` in den Farm App Catalog hochladen beziehungsweise ersetzen. +2. Die Lösung zentral für alle Sites verfügbar machen. +3. MegaMenu nicht über „App hinzufügen“ in Inhaltswebsites installieren. +4. Pro gewünschter Site Collection eine Site-Collection-Action anlegen. -Das folgende Skript ist nur erforderlich, wenn PortalSettings nicht verwendet wird oder eine vollständig skriptbasierte Vorkonfiguration gewünscht ist. - -Empfohlen mit Termset-GUID: +Beispiel für das Mega Menu: ```powershell .\deployment\add-megamenu.ps1 ` - -SiteUrl 'https://sharepoint/sites/portal' ` - -TermSetId '6f36a1a8-7bd8-4ed0-a22f-e219f4d2eacc' ` + -SiteUrl 'http://clshp001/sites/target' ` + -TermSetId '7948e6f9-7af4-431e-b6fe-328122f2746c' ` -TermSetName 'Global Navigation' ` - -CacheMinutes 15 + -CacheMinutes 15 ` + -MenuMode megaMenu ``` -Abwärtskompatibel nur mit Namen: +Beispiel für das Flyout: ```powershell .\deployment\add-megamenu.ps1 ` - -SiteUrl 'https://sharepoint/sites/portal' ` - -TermSetName 'Global Navigation' + -SiteUrl 'http://clshp001/sites/target' ` + -TermSetId '7948e6f9-7af4-431e-b6fe-328122f2746c' ` + -MenuMode flyout ` + -EnableDebug ``` -Das Skript speichert die Konfiguration zentral unter `PortalSettings.MegaMenu.Configuration`, entfernt alte beziehungsweise doppelte Component IDs und synchronisiert die neue web-scoped Runtime-Bindung idempotent auf alle vorhandenen Webs. Fuer spaeter angelegte Unterwebs kann es ohne Nebenwirkungen erneut ausgefuehrt werden. +Das Skript entfernt alte Web- und Site-Registrierungen, bereinigt die frühere Property-Bag-Konfiguration und erstellt genau eine neue Site-Collection-Action. -## Individuelles Branding +## Classic Pages -Zusätzliche Stylesheets werden zentral über die Solution Custom Branding eingebunden. Das MegaMenu besitzt bewusst keine eigene `cssUrl`-Property. +Die Classic-Variante bleibt erhalten, weil ein SPFx Application Customizer nur in der modernen Oberfläche ausgeführt wird. -Die wichtigsten CSS-Klassen sind: +Das Classic-Paket wird bei `npm run build` und `npm run package` automatisch erzeugt. Es kann bei Bedarf auch separat gebaut werden: -```css -#CustomNavigation { } -#Mega-Menu { } -.mega-menu-top-level { } -.mega-menu-top-item { } -.mega-menu { } -.mega-menu-grid { } -.mega-menu-category { } -.mega-menu-links { } +```powershell +npm run build:classic ``` -Viele Farben und Abstände können über CSS Custom Properties überschrieben werden, beispielsweise: +Ausgabe: + +```text +classic/dist/ +├── megamenu-classic.css +├── megamenu-services-standalone.js +├── megamenu-classic.js +└── classic-deployment.md +``` + +Die Classic-Runtime liest dieselben `ClientSideComponentProperties` der zentralen Site-Collection-Action und unterstützt ebenfalls beide Menümodi. Die Installationsdetails stehen in [classic/classic-deployment.md](classic/classic-deployment.md). + +## Styling + +Das moderne Styling liegt in: + +```text +src/extensions/megaMenu/MegaMenu.module.scss +``` + +SPFx kompiliert diese Datei in das Bundle-CSS. Die eigenständige Classic-CSS liegt unter: + +```text +classic/megamenu-classic.css +``` + +Beide Varianten orientieren sich an SharePoint mit Segoe UI, neutralen Flächen, Theme-Farbe für den aktiven Pfad, kompakten Abständen und Fabric-kompatiblen Fokusmarkierungen. + +Die wichtigsten CSS-Variablen können durch Custom Branding überschrieben werden: ```css :root { - --megaMenuNavBackground: #5f6f74; - --megaMenuNavTextColor: #ffffff; - --megaMenuPanelWidth: 1280px; + --megaMenuBarHeight: 44px; + --megaMenuContentWidth: 1200px; + --megaMenuFlyoutWidth: 288px; --megaMenuZIndex: 6000; } ``` -## Cache +Das MegaMenu lädt bewusst keine externe `cssUrl`-Property. Kundenspezifische Gestaltung gehört in die Solution Custom Branding. -Das geladene Termset wird im `sessionStorage` des Browsers gespeichert. Der Schlüssel ist mit `MegaMenu:TermSet:` namensräumlich getrennt. Nach Ablauf von `cacheMinutes` wird das Termset automatisch neu geladen. +## Diagnose -Für einen sofortigen administrativen Test kann der Session-Cache in den Browser-Entwicklertools gelöscht oder ein neues privates Browserfenster verwendet werden. +Mit `"debug": true` schreibt die moderne Extension Meldungen mit diesen Quellen: -## Barrierefreiheit +```text +[MegaMenuApplicationCustomizer] +[TaxonomyNavigationService] +[SPTermStorePickerService] +[MegaMenuRenderer] +``` -- semantisches `