diff --git a/README.md b/README.md index 5e9c583..d784e00 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,55 @@ -## portal-settings +# PortalSettings -Separate Settings-App fuer bestehende SharePoint Extensions. +PortalSettings wird einmal im Root Web einer Site Collection installiert. Die Seite erkennt registrierte +Einstellungsanbieter automatisch und zeigt nur Tabs fuer tatsaechlich vorhandene Solutions. + +Aktuell verwaltet sie: -Aktuell verwaltet die Seite dynamisch die aktiven Application Customizer fuer: - Custom Branding - Mega Menu +- ExpiryIndicator + +## ExpiryIndicator 2.1 + +- Site-Collection-Standard im Property Bag des Root Webs, +- Inventar aller durch das Aktivierungsskript registrierten Bindungen in Root Web und Subwebs, +- Vererbung des zentralen Standards durch alle Bindungen, +- weiterhin moegliche lokale Ausnahmen in `ClientSideComponentProperties` des gebundenen Feldes, +- keine zusaetzliche Konfigurationsliste, +- Unterstuetzung alter Einzelregeln und verschachtelter V2-Regeln mit `and`/`or`, +- Validierung und Formatierung der vollstaendigen JSON-Konfiguration vor dem Speichern. + +Die Prioritaet lautet: lokale Feldausnahme, Subweb-Override, Site-Collection-Standard, eingebauter Standard. +PortalSettings bleibt fuer den Betrieb des ExpiryIndicators optional. + +## Erkennung + +- Custom Branding und Mega Menu werden anhand ihrer aktiven, markierten Application-Customizer-UserCustomAction erkannt. +- ExpiryIndicator registriert einen Solution-Descriptor und sein Bindungsinventar im Property Bag des Root Webs. + +Neue eigene Solutions werden zentral im Provider-Register in `PortalSettings.aspx` hinterlegt. Ein Provider +definiert Kennung, Anzeigename, Component-ID, Panel und Erkennungsart. So bleibt PortalSettings die gemeinsame +Admin-Oberflaeche, ohne dass nicht installierte Solutions leere Tabs erzeugen. + +## Build + +Die Solution verwendet die SPFx-1.4.1-Toolchain und wird reproduzierbar mit Node.js 8.17.0 gebaut: + +```powershell +npm install +npm run package +``` + +Das Paket liegt danach unter `sharepoint/solution/portal-settings.sppkg`. + +## Installation und Upgrade + +1. `portal-settings.sppkg` im App Catalog durch Version `2.0.0.0` ersetzen. +2. PortalSettings im Root Web der Site Collection installieren beziehungsweise aktualisieren. +3. `expiry-indicator.sppkg` durch Version `2.1.0.0` ersetzen und die App aktualisieren. +4. `Enable-ExpiryIndicator.ps1` fuer jede verwendete Liste oder Bibliothek erneut ausfuehren. Dadurch werden + Descriptor und Bindungsinventar idempotent registriert; vorhandene lokale Konfigurationen bleiben erhalten. +5. `/SitePages/PortalSettings.aspx` mit geleertem Browsercache laden. + +Der ExpiryIndicator-Tab erscheint erst, wenn mindestens eine Bindung registriert ist, ein zentraler Standard +existiert oder der Solution-Descriptor im Root Web vorhanden ist. diff --git a/config/package-solution.json b/config/package-solution.json index 7799903..57f71c8 100644 --- a/config/package-solution.json +++ b/config/package-solution.json @@ -3,7 +3,7 @@ "solution": { "name": "portal-settings-client-side-solution", "id": "1c98e32d-bb7b-43b7-9625-074d6e4ea286", - "version": "1.0.0.0", + "version": "2.0.0.0", "includeClientSideAssets": true, "skipFeatureDeployment": false, "features": [ @@ -11,13 +11,16 @@ "title": "Portal Settings", "description": "Provisioniert die zentrale Settings-Seite fuer aktive Portal-Erweiterungen.", "id": "57bd9daf-48f9-49e2-aebd-11b15a0b5e93", - "version": "1.0.0.0", + "version": "2.0.0.0", "assets": { "elementManifests": [ - "elements.xml" + "elements-v2.xml" ], "elementFiles": [ "PortalSettings.aspx" + ], + "upgradeActions": [ + "upgrade-actions-v2.xml" ] } } diff --git a/package-lock.json b/package-lock.json index 8d8256d..dd9b441 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "portal-settings", - "version": "0.0.1", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -281,6 +281,14 @@ "sinon": "~1.17.3", "sinon-chai": "~2.8.0", "webpack": "~3.6.0" + }, + "dependencies": { + "phantomjs-polyfill": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/phantomjs-polyfill/-/phantomjs-polyfill-0.0.2.tgz", + "integrity": "sha512-USErWAfES7rDxo6XgXkb8gt+0viV9lRb8OZNixEgjRBQjvVMyBeUZgy3HuE7vful8fv0UWb2wUD9jhkYB269wA==", + "dev": true + } } }, "@microsoft/gulp-core-build-sass": { @@ -1227,6 +1235,13 @@ "react-dom": "15.6.2", "scrollreveal": "3.3.6", "tslib": "~1.8.0" + }, + "dependencies": { + "@types/scrollreveal": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@types/scrollreveal/-/scrollreveal-0.0.2.tgz", + "integrity": "sha512-tLP/n3XGheuFYKfQsNlZbn8d6Gm7e81r9He131adAZltpYySyF99GLgfx4Qikl2ERuY+Pbp73F78PgEicZAzHA==" + } } }, "@microsoft/sp-webpart-workbench": { @@ -1565,11 +1580,6 @@ "integrity": "sha512-xnLdvcPWgKF71R2DEQCZfXLutuAApHhJT+Y4/ptZ8FN610hSVT98TyLLkMjRm3VJ2BqUUXRjYtdZ12KvDXBT7A==", "dev": true }, - "@types/scrollreveal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@types/scrollreveal/-/scrollreveal-0.0.2.tgz", - "integrity": "sha512-tLP/n3XGheuFYKfQsNlZbn8d6Gm7e81r9He131adAZltpYySyF99GLgfx4Qikl2ERuY+Pbp73F78PgEicZAzHA==" - }, "@types/semver": { "version": "5.3.33", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.3.33.tgz", @@ -3495,7 +3505,7 @@ } }, "charenc": { - "version": "0.0.1", + "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true @@ -4191,7 +4201,7 @@ } }, "crypt": { - "version": "0.0.1", + "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "dev": true @@ -4816,15 +4826,6 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "duplexer2": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", - "dev": true, - "requires": { - "readable-stream": "~1.1.9" - } - }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -6433,7 +6434,7 @@ } }, "glob-escape": { - "version": "0.0.1", + "version": "0.0.2", "resolved": "https://registry.npmjs.org/glob-escape/-/glob-escape-0.0.2.tgz", "integrity": "sha512-L/cXYz8x7qer1HAyUQ+mbjcUsJVdpRxpAf7CwqHoNBs9vTpABlGfNN4tzkDxt+u3Z7ZncVyKlCNPtzb0R/7WbA==", "dev": true @@ -11479,6 +11480,17 @@ "dev": true, "requires": { "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", + "dev": true, + "requires": { + "readable-stream": "~1.1.9" + } + } } }, "mute-stream": { @@ -12552,12 +12564,6 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, - "phantomjs-polyfill": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/phantomjs-polyfill/-/phantomjs-polyfill-0.0.2.tgz", - "integrity": "sha512-USErWAfES7rDxo6XgXkb8gt+0viV9lRb8OZNixEgjRBQjvVMyBeUZgy3HuE7vful8fv0UWb2wUD9jhkYB269wA==", - "dev": true - }, "phantomjs-prebuilt": { "version": "2.1.16", "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", @@ -16329,6 +16335,14 @@ "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==", + "dev": true + } } }, "uglify-js": { @@ -16349,10 +16363,9 @@ "dev": true }, "wordwrap": { - "version": "0.0.1", + "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==", - "dev": true + "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==" }, "yargs": { "version": "3.10.0", @@ -17615,4 +17628,3 @@ } } } - diff --git a/package.json b/package.json index 1188929..32b59fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "portal-settings", - "version": "0.0.1", + "version": "2.0.0", "private": true, "main": "lib/index.js", "engines": { @@ -9,6 +9,7 @@ "scripts": { "build": "gulp bundle", "clean": "gulp clean", + "package": "gulp clean && gulp bundle --ship && gulp package-solution --ship", "test": "gulp test" }, "dependencies": { diff --git a/sharepoint/assets/PortalSettings.aspx b/sharepoint/assets/PortalSettings.aspx new file mode 100644 index 0000000..fec31ea --- /dev/null +++ b/sharepoint/assets/PortalSettings.aspx @@ -0,0 +1,86 @@ +<%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> +<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> +<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> +<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> + + + + + + +
Portal Settings

