| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <v-data-table | 
					
						
							|  |  |  |     v-model="selected" | 
					
						
							|  |  |  |     item-key="id" | 
					
						
							|  |  |  |     show-select | 
					
						
							| 
									
										
										
										
											2025-07-20 17:06:39 +02:00
										 |  |  |     :sort-by="sortBy" | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |     :headers="headers" | 
					
						
							|  |  |  |     :items="recipes" | 
					
						
							|  |  |  |     :items-per-page="15" | 
					
						
							|  |  |  |     class="elevation-0" | 
					
						
							| 
									
										
										
										
											2021-12-04 14:18:46 -09:00
										 |  |  |     :loading="loading" | 
					
						
							| 
									
										
										
										
											2025-07-20 17:06:39 +02:00
										 |  |  |     return-object | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |   > | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.name`]="{ item }"> | 
					
						
							|  |  |  |       <a | 
					
						
							|  |  |  |         :href="`/g/${groupSlug}/r/${item.slug}`" | 
					
						
							|  |  |  |         style="color: inherit; text-decoration: inherit; " | 
					
						
							|  |  |  |         @click="$emit('click')" | 
					
						
							|  |  |  |       >{{ item.name }}</a> | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.tags`]="{ item }"> | 
					
						
							|  |  |  |       <RecipeChip | 
					
						
							|  |  |  |         small | 
					
						
							|  |  |  |         :items="item.tags!" | 
					
						
							|  |  |  |         :is-category="false" | 
					
						
							|  |  |  |         url-prefix="tags" | 
					
						
							|  |  |  |         @item-selected="filterItems" | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2023-03-21 14:47:26 -05:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.recipeCategory`]="{ item }"> | 
					
						
							|  |  |  |       <RecipeChip | 
					
						
							|  |  |  |         small | 
					
						
							|  |  |  |         :items="item.recipeCategory!" | 
					
						
							|  |  |  |         @item-selected="filterItems" | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.tools`]="{ item }"> | 
					
						
							|  |  |  |       <RecipeChip | 
					
						
							|  |  |  |         small | 
					
						
							|  |  |  |         :items="item.tools" | 
					
						
							|  |  |  |         url-prefix="tools" | 
					
						
							|  |  |  |         @item-selected="filterItems" | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.userId`]="{ item }"> | 
					
						
							|  |  |  |       <div class="d-flex align-center"> | 
					
						
							|  |  |  |         <UserAvatar | 
					
						
							|  |  |  |           :user-id="item.userId!" | 
					
						
							|  |  |  |           :tooltip="false" | 
					
						
							|  |  |  |           size="40" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |         <div class="pl-2"> | 
					
						
							|  |  |  |           <span class="text-left"> | 
					
						
							|  |  |  |             {{ getMember(item.userId!) }} | 
					
						
							|  |  |  |           </span> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2021-12-04 14:18:46 -09:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <template #[`item.dateAdded`]="{ item }"> | 
					
						
							|  |  |  |       {{ formatDate(item.dateAdded!) }} | 
					
						
							| 
									
										
										
										
											2024-09-22 09:59:20 -05:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  |   </v-data-table> | 
					
						
							|  |  |  | </template> | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-30 20:37:02 +02:00
										 |  |  | <script setup lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-03-21 14:47:26 -05:00
										 |  |  | import UserAvatar from "../User/UserAvatar.vue"; | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  | import RecipeChip from "./RecipeChips.vue"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { Recipe, RecipeCategory, RecipeTool } from "~/lib/api/types/recipe"; | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { UserSummary } from "~/lib/api/types/user"; | 
					
						
							|  |  |  | import type { RecipeTag } from "~/lib/api/types/household"; | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | interface ShowHeaders { | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |   id: boolean; | 
					
						
							|  |  |  |   owner: boolean; | 
					
						
							|  |  |  |   tags: boolean; | 
					
						
							|  |  |  |   categories: boolean; | 
					
						
							|  |  |  |   tools: boolean; | 
					
						
							| 
									
										
										
										
											2024-11-20 08:46:27 -06:00
										 |  |  |   recipeServings: boolean; | 
					
						
							|  |  |  |   recipeYieldQuantity: boolean; | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |   recipeYield: boolean; | 
					
						
							|  |  |  |   dateAdded: boolean; | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-30 20:37:02 +02:00
										 |  |  | interface Props { | 
					
						
							|  |  |  |   loading?: boolean; | 
					
						
							|  |  |  |   recipes?: Recipe[]; | 
					
						
							|  |  |  |   showHeaders?: ShowHeaders; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const props = withDefaults(defineProps<Props>(), { | 
					
						
							|  |  |  |   loading: false, | 
					
						
							|  |  |  |   recipes: () => [], | 
					
						
							|  |  |  |   showHeaders: () => ({ | 
					
						
							|  |  |  |     id: true, | 
					
						
							|  |  |  |     owner: false, | 
					
						
							|  |  |  |     tags: true, | 
					
						
							|  |  |  |     categories: true, | 
					
						
							|  |  |  |     tools: true, | 
					
						
							|  |  |  |     recipeServings: true, | 
					
						
							|  |  |  |     recipeYieldQuantity: true, | 
					
						
							|  |  |  |     recipeYield: true, | 
					
						
							|  |  |  |     dateAdded: true, | 
					
						
							|  |  |  |   }), | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | defineEmits<{ | 
					
						
							|  |  |  |   click: []; | 
					
						
							|  |  |  | }>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const selected = defineModel<Recipe[]>({ default: () => [] }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const i18n = useI18n(); | 
					
						
							|  |  |  | const $auth = useMealieAuth(); | 
					
						
							|  |  |  | const groupSlug = $auth.user.value?.groupSlug; | 
					
						
							|  |  |  | const router = useRouter(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Initialize sort state with default sorting by dateAdded descending
 | 
					
						
							|  |  |  | const sortBy = ref([{ key: "dateAdded", order: "desc" as const }]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const headers = computed(() => { | 
					
						
							|  |  |  |   const hdrs: Array<{ title: string; value: string; align?: "center" | "start" | "end"; sortable?: boolean }> = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (props.showHeaders.id) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("general.id"), value: "id" }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.owner) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("general.owner"), value: "userId", align: "center", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   hdrs.push({ title: i18n.t("general.name"), value: "name", sortable: true }); | 
					
						
							|  |  |  |   if (props.showHeaders.categories) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("recipe.categories"), value: "recipeCategory", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (props.showHeaders.tags) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("tag.tags"), value: "tags", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.tools) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("tool.tools"), value: "tools", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.recipeServings) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("recipe.servings"), value: "recipeServings", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.recipeYieldQuantity) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("recipe.yield"), value: "recipeYieldQuantity", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.recipeYield) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("recipe.yield-text"), value: "recipeYield", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (props.showHeaders.dateAdded) { | 
					
						
							|  |  |  |     hdrs.push({ title: i18n.t("general.date-added"), value: "dateAdded", sortable: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return hdrs; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function formatDate(date: string) { | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     return i18n.d(Date.parse(date), "medium"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   catch { | 
					
						
							|  |  |  |     return ""; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ============
 | 
					
						
							|  |  |  | // Group Members
 | 
					
						
							|  |  |  | const api = useUserApi(); | 
					
						
							|  |  |  | const members = ref<UserSummary[]>([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function refreshMembers() { | 
					
						
							|  |  |  |   const { data } = await api.groups.fetchMembers(); | 
					
						
							|  |  |  |   if (data) { | 
					
						
							|  |  |  |     members.value = data.items; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function filterItems(item: RecipeTag | RecipeCategory | RecipeTool, itemType: string) { | 
					
						
							|  |  |  |   if (!groupSlug || !item.id) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   router.push(`/g/${groupSlug}?${itemType}=${item.id}`); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | onMounted(() => { | 
					
						
							|  |  |  |   refreshMembers(); | 
					
						
							| 
									
										
										
										
											2021-10-18 19:41:41 -08:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2025-07-30 20:37:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | function getMember(id: string) { | 
					
						
							|  |  |  |   if (members.value[0]) { | 
					
						
							|  |  |  |     return members.value.find(m => m.id === id)?.fullName; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return i18n.t("general.none"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | </script> |