feat(ext/settings): retention section (trash + field history)

This commit is contained in:
adlee-was-taken
2026-05-03 21:18:22 -04:00
parent 4e9859d461
commit 6c8e702260

View File

@@ -1,5 +1,5 @@
import { sendMessage, escapeHtml } from '../../shared/state';
import type { VaultSettings, DeviceSettings } from '../../shared/types';
import type { VaultSettings, DeviceSettings, TrashRetention, HistoryRetention } from '../../shared/types';
import type { ColorScheme } from '../../shared/color-scheme';
import {
loadColorScheme, saveColorScheme, resetColorScheme,
@@ -285,7 +285,103 @@ async function renderGeneratorSection(content: HTMLElement): Promise<void> {
}
async function renderRetentionSection(content: HTMLElement): Promise<void> {
content.innerHTML = '<p class="muted" style="padding:20px;font-size:12px;">Retention — coming soon</p>';
content.innerHTML = '<p class="muted" style="padding:20px;font-size:12px;">Loading…</p>';
const resp = await sendMessage({ type: 'get_vault_settings' });
if (!resp.ok) {
content.innerHTML = `<p class="muted" style="padding:20px;">Failed to load: ${escapeHtml(resp.error ?? 'unknown')}</p>`;
return;
}
const settings = (resp.data as { settings: VaultSettings }).settings;
pendingVaultSettings = { ...settings };
content.innerHTML = `
<h3 class="settings-section-title">Trash retention</h3>
<div class="setting-row">
<div class="setting-row__info">
<div class="setting-row__title">Keep deleted items for</div>
<div class="setting-row__desc">Items in trash older than this are permanently deleted on the next sync.</div>
</div>
<div class="setting-row__control">
<select id="trash-retention" style="font-size:12px;">
<option value="days:7">7 days</option>
<option value="days:30">30 days</option>
<option value="days:90">90 days</option>
<option value="forever">Forever</option>
</select>
</div>
</div>
<h3 class="settings-section-title" style="margin-top:20px;">Field history retention</h3>
<div class="setting-row">
<div class="setting-row__info">
<div class="setting-row__title">Keep password history for</div>
<div class="setting-row__desc">History entries older than this are pruned on save.</div>
</div>
<div class="setting-row__control">
<select id="history-retention" style="font-size:12px;">
<option value="last_n:5">Last 5</option>
<option value="last_n:10">Last 10</option>
<option value="days:90">90 days</option>
<option value="days:365">1 year</option>
<option value="forever">Forever</option>
</select>
</div>
</div>
<div style="margin-top:12px;">
<button class="btn btn-primary" id="save-retention" style="font-size:11px;">Save retention settings</button>
</div>
`;
// Set current select values
(document.getElementById('trash-retention') as HTMLSelectElement).value =
trashRetentionToValue(settings.trash_retention);
(document.getElementById('history-retention') as HTMLSelectElement).value =
historyRetentionToValue(settings.field_history_retention);
document.getElementById('trash-retention')?.addEventListener('change', (e) => {
if (pendingVaultSettings) {
pendingVaultSettings.trash_retention = valueToTrashRetention((e.target as HTMLSelectElement).value);
}
});
document.getElementById('history-retention')?.addEventListener('change', (e) => {
if (pendingVaultSettings) {
pendingVaultSettings.field_history_retention = valueToHistoryRetention((e.target as HTMLSelectElement).value);
}
});
document.getElementById('save-retention')?.addEventListener('click', async () => {
if (!pendingVaultSettings) return;
const r = await sendMessage({ type: 'update_vault_settings', settings: pendingVaultSettings });
if (!r.ok) alert(`Save failed: ${r.error}`);
});
}
function trashRetentionToValue(r: TrashRetention): string {
if (r.kind === 'forever') return 'forever';
return `days:${r.value}`;
}
function valueToTrashRetention(v: string): TrashRetention {
if (v === 'forever') return { kind: 'forever' };
const m = /^days:(\d+)$/.exec(v);
if (m) return { kind: 'days', value: Number(m[1]) };
return { kind: 'forever' };
}
function historyRetentionToValue(r: HistoryRetention): string {
if (r.kind === 'forever') return 'forever';
if (r.kind === 'last_n') return `last_n:${r.value}`;
return `days:${r.value}`;
}
function valueToHistoryRetention(v: string): HistoryRetention {
if (v === 'forever') return { kind: 'forever' };
const mLast = /^last_n:(\d+)$/.exec(v);
if (mLast) return { kind: 'last_n', value: Number(mLast[1]) };
const mDays = /^days:(\d+)$/.exec(v);
if (mDays) return { kind: 'days', value: Number(mDays[1]) };
return { kind: 'forever' };
}
function renderBackupSection(content: HTMLElement): void {