preserve list filters when navigating back from detail pages
This commit is contained in:
parent
469cf66ad4
commit
3f2f6abefa
9 changed files with 62 additions and 30 deletions
|
|
@ -23,6 +23,7 @@
|
||||||
} from '$lib/utils/filterParams'
|
} from '$lib/utils/filterParams'
|
||||||
import Button from '$lib/components/ui/Button.svelte'
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
import Icon from '$lib/components/Icon.svelte'
|
import Icon from '$lib/components/Icon.svelte'
|
||||||
|
import { storeListUrl } from '$lib/utils/listNavigation'
|
||||||
|
|
||||||
import type { Snippet } from 'svelte'
|
import type { Snippet } from 'svelte'
|
||||||
|
|
||||||
|
|
@ -232,6 +233,8 @@
|
||||||
// Find the row data to get the granblueId
|
// Find the row data to get the granblueId
|
||||||
const rowData = data.find((item: any) => item.id === rowId)
|
const rowData = data.find((item: any) => item.id === rowId)
|
||||||
if (rowData && rowData.granblueId) {
|
if (rowData && rowData.granblueId) {
|
||||||
|
// Store current list URL before navigating so Back button can return here
|
||||||
|
storeListUrl($page.url.href, resource)
|
||||||
goto(`/database/${resource}/${rowData.granblueId}`)
|
goto(`/database/${resource}/${rowData.granblueId}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,16 @@
|
||||||
title: string
|
title: string
|
||||||
/** Custom right action content */
|
/** Custom right action content */
|
||||||
rightAction?: Snippet | undefined
|
rightAction?: Snippet | undefined
|
||||||
/** Click handler for back button - defaults to history.back() */
|
/** URL to navigate to when back is clicked */
|
||||||
onBack?: (() => void) | undefined
|
backHref: string
|
||||||
}
|
}
|
||||||
|
|
||||||
let { title, rightAction, onBack }: Props = $props()
|
let { title, rightAction, backHref }: Props = $props()
|
||||||
|
|
||||||
function handleBack() {
|
|
||||||
if (onBack) {
|
|
||||||
onBack()
|
|
||||||
} else {
|
|
||||||
history.back()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Button variant="ghost" size="small" leftIcon="chevron-left" onclick={handleBack}>
|
<Button variant="ghost" size="small" leftIcon="chevron-left" href={backHref}>
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
46
src/lib/utils/listNavigation.ts
Normal file
46
src/lib/utils/listNavigation.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* Utilities for preserving list navigation state
|
||||||
|
* Stores the list URL when navigating to a detail page so the Back button
|
||||||
|
* can return to the filtered list
|
||||||
|
*/
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'database_list_url'
|
||||||
|
|
||||||
|
interface StoredListUrl {
|
||||||
|
url: string
|
||||||
|
resource: 'characters' | 'weapons' | 'summons'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the current list URL before navigating to a detail page
|
||||||
|
*/
|
||||||
|
export function storeListUrl(url: string, resource: 'characters' | 'weapons' | 'summons'): void {
|
||||||
|
try {
|
||||||
|
const data: StoredListUrl = { url, resource }
|
||||||
|
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(data))
|
||||||
|
} catch {
|
||||||
|
// sessionStorage not available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stored list URL for a resource, or return the base path as fallback
|
||||||
|
*/
|
||||||
|
export function getListUrl(resource: 'characters' | 'weapons' | 'summons'): string {
|
||||||
|
const basePath = `/database/${resource}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stored = sessionStorage.getItem(STORAGE_KEY)
|
||||||
|
if (stored) {
|
||||||
|
const data: StoredListUrl = JSON.parse(stored)
|
||||||
|
// Only use stored URL if it matches the current resource
|
||||||
|
if (data.resource === resource) {
|
||||||
|
return data.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// sessionStorage not available or invalid data
|
||||||
|
}
|
||||||
|
|
||||||
|
return basePath
|
||||||
|
}
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
import Button from '$lib/components/ui/Button.svelte'
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
||||||
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
||||||
|
import { getListUrl } from '$lib/utils/listNavigation'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -193,7 +194,7 @@
|
||||||
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Character">
|
<DatabasePageHeader title="Character" backHref={getListUrl('characters')}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
{#if canEdit && editUrl}
|
{#if canEdit && editUrl}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
||||||
|
|
|
||||||
|
|
@ -276,10 +276,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
|
||||||
goto(`/database/characters/${character?.granblueId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for character grid image
|
// Helper function for character grid image
|
||||||
function getCharacterGridImage(character: any): string {
|
function getCharacterGridImage(character: any): string {
|
||||||
return getCharacterImage(character?.granblueId, 'grid', '01')
|
return getCharacterImage(character?.granblueId, 'grid', '01')
|
||||||
|
|
@ -292,7 +288,7 @@
|
||||||
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Edit Character" onBack={handleCancel}>
|
<DatabasePageHeader title="Edit Character" backHref={`/database/characters/${character?.granblueId}`}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
||||||
{isSaving ? 'Saving...' : 'Save'}
|
{isSaving ? 'Saving...' : 'Save'}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
} from '$lib/utils/external-links'
|
} from '$lib/utils/external-links'
|
||||||
import Button from '$lib/components/ui/Button.svelte'
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
||||||
|
import { getListUrl } from '$lib/utils/listNavigation'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -185,7 +186,7 @@
|
||||||
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Summon">
|
<DatabasePageHeader title="Summon" backHref={getListUrl('summons')}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
{#if canEdit && editUrl}
|
{#if canEdit && editUrl}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
||||||
|
|
|
||||||
|
|
@ -205,10 +205,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
|
||||||
goto(`/database/summons/${summon?.granblueId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for summon grid image
|
// Helper function for summon grid image
|
||||||
function getSummonGridImage(summon: any): string {
|
function getSummonGridImage(summon: any): string {
|
||||||
return getSummonImage(summon?.granblueId, 'grid')
|
return getSummonImage(summon?.granblueId, 'grid')
|
||||||
|
|
@ -216,7 +212,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Edit Summon" onBack={handleCancel}>
|
<DatabasePageHeader title="Edit Summon" backHref={`/database/summons/${summon?.granblueId}`}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
||||||
{isSaving ? 'Saving...' : 'Save'}
|
{isSaving ? 'Saving...' : 'Save'}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
} from '$lib/utils/external-links'
|
} from '$lib/utils/external-links'
|
||||||
import Button from '$lib/components/ui/Button.svelte'
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
import DatabasePageHeader from '$lib/components/database/DatabasePageHeader.svelte'
|
||||||
|
import { getListUrl } from '$lib/utils/listNavigation'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -187,7 +188,7 @@
|
||||||
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
<PageMeta title={pageTitle} description={m.page_desc_home()} />
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Weapon">
|
<DatabasePageHeader title="Weapon" backHref={getListUrl('weapons')}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
{#if canEdit && editUrl}
|
{#if canEdit && editUrl}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
<Button variant="element-ghost" element={elementName} size="small" href={editUrl}>Edit</Button>
|
||||||
|
|
|
||||||
|
|
@ -228,10 +228,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
|
||||||
goto(`/database/weapons/${weapon?.granblueId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for weapon grid image
|
// Helper function for weapon grid image
|
||||||
function getWeaponImage(weapon: any): string {
|
function getWeaponImage(weapon: any): string {
|
||||||
return getWeaponGridImage(weapon?.granblueId, weapon?.element, weapon?.instanceElement)
|
return getWeaponGridImage(weapon?.granblueId, weapon?.element, weapon?.instanceElement)
|
||||||
|
|
@ -239,7 +235,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<DatabasePageHeader title="Edit Weapon" onBack={handleCancel}>
|
<DatabasePageHeader title="Edit Weapon" backHref={`/database/weapons/${weapon?.granblueId}`}>
|
||||||
{#snippet rightAction()}
|
{#snippet rightAction()}
|
||||||
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
<Button variant="element-ghost" element={elementName} size="small" onclick={saveChanges} disabled={isSaving}>
|
||||||
{isSaving ? 'Saving...' : 'Save'}
|
{isSaving ? 'Saving...' : 'Save'}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue