mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-04 05:39:00 -05:00
Fix after rebase
This commit is contained in:
@@ -1,217 +0,0 @@
|
||||
<template>
|
||||
<tr>
|
||||
<template v-if="ingredient.is_header">
|
||||
<td colspan="5" @click="done">
|
||||
<b>{{ ingredient.note }}</b>
|
||||
</td>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<td class="d-print-non" v-if="detailed && !add_shopping_mode" @click="done">
|
||||
<i class="far fa-check-circle text-success" v-if="ingredient.checked"></i>
|
||||
<i class="far fa-check-circle text-primary" v-if="!ingredient.checked"></i>
|
||||
</td>
|
||||
<td class="text-nowrap" @click="done">
|
||||
<span v-if="ingredient.amount !== 0" v-html="calculateAmount(ingredient.amount)"></span>
|
||||
</td>
|
||||
<td @click="done">
|
||||
<span v-if="ingredient.unit !== null && !ingredient.no_amount">{{ ingredient.unit.name }}</span>
|
||||
</td>
|
||||
<td @click="done">
|
||||
<template v-if="ingredient.food !== null">
|
||||
<!-- <i
|
||||
v-if="show_shopping && !add_shopping_mode"
|
||||
class="far fa-edit fa-sm px-1"
|
||||
@click="editFood()"
|
||||
></i> -->
|
||||
<a :href="resolveDjangoUrl('view_recipe', ingredient.food.recipe.id)" v-if="ingredient.food.recipe !== null" target="_blank" rel="noopener noreferrer">{{
|
||||
ingredient.food.name
|
||||
}}</a>
|
||||
<span v-if="ingredient.food.recipe === null">{{ ingredient.food.name }}</span>
|
||||
</template>
|
||||
</td>
|
||||
<td v-if="detailed && !show_shopping">
|
||||
<div v-if="ingredient.note">
|
||||
<span v-b-popover.hover="ingredient.note" class="d-print-none touchable">
|
||||
<i class="far fa-comment"></i>
|
||||
</span>
|
||||
<!-- v-if="ingredient.note.length > 15" -->
|
||||
<!-- <span v-else>-->
|
||||
<!-- {{ ingredient.note }}-->
|
||||
<!-- </span>-->
|
||||
|
||||
<div class="d-none d-print-block"><i class="far fa-comment-alt d-print-none"></i> {{ ingredient.note }}</div>
|
||||
</div>
|
||||
</td>
|
||||
<td v-else-if="show_shopping" class="text-right text-nowrap">
|
||||
<!-- in shopping mode and ingredient is not ignored -->
|
||||
<div v-if="!ingredient.food.ignore_shopping">
|
||||
<b-button
|
||||
class="btn text-decoration-none fas fa-shopping-cart px-2 user-select-none"
|
||||
variant="link"
|
||||
v-b-popover.hover.click.blur.html.top="{ title: ShoppingPopover, variant: 'outline-dark' }"
|
||||
:class="{
|
||||
'text-success': shopping_status === true,
|
||||
'text-muted': shopping_status === false,
|
||||
'text-warning': shopping_status === null,
|
||||
}"
|
||||
/>
|
||||
<span class="px-2">
|
||||
<input type="checkbox" class="align-middle" v-model="shop" @change="changeShopping" />
|
||||
</span>
|
||||
<on-hand-badge :item="ingredient.food" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- or in shopping mode and food is ignored: Shopping Badge bypasses linking ingredient to Recipe which would get ignored -->
|
||||
<shopping-badge :item="ingredient.food" :override_ignore="true" class="px-1" />
|
||||
<span class="px-2">
|
||||
<input type="checkbox" class="align-middle" disabled v-b-popover.hover.click.blur :title="$t('IgnoredFood', { food: ingredient.food.name })" />
|
||||
</span>
|
||||
<on-hand-badge :item="ingredient.food" />
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calculateAmount, ResolveUrlMixin, ApiMixin } from "@/utils/utils"
|
||||
import OnHandBadge from "@/components/Badges/OnHand"
|
||||
import ShoppingBadge from "@/components/Badges/Shopping"
|
||||
|
||||
export default {
|
||||
name: "Ingredient",
|
||||
components: { OnHandBadge, ShoppingBadge },
|
||||
props: {
|
||||
ingredient: Object,
|
||||
ingredient_factor: { type: Number, default: 1 },
|
||||
detailed: { type: Boolean, default: true },
|
||||
recipe_list: { type: Number }, // ShoppingListRecipe ID, to filter ShoppingStatus
|
||||
show_shopping: { type: Boolean, default: false },
|
||||
add_shopping_mode: { type: Boolean, default: false },
|
||||
shopping_list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
}, // list of unchecked ingredients in shopping list
|
||||
},
|
||||
mixins: [ResolveUrlMixin, ApiMixin],
|
||||
data() {
|
||||
return {
|
||||
checked: false,
|
||||
shopping_status: null,
|
||||
shopping_items: [],
|
||||
shop: false,
|
||||
dirty: undefined,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ShoppingListAndFilter: {
|
||||
immediate: true,
|
||||
handler(newVal, oldVal) {
|
||||
let filtered_list = this.shopping_list
|
||||
// if a recipe list is provided, filter the shopping list
|
||||
if (this.recipe_list) {
|
||||
filtered_list = filtered_list.filter((x) => x.list_recipe == this.recipe_list)
|
||||
}
|
||||
// how many ShoppingListRecipes are there for this recipe?
|
||||
let count_shopping_recipes = [...new Set(filtered_list.map((x) => x.list_recipe))].length
|
||||
let count_shopping_ingredient = filtered_list.filter((x) => x.ingredient == this.ingredient.id).length
|
||||
|
||||
if (count_shopping_recipes > 1) {
|
||||
this.shop = false // don't check any boxes until user selects a shopping list to edit
|
||||
if (count_shopping_ingredient >= 1) {
|
||||
this.shopping_status = true
|
||||
} else if (this.ingredient.food.shopping) {
|
||||
this.shopping_status = null // food is in the shopping list, just not for this ingredient/recipe
|
||||
} else {
|
||||
this.shopping_status = false // food is not in any shopping list
|
||||
}
|
||||
} else {
|
||||
// mark checked if the food is in the shopping list for this ingredient/recipe
|
||||
if (count_shopping_ingredient >= 1) {
|
||||
// ingredient is in this shopping list
|
||||
this.shop = true
|
||||
this.shopping_status = true
|
||||
} else if (count_shopping_ingredient == 0 && this.ingredient.food.shopping) {
|
||||
// food is in the shopping list, just not for this ingredient/recipe
|
||||
this.shop = false
|
||||
this.shopping_status = null
|
||||
} else {
|
||||
// the food is not in any shopping list
|
||||
this.shop = false
|
||||
this.shopping_status = false
|
||||
}
|
||||
}
|
||||
// if we are in add shopping mode start with all checks marked
|
||||
if (this.add_shopping_mode) {
|
||||
this.shop = !this.ingredient.food.on_hand && !this.ingredient.food.ignore_shopping && !this.ingredient.food.recipe
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
ShoppingListAndFilter() {
|
||||
// hack to watch the shopping list and the recipe list at the same time
|
||||
return this.shopping_list.map((x) => x.id).join(this.recipe_list)
|
||||
},
|
||||
ShoppingPopover() {
|
||||
if (this.shopping_status == false) {
|
||||
return this.$t("NotInShopping", { food: this.ingredient.food.name })
|
||||
} else {
|
||||
let list = this.shopping_list.filter((x) => x.food.id == this.ingredient.food.id)
|
||||
let category = this.$t("Category") + ": " + this.ingredient?.food?.supermarket_category?.name ?? this.$t("Undefined")
|
||||
let popover = []
|
||||
|
||||
list.forEach((x) => {
|
||||
popover.push(
|
||||
[
|
||||
"<tr style='border-bottom: 1px solid #ccc'>",
|
||||
"<td style='padding: 3px;'><em>",
|
||||
x?.recipe_mealplan?.name ?? "",
|
||||
"</em></td>",
|
||||
"<td style='padding: 3px;'>",
|
||||
x?.amount ?? "",
|
||||
"</td>",
|
||||
"<td style='padding: 3px;'>",
|
||||
x?.unit?.name ?? "" + "</td>",
|
||||
"<td style='padding: 3px;'>",
|
||||
x?.food?.name ?? "",
|
||||
"</td></tr>",
|
||||
].join("")
|
||||
)
|
||||
})
|
||||
return "<table class='table-small'><th colspan='4'>" + category + "</th>" + popover.join("") + "</table>"
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
calculateAmount: function(x) {
|
||||
return calculateAmount(x, this.ingredient_factor)
|
||||
},
|
||||
// sends parent recipe ingredient to notify complete has been toggled
|
||||
done: function() {
|
||||
this.$emit("checked-state-changed", this.ingredient)
|
||||
},
|
||||
// sends true/false to parent to save all ingredient shopping updates as a batch
|
||||
changeShopping: function() {
|
||||
this.$emit("add-to-shopping", { item: this.ingredient, add: this.shop })
|
||||
},
|
||||
editFood: function() {
|
||||
console.log("edit the food")
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* increase size of hover/touchable space without changing spacing */
|
||||
.touchable {
|
||||
padding-right: 2em;
|
||||
padding-left: 2em;
|
||||
margin-right: -2em;
|
||||
margin-left: -2em;
|
||||
}
|
||||
</style>
|
||||
@@ -19,11 +19,6 @@
|
||||
</td>
|
||||
<td @click="done">
|
||||
<template v-if="ingredient.food !== null">
|
||||
<!-- <i
|
||||
v-if="show_shopping && !add_shopping_mode"
|
||||
class="far fa-edit fa-sm px-1"
|
||||
@click="editFood()"
|
||||
></i> -->
|
||||
<a :href="resolveDjangoUrl('view_recipe', ingredient.food.recipe.id)" v-if="ingredient.food.recipe !== null" target="_blank" rel="noopener noreferrer">{{
|
||||
ingredient.food.name
|
||||
}}</a>
|
||||
@@ -35,10 +30,6 @@
|
||||
<span v-b-popover.hover="ingredient.note" class="d-print-none touchable">
|
||||
<i class="far fa-comment"></i>
|
||||
</span>
|
||||
<!-- v-if="ingredient.note.length > 15" -->
|
||||
<!-- <span v-else>-->
|
||||
<!-- {{ ingredient.note }}-->
|
||||
<!-- </span>-->
|
||||
|
||||
<div class="d-none d-print-block"><i class="far fa-comment-alt d-print-none"></i> {{ ingredient.note }}</div>
|
||||
</div>
|
||||
@@ -80,7 +71,7 @@ import OnHandBadge from "@/components/Badges/OnHand"
|
||||
import ShoppingBadge from "@/components/Badges/Shopping"
|
||||
|
||||
export default {
|
||||
name: "Ingredient",
|
||||
name: "IngredientComponent",
|
||||
components: { OnHandBadge, ShoppingBadge },
|
||||
props: {
|
||||
ingredient: Object,
|
||||
|
||||
@@ -12,6 +12,17 @@
|
||||
<b-badge pill variant="secondary" class="mt-1 font-weight-normal"><i class="fa fa-pause"></i> {{ recipe.waiting_time }} {{ $t("min") }} </b-badge>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-img-overlay w-50 d-flex flex-column justify-content-left float-left text-left pt-2"
|
||||
v-if="recipe.working_time !== 0 || recipe.waiting_time !== 0">
|
||||
<b-badge pill variant="light" class="mt-1 font-weight-normal" v-if="recipe.working_time !== 0"><i class="fa fa-clock"></i>
|
||||
{{ recipe.working_time }} {{ $t('min') }}
|
||||
</b-badge>
|
||||
<b-badge pill variant="secondary" class="mt-1 font-weight-normal" v-if="recipe.waiting_time !== 0"><i class="fa fa-pause"></i>
|
||||
{{ recipe.waiting_time }} {{ $t('min') }}
|
||||
</b-badge>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<b-card-body class="p-4">
|
||||
<h6>
|
||||
@@ -34,7 +45,7 @@
|
||||
</template>
|
||||
<p class="mt-1">
|
||||
<last-cooked :recipe="recipe"></last-cooked>
|
||||
<keywords :recipe="recipe" style="margin-top: 4px"></keywords>
|
||||
<keywords-component :recipe="recipe" style="margin-top: 4px"></keywords-component>
|
||||
</p>
|
||||
<transition name="fade" mode="in-out">
|
||||
<div class="row mt-3" v-if="detailed">
|
||||
@@ -47,10 +58,6 @@
|
||||
</transition>
|
||||
|
||||
<b-badge pill variant="info" v-if="!recipe.internal">{{ $t("External") }}</b-badge>
|
||||
<!-- <b-badge pill variant="success"
|
||||
v-if="Date.parse(recipe.created_at) > new Date(Date.now() - (7 * (1000 * 60 * 60 * 24)))">
|
||||
{{ $t('New') }}
|
||||
</b-badge> -->
|
||||
</template>
|
||||
<template v-else>{{ meal_plan.note }}</template>
|
||||
</b-card-text>
|
||||
@@ -62,7 +69,7 @@
|
||||
|
||||
<script>
|
||||
import RecipeContextMenu from "@/components/ContextMenu/RecipeContextMenu"
|
||||
import Keywords from "@/components/Keywords"
|
||||
import KeywordsComponent from "@/components/KeywordsComponent";
|
||||
import { resolveDjangoUrl, ResolveUrlMixin } from "@/utils/utils"
|
||||
import RecipeRating from "@/components/RecipeRating"
|
||||
import moment from "moment/moment"
|
||||
@@ -75,7 +82,7 @@ Vue.prototype.moment = moment
|
||||
export default {
|
||||
name: "RecipeCard",
|
||||
mixins: [ResolveUrlMixin],
|
||||
components: { LastCooked, RecipeRating, Keywords, RecipeContextMenu, IngredientsCard },
|
||||
components: { LastCooked, RecipeRating, KeywordsComponent, RecipeContextMenu, IngredientsCard },
|
||||
props: {
|
||||
recipe: Object,
|
||||
meal_plan: Object,
|
||||
|
||||
@@ -1,217 +1,200 @@
|
||||
<template>
|
||||
<div>
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<hr />
|
||||
|
||||
<template v-if="step.type === 'TEXT' || step.type === 'RECIPE'">
|
||||
<div class="row" v-if="recipe.steps.length > 1">
|
||||
<div class="col col-md-8">
|
||||
<h5 class="text-primary">
|
||||
<template v-if="step.name">{{ step.name }}</template>
|
||||
<template v-else>{{ $t('Step') }} {{ index + 1 }}</template>
|
||||
<small style="margin-left: 4px" class="text-muted" v-if="step.time !== 0"><i class="fas fa-user-clock"></i>
|
||||
{{ step.time }} {{ $t('min') }}
|
||||
|
||||
</small>
|
||||
<small v-if="start_time !== ''" class="d-print-none">
|
||||
<b-link :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#">
|
||||
{{ moment(start_time).add(step.time_offset, 'minutes').format('HH:mm') }}
|
||||
</b-link>
|
||||
</small>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col col-md-4" style="text-align: right">
|
||||
<b-button @click="details_visible = !details_visible" style="border: none; background: none"
|
||||
class="shadow-none d-print-none"
|
||||
:class="{ 'text-primary': details_visible, 'text-success': !details_visible}">
|
||||
<i class="far fa-check-circle"></i>
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="step.type === 'TEXT'">
|
||||
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="row">
|
||||
<div class="col col-md-4"
|
||||
v-if="step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)">
|
||||
<table class="table table-sm">
|
||||
<ingredients-card
|
||||
:steps="[step]"
|
||||
:ingredient_factor="ingredient_factor"
|
||||
@checked-state-changed="$emit('checked-state-changed', $event)"
|
||||
/>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col" :class="{ 'col-md-8': recipe.steps.length > 1, 'col-md-12': recipe.steps.length <= 1,}">
|
||||
<compile-component :code="step.ingredients_markdown"
|
||||
:ingredient_factor="ingredient_factor"></compile-component>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</template>
|
||||
|
||||
<template v-if="step.type === 'TIME' || step.type === 'FILE'">
|
||||
<div class="row">
|
||||
<div class="col-md-8 offset-md-2" style="text-align: center">
|
||||
<h4 class="text-primary">
|
||||
<template v-if="step.name">{{ step.name }}</template>
|
||||
<template v-else>{{ $t('Step') }} {{ index + 1 }}</template>
|
||||
</h4>
|
||||
<span style="margin-left: 4px" class="text-muted" v-if="step.time !== 0"><i class="fa fa-stopwatch"></i>
|
||||
{{ step.time }} {{ $t('min') }}</span>
|
||||
<b-link class="d-print-none" :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#"
|
||||
v-if="start_time !== ''">
|
||||
{{ moment(start_time).add(step.time_offset, 'minutes').format('HH:mm') }}
|
||||
</b-link>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2" style="text-align: right">
|
||||
<b-button @click="details_visible = !details_visible" style="border: none; background: none"
|
||||
class="shadow-none d-print-none"
|
||||
:class="{ 'text-primary': details_visible, 'text-success': !details_visible}">
|
||||
<i class="far fa-check-circle"></i>
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="row" v-if="step.instruction !== ''">
|
||||
<div class="col col-md-12" style="text-align: center">
|
||||
<compile-component :code="step.ingredients_markdown"
|
||||
:ingredient_factor="ingredient_factor"></compile-component>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</template>
|
||||
|
||||
<div class="row" style="text-align: center">
|
||||
<div class="col col-md-12">
|
||||
<template v-if="step.file !== null">
|
||||
<div
|
||||
v-if="step.file.file.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg') || recipe.file_path.includes('.gif')">
|
||||
<img :src="step.file.file" style="max-width: 50vw; max-height: 50vh">
|
||||
</div>
|
||||
<div v-else>
|
||||
<a :href="step.file.file" target="_blank" rel="noreferrer nofollow">{{ $t('Download') }} {{
|
||||
$t('File')
|
||||
}}</a>
|
||||
</div>
|
||||
<template v-if="step.type === 'TEXT' || step.type === 'RECIPE'">
|
||||
<div class="row" v-if="recipe.steps.length > 1">
|
||||
<div class="col col-md-8">
|
||||
<h5 class="text-primary">
|
||||
<template v-if="step.name">{{ step.name }}</template>
|
||||
<template v-else>{{ $t("Step") }} {{ index + 1 }}</template>
|
||||
<small style="margin-left: 4px" class="text-muted" v-if="step.time !== 0"><i class="fas fa-user-clock"></i> {{ step.time }} {{ $t("min") }} </small>
|
||||
<small v-if="start_time !== ''" class="d-print-none">
|
||||
<b-link :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#">
|
||||
{{
|
||||
moment(start_time)
|
||||
.add(step.time_offset, "minutes")
|
||||
.format("HH:mm")
|
||||
}}
|
||||
</b-link>
|
||||
</small>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col col-md-4" style="text-align: right">
|
||||
<b-button
|
||||
@click="details_visible = !details_visible"
|
||||
style="border: none; background: none"
|
||||
class="shadow-none d-print-none"
|
||||
:class="{ 'text-primary': details_visible, 'text-success': !details_visible }"
|
||||
>
|
||||
<i class="far fa-check-circle"></i>
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="step.type === 'TEXT'">
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="row">
|
||||
<div class="col col-md-4" v-if="step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)">
|
||||
<table class="table table-sm">
|
||||
<ingredients-card :steps="[step]" :ingredient_factor="ingredient_factor" @checked-state-changed="$emit('checked-state-changed', $event)" />
|
||||
</table>
|
||||
</div>
|
||||
<div class="col" :class="{ 'col-md-8': recipe.steps.length > 1, 'col-md-12': recipe.steps.length <= 1 }">
|
||||
<compile-component :code="step.ingredients_markdown" :ingredient_factor="ingredient_factor"></compile-component>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</template>
|
||||
|
||||
<div class="card" v-if="step.type === 'RECIPE' && step.step_recipe_data !== null">
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
<a :href="resolveDjangoUrl('view_recipe',step.step_recipe_data.id)">{{ step.step_recipe_data.name }}</a>
|
||||
</h2>
|
||||
<div v-for="(sub_step, index) in step.step_recipe_data.steps" v-bind:key="`substep_${sub_step.id}`">
|
||||
<Step :recipe="step.step_recipe_data" :step="sub_step" :ingredient_factor="ingredient_factor" :index="index"
|
||||
:start_time="start_time" :force_ingredients="true"></Step>
|
||||
<template v-if="step.type === 'TIME' || step.type === 'FILE'">
|
||||
<div class="row">
|
||||
<div class="col-md-8 offset-md-2" style="text-align: center">
|
||||
<h4 class="text-primary">
|
||||
<template v-if="step.name">{{ step.name }}</template>
|
||||
<template v-else>{{ $t("Step") }} {{ index + 1 }}</template>
|
||||
</h4>
|
||||
<span style="margin-left: 4px" class="text-muted" v-if="step.time !== 0"><i class="fa fa-stopwatch"></i> {{ step.time }} {{ $t("min") }}</span>
|
||||
<b-link class="d-print-none" :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#" v-if="start_time !== ''">
|
||||
{{
|
||||
moment(start_time)
|
||||
.add(step.time_offset, "minutes")
|
||||
.format("HH:mm")
|
||||
}}
|
||||
</b-link>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2" style="text-align: right">
|
||||
<b-button
|
||||
@click="details_visible = !details_visible"
|
||||
style="border: none; background: none"
|
||||
class="shadow-none d-print-none"
|
||||
:class="{ 'text-primary': details_visible, 'text-success': !details_visible }"
|
||||
>
|
||||
<i class="far fa-check-circle"></i>
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="row" v-if="step.instruction !== ''">
|
||||
<div class="col col-md-12" style="text-align: center">
|
||||
<compile-component :code="step.ingredients_markdown" :ingredient_factor="ingredient_factor"></compile-component>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</template>
|
||||
|
||||
<div class="row" style="text-align: center">
|
||||
<div class="col col-md-12">
|
||||
<template v-if="step.file !== null">
|
||||
<div v-if="step.file.file.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg') || recipe.file_path.includes('.gif')">
|
||||
<img :src="step.file.file" style="max-width: 50vw; max-height: 50vh" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<a :href="step.file.file" target="_blank" rel="noreferrer nofollow">{{ $t("Download") }} {{ $t("File") }}</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="start_time !== ''">
|
||||
<b-popover
|
||||
:target="`id_reactive_popover_${step.id}`"
|
||||
triggers="click"
|
||||
placement="bottom"
|
||||
:ref="`id_reactive_popover_${step.id}`"
|
||||
:title="$t('Step start time')">
|
||||
<div>
|
||||
<b-form-group
|
||||
label="Time"
|
||||
label-for="popover-input-1"
|
||||
label-cols="3"
|
||||
class="mb-1">
|
||||
<b-form-input
|
||||
type="datetime-local"
|
||||
id="popover-input-1"
|
||||
v-model.datetime-local="set_time_input"
|
||||
size="sm"
|
||||
></b-form-input>
|
||||
</b-form-group>
|
||||
<div class="card" v-if="step.type === 'RECIPE' && step.step_recipe_data !== null">
|
||||
<b-collapse id="collapse-1" v-model="details_visible">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
<a :href="resolveDjangoUrl('view_recipe', step.step_recipe_data.id)">{{ step.step_recipe_data.name }}</a>
|
||||
</h2>
|
||||
<div v-for="(sub_step, index) in step.step_recipe_data.steps" v-bind:key="`substep_${sub_step.id}`">
|
||||
<Step
|
||||
:recipe="step.step_recipe_data"
|
||||
:step="sub_step"
|
||||
:ingredient_factor="ingredient_factor"
|
||||
:index="index"
|
||||
:start_time="start_time"
|
||||
:force_ingredients="true"
|
||||
></Step>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 1vh">
|
||||
<div class="col-12" style="text-align: right">
|
||||
<b-button @click="closePopover" size="sm" variant="secondary" style="margin-right:8px">Cancel</b-button>
|
||||
<b-button @click="updateTime" size="sm" variant="primary">Ok</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</b-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="start_time !== ''">
|
||||
<b-popover :target="`id_reactive_popover_${step.id}`" triggers="click" placement="bottom" :ref="`id_reactive_popover_${step.id}`" :title="$t('Step start time')">
|
||||
<div>
|
||||
<b-form-group label="Time" label-for="popover-input-1" label-cols="3" class="mb-1">
|
||||
<b-form-input type="datetime-local" id="popover-input-1" v-model.datetime-local="set_time_input" size="sm"></b-form-input>
|
||||
</b-form-group>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 1vh">
|
||||
<div class="col-12" style="text-align: right">
|
||||
<b-button @click="closePopover" size="sm" variant="secondary" style="margin-right:8px">Cancel</b-button>
|
||||
<b-button @click="updateTime" size="sm" variant="primary">Ok</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</b-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calculateAmount } from "@/utils/utils"
|
||||
|
||||
import {calculateAmount} from "@/utils/utils";
|
||||
import { GettextMixin } from "@/utils/utils"
|
||||
|
||||
import {GettextMixin} from "@/utils/utils";
|
||||
|
||||
import CompileComponent from "@/components/CompileComponent";
|
||||
import IngredientsCard from "@/components/IngredientsCard";
|
||||
import Vue from "vue";
|
||||
import moment from "moment";
|
||||
import {ResolveUrlMixin} from "@/utils/utils";
|
||||
import IngredientComponent from "@/components/IngredientComponent";
|
||||
import CompileComponent from "@/components/CompileComponent"
|
||||
import IngredientsCard from "@/components/IngredientsCard"
|
||||
import Vue from "vue"
|
||||
import moment from "moment"
|
||||
import { ResolveUrlMixin } from "@/utils/utils"
|
||||
|
||||
Vue.prototype.moment = moment
|
||||
|
||||
export default {
|
||||
name: 'StepComponent',
|
||||
mixins: [
|
||||
GettextMixin,
|
||||
ResolveUrlMixin,
|
||||
],
|
||||
components: { CompileComponent, IngredientsCard},
|
||||
props: {
|
||||
step: Object,
|
||||
ingredient_factor: Number,
|
||||
index: Number,
|
||||
recipe: Object,
|
||||
start_time: String,
|
||||
force_ingredients: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
details_visible: true,
|
||||
set_time_input: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.set_time_input = moment(this.start_time).add(this.step.time_offset, 'minutes').format('yyyy-MM-DDTHH:mm')
|
||||
},
|
||||
methods: {
|
||||
calculateAmount: function (x) {
|
||||
// used by the jinja2 template
|
||||
return calculateAmount(x, this.ingredient_factor)
|
||||
name: "StepComponent",
|
||||
mixins: [GettextMixin, ResolveUrlMixin],
|
||||
components: { CompileComponent, IngredientsCard },
|
||||
props: {
|
||||
step: Object,
|
||||
ingredient_factor: Number,
|
||||
index: Number,
|
||||
recipe: Object,
|
||||
start_time: String,
|
||||
force_ingredients: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
updateTime: function () {
|
||||
let new_start_time = moment(this.set_time_input).add(this.step.time_offset * -1, 'minutes').format('yyyy-MM-DDTHH:mm')
|
||||
data() {
|
||||
return {
|
||||
details_visible: true,
|
||||
set_time_input: "",
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.set_time_input = moment(this.start_time)
|
||||
.add(this.step.time_offset, "minutes")
|
||||
.format("yyyy-MM-DDTHH:mm")
|
||||
},
|
||||
methods: {
|
||||
calculateAmount: function(x) {
|
||||
// used by the jinja2 template
|
||||
return calculateAmount(x, this.ingredient_factor)
|
||||
},
|
||||
updateTime: function() {
|
||||
let new_start_time = moment(this.set_time_input)
|
||||
.add(this.step.time_offset * -1, "minutes")
|
||||
.format("yyyy-MM-DDTHH:mm")
|
||||
|
||||
this.$emit('update-start-time', new_start_time)
|
||||
this.closePopover()
|
||||
this.$emit("update-start-time", new_start_time)
|
||||
this.closePopover()
|
||||
},
|
||||
closePopover: function() {
|
||||
this.$refs[`id_reactive_popover_${this.step.id}`].$emit("close")
|
||||
},
|
||||
openPopover: function() {
|
||||
this.$refs[`id_reactive_popover_${this.step.id}`].$emit("open")
|
||||
},
|
||||
},
|
||||
closePopover: function () {
|
||||
this.$refs[`id_reactive_popover_${this.step.id}`].$emit('close')
|
||||
},
|
||||
openPopover: function () {
|
||||
this.$refs[`id_reactive_popover_${this.step.id}`].$emit('open')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user