step header rendering
This commit is contained in:
parent
1e2d7f77af
commit
1619d4894c
18
cookbook/migrations/0072_step_show_as_header.py
Normal file
18
cookbook/migrations/0072_step_show_as_header.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2020-07-02 10:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cookbook', '0071_auto_20200701_2048'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='step',
|
||||||
|
name='show_as_header',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
@ -168,6 +168,7 @@ class Step(models.Model):
|
|||||||
ingredients = models.ManyToManyField(Ingredient, blank=True)
|
ingredients = models.ManyToManyField(Ingredient, blank=True)
|
||||||
time = models.IntegerField(default=0, blank=True)
|
time = models.IntegerField(default=0, blank=True)
|
||||||
order = models.IntegerField(default=0)
|
order = models.IntegerField(default=0)
|
||||||
|
show_as_header = models.BooleanField(default=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['order', 'pk']
|
ordering = ['order', 'pk']
|
||||||
|
@ -116,7 +116,7 @@ class StepSerializer(WritableNestedModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Step
|
model = Step
|
||||||
fields = '__all__'
|
fields = ('id', 'name', 'type', 'instruction', 'ingredients', 'time', 'order', 'show_as_header')
|
||||||
|
|
||||||
|
|
||||||
class RecipeSerializer(WritableNestedModelSerializer):
|
class RecipeSerializer(WritableNestedModelSerializer):
|
||||||
|
@ -109,11 +109,22 @@
|
|||||||
<button class="dropdown-item" @click="removeStep(step)"><i
|
<button class="dropdown-item" @click="removeStep(step)"><i
|
||||||
class="fa fa-trash fa-fw"></i> {% trans 'Delete Step' %}</button>
|
class="fa fa-trash fa-fw"></i> {% trans 'Delete Step' %}</button>
|
||||||
|
|
||||||
|
<button type="button" class="dropdown-item"
|
||||||
|
v-if="!step.show_as_header"
|
||||||
|
@click="step.show_as_header = true"><i
|
||||||
|
class="fas fa-eye fa-fw"></i> {% trans 'Show as header' %}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="dropdown-item"
|
||||||
|
v-if="step.show_as_header"
|
||||||
|
@click="step.show_as_header = false"><i
|
||||||
|
class="fas fa-eye-slash fa-fw"></i> {% trans 'Hide as header' %}
|
||||||
|
</button>
|
||||||
|
|
||||||
<button class="dropdown-item" @click="moveStep(step, (step_index - 1))"
|
<button class="dropdown-item" @click="moveStep(step, (step_index - 1))"
|
||||||
v-if="step_index > 0">
|
v-if="step_index > 0">
|
||||||
<i class="fa fa-arrow-up fa-fw"></i> {% trans 'Move Up' %}
|
<i class="fa fa-arrow-up fa-fw"></i> {% trans 'Move Up' %}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="dropdown-item"
|
<button class="dropdown-item"
|
||||||
@click="moveStep(step, (step_index + 1))"
|
@click="moveStep(step, (step_index + 1))"
|
||||||
v-if="step_index != (recipe.steps.length - 1)">
|
v-if="step_index != (recipe.steps.length - 1)">
|
||||||
@ -350,7 +361,7 @@
|
|||||||
<button type="button" @click="addStep()"
|
<button type="button" @click="addStep()"
|
||||||
class="btn btn-primary btn-block shadow-none">{% trans 'Add Step' %}</button>
|
class="btn btn-primary btn-block shadow-none">{% trans 'Add Step' %}</button>
|
||||||
|
|
||||||
<a href="{% url 'view_recipe' recipe.pk %}" @click="addStep()"
|
<a href="{% url 'view_recipe' recipe.pk %}"
|
||||||
class="btn btn-secondary btn-block shadow-none">{% trans 'View Recipe' %}</a> <br/>
|
class="btn btn-secondary btn-block shadow-none">{% trans 'View Recipe' %}</a> <br/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
<br/>
|
<br/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="row" v-if="recipe">
|
<div class="row" v-if="recipe && has_ingredients">
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2">
|
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -116,7 +116,8 @@
|
|||||||
<div class="col col-md-3">
|
<div class="col col-md-3">
|
||||||
|
|
||||||
<div class="input-group d-print-none">
|
<div class="input-group d-print-none">
|
||||||
<input type="number" value="1" maxlength="3" class="form-control" v-model="ingredient_factor"/>
|
<input type="number" value="1" maxlength="3" class="form-control"
|
||||||
|
v-model="ingredient_factor"/>
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<span class="input-group-text"><i class="fas fa-calculator"></i></span>
|
<span class="input-group-text"><i class="fas fa-calculator"></i></span>
|
||||||
</div>
|
</div>
|
||||||
@ -124,80 +125,87 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<table class="table table-sm">
|
<div class="row">
|
||||||
<template v-for="s in recipe.steps">
|
<div class="col-md-12">
|
||||||
<template v-for="i in s.ingredients">
|
<table class="table table-sm">
|
||||||
<template v-if="i.is_header">
|
<template v-for="s in recipe.steps">
|
||||||
<tr>
|
<template v-if="s.name != '' && s.show_as_header && s.ingredients.length > 0">
|
||||||
<td style="padding-top: 8px!important; ">
|
<tr>
|
||||||
<b>[[i.note]]</b>
|
<td style="padding-top: 8px!important; ">
|
||||||
</td>
|
<b>[[s.name]]</b>
|
||||||
<td>
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template v-for="i in s.ingredients">
|
||||||
|
<template v-if="i.is_header">
|
||||||
|
<tr>
|
||||||
|
<td style="padding-top: 8px!important; ">
|
||||||
|
<b>[[i.note]]</b>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<tr>
|
||||||
|
<td style="vertical-align: middle!important;">
|
||||||
|
<div class="pretty p-default p-curve">
|
||||||
|
<input type="checkbox"/>
|
||||||
|
<div class="state p-success">
|
||||||
|
<label>
|
||||||
|
<template v-if="i.no_amount">
|
||||||
|
<span>⁣</span>
|
||||||
|
</template>
|
||||||
|
<template v-if="!i.no_amount && i.unit">
|
||||||
|
<span>[[roundDecimals(i.amount * ingredient_factor)]]</span>
|
||||||
|
[[i.unit.name]]
|
||||||
|
</template>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td style="vertical-align: middle!important;">
|
||||||
</tr>
|
<template v-if="i.food && i.food.recipe">
|
||||||
|
<a v-bind:href='"{% url 'view_recipe' 12345 %}".replace(/12345/, i.food.recipe)'
|
||||||
|
target="_blank" rel="noopener noreferrer">[[i.food.name]]</a>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="i.food">
|
||||||
|
[[i.food.name]]
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
<td style="vertical-align: middle!important;">
|
||||||
|
<template v-if="i.note">
|
||||||
|
<a class="btn btn-light btn-sm d-print-none" tabindex="-1"
|
||||||
|
data-toggle="popover"
|
||||||
|
data-placement="right" data-html="true" data-trigger="focus"
|
||||||
|
v-bind:data-content="i.note">
|
||||||
|
<i class="fas fa-info"></i>
|
||||||
|
</a>
|
||||||
|
<div class="d-none d-print-block">
|
||||||
|
<i class="far fa-comment-alt"></i> [[i.note]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: middle!important;">
|
|
||||||
<div class="pretty p-default p-curve">
|
|
||||||
<input type="checkbox"/>
|
|
||||||
<div class="state p-success">
|
|
||||||
<label>
|
|
||||||
<template v-if="i.no_amount">
|
|
||||||
<span>⁣</span>
|
|
||||||
</template>
|
|
||||||
<template v-if="!i.no_amount && i.unit">
|
|
||||||
<span>[[roundDecimals(i.amount * ingredient_factor)]]</span>
|
|
||||||
[[i.unit.name]]
|
|
||||||
</template>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td style="vertical-align: middle!important;">
|
|
||||||
<template v-if="i.food && i.food.recipe">
|
|
||||||
<a v-bind:href='"{% url 'view_recipe' 12345 %}".replace(/12345/, i.food.recipe)'
|
|
||||||
target="_blank" rel="noopener noreferrer">[[i.food.name]]</a>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="i.food">
|
|
||||||
[[i.food.name]]
|
|
||||||
</template>
|
|
||||||
</td>
|
|
||||||
<td style="vertical-align: middle!important;">
|
|
||||||
<template v-if="i.note">
|
|
||||||
<a class="btn btn-light btn-sm d-print-none" tabindex="-1"
|
|
||||||
data-toggle="popover"
|
|
||||||
data-placement="right" data-html="true" data-trigger="focus"
|
|
||||||
v-bind:data-content="i.note">
|
|
||||||
<i class="fas fa-info"></i>
|
|
||||||
</a>
|
|
||||||
<div class="d-none d-print-block">
|
|
||||||
<i class="far fa-comment-alt"></i> [[i.note]]
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Bottom border -->
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bottom border -->
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% if recipe.image %}
|
{% if recipe.image %}
|
||||||
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2" style="text-align: center">
|
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2" style="text-align: center">
|
||||||
<img class="img img-fluid rounded" src="{{ recipe.image.url }}" style="max-height: 30vh;"
|
<img class="img img-fluid rounded" src="{{ recipe.image.url }}" style="max-height: 30vh;"
|
||||||
@ -207,41 +215,116 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if ingredients or recipe.image %}
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div style="font-size: large">
|
<div style="font-size: large;">
|
||||||
{% for s in recipe.steps.all %}
|
{% for s in recipe.steps.all %}
|
||||||
{% if recipe.steps.all|length > 1 %}
|
<div style="margin-top: 1vh" class="card">
|
||||||
<div class="row">
|
<div class="card-body">
|
||||||
<div class="col-md-12 text-muted">
|
{% if recipe.steps.all|length > 1 %}
|
||||||
<small>
|
<div class="card-title">
|
||||||
{% if s.type == 'TEXT' %}
|
|
||||||
<i class="fas fa-paragraph fa-fw"></i>
|
|
||||||
{% elif s.type == 'TIME' %}
|
|
||||||
<i class="fas fa-clock fa-fw"></i>
|
|
||||||
{% endif %}
|
|
||||||
{% if s.name %}{{ s.name }}{% else %}{% trans 'Step' %}
|
|
||||||
{{ forloop.counter }}{% endif %}
|
|
||||||
{% if s.type == 'TIME' %}
|
|
||||||
- {{ s.time }} {% trans 'Minutes' %}
|
|
||||||
{% endif %}
|
|
||||||
</small>
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 text-muted">
|
||||||
|
|
||||||
|
{% if s.type == 'TEXT' %}
|
||||||
|
<i class="fas fa-paragraph fa-fw"></i>
|
||||||
|
{% elif s.type == 'TIME' %}
|
||||||
|
<i class="fas fa-clock fa-fw"></i>
|
||||||
|
{% endif %}
|
||||||
|
{% if s.name %}{{ s.name }}{% else %}{% trans 'Step' %}
|
||||||
|
{{ forloop.counter }}{% endif %}
|
||||||
|
{% if s.type == 'TIME' %}
|
||||||
|
- {{ s.time }} {% trans 'Minutes' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" v-if="recipe && recipe.steps[{{ forloop.counter0 }}].ingredients.length > 0"
|
||||||
|
style="margin-top: 1vh">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<template v-for="i in recipe.steps[{{ forloop.counter0 }}].ingredients">
|
||||||
|
|
||||||
|
<template v-if="i.is_header">
|
||||||
|
<tr>
|
||||||
|
<td style="padding-top: 8px!important; ">
|
||||||
|
<b>[[i.note]]</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<tr>
|
||||||
|
<td style="vertical-align: middle!important;">
|
||||||
|
<div class="pretty p-default p-curve">
|
||||||
|
<input type="checkbox"/>
|
||||||
|
<div class="state p-success">
|
||||||
|
<label>
|
||||||
|
<template v-if="i.no_amount">
|
||||||
|
<span>⁣</span>
|
||||||
|
</template>
|
||||||
|
<template v-if="!i.no_amount && i.unit">
|
||||||
|
<span>[[roundDecimals(i.amount * ingredient_factor)]]</span>
|
||||||
|
[[i.unit.name]]
|
||||||
|
</template>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td style="vertical-align: middle!important;">
|
||||||
|
<template v-if="i.food && i.food.recipe">
|
||||||
|
<a v-bind:href='"{% url 'view_recipe' 12345 %}".replace(/12345/, i.food.recipe)'
|
||||||
|
target="_blank" rel="noopener noreferrer">[[i.food.name]]</a>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="i.food">
|
||||||
|
[[i.food.name]]
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
<td style="vertical-align: middle!important;">
|
||||||
|
<template v-if="i.note">
|
||||||
|
<a class="btn btn-light btn-sm d-print-none" tabindex="-1"
|
||||||
|
data-toggle="popover"
|
||||||
|
data-placement="right" data-html="true" data-trigger="focus"
|
||||||
|
v-bind:data-content="i.note">
|
||||||
|
<i class="fas fa-info"></i>
|
||||||
|
</a>
|
||||||
|
<div class="d-none d-print-block">
|
||||||
|
<i class="far fa-comment-alt"></i> [[i.note]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<!-- Bottom border -->
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 8px">
|
||||||
|
<div class="col-md-12">
|
||||||
|
{% if s.instruction %}
|
||||||
|
{{ s.instruction | markdown | safe }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="row" style="margin-top: 8px">
|
|
||||||
<div class="col-md-12">
|
|
||||||
{% if s.instruction %}
|
|
||||||
{{ s.instruction | markdown | safe }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -380,6 +463,7 @@
|
|||||||
el: '#id_base_container',
|
el: '#id_base_container',
|
||||||
data: {
|
data: {
|
||||||
recipe: undefined,
|
recipe: undefined,
|
||||||
|
has_ingredients: false,
|
||||||
ingredient_factor: 1,
|
ingredient_factor: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -391,6 +475,14 @@
|
|||||||
this.$http.get("{% url 'api:recipe-detail' recipe.pk %}").then((response) => {
|
this.$http.get("{% url 'api:recipe-detail' recipe.pk %}").then((response) => {
|
||||||
this.recipe = response.data;
|
this.recipe = response.data;
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
for (let step of this.recipe.steps) {
|
||||||
|
if (step.ingredients.length > 0) {
|
||||||
|
this.has_ingredients = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.error = err.data
|
this.error = err.data
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
Loading…
Reference in New Issue
Block a user