cb15db2d27
rewrite get_all routes to use a pagination pattern to allow for better implementations of search, filter, and sorting on the frontend or by any client without fetching all the data. Additionally we added a CI check for running the Nuxt built to confirm that no TS errors were present. Finally, I had to remove the header support for the Shopping lists as the browser caching based off last_updated header was not allowing it to read recent updates due to how we're handling the updated_at property in the database with nested fields. This will have to be looked at in the future to reimplement. I'm unsure how many other routes have a similar issue. Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
110 lines
3 KiB
Vue
110 lines
3 KiB
Vue
<template>
|
|
<v-container v-if="shoppingLists" class="narrow-container">
|
|
<BaseDialog v-model="createDialog" :title="$tc('shopping-list.create-shopping-list')" @submit="createOne">
|
|
<v-card-text>
|
|
<v-text-field v-model="createName" autofocus :label="$t('shopping-list.new-list')"> </v-text-field>
|
|
</v-card-text>
|
|
</BaseDialog>
|
|
|
|
<BaseDialog v-model="deleteDialog" :title="$tc('general.confirm')" color="error" @confirm="deleteOne">
|
|
<v-card-text> Are you sure you want to delete this item?</v-card-text>
|
|
</BaseDialog>
|
|
<BasePageTitle divider>
|
|
<template #header>
|
|
<v-img max-height="100" max-width="100" :src="require('~/static/svgs/shopping-cart.svg')"></v-img>
|
|
</template>
|
|
<template #title> Shopping Lists </template>
|
|
</BasePageTitle>
|
|
<BaseButton create @click="createDialog = true" />
|
|
|
|
<section>
|
|
<v-card v-for="list in shoppingLists" :key="list.id" class="my-2 left-border" :to="`/shopping-lists/${list.id}`">
|
|
<v-card-title>
|
|
<v-icon left>
|
|
{{ $globals.icons.cartCheck }}
|
|
</v-icon>
|
|
{{ list.name }}
|
|
<v-btn class="ml-auto" icon @click.prevent="openDelete(list.id)">
|
|
<v-icon>
|
|
{{ $globals.icons.delete }}
|
|
</v-icon>
|
|
</v-btn>
|
|
</v-card-title>
|
|
</v-card>
|
|
</section>
|
|
<div class="d-flex justify-end mt-10">
|
|
<ButtonLink to="/group/data/labels" text="Manage Labels" :icon="$globals.icons.tags" />
|
|
</div>
|
|
</v-container>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, useAsync, reactive, toRefs } from "@nuxtjs/composition-api";
|
|
import { useUserApi } from "~/composables/api";
|
|
import { useAsyncKey } from "~/composables/use-utils";
|
|
|
|
export default defineComponent({
|
|
setup() {
|
|
const userApi = useUserApi();
|
|
|
|
const state = reactive({
|
|
createName: "",
|
|
createDialog: false,
|
|
deleteDialog: false,
|
|
deleteTarget: "",
|
|
});
|
|
|
|
const shoppingLists = useAsync(async () => {
|
|
return await fetchShoppingLists();
|
|
}, useAsyncKey());
|
|
|
|
async function fetchShoppingLists() {
|
|
const { data } = await userApi.shopping.lists.getAll();
|
|
|
|
if (!data) {
|
|
return [];
|
|
}
|
|
|
|
return data.items;
|
|
}
|
|
|
|
async function refresh() {
|
|
shoppingLists.value = await fetchShoppingLists();
|
|
}
|
|
|
|
async function createOne() {
|
|
const { data } = await userApi.shopping.lists.createOne({ name: state.createName });
|
|
|
|
if (data) {
|
|
refresh();
|
|
state.createName = "";
|
|
}
|
|
}
|
|
|
|
function openDelete(id: string) {
|
|
state.deleteDialog = true;
|
|
state.deleteTarget = id;
|
|
}
|
|
|
|
async function deleteOne() {
|
|
const { data } = await userApi.shopping.lists.deleteOne(state.deleteTarget);
|
|
if (data) {
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
return {
|
|
...toRefs(state),
|
|
shoppingLists,
|
|
createOne,
|
|
deleteOne,
|
|
openDelete,
|
|
};
|
|
},
|
|
head() {
|
|
return {
|
|
title: this.$t("shopping-list.shopping-list") as string,
|
|
};
|
|
},
|
|
});
|
|
</script>
|