Import/export
This commit is contained in:
parent
210c204f88
commit
9ad62d9d61
2 changed files with 153 additions and 1 deletions
|
|
@ -332,6 +332,33 @@
|
|||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Import/Export Section -->
|
||||
<details class="config-section">
|
||||
<summary class="config-summary">Import/Export Settings</summary>
|
||||
<div class="config-content space-y-4 pt-2">
|
||||
<div>
|
||||
<button onclick="exportSettings()" class="w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
|
||||
Export Current Settings
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<label for="settings-file-input" class="block text-sm font-medium text-gray-700">Or Load Settings from File:</label>
|
||||
<input type="file" id="settings-file-input" name="settings-file-input" accept=".json, .txt" class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-purple-50 file:text-purple-700 hover:file:bg-purple-100">
|
||||
<p class="mt-1 text-xs text-gray-500">Select a previously exported settings file (.json or .txt).</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="settings-json" class="block text-sm font-medium text-gray-700">Settings Data (JSON):</label>
|
||||
<textarea id="settings-json" rows="8" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500 sm:text-sm font-mono text-xs" placeholder="Click 'Export' to view settings here, or paste exported settings to import."></textarea>
|
||||
<p class="mt-1 text-xs text-gray-500">Copy this text to save your settings, or paste previously exported settings here and click 'Import'.</p>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="importSettings()" class="w-full bg-purple-500 hover:bg-purple-600 text-white font-bold py-2 px-4 rounded">
|
||||
Import Settings from Above
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Dangerous Reset All Button -->
|
||||
<div class="border-t border-red-300 pt-4 mt-6">
|
||||
<button onclick="resetAllSettings()" class="w-full bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
|
||||
|
|
@ -339,7 +366,7 @@
|
|||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.008v.008H12v-.008Z" />
|
||||
</svg>
|
||||
Reset ALL Settings to Defaults
|
||||
</button>
|
||||
</button>
|
||||
<p class="mt-2 text-xs text-red-600 text-center">Warning: This will clear all saved customizations and board content.</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1755,3 +1755,128 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
window.addEventListener('resize', equalizeCellSizes);
|
||||
equalizeCellSizes(); // Initial call after load
|
||||
});
|
||||
|
||||
// --- Settings Import/Export ---
|
||||
function exportSettings() {
|
||||
const settingsToExport = {};
|
||||
const prefix = 'beango_';
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key.startsWith(prefix)) {
|
||||
try {
|
||||
settingsToExport[key] = JSON.parse(localStorage.getItem(key));
|
||||
} catch (e) {
|
||||
settingsToExport[key] = localStorage.getItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(settingsToExport).length === 0) {
|
||||
showNotification('No settings found to export.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const settingsJson = JSON.stringify(settingsToExport, null, 2); // Pretty print JSON
|
||||
const blob = new Blob([settingsJson], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
|
||||
a.href = url;
|
||||
// Suggest a filename
|
||||
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-'); // YYYY-MM-DD-HH-MM-SS
|
||||
a.download = `beango-settings-${timestamp}.json`;
|
||||
|
||||
// Append the link to the body (required for Firefox), click it, and remove it
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
// Release the object URL
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
showNotification('Settings export download started.', 'success');
|
||||
|
||||
// Keep the textarea update as a visual confirmation/alternative
|
||||
const textarea = document.getElementById('settings-json');
|
||||
if (textarea) {
|
||||
textarea.value = settingsJson;
|
||||
}
|
||||
}
|
||||
|
||||
function importSettings() {
|
||||
const settingsJson = document.getElementById('settings-json');
|
||||
let parsedSettings;
|
||||
try {
|
||||
parsedSettings = JSON.parse(settingsJson.value);
|
||||
if (typeof parsedSettings !== 'object' || parsedSettings === null) {
|
||||
throw new Error('Imported data is not a valid JSON object.');
|
||||
}
|
||||
} catch (e) {
|
||||
showNotification(`Error parsing settings JSON: ${e.message}`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm('Importing these settings will OVERWRITE your current settings and reload the page. Are you sure you want to continue?')) {
|
||||
const prefix = 'beango_';
|
||||
const keysToRemove = [];
|
||||
|
||||
// 1. Clear existing beango settings first
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key.startsWith(prefix)) {
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
}
|
||||
keysToRemove.forEach(key => localStorage.removeItem(key));
|
||||
|
||||
// 2. Import new settings
|
||||
let importCount = 0;
|
||||
for (const key in parsedSettings) {
|
||||
// Basic validation: Ensure the key starts with the prefix and has a value
|
||||
if (key.startsWith(prefix) && parsedSettings.hasOwnProperty(key) && parsedSettings[key] !== undefined && parsedSettings[key] !== null) {
|
||||
const value = parsedSettings[key];
|
||||
// Store arrays/objects as JSON strings, others as plain strings
|
||||
const valueToStore = (typeof value === 'object') ? JSON.stringify(value) : String(value);
|
||||
localStorage.setItem(key, valueToStore);
|
||||
importCount++;
|
||||
} else {
|
||||
console.warn(`Skipping import for invalid key or value: ${key}`);
|
||||
}
|
||||
}
|
||||
|
||||
showNotification(`Successfully imported ${importCount} settings. Reloading...`, 'success', 1500);
|
||||
|
||||
// Use a short delay before reload
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1600);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Settings File Input Listener ---
|
||||
const settingsFileInput = document.getElementById('settings-file-input');
|
||||
if (settingsFileInput) {
|
||||
settingsFileInput.addEventListener('change', function(event) {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const settingsTextarea = document.getElementById('settings-json');
|
||||
if (settingsTextarea) {
|
||||
settingsTextarea.value = e.target.result;
|
||||
showNotification('Settings file loaded into textarea. Click Import to apply.', 'success');
|
||||
} else {
|
||||
showNotification('Error: Could not find settings textarea.', 'error');
|
||||
}
|
||||
// Clear the file input value so the same file can be selected again if needed
|
||||
event.target.value = null;
|
||||
};
|
||||
reader.onerror = function() {
|
||||
showNotification('Error reading settings file.', 'error');
|
||||
event.target.value = null; // Clear on error too
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue