feat(navigation) : preserve list state in URL and use browser history for back buttons

Add useUrlState composable to sync page, search, sort and filter state
with URL query params. Back/forward navigation now restores the exact
list position. Replace hardcoded NuxtLink back buttons with
router.back() across all create/edit pages. Fix documents attachment
filter that checked non-existent ID fields instead of relation objects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-02-11 16:48:40 +01:00
parent 185af65519
commit 480aaa24b2
18 changed files with 228 additions and 77 deletions

View File

@@ -92,11 +92,12 @@
</template>
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { computed, onBeforeUnmount, onMounted, ref, watch, type Ref } from "vue";
import { useHead, useRouter } from "#imports";
import ModelTypesToolbar from "~/components/model-types/Toolbar.vue";
import ModelTypesTable from "~/components/model-types/Table.vue";
import { useApi } from "~/composables/useApi";
import { useUrlState } from "~/composables/useUrlState";
import { extractCollection } from "~/shared/utils/apiHelpers";
import {
deleteModelType,
@@ -125,11 +126,28 @@ const props = withDefaults(
const selectedCategory = ref<ModelCategory>(props.category);
const searchInput = ref("");
const searchTerm = ref("");
const sort = ref<"name" | "createdAt">("name");
const dir = ref<"asc" | "desc">("asc");
const limit = ref(20);
const offset = ref(0);
// State synced with URL query params (preserved on back/forward navigation)
const urlState = useUrlState({
q: { default: '' },
sort: { default: 'name' },
dir: { default: 'asc' },
limit: { default: 20, type: 'number' },
offset: { default: 0, type: 'number' },
}, {
onRestore: () => {
searchInput.value = urlState.q.value;
refresh();
},
});
const searchTerm = urlState.q;
const sort = urlState.sort as Ref<'name' | 'createdAt'>;
const dir = urlState.dir as Ref<'asc' | 'desc'>;
const limit = urlState.limit;
const offset = urlState.offset;
// Initialize searchInput from URL (for direct navigation with ?q=...)
searchInput.value = searchTerm.value;
const items = ref<ModelType[]>([]);
const total = ref(0);