feat: Implement recursive storage listing and directory browsing for backups, and add a migration option to fix cross-filters.

This commit is contained in:
2026-02-25 20:01:33 +03:00
parent 5d42a6b930
commit f9ac282596
12 changed files with 533 additions and 53 deletions

View File

@@ -65,7 +65,15 @@
};
function normalizeTab(value) {
return SETTINGS_TABS.includes(value) ? value : "environments";
const normalized = String(value || "").trim().toLowerCase();
const aliases = {
environment: "environments",
env: "environments",
"migration-sync": "migration",
storages: "storage",
};
const resolved = aliases[normalized] || normalized;
return SETTINGS_TABS.includes(resolved) ? resolved : "environments";
}
function readTabFromUrl() {
@@ -89,8 +97,17 @@
// Load settings on mount
onMount(async () => {
activeTab = readTabFromUrl();
const syncTabFromUrl = () => {
activeTab = readTabFromUrl();
};
window.addEventListener("popstate", syncTabFromUrl);
window.addEventListener("hashchange", syncTabFromUrl);
await loadSettings();
await loadMigrationSettings();
return () => {
window.removeEventListener("popstate", syncTabFromUrl);
window.removeEventListener("hashchange", syncTabFromUrl);
};
});
// Load consolidated settings from API
@@ -163,9 +180,10 @@
// Handle tab change
function handleTabChange(tab) {
activeTab = normalizeTab(tab);
const normalizedTab = normalizeTab(tab);
activeTab = normalizedTab;
writeTabToUrl(activeTab);
if (tab === "migration") {
if (normalizedTab === "migration") {
loadMigrationSettings();
}
}

View File

@@ -148,7 +148,10 @@
{#each currentPath.split('/').slice(1) as part, i}
<span class="mx-2">/</span>
<button
on:click={() => { currentPath = currentPath.split('/').slice(0, i + 1).join('/'); loadFiles(); }}
on:click={() => {
currentPath = currentPath.split('/').slice(0, i + 2).join('/');
loadFiles();
}}
class="hover:text-indigo-600 capitalize"
>
{part}
@@ -198,7 +201,7 @@
<svg class="h-4 w-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Back
{$t.common?.back}
</button>
{/if}
</div>
@@ -219,4 +222,4 @@
<!-- [/SECTION: TEMPLATE] -->
<!-- [/DEF:StoragePage:Component] -->
<!-- [/DEF:StoragePage:Component] -->