Merge pull request #1163 from TriliumNext/feat_erasure-timeout-ui

feat: friendly number handling for note erasure timeouts
This commit is contained in:
Elian Doran 2025-02-13 22:22:27 +02:00 committed by GitHub
commit 283482caa5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 108 additions and 17 deletions

View File

@ -11,26 +11,68 @@ const TPL = `
<p>${t("note_erasure_timeout.note_erasure_description")}</p>
<div class="form-group">
<label>${t("note_erasure_timeout.erase_notes_after_x_seconds")}</label>
<input class="erase-entities-after-time-in-seconds form-control options-number-input" type="number" min="0">
<label for="erase-entities-after-time">${t("note_erasure_timeout.erase_notes_after")}</label>
<div class="d-flex gap-2">
<input id="erase-entities-after-time" class="form-control options-number-input" type="number" min="0" steps="1" required>
<!-- TriliumNextTODO: i18n the strings when refactoring this to a standalone widget -->
<select id="erase-entities-after-time-scale" class="form-select duration-selector" required>
<option value="1">${t("duration.seconds")}</option>
<option value="60">${t("duration.minutes")}</option>
<option value="3600">${t("duration.hours")}</option>
<option value="86400">${t("duration.days")}</option>
</select>
</div>
</div>
<p>${t("note_erasure_timeout.manual_erasing_description")}</p>
<button class="erase-deleted-notes-now-button btn btn-secondary">${t("note_erasure_timeout.erase_deleted_notes_now")}</button>
<button id="erase-deleted-notes-now-button" class="btn btn-secondary">${t("note_erasure_timeout.erase_deleted_notes_now")}</button>
<style>
.duration-selector {
width: auto;
}
</style>
</div>`;
export default class NoteErasureTimeoutOptions extends OptionsWidget {
private $eraseEntitiesAfterTimeInSeconds!: JQuery<HTMLElement>;
private $eraseDeletedNotesButton!: JQuery<HTMLElement>;
private $eraseEntitiesAfterTime!: JQuery<HTMLInputElement>;
private $eraseEntitiesAfterTimeScale!: JQuery<HTMLSelectElement>;
private $eraseDeletedNotesButton!: JQuery<HTMLButtonElement>;
private eraseEntitiesAfterTimeInSeconds!: string | number;
doRender() {
this.$widget = $(TPL);
this.$eraseEntitiesAfterTimeInSeconds = this.$widget.find(".erase-entities-after-time-in-seconds");
this.$eraseEntitiesAfterTimeInSeconds.on("change", () => this.updateOption("eraseEntitiesAfterTimeInSeconds", this.$eraseEntitiesAfterTimeInSeconds.val()));
this.$eraseEntitiesAfterTime = this.$widget.find("#erase-entities-after-time");
this.$eraseEntitiesAfterTimeScale = this.$widget.find("#erase-entities-after-time-scale");
this.$eraseDeletedNotesButton = this.$widget.find(".erase-deleted-notes-now-button");
this.$eraseEntitiesAfterTime.on("change", () => {
const time = this.$eraseEntitiesAfterTime.val();
const timeScale = this.$eraseEntitiesAfterTimeScale.val();
if (!this.handleTimeValidation() || typeof timeScale !== "string" || !time) return;
this.eraseEntitiesAfterTimeInSeconds = this.convertTime(time, timeScale).toOption();
this.updateOption("eraseEntitiesAfterTimeInSeconds", this.eraseEntitiesAfterTimeInSeconds);
});
this.$eraseEntitiesAfterTimeScale.on("change", () => {
const timeScale = this.$eraseEntitiesAfterTimeScale.val();
if (!this.handleTimeValidation() || typeof timeScale !== "string") return;
//calculate the new displayed value
const displayedTime = this.convertTime(this.eraseEntitiesAfterTimeInSeconds, timeScale).toDisplay();
this.updateOption("eraseEntitiesAfterTimeScale", timeScale);
this.$eraseEntitiesAfterTime.val(displayedTime).trigger("change");
});
this.$eraseDeletedNotesButton = this.$widget.find("#erase-deleted-notes-now-button");
this.$eraseDeletedNotesButton.on("click", () => {
server.post("notes/erase-deleted-notes-now").then(() => {
toastService.showMessage(t("note_erasure_timeout.deleted_notes_erased"));
@ -39,6 +81,40 @@ export default class NoteErasureTimeoutOptions extends OptionsWidget {
}
async optionsLoaded(options: OptionMap) {
this.$eraseEntitiesAfterTimeInSeconds.val(options.eraseEntitiesAfterTimeInSeconds);
this.eraseEntitiesAfterTimeInSeconds = options.eraseEntitiesAfterTimeInSeconds;
const displayedTime = this.convertTime(options.eraseEntitiesAfterTimeInSeconds, options.eraseEntitiesAfterTimeScale).toDisplay();
this.$eraseEntitiesAfterTime.val(displayedTime);
this.$eraseEntitiesAfterTimeScale.val(options.eraseEntitiesAfterTimeScale);
}
convertTime(time: string | number, timeScale: string | number) {
const value = typeof time === "number" ? time : parseInt(time);
if (Number.isNaN(value)) {
throw new Error(`Time needs to be a valid integer, but received: ${time}`);
}
const operand = typeof timeScale === "number" ? timeScale : parseInt(timeScale);
if (Number.isNaN(operand) || operand < 1) {
throw new Error(`TimeScale needs to be a valid integer >= 1, but received: ${timeScale}`);
}
return {
toOption: () => Math.ceil(value * operand),
toDisplay: () => Math.ceil(value / operand),
}
}
handleTimeValidation() {
if (this.$eraseEntitiesAfterTime.is(":invalid")) {
// TriliumNextTODO: i18n
toastService.showMessage("The entered time value is not a valid number.");
return false
}
return true;
}
}

View File

@ -1643,4 +1643,4 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
background: var(--main-background-color);
box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--dropdown-shadow-opacity));
border-radius: 4px;
}
}

View File

@ -1134,7 +1134,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "笔记清理超时",
"note_erasure_description": "被删除的笔记(以及属性、历史版本等)最初仅被标记为“删除”,可以从“最近修改”对话框中恢复它们。经过一段时间后,已删除的笔记会被“清理”,这意味着它们的内容将无法恢复。此设置允许您配置从删除到清除笔记之间的时间长度。",
"erase_notes_after_x_seconds": "在笔记删除 X 秒后清理",
"erase_notes_after": "Erase notes after",
"manual_erasing_description": "您还可以手动触发清理(不考虑上述定义的超时):",
"erase_deleted_notes_now": "立即清理已删除的笔记",
"deleted_notes_erased": "已删除的笔记已被清理。"

View File

@ -1102,7 +1102,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "Beachte das Zeitlimit für die Löschung",
"note_erasure_description": "Deleted notes (and attributes, revisions...) are at first only marked as deleted and it is possible to recover them from Recent Notes dialog. After a period of time, deleted notes are \"erased\" which means their content is not recoverable anymore. This setting allows you to configure the length of the period between deleting and erasing the note.",
"erase_notes_after_x_seconds": "Notizen nach X Sekunden löschen",
"erase_notes_after": "Notizen löschen nach",
"manual_erasing_description": "Du kannst das Löschen auch manuell auslösen (ohne Berücksichtigung des oben definierten Timeouts):",
"erase_deleted_notes_now": "Jetzt gelöschte Notizen löschen",
"deleted_notes_erased": "Gelöschte Notizen wurden gelöscht."

View File

@ -1158,7 +1158,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "Note Erasure Timeout",
"note_erasure_description": "Deleted notes (and attributes, revisions...) are at first only marked as deleted and it is possible to recover them from Recent Notes dialog. After a period of time, deleted notes are \"erased\" which means their content is not recoverable anymore. This setting allows you to configure the length of the period between deleting and erasing the note.",
"erase_notes_after_x_seconds": "Erase notes after X seconds",
"erase_notes_after": "Erase notes after",
"manual_erasing_description": "You can also trigger erasing manually (without considering the timeout defined above):",
"erase_deleted_notes_now": "Erase deleted notes now",
"deleted_notes_erased": "Deleted notes have been erased."
@ -1648,5 +1648,11 @@
},
"help-button": {
"title": "Open the relevant help page"
},
"duration": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days"
}
}

