diff --git a/README.md b/README.md index d056c0b..4fc114c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ PortalSettings V3 ist ein providerbasiertes SPFx-WebPart für SharePoint Server | Eigenschaft | Wert | |---|---| -| Version | 3.2.2 | +| Version | 3.2.3 | | SharePoint Framework | 1.4.1 | | Build-Node | 8.17.0 | | npm | 6.x | @@ -165,7 +165,7 @@ sharepoint/solution/portal-settings.sppkg ## 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. 3. Die Seite mit dem PnP-PowerShell-Skript erzeugen beziehungsweise reparieren: diff --git a/ToDo.md b/ToDo.md index 1224a34..95b6cf6 100644 --- a/ToDo.md +++ b/ToDo.md @@ -2,7 +2,7 @@ Stand: 21.07.2026 Branch: `dev-3.0` -Zielversion: 3.2.2 +Zielversion: 3.2.3 ## Architektur diff --git a/config/package-solution.json b/config/package-solution.json index d4dd341..233b697 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": "3.2.2.0", + "version": "3.2.3.0", "includeClientSideAssets": true, "skipFeatureDeployment": false }, diff --git a/package-lock.json b/package-lock.json index 6cb8087..7335177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "portal-settings", - "version": "3.2.2", + "version": "3.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9819b0f..ffbdad4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "portal-settings", - "version": "3.2.2", + "version": "3.2.3", "private": true, "main": "lib/index.js", "engines": { diff --git a/src/providers/CustomBrandingSettingsProvider.ts b/src/providers/CustomBrandingSettingsProvider.ts index 7872c88..5ab7e4c 100644 --- a/src/providers/CustomBrandingSettingsProvider.ts +++ b/src/providers/CustomBrandingSettingsProvider.ts @@ -31,7 +31,7 @@ export const CustomBrandingSettingsProvider: ISettingsProvider = 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); return persist.then((action: IUserCustomActionInfo): void => { item.context.action = action; @@ -252,12 +252,13 @@ export class PortalSettingsDataService { .then((payload: any): any => payload.d || payload); } - private saveUserCustomAction(action: IUserCustomActionInfo, config: any): Promise { + private saveUserCustomAction(action: IUserCustomActionInfo, config: any, provider: ISettingsProvider): Promise { const url: string = this.siteUrl + "/_api/site/UserCustomActions(guid'" + action.id + "')"; const body: any = { '__metadata': { 'type': action.entityType || 'SP.UserCustomAction' }, 'ClientSideComponentProperties': JSON.stringify(config) }; + if (provider.storage.action) { body.Sequence = provider.storage.action.sequence; } return this.context.spHttpClient.post(url, SPHttpClient.configurations.v1, { headers: this.writeHeaders('MERGE'), body: JSON.stringify(body) }).then((response: SPHttpClientResponse): Promise => this.ensureOk(response, 'Konfiguration konnte nicht gespeichert werden.')); diff --git a/tests/ProviderRegistry.test.ts b/tests/ProviderRegistry.test.ts index 3678b41..344cc1c 100644 --- a/tests/ProviderRegistry.test.ts +++ b/tests/ProviderRegistry.test.ts @@ -25,6 +25,7 @@ const mega: ISettingsProvider = getSettingsProvider('megamenu'); // tslint: assert(!!mega.storage.action, 'MegaMenu-Aktivierungsdefinition fehlt.'); 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.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 assert(normalizedMega.cacheMinutes === 1440, 'MegaMenu Cache-Maximum greift nicht.'); assert(normalizedMega.cacheVersion === '1', 'MegaMenu Cache-Fallback fehlt.'); @@ -52,6 +53,7 @@ const branding: ISettingsProvider = getSettingsProvider('custombranding'); assert(!!branding.storage.action, 'CustomBranding-Aktivierungsdefinition fehlt.'); 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.sequence === 90, 'CustomBranding muss vor MegaMenu geladen werden.'); const defaultBranding: any = branding.createDefault(); // tslint:disable-line:no-any assert(defaultBranding.placeholderbottom.elements.length === 0, 'PortalSettings darf keinen Runtime-Standard-Footer in die Konfiguration schreiben.'); diff --git a/tests/validate-static-assets.js b/tests/validate-static-assets.js index d60014c..4e1542d 100644 --- a/tests/validate-static-assets.js +++ b/tests/validate-static-assets.js @@ -22,8 +22,8 @@ var sourceFiles = [ ].map(read).join('\n'); var dataService = read('src/services/PortalSettingsDataService.ts'); -assert(packageJson.version === '3.2.2', 'Package-Version ist nicht 3.2.2.'); -assert(solution.version === '3.2.2.0', 'Solution-Version ist nicht 3.2.2.0.'); +assert(packageJson.version === '3.2.3', 'Package-Version ist nicht 3.2.3.'); +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(!!config.bundles['portal-settings-web-part'], 'WebPart-Bundle fehlt.'); 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 && dataService.indexOf('siteActions.concat(values[1])') >= 0, '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) { assert(styles.indexOf('[theme: ' + slot + ', default:') >= 0, 'Themeslot fehlt: ' + slot); });