mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
added loading spinner and made new view the main recipe view
This commit is contained in:
@@ -1,444 +1,19 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% load render_bundle from webpack_loader %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load crispy_forms_tags %}
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load l10n %}
|
{% load l10n %}
|
||||||
{% load custom_tags %}
|
{% load custom_tags %}
|
||||||
|
|
||||||
{% block title %}{{ recipe.name }}{% endblock %}
|
{% block title %}{{ recipe.name }}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
|
|
||||||
{% include 'include/vue_base.html' %}
|
|
||||||
<script src="{% static 'js/moment-with-locales.min.js' %}"></script>
|
|
||||||
|
|
||||||
<script src="{% static 'js/frac.js' %}"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{% static 'css/pretty-checkbox.min.css' %}">
|
|
||||||
<link rel="stylesheet" href="{% static 'custom/css/markdown_blockquote.css' %}">
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
{% recipe_rating recipe request.user as rating %}
|
||||||
<div class="col col-md-8">
|
|
||||||
{% recipe_rating recipe request.user as rating %}
|
|
||||||
<h3>{{ recipe.name }} {{ rating|safe }}</h3>
|
|
||||||
</div>
|
|
||||||
{% if request.user.is_authenticated %}
|
|
||||||
<div class="col col-md-4 d-print-none" style="text-align: right">
|
|
||||||
<div class="dropdown">
|
|
||||||
<a class="btn shadow-none" href="#" role="button" id="dropdownMenuLink"
|
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<i class="fas fa-ellipsis-v"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
|
<div id="app">
|
||||||
<a class="dropdown-item" href="{% url 'edit_recipe' recipe.pk %}"><i
|
<recipe-view recipe_id="5"></recipe-view>
|
||||||
class="fas fa-pencil-alt fa-fw"></i> {% trans 'Edit' %}</a>
|
|
||||||
<button class="dropdown-item" onclick="$('#bookmarkModal').modal({'show':true})">
|
|
||||||
<i class="fas fa-bookmark fa-fw"></i> {% trans 'Add to Book' %}</button>
|
|
||||||
|
|
||||||
<a class="dropdown-item" v-bind:href="shopping_url" v-if="has_ingredients">
|
|
||||||
<i class="fas fa-shopping-cart fa-fw"></i> {% trans 'Add to Shopping' %}</a>
|
|
||||||
|
|
||||||
<a class="dropdown-item" href="{% url 'new_meal_plan' %}?recipe={{ recipe.pk }}"><i
|
|
||||||
class="fas fa-calendar fa-fw"></i> {% trans 'Add to Plan' %}</a>
|
|
||||||
<button class="dropdown-item" onclick="openCookLogModal({{ recipe.pk }})"><i
|
|
||||||
class="fas fa-clipboard-list fa-fw"></i> {% trans 'Log Cooking' %}</button>
|
|
||||||
<button class="dropdown-item" onclick="window.print()"><i
|
|
||||||
class="fas fa-print fa-fw"></i> {% trans 'Print' %}</button>
|
|
||||||
<a class="dropdown-item" href="{% url 'view_export' %}?r={{ recipe.pk }}" target="_blank"
|
|
||||||
rel="noopener noreferrer"><i class="fas fa-file-export fa-fw"></i> {% trans 'Export' %}</a>
|
|
||||||
{% if recipe.internal %}
|
|
||||||
<a class="dropdown-item" href="{% url 'new_share_link' recipe.pk %}" target="_blank"
|
|
||||||
rel="noopener noreferrer"><i class="fas fa-share-alt fa-fw"></i> {% trans 'Share' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if recipe.storage %}
|
|
||||||
<small>{% trans 'in' %} <a
|
|
||||||
href="{% url 'edit_storage' recipe.storage.pk %}">{{ recipe.storage.name }}</a></small><br/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.internal %}
|
|
||||||
<small>{% trans 'by' %} {{ recipe.created_by.get_user_name }}<br/></small>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.keywords %}
|
|
||||||
{% for x in recipe.keywords.all %}
|
|
||||||
<span class="badge badge-pill badge-light">{{ x }}</span>
|
|
||||||
{% endfor %}
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.working_time and recipe.working_time != 0 %}
|
|
||||||
<span class="badge badge-secondary"><i
|
|
||||||
class="fas fa-user-clock"></i> {% trans 'Preparation time ~' %} {{ recipe.working_time }} min </span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.waiting_time and recipe.waiting_time != 0 %}
|
|
||||||
<span
|
|
||||||
class="badge badge-secondary"><i
|
|
||||||
class="far fa-clock"></i> {% trans 'Waiting time ~' %} {{ recipe.waiting_time }} min </span>
|
|
||||||
{% endif %}
|
|
||||||
{% recipe_last recipe request.user as last_cooked %}
|
|
||||||
{% if last_cooked %}
|
|
||||||
<span class="badge badge-primary">{% trans 'Last cooked' %} {{ last_cooked|date }}</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.waiting_time and recipe.waiting_time != 0 or recipe.working_time and recipe.working_time != 0 or last_cooked %}
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2" v-if="recipe && has_ingredients">
|
|
||||||
<!-- TODO duplicate code remove -->
|
|
||||||
<div class="card border-primary">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-9">
|
|
||||||
<h4 class="card-title">{% trans 'Ingredients' %}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-3">
|
|
||||||
|
|
||||||
<div class="input-group d-print-none">
|
|
||||||
<input type="number" value="1" maxlength="3" class="form-control" style="min-width: 2vw"
|
|
||||||
v-model="servings"/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<span class="input-group-text"><i class="fas fa-calculator"></i></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<template v-for="s in recipe.steps">
|
|
||||||
<template v-if="s.name != '' && s.show_as_header && s.ingredients.length > 0">
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top: 8px!important; ">
|
|
||||||
<b>[[s.name]]</b>
|
|
||||||
</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" v-model="i.checked"/>
|
|
||||||
<div class="state p-success">
|
|
||||||
<label>
|
|
||||||
<template v-if="i.no_amount">
|
|
||||||
<span>⁣</span>
|
|
||||||
</template>
|
|
||||||
<template v-if="!i.no_amount">
|
|
||||||
<span v-html="calculateAmount(i.amount)"></span>
|
|
||||||
{# Allow for amounts without units, such as "2 eggs" #}
|
|
||||||
<template v-if="i.unit">
|
|
||||||
[[i.unit.name]]
|
|
||||||
</template>
|
|
||||||
</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">
|
|
||||||
<b-button v-b-popover.hover="i.note"
|
|
||||||
class="btn btn-sm d-print-none"><i
|
|
||||||
class="fas fa-info"></i></b-button>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% 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">
|
|
||||||
<img class="img img-fluid rounded" src="{{ recipe.image.url }}" style="max-height: 30vh;"
|
|
||||||
alt="{% trans 'Recipe Image' %}">
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if recipe.nutrition %}
|
|
||||||
<div class="row mt-5">
|
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2">
|
|
||||||
<div class="card border-primary">
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="card-title">{% trans 'Nutrition' %}</h4>
|
|
||||||
<table class="table table-sm">
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top: 8px!important; ">
|
|
||||||
<b>{% trans 'Calories' %}</b>
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right">{{ recipe.nutrition.calories|floatformat:2 }}</td>
|
|
||||||
<td>kcal</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top: 8px!important; ">
|
|
||||||
<b>{% trans 'Carbohydrates' %}</b>
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right">{{ recipe.nutrition.carbohydrates|floatformat:2 }}</td>
|
|
||||||
<td>g</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top: 8px!important; ">
|
|
||||||
<b>{% trans 'Fats' %}</b>
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right">{{ recipe.nutrition.fats|floatformat:2 }}</td>
|
|
||||||
<td>g</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top: 8px!important; ">
|
|
||||||
<b>{% trans 'Proteins' %}</b>
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right">{{ recipe.nutrition.proteins|floatformat:2 }}</td>
|
|
||||||
<td>g</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{% if recipe.nutrition.source %}
|
|
||||||
Source: {{ recipe.nutrition.source }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
<div v-if="recipe !== undefined && recipe.steps.length > 0">
|
|
||||||
<hr>
|
|
||||||
<h3>{% trans 'Instructions' %}</h3>
|
|
||||||
<hr>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="font-size: large;" v-if="recipe">
|
|
||||||
{% for s in recipe.steps.all %}
|
|
||||||
<div style="margin-top: 1vh" class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
{% if recipe.steps.all|length > 1 %}
|
|
||||||
<div class="card-title">
|
|
||||||
|
|
||||||
<div class="row d-flex">
|
|
||||||
<div class="col-md-8 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.time != 0 %}
|
|
||||||
- {{ s.time }} {% trans 'Minutes' %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 col-12 justify-content-end" v-if="has_times">
|
|
||||||
<input type="datetime-local" class="form-control"
|
|
||||||
@change="updateTimes(recipe.steps[{{ forloop.counter0 }}])"
|
|
||||||
v-model="recipe.steps[{{ forloop.counter0 }}].time_finished">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" v-if="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">
|
|
||||||
<!-- TODO duplicate code remove -->
|
|
||||||
|
|
||||||
<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" v-model="i.checked"/>
|
|
||||||
<div class="state p-success">
|
|
||||||
<label>
|
|
||||||
<template v-if="i.no_amount">
|
|
||||||
<span>⁣</span>
|
|
||||||
</template>
|
|
||||||
<template v-if="!i.no_amount">
|
|
||||||
<span v-html="calculateAmount(i.amount)"></span>
|
|
||||||
{# Allow for amounts without units, such as "2 eggs" #}
|
|
||||||
<template v-if="i.unit">
|
|
||||||
[[i.unit.name]]
|
|
||||||
</template>
|
|
||||||
</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">
|
|
||||||
<b-button v-b-popover.hover="i.note"
|
|
||||||
class="btn btn-sm d-print-none"><i
|
|
||||||
class="fas fa-info"></i></b-button>
|
|
||||||
<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.get_instruction_render | safe }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if recipe.storage %}
|
|
||||||
<div class="row">
|
|
||||||
{% if recipe.internal %}
|
|
||||||
<div class="col col-12" style="margin-top: 2vh">
|
|
||||||
<a href='#' onClick='openRecipe({{ recipe.id }})'
|
|
||||||
class="d-print-none">{% trans 'View external recipe' %} <i class="fas fa-external-link-alt"></i></a>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
{% if '.pdf' in recipe.file_path %}
|
|
||||||
<div class="col col-12">
|
|
||||||
<iframe src="{% static 'pdfjs/viewer.html' %}?file={% url 'api_get_recipe_file' recipe.id %}"
|
|
||||||
width="100%"
|
|
||||||
height="700px"
|
|
||||||
style="border: none;"></iframe>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if '.jpg' in recipe.file_path or '.png' in recipe.file_path or '.jpeg' in recipe.file_path %}
|
|
||||||
<div class="col-md-12" style="text-align: center">
|
|
||||||
<img class="img img-fluid" src="{% url 'api_get_recipe_file' recipe.id %}"
|
|
||||||
alt="{% trans 'External recipe image' %}">
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="col col-12" style="margin-top: 1vh">
|
|
||||||
<div class="card border-info">
|
|
||||||
<div class="card-body text-info">
|
|
||||||
<h5 class="card-title">{% trans 'External recipe' %}</h5>
|
|
||||||
<p class="card-text">
|
|
||||||
{% blocktrans %}
|
|
||||||
This is an external recipe, which means you can only view it by opening the link
|
|
||||||
above.
|
|
||||||
You can convert this recipe to a fancy recipe by pressing the convert button. The
|
|
||||||
original
|
|
||||||
file
|
|
||||||
will still be accessible.
|
|
||||||
{% endblocktrans %}.
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
<a href="{% url 'edit_convert_recipe' recipe.pk %}"
|
|
||||||
class="card-link btn btn-info">{% trans 'Convert now!' %}</a>
|
|
||||||
<a href='#' onClick='openRecipe({{ recipe.id }})'
|
|
||||||
class="d-print-none btn btn-warning">{% trans 'View external recipe' %} <i
|
|
||||||
class="fas fa-external-link-alt"></i></a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.user.userpreference.comments %}
|
{% if request.user.userpreference.comments %}
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -474,144 +49,27 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if recipe.storage %}
|
|
||||||
{% include 'include/recipe_open_modal.html' %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Bookmark Modal -->
|
|
||||||
<div class="modal fade" id="bookmarkModal" tabindex="-1" role="dialog" aria-labelledby="bookmarkModalLabel"
|
|
||||||
aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="bookmarkModalLabel">Modal title</h5>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<form method="POST" class="post-form">
|
|
||||||
<div class="modal-body">
|
|
||||||
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ bookmark_form|crispy }}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
||||||
<input type="submit" value="{% trans 'Save' %}" class="btn btn-success">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% include 'include/log_cooking.html' %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
|
<script src="{% url 'javascript-catalog' %}"></script>
|
||||||
|
|
||||||
|
{% if debug %}
|
||||||
|
<script src="{% url 'js_reverse' %}"></script>
|
||||||
|
{% else %}
|
||||||
|
<script src="{% static 'django_js_reverse/js/reverse.js' %}"></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
window.RECIPE_ID = {{recipe.pk}};
|
||||||
let csrftoken = Cookies.get('csrftoken');
|
window.USER_PREF = {
|
||||||
Vue.http.headers.common['X-CSRFToken'] = csrftoken;
|
'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %},
|
||||||
|
'ingredient_decimals': {{ request.user.userpreference.ingredient_decimals }},
|
||||||
{% if user_servings %}
|
}
|
||||||
const recipe_servings = {{ user_servings|floatformat:0 }}
|
|
||||||
{% else %}
|
|
||||||
const recipe_servings = {{ recipe.servings }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
let app = new Vue({
|
|
||||||
delimiters: ['[[', ']]'],
|
|
||||||
el: '#id_base_container',
|
|
||||||
data: {
|
|
||||||
recipe: undefined,
|
|
||||||
has_ingredients: false,
|
|
||||||
has_times: false,
|
|
||||||
servings: recipe_servings,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
ingredient_factor: function () {
|
|
||||||
return this.servings / recipe_servings
|
|
||||||
},
|
|
||||||
shopping_url: function () {
|
|
||||||
return `{% url 'view_shopping' %}?r=[${this.recipe.id},${this.servings}]`
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted: function () {
|
|
||||||
this.loadRecipe()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadRecipe: function () {
|
|
||||||
this.$http.get("{% url 'api:recipe-detail' recipe.pk %}" {% if share %}
|
|
||||||
+ "?share={{ share }}"{% endif %}).then((response) => {
|
|
||||||
this.recipe = response.data;
|
|
||||||
this.loading = false;
|
|
||||||
|
|
||||||
for (let step of this.recipe.steps) {
|
|
||||||
if (step.ingredients.length > 0) {
|
|
||||||
this.has_ingredients = true
|
|
||||||
}
|
|
||||||
if (step.time !== 0) {
|
|
||||||
this.has_times = true
|
|
||||||
}
|
|
||||||
this.$set(step, 'time_finished', undefined);
|
|
||||||
for (let i of step.ingredients) {
|
|
||||||
this.$set(i, 'checked', false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}).catch((err) => {
|
|
||||||
this.error = err.data;
|
|
||||||
this.loading = false;
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
roundDecimals: function (num) {
|
|
||||||
let decimals = {% if request.user.userpreference.ingredient_decimals %}
|
|
||||||
{{ request.user.userpreference.ingredient_decimals }} {% else %} 2; {% endif %}
|
|
||||||
return +(Math.round(num + `e+${decimals}`) + `e-${decimals}`);
|
|
||||||
},
|
|
||||||
updateTimes: function (step) {
|
|
||||||
let time_diff_first = 0;
|
|
||||||
for (let s of this.recipe.steps) {
|
|
||||||
if (this.recipe.steps.indexOf(s) < this.recipe.steps.indexOf(step)) {
|
|
||||||
time_diff_first += s.time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.recipe.steps[0].time_finished = moment(step.time_finished).subtract(time_diff_first, 'minutes').format(moment.HTML5_FMT.DATETIME_LOCAL);
|
|
||||||
|
|
||||||
let time_diff = 0;
|
|
||||||
for (let s of this.recipe.steps) {
|
|
||||||
s.time_finished = moment(this.recipe.steps[0].time_finished).add(time_diff, 'minutes').format(moment.HTML5_FMT.DATETIME_LOCAL);
|
|
||||||
time_diff += s.time
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
calculateAmount: function (amount) {
|
|
||||||
{% if request.user.userpreference.use_fractions %}
|
|
||||||
let return_string = ''
|
|
||||||
let fraction = frac.cont((amount * this.ingredient_factor), 9, true)
|
|
||||||
|
|
||||||
if (fraction[0] > 0) {
|
|
||||||
return_string += fraction[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fraction[1] > 0) {
|
|
||||||
return_string += ` <sup>${(fraction[1])}</sup>⁄<sub>${(fraction[2])}</sub>`
|
|
||||||
}
|
|
||||||
|
|
||||||
return return_string
|
|
||||||
{% else %}
|
|
||||||
return this.roundDecimals(amount * this.ingredient_factor)
|
|
||||||
{% endif %}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{% render_bundle 'chunk-vendors' %}
|
||||||
|
{% render_bundle 'recipe_view' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% load render_bundle from webpack_loader %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load l10n %}
|
|
||||||
{% load custom_tags %}
|
|
||||||
|
|
||||||
{% block title %}{{ recipe.name }}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% recipe_rating recipe request.user as rating %}
|
|
||||||
<!--
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h3>{{ recipe.name }} {{ rating|safe }}</h3>
|
|
||||||
|
|
||||||
{% if recipe.storage %}
|
|
||||||
<small>{% trans 'in' %} <a
|
|
||||||
href="{% url 'edit_storage' recipe.storage.pk %}">{{ recipe.storage.name }}</a></small><br/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.internal %}
|
|
||||||
<small>{% trans 'by' %} {{ recipe.created_by.get_user_name }}<br/></small>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if recipe.keywords %}
|
|
||||||
{% for x in recipe.keywords.all %}
|
|
||||||
<span class="badge badge-pill badge-light">{{ x }}</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<div id="app">
|
|
||||||
<recipe-view recipe_id="5"></recipe-view>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if request.user.userpreference.comments %}
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<h5 {% if not comments %}class="d-print-none" {% endif %}><i class="far fa-comments"></i> {% trans 'Comments' %}
|
|
||||||
</h5>
|
|
||||||
{% for c in comments %}
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<small class="card-title">{{ c.updated_at }} {% trans 'by' %} {{ c.created_by.username }}</small> <a
|
|
||||||
href="{% url 'edit_comment' c.pk %}" class="d-print-none"><i
|
|
||||||
class="fas fa-pencil-alt"></i></a><br/>
|
|
||||||
{{ c.text }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
|
||||||
<div class="d-print-none">
|
|
||||||
|
|
||||||
<form method="POST" class="post-form">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<textarea name="comment-text" cols="15" rows="2" class="textarea form-control" required
|
|
||||||
id="comment-id_text"></textarea>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<input type="submit" value="{% trans 'Comment' %}" class="btn btn-success">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block script %}
|
|
||||||
<script src="{% url 'javascript-catalog' %}"></script>
|
|
||||||
|
|
||||||
{% if debug %}
|
|
||||||
<script src="{% url 'js_reverse' %}"></script>
|
|
||||||
{% else %}
|
|
||||||
<script src="{% static 'django_js_reverse/js/reverse.js' %}"></script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
|
||||||
window.RECIPE_ID = {{recipe.pk}};
|
|
||||||
window.USER_PREF = {
|
|
||||||
'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %},
|
|
||||||
'ingredient_decimals': {{ request.user.userpreference.ingredient_decimals }},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% render_bundle 'chunk-vendors' %}
|
|
||||||
{% render_bundle 'recipe_view' %}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -153,7 +153,6 @@ def recipe_view(request, pk, share=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
comment_form = CommentForm()
|
comment_form = CommentForm()
|
||||||
bookmark_form = RecipeBookEntryForm()
|
|
||||||
|
|
||||||
user_servings = None
|
user_servings = None
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
@@ -172,18 +171,7 @@ def recipe_view(request, pk, share=None):
|
|||||||
.exists():
|
.exists():
|
||||||
ViewLog.objects.create(recipe=recipe, created_by=request.user)
|
ViewLog.objects.create(recipe=recipe, created_by=request.user)
|
||||||
|
|
||||||
return render(
|
return render(request, 'recipe_view.html', {'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, 'user_servings': user_servings})
|
||||||
request,
|
|
||||||
'recipe_view.html',
|
|
||||||
{
|
|
||||||
'recipe': recipe,
|
|
||||||
'comments': comments,
|
|
||||||
'comment_form': comment_form,
|
|
||||||
'bookmark_form': bookmark_form,
|
|
||||||
'share': share,
|
|
||||||
'user_servings': user_servings
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@group_required('user')
|
@group_required('user')
|
||||||
|
|||||||
@@ -1,132 +1,136 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" v-if="!loading">
|
<div id="app">
|
||||||
|
<template v-if="loading">
|
||||||
|
<loading-spinner></loading-spinner>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="row">
|
<div v-if="!loading">
|
||||||
<div class="col-12" style="text-align: center">
|
<div class="row">
|
||||||
<h3>{{ recipe.name }}</h3>
|
<div class="col-12" style="text-align: center">
|
||||||
</div>
|
<h3>{{ recipe.name }}</h3>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="text-align: center">
|
|
||||||
<keywords :recipe="recipe"></keywords>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" style="margin-top: 8px">
|
|
||||||
<div class="col-12" style="text-align: center">
|
|
||||||
<i>{{ recipe.description }}</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-3">
|
|
||||||
<div class="row d-flex" style="padding-left: 16px;height: 100%">
|
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
|
||||||
<i class="fas fa-user-clock fa-2x text-primary"></i>
|
|
||||||
</div>
|
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
|
||||||
<span class="text-primary"><b>{{ _('Preparation') }}</b></span><br/>
|
|
||||||
{{ recipe.working_time }} {{ _('min') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-3">
|
<div style="text-align: center">
|
||||||
<div class="row d-flex" style="height: 100%">
|
<keywords :recipe="recipe"></keywords>
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
</div>
|
||||||
<i class="far fa-clock fa-2x text-primary"></i>
|
|
||||||
</div>
|
<div class="row" style="margin-top: 8px">
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
<div class="col-12" style="text-align: center">
|
||||||
<span class="text-primary"><b>{{ _('Waiting') }}</b></span><br/>
|
<i>{{ recipe.description }}</i>
|
||||||
{{ recipe.waiting_time }} {{ _('min') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-4 col-10">
|
<hr/>
|
||||||
<div class="row d-flex" style="padding-left: 16px;height: 100%">
|
<div class="row">
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
<div class="col col-md-3">
|
||||||
<i class="fas fa-pizza-slice fa-2x text-primary"></i>
|
<div class="row d-flex" style="padding-left: 16px;height: 100%">
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<i class="fas fa-user-clock fa-2x text-primary"></i>
|
||||||
|
</div>
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<span class="text-primary"><b>{{ _('Preparation') }}</b></span><br/>
|
||||||
|
{{ recipe.working_time }} {{ _('min') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-auto" style="padding-right: 4px">
|
</div>
|
||||||
<input dir="rtl"
|
|
||||||
|
<div class="col col-md-3">
|
||||||
|
<div class="row d-flex" style="height: 100%">
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<i class="far fa-clock fa-2x text-primary"></i>
|
||||||
|
</div>
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<span class="text-primary"><b>{{ _('Waiting') }}</b></span><br/>
|
||||||
|
{{ recipe.waiting_time }} {{ _('min') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col col-md-4 col-10">
|
||||||
|
<div class="row d-flex" style="padding-left: 16px;height: 100%">
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<i class="fas fa-pizza-slice fa-2x text-primary"></i>
|
||||||
|
</div>
|
||||||
|
<div class="my-auto" style="padding-right: 4px">
|
||||||
|
<input dir="rtl"
|
||||||
style="border-width:0px;border:none; padding:0px; padding-left: 0.5vw; padding-right: 8px; max-width: 80px"
|
style="border-width:0px;border:none; padding:0px; padding-left: 0.5vw; padding-right: 8px; max-width: 80px"
|
||||||
value="1" maxlength="3"
|
value="1" maxlength="3"
|
||||||
type="number" class="form-control form-control-lg" v-model.number="servings"/>
|
type="number" class="form-control form-control-lg" v-model.number="servings"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-auto">
|
<div class="my-auto">
|
||||||
<b>{{ _('Servings') }}</b>
|
<b>{{ _('Servings') }}</b>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col col-md-2 col-2 my-auto" style="text-align: right; padding-right: 1vw">
|
||||||
|
<recipe-context-menu v-bind:recipe="recipe" :servings="servings"></recipe-context-menu>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<div class="col col-md-2 col-2 my-auto" style="text-align: right; padding-right: 1vw">
|
<div class="row" style="margin-top: 2vh">
|
||||||
<recipe-context-menu v-bind:recipe="recipe" :servings="servings"></recipe-context-menu>
|
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2" v-if="recipe && ingredient_count > 0"
|
||||||
</div>
|
style="margin-top: 2vh">
|
||||||
</div>
|
<div class="card border-primary">
|
||||||
<hr/>
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
<div class="row" style="margin-top: 2vh">
|
<div class="col col-md-8">
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2" v-if="recipe && ingredient_count > 0">
|
<h4 class="card-title"><i class="fas fa-pepper-hot"></i> {{ _('Ingredients') }}</h4>
|
||||||
|
</div>
|
||||||
<div class="card border-primary">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-8">
|
|
||||||
<h4 class="card-title"><i class="fas fa-pepper-hot"></i> {{ _('Ingredients') }}</h4>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<br/>
|
||||||
<br/>
|
<div class="row">
|
||||||
<div class="row">
|
<div class="col-md-12">
|
||||||
<div class="col-md-12">
|
<table class="table table-sm">
|
||||||
<table class="table table-sm">
|
<!-- eslint-disable vue/no-v-for-template-key-on-child -->
|
||||||
<!-- eslint-disable vue/no-v-for-template-key-on-child -->
|
<template v-for="s in recipe.steps">
|
||||||
<template v-for="s in recipe.steps">
|
<template v-for="i in s.ingredients">
|
||||||
<template v-for="i in s.ingredients">
|
<Ingredient v-bind:ingredient="i" v-bind:servings="servings" :key="i.id"
|
||||||
<Ingredient v-bind:ingredient="i" v-bind:servings="servings" :key="i.id"
|
@checked-state-changed="updateIngredientCheckedState"></Ingredient>
|
||||||
@checked-state-changed="updateIngredientCheckedState"></Ingredient>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
<!-- eslint-enable vue/no-v-for-template-key-on-child -->
|
||||||
<!-- eslint-enable vue/no-v-for-template-key-on-child -->
|
</table>
|
||||||
</table>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2">
|
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|
||||||
<img class="img img-fluid rounded" :src="recipe.image" style="max-height: 30vh;"
|
<img class="img img-fluid rounded" :src="recipe.image" style="max-height: 30vh;"
|
||||||
:alt="_( 'Recipe Image')" v-if="recipe.image !== null">
|
:alt="_( 'Recipe Image')" v-if="recipe.image !== null">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 2vh">
|
||||||
|
<div class="col-12">
|
||||||
|
<Nutrition :recipe="recipe" :servings="servings"></Nutrition>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" style="margin-top: 2vh">
|
|
||||||
<div class="col-12">
|
|
||||||
<Nutrition :recipe="recipe" :servings="servings"></Nutrition>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="recipe.file_path.includes('.pdf')">
|
||||||
|
<PdfViewer :recipe="recipe"></PdfViewer>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="recipe.file_path.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg')">
|
||||||
|
<ImageViewer :recipe="recipe"></ImageViewer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-for="(s, index) in recipe.steps" v-bind:key="s.id" style="margin-top: 1vh">
|
||||||
|
<Step :recipe="recipe" :step="s" :servings="servings" :index="index" :start_time="start_time"
|
||||||
|
@update-start-time="updateStartTime" @checked-state-changed="updateIngredientCheckedState"></Step>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="recipe.file_path.includes('.pdf')">
|
|
||||||
<PdfViewer :recipe="recipe"></PdfViewer>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="recipe.file_path.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg')">
|
|
||||||
<ImageViewer :recipe="recipe"></ImageViewer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-for="(s, index) in recipe.steps" v-bind:key="s.id" style="margin-top: 1vh">
|
|
||||||
<Step :recipe="recipe" :step="s" :servings="servings" :index="index" :start_time="start_time"
|
|
||||||
@update-start-time="updateStartTime" @checked-state-changed="updateIngredientCheckedState"></Step>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -149,6 +153,7 @@ import Nutrition from "@/components/Nutrition";
|
|||||||
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import Keywords from "@/components/Keywords";
|
import Keywords from "@/components/Keywords";
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||||
|
|
||||||
Vue.prototype.moment = moment
|
Vue.prototype.moment = moment
|
||||||
|
|
||||||
@@ -168,6 +173,7 @@ export default {
|
|||||||
RecipeContextMenu,
|
RecipeContextMenu,
|
||||||
Nutrition,
|
Nutrition,
|
||||||
Keywords,
|
Keywords,
|
||||||
|
LoadingSpinner,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -191,7 +197,7 @@ export default {
|
|||||||
this.ingredient_count += step.ingredients.length
|
this.ingredient_count += step.ingredients.length
|
||||||
|
|
||||||
for (let ingredient of step.ingredients) {
|
for (let ingredient of step.ingredients) {
|
||||||
this.$set(ingredient, 'checked', false)
|
this.$set(ingredient, 'checked', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
step.time_offset = total_time
|
step.time_offset = total_time
|
||||||
|
|||||||
17
vue/src/components/LoadingSpinner.vue
Normal file
17
vue/src/components/LoadingSpinner.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col" style="text-align: center">
|
||||||
|
<i class="fas fa-spinner fa-spin fa-10x"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LoadingSpinner',
|
||||||
|
props: {
|
||||||
|
recipe: Object,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1 +1 @@
|
|||||||
{"status":"done","publicPath":"http://localhost:8080/","chunks":{"chunk-vendors":[{"name":"js/chunk-vendors.js","publicPath":"http://localhost:8080/js/chunk-vendors.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\js\\chunk-vendors.js"}],"recipe_view":[{"name":"js/recipe_view.js","publicPath":"http://localhost:8080/js/recipe_view.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\js\\recipe_view.js"},{"name":"recipe_view.6a32bc3201ad26dbc898.hot-update.js","publicPath":"http://localhost:8080/recipe_view.6a32bc3201ad26dbc898.hot-update.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\recipe_view.6a32bc3201ad26dbc898.hot-update.js"}]},"error":"ModuleError","message":"Module Error (from ./node_modules/eslint-loader/index.js):\n\nF:\\Developement\\Django\\recipes\\vue\\src\\components\\Keywords.vue\n 3:7 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key\n\n✖ 1 problem (1 error, 0 warnings)\n"}
|
{"status":"done","publicPath":"http://localhost:8080/","chunks":{"chunk-vendors":[{"name":"js/chunk-vendors.js","publicPath":"http://localhost:8080/js/chunk-vendors.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\js\\chunk-vendors.js"}],"recipe_view":[{"name":"js/recipe_view.js","publicPath":"http://localhost:8080/js/recipe_view.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\js\\recipe_view.js"},{"name":"recipe_view.cfc8fcd2004c1b08df3e.hot-update.js","publicPath":"http://localhost:8080/recipe_view.cfc8fcd2004c1b08df3e.hot-update.js","path":"F:\\Developement\\Django\\recipes\\cookbook\\static\\vue\\recipe_view.cfc8fcd2004c1b08df3e.hot-update.js"}]},"error":"ModuleError","message":"Module Error (from ./node_modules/eslint-loader/index.js):\n\nF:\\Developement\\Django\\recipes\\vue\\src\\components\\Keywords.vue\n 3:7 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key\n\n✖ 1 problem (1 error, 0 warnings)\n"}
|
||||||
Reference in New Issue
Block a user