// Auto-extracted from backup-page.js (verbatim) — augments BackupPage.prototype. Loaded after the base. Object.assign(BackupPage.prototype, { openLocationModal_unused(idx) { const loc = (this.locations?.locations || []).find(l => l.idx === idx); if (!loc) return; const modal = document.getElementById('backup-location-modal'); const body = document.getElementById('backup-location-modal-body'); const title = document.getElementById('backup-location-modal-title'); if (!modal || !body) return; modal.dataset.locIdx = idx; title.textContent = `Edit location: ${loc.name}`; body.innerHTML = `

Retention

When to delete old backups from this location.

`; this.refreshLocationModalTypeFields(loc.type, loc); this.refreshLocationModalRetention(loc.custom_retention); modal.classList.add('open'); }, refreshLocationModalTypeFields(type, locOverride) { const container = document.getElementById('backup-location-connection'); const modal = document.getElementById('backup-location-modal'); if (!container || !modal) return; const idx = parseInt(modal.dataset.locIdx, 10); const loc = locOverride || (this.locations?.locations || []).find(l => l.idx === idx) || {}; const suffixes = this.locFieldsForType(type); container.innerHTML = this.renderLocFields(idx, suffixes, loc); this.tagFieldsForSave(container); }, refreshLocationModalRetention(enabled) { const container = document.getElementById('backup-location-retention'); const modal = document.getElementById('backup-location-modal'); if (!container || !modal) return; const idx = parseInt(modal.dataset.locIdx, 10); const loc = (this.locations?.locations || []).find(l => l.idx === idx) || {}; // The "Use custom retention" toggle itself stays at the top regardless. const toggleField = this.renderLocFields(idx, ['CUSTOM_RETENTION'], loc); if (!enabled) { container.innerHTML = ` ${toggleField}
Inherits the global retention policy from the Configuration tab.
`; this.tagFieldsForSave(container); return; } const values = { last: loc.keep_last || '', daily: loc.keep_daily || '', weekly: loc.keep_weekly || '', monthly: loc.keep_monthly || '', yearly: loc.keep_yearly || '' }; container.innerHTML = ` ${toggleField} ${this.formRetention(`CFG_BACKUP_LOC_${idx}_`, values)} `; this.tagFieldsForSave(container); }, async saveLocationModal() { const modal = document.getElementById('backup-location-modal'); if (!modal) return; const idx = parseInt(modal.dataset.locIdx, 10); this.closeAllModals(); await this.saveSection(`location-${idx}`); }, async deleteLocationModal() { const modal = document.getElementById('backup-location-modal'); if (!modal) return; const idx = parseInt(modal.dataset.locIdx, 10); const loc = (this.locations?.locations || []).find(l => l.idx === idx); const name = loc?.name || `Location ${idx}`; if (!confirm(`Delete location "${name}"?\n\nBackup data already stored at this location is not deleted by this action — only LibrePortal's reference to it. The password file on disk also stays in place (rename it manually if you want to start fresh).`)) return; this.closeAllModals(); await this.runTask(`libreportal backup location remove ${idx}`, 'backup', null); setTimeout(() => this.reloadAfterSave(), 2000); }, openAddLocationModal() { const modal = document.getElementById('backup-add-location-modal'); const body = document.getElementById('backup-add-location-modal-body'); if (!modal || !body) return; body.innerHTML = `
${this.formSelect('__add_type', 'Type', 'local', [ ['local', 'Local / mounted path'], ['sftp', 'SFTP'], ['rest', 'REST server'], ['s3', 'S3'], ['b2', 'Backblaze B2'], ['gs', 'Google Cloud Storage'], ['azure', 'Azure'], ['rclone', 'rclone'] ])} ${this.formInput('__add_name', 'Friendly name', '', 'text', 'e.g. Office NAS')}

The location starts disabled — fill in its connection details on the next screen, then toggle Enabled.

`; modal.classList.add('open'); }, async confirmAddLocation() { const modal = document.getElementById('backup-add-location-modal'); if (!modal) return; const name = modal.querySelector('[name="__add_name"]')?.value?.trim(); const type = modal.querySelector('[name="__add_type"]')?.value || 'local'; if (!name) { this.notify('Name is required.', 'error'); return; } this.closeAllModals(); const safeName = name.replace(/'/g, "'\\''"); await this.runTask(`libreportal backup location add '${safeName}' ${type}`, 'backup', null); setTimeout(() => this.reloadAfterSave(), 2000); }, });