Recipe Data Table

This commit is contained in:
Kuchenpirat 2025-07-30 10:39:25 +00:00
commit ee68f95d4b

View file

@ -62,7 +62,7 @@
</v-data-table> </v-data-table>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import UserAvatar from "../User/UserAvatar.vue"; import UserAvatar from "../User/UserAvatar.vue";
import RecipeChip from "./RecipeChips.vue"; import RecipeChip from "./RecipeChips.vue";
import type { Recipe, RecipeCategory, RecipeTool } from "~/lib/api/types/recipe"; import type { Recipe, RecipeCategory, RecipeTool } from "~/lib/api/types/recipe";
@ -70,8 +70,6 @@ import { useUserApi } from "~/composables/api";
import type { UserSummary } from "~/lib/api/types/user"; import type { UserSummary } from "~/lib/api/types/user";
import type { RecipeTag } from "~/lib/api/types/household"; import type { RecipeTag } from "~/lib/api/types/household";
const INPUT_EVENT = "update:modelValue";
interface ShowHeaders { interface ShowHeaders {
id: boolean; id: boolean;
owner: boolean; owner: boolean;
@ -84,56 +82,43 @@ interface ShowHeaders {
dateAdded: boolean; dateAdded: boolean;
} }
export default defineNuxtComponent({ interface Props {
components: { RecipeChip, UserAvatar }, loading?: boolean;
props: { recipes?: Recipe[];
modelValue: { showHeaders?: ShowHeaders;
type: Array as PropType<Recipe[]>, }
required: false, const props = withDefaults(defineProps<Props>(), {
default: () => [], loading: false,
}, recipes: () => [],
loading: { showHeaders: () => ({
type: Boolean,
required: false,
default: false,
},
recipes: {
type: Array as () => Recipe[],
default: () => [],
},
showHeaders: {
type: Object as () => ShowHeaders,
required: false,
default: () => {
return {
id: true, id: true,
owner: false, owner: false,
tags: true, tags: true,
categories: true, categories: true,
tools: true,
recipeServings: true, recipeServings: true,
recipeYieldQuantity: true, recipeYieldQuantity: true,
recipeYield: true, recipeYield: true,
dateAdded: true, dateAdded: true,
}; }),
}, });
},
},
emits: ["click", "update:modelValue"],
setup(props, context) {
const i18n = useI18n();
const $auth = useMealieAuth();
const groupSlug = $auth.user.value?.groupSlug;
const router = useRouter();
const selected = computed({
get: () => props.modelValue,
set: value => context.emit(INPUT_EVENT, value),
});
// Initialize sort state with default sorting by dateAdded descending defineEmits<{
const sortBy = ref([{ key: "dateAdded", order: "desc" }]); click: [];
}>();
const headers = computed(() => { const selected = defineModel<Recipe[]>({ default: () => [] });
const hdrs: Array<{ title: string; value: string; align?: string; sortable?: boolean }> = [];
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) { if (props.showHeaders.id) {
hdrs.push({ title: i18n.t("general.id"), value: "id" }); hdrs.push({ title: i18n.t("general.id"), value: "id" });
@ -166,58 +151,45 @@ export default defineNuxtComponent({
} }
return hdrs; return hdrs;
}); });
function formatDate(date: string) { function formatDate(date: string) {
try { try {
return i18n.d(Date.parse(date), "medium"); return i18n.d(Date.parse(date), "medium");
} }
catch { catch {
return ""; return "";
} }
} }
// ============ // ============
// Group Members // Group Members
const api = useUserApi(); const api = useUserApi();
const members = ref<UserSummary[]>([]); const members = ref<UserSummary[]>([]);
async function refreshMembers() { async function refreshMembers() {
const { data } = await api.groups.fetchMembers(); const { data } = await api.groups.fetchMembers();
if (data) { if (data) {
members.value = data.items; members.value = data.items;
} }
} }
function filterItems(item: RecipeTag | RecipeCategory | RecipeTool, itemType: string) { function filterItems(item: RecipeTag | RecipeCategory | RecipeTool, itemType: string) {
if (!groupSlug || !item.id) { if (!groupSlug || !item.id) {
return; return;
} }
router.push(`/g/${groupSlug}?${itemType}=${item.id}`); router.push(`/g/${groupSlug}?${itemType}=${item.id}`);
} }
onMounted(() => { onMounted(() => {
refreshMembers(); refreshMembers();
}); });
function getMember(id: string) { function getMember(id: string) {
if (members.value[0]) { if (members.value[0]) {
return members.value.find(m => m.id === id)?.fullName; return members.value.find(m => m.id === id)?.fullName;
} }
return i18n.t("general.none"); return i18n.t("general.none");
} }
return {
selected,
sortBy,
groupSlug,
headers,
formatDate,
members,
getMember,
filterItems,
};
},
});
</script> </script>