View File

@ -1158,7 +1158,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "Tiempo de espera de borrado de notas",
"note_erasure_description": "Las notas eliminadas (y los atributos, las revisiones ...) en principio solo están marcadas como eliminadas y es posible recuperarlas del diálogo de Notas recientes. Después de un período de tiempo, las notas eliminadas son \" borradas\", lo que significa que su contenido ya no es recuperable. Esta configuración le permite configurar la longitud del período entre eliminar y borrar la nota.",
"erase_notes_after_x_seconds": "Borrar notas después de X segundos",
"erase_notes_after": "Borrar notas después de",
"manual_erasing_description": "También puede activar el borrado manualmente (sin considerar el tiempo de espera definido anteriormente):",
"erase_deleted_notes_now": "Borrar notas eliminadas ahora",
"deleted_notes_erased": "Las notas eliminadas han sido borradas."

View File

@ -1103,7 +1103,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "Délai d'effacement des notes",
"note_erasure_description": "Les notes supprimées (et les attributs, versions...) sont seulement marquées comme supprimées et il est possible de les récupérer à partir de la boîte de dialogue Notes récentes. Après un certain temps, les notes supprimées sont « effacées », ce qui signifie que leur contenu n'est plus récupérable. Ce paramètre vous permet de configurer la durée entre la suppression et l'effacement de la note.",
"erase_notes_after_x_seconds": "Effacer les notes après X secondes",
"erase_notes_after": "Effacer les notes après",
"manual_erasing_description": "Vous pouvez également déclencher l'effacement manuellement (sans tenir compte de la durée définie ci-dessus) :",
"erase_deleted_notes_now": "Effacer les notes supprimées maintenant",
"deleted_notes_erased": "Les notes supprimées ont été effacées."

