Aktualisiere Versionsnummer auf 3.2.7 in README.md, package.json, package-lock.json und package-solution.json. Passe Tests an, um die neuen Versionen zu validieren und ändere die Methode zur Speicherung von Root-Web-Eigenschaften in PortalSettingsDataService.
This commit is contained in:
@@ -6,7 +6,7 @@ PortalSettings V3 ist ein providerbasiertes SPFx-WebPart für SharePoint Server
|
|||||||
|
|
||||||
| Eigenschaft | Wert |
|
| Eigenschaft | Wert |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Version | 3.2.6 |
|
| Version | 3.2.7 |
|
||||||
| 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 |
|
||||||
@@ -171,7 +171,7 @@ sharepoint/solution/portal-settings.sppkg
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. `portal-settings.sppkg` im App Catalog durch Version `3.2.6.0` ersetzen.
|
1. `portal-settings.sppkg` im App Catalog durch Version `3.2.7.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:
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Stand: 21.07.2026
|
Stand: 21.07.2026
|
||||||
Branch: `dev-3.0`
|
Branch: `dev-3.0`
|
||||||
Zielversion: 3.2.6
|
Zielversion: 3.2.7
|
||||||
|
|
||||||
## Architektur
|
## Architektur
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ Zielversion: 3.2.6
|
|||||||
- [ ] Per PnP-Skript provisionierte `PortalSettings.aspx` und enthaltenes WebPart prüfen.
|
- [ ] Per PnP-Skript provisionierte `PortalSettings.aspx` und enthaltenes WebPart prüfen.
|
||||||
- [ ] MegaMenu-Termsets laden und speichern.
|
- [ ] MegaMenu-Termsets laden und speichern.
|
||||||
- [ ] CustomBranding laden und schemaerhaltend speichern.
|
- [ ] CustomBranding laden und schemaerhaltend speichern.
|
||||||
- [x] ExpiryIndicator-Standard über SharePoint-SE-kompatibles POST ohne MERGE/PATCH speichern.
|
- [x] ExpiryIndicator-Standard über SharePoint-SE-kompatibles CSOM `ProcessQuery` speichern.
|
||||||
- [ ] Expiry-Bindung hinzufügen, lokal konfigurieren und wieder auf Vererbung stellen.
|
- [ ] Expiry-Bindung hinzufügen, lokal konfigurieren und wieder auf Vererbung stellen.
|
||||||
- [ ] Bedienung mit Tastatur, 200-Prozent-Zoom und Windows-Hochkontrast prüfen.
|
- [ ] Bedienung mit Tastatur, 200-Prozent-Zoom und Windows-Hochkontrast prüfen.
|
||||||
- [ ] Alte V2-Seite nach erfolgreicher Parallelabnahme archivieren oder entfernen.
|
- [ ] Alte V2-Seite nach erfolgreicher Parallelabnahme archivieren oder entfernen.
|
||||||
|
|||||||
@@ -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.6.0",
|
"version": "3.2.7.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": false
|
"skipFeatureDeployment": false
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "portal-settings",
|
"name": "portal-settings",
|
||||||
"version": "3.2.6",
|
"version": "3.2.7",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "portal-settings",
|
"name": "portal-settings",
|
||||||
"version": "3.2.6",
|
"version": "3.2.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -299,13 +299,35 @@ export class PortalSettingsDataService {
|
|||||||
|
|
||||||
private saveRootProperty(key: string, value: string): Promise<void> {
|
private saveRootProperty(key: string, value: string): Promise<void> {
|
||||||
if (!key) { return Promise.reject(new Error('Der Property-Bag-Schlüssel fehlt.')); }
|
if (!key) { return Promise.reject(new Error('Der Property-Bag-Schlüssel fehlt.')); }
|
||||||
const body: any = { '__metadata': { 'type': 'SP.PropertyValues' } };
|
const requestXml: string = '<Request SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="PortalSettingsV3" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009">' +
|
||||||
body[this.encodePropertyName(key)] = value;
|
'<Actions>' +
|
||||||
return this.context.spHttpClient.post(this.siteUrl + '/_api/web/AllProperties', SPHttpClient.configurations.v1, {
|
'<Method Name="SetFieldValue" Id="5" ObjectPathId="4"><Parameters>' +
|
||||||
// SP.PropertyValues accepts POST, but SharePoint Server SE rejects the
|
'<Parameter Type="String">' + this.escapeXml(key) + '</Parameter>' +
|
||||||
// MERGE override because it is handled as an unsupported HTTP PATCH.
|
'<Parameter Type="String">' + this.escapeXml(value) + '</Parameter>' +
|
||||||
headers: this.writeHeaders(), body: JSON.stringify(body)
|
'</Parameters></Method>' +
|
||||||
}).then((response: SPHttpClientResponse): Promise<void> => this.ensureOk(response, 'Der Site-Collection-Standard konnte nicht gespeichert werden.'));
|
'<Method Name="Update" Id="6" ObjectPathId="2" />' +
|
||||||
|
'</Actions>' +
|
||||||
|
'<ObjectPaths>' +
|
||||||
|
'<StaticProperty Id="0" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />' +
|
||||||
|
'<Property Id="2" ParentId="0" Name="Web" />' +
|
||||||
|
'<Property Id="4" ParentId="2" Name="AllProperties" />' +
|
||||||
|
'</ObjectPaths>' +
|
||||||
|
'</Request>';
|
||||||
|
return this.context.spHttpClient.post(this.siteUrl + '/_vti_bin/client.svc/ProcessQuery', SPHttpClient.configurations.v1, {
|
||||||
|
headers: { 'Accept': 'application/json', 'Content-Type': 'text/xml;charset="UTF-8"' }, body: requestXml
|
||||||
|
}).then((response: SPHttpClientResponse): Promise<string> => {
|
||||||
|
if (!response.ok) {
|
||||||
|
return this.responseError(response, 'Der Site-Collection-Standard konnte nicht gespeichert werden.')
|
||||||
|
.then((error: Error): Promise<string> => Promise.reject(error));
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
}).then((text: string): void => {
|
||||||
|
const payload: any[] = text ? JSON.parse(text) : [];
|
||||||
|
if (payload.length && payload[0] && payload[0].ErrorInfo) {
|
||||||
|
throw new Error('Der Site-Collection-Standard konnte nicht gespeichert werden. ' +
|
||||||
|
(payload[0].ErrorInfo.ErrorMessage || 'SharePoint hat den CSOM-Aufruf abgelehnt.'));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private findAction(provider: ISettingsProvider<any>, actions: IUserCustomActionInfo[]): IUserCustomActionInfo | undefined {
|
private findAction(provider: ISettingsProvider<any>, actions: IUserCustomActionInfo[]): IUserCustomActionInfo | undefined {
|
||||||
@@ -381,7 +403,10 @@ export class PortalSettingsDataService {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
private normalizePropertyName(value: string): string { return String(value || '').replace(/_x002e_/gi, '.').toLowerCase(); }
|
private normalizePropertyName(value: string): string { return String(value || '').replace(/_x002e_/gi, '.').toLowerCase(); }
|
||||||
private encodePropertyName(value: string): string { return value.replace(/\./g, '_x002e_'); }
|
private escapeXml(value: string): string {
|
||||||
|
return String(value || '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"').replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
private readHeaders(): any { return { 'Accept': 'application/json;odata=verbose', 'OData-Version': '3.0' }; }
|
private readHeaders(): any { return { 'Accept': 'application/json;odata=verbose', 'OData-Version': '3.0' }; }
|
||||||
private writeHeaders(method?: string): any {
|
private writeHeaders(method?: string): any {
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ var rootPropertyWriter = dataService.substring(
|
|||||||
dataService.indexOf('private findAction')
|
dataService.indexOf('private findAction')
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(packageJson.version === '3.2.6', 'Package-Version ist nicht 3.2.6.');
|
assert(packageJson.version === '3.2.7', 'Package-Version ist nicht 3.2.7.');
|
||||||
assert(solution.version === '3.2.6.0', 'Solution-Version ist nicht 3.2.6.0.');
|
assert(solution.version === '3.2.7.0', 'Solution-Version ist nicht 3.2.7.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.');
|
||||||
@@ -40,9 +40,10 @@ assert(dataService.indexOf('/_api/site/rootweb/UserCustomActions') >= 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,
|
assert(dataService.indexOf('body.Sequence = provider.storage.action.sequence') >= 0,
|
||||||
'Bestehende Actions werden nicht auf die Provider-Sequence aktualisiert.');
|
'Bestehende Actions werden nicht auf die Provider-Sequence aktualisiert.');
|
||||||
assert(rootPropertyWriter.indexOf('headers: this.writeHeaders(), body: JSON.stringify(body)') >= 0 &&
|
assert(rootPropertyWriter.indexOf('/_vti_bin/client.svc/ProcessQuery') >= 0 &&
|
||||||
rootPropertyWriter.indexOf("writeHeaders('MERGE')") < 0,
|
rootPropertyWriter.indexOf('SetFieldValue') >= 0 && rootPropertyWriter.indexOf('Name="Update"') >= 0 &&
|
||||||
'Root-Web-Properties müssen mit POST ohne MERGE/PATCH gespeichert werden.');
|
rootPropertyWriter.indexOf('/_api/web/AllProperties') < 0,
|
||||||
|
'Root-Web-Properties müssen über den SharePoint-CSOM-Endpunkt gespeichert werden.');
|
||||||
['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);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user