mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 06:23:34 -07:00
Meal Planner Item Context Menu
This commit is contained in:
parent
05f211c341
commit
b2e04e9cb6
1 changed files with 82 additions and 99 deletions
|
@ -18,7 +18,7 @@
|
||||||
:open-on-hover="mdAndUp"
|
:open-on-hover="mdAndUp"
|
||||||
content-class="d-print-none"
|
content-class="d-print-none"
|
||||||
>
|
>
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props: activatorProps }">
|
||||||
<v-btn
|
<v-btn
|
||||||
:class="{ 'rounded-circle': fab }"
|
:class="{ 'rounded-circle': fab }"
|
||||||
:size="fab ? 'small' : undefined"
|
:size="fab ? 'small' : undefined"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
:icon="!fab"
|
:icon="!fab"
|
||||||
variant="text"
|
variant="text"
|
||||||
dark
|
dark
|
||||||
v-bind="props"
|
v-bind="activatorProps"
|
||||||
@click.prevent
|
@click.prevent
|
||||||
>
|
>
|
||||||
<v-icon>{{ icon }}</v-icon>
|
<v-icon>{{ icon }}</v-icon>
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Recipe } from "~/lib/api/types/recipe";
|
import type { Recipe } from "~/lib/api/types/recipe";
|
||||||
import RecipeDialogAddToShoppingList from "~/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue";
|
import RecipeDialogAddToShoppingList from "~/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue";
|
||||||
import type { ShoppingListSummary } from "~/lib/api/types/household";
|
import type { ShoppingListSummary } from "~/lib/api/types/household";
|
||||||
|
@ -64,101 +64,84 @@ export interface ContextMenuItem {
|
||||||
isPublic: boolean;
|
isPublic: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
interface Props {
|
||||||
components: {
|
recipes?: Recipe[];
|
||||||
RecipeDialogAddToShoppingList,
|
menuTop?: boolean;
|
||||||
},
|
fab?: boolean;
|
||||||
props: {
|
color?: string;
|
||||||
recipes: {
|
menuIcon?: string | null;
|
||||||
type: Array as () => Recipe[],
|
}
|
||||||
default: () => [],
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
},
|
recipes: () => [],
|
||||||
menuTop: {
|
menuTop: true,
|
||||||
type: Boolean,
|
fab: false,
|
||||||
default: true,
|
color: "primary",
|
||||||
},
|
menuIcon: null,
|
||||||
fab: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default: "primary",
|
|
||||||
},
|
|
||||||
menuIcon: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props, context) {
|
|
||||||
const { mdAndUp } = useDisplay();
|
|
||||||
|
|
||||||
const i18n = useI18n();
|
|
||||||
const { $globals } = useNuxtApp();
|
|
||||||
const api = useUserApi();
|
|
||||||
|
|
||||||
const state = reactive({
|
|
||||||
loading: false,
|
|
||||||
shoppingListDialog: false,
|
|
||||||
menuItems: [
|
|
||||||
{
|
|
||||||
title: i18n.t("recipe.add-to-list"),
|
|
||||||
icon: $globals.icons.cartCheck,
|
|
||||||
color: undefined,
|
|
||||||
event: "shoppingList",
|
|
||||||
isPublic: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const icon = props.menuIcon || $globals.icons.dotsVertical;
|
|
||||||
|
|
||||||
const shoppingLists = ref<ShoppingListSummary[]>();
|
|
||||||
const recipesWithScales = computed(() => {
|
|
||||||
return props.recipes.map((recipe) => {
|
|
||||||
return {
|
|
||||||
scale: 1,
|
|
||||||
...recipe,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
async function getShoppingLists() {
|
|
||||||
const { data } = await api.shopping.lists.getAll(1, -1, { orderBy: "name", orderDirection: "asc" });
|
|
||||||
if (data) {
|
|
||||||
shoppingLists.value = data.items as ShoppingListSummary[] ?? [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
||||||
const eventHandlers: { [key: string]: () => void | Promise<any> } = {
|
|
||||||
shoppingList: () => {
|
|
||||||
getShoppingLists();
|
|
||||||
state.shoppingListDialog = true;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function contextMenuEventHandler(eventKey: string) {
|
|
||||||
const handler = eventHandlers[eventKey];
|
|
||||||
|
|
||||||
if (handler && typeof handler === "function") {
|
|
||||||
handler();
|
|
||||||
state.loading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.emit(eventKey);
|
|
||||||
state.loading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...toRefs(state),
|
|
||||||
contextMenuEventHandler,
|
|
||||||
icon,
|
|
||||||
recipesWithScales,
|
|
||||||
shoppingLists,
|
|
||||||
mdAndUp,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
[key: string]: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const { mdAndUp } = useDisplay();
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
|
const { $globals } = useNuxtApp();
|
||||||
|
const api = useUserApi();
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
shoppingListDialog: false,
|
||||||
|
menuItems: [
|
||||||
|
{
|
||||||
|
title: i18n.t("recipe.add-to-list"),
|
||||||
|
icon: $globals.icons.cartCheck,
|
||||||
|
color: undefined,
|
||||||
|
event: "shoppingList",
|
||||||
|
isPublic: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shoppingListDialog, menuItems } = toRefs(state);
|
||||||
|
|
||||||
|
const icon = props.menuIcon || $globals.icons.dotsVertical;
|
||||||
|
|
||||||
|
const shoppingLists = ref<ShoppingListSummary[]>();
|
||||||
|
const recipesWithScales = computed(() => {
|
||||||
|
return props.recipes.map((recipe) => {
|
||||||
|
return {
|
||||||
|
scale: 1,
|
||||||
|
...recipe,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getShoppingLists() {
|
||||||
|
const { data } = await api.shopping.lists.getAll(1, -1, { orderBy: "name", orderDirection: "asc" });
|
||||||
|
if (data) {
|
||||||
|
shoppingLists.value = data.items as ShoppingListSummary[] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||||
|
const eventHandlers: { [key: string]: () => void | Promise<any> } = {
|
||||||
|
shoppingList: () => {
|
||||||
|
getShoppingLists();
|
||||||
|
state.shoppingListDialog = true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function contextMenuEventHandler(eventKey: string) {
|
||||||
|
const handler = eventHandlers[eventKey];
|
||||||
|
|
||||||
|
if (handler && typeof handler === "function") {
|
||||||
|
handler();
|
||||||
|
state.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(eventKey);
|
||||||
|
state.loading = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue