Aktualisiere Versionsnummer auf 3.2.3 in README.md, package.json, package-lock.json und package-solution.json. Passe Sequenzen in CustomBrandingSettingsProvider und Tests an.

This commit is contained in:
Torsten Brendgen
2026-08-19 21:08:15 +02:00
parent 55615fe75c
commit 457e58b54f
9 changed files with 16 additions and 11 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ PortalSettings V3 ist ein providerbasiertes SPFx-WebPart für SharePoint Server
| Eigenschaft | Wert | | Eigenschaft | Wert |
|---|---| |---|---|
| Version | 3.2.2 | | Version | 3.2.3 |
| SharePoint Framework | 1.4.1 | | SharePoint Framework | 1.4.1 |
| Build-Node | 8.17.0 | | Build-Node | 8.17.0 |
| npm | 6.x | | npm | 6.x |
@@ -165,7 +165,7 @@ sharepoint/solution/portal-settings.sppkg
## Installation ## Installation
1. `portal-settings.sppkg` im App Catalog durch Version `3.2.2.0` ersetzen. 1. `portal-settings.sppkg` im App Catalog durch Version `3.2.3.0` ersetzen.
2. Die App im Root Web der gewünschten Site Collection installieren oder aktualisieren. 2. Die App im Root Web der gewünschten Site Collection installieren oder aktualisieren.
3. Die Seite mit dem PnP-PowerShell-Skript erzeugen beziehungsweise reparieren: 3. Die Seite mit dem PnP-PowerShell-Skript erzeugen beziehungsweise reparieren:
+1 -1
View File
@@ -2,7 +2,7 @@
Stand: 21.07.2026 Stand: 21.07.2026
Branch: `dev-3.0` Branch: `dev-3.0`
Zielversion: 3.2.2 Zielversion: 3.2.3
## Architektur ## Architektur
+1 -1
View File
@@ -3,7 +3,7 @@
"solution": { "solution": {
"name": "portal-settings-client-side-solution", "name": "portal-settings-client-side-solution",
"id": "1c98e32d-bb7b-43b7-9625-074d6e4ea286", "id": "1c98e32d-bb7b-43b7-9625-074d6e4ea286",
"version": "3.2.2.0", "version": "3.2.3.0",
"includeClientSideAssets": true, "includeClientSideAssets": true,
"skipFeatureDeployment": false "skipFeatureDeployment": false
}, },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "portal-settings", "name": "portal-settings",
"version": "3.2.2", "version": "3.2.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "portal-settings", "name": "portal-settings",
"version": "3.2.2", "version": "3.2.3",
"private": true, "private": true,
"main": "lib/index.js", "main": "lib/index.js",
"engines": { "engines": {
@@ -31,7 +31,7 @@ export const CustomBrandingSettingsProvider: ISettingsProvider<ICustomBrandingSe
title: 'Custom Branding Application Customizer', title: 'Custom Branding Application Customizer',
description: 'MSFT-Custom-Solution:CustomBranding', description: 'MSFT-Custom-Solution:CustomBranding',
location: 'ClientSideExtension.ApplicationCustomizer', location: 'ClientSideExtension.ApplicationCustomizer',
sequence: 100 sequence: 90
} }
}, },
sections: [ sections: [
+3 -2
View File
@@ -54,7 +54,7 @@ export class PortalSettingsDataService {
const merged: any = mergePreservingUnknown(item.originalConfig, item.provider.normalize(item.config)); const merged: any = mergePreservingUnknown(item.originalConfig, item.provider.normalize(item.config));
if (item.provider.storage.kind === 'siteUserCustomAction') { if (item.provider.storage.kind === 'siteUserCustomAction') {
const persist: Promise<IUserCustomActionInfo> = item.context.action const persist: Promise<IUserCustomActionInfo> = item.context.action
? this.saveUserCustomAction(item.context.action, merged).then((): IUserCustomActionInfo => item.context.action) ? this.saveUserCustomAction(item.context.action, merged, item.provider).then((): IUserCustomActionInfo => item.context.action)
: this.createUserCustomAction(item.provider, merged); : this.createUserCustomAction(item.provider, merged);
return persist.then((action: IUserCustomActionInfo): void => { return persist.then((action: IUserCustomActionInfo): void => {
item.context.action = action; item.context.action = action;
@@ -252,12 +252,13 @@ export class PortalSettingsDataService {
.then((payload: any): any => payload.d || payload); .then((payload: any): any => payload.d || payload);
} }
private saveUserCustomAction(action: IUserCustomActionInfo, config: any): Promise<void> { private saveUserCustomAction(action: IUserCustomActionInfo, config: any, provider: ISettingsProvider<any>): Promise<void> {
const url: string = this.siteUrl + "/_api/site/UserCustomActions(guid'" + action.id + "')"; const url: string = this.siteUrl + "/_api/site/UserCustomActions(guid'" + action.id + "')";
const body: any = { const body: any = {
'__metadata': { 'type': action.entityType || 'SP.UserCustomAction' }, '__metadata': { 'type': action.entityType || 'SP.UserCustomAction' },
'ClientSideComponentProperties': JSON.stringify(config) 'ClientSideComponentProperties': JSON.stringify(config)
}; };
if (provider.storage.action) { body.Sequence = provider.storage.action.sequence; }
return this.context.spHttpClient.post(url, SPHttpClient.configurations.v1, { return this.context.spHttpClient.post(url, SPHttpClient.configurations.v1, {
headers: this.writeHeaders('MERGE'), body: JSON.stringify(body) headers: this.writeHeaders('MERGE'), body: JSON.stringify(body)
}).then((response: SPHttpClientResponse): Promise<void> => this.ensureOk(response, 'Konfiguration konnte nicht gespeichert werden.')); }).then((response: SPHttpClientResponse): Promise<void> => this.ensureOk(response, 'Konfiguration konnte nicht gespeichert werden.'));
+2
View File
@@ -25,6 +25,7 @@ const mega: ISettingsProvider<any> = getSettingsProvider('megamenu'); // tslint:
assert(!!mega.storage.action, 'MegaMenu-Aktivierungsdefinition fehlt.'); assert(!!mega.storage.action, 'MegaMenu-Aktivierungsdefinition fehlt.');
assert(mega.storage.action.name === 'MegaMenu', 'MegaMenu Action-Name ist nicht stabil.'); assert(mega.storage.action.name === 'MegaMenu', 'MegaMenu Action-Name ist nicht stabil.');
assert(mega.storage.action.location === 'ClientSideExtension.ApplicationCustomizer', 'MegaMenu Action-Location ist ungültig.'); assert(mega.storage.action.location === 'ClientSideExtension.ApplicationCustomizer', 'MegaMenu Action-Location ist ungültig.');
assert(mega.storage.action.sequence === 100, 'MegaMenu Action-Sequenz ist nicht stabil.');
const normalizedMega: any = mega.normalize({ cacheMinutes: 5000, cacheVersion: '', unknownFuture: 'keep', menuMode: 'other' }); // tslint:disable-line:no-any const normalizedMega: any = mega.normalize({ cacheMinutes: 5000, cacheVersion: '', unknownFuture: 'keep', menuMode: 'other' }); // tslint:disable-line:no-any
assert(normalizedMega.cacheMinutes === 1440, 'MegaMenu Cache-Maximum greift nicht.'); assert(normalizedMega.cacheMinutes === 1440, 'MegaMenu Cache-Maximum greift nicht.');
assert(normalizedMega.cacheVersion === '1', 'MegaMenu Cache-Fallback fehlt.'); assert(normalizedMega.cacheVersion === '1', 'MegaMenu Cache-Fallback fehlt.');
@@ -52,6 +53,7 @@ const branding: ISettingsProvider<any> = getSettingsProvider('custombranding');
assert(!!branding.storage.action, 'CustomBranding-Aktivierungsdefinition fehlt.'); assert(!!branding.storage.action, 'CustomBranding-Aktivierungsdefinition fehlt.');
assert(branding.storage.action.name === 'CustomBranding', 'CustomBranding Action-Name ist nicht stabil.'); assert(branding.storage.action.name === 'CustomBranding', 'CustomBranding Action-Name ist nicht stabil.');
assert(branding.storage.action.location === 'ClientSideExtension.ApplicationCustomizer', 'CustomBranding Action-Location ist ungültig.'); assert(branding.storage.action.location === 'ClientSideExtension.ApplicationCustomizer', 'CustomBranding Action-Location ist ungültig.');
assert(branding.storage.action.sequence === 90, 'CustomBranding muss vor MegaMenu geladen werden.');
const defaultBranding: any = branding.createDefault(); // tslint:disable-line:no-any const defaultBranding: any = branding.createDefault(); // tslint:disable-line:no-any
assert(defaultBranding.placeholderbottom.elements.length === 0, assert(defaultBranding.placeholderbottom.elements.length === 0,
'PortalSettings darf keinen Runtime-Standard-Footer in die Konfiguration schreiben.'); 'PortalSettings darf keinen Runtime-Standard-Footer in die Konfiguration schreiben.');
+4 -2
View File
@@ -22,8 +22,8 @@ var sourceFiles = [
].map(read).join('\n'); ].map(read).join('\n');
var dataService = read('src/services/PortalSettingsDataService.ts'); var dataService = read('src/services/PortalSettingsDataService.ts');
assert(packageJson.version === '3.2.2', 'Package-Version ist nicht 3.2.2.'); assert(packageJson.version === '3.2.3', 'Package-Version ist nicht 3.2.3.');
assert(solution.version === '3.2.2.0', 'Solution-Version ist nicht 3.2.2.0.'); assert(solution.version === '3.2.3.0', 'Solution-Version ist nicht 3.2.3.0.');
assert(!solution.features, 'Das inkompatible Seiten-Provisioning-Feature darf nicht paketiert werden.'); assert(!solution.features, 'Das inkompatible Seiten-Provisioning-Feature darf nicht paketiert werden.');
assert(!!config.bundles['portal-settings-web-part'], 'WebPart-Bundle fehlt.'); assert(!!config.bundles['portal-settings-web-part'], 'WebPart-Bundle fehlt.');
assert(copyAssets.deployCdnPath === 'temp/deploy', 'Ship-Assets werden nicht nach temp/deploy geschrieben.'); assert(copyAssets.deployCdnPath === 'temp/deploy', 'Ship-Assets werden nicht nach temp/deploy geschrieben.');
@@ -34,6 +34,8 @@ assert(sourceFiles.indexOf('innerHTML') < 0, 'UI darf innerHTML nicht verwenden.
assert(dataService.indexOf('/_api/site/rootweb/UserCustomActions') >= 0 && assert(dataService.indexOf('/_api/site/rootweb/UserCustomActions') >= 0 &&
dataService.indexOf('siteActions.concat(values[1])') >= 0, dataService.indexOf('siteActions.concat(values[1])') >= 0,
'Root-Web-Actions werden nicht für die Provider-Erkennung berücksichtigt.'); 'Root-Web-Actions werden nicht für die Provider-Erkennung berücksichtigt.');
assert(dataService.indexOf('body.Sequence = provider.storage.action.sequence') >= 0,
'Bestehende Actions werden nicht auf die Provider-Sequence aktualisiert.');
['themePrimary', 'neutralPrimary', 'neutralLight', 'white'].forEach(function (slot) { ['themePrimary', 'neutralPrimary', 'neutralLight', 'white'].forEach(function (slot) {
assert(styles.indexOf('[theme: ' + slot + ', default:') >= 0, 'Themeslot fehlt: ' + slot); assert(styles.indexOf('[theme: ' + slot + ', default:') >= 0, 'Themeslot fehlt: ' + slot);
}); });