Aktualisiere Versionsnummer auf 3.2.0 in README.md, package.json, package-lock.json und package-solution.json. Füge Provisionierungsfeature für moderne PortalSettings.aspx hinzu und integriere zugehörige Tests.

This commit is contained in:
Torsten Brendgen
2026-08-18 21:06:28 +02:00
parent c0e7c316e3
commit eb1ad7ba1e
10 changed files with 85 additions and 24 deletions
+10 -13
View File
@@ -6,14 +6,14 @@ PortalSettings V3 ist ein providerbasiertes SPFx-WebPart für SharePoint Server
| Eigenschaft | Wert |
|---|---|
| Version | 3.1.0 |
| Version | 3.2.0 |
| SharePoint Framework | 1.4.1 |
| Build-Node | 8.17.0 |
| npm | 6.x |
| Gulp | lokal 3.9.1 |
| Komponente | Client-Side WebPart |
Die frühere provisionierte `PortalSettings.aspx` und der leere Application Customizer wurden entfernt. Die Oberfläche wird vollständig vom WebPart erzeugt und verwendet kein `innerHTML`.
Die Oberfläche wird vollständig vom WebPart erzeugt und verwendet kein `innerHTML`. Ein schlankes SharePoint-Feature provisioniert beim Installieren der App im Root-Web automatisch die moderne `SitePages/PortalSettings.aspx` und platziert dort genau eine Instanz des WebParts.
## Unterstützte Solutions
@@ -164,22 +164,20 @@ sharepoint/solution/portal-settings.sppkg
## Installation
1. `portal-settings.sppkg` im App Catalog durch Version `3.1.0.0` ersetzen.
1. `portal-settings.sppkg` im App Catalog durch Version `3.2.0.0` ersetzen.
2. Die App im Root Web der gewünschten Site Collection installieren oder aktualisieren.
3. Eine moderne Seite erstellen.
4. Das WebPart **Portal Settings** einmal auf der Seite hinzufügen.
5. Die Seite veröffentlichen und nur für die gewünschte Administratorgruppe verlinken.
3. Die App provisioniert automatisch die veröffentlichte Seite `SitePages/PortalSettings.aspx` mit dem WebPart.
4. Eine bereits vorhandene `PortalSettings.aspx` wird nicht überschrieben.
Optional kann eine Seite per PnP PowerShell erzeugt werden:
```powershell
.\deployment\Add-PortalSettingsPage.ps1 `
-SiteUrl 'http://clshp001/sites/target' `
-PageName 'PortalSettingsV3' `
-Publish
```
Die Standardseite heißt absichtlich `PortalSettingsV3.aspx`, damit die alte V2-Seite während der Abnahme erhalten bleiben kann.
Das Skript bleibt als Reparaturweg erhalten und verwendet standardmäßig ebenfalls `PortalSettings.aspx`.
## Migration von V2
@@ -191,11 +189,10 @@ V3 liest die vorhandenen Konfigurationsorte direkt weiter:
Es ist keine Datenmigration in eine neue Liste erforderlich. Empfohlenes Vorgehen:
1. V3-Paket installieren.
2. `PortalSettingsV3.aspx` parallel zur alten Seite bereitstellen.
3. Alle drei Provider laden und Konfigurationen testweise speichern.
4. Root Web und Subwebs prüfen.
5. Erst danach die alte `PortalSettings.aspx` löschen oder archivieren.
1. Paket aktualisieren und die App im Root-Web aktualisieren.
2. Fehlt `PortalSettings.aspx`, wird sie durch das Feature angelegt. Eine vorhandene Seite bleibt unverändert.
3. Falls eine vorhandene Seite das WebPart noch nicht enthält, das PnP-Skript als Reparaturweg ausführen.
4. Alle Provider laden, Konfigurationen testweise speichern und Root Web sowie Subwebs prüfen.
## Diagnose
+4 -3
View File
@@ -2,7 +2,7 @@
Stand: 21.07.2026
Branch: `dev-3.0`
Zielversion: 3.1.0
Zielversion: 3.2.0
## Architektur
@@ -51,7 +51,8 @@ Zielversion: 3.1.0
- [x] Versionen auf 3.0.0 angehoben.
- [x] Node-Engine auf SPFx-1.4.1-Buildumgebung begrenzt.
- [x] Alte Feature-, Upgrade-, Copy- und Azure-Assets entfernt.
- [x] Alte monolithische Seiten-, Copy- und Azure-Assets entfernt.
- [x] Schlankes Feature zur automatischen Provisionierung der modernen PortalSettings.aspx ergänzt.
- [x] Altes Gulp-Copy-Task entfernt.
- [x] Serve-Konfiguration auf WebPart Workbench umgestellt.
- [x] Tests laufen vor der Paketierung.
@@ -74,7 +75,7 @@ Zielversion: 3.1.0
- [ ] Ship-Paket mit Node.js 8.17.0 erstellen.
- [ ] App im Root Web aktualisieren.
- [ ] Moderne `PortalSettingsV3.aspx` provisionieren.
- [ ] Automatisch provisionierte `PortalSettings.aspx` und enthaltenes WebPart prüfen.
- [ ] MegaMenu-Termsets laden und speichern.
- [ ] CustomBranding laden und schemaerhaltend speichern.
- [ ] ExpiryIndicator-Standard speichern.
+15 -2
View File
@@ -3,9 +3,22 @@
"solution": {
"name": "portal-settings-client-side-solution",
"id": "1c98e32d-bb7b-43b7-9625-074d6e4ea286",
"version": "3.1.0.0",
"version": "3.2.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": false
"skipFeatureDeployment": false,
"features": [
{
"title": "Portal Settings Page",
"description": "Provisioniert die moderne PortalSettings.aspx im Root-Web.",
"id": "71841e33-8bbd-4007-83a6-d950453226a2",
"version": "3.2.0.0",
"assets": {
"elementManifests": ["elements.xml"],
"elementFiles": ["PortalSettings.aspx"],
"upgradeActions": ["upgrade-actions.xml"]
}
}
]
},
"paths": {
"zippedPackage": "solution/portal-settings.sppkg"
+1 -1
View File
@@ -2,7 +2,7 @@ param(
[Parameter(Mandatory = $true)]
[string]$SiteUrl,
[string]$PageName = 'PortalSettingsV3',
[string]$PageName = 'PortalSettings',
[switch]$Publish
)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "portal-settings",
"version": "3.1.0",
"version": "3.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "portal-settings",
"version": "3.1.0",
"version": "3.2.0",
"private": true,
"main": "lib/index.js",
"engines": {
+16
View File
@@ -0,0 +1,16 @@
<%@ Page language="C#" Inherits="Microsoft.SharePoint.WebControls.ClientSidePage, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<!--[if gte mso 9]><SharePoint:CTFieldRefs runat="server" Prefix="mso:" FieldList="FileLeafRef,Title,ContentTypeId,ClientSideApplicationId,PageLayoutType,CanvasContent1,BannerImageUrl,PromotedState"><xml>
<mso:CustomDocumentProperties>
<mso:Title msdt:dt="string">Portal Settings</mso:Title>
<mso:ContentTypeId msdt:dt="string">0x0101009D1CB255DA76424F860D91F20E6C4118</mso:ContentTypeId>
<mso:ClientSideApplicationId msdt:dt="string">b6917cb1-93a0-4b97-a84d-7cf49975d4ec</mso:ClientSideApplicationId>
<mso:PageLayoutType msdt:dt="string">Article</mso:PageLayoutType>
<mso:PromotedState msdt:dt="string">0</mso:PromotedState>
</mso:CustomDocumentProperties>
</xml></SharePoint:CTFieldRefs><![endif]-->
</head>
<body></body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="PortalSettingsModernPage" Url="SitePages" RootWebOnly="TRUE">
<File Path="PortalSettings.aspx" Url="PortalSettings.aspx" Type="GhostableInLibrary" Level="Published" IgnoreIfAlreadyExists="TRUE">
<Property Name="Title" Value="Portal Settings" />
<Property Name="ContentTypeId" Value="0x0101009D1CB255DA76424F860D91F20E6C4118" />
<Property Name="ClientSideApplicationId" Value="b6917cb1-93a0-4b97-a84d-7cf49975d4ec" />
<Property Name="PageLayoutType" Value="Article" />
<Property Name="PromotedState" Value="0" />
<Property Name="BannerImageUrl" Value="/_layouts/15/images/sitepagethumbnail.png" />
<Property Name="CanvasContent1" Value="&lt;div&gt;&lt;div data-sp-canvascontrol=&quot;&quot; data-sp-canvasdataversion=&quot;1.0&quot; data-sp-controldata=&quot;&amp;#123;&amp;quot;controlType&amp;quot;:3,&amp;quot;id&amp;quot;:&amp;quot;7f1bf9be-7eca-4952-937f-4c72daccfc26&amp;quot;,&amp;quot;position&amp;quot;:&amp;#123;&amp;quot;zoneIndex&amp;quot;:1,&amp;quot;sectionIndex&amp;quot;:1,&amp;quot;controlIndex&amp;quot;:1,&amp;quot;layoutIndex&amp;quot;:1,&amp;quot;sectionFactor&amp;quot;:12&amp;#125;,&amp;quot;webPartId&amp;quot;:&amp;quot;c41d05ec-0682-4af0-b807-649806ed56b3&amp;quot;,&amp;quot;addedFromPersistedData&amp;quot;:true&amp;#125;&quot;&gt;&lt;div data-sp-webpart=&quot;&quot; data-sp-webpartdataversion=&quot;1.0&quot; data-sp-webpartdata=&quot;&amp;#123;&amp;quot;id&amp;quot;:&amp;quot;c41d05ec-0682-4af0-b807-649806ed56b3&amp;quot;,&amp;quot;instanceId&amp;quot;:&amp;quot;7f1bf9be-7eca-4952-937f-4c72daccfc26&amp;quot;,&amp;quot;title&amp;quot;:&amp;quot;Portal Settings&amp;quot;,&amp;quot;description&amp;quot;:&amp;quot;Zentrale Verwaltung installierter Portal-Erweiterungen.&amp;quot;,&amp;quot;serverProcessedContent&amp;quot;:&amp;#123;&amp;quot;htmlStrings&amp;quot;:&amp;#123;&amp;#125;,&amp;quot;searchablePlainTexts&amp;quot;:&amp;#123;&amp;#125;,&amp;quot;imageSources&amp;quot;:&amp;#123;&amp;#125;,&amp;quot;links&amp;quot;:&amp;#123;&amp;#125;&amp;#125;,&amp;quot;dataVersion&amp;quot;:&amp;quot;1.0&amp;quot;,&amp;quot;properties&amp;quot;:&amp;#123;&amp;quot;title&amp;quot;:&amp;quot;Zentrale Verwaltung der Portal-Erweiterungen&amp;quot;&amp;#125;&amp;#125;&quot;&gt;&lt;div data-sp-componentid=&quot;&quot;&gt;c41d05ec-0682-4af0-b807-649806ed56b3&lt;/div&gt;&lt;div data-sp-htmlproperties=&quot;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" />
</File>
</Module>
</Elements>
+3
View File
@@ -0,0 +1,3 @@
<ApplyElementManifests>
<ElementManifest Location="71841e33-8bbd-4007-83a6-d950453226a2\elements.xml" />
</ApplyElementManifests>
+20 -3
View File
@@ -15,19 +15,36 @@ var config = json('config/config.json');
var copyAssets = json('config/copy-assets.json');
var manifest = json('src/webparts/portalSettings/PortalSettingsWebPart.manifest.json');
var styles = read('src/webparts/portalSettings/PortalSettings.scss');
var pageAsset = read('sharepoint/assets/PortalSettings.aspx');
var elements = read('sharepoint/assets/elements.xml');
var upgradeActions = read('sharepoint/assets/upgrade-actions.xml');
var sourceFiles = [
'src/ui/Dom.ts',
'src/ui/DynamicFormRenderer.ts',
'src/ui/PortalSettingsApp.ts'
].map(read).join('\n');
assert(packageJson.version === '3.1.0', 'Package-Version ist nicht 3.1.0.');
assert(solution.version === '3.1.0.0', 'Solution-Version ist nicht 3.1.0.0.');
assert(!solution.features, 'Alte ASPX-Feature-Assets sind noch registriert.');
assert(packageJson.version === '3.2.0', 'Package-Version ist nicht 3.2.0.');
assert(solution.version === '3.2.0.0', 'Solution-Version ist nicht 3.2.0.0.');
assert(solution.features && solution.features.length === 1, 'Das Seiten-Provisioning-Feature fehlt.');
assert(solution.features[0].assets.elementManifests.indexOf('elements.xml') >= 0 &&
solution.features[0].assets.elementFiles.indexOf('PortalSettings.aspx') >= 0 &&
solution.features[0].assets.upgradeActions.indexOf('upgrade-actions.xml') >= 0,
'Die Provisioning-Assets sind nicht vollständig registriert.');
assert(!!config.bundles['portal-settings-web-part'], 'WebPart-Bundle fehlt.');
assert(copyAssets.deployCdnPath === 'temp/deploy', 'Ship-Assets werden nicht nach temp/deploy geschrieben.');
assert(manifest.componentType === 'WebPart', 'Komponente ist kein WebPart.');
assert(!fs.existsSync(path.join(root, 'src/assets/PortalSettings.aspx')), 'Alte ASPX-Seite ist noch vorhanden.');
assert(pageAsset.indexOf('Microsoft.SharePoint.WebControls.ClientSidePage') >= 0,
'Das provisionierte Asset ist keine moderne SharePoint-Seite.');
assert(elements.indexOf('Url="PortalSettings.aspx"') >= 0 && elements.indexOf('RootWebOnly="TRUE"') >= 0 &&
elements.indexOf('IgnoreIfAlreadyExists="TRUE"') >= 0 && elements.indexOf('Level="Published"') >= 0,
'PortalSettings.aspx wird nicht sicher im Root-Web provisioniert.');
assert(elements.indexOf('CanvasContent1') >= 0 &&
elements.indexOf('c41d05ec-0682-4af0-b807-649806ed56b3') >= 0,
'Das PortalSettings-WebPart fehlt im provisionierten Canvas.');
assert(upgradeActions.indexOf('71841e33-8bbd-4007-83a6-d950453226a2\\elements.xml') >= 0,
'Die Upgrade-Provisionierung fehlt.');
assert(!fs.existsSync(path.join(root, 'src/extensions/portalSettings/PortalSettingsApplicationCustomizer.ts')), 'Alter Application Customizer ist noch vorhanden.');
assert(sourceFiles.indexOf('innerHTML') < 0, 'UI darf innerHTML nicht verwenden.');
['themePrimary', 'neutralPrimary', 'neutralLight', 'white'].forEach(function (slot) {