diff --git a/frontend/app/router.options.ts b/frontend/app/router.options.ts new file mode 100644 index 0000000..e650b3f --- /dev/null +++ b/frontend/app/router.options.ts @@ -0,0 +1,14 @@ +import type { RouterConfig } from "@nuxt/schema"; + +export default { + scrollBehavior(to, from, savedPosition) { + console.log(to, from, savedPosition); + if (savedPosition) { + return savedPosition; + } else { + return { + top: 0, + }; + } + }, +}; diff --git a/frontend/components/Item/Card.vue b/frontend/components/Item/Card.vue index 5357c9e..96b3b04 100644 --- a/frontend/components/Item/Card.vue +++ b/frontend/components/Item/Card.vue @@ -29,9 +29,7 @@ -

- {{ item.description }} -

+
diff --git a/frontend/composables/use-formatters.ts b/frontend/composables/use-formatters.ts index 1583400..58ed22d 100644 --- a/frontend/composables/use-formatters.ts +++ b/frontend/composables/use-formatters.ts @@ -2,12 +2,12 @@ const cache = { currency: "", }; -export function ResetCurrency() { +export function resetCurrency() { cache.currency = ""; } export async function useFormatCurrency() { - if (!cache.currency) { + if (cache.currency === "") { const client = useUserApi(); const { data: group } = await client.group.get(); diff --git a/frontend/layouts/default.vue b/frontend/layouts/default.vue index ef1a8ca..1b6a88c 100644 --- a/frontend/layouts/default.vue +++ b/frontend/layouts/default.vue @@ -102,6 +102,9 @@ const username = computed(() => authStore.self?.name || "User"); + // Preload currency format + useFormatCurrency(); + const modals = reactive({ item: false, location: false, diff --git a/frontend/pages/items.vue b/frontend/pages/items.vue index 0c16cf4..4c570bc 100644 --- a/frontend/pages/items.vue +++ b/frontend/pages/items.vue @@ -21,32 +21,34 @@ const items = ref([]); const total = ref(0); - const page = useRouteQuery("page", 1); + const page1 = useRouteQuery("page", 1); + + const page = computed({ + get: () => page1.value, + set: value => { + page1.value = value; + }, + }); + const pageSize = useRouteQuery("pageSize", 21); const query = useRouteQuery("q", ""); const advanced = useRouteQuery("advanced", false); const includeArchived = useRouteQuery("archived", false); - const hasNext = computed(() => { - return page.value * pageSize.value < total.value; - }); + const totalPages = computed(() => Math.ceil(total.value / pageSize.value)); + const hasNext = computed(() => page.value * pageSize.value < total.value); + const hasPrev = computed(() => page.value > 1); - const totalPages = computed(() => { - return Math.ceil(total.value / pageSize.value); - }); - - function next() { - page.value = Math.min(Math.ceil(total.value / pageSize.value), page.value + 1); - } - - const hasPrev = computed(() => { - return page.value > 1; - }); + const itemsTitle = ref(); function prev() { page.value = Math.max(1, page.value - 1); } + function next() { + page.value = Math.min(Math.ceil(total.value / pageSize.value), page.value + 1); + } + async function resetPageSearch() { if (searchLocked.value) { return; @@ -67,17 +69,15 @@ loading.value = true; - const locations = selectedLocations.value.map(l => l.id); - const labels = selectedLabels.value.map(l => l.id); - const { data, error } = await api.items.getAll({ q: query.value || "", - locations, - labels, + locations: locIDs.value, + labels: labIDs.value, includeArchived: includeArchived.value, page: page.value, pageSize: pageSize.value, }); + if (error) { page.value = Math.max(1, page.value - 1); loading.value = false; @@ -130,6 +130,11 @@ } loading.value = false; + window.scroll({ + top: 0, + left: 0, + behavior: "smooth", + }); }); const locationsStore = useLocationStore(); @@ -141,16 +146,18 @@ const selectedLocations = ref([]); const selectedLabels = ref([]); + const locIDs = computed(() => selectedLocations.value.map(l => l.id)); + const labIDs = computed(() => selectedLabels.value.map(l => l.id)); + watchPostEffect(() => { if (!queryParamsInitialized.value) { return; } - const labelIds = selectedLabels.value.map(l => l.id); router.push({ query: { ...router.currentRoute.value.query, - lab: labelIds, + lab: labIDs.value, }, }); }); @@ -160,11 +167,10 @@ return; } - const locIds = selectedLocations.value.map(l => l.id); router.push({ query: { ...router.currentRoute.value.query, - loc: locIds, + loc: locIDs.value, }, }); }); @@ -176,8 +182,20 @@ } }); - watchDebounced([selectedLocations, selectedLabels, query], resetPageSearch, { debounce: 250, maxWait: 1000 }); - watch(includeArchived, resetPageSearch); + // resetPageHash computes a JSON string that is used to detect if the search + // parameters have changed. If they have changed, the page is reset to 1. + const resetPageHash = computed(() => { + const map = { + q: query.value, + includeArchived: includeArchived.value, + locations: locIDs.value, + labels: labIDs.value, + }; + + return JSON.stringify(map); + }); + + watchDebounced(resetPageHash, resetPageSearch, { debounce: 250, maxWait: 1000 }); watchDebounced([page, pageSize], search, { debounce: 250, maxWait: 1000 }); @@ -210,7 +228,7 @@
- Items + Items

{{ total }} Results Page {{ page }} of {{ totalPages }} @@ -221,7 +239,7 @@

-
+