diff --git a/README.md b/README.md index 79dbc16..a757ad2 100644 --- a/README.md +++ b/README.md @@ -128,9 +128,10 @@ In **Standard-Farbregeln** wird nur das JSON-Array für `default.columnRule` ein Die Farbregeln werden von oben nach unten ausgewertet; die erste passende Regel gewinnt. Deshalb muss `<= 0` vor `<= 30` und `<= 90` stehen. Ohne passende Farbregel wird das Datum ohne besondere Farbe angezeigt. -Eine passende Regel färbt die komplette SharePoint-Zeile einschließlich aller sichtbaren Zellen mit -`backgroundColor` und passt deren Schriftfarbe über `textColor` an. Ein konfiguriertes `label` wird in derselben -SharePoint-Standardschrift direkt neben dem Datum dargestellt. +Eine passende Regel färbt die komplette SharePoint-Zeile mit einem durchgehenden Verlauf vom weißen +SharePoint-Standardhintergrund links bis zur konfigurierten `backgroundColor` rechts. Die Auswahlspalte bleibt +ungefärbt. `textColor` bestimmt die Schriftfarbe der eingefärbten Zellen. Ein konfiguriertes `label` wird in +derselben SharePoint-Standardschrift direkt neben dem Datum dargestellt. Unterstützte Operatoren: diff --git a/ToDo.md b/ToDo.md index f15ceec..e41ebd5 100644 --- a/ToDo.md +++ b/ToDo.md @@ -27,7 +27,7 @@ Berechnung des effektiven Ablaufdatums: 3. Vor jeder Wertprüfung wird geprüft, ob `columnName` in der aktuellen Liste/Bibliothek existiert. Ein fehlendes Feld kann die Regel nicht erfüllen. 4. Existiert das Feld und entspricht sein Wert `columnValue`, werden `lifeTime` und `columnRule` dieser Regel verwendet. 5. Passt keine Regel oder existiert keines der Regelfelder, werden `default.lifeTime` und `default.columnRule` verwendet. -6. Die erste passende `columnRule` bestimmt die Hintergrundfarbe der kompletten Listenzeile, deren Textfarbe und die optionale Beschriftung. +6. Die erste passende `columnRule` bestimmt den Zeilenverlauf vom Standardhintergrund zur Regel-Hintergrundfarbe, die Textfarbe und die optionale Beschriftung; die Auswahlspalte bleibt ungefärbt. Die Berechnung arbeitet mit Kalenderjahren/-monaten/-tagen, nicht mit pauschalen 365-Tage-Jahren. diff --git a/config/package-solution.json b/config/package-solution.json index 3a917c8..2b02331 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": "1.0.7.0", + "version": "1.0.8.0", "includeClientSideAssets": true, "skipFeatureDeployment": false, "features": [ @@ -11,7 +11,7 @@ "title": "ExpiryIndicator command set registration", "description": "Registers ExpiryIndicator commands for modern lists and document libraries. Does not provision ExpiryDate.", "id": "913402af-ab9a-4974-9f86-5c2159ae41db", - "version": "1.0.7.0", + "version": "1.0.8.0", "assets": { "elementManifests": [ "elements.xml" diff --git a/package.json b/package.json index 3144e5a..9190091 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expiry-indicator", - "version": "1.0.7", + "version": "1.0.8", "private": true, "engines": { "node": ">=6.9.0 <9.0.0" diff --git a/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json b/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.manifest.json index d59de00..a5bd1fe 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": "1.0.7", + "version": "1.0.8", "manifestVersion": 2, "requiresCustomScript": false } diff --git a/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.ts b/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.ts index 391e9f2..f2dfe7f 100644 --- a/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.ts +++ b/src/extensions/expiryIndicator/ExpiryIndicatorFieldCustomizer.ts @@ -100,11 +100,11 @@ export default class ExpiryIndicatorFieldCustomizer this._rememberCellStyle(cell); if (evaluation.matchedRule) { - this._getRowStyleTargets(container).forEach((target: HTMLElement): void => { - this._rememberCellStyle(target); - target.style.backgroundColor = evaluation.matchedRule!.backgroundColor; - target.style.color = evaluation.matchedRule!.textColor; - }); + this._applyRowGradient( + container, + evaluation.matchedRule.backgroundColor, + evaluation.matchedRule.textColor + ); } wrapper.textContent = formatDate(evaluation.effectiveExpiryDate); @@ -159,14 +159,41 @@ export default class ExpiryIndicatorFieldCustomizer return [this._findCellElement(container)]; } - const targets: HTMLElement[] = [row]; - const cells: NodeListOf = row.querySelectorAll('[role="gridcell"]'); + const targets: HTMLElement[] = []; + const cells: NodeListOf = row.querySelectorAll('[role="gridcell"], [role="rowheader"]'); for (let index: number = 0; index < cells.length; index++) { - targets.push(cells[index] as HTMLElement); + const cell: HTMLElement = cells[index] as HTMLElement; + if (cell.getAttribute('aria-colindex') !== '1') { + targets.push(cell); + } } return targets; } + private _applyRowGradient(container: HTMLElement, backgroundColor: string, textColor: string): void { + const cells: HTMLElement[] = this._getRowStyleTargets(container); + if (cells.length === 0) { + return; + } + + const firstRect: ClientRect = cells[0].getBoundingClientRect(); + const lastRect: ClientRect = cells[cells.length - 1].getBoundingClientRect(); + const totalWidth: number = Math.max(1, lastRect.right - firstRect.left); + const gradient: string = 'linear-gradient(to right, #ffffff, ' + backgroundColor + ')'; + + cells.forEach((cell: HTMLElement): void => { + const rect: ClientRect = cell.getBoundingClientRect(); + const offset: number = rect.left - firstRect.left; + this._rememberCellStyle(cell); + cell.style.backgroundColor = '#ffffff'; + cell.style.backgroundImage = gradient; + cell.style.backgroundSize = totalWidth + 'px 100%'; + cell.style.backgroundPosition = (-offset) + 'px 0'; + cell.style.backgroundRepeat = 'no-repeat'; + cell.style.color = textColor; + }); + } + private _findRowElement(container: HTMLElement): HTMLElement | undefined { let current: HTMLElement | null = container; let level: number = 0; @@ -208,6 +235,10 @@ export default class ExpiryIndicatorFieldCustomizer } cell.setAttribute('data-expiry-indicator-styled', 'true'); cell.setAttribute('data-expiry-original-background', cell.style.backgroundColor || ''); + cell.setAttribute('data-expiry-original-background-image', cell.style.backgroundImage || ''); + cell.setAttribute('data-expiry-original-background-size', cell.style.backgroundSize || ''); + cell.setAttribute('data-expiry-original-background-position', cell.style.backgroundPosition || ''); + cell.setAttribute('data-expiry-original-background-repeat', cell.style.backgroundRepeat || ''); cell.setAttribute('data-expiry-original-color', cell.style.color || ''); cell.setAttribute('data-expiry-original-had-title', cell.hasAttribute('title') ? 'true' : 'false'); cell.setAttribute('data-expiry-original-title', cell.getAttribute('title') || ''); @@ -219,6 +250,10 @@ export default class ExpiryIndicatorFieldCustomizer } cell.style.backgroundColor = cell.getAttribute('data-expiry-original-background') || ''; + cell.style.backgroundImage = cell.getAttribute('data-expiry-original-background-image') || ''; + cell.style.backgroundSize = cell.getAttribute('data-expiry-original-background-size') || ''; + cell.style.backgroundPosition = cell.getAttribute('data-expiry-original-background-position') || ''; + cell.style.backgroundRepeat = cell.getAttribute('data-expiry-original-background-repeat') || ''; cell.style.color = cell.getAttribute('data-expiry-original-color') || ''; if (cell.getAttribute('data-expiry-original-had-title') === 'true') { cell.setAttribute('title', cell.getAttribute('data-expiry-original-title') || ''); @@ -228,6 +263,10 @@ export default class ExpiryIndicatorFieldCustomizer cell.removeAttribute('data-expiry-indicator-styled'); cell.removeAttribute('data-expiry-original-background'); + cell.removeAttribute('data-expiry-original-background-image'); + cell.removeAttribute('data-expiry-original-background-size'); + cell.removeAttribute('data-expiry-original-background-position'); + cell.removeAttribute('data-expiry-original-background-repeat'); cell.removeAttribute('data-expiry-original-color'); cell.removeAttribute('data-expiry-original-had-title'); cell.removeAttribute('data-expiry-original-title'); diff --git a/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json b/src/extensions/expiryIndicatorCommandSet/ExpiryIndicatorCommandSet.manifest.json index 410849f..586d6c7 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": "1.0.7", + "version": "1.0.8", "manifestVersion": 2, "requiresCustomScript": false, "items": {