View File

@ -834,7 +834,7 @@
"note_erasure_timeout": {
"deleted_notes_erased": "Notițele șterse au fost eliminate permanent.",
"erase_deleted_notes_now": "Elimină notițele șterse acum",
"erase_notes_after_x_seconds": "Elimină notițele șterse după X secunde",
"erase_notes_after": "Elimină notițele șterse după",
"manual_erasing_description": "Se poate rula o eliminare manuală (fără a lua în considerare timpul definit mai sus):",
"note_erasure_description": "Notițele șterse (precum și atributele, reviziile) sunt prima oară doar marcate drept șterse și este posibil să fie recuperate din ecranul Notițe recente. După o perioadă de timp, notițele șterse vor fi „eliminate”, caz în care conținutul lor nu se poate recupera. Această setare permite configurarea duratei de timp dintre ștergerea și eliminarea notițelor.",
"note_erasure_timeout_title": "Timpul de eliminare automată a notițelor șterse"
@ -1649,6 +1649,12 @@
"create-child-note-title": "Crează o notiță nouă și adaug-o pe hartă",
"unable-to-load-map": "Nu s-a putut încărca harta."
},
"duration": {
"days": "zile",
"hours": "ore",
"minutes": "minute",
"seconds": "secunde"
},
"help-button": {
"title": "Deschide ghidul relevant"
}

View File

@ -1112,7 +1112,7 @@
"note_erasure_timeout": {
"note_erasure_timeout_title": "筆記清理超時",
"note_erasure_description": "被刪除的筆記(以及屬性、歷史版本等)最初僅被標記為「刪除」,可以從「最近修改」對話框中恢復它們。經過一段時間後,已刪除的筆記會被「清理」,這意味著它們的內容將無法恢復。此設定允許您設定從刪除到清除筆記之間的時間長度。",
"erase_notes_after_x_seconds": "在筆記刪除 X 秒後清理",
"erase_notes_after": "Erase notes after",
"manual_erasing_description": "您還可以手動觸發清理(不考慮上述定義的超時):",
"erase_deleted_notes_now": "立即清理已刪除的筆記",
"deleted_notes_erased": "已刪除的筆記已被清理。"

View File

@ -12,6 +12,7 @@ import type { OptionNames } from "../../services/options_interface.js";
// options allowed to be updated directly in the Options dialog
const ALLOWED_OPTIONS = new Set([
"eraseEntitiesAfterTimeInSeconds",
"eraseEntitiesAfterTimeScale",
"protectedSessionTimeout",
"revisionSnapshotTimeInterval",
"revisionSnapshotNumberLimit",

View File

@ -105,6 +105,7 @@ const defaultOptions: DefaultOption[] = [
{ name: "rightPaneVisible", value: "true", isSynced: false },
{ name: "nativeTitleBarVisible", value: "false", isSynced: false },
{ name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days
{ name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day
{ name: "hideArchivedNotes_main", value: "false", isSynced: false },
{ name: "debugModeEnabled", value: "false", isSynced: false },
{ name: "headingStyle", value: "underline", isSynced: true },

View File

@ -61,6 +61,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
leftPaneWidth: number;
rightPaneWidth: number;
eraseEntitiesAfterTimeInSeconds: number;
eraseEntitiesAfterTimeScale: number;
autoReadonlySizeText: number;
autoReadonlySizeCode: number;
maxContentWidth: number;