Zentrale Verwaltung fuer aktive Portal-Erweiterungen

Diese Seite erkennt installierte Einstellungsanbieter automatisch und zeigt nur deren Tabs. Konfigurationen werden in UserCustomActions, Feld-Properties oder im Property Bag des Root Webs gespeichert.

0
-
-
Keine
+ + + +
+
diff --git a/sharepoint/assets/elements-v1.1.xml b/sharepoint/assets/elements-v1.1.xml new file mode 100644 index 0000000..e026656 --- /dev/null +++ b/sharepoint/assets/elements-v1.1.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/sharepoint/assets/elements-v2.xml b/sharepoint/assets/elements-v2.xml new file mode 100644 index 0000000..013bdac --- /dev/null +++ b/sharepoint/assets/elements-v2.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/sharepoint/assets/elements.xml b/sharepoint/assets/elements.xml new file mode 100644 index 0000000..cf9a062 --- /dev/null +++ b/sharepoint/assets/elements.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/sharepoint/assets/upgrade-actions-v1.1.xml b/sharepoint/assets/upgrade-actions-v1.1.xml new file mode 100644 index 0000000..bf40abd --- /dev/null +++ b/sharepoint/assets/upgrade-actions-v1.1.xml @@ -0,0 +1,3 @@ + + + diff --git a/sharepoint/assets/upgrade-actions-v2.xml b/sharepoint/assets/upgrade-actions-v2.xml new file mode 100644 index 0000000..b757cdf --- /dev/null +++ b/sharepoint/assets/upgrade-actions-v2.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/PortalSettings.aspx b/src/assets/PortalSettings.aspx index 883a626..fec31ea 100644 --- a/src/assets/PortalSettings.aspx +++ b/src/assets/PortalSettings.aspx @@ -12,20 +12,21 @@ -
Portal Settings

Zentrale Verwaltung fuer aktive Portal-Erweiterungen

Diese Seite erkennt automatisch unterstuetzte Application Customizer und blendet pro aktiver Loesung einen eigenen Tab ein. Die Aenderungen werden direkt in die jeweilige UserCustomAction geschrieben.

0
-
-
Keine
+
Portal Settings

Zentrale Verwaltung fuer aktive Portal-Erweiterungen

Diese Seite erkennt installierte Einstellungsanbieter automatisch und zeigt nur deren Tabs. Konfigurationen werden in UserCustomActions, Feld-Properties oder im Property Bag des Root Webs gespeichert.

0
-
-
Keine
+