From ad060f206cceb9fe0453eab2cc0bb7f55b0949cb Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 10:59:16 +0200 Subject: [PATCH 1/7] refac: component-ize creating household --- src/components/CreateHouseholdComponent.vue | 51 ++++++++++++++ src/components/RegisterComponent.vue | 73 +++++++++------------ src/components/SideNavBar.vue | 6 ++ src/router/index.ts | 2 +- src/views/RegisterView.vue | 49 +++++++------- 5 files changed, 115 insertions(+), 66 deletions(-) create mode 100644 src/components/CreateHouseholdComponent.vue diff --git a/src/components/CreateHouseholdComponent.vue b/src/components/CreateHouseholdComponent.vue new file mode 100644 index 0000000..cb1a61c --- /dev/null +++ b/src/components/CreateHouseholdComponent.vue @@ -0,0 +1,51 @@ +<template> + <h2>Lag husholdning</h2> + <el-form :model="householdName" ref="ruleFormRef" label-position="top" status-icon> + <el-form-item label="Navn på husholdning" prop="houseHoldName"> + <el-input v-model="householdName" placeholder="husholdning"></el-input> + </el-form-item> + <el-row> + <div class="spacer"></div> + <el-link @click="skipCreateHousehold">Jeg ønsker ikke å lage husholdning</el-link> + </el-row> + <el-form-item> + <el-button @click="createHousehold" type="primary">Lag husholdning</el-button> + </el-form-item> + </el-form> +</template> +<script setup lang="ts"> +import { computed, ref } from "vue"; +import type { FormInstance } from "element-plus"; + +const props = defineProps<{ + householdName: string; +}>(); +const ruleFormRef = ref<FormInstance>(); + +const emit = defineEmits<{ + "update:householdName": (householdName: string) => void; + skip: () => void; + submit: () => void; +}>(); + +const householdName = computed({ + get: () => props.householdName, + set: (value) => emit("update:householdName", value), +}); + +const validationRules = ref({ + householdName: [{ required: true, message: "Husholdningens navn er påkrevd", trigger: "blur" }], +}); + +function skipCreateHousehold() { + emit("skip"); +} + +function createHousehold() { + ruleFormRef.value.validate((valid) => { + if (valid) { + emit("submit"); + } + }); +} +</script> diff --git a/src/components/RegisterComponent.vue b/src/components/RegisterComponent.vue index fa65ee8..90ddfb8 100644 --- a/src/components/RegisterComponent.vue +++ b/src/components/RegisterComponent.vue @@ -1,42 +1,39 @@ <template> - <el-card class="container"> - <h2 class="my-3">Registrer deg</h2> + <h2 class="my-3">Registrer deg</h2> + <el-form + ref="ruleFormRef" + label-position="top" + :model="newUser" + :rules="validationRules" + status-icon + > + <el-form-item label="Email" prop="email"> + <el-input placeholder="Email" type="text" v-model="email" size="large" /> + </el-form-item> - <el-form - ref="ruleFormRef" - label-position="top" - :model="newUser" - :rules="validationRules" - status-icon - > - <el-form-item label="Email" prop="email"> - <el-input placeholder="Email" type="text" v-model="email" size="large" /> - </el-form-item> + <el-form-item label="Fornavn" prop="firstName"> + <el-input placeholder="fornavn" type="text" v-model="firstName" size="large" /> + </el-form-item> - <el-form-item label="Fornavn" prop="firstName"> - <el-input placeholder="fornavn" type="text" v-model="firstName" size="large" /> - </el-form-item> + <el-form-item label="Passord" prop="password"> + <el-input type="password" v-model="password" placeholder="Password" size="large" /> + </el-form-item> - <el-form-item label="Passord" prop="password"> - <el-input type="password" v-model="password" placeholder="Password" size="large" /> - </el-form-item> + <el-form-item label="Gjenta passord" prop="passwordConfirm"> + <el-input type="password" v-model="passwordConfirm" placeholder="Password" size="large" /> + </el-form-item> - <el-form-item label="Gjenta passord" prop="passwordConfirm"> - <el-input type="password" v-model="passwordConfirm" placeholder="Password" size="large" /> - </el-form-item> - - <el-button ref="submitButton" type="primary" size="large" @click="submit" - >Registrer deg - </el-button> - </el-form> - <el-alert - type="error" - show-icon - :title="errorMessage" - v-if="errorMessage" - style="margin-top: 1rem" - /> - </el-card> + <el-button ref="submitButton" type="primary" size="large" @click="submit" + >Registrer deg + </el-button> + </el-form> + <el-alert + type="error" + show-icon + :title="errorMessage" + v-if="errorMessage" + style="margin-top: 1rem" + /> </template> <script setup lang="ts"> import type { CreateUser } from "@/services"; @@ -122,10 +119,4 @@ function submit() { }); } </script> -<style scoped> -.container { - width: 90%; - margin: 10vh auto; - max-width: 500px; -} -</style> +<style scoped></style> diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index afbc667..b0f6ae8 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -19,6 +19,12 @@ :label="item.name" :value="item.id" ></el-option> + <el-button style="width: 100%" type="primary"> + <el-icon> + <HomeFilled /> + </el-icon> + <span>Legg til husholdning</span> + </el-button> </el-select> <el-menu-item index="/shopping-list"> <el-icon> diff --git a/src/router/index.ts b/src/router/index.ts index d28271c..1876a8c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -4,7 +4,7 @@ import NotFoundView from "../views/NotFoundView.vue"; import { useSessionStore } from "@/stores/session"; import { AccountApi } from "@/services/index"; -let startup = true; +const startup = true; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue index 03e3bf6..7e8c65f 100644 --- a/src/views/RegisterView.vue +++ b/src/views/RegisterView.vue @@ -8,30 +8,23 @@ <el-step title="Lag bruker"></el-step> <el-step title="Lag husholdning"></el-step> </el-steps> - <RegisterComponent - v-model:email="user.email" - v-model:first-name="user.firstName" - v-model:password="user.password" - @submit="submit" - :error-message="errorMessage" - v-if="active == 0" - > - </RegisterComponent> - <el-form v-if="active == 1" label-position="top"> - <el-card style="max-width: 500px; width: 100%; margin: auto 10rem"> - <h2>Lag husholdning</h2> - <el-form-item label="Navn på husholdning"> - <el-input v-model="household.name" placeholder="husholdning"></el-input> - </el-form-item> - <el-row> - <div class="spacer"></div> - <el-link @click="skipCreateHousehold">Jeg ønsker ikke å lage husholdning</el-link> - </el-row> - <el-form-item> - <el-button @click="createHousehold" type="primary">Lag husholdning</el-button> - </el-form-item> - </el-card> - </el-form> + <el-card class="container"> + <RegisterComponent + v-model:email="user.email" + v-model:first-name="user.firstName" + v-model:password="user.password" + @submit="submit" + :error-message="errorMessage" + v-if="active == 0" + > + </RegisterComponent> + <CreateHouseholdComponent + v-model:household-name="household.name" + @submit="createHousehold" + @skip="skipCreateHousehold" + v-if="active == 1" + ></CreateHouseholdComponent> + </el-card> </template> <script setup lang="ts"> import { reactive, ref } from "vue"; @@ -42,6 +35,7 @@ import { useSessionStore } from "@/stores/session"; import router from "@/router"; import { showError } from "@/utils/error-utils"; import { useHouseholdStore } from "@/stores/household"; +import CreateHouseholdComponent from "@/components/CreateHouseholdComponent.vue"; const user = reactive({ email: "", @@ -109,3 +103,10 @@ function createHousehold() { }); } </script> +<style> +.container { + width: 90%; + margin: 10vh auto; + max-width: 500px; +} +</style> -- GitLab From e8dc7e5e8a5d71e81e2e588785e4c8f1c7a02224 Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 11:17:18 +0200 Subject: [PATCH 2/7] chore: run formatter --- src/components/SideNavBar.vue | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index b0f6ae8..5632ff7 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -19,7 +19,7 @@ :label="item.name" :value="item.id" ></el-option> - <el-button style="width: 100%" type="primary"> + <el-button style="width: 100%" type="primary" @click="isCreateHousehold = true"> <el-icon> <HomeFilled /> </el-icon> @@ -57,6 +57,13 @@ <span>Rediger husholdning</span> </el-menu-item> </el-menu> + <el-dialog v-model="isCreateHousehold" show-close> + <CreateHouseholdComponent + v-model:household-name="newHousehold.name" + @submit="createHousehold" + @skip="skipCreateHousehold" + ></CreateHouseholdComponent> + </el-dialog> </template> <script lang="ts" setup> @@ -64,8 +71,10 @@ import router from "@/router"; import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue"; import { getCurrentInstance, onMounted, ref } from "vue"; import { useHouseholdStore } from "@/stores/household"; -import { Household, HouseholdApi } from "@/services/index"; +import { CreateHousehold, Household, HouseholdApi } from "@/services/index"; import { useSessionStore } from "@/stores/session"; +import CreateHouseholdComponent from "@/components/CreateHouseholdComponent.vue"; +import { showError } from "@/utils/error-utils"; const defaultActive = ref("/"); onMounted(async () => { @@ -84,9 +93,13 @@ const handleClose = (key: string, keyPath: string[]) => { const houseHoldStore = useHouseholdStore(); const houseHoldApi = new HouseholdApi(); const sessionStore = useSessionStore(); +const isCreateHousehold = ref(false); const households = ref([]); const household = ref(houseHoldStore.getHousehold()); +const newHousehold = ref({ + name: "", +} as CreateHousehold); const emit = defineEmits<{ (event: "select", ...args: any[]): void; }>(); @@ -105,4 +118,21 @@ function setHouseHold(val: Household) { const root = getCurrentInstance(); root?.emit("household-changed", val); } + +function createHousehold() { + houseHoldApi + .createHousehold(newHousehold.value) + .then((res) => { + households.value.push(res.data); + setHouseHold(res.data); + isCreateHousehold.value = false; + }) + .catch(() => { + showError("En uventet feil oppstod", "vennligst prøv igjen senere", 0); + }); +} + +function skipCreateHousehold() { + isCreateHousehold.value = false; +} </script> -- GitLab From a6d2d47a8b1e8a1186a6acbc63903c8676ee0e3b Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 12:32:16 +0200 Subject: [PATCH 3/7] refac: use computed on household instead of getters and setters --- src/components/SideNavBar.vue | 11 +++++------ src/stores/household.ts | 25 +++++++++++++++---------- src/views/InventoryView.vue | 5 ++--- src/views/LoginView.vue | 2 +- src/views/ShoppingListView.vue | 2 +- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index 5632ff7..c21462c 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -96,7 +96,7 @@ const sessionStore = useSessionStore(); const isCreateHousehold = ref(false); const households = ref([]); -const household = ref(houseHoldStore.getHousehold()); +const household = houseHoldStore.household; const newHousehold = ref({ name: "", } as CreateHousehold); @@ -107,16 +107,15 @@ const emit = defineEmits<{ houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { households.value = res.data; console.log(res.data); - if (household.value == null) { - houseHoldStore.setHousehold(res.data[0]); + if (household == null) { household.value = res.data[0]; } }); function setHouseHold(val: Household) { - houseHoldStore.setHousehold(val); - const root = getCurrentInstance(); - root?.emit("household-changed", val); + console.log("setting household" + val); + household.value = val; + console.log(houseHoldStore.household); } function createHousehold() { diff --git a/src/stores/household.ts b/src/stores/household.ts index 830472b..5dabce6 100644 --- a/src/stores/household.ts +++ b/src/stores/household.ts @@ -1,18 +1,23 @@ -import { ref } from "vue"; +import { computed, ref } from "vue"; import { defineStore } from "pinia"; import type { Household } from "@/services/index"; export const useHouseholdStore = defineStore("household", () => { - const household = ref<Household | null>(null); + const householdValue = ref({} as Household); - function getHousehold() { - return household.value; - } + const household = computed({ + get: () => { + if (!householdValue.value?.id) { + householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}"); + } + return householdValue.value; + }, + set: (val) => { + householdValue.value = val; + sessionStorage.setItem("household", JSON.stringify(val)); + }, + }); - function setHousehold(newHousehold: Household) { - household.value = newHousehold; - } - - return { getHousehold, setHousehold }; + return { household }; }); diff --git a/src/views/InventoryView.vue b/src/views/InventoryView.vue index 7a0b31b..7dc64c6 100644 --- a/src/views/InventoryView.vue +++ b/src/views/InventoryView.vue @@ -85,7 +85,7 @@ const isLoading = computed(() => items.value === null && error.value === null); // Define callbacks function deleteItem(item: Item) { - let householdId = householdStore.getHousehold()?.id; + let householdId = householdStore.household.id; if (!householdId) { console.error(`Could not delete item ${item.type?.name}. No household id was selected.`); showError("Ingen hjem valgt.", "Velg et hjem for å slette et element.", 15000); @@ -160,10 +160,9 @@ function removeItemClientSide(item: Item) { } function getHouseholdId(): number | null { - let householdId = householdStore.getHousehold()?.id; + let householdId = householdStore.household?.id; if (!householdId) { - console.error("No household id was selected. Can not fetch inventory items."); error.value = new Error("No household id was selected. Can not fetch inventory items."); showError("Ingen hjem valgt.", "Velg et hjem for å se inventaret til hjemmet.", 15000); return null; diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue index 5fcd9fc..aa95038 100644 --- a/src/views/LoginView.vue +++ b/src/views/LoginView.vue @@ -85,7 +85,7 @@ function signIn() { .getHouseholds(data.id!) .then((response) => response.data) .then((households) => { - householdStore.setHousehold(households[0]); + householdStore.household = households[0]; router.push({ name: "inventory" }); }); }) diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue index be5890f..9da0628 100644 --- a/src/views/ShoppingListView.vue +++ b/src/views/ShoppingListView.vue @@ -191,7 +191,7 @@ const itemTypesApi = new ItemTypeApi(); const houseHoldStore = useHouseholdStore(); -const householdId = houseHoldStore.getHousehold().id; +const householdId = houseHoldStore.household.id; const itemTypeAutocomplete = ref(null as any); const loading = ref(undefined) as Ref<undefined | boolean>; const loadingSubmit = ref(false); -- GitLab From 8979c453244a4e97a96040a442163ce2e762b508 Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 13:08:29 +0200 Subject: [PATCH 4/7] fix: side nav picker not working --- src/components/SideNavBar.vue | 25 ++++--------------------- src/views/HouseholdView.vue | 2 +- src/views/ShoppingListView.vue | 4 +--- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index c21462c..12aea0d 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -1,23 +1,16 @@ <template> - <el-menu - :default-active="defaultActive" - @open="handleOpen" - @close="handleClose" - router - @select="$emit('select')" - > + <el-menu :default-active="defaultActive" @open="handleOpen" @close="handleClose" router> <el-select style="width: calc(100% - 2rem); margin: 1rem" - :placeholder="household.name" - @change="setHouseHold(household)" - v-model="household" + :model-value="houseHoldStore.household.name" v-if="household" > <el-option v-for="item in households" :key="item.id" :label="item.name" - :value="item.id" + @click="houseHoldStore.household = item" + :value="item" ></el-option> <el-button style="width: 100%" type="primary" @click="isCreateHousehold = true"> <el-icon> @@ -100,9 +93,6 @@ const household = houseHoldStore.household; const newHousehold = ref({ name: "", } as CreateHousehold); -const emit = defineEmits<{ - (event: "select", ...args: any[]): void; -}>(); houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { households.value = res.data; @@ -112,18 +102,11 @@ houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { } }); -function setHouseHold(val: Household) { - console.log("setting household" + val); - household.value = val; - console.log(houseHoldStore.household); -} - function createHousehold() { houseHoldApi .createHousehold(newHousehold.value) .then((res) => { households.value.push(res.data); - setHouseHold(res.data); isCreateHousehold.value = false; }) .catch(() => { diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue index f980615..b94f211 100644 --- a/src/views/HouseholdView.vue +++ b/src/views/HouseholdView.vue @@ -45,7 +45,7 @@ const householdApi = new HouseholdApi(); const accountApi = new AccountApi(); let users = ref([]); -const currentHousehold = householdStore.getHousehold(); +const currentHousehold = householdStore.household; householdApi.getUsers(currentHousehold?.id!).then((data) => { users.value = data.data; diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue index 9da0628..c6276a8 100644 --- a/src/views/ShoppingListView.vue +++ b/src/views/ShoppingListView.vue @@ -314,9 +314,7 @@ async function declineAllSuggestions() { function completeShopping() { shoppingListApi - .markItemsAsBought(householdId, { - listEntryIds: Array.from(boughtItems.value.values()).map((item) => item.id), - } as ShoppinglistBuyBody) + .markItemsAsBought() .then(() => { ElNotification({ message: "Handleturen er avsluttet. Du finner de kjøpte varene i vareoversikten!", -- GitLab From 81a5a81f034f9bab7a5ed7626d16275da2f1d63a Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 14:08:59 +0200 Subject: [PATCH 5/7] fix: bug on navbar, and show create household button when no households --- src/components/SideNavBar.vue | 28 ++++++++++++++++++++-------- src/stores/household.ts | 11 +++++++++-- src/views/LoginView.vue | 5 ++++- src/views/RegisterView.vue | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index 12aea0d..3f267a4 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -3,7 +3,7 @@ <el-select style="width: calc(100% - 2rem); margin: 1rem" :model-value="houseHoldStore.household.name" - v-if="household" + v-if="households?.length > 0" > <el-option v-for="item in households" @@ -19,6 +19,18 @@ <span>Legg til husholdning</span> </el-button> </el-select> + <el-button + style="width: calc(100% - 2rem); margin: 1rem" + type="primary" + @click="isCreateHousehold = true" + v-else-if="households?.length === 0" + > + <el-icon> + <HomeFilled /> + </el-icon> + <span>Legg til husholdning</span> + </el-button> + <el-menu-item index="/shopping-list"> <el-icon> <List /> @@ -62,7 +74,7 @@ <script lang="ts" setup> import router from "@/router"; import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue"; -import { getCurrentInstance, onMounted, ref } from "vue"; +import { onMounted, ref } from "vue"; import { useHouseholdStore } from "@/stores/household"; import { CreateHousehold, Household, HouseholdApi } from "@/services/index"; import { useSessionStore } from "@/stores/session"; @@ -88,26 +100,26 @@ const houseHoldApi = new HouseholdApi(); const sessionStore = useSessionStore(); const isCreateHousehold = ref(false); -const households = ref([]); -const household = houseHoldStore.household; +const households = ref(null as Household[] | null); const newHousehold = ref({ name: "", } as CreateHousehold); houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { - households.value = res.data; console.log(res.data); - if (household == null) { - household.value = res.data[0]; - } + households.value = res.data; }); function createHousehold() { houseHoldApi .createHousehold(newHousehold.value) .then((res) => { + if (households.value === null) { + households.value = []; + } households.value.push(res.data); isCreateHousehold.value = false; + houseHoldStore.household = res.data; }) .catch(() => { showError("En uventet feil oppstod", "vennligst prøv igjen senere", 0); diff --git a/src/stores/household.ts b/src/stores/household.ts index 5dabce6..59289d3 100644 --- a/src/stores/household.ts +++ b/src/stores/household.ts @@ -9,7 +9,9 @@ export const useHouseholdStore = defineStore("household", () => { const household = computed({ get: () => { if (!householdValue.value?.id) { - householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}"); + if (sessionStorage.getItem("household")) { + householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}"); + } } return householdValue.value; }, @@ -19,5 +21,10 @@ export const useHouseholdStore = defineStore("household", () => { }, }); - return { household }; + function removeHousehold() { + household.value = {} as Household; + sessionStorage.removeItem("household"); + } + + return { household, removeHousehold }; }); diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue index aa95038..3c67ce2 100644 --- a/src/views/LoginView.vue +++ b/src/views/LoginView.vue @@ -85,7 +85,10 @@ function signIn() { .getHouseholds(data.id!) .then((response) => response.data) .then((households) => { - householdStore.household = households[0]; + console.log(households); + if (households?.length > 0) { + householdStore.household = households[0]; + } router.push({ name: "inventory" }); }); }) diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue index 7e8c65f..fa0380f 100644 --- a/src/views/RegisterView.vue +++ b/src/views/RegisterView.vue @@ -87,7 +87,7 @@ function createHousehold() { householdApi .createHousehold(household) .then((data) => { - useHouseholdStore().setHousehold(data.data); + useHouseholdStore().household = data.data; next(); router.push({ name: "inventory" }); }) -- GitLab From cd6eba61a5d49bc980e889f1bd4ad04867a59779 Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 14:23:09 +0200 Subject: [PATCH 6/7] fix: show create household button when there are no households --- src/components/SideNavBar.vue | 4 ++-- src/views/HouseholdView.vue | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index 3f267a4..c9bfa2f 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -3,7 +3,7 @@ <el-select style="width: calc(100% - 2rem); margin: 1rem" :model-value="houseHoldStore.household.name" - v-if="households?.length > 0" + v-if="households?.length > 0 && houseHoldStore.household?.id" > <el-option v-for="item in households" @@ -23,7 +23,7 @@ style="width: calc(100% - 2rem); margin: 1rem" type="primary" @click="isCreateHousehold = true" - v-else-if="households?.length === 0" + v-else-if="households?.length === 0 || !houseHoldStore.household?.id" > <el-icon> <HomeFilled /> diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue index b94f211..413c2dc 100644 --- a/src/views/HouseholdView.vue +++ b/src/views/HouseholdView.vue @@ -146,6 +146,7 @@ function deleteHousehold() { .then(() => { ElMessage.success("Slettet husholdning"); console.log("deleted household: " + currentHousehold?.name); + householdStore.removeHousehold(); }) .catch((error) => { ElMessage.error("Kunne ikke slette husholdning" + error); -- GitLab From 6a65ec255f8a746dde7b4cd879f1f514d4ada04b Mon Sep 17 00:00:00 2001 From: Arunan Gnanasekaran <arunan2212@gmail.com> Date: Wed, 26 Apr 2023 15:06:36 +0200 Subject: [PATCH 7/7] fix: global events when updating household --- package-lock.json | 6 ++++ package.json | 1 + src/components/SideNavBar.vue | 53 ++++++++++++++++++---------------- src/main.ts | 3 ++ src/stores/household.ts | 6 +++- src/views/HouseholdView.vue | 26 +++++++++++------ src/views/InventoryView.vue | 7 ++++- src/views/ShoppingListView.vue | 49 ++++++++++++++++++------------- 8 files changed, 95 insertions(+), 56 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc152e8..1f70eae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@vuelidate/core": "^2.0.2", "@vuelidate/validators": "^2.0.2", "element-plus": "^2.3.3", + "mitt": "^3.0.0", "pinia": "^2.0.32", "vue": "^3.2.47", "vue-router": "^4.1.6" @@ -4950,6 +4951,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" + }, "node_modules/mlly": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz", diff --git a/package.json b/package.json index 789b6e6..68acbf6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@vuelidate/core": "^2.0.2", "@vuelidate/validators": "^2.0.2", "element-plus": "^2.3.3", + "mitt": "^3.0.0", "pinia": "^2.0.32", "vue": "^3.2.47", "vue-router": "^4.1.6" diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue index c9bfa2f..66ea298 100644 --- a/src/components/SideNavBar.vue +++ b/src/components/SideNavBar.vue @@ -1,9 +1,20 @@ <template> - <el-menu :default-active="defaultActive" @open="handleOpen" @close="handleClose" router> + <el-menu :default-active="defaultActive" router> + <el-button + style="width: calc(100% - 2rem); margin: 1rem" + type="primary" + @click="isCreateHousehold = true" + v-if="households?.length == 0" + > + <el-icon> + <HomeFilled /> + </el-icon> + <span>Legg til husholdning</span> + </el-button> <el-select style="width: calc(100% - 2rem); margin: 1rem" :model-value="houseHoldStore.household.name" - v-if="households?.length > 0 && houseHoldStore.household?.id" + v-else-if="households?.length > 0" > <el-option v-for="item in households" @@ -19,17 +30,6 @@ <span>Legg til husholdning</span> </el-button> </el-select> - <el-button - style="width: calc(100% - 2rem); margin: 1rem" - type="primary" - @click="isCreateHousehold = true" - v-else-if="households?.length === 0 || !houseHoldStore.household?.id" - > - <el-icon> - <HomeFilled /> - </el-icon> - <span>Legg til husholdning</span> - </el-button> <el-menu-item index="/shopping-list"> <el-icon> @@ -74,7 +74,7 @@ <script lang="ts" setup> import router from "@/router"; import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue"; -import { onMounted, ref } from "vue"; +import { inject, onMounted, ref } from "vue"; import { useHouseholdStore } from "@/stores/household"; import { CreateHousehold, Household, HouseholdApi } from "@/services/index"; import { useSessionStore } from "@/stores/session"; @@ -85,31 +85,34 @@ const defaultActive = ref("/"); onMounted(async () => { await router.isReady(); defaultActive.value = router.currentRoute.value.path; - console.log(defaultActive.value); }); -const handleOpen = (key: string, keyPath: string[]) => { - console.log(key, keyPath); -}; -const handleClose = (key: string, keyPath: string[]) => { - console.log(key, keyPath); -}; - const houseHoldStore = useHouseholdStore(); const houseHoldApi = new HouseholdApi(); const sessionStore = useSessionStore(); const isCreateHousehold = ref(false); +const emitter = inject("emitter"); const households = ref(null as Household[] | null); const newHousehold = ref({ name: "", } as CreateHousehold); -houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { - console.log(res.data); - households.value = res.data; +emitter.on("household-removed", () => { + console.log("removing"); + getHouseholds(); }); +getHouseholds(); +function getHouseholds() { + houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => { + households.value = res.data; + if (households.value?.length > 0 && !houseHoldStore.household?.id) { + houseHoldStore.household = households.value[0]; + } + }); +} + function createHousehold() { houseHoldApi .createHousehold(newHousehold.value) diff --git a/src/main.ts b/src/main.ts index 8fa27d8..15ed4d1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,6 @@ import { createApp } from "vue"; import { createPinia } from "pinia"; +import mitt from "mitt"; import App from "./App.vue"; import router from "./router"; @@ -9,9 +10,11 @@ import "./assets/main.css"; import "element-plus/dist/index.css"; const app = createApp(App); +const emitter = mitt(); app.use(createPinia()); app.use(router); app.use(ElementPlus); +app.provide("emitter", emitter); app.mount("#app"); diff --git a/src/stores/household.ts b/src/stores/household.ts index 59289d3..3b6c1b4 100644 --- a/src/stores/household.ts +++ b/src/stores/household.ts @@ -1,10 +1,11 @@ -import { computed, ref } from "vue"; +import { computed, inject, ref } from "vue"; import { defineStore } from "pinia"; import type { Household } from "@/services/index"; export const useHouseholdStore = defineStore("household", () => { const householdValue = ref({} as Household); + const emitter = inject("emitter"); const household = computed({ get: () => { @@ -18,12 +19,15 @@ export const useHouseholdStore = defineStore("household", () => { set: (val) => { householdValue.value = val; sessionStorage.setItem("household", JSON.stringify(val)); + emitter.emit("household-updated"); }, }); function removeHousehold() { household.value = {} as Household; sessionStorage.removeItem("household"); + emitter.emit("household-removed"); + emitter.emit("household-updated"); } return { household, removeHousehold }; diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue index 413c2dc..f7ebf0f 100644 --- a/src/views/HouseholdView.vue +++ b/src/views/HouseholdView.vue @@ -1,8 +1,8 @@ <template> <div id="householdview" class="householdview-wrapper"> - <h1 v-if="currentHousehold?.id">{{ currentHousehold?.name }}</h1> + <h1 v-if="householdStore.household?.id">{{ householdStore.household?.name }}</h1> <h1 v-else>Velg husholdning i meny</h1> - <div class="top-bar" v-if="currentHousehold?.id"> + <div class="top-bar" v-if="householdStore.household?.id"> <HouseholdTopBar @delete-household="deleteHousehold()" @add-user="addUser" /> </div> <div> @@ -30,7 +30,7 @@ </template> <script setup lang="ts"> -import { onMounted, ref } from "vue"; +import { inject, onMounted, ref } from "vue"; import type { UserFull } from "@/services"; import UserCard from "@/components/HouseholdCard.vue"; import HouseholdTopBar from "@/components/HouseholdTopBar.vue"; @@ -45,12 +45,20 @@ const householdApi = new HouseholdApi(); const accountApi = new AccountApi(); let users = ref([]); -const currentHousehold = householdStore.household; +const emitter = inject("emitter"); -householdApi.getUsers(currentHousehold?.id!).then((data) => { - users.value = data.data; +emitter.on("household-updated", () => { + getUsers(); }); +getUsers(); + +function getUsers() { + householdApi.getUsers(householdStore.household?.id!).then((data) => { + users.value = data.data; + }); +} + function removeUser(user: UserFull) { return householdApi .removeUserFromHousehold(23, user.id!) @@ -115,7 +123,7 @@ function addUser(value: string) { console.log(error); }) return householdApi - .addUser(currentHousehold?.id!, { userId }) + .addUser(householdStore.household?.id!, { userId }) .then((data) => { ElMessage.success("La til " + value + " i husholdning"); addUserLocally(userId); @@ -142,10 +150,10 @@ function addUserLocally(id: number) { function deleteHousehold() { householdApi - .deleteHousehold(currentHousehold?.id!) + .deleteHousehold(householdStore.household?.id!) .then(() => { ElMessage.success("Slettet husholdning"); - console.log("deleted household: " + currentHousehold?.name); + console.log("deleted household: " + householdStore.household?.name); householdStore.removeHousehold(); }) .catch((error) => { diff --git a/src/views/InventoryView.vue b/src/views/InventoryView.vue index 7dc64c6..98f1f19 100644 --- a/src/views/InventoryView.vue +++ b/src/views/InventoryView.vue @@ -51,7 +51,7 @@ <script setup lang="ts"> import axios from "axios"; -import { ref, computed } from "vue"; +import { ref, computed, inject } from "vue"; import { ElDialog } from "element-plus"; import type { Item, UpdateItem } from "@/services/index"; @@ -106,6 +106,11 @@ function useItemDialog(item: Item) { useItemDialogVisible.value = true; } +const emitter = inject("emitter"); + +emitter.on("household-updated", () => { + updateItems(); +}); // Other script logic function useItem(item: Item, amount: number | null) { if (amount === null) { diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue index c6276a8..acdd0a2 100644 --- a/src/views/ShoppingListView.vue +++ b/src/views/ShoppingListView.vue @@ -139,7 +139,7 @@ import type { ShoppingListEntry, UpdateShoppingListEntry, } from "@/services"; -import { Ref, ref } from "vue"; +import { inject, Ref, ref } from "vue"; import { ElMessage, ElNotification, FormInstance } from "element-plus"; import { ItemTypeApi, ShoppingListApi } from "@/services/index"; import ShoppingListCardSkeleton from "@/components/ShoppingListCardSkeleton.vue"; @@ -197,26 +197,35 @@ const loading = ref(undefined) as Ref<undefined | boolean>; const loadingSubmit = ref(false); const timeout = setTimeout(() => (loading.value = true), 100); -shoppingListApi - .getShoppingList(householdId) - .then((response) => { - activeItems.value.clear(); - suggestedItems.value.clear(); - boughtItems.value.clear(); - response.data.forEach((item) => { - setItemLocal(item); - }); - }) - .catch((error) => { - ElMessage.error({ - message: "Noe gikk galt ved henting av handleliste", - type: "error", +const emitter = inject("emitter"); + +emitter.on("household-updated", () => { + getShoppingList(); +}); + +getShoppingList(); +function getShoppingList() { + shoppingListApi + .getShoppingList(houseHoldStore.household?.id) + .then((response) => { + activeItems.value.clear(); + suggestedItems.value.clear(); + boughtItems.value.clear(); + response.data.forEach((item) => { + setItemLocal(item); + }); + }) + .catch((error) => { + ElMessage.error({ + message: "Noe gikk galt ved henting av handleliste", + type: "error", + }); + }) + .finally(() => { + clearTimeout(timeout); + loading.value = false; }); - }) - .finally(() => { - clearTimeout(timeout); - loading.value = false; - }); +} async function searchItemType(queryString: string, cb: any) { const results = await itemTypesApi.searchItemTypes(queryString).then((response) => { -- GitLab