From d97dbf45aab6bcf8f0758d36e3bef44df46b9ffc Mon Sep 17 00:00:00 2001 From: Torsten Brendgen Date: Sat, 18 Jul 2026 23:48:40 +0200 Subject: [PATCH] feat: update version to 2.1.2 and enhance ExpiryIndicator functionality with new binding handling --- README.md | 4 +-- config/package-solution.json | 4 +-- package-lock.json | 2 +- package.json | 2 +- scripts/Disable-ExpiryIndicator.ps1 | 20 +++++++++++++- scripts/Enable-ExpiryIndicator.ps1 | 26 ++++++++++++++++--- sharepoint/assets/ExpiryIndicatorClassic.js | 25 +++++++++++++++--- ...piryIndicatorFieldCustomizer.manifest.json | 2 +- ...dicatorApplicationCustomizer.manifest.json | 2 +- .../ExpiryIndicatorCommandSet.manifest.json | 2 +- 10 files changed, 71 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 13b8f7a..295368f 100644 --- a/README.md +++ b/README.md @@ -354,7 +354,7 @@ Version 2.1 legt bei der App-Installation `ExpiryIndicatorClassic.js` unter - einen einmaligen Web-`ScriptLink` für CSR/JSLink, der das gebundene Feld der aktuellen Liste selbst erkennt, - die Berechnung, Beschriftung und den Zeilenverlauf in der klassischen Ansicht, -- den Ribbon-Befehl **Ablaufdatum +1 Jahr**, +- den Ribbon-Befehl **Ablaufdatum +1 Jahr** im Tab **Files** beziehungsweise **Items**, - den Einstellungsdialog über denselben URL-Parameter `expiryIndicatorSettings=1`. Soll nur die moderne Ansicht aktiviert werden, kann die Classic-Registrierung ausgelassen werden: @@ -414,7 +414,7 @@ anlegen. Das Skript bleibt vor allem für automatisierte oder umfangreiche Rollo ### Upgrade auf Version 2.1 -1. Das vorhandene Paket im App Catalog durch Version `2.1.1.0` ersetzen. +1. Das vorhandene Paket im App Catalog durch Version `2.1.2.0` ersetzen. 2. Die App in der Site aktualisieren. Die enthaltene Feature-UpgradeAction provisioniert ausschließlich das aktualisierten Assets und legt keine fachliche Spalte an. 3. `Enable-ExpiryIndicator.ps1` für jede bereits angebundene Liste erneut ausführen. Das Skript erhält die diff --git a/config/package-solution.json b/config/package-solution.json index ccc8a33..be528ae 100644 --- a/config/package-solution.json +++ b/config/package-solution.json @@ -3,7 +3,7 @@ "solution": { "name": "expiry-indicator-client-side-solution", "id": "68bb6d2d-9895-45b4-88e8-b98835faa981", - "version": "2.1.1.0", + "version": "2.1.2.0", "includeClientSideAssets": true, "skipFeatureDeployment": false, "features": [ @@ -11,7 +11,7 @@ "title": "ExpiryIndicator extension registration", "description": "Registers ExpiryIndicator commands and its settings Application Customizer. Does not provision ExpiryDate.", "id": "913402af-ab9a-4974-9f86-5c2159ae41db", - "version": "2.1.1.0", + "version": "2.1.2.0", "assets": { "elementManifests": [ "elements.xml", diff --git a/package-lock.json b/package-lock.json index e5c5a95..4a6ecdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "expiry-indicator", - "version": "2.1.1", + "version": "2.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 845d68a..97a48b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expiry-indicator", - "version": "2.1.1", + "version": "2.1.2", "private": true, "engines": { "node": ">=6.9.0 <9.0.0" diff --git a/scripts/Disable-ExpiryIndicator.ps1 b/scripts/Disable-ExpiryIndicator.ps1 index d0077fd..cc974ba 100644 --- a/scripts/Disable-ExpiryIndicator.ps1 +++ b/scripts/Disable-ExpiryIndicator.ps1 @@ -18,6 +18,23 @@ $isapiPath = Join-Path ([Environment]::GetFolderPath('CommonProgramFiles')) 'mic Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.Runtime.dll') Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.dll') +function Expand-ExpiryIndicatorBindings { + param([object]$Value) + + if ($null -eq $Value) { return } + if ($Value -is [System.Array]) { + foreach ($item in $Value) { + Expand-ExpiryIndicatorBindings -Value $item + } + return + } + if ($Value.PSObject.Properties['webUrl'] -and + $Value.PSObject.Properties['listId'] -and + $Value.PSObject.Properties['fieldInternalName']) { + Write-Output $Value + } +} + $context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl) $context.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials @@ -50,7 +67,8 @@ try { $existingBindingsJson = [string]$rootWeb.AllProperties[$bindingsKey] if (-not [string]::IsNullOrWhiteSpace($existingBindingsJson)) { try { - $bindings = @($existingBindingsJson | ConvertFrom-Json) + $parsedBindings = $existingBindingsJson | ConvertFrom-Json + $bindings = @(Expand-ExpiryIndicatorBindings -Value $parsedBindings) } catch { $bindings = @() diff --git a/scripts/Enable-ExpiryIndicator.ps1 b/scripts/Enable-ExpiryIndicator.ps1 index 80ed692..283daa0 100644 --- a/scripts/Enable-ExpiryIndicator.ps1 +++ b/scripts/Enable-ExpiryIndicator.ps1 @@ -20,6 +20,23 @@ $isapiPath = Join-Path ([Environment]::GetFolderPath('CommonProgramFiles')) 'mic Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.Runtime.dll') Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.dll') +function Expand-ExpiryIndicatorBindings { + param([object]$Value) + + if ($null -eq $Value) { return } + if ($Value -is [System.Array]) { + foreach ($item in $Value) { + Expand-ExpiryIndicatorBindings -Value $item + } + return + } + if ($Value.PSObject.Properties['webUrl'] -and + $Value.PSObject.Properties['listId'] -and + $Value.PSObject.Properties['fieldInternalName']) { + Write-Output $Value + } +} + $context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl) $context.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials @@ -58,7 +75,7 @@ try { $rootWeb.AllProperties[$descriptorKey] = ([ordered]@{ key = 'ExpiryIndicator' displayName = 'Expiry Indicator' - version = '2.1.1' + version = '2.1.2' provider = 'expiryIndicator' componentIds = @( 'a555f4fc-d6a6-4421-8189-457449d9bbde', @@ -72,7 +89,8 @@ try { $existingBindingsJson = [string]$rootWeb.AllProperties[$bindingsKey] if (-not [string]::IsNullOrWhiteSpace($existingBindingsJson)) { try { - $bindings = @($existingBindingsJson | ConvertFrom-Json) + $parsedBindings = $existingBindingsJson | ConvertFrom-Json + $bindings = @(Expand-ExpiryIndicatorBindings -Value $parsedBindings) } catch { Write-Warning 'Das vorhandene ExpiryIndicator-Bindungsinventar war ungültig und wird neu aufgebaut.' @@ -130,10 +148,10 @@ try { $scriptAction.Update() $ribbonLocation = if ($list.BaseType -eq [Microsoft.SharePoint.Client.BaseType]::DocumentLibrary) { - 'Ribbon.Library.Actions.Controls._children' + 'Ribbon.Documents.Manage.Controls._children' } else { - 'Ribbon.List.Actions.Controls._children' + 'Ribbon.ListItem.Actions.Controls._children' } $ribbonXml = @" diff --git a/sharepoint/assets/ExpiryIndicatorClassic.js b/sharepoint/assets/ExpiryIndicatorClassic.js index d36312e..50d440b 100644 --- a/sharepoint/assets/ExpiryIndicatorClassic.js +++ b/sharepoint/assets/ExpiryIndicatorClassic.js @@ -4,7 +4,7 @@ var FIELD_CUSTOMIZER_ID = 'a555f4fc-d6a6-4421-8189-457449d9bbde'; var SITE_DEFAULTS_PROPERTY = 'PortalSettings.ExpiryIndicator.Defaults'; var WEB_OVERRIDE_PROPERTY = 'PortalSettings.ExpiryIndicator.Override'; - var state = { context: null, field: null, config: null, loading: null }; + var state = { context: null, field: null, config: null, loading: null, itemEntityType: null }; function configuredExpiryField() { var scripts = document.getElementsByTagName('script'); @@ -421,16 +421,33 @@ } catch (ignore) { return []; } } + function getItemEntityType() { + if (state.itemEntityType) { return Promise.resolve(state.itemEntityType); } + return request('GET', listUrl(state.context) + '?$select=ListItemEntityTypeFullName') + .then(function (data) { + var list = data.d || data; + if (!list.ListItemEntityTypeFullName) { + throw new Error('Der REST-Entitätstyp der Liste konnte nicht ermittelt werden.'); + } + state.itemEntityType = list.ListItemEntityTypeFullName; + return state.itemEntityType; + }); + } + function extendOne(id, config) { var fields = [config.baseField, config.expiryField].concat(ruleFields(config)); - return request('GET', listUrl(state.context) + '/items(' + id + ')?$select=Id,' + fields.join(',')) - .then(function (data) { + return Promise.all([ + request('GET', listUrl(state.context) + '/items(' + id + ')?$select=Id,' + fields.join(',')), + getItemEntityType() + ]).then(function (results) { + var data = results[0]; + var entityType = results[1]; var item = data.d || data; var created = parseDate(item[config.baseField]); var expiry = parseDate(item[config.expiryField]); var base = expiry || addDuration(created, behavior(config, item).lifeTime); var updated = addDuration(base, { value: 1, unit: 'years' }); - var body = { '__metadata': { 'type': item.__metadata.type } }; + var body = { '__metadata': { 'type': item.__metadata && item.__metadata.type || entityType } }; body[config.expiryField] = updated.toISOString(); return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); diff --git a/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json b/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json index f558685..0faad74 100644 --- a/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json +++ b/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json @@ -4,7 +4,7 @@ "alias": "ExpiryIndicatorFieldCustomizer", "componentType": "Extension", "extensionType": "FieldCustomizer", - "version": "2.1.1", + "version": "2.1.2", "manifestVersion": 2, "requiresCustomScript": false } diff --git a/src/extensions/expiryIndicatorApplicationCustomizer/ExpiryIndicatorApplicationCustomizer.manifest.json b/src/extensions/expiryIndicatorApplicationCustomizer/ExpiryIndicatorApplicationCustomizer.manifest.json index 1a5dadf..4ab953f 100644 --- a/src/extensions/expiryIndicatorApplicationCustomizer/ExpiryIndicatorApplicationCustomizer.manifest.json +++ b/src/extensions/expiryIndicatorApplicationCustomizer/ExpiryIndicatorApplicationCustomizer.manifest.json @@ -4,7 +4,7 @@ "alias": "ExpiryIndicatorApplicationCustomizer", "componentType": "Extension", "extensionType": "ApplicationCustomizer", - "version": "2.1.1", + "version": "2.1.2", "manifestVersion": 2, "requiresCustomScript": false } diff --git a/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json b/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json index b84d7ab..b9f5515 100644 --- a/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json +++ b/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json @@ -4,7 +4,7 @@ "alias": "ExpiryIndicatorCommandSet", "componentType": "Extension", "extensionType": "ListViewCommandSet", - "version": "2.1.1", + "version": "2.1.2", "manifestVersion": 2, "requiresCustomScript": false, "items": {