visual indicator meal plan in shopping
This commit is contained in:
parent
24b0643765
commit
2af7b64d4f
@ -610,10 +610,14 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
|||||||
note_markdown = serializers.SerializerMethodField('get_note_markdown')
|
note_markdown = serializers.SerializerMethodField('get_note_markdown')
|
||||||
servings = CustomDecimalField()
|
servings = CustomDecimalField()
|
||||||
shared = UserNameSerializer(many=True, required=False, allow_null=True)
|
shared = UserNameSerializer(many=True, required=False, allow_null=True)
|
||||||
|
shopping = serializers.SerializerMethodField('in_shopping')
|
||||||
|
|
||||||
def get_note_markdown(self, obj):
|
def get_note_markdown(self, obj):
|
||||||
return markdown(obj.note)
|
return markdown(obj.note)
|
||||||
|
|
||||||
|
def in_shopping(self, obj):
|
||||||
|
return ShoppingListRecipe.objects.filter(mealplan=obj.id).exists()
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
validated_data['created_by'] = self.context['request'].user
|
validated_data['created_by'] = self.context['request'].user
|
||||||
mealplan = super().create(validated_data)
|
mealplan = super().create(validated_data)
|
||||||
@ -626,7 +630,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
|||||||
fields = (
|
fields = (
|
||||||
'id', 'title', 'recipe', 'servings', 'note', 'note_markdown',
|
'id', 'title', 'recipe', 'servings', 'note', 'note_markdown',
|
||||||
'date', 'meal_type', 'created_by', 'shared', 'recipe_name',
|
'date', 'meal_type', 'created_by', 'shared', 'recipe_name',
|
||||||
'meal_type_name'
|
'meal_type_name', 'shopping'
|
||||||
)
|
)
|
||||||
read_only_fields = ('created_by',)
|
read_only_fields = ('created_by',)
|
||||||
|
|
||||||
|
@ -1,26 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-hover class="card cv-item meal-plan-card p-0" :key="value.id" :draggable="true"
|
<div
|
||||||
|
v-hover
|
||||||
|
class="card cv-item meal-plan-card p-0"
|
||||||
|
:key="value.id"
|
||||||
|
:draggable="true"
|
||||||
:style="`top:${top};max-height:${item_height}`"
|
:style="`top:${top};max-height:${item_height}`"
|
||||||
@dragstart="onDragItemStart(value, $event)"
|
@dragstart="onDragItemStart(value, $event)"
|
||||||
@click="onClickItem(value, $event)"
|
@click="onClickItem(value, $event)"
|
||||||
:aria-grabbed="value == currentDragItem"
|
:aria-grabbed="value == currentDragItem"
|
||||||
:class="value.classes"
|
:class="value.classes"
|
||||||
@contextmenu.prevent="$emit('open-context-menu', $event, value)">
|
@contextmenu.prevent="$emit('open-context-menu', $event, value)"
|
||||||
<div class="card-header p-1 text-center text-primary border-bottom-0" v-if="detailed"
|
>
|
||||||
:style="`background-color: ${background_color}`">
|
<div class="card-header p-1 text-center text-primary border-bottom-0" v-if="detailed" :style="`background-color: ${background_color}`">
|
||||||
<span class="font-light text-center" v-if="entry.entry.meal_type.icon != null">{{
|
<span class="font-light text-center" v-if="entry.entry.meal_type.icon != null">{{ entry.entry.meal_type.icon }}</span>
|
||||||
entry.entry.meal_type.icon
|
|
||||||
}}</span>
|
|
||||||
<span class="font-light d-none d-md-inline">{{ entry.entry.meal_type.name }}</span>
|
<span class="font-light d-none d-md-inline">{{ entry.entry.meal_type.name }}</span>
|
||||||
|
<span v-if="entry.entry.shopping" class="font-light"><i class="fas fa-shopping-cart fa-xs float-left" v-b-tooltip.hover.top :title="$t('in_shopping')" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-img-overlay h-100 d-flex flex-column justify-content-right float-right text-right p-0"
|
<div class="card-img-overlay h-100 d-flex flex-column justify-content-right float-right text-right p-0" v-if="detailed">
|
||||||
v-if="detailed">
|
|
||||||
<a>
|
<a>
|
||||||
<div style="position: static;">
|
<div style="position: static">
|
||||||
<div class="dropdown b-dropdown position-static btn-group">
|
<div class="dropdown b-dropdown position-static btn-group">
|
||||||
<button aria-haspopup="true" aria-expanded="false" type="button"
|
<button
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
|
type="button"
|
||||||
class="btn btn-link text-decoration-none text-body pr-2 dropdown-toggle-no-caret"
|
class="btn btn-link text-decoration-none text-body pr-2 dropdown-toggle-no-caret"
|
||||||
@click.stop="$emit('open-context-menu', $event, value)"><i class="fas fa-ellipsis-v fa-lg"></i>
|
@click.stop="$emit('open-context-menu', $event, value)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-ellipsis-v fa-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -29,21 +36,15 @@
|
|||||||
<div class="card-header p-1 text-center" v-if="detailed" :style="`background-color: ${background_color}`">
|
<div class="card-header p-1 text-center" v-if="detailed" :style="`background-color: ${background_color}`">
|
||||||
<span class="font-light">{{ title }}</span>
|
<span class="font-light">{{ title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<b-img fluid class="card-img-bottom" :src="entry.entry.recipe.image" v-if="hasRecipe && detailed" ></b-img>
|
<b-img fluid class="card-img-bottom" :src="entry.entry.recipe.image" v-if="hasRecipe && detailed"></b-img>
|
||||||
<b-img fluid class="card-img-bottom" :src="image_placeholder"
|
<b-img fluid class="card-img-bottom" :src="image_placeholder" v-if="detailed && ((!hasRecipe && entry.entry.note === '') || (hasRecipe && entry.entry.recipe.image === null))"></b-img>
|
||||||
v-if="detailed && ((!hasRecipe && entry.entry.note === '') || (hasRecipe && entry.entry.recipe.image === null))"></b-img>
|
<div class="card-body p-1" v-if="detailed && entry.entry.recipe == null" :style="`background-color: ${background_color}`">
|
||||||
<div class="card-body p-1" v-if="detailed && entry.entry.recipe == null"
|
|
||||||
:style="`background-color: ${background_color}`">
|
|
||||||
<p>{{ entry.entry.note }}</p>
|
<p>{{ entry.entry.note }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="row p-1 flex-nowrap" v-if="!detailed" :style="`background-color: ${background_color}`">
|
<div class="row p-1 flex-nowrap" v-if="!detailed" :style="`background-color: ${background_color}`">
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
<span class="font-light text-center" v-if="entry.entry.meal_type.icon != null" v-b-tooltip.hover.left
|
<span class="font-light text-center" v-if="entry.entry.meal_type.icon != null" v-b-tooltip.hover.left :title="entry.entry.meal_type.name">{{ entry.entry.meal_type.icon }}</span>
|
||||||
:title=" entry.entry.meal_type.name">{{
|
<span class="font-light text-center" v-if="entry.entry.meal_type.icon == null" v-b-tooltip.hover.left :title="entry.entry.meal_type.name">❓</span>
|
||||||
entry.entry.meal_type.icon
|
|
||||||
}}</span>
|
|
||||||
<span class="font-light text-center" v-if="entry.entry.meal_type.icon == null" v-b-tooltip.hover.left
|
|
||||||
:title=" entry.entry.meal_type.name">❓</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-10 d-inline-block text-truncate" :style="`max-height:${item_height}`">
|
<div class="col-10 d-inline-block text-truncate" :style="`max-height:${item_height}`">
|
||||||
<span class="font-light">{{ title }}</span>
|
<span class="font-light">{{ title }}</span>
|
||||||
@ -61,31 +62,34 @@ export default {
|
|||||||
weekStartDate: Date,
|
weekStartDate: Date,
|
||||||
top: String,
|
top: String,
|
||||||
detailed: Boolean,
|
detailed: Boolean,
|
||||||
item_height: String
|
item_height: String,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
dateSelectionOrigin: null,
|
dateSelectionOrigin: null,
|
||||||
currentDragItem: null,
|
currentDragItem: null,
|
||||||
image_placeholder: window.IMAGE_PLACEHOLDER
|
image_placeholder: window.IMAGE_PLACEHOLDER,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log(this.value)
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
entry: function () {
|
entry: function () {
|
||||||
return this.value.originalItem
|
return this.value.originalItem
|
||||||
},
|
},
|
||||||
title: function () {
|
title: function () {
|
||||||
if (this.entry.entry.title != null && this.entry.entry.title !== '') {
|
if (this.entry.entry.title != null && this.entry.entry.title !== "") {
|
||||||
return this.entry.entry.title
|
return this.entry.entry.title
|
||||||
} else {
|
} else {
|
||||||
return this.entry.entry.recipe_name
|
return this.entry.entry.recipe_name
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hasRecipe: function () {
|
hasRecipe: function () {
|
||||||
return this.entry.entry.recipe != null;
|
return this.entry.entry.recipe != null
|
||||||
},
|
},
|
||||||
background_color: function () {
|
background_color: function () {
|
||||||
if (this.entry.entry.meal_type.color != null && this.entry.entry.meal_type.color !== '') {
|
if (this.entry.entry.meal_type.color != null && this.entry.entry.meal_type.color !== "") {
|
||||||
return this.entry.entry.meal_type.color
|
return this.entry.entry.meal_type.color
|
||||||
} else {
|
} else {
|
||||||
return "#fff"
|
return "#fff"
|
||||||
@ -109,15 +113,15 @@ export default {
|
|||||||
directives: {
|
directives: {
|
||||||
hover: {
|
hover: {
|
||||||
inserted: (el) => {
|
inserted: (el) => {
|
||||||
el.addEventListener('mouseenter', () => {
|
el.addEventListener("mouseenter", () => {
|
||||||
el.classList.add("shadow")
|
el.classList.add("shadow")
|
||||||
});
|
})
|
||||||
el.addEventListener('mouseleave', () => {
|
el.addEventListener("mouseleave", () => {
|
||||||
el.classList.remove("shadow")
|
el.classList.remove("shadow")
|
||||||
});
|
})
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<a class="dropdown-item" :href="`${resolveDjangoUrl('view_shopping')}?r=[${recipe.id},${servings_value}]`" v-if="recipe.internal" target="_blank" rel="noopener noreferrer">
|
<a class="dropdown-item" :href="`${resolveDjangoUrl('view_shopping')}?r=[${recipe.id},${servings_value}]`" v-if="recipe.internal" target="_blank" rel="noopener noreferrer">
|
||||||
<i class="fas fa-shopping-cart fa-fw"></i> {{ $t("Add_to_Shopping") }}
|
<i class="fas fa-shopping-cart fa-fw"></i> {{ $t("Add_to_Shopping") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item" v-if="recipe.internal" @click="addToShopping" href="#"> <i class="fas fa-shopping-cart fa-fw"></i> New {{ $t("create_shopping_new") }} </a>
|
<a class="dropdown-item" v-if="recipe.internal" @click="addToShopping" href="#"> <i class="fas fa-shopping-cart fa-fw"></i> {{ $t("create_shopping_new") }} </a>
|
||||||
|
|
||||||
<a class="dropdown-item" @click="createMealPlan" href="javascript:void(0);"><i class="fas fa-calendar fa-fw"></i> {{ $t("Add_to_Plan") }} </a>
|
<a class="dropdown-item" @click="createMealPlan" href="javascript:void(0);"><i class="fas fa-calendar fa-fw"></i> {{ $t("Add_to_Plan") }} </a>
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@
|
|||||||
"CategoryInstruction": "Drag categories to change the order categories appear in shopping list.",
|
"CategoryInstruction": "Drag categories to change the order categories appear in shopping list.",
|
||||||
"shopping_recent_days_desc": "Days of recent shopping list entries to display.",
|
"shopping_recent_days_desc": "Days of recent shopping list entries to display.",
|
||||||
"shopping_recent_days": "Recent Days",
|
"shopping_recent_days": "Recent Days",
|
||||||
"create_shopping_new": "NEW: Add to Shopping List",
|
"create_shopping_new": "Add to NEW Shopping List",
|
||||||
"download_pdf": "Download PDF",
|
"download_pdf": "Download PDF",
|
||||||
"download_csv": "Download CSV",
|
"download_csv": "Download CSV",
|
||||||
"csv_delim_help": "Delimiter to use for CSV exports.",
|
"csv_delim_help": "Delimiter to use for CSV exports.",
|
||||||
@ -274,5 +274,6 @@
|
|||||||
"copy_to_clipboard": "Copy to Clipboard",
|
"copy_to_clipboard": "Copy to Clipboard",
|
||||||
"csv_prefix_help": "Prefix to add when copying list to the clipboard.",
|
"csv_prefix_help": "Prefix to add when copying list to the clipboard.",
|
||||||
"csv_prefix_label": "List Prefix",
|
"csv_prefix_label": "List Prefix",
|
||||||
"copy_markdown_table": "Copy as Markdown Table"
|
"copy_markdown_table": "Copy as Markdown Table",
|
||||||
|
"in_shopping": "In Shopping List"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user