Files
ExpiryIndicator/src/extensions/expiryIndicatorCommandSet/ExpirySettingsDialog.ts
Torsten Brendgen c1f1d02d9c Add Expiry Indicator functionality with configuration and command set
- Implemented ExpiryItemService to manage expiry date logic for list items.
- Created ExpiryModels to define types and structures for expiry configurations and rules.
- Added RestError utility for handling API response errors.
- Developed ExpiryIndicatorFieldCustomizer to display expiry information in list views.
- Introduced ExpiryIndicatorCommandSet for extending expiry dates and managing settings.
- Added settings dialog for configuring expiry settings.
- Implemented localization support for English and German languages.
- Added TypeScript configuration files for project setup.
- Included TSLint configuration for code quality enforcement.
2026-07-16 21:55:30 +02:00

126 lines
5.7 KiB
TypeScript

import { BaseDialog, IDialogConfiguration } from '@microsoft/sp-dialog';
import {
IExpiryConfig,
IExpiryColumnRule,
IExpiryValueRule,
normalizeConfig
} from '../../common/ExpiryModels';
import * as strings from 'ExpiryIndicatorCommandSetStrings';
export class ExpirySettingsDialog extends BaseDialog {
private _config: IExpiryConfig;
private _save: (config: IExpiryConfig) => Promise<void>;
public constructor(config: IExpiryConfig, save: (config: IExpiryConfig) => Promise<void>) {
super();
this._config = config;
this._save = save;
}
public render(): void {
this.domElement.innerHTML =
'<div style="max-width:760px;padding:20px;font-family:Segoe UI,Arial,sans-serif">' +
'<h2 style="margin-top:0">' + strings.SettingsTitle + '</h2>' +
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">' +
this._input('baseField', strings.BaseField) +
this._input('expiryField', strings.ExpiryField) +
this._input('lifetimeValue', strings.DefaultLifetimeValue, 'number') +
'<label>' + strings.DefaultLifetimeUnit +
'<select data-field="lifetimeUnit" style="display:block;width:100%;padding:6px;margin-top:4px">' +
'<option value="days">days</option><option value="months">months</option><option value="years">years</option>' +
'</select>' +
'</label>' +
'</div>' +
'<label style="display:block;margin-top:12px">' + strings.DefaultColumnRulesJson +
'<textarea data-field="defaultColumnRule" rows="10" style="display:block;width:100%;box-sizing:border-box;font-family:Consolas,monospace;margin-top:4px"></textarea>' +
'</label>' +
'<label style="display:block;margin-top:12px">' + strings.RulesJson +
'<textarea data-field="rules" rows="12" style="display:block;width:100%;box-sizing:border-box;font-family:Consolas,monospace;margin-top:4px"></textarea>' +
'</label>' +
'<label style="display:block;margin-top:12px"><input data-field="confirmExtension" type="checkbox"> ' +
strings.ConfirmExtension + '</label>' +
'<label style="display:block;margin-top:12px">' + strings.NullText +
'<input data-field="nullText" type="text" style="display:block;width:100%;box-sizing:border-box;padding:6px;margin-top:4px">' +
'</label>' +
'<div data-field="error" style="color:#a4262c;min-height:20px;margin-top:10px"></div>' +
'<div style="text-align:right;margin-top:12px">' +
'<button data-action="cancel" type="button" style="padding:7px 18px;margin-right:8px">' + strings.Cancel + '</button>' +
'<button data-action="save" type="button" style="padding:7px 18px;background:#0078d4;color:#fff;border:0">' + strings.Save + '</button>' +
'</div>' +
'</div>';
this._setValue('baseField', this._config.baseField);
this._setValue('expiryField', this._config.expiryField);
this._setValue('lifetimeValue', String(this._config.default.lifeTime.value));
this._setValue('lifetimeUnit', this._config.default.lifeTime.unit);
this._setValue('defaultColumnRule', JSON.stringify(this._config.default.columnRule, undefined, 2));
this._setValue('rules', JSON.stringify(this._config.rules, undefined, 2));
this._setValue('nullText', this._config.nullText);
(this._field('confirmExtension') as HTMLInputElement).checked = this._config.confirmExtension;
(this.domElement.querySelector('[data-action="cancel"]') as HTMLButtonElement).onclick = (): void => {
this.close();
};
(this.domElement.querySelector('[data-action="save"]') as HTMLButtonElement).onclick = (): void => {
this._saveForm();
};
}
public getConfig(): IDialogConfiguration {
return { isBlocking: true };
}
private _saveForm(): void {
const saveButton: HTMLButtonElement = this.domElement.querySelector('[data-action="save"]') as HTMLButtonElement;
const errorElement: HTMLElement = this._field('error') as HTMLElement;
errorElement.textContent = '';
try {
const defaultColumnRule: IExpiryColumnRule[] = JSON.parse(this._value('defaultColumnRule'));
const rules: IExpiryValueRule[] = JSON.parse(this._value('rules'));
const config: IExpiryConfig = normalizeConfig({
baseField: this._value('baseField').trim(),
expiryField: this._value('expiryField').trim(),
default: {
lifeTime: {
value: Number(this._value('lifetimeValue')),
unit: this._value('lifetimeUnit')
},
columnRule: defaultColumnRule
},
rules: rules,
nullText: this._value('nullText'),
confirmExtension: (this._field('confirmExtension') as HTMLInputElement).checked
});
saveButton.disabled = true;
this._save(config).then((): void => {
this._config = config;
this.close();
}).catch((error: Error): void => {
saveButton.disabled = false;
errorElement.textContent = error && error.message ? error.message : String(error);
});
} catch (error) {
errorElement.textContent = strings.InvalidJson + ': ' + (error && error.message ? error.message : String(error));
}
}
private _input(field: string, label: string, type?: string): string {
return '<label>' + label + '<input data-field="' + field + '" type="' + (type || 'text') +
'" style="display:block;width:100%;box-sizing:border-box;padding:6px;margin-top:4px"></label>';
}
private _field(name: string): Element {
return this.domElement.querySelector('[data-field="' + name + '"]') as Element;
}
private _value(name: string): string {
return (this._field(name) as HTMLInputElement).value;
}
private _setValue(name: string, value: string): void {
(this._field(name) as HTMLInputElement).value = value;
}
}