Merge pull request #2941 from tomtjes/add-human-friendly-css-classes
Add human-friendly css classes and scaling indicators
This commit is contained in:
commit
03ccc8e044
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" class="col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1 offset">
|
<div id="app" class="books col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1 offset">
|
||||||
<div class="col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1">
|
<div class="col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div id="app" class="mealplan">
|
||||||
<div class="d-none d-lg-block">
|
<div class="d-none d-lg-block">
|
||||||
<div class="row ">
|
<div class="row ">
|
||||||
<div class="col col-2">
|
<div class="col col-2">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" style="padding-bottom: 60px">
|
<div id="app" class="search" style="padding-bottom: 60px">
|
||||||
<RecipeSwitcher ref="ref_recipe_switcher" />
|
<RecipeSwitcher ref="ref_recipe_switcher" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-xl-10 col-lg-10 offset-xl-1 offset-lg-1">
|
<div class="col-12 col-xl-10 col-lg-10 offset-xl-1 offset-lg-1">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" v-if="recipe_id !== undefined">
|
<div id="app" class="recipe" v-if="recipe_id !== undefined">
|
||||||
<recipe-view-component :recipe_id="recipe_id"></recipe-view-component>
|
<recipe-view-component :recipe_id="recipe_id"></recipe-view-component>
|
||||||
|
|
||||||
<bottom-navigation-bar active-view="view_search"></bottom-navigation-bar>
|
<bottom-navigation-bar active-view="view_search"></bottom-navigation-bar>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app" class="shopping">
|
||||||
<b-alert :show="shopping_list_store.has_failed_items" class="float-up mt-2" variant="warning">
|
<b-alert :show="shopping_list_store.has_failed_items" class="float-up mt-2" variant="warning">
|
||||||
{{ $t('ShoppingBackgroundSyncWarning') }}
|
{{ $t('ShoppingBackgroundSyncWarning') }}
|
||||||
</b-alert>
|
</b-alert>
|
||||||
@ -55,7 +55,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Entry input on large screens -->
|
<!-- Entry input on large screens -->
|
||||||
<b-row class="d-lg-block d-print-none d-none mb-3 mt-3">
|
<b-row class="d-lg-block d-print-none d-none mb-3 mt-3">
|
||||||
<b-col cols="12">
|
<b-col cols="12">
|
||||||
|
@ -1,52 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<tr>
|
<tr class="ingredients__item">
|
||||||
<template v-if="ingredient.is_header">
|
<template v-if="ingredient.is_header">
|
||||||
<td colspan="5" @click="done">
|
<td class="ingredients__header-note header" colspan="5" @click="done">
|
||||||
<b>{{ ingredient.note }}</b>
|
<b>{{ ingredient.note }}</b>
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<td class="d-print-none align-baseline py-2" v-if="detailed" @click="done">
|
<td class="ingredients__check d-print-none align-baseline py-2" v-if="detailed" @click="done">
|
||||||
<i class="far fa-check-circle text-success" v-if="ingredient.checked"></i>
|
<i class="ingredients__check ingredients__check_checked far fa-check-circle text-success" v-if="ingredient.checked"></i>
|
||||||
<i class="far fa-check-circle text-primary" v-if="!ingredient.checked"></i>
|
<i class="ingredients__check ingredients__check_checked_false far fa-check-circle text-primary" v-if="!ingredient.checked"></i>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-nowrap" @click="done">
|
<td class="ingredients__amount text-nowrap" @click="done">
|
||||||
<span v-if="ingredient.amount !== 0 && !ingredient.no_amount" v-html="calculateAmount(ingredient.amount)"></span>
|
<span class="ingredients__amount" :class="amountClass" v-if="ingredient.amount !== 0 && !ingredient.no_amount" v-html="amount"></span>
|
||||||
</td>
|
</td>
|
||||||
<td @click="done">
|
<td class="ingredients__unit" @click="done">
|
||||||
<template v-if="ingredient.unit !== null && !ingredient.no_amount">
|
<span v-if="ingredient.unit !== null && !ingredient.no_amount" :class="unitClass">{{ unitName }}</span>
|
||||||
<template>
|
|
||||||
<template v-if="ingredient.unit.plural_name === '' || ingredient.unit.plural_name === null">
|
|
||||||
<span>{{ ingredient.unit.name }}</span>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<span v-if="ingredient.always_use_plural_unit">{{ ingredient.unit.plural_name }}</span>
|
|
||||||
<span v-else-if="ingredient.amount * this.ingredient_factor > 1">{{ ingredient.unit.plural_name }}</span>
|
|
||||||
<span v-else>{{ ingredient.unit.name }}</span>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</td>
|
</td>
|
||||||
<td @click="done">
|
<td class="ingredients__food" :class="foodClass" @click="done">
|
||||||
<template v-if="ingredient.food !== null">
|
<template v-if="ingredient.food !== null">
|
||||||
<a :href="resolveDjangoUrl('view_recipe', ingredient.food.recipe.id)" v-if="ingredient.food.recipe !== null" target="_blank" rel="noopener noreferrer">
|
<a :href="resolveDjangoUrl('view_recipe', ingredient.food.recipe.id)" v-if="ingredient.food.recipe !== null" target="_blank" rel="noopener noreferrer">
|
||||||
{{ ingredientName(ingredient) }}
|
{{ foodName }}
|
||||||
</a>
|
</a>
|
||||||
<a :href="ingredient.food.url" v-else-if="ingredient.food.url !== ''" target="_blank" rel="noopener noreferrer">
|
<a :href="ingredient.food.url" v-else-if="ingredient.food.url !== ''" target="_blank" rel="noopener noreferrer">
|
||||||
{{ ingredientName(ingredient) }}</a>
|
{{ foodName }}</a>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span>{{ ingredientName(ingredient) }}</span>
|
<span :class="foodClass">{{ foodName }}</span>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
<td v-if="detailed" class="align-baseline">
|
<td v-if="detailed" class="ingredients__note align-baseline">
|
||||||
<template v-if="ingredient.note">
|
<template v-if="ingredient.note">
|
||||||
<span class="d-print-none touchable py-0 px-2" v-b-popover.hover="ingredient.note">
|
<span class="ingredients__note ingredients__note_hover d-print-none touchable py-0 px-2" v-b-popover.hover="ingredient.note">
|
||||||
<i class="far fa-comment"></i>
|
<i class="far fa-comment"></i>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="d-none d-print-block"><i class="far fa-comment-alt d-print-none"></i> {{ ingredient.note }}</div>
|
<div class="ingredients__note ingredients__note_print d-none d-print-block"><i class="far fa-comment-alt d-print-none"></i> {{ ingredient.note }}</div>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
@ -54,7 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {calculateAmount, ResolveUrlMixin} from "@/utils/utils"
|
import {calculateAmount, ResolveUrlMixin, EscapeCSSMixin} from "@/utils/utils"
|
||||||
|
|
||||||
import Vue from "vue"
|
import Vue from "vue"
|
||||||
import VueSanitize from "vue-sanitize"
|
import VueSanitize from "vue-sanitize"
|
||||||
@ -68,7 +57,7 @@ export default {
|
|||||||
ingredient_factor: {type: Number, default: 1},
|
ingredient_factor: {type: Number, default: 1},
|
||||||
detailed: {type: Boolean, default: true},
|
detailed: {type: Boolean, default: true},
|
||||||
},
|
},
|
||||||
mixins: [ResolveUrlMixin],
|
mixins: [ResolveUrlMixin, EscapeCSSMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
checked: false,
|
checked: false,
|
||||||
@ -77,27 +66,65 @@ export default {
|
|||||||
watch: {},
|
watch: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
},
|
},
|
||||||
methods: {
|
computed: {
|
||||||
calculateAmount: function (x) {
|
amount: function() {
|
||||||
return this.$sanitize(calculateAmount(x, this.ingredient_factor))
|
return this.$sanitize(calculateAmount(this.ingredient.amount, this.ingredient_factor))
|
||||||
},
|
},
|
||||||
|
isScaledUp: function() {
|
||||||
|
return this.ingredient_factor > 1 ? true:false
|
||||||
|
},
|
||||||
|
isScaledDown: function() {
|
||||||
|
return this.ingredient_factor < 1 ? true:false
|
||||||
|
},
|
||||||
|
amountClass: function () {
|
||||||
|
if (this.isScaledDown) {
|
||||||
|
return this.escapeCSS('ingredients__amount_scaled_down')
|
||||||
|
} else if (this.isScaledUp) {
|
||||||
|
return this.escapeCSS('ingredients__amount_scaled_up')
|
||||||
|
} else {
|
||||||
|
return this.escapeCSS('ingredients__amount_scaled_false')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isUnitPlural: function () {
|
||||||
|
if (this.ingredient.unit.plural_name === '' || this.ingredient.unit.plural_name === null) {
|
||||||
|
return false
|
||||||
|
} else if (this.ingredient.always_use_plural_unit || this.ingredient.amount * this.ingredient_factor > 1) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isFoodPlural: function () {
|
||||||
|
if (this.ingredient.food.plural_name == null || this.ingredient.food.plural_name === '') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this.ingredient.always_use_plural_food) {
|
||||||
|
return true
|
||||||
|
} else if (this.ingredient.no_amount) {
|
||||||
|
return false
|
||||||
|
} else if (this.ingredient.amount * this.ingredient_factor > 1) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unitClass: function () {
|
||||||
|
return this.escapeCSS('_unitname-' + this.ingredient.unit.name)
|
||||||
|
},
|
||||||
|
foodClass: function () {
|
||||||
|
return this.escapeCSS('_foodname-' + this.ingredient.food.name)
|
||||||
|
},
|
||||||
|
unitName: function () {
|
||||||
|
return this.isUnitPlural ? this.ingredient.unit.plural_name : this.ingredient.unit.name
|
||||||
|
},
|
||||||
|
foodName: function () {
|
||||||
|
return this.isFoodPlural ? this.ingredient.food.plural_name : this.ingredient.food.name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
// sends parent recipe ingredient to notify complete has been toggled
|
// sends parent recipe ingredient to notify complete has been toggled
|
||||||
done: function () {
|
done: function () {
|
||||||
this.$emit("checked-state-changed", this.ingredient)
|
this.$emit("checked-state-changed", this.ingredient)
|
||||||
},
|
|
||||||
ingredientName: function (ingredient) {
|
|
||||||
if (ingredient.food.plural_name == null || ingredient.food.plural_name === '') {
|
|
||||||
return ingredient.food.name
|
|
||||||
}
|
|
||||||
if (ingredient.always_use_plural_food) {
|
|
||||||
return ingredient.food.plural_name
|
|
||||||
} else if (ingredient.no_amount) {
|
|
||||||
return ingredient.food.name
|
|
||||||
} else if (ingredient.amount * this.ingredient_factor > 1) {
|
|
||||||
return ingredient.food.plural_name
|
|
||||||
} else {
|
|
||||||
return ingredient.food.name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{ 'card border-primary no-border': header }">
|
<div class="ingredients" :class="{ 'card border-primary no-border': header }">
|
||||||
<div :class="{ 'card-body': header, 'p-0': header }">
|
<div :class="{ 'card-body': header, 'p-0': header }">
|
||||||
<div class="card-header" v-if="header">
|
<div class="card-header" v-if="header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<table class="table table-sm mb-0">
|
<table class="table table-sm mb-0">
|
||||||
<!-- 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 steps">
|
<template v-for="s in steps">
|
||||||
<tr v-bind:key="s.id" v-if="s.show_as_header && s.name !== '' && steps.length > 1">
|
<tr class="ingredients__header-step-name" v-bind:key="s.id" v-if="s.show_as_header && s.name !== '' && steps.length > 1">
|
||||||
<td colspan="5">
|
<td colspan="5">
|
||||||
<b>{{ s.name }}</b>
|
<b>{{ s.name }}</b>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="recipe.keywords.length > 0">
|
<div class="keywords" v-if="recipe.keywords.length > 0">
|
||||||
<span :key="k.id" v-for="k in recipe.keywords.slice(0,keyword_splice).filter((kk) => { return kk.show || kk.show === undefined })" class="pl-1">
|
<span :key="k.id" v-for="k in recipe.keywords.slice(0,keyword_splice).filter((kk) => { return kk.show || kk.show === undefined })" class="keywords__item pl-1" :class="keywordClass(k)">
|
||||||
<template v-if="enable_keyword_links">
|
<template v-if="enable_keyword_links">
|
||||||
<a :href="`${resolveDjangoUrl('view_search')}?keyword=${k.id}`">
|
<a :href="`${resolveDjangoUrl('view_search')}?keyword=${k.id}`">
|
||||||
<b-badge pill variant="light" class="font-weight-normal">{{ k.label }}</b-badge>
|
<b-badge pill variant="light" class="font-weight-normal">{{ k.label }}</b-badge>
|
||||||
@ -9,18 +9,17 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<b-badge pill variant="light" class="font-weight-normal">{{ k.label }}</b-badge>
|
<b-badge pill variant="light" class="font-weight-normal">{{ k.label }}</b-badge>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {ResolveUrlMixin} from "@/utils/utils";
|
import {ResolveUrlMixin, EscapeCSSMixin} from "@/utils/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'KeywordsComponent',
|
name: 'KeywordsComponent',
|
||||||
mixins: [ResolveUrlMixin],
|
mixins: [ResolveUrlMixin, EscapeCSSMixin],
|
||||||
props: {
|
props: {
|
||||||
recipe: Object,
|
recipe: Object,
|
||||||
limit: Number,
|
limit: Number,
|
||||||
@ -31,7 +30,12 @@ export default {
|
|||||||
if (this.limit) {
|
if (this.limit) {
|
||||||
return this.limit
|
return this.limit
|
||||||
}
|
}
|
||||||
return this.recipe.keywords.lenght
|
return this.recipe.keywords.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
keywordClass: function(k) {
|
||||||
|
return this.escapeCSS('_keywordname-' + k.label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="last-cooked">
|
||||||
<span class="pl-1" v-if="recipe.last_cooked !== undefined && recipe.last_cooked !== null">
|
<span class="pl-1" v-if="recipe.last_cooked !== undefined && recipe.last_cooked !== null">
|
||||||
<b-badge pill variant="primary" class="font-weight-normal"><i class="fas fa-utensils"></i> {{
|
<b-badge pill variant="primary" class="font-weight-normal"><i class="fas fa-utensils"></i> {{
|
||||||
formatDate(recipe.last_cooked)
|
formatDate(recipe.last_cooked)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="rating">
|
||||||
<span class="d-inline" v-if="recipe.rating > 0">
|
<span class="d-inline" v-if="recipe.rating > 0">
|
||||||
<div v-if="!pill">
|
<div v-if="!pill">
|
||||||
<i class="fas fa-star fa-xs text-primary" v-for="i in Math.floor(recipe.rating)" v-bind:key="i"></i>
|
<i class="fas fa-star fa-xs text-primary" v-for="i in Math.floor(recipe.rating)" v-bind:key="i"></i>
|
||||||
|
@ -7,32 +7,32 @@
|
|||||||
|
|
||||||
<div v-if="!loading" style="padding-bottom: 60px">
|
<div v-if="!loading" style="padding-bottom: 60px">
|
||||||
<RecipeSwitcher ref="ref_recipe_switcher" @switch="quickSwitch($event)" v-if="show_recipe_switcher"/>
|
<RecipeSwitcher ref="ref_recipe_switcher" @switch="quickSwitch($event)" v-if="show_recipe_switcher"/>
|
||||||
<div class="row">
|
<div class="recipe__title row">
|
||||||
<div class="col-12" style="text-align: center">
|
<div class="col-12" style="text-align: center">
|
||||||
<h3>{{ recipe.name }}</h3>
|
<h3>{{ recipe.name }}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row text-center">
|
<div class="recipe__history row text-center">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<recipe-rating :recipe="recipe"></recipe-rating>
|
<recipe-rating :recipe="recipe"></recipe-rating>
|
||||||
<last-cooked :recipe="recipe" class="mt-2"></last-cooked>
|
<last-cooked :recipe="recipe" class="mt-2"></last-cooked>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="my-auto">
|
<div class="recipe__description my-auto">
|
||||||
<div class="col-12" style="text-align: center">
|
<div class="col-12" style="text-align: center">
|
||||||
<i>{{ recipe.description }}</i>
|
<i>{{ recipe.description }}</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div class="recipe__keywords" style="text-align: center">
|
||||||
<keywords-component :recipe="recipe" :enable_keyword_links="enable_keyword_links"></keywords-component>
|
<keywords-component :recipe="recipe" :enable_keyword_links="enable_keyword_links"></keywords-component>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="row align-items-center">
|
<div class="recipe__prep-data row align-items-center">
|
||||||
<div class="col col-md-3">
|
<div class="recipe__prep-time col col-md-3">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="my-auto mr-1">
|
<div class="my-auto mr-1">
|
||||||
<i class="fas fa-fw fa-user-clock fa-2x text-primary"></i>
|
<i class="fas fa-fw fa-user-clock fa-2x text-primary"></i>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-3">
|
<div class="recipe__wait-time col col-md-3">
|
||||||
<div class="row d-flex">
|
<div class="row d-flex">
|
||||||
<div class="my-auto mr-1">
|
<div class="my-auto mr-1">
|
||||||
<i class="far fa-fw fa-clock fa-2x text-primary"></i>
|
<i class="far fa-fw fa-clock fa-2x text-primary"></i>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-4 col-10 mt-2 mt-md-0">
|
<div class="recipe__servings col col-md-4 col-10 mt-2 mt-md-0">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="my-auto mr-1">
|
<div class="my-auto mr-1">
|
||||||
<i class="fas fa-fw fa-pizza-slice fa-2x text-primary"></i>
|
<i class="fas fa-fw fa-pizza-slice fa-2x text-primary"></i>
|
||||||
@ -75,15 +75,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-2 col-2 mt-2 mt-md-0 text-right">
|
<div class="recipe__context-menu col col-md-2 col-2 mt-2 mt-md-0 text-right">
|
||||||
<recipe-context-menu v-bind:recipe="recipe" :servings="servings"
|
<recipe-context-menu v-bind:recipe="recipe" :servings="servings"
|
||||||
:disabled_options="{print:false}" v-if="show_context_menu"></recipe-context-menu>
|
:disabled_options="{print:false}" v-if="show_context_menu"></recipe-context-menu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
<div class="row">
|
<div class="recipe__overview row">
|
||||||
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2"
|
<div class="recipe__ingredients col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2"
|
||||||
v-if="recipe && ingredient_count > 0 && (recipe.show_ingredient_overview || recipe.steps.length < 2)">
|
v-if="recipe && ingredient_count > 0 && (recipe.show_ingredient_overview || recipe.steps.length < 2)">
|
||||||
<ingredients-card
|
<ingredients-card
|
||||||
:recipe="recipe.id"
|
:recipe="recipe.id"
|
||||||
@ -97,7 +97,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2">
|
<div class="recipe__image 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" :alt="$t('Recipe_Image')"
|
<img class="img img-fluid rounded" :src="recipe.image" :alt="$t('Recipe_Image')"
|
||||||
@ -109,16 +109,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!recipe.internal">
|
<template v-if="!recipe.internal">
|
||||||
<div v-if="recipe.file_path.includes('.pdf')">
|
<div v-if="recipe.file_path.includes('.pdf')" class="recipe__file-pdf">
|
||||||
<PdfViewer :recipe="recipe"></PdfViewer>
|
<PdfViewer :recipe="recipe"></PdfViewer>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="recipe.file_path.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg') || recipe.file_path.includes('.gif')">
|
v-if="recipe.file_path.includes('.png') || recipe.file_path.includes('.jpg') || recipe.file_path.includes('.jpeg') || recipe.file_path.includes('.gif')"
|
||||||
|
class="recipe__file-img">
|
||||||
<ImageViewer :recipe="recipe"></ImageViewer>
|
<ImageViewer :recipe="recipe"></ImageViewer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div v-for="(s, index) in recipe.steps" v-bind:key="s.id" style="margin-top: 1vh">
|
<div class="recipe__step" v-for="(s, index) in recipe.steps" v-bind:key="s.id" style="margin-top: 1vh">
|
||||||
<step-component
|
<step-component
|
||||||
:recipe="recipe"
|
:recipe="recipe"
|
||||||
:step="s"
|
:step="s"
|
||||||
@ -130,13 +131,13 @@
|
|||||||
></step-component>
|
></step-component>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="recipe.source_url !== null">
|
<div class="recipe__source" v-if="recipe.source_url !== null">
|
||||||
<h6 class="d-print-none"><i class="fas fa-file-import"></i> {{ $t("Imported_From") }}</h6>
|
<h6 class="d-print-none"><i class="fas fa-file-import"></i> {{ $t("Imported_From") }}</h6>
|
||||||
<span class="text-muted mt-1"><a style="overflow-wrap: break-word;"
|
<span class="text-muted mt-1"><a style="overflow-wrap: break-word;"
|
||||||
:href="recipe.source_url">{{ recipe.source_url }}</a></span>
|
:href="recipe.source_url">{{ recipe.source_url }}</a></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" style="margin-top: 2vh; ">
|
<div class="recipe__properties row" style="margin-top: 2vh; ">
|
||||||
<div class="col-lg-6 offset-lg-3 col-12">
|
<div class="col-lg-6 offset-lg-3 col-12">
|
||||||
<property-view-component :recipe="recipe" :servings="servings" @foodUpdated="loadRecipe(recipe.id)"></property-view-component>
|
<property-view-component :recipe="recipe" :servings="servings" @foodUpdated="loadRecipe(recipe.id)"></property-view-component>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<span v-html="calculateAmount(number)"></span>
|
<span class="step__scalable-num" :class="[this.factor===1 ? 'step__scalable-num_scaled_false' : (this.factor > 1 ? 'step__scalable-num_scaled_up':'step__scalable-num_scaled_down')]" v-html="calculateAmount(number)"></span>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="step" :class="stepClassName" >
|
||||||
<hr/>
|
<hr/>
|
||||||
<!-- Step header (only shown if more than one step -->
|
<!-- Step header (only shown if more than one step -->
|
||||||
<div class="row mb-1" v-if="recipe.steps.length > 1">
|
<div class="row mb-1" v-if="recipe.steps.length > 1">
|
||||||
<div class="col col-md-8">
|
<div class="col col-md-8">
|
||||||
<h5 class="text-primary">
|
<h5 class="step__name text-primary" :class="stepClassNameType">
|
||||||
<template v-if="step.name">{{ step.name }}</template>
|
{{ step_name }}
|
||||||
<template v-else>{{ $t("Step") }} {{ index + 1 }}</template>
|
<small style="margin-left: 4px" class="step__time text-muted" v-if="step.time !== 0"><i
|
||||||
<small style="margin-left: 4px" class="text-muted" v-if="step.time !== 0"><i
|
|
||||||
class="fas fa-user-clock"></i> {{ step_time }}</small>
|
class="fas fa-user-clock"></i> {{ step_time }}</small>
|
||||||
<small v-if="start_time !== ''" class="d-print-none">
|
<small v-if="start_time !== ''" class="step__start-time d-print-none">
|
||||||
<b-link :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#">
|
<b-link :id="`id_reactive_popover_${step.id}`" @click="openPopover" href="#">
|
||||||
{{ moment(start_time).add(step.time_offset, "minutes").format("HH:mm") }}
|
{{ moment(start_time).add(step.time_offset, "minutes").format("HH:mm") }}
|
||||||
</b-link>
|
</b-link>
|
||||||
@ -20,19 +19,19 @@
|
|||||||
<b-button
|
<b-button
|
||||||
@click="details_visible = !details_visible"
|
@click="details_visible = !details_visible"
|
||||||
style="border: none; background: none"
|
style="border: none; background: none"
|
||||||
class="shadow-none d-print-none"
|
class="shadow-none d-print-none step__button-collapse"
|
||||||
:class="{ 'text-primary': details_visible, 'text-success': !details_visible }"
|
:class="{ 'step__button-collapse_visible text-primary': details_visible, 'step_button-collapse_visible_false text-success': !details_visible }"
|
||||||
>
|
>
|
||||||
<i class="far fa-check-circle"></i>
|
<i class="far fa-check-circle"></i>
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<b-collapse id="collapse-1" v-model="details_visible">
|
<b-collapse id="collapse-1" class="step__details" :class="[details_visible ? 'step__details_visible':'step__details_visible_false']" v-model="details_visible">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- ingredients table -->
|
<!-- ingredients table -->
|
||||||
<div class="col col-md-4"
|
<div class="step__ingredients col col-md-4"
|
||||||
v-if="step.show_ingredients_table && step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)">
|
v-if="step.show_ingredients_table && step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)">
|
||||||
<table class="table table-sm">
|
<table class="table table-sm">
|
||||||
<ingredients-card :steps="[step]" :ingredient_factor="ingredient_factor"
|
<ingredients-card :steps="[step]" :ingredient_factor="ingredient_factor"
|
||||||
@ -40,7 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col"
|
<div class="step__instructions col"
|
||||||
:class="{ 'col-md-8 col-12': recipe.steps.length > 1, 'col-md-12 col-12': recipe.steps.length <= 1 }">
|
:class="{ 'col-md-8 col-12': recipe.steps.length > 1, 'col-md-12 col-12': recipe.steps.length <= 1 }">
|
||||||
<!-- step text -->
|
<!-- step text -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -51,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- File (preview if image, download else) -->
|
<!-- File (preview if image, download else) -->
|
||||||
<div class="row" v-if="step.file !== null">
|
<div class="step__file row" v-if="step.file !== null">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
@ -71,10 +70,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sub recipe (always full width own row) -->
|
<!-- Sub recipe (always full width own row) -->
|
||||||
<div class="row">
|
<div class="step__subrecipe row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<div class="card" v-if="step.step_recipe_data !== null">
|
<div class="card" v-if="step.step_recipe_data !== null">
|
||||||
<b-collapse id="collapse-1" v-model="details_visible">
|
<b-collapse id="collapse-1" :class="[details_visible ? 'step__details_visible':'step__details_visible_false']" v-model="details_visible">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="card-title">
|
<h2 class="card-title">
|
||||||
<a :href="resolveDjangoUrl('view_recipe', step.step_recipe_data.id)">{{
|
<a :href="resolveDjangoUrl('view_recipe', step.step_recipe_data.id)">{{
|
||||||
@ -128,13 +127,13 @@ import CompileComponent from "@/components/CompileComponent"
|
|||||||
import IngredientsCard from "@/components/IngredientsCard"
|
import IngredientsCard from "@/components/IngredientsCard"
|
||||||
import Vue from "vue"
|
import Vue from "vue"
|
||||||
import moment from "moment"
|
import moment from "moment"
|
||||||
import {ResolveUrlMixin, calculateHourMinuteSplit} from "@/utils/utils"
|
import {ResolveUrlMixin, calculateHourMinuteSplit, EscapeCSSMixin} from "@/utils/utils"
|
||||||
|
|
||||||
Vue.prototype.moment = moment
|
Vue.prototype.moment = moment
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "StepComponent",
|
name: "StepComponent",
|
||||||
mixins: [GettextMixin, ResolveUrlMixin],
|
mixins: [GettextMixin, ResolveUrlMixin, EscapeCSSMixin],
|
||||||
components: {CompileComponent, IngredientsCard},
|
components: {CompileComponent, IngredientsCard},
|
||||||
props: {
|
props: {
|
||||||
step: Object,
|
step: Object,
|
||||||
@ -149,7 +148,27 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
step_time: function() {
|
step_time: function() {
|
||||||
return calculateHourMinuteSplit(this.step.time)},
|
return calculateHourMinuteSplit(this.step.time)
|
||||||
|
},
|
||||||
|
step_name: function() {
|
||||||
|
if (this.step.name) {
|
||||||
|
return this.step.name
|
||||||
|
}
|
||||||
|
return this.$t("Step") + ' ' + String(this.index+1)
|
||||||
|
},
|
||||||
|
stepClassName: function() {
|
||||||
|
let classes = {}
|
||||||
|
const nameclass = this.escapeCSS("_stepname-" + this.step_name)
|
||||||
|
classes[nameclass] = !!this.step.name
|
||||||
|
classes['_stepname-' + String(this.index+1)] = !this.step.name
|
||||||
|
return classes
|
||||||
|
},
|
||||||
|
stepClassNameType: function() {
|
||||||
|
let classes = {}
|
||||||
|
classes['step__name_custom'] = !!this.step.name
|
||||||
|
classes['step__name_custom_false'] = !this.step.name
|
||||||
|
return classes
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -178,7 +197,7 @@ export default {
|
|||||||
},
|
},
|
||||||
openPopover: function () {
|
openPopover: function () {
|
||||||
this.$refs[`id_reactive_popover_${this.step.id}`].$emit("open")
|
this.$refs[`id_reactive_popover_${this.step.id}`].$emit("open")
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -317,6 +317,15 @@ export function calculateAmount(amount, factor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Replace spaces by dashes, then use DOM method to escape special characters. Use for dynamically generated CSS classes*/
|
||||||
|
export const EscapeCSSMixin = {
|
||||||
|
methods: {
|
||||||
|
escapeCSS: function(classname) {
|
||||||
|
return CSS.escape(classname.replace(/\s+/g, "-").toLowerCase())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function roundDecimals(num) {
|
export function roundDecimals(num) {
|
||||||
let decimals = getUserPreference("user_fractions") ? getUserPreference("user_fractions") : 2
|
let decimals = getUserPreference("user_fractions") ? getUserPreference("user_fractions") : 2
|
||||||
return +(Math.round(num + `e+${decimals}`) + `e-${decimals}`)
|
return +(Math.round(num + `e+${decimals}`) + `e-${decimals}`)
|
||||||
|
Loading…
Reference in New Issue
Block a user