Aktualisiere Versionsnummern auf 1.0.8 in package.json, package-solution.json, ExpiryIndicatorFieldCustomizer.manifest.json und ExpiryIndicatorCommandSet.manifest.json; verbessere die Darstellung der Ablaufdatumsspalte in ExpiryIndicatorFieldCustomizer.ts und aktualisiere die ToDo.md mit neuen Informationen zur Zeilenfärbung.

This commit is contained in:
Torsten Brendgen
2026-07-17 21:32:39 +02:00
parent b585816faf
commit 76a0fcd898
7 changed files with 57 additions and 17 deletions

View File

@@ -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:

View File

@@ -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.

View File

@@ -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"

View File

@@ -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"

View File

@@ -4,7 +4,7 @@
"alias": "ExpiryIndicatorFieldCustomizer",
"componentType": "Extension",
"extensionType": "FieldCustomizer",
"version": "1.0.7",
"version": "1.0.8",
"manifestVersion": 2,
"requiresCustomScript": false
}

View File

@@ -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<Element> = row.querySelectorAll('[role="gridcell"]');
const targets: HTMLElement[] = [];
const cells: NodeListOf<Element> = 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');

View File

@@ -4,7 +4,7 @@
"alias": "ExpiryIndicatorCommandSet",
"componentType": "Extension",
"extensionType": "ListViewCommandSet",
"version": "1.0.7",
"version": "1.0.8",
"manifestVersion": 2,
"requiresCustomScript": false,
"items": {