mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-30 17:53:31 -04:00 
			
		
		
		
	fix: user & household creation (#5699)
This commit is contained in:
		| @@ -45,28 +45,11 @@ export const useGroupSelf = function () { | ||||
| export const useGroups = function () { | ||||
|   const api = useUserApi(); | ||||
|   const loading = ref(false); | ||||
|   const groups = ref<GroupSummary[] | null>(null); | ||||
|  | ||||
|   function getAllGroups() { | ||||
|   async function getAllGroups() { | ||||
|     loading.value = true; | ||||
|     const asyncKey = String(Date.now()); | ||||
|     const { data: groups } = useAsyncData(asyncKey, async () => { | ||||
|       const { data } = await api.groups.getAll(1, -1, { orderBy: "name", orderDirection: "asc" }); ; | ||||
|  | ||||
|       if (data) { | ||||
|         return data.items; | ||||
|       } | ||||
|       else { | ||||
|         return null; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     loading.value = false; | ||||
|     return groups; | ||||
|   } | ||||
|  | ||||
|   async function refreshAllGroups() { | ||||
|     loading.value = true; | ||||
|     const { data } = await api.groups.getAll(1, -1, { orderBy: "name", orderDirection: "asc" }); ; | ||||
|     const { data } = await api.groups.getAll(1, -1, { orderBy: "name", orderDirection: "asc" }); | ||||
|  | ||||
|     if (data) { | ||||
|       groups.value = data.items; | ||||
| @@ -78,11 +61,15 @@ export const useGroups = function () { | ||||
|     loading.value = false; | ||||
|   } | ||||
|  | ||||
|   async function refreshAllGroups() { | ||||
|     await getAllGroups(); | ||||
|   } | ||||
|  | ||||
|   async function deleteGroup(id: string | number) { | ||||
|     loading.value = true; | ||||
|     const { data } = await api.groups.deleteOne(id); | ||||
|     loading.value = false; | ||||
|     refreshAllGroups(); | ||||
|     await refreshAllGroups(); | ||||
|     return data; | ||||
|   } | ||||
|  | ||||
| @@ -93,9 +80,13 @@ export const useGroups = function () { | ||||
|     if (data && groups.value) { | ||||
|       groups.value.push(data); | ||||
|     } | ||||
|     loading.value = false; | ||||
|   } | ||||
|  | ||||
|   const groups = getAllGroups(); | ||||
|   // Initialize data on first call | ||||
|   if (!groups.value) { | ||||
|     getAllGroups(); | ||||
|   } | ||||
|  | ||||
|   return { groups, getAllGroups, refreshAllGroups, deleteGroup, createGroup }; | ||||
| }; | ||||
|   | ||||
| @@ -48,29 +48,12 @@ export const useHouseholdSelf = function () { | ||||
| export const useAdminHouseholds = function () { | ||||
|   const api = useAdminApi(); | ||||
|   const loading = ref(false); | ||||
|   const households = ref<HouseholdInDB[] | null>(null); | ||||
|  | ||||
|   function getAllHouseholds() { | ||||
|   async function getAllHouseholds() { | ||||
|     loading.value = true; | ||||
|     const asyncKey = String(Date.now()); | ||||
|     const { data: households } = useAsyncData(asyncKey, async () => { | ||||
|     const { data } = await api.households.getAll(1, -1, { orderBy: "name, group.name", orderDirection: "asc" }); | ||||
|  | ||||
|       if (data) { | ||||
|         return data.items; | ||||
|       } | ||||
|       else { | ||||
|         return null; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     loading.value = false; | ||||
|     return households; | ||||
|   } | ||||
|  | ||||
|   async function refreshAllHouseholds() { | ||||
|     loading.value = true; | ||||
|     const { data } = await api.households.getAll(1, -1, { orderBy: "name, group.name", orderDirection: "asc" }); ; | ||||
|  | ||||
|     if (data) { | ||||
|       households.value = data.items; | ||||
|     } | ||||
| @@ -81,11 +64,15 @@ export const useAdminHouseholds = function () { | ||||
|     loading.value = false; | ||||
|   } | ||||
|  | ||||
|   async function refreshAllHouseholds() { | ||||
|     await getAllHouseholds(); | ||||
|   } | ||||
|  | ||||
|   async function deleteHousehold(id: string | number) { | ||||
|     loading.value = true; | ||||
|     const { data } = await api.households.deleteOne(id); | ||||
|     loading.value = false; | ||||
|     refreshAllHouseholds(); | ||||
|     await refreshAllHouseholds(); | ||||
|     return data; | ||||
|   } | ||||
|  | ||||
| @@ -96,9 +83,9 @@ export const useAdminHouseholds = function () { | ||||
|     if (data && households.value) { | ||||
|       households.value.push(data); | ||||
|     } | ||||
|     loading.value = false; | ||||
|   } | ||||
|  | ||||
|   const households = getAllHouseholds(); | ||||
|   function useHouseholdsInGroup(groupIdRef: Ref<string>) { | ||||
|     return computed( | ||||
|       () => { | ||||
| @@ -109,6 +96,10 @@ export const useAdminHouseholds = function () { | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   if (!households.value) { | ||||
|     getAllHouseholds(); | ||||
|   } | ||||
|  | ||||
|   return { | ||||
|     households, | ||||
|     useHouseholdsInGroup, | ||||
|   | ||||
| @@ -14,7 +14,6 @@ | ||||
|             :items="groups" | ||||
|             item-title="name" | ||||
|             item-value="id" | ||||
|             :return-object="false" | ||||
|             variant="filled" | ||||
|             :label="$t('household.household-group')" | ||||
|             :rules="[validators.required]" | ||||
| @@ -94,10 +93,7 @@ | ||||
|                   icon | ||||
|                   color="error" | ||||
|                   variant="text" | ||||
|                   @click.stop=" | ||||
|                     confirmDialog = true; | ||||
|                     deleteTarget = +item.id; | ||||
|                   " | ||||
|                   @click.stop="confirmDialog = true; deleteTarget = item.id" | ||||
|                 > | ||||
|                   <v-icon> | ||||
|                     {{ $globals.icons.delete }} | ||||
| @@ -114,7 +110,7 @@ | ||||
|   </v-container> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| <script setup lang="ts"> | ||||
| import { fieldTypes } from "~/composables/forms"; | ||||
| import { useGroups } from "~/composables/use-groups"; | ||||
| import { useAdminHouseholds } from "~/composables/use-households"; | ||||
| @@ -122,30 +118,28 @@ import { validators } from "~/composables/use-validators"; | ||||
| import type { HouseholdInDB } from "~/lib/api/types/household"; | ||||
| import type { VForm } from "~/types/auto-forms"; | ||||
|  | ||||
| export default defineNuxtComponent({ | ||||
|   setup() { | ||||
|     definePageMeta({ | ||||
| definePageMeta({ | ||||
|   layout: "admin", | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|     const i18n = useI18n(); | ||||
| const i18n = useI18n(); | ||||
|  | ||||
|     // Set page title | ||||
|     useSeoMeta({ | ||||
| useSeoMeta({ | ||||
|   title: i18n.t("household.manage-households"), | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|     const { groups } = useGroups(); | ||||
|     const { households, refreshAllHouseholds, deleteHousehold, createHousehold } = useAdminHouseholds(); | ||||
|     const refNewHouseholdForm = ref<VForm | null>(null); | ||||
| const { groups } = useGroups(); | ||||
| const { households, deleteHousehold, createHousehold } = useAdminHouseholds(); | ||||
|  | ||||
|     const state = reactive({ | ||||
|       createDialog: false, | ||||
|       confirmDialog: false, | ||||
|       loading: false, | ||||
|       deleteTarget: 0, | ||||
|       search: "", | ||||
|       headers: [ | ||||
| const refNewHouseholdForm = ref<VForm | null>(null); | ||||
|  | ||||
| const createDialog = ref(false); | ||||
| const confirmDialog = ref(false); | ||||
| const deleteTarget = ref<string>(""); | ||||
| const search = ref(""); | ||||
| const updateMode = ref(false); | ||||
|  | ||||
| const headers = [ | ||||
|   { | ||||
|     title: i18n.t("household.household"), | ||||
|     align: "start", | ||||
| @@ -157,9 +151,9 @@ export default defineNuxtComponent({ | ||||
|   { title: i18n.t("user.total-users"), value: "users" }, | ||||
|   { title: i18n.t("user.webhooks-enabled"), value: "webhookEnable" }, | ||||
|   { title: i18n.t("general.delete"), value: "actions" }, | ||||
|       ], | ||||
|       updateMode: false, | ||||
|       createHouseholdForm: { | ||||
| ]; | ||||
|  | ||||
| const createHouseholdForm = reactive({ | ||||
|   items: [ | ||||
|     { | ||||
|       label: i18n.t("household.household-name"), | ||||
| @@ -172,42 +166,25 @@ export default defineNuxtComponent({ | ||||
|     groupId: "", | ||||
|     name: "", | ||||
|   }, | ||||
|       }, | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|     function openDialog() { | ||||
|       state.createDialog = true; | ||||
|       state.createHouseholdForm.data.name = ""; | ||||
|       state.createHouseholdForm.data.groupId = ""; | ||||
|     } | ||||
| function openDialog() { | ||||
|   createDialog.value = true; | ||||
|   createHouseholdForm.data.name = ""; | ||||
|   createHouseholdForm.data.groupId = ""; | ||||
| } | ||||
|  | ||||
|     const router = useRouter(); | ||||
| const router = useRouter(); | ||||
|  | ||||
|     function handleRowClick(item: HouseholdInDB) { | ||||
| function handleRowClick(item: HouseholdInDB) { | ||||
|   router.push(`/admin/manage/households/${item.id}`); | ||||
|     } | ||||
| } | ||||
|  | ||||
|     async function handleCreateSubmit() { | ||||
| async function handleCreateSubmit() { | ||||
|   if (!refNewHouseholdForm.value?.validate()) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|       state.createDialog = false; | ||||
|       await createHousehold(state.createHouseholdForm.data); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|       ...toRefs(state), | ||||
|       refNewHouseholdForm, | ||||
|       groups, | ||||
|       households, | ||||
|       validators, | ||||
|       refreshAllHouseholds, | ||||
|       deleteHousehold, | ||||
|       handleCreateSubmit, | ||||
|       openDialog, | ||||
|       handleRowClick, | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|   createDialog.value = false; | ||||
|   await createHousehold(createHouseholdForm.data); | ||||
| } | ||||
| </script> | ||||
|   | ||||
| @@ -21,26 +21,23 @@ | ||||
|       <v-card variant="outlined"> | ||||
|         <v-card-text> | ||||
|           <v-select | ||||
|             v-if="groups" | ||||
|             v-model="selectedGroupId" | ||||
|             :items="groups" | ||||
|             v-model="selectedGroup" | ||||
|             :items="groups || []" | ||||
|             item-title="name" | ||||
|             item-value="id" | ||||
|             :return-object="false" | ||||
|             return-object | ||||
|             variant="filled" | ||||
|             :label="$t('group.user-group')" | ||||
|             :rules="[validators.required]" | ||||
|           /> | ||||
|           <v-select | ||||
|             v-model="newUserData.household" | ||||
|             :disabled="!selectedGroupId" | ||||
|             :disabled="!selectedGroup" | ||||
|             :items="households" | ||||
|             item-title="name" | ||||
|             item-value="name" | ||||
|             :return-object="false" | ||||
|             variant="filled" | ||||
|             :label="$t('household.user-household')" | ||||
|             :hint="selectedGroupId ? '' : $t('group.you-must-select-a-group-before-selecting-a-household')" | ||||
|             :hint="selectedGroup ? '' : $t('group.you-must-select-a-group-before-selecting-a-household')" | ||||
|             persistent-hint | ||||
|             :rules="[validators.required]" | ||||
|           /> | ||||
| @@ -60,46 +57,33 @@ | ||||
|   </v-container> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| <script setup lang="ts"> | ||||
| import { useAdminApi } from "~/composables/api"; | ||||
| import { useGroups } from "~/composables/use-groups"; | ||||
| import { useAdminHouseholds } from "~/composables/use-households"; | ||||
| import { useUserForm } from "~/composables/use-users"; | ||||
| import { validators } from "~/composables/use-validators"; | ||||
| import type { UserIn } from "~/lib/api/types/user"; | ||||
| import type { GroupInDB, UserIn } from "~/lib/api/types/user"; | ||||
| import type { VForm } from "~/types/auto-forms"; | ||||
|  | ||||
| export default defineNuxtComponent({ | ||||
|   setup() { | ||||
|     definePageMeta({ | ||||
| definePageMeta({ | ||||
|   layout: "admin", | ||||
|     }); | ||||
| }); | ||||
| const { userForm } = useUserForm(); | ||||
| const { groups } = useGroups(); | ||||
| const router = useRouter(); | ||||
|  | ||||
|     const { userForm } = useUserForm(); | ||||
|     const { groups } = useGroups(); | ||||
|     const { useHouseholdsInGroup } = useAdminHouseholds(); | ||||
|     const router = useRouter(); | ||||
| const refNewUserForm = ref<VForm | null>(null); | ||||
| const adminApi = useAdminApi(); | ||||
|  | ||||
|     // ============================================== | ||||
|     // New User Form | ||||
| const selectedGroup = ref<GroupInDB | undefined>(undefined); | ||||
| const households = computed(() => selectedGroup.value?.households || []); | ||||
|  | ||||
|     const refNewUserForm = ref<VForm | null>(null); | ||||
|  | ||||
|     const adminApi = useAdminApi(); | ||||
|  | ||||
|     const selectedGroupId = ref<string>(""); | ||||
|     const households = useHouseholdsInGroup(selectedGroupId); | ||||
|  | ||||
|     const selectedGroup = computed(() => { | ||||
|       return groups.value?.find(group => group.id === selectedGroupId.value); | ||||
|     }); | ||||
|     const state = reactive({ | ||||
|       newUserData: { | ||||
| const newUserData = ref({ | ||||
|   username: "", | ||||
|   fullName: "", | ||||
|   email: "", | ||||
|   admin: false, | ||||
|         group: selectedGroup.value?.name || "", | ||||
|   group: computed(() => selectedGroup.value?.name || ""), | ||||
|   household: "", | ||||
|   advanced: false, | ||||
|   canInvite: false, | ||||
| @@ -107,35 +91,17 @@ export default defineNuxtComponent({ | ||||
|   canOrganize: false, | ||||
|   password: "", | ||||
|   authMethod: "Mealie", | ||||
|       }, | ||||
|     }); | ||||
|     watch(selectedGroup, (newGroup) => { | ||||
|       state.newUserData.group = newGroup?.name || ""; | ||||
|       state.newUserData.household = ""; | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|     async function handleSubmit() { | ||||
| async function handleSubmit() { | ||||
|   if (!refNewUserForm.value?.validate()) return; | ||||
|  | ||||
|       const { response } = await adminApi.users.createOne(state.newUserData as UserIn); | ||||
|   const { response } = await adminApi.users.createOne(newUserData.value as UserIn); | ||||
|  | ||||
|   if (response?.status === 201) { | ||||
|     router.push("/admin/manage/users"); | ||||
|   } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|       ...toRefs(state), | ||||
|       userForm, | ||||
|       refNewUserForm, | ||||
|       handleSubmit, | ||||
|       groups, | ||||
|       selectedGroupId, | ||||
|       households, | ||||
|       validators, | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped></style> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user