Merge pull request #2539 from srwareham/hide-step-ingredients

Added option: Hide step ingredients
This commit is contained in:
vabene1111 2023-08-24 10:33:57 +02:00 committed by GitHub
commit 2f0929e90e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 87 additions and 38 deletions

View File

@ -46,6 +46,7 @@ class UserPreferenceForm(forms.ModelForm):
fields = ( fields = (
'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color', 'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color',
'sticky_navbar', 'default_page', 'plan_share', 'ingredient_decimals', 'comments', 'left_handed', 'sticky_navbar', 'default_page', 'plan_share', 'ingredient_decimals', 'comments', 'left_handed',
'show_step_ingredients',
) )
labels = { labels = {
@ -60,7 +61,8 @@ class UserPreferenceForm(forms.ModelForm):
'ingredient_decimals': _('Ingredient decimal places'), 'ingredient_decimals': _('Ingredient decimal places'),
'shopping_auto_sync': _('Shopping list auto sync period'), 'shopping_auto_sync': _('Shopping list auto sync period'),
'comments': _('Comments'), 'comments': _('Comments'),
'left_handed': _('Left-handed mode') 'left_handed': _('Left-handed mode'),
'show_step_ingredients': _('Show step ingredients table')
} }
help_texts = { help_texts = {
@ -82,7 +84,8 @@ class UserPreferenceForm(forms.ModelForm):
'sticky_navbar': _('Makes the navbar stick to the top of the page.'), 'sticky_navbar': _('Makes the navbar stick to the top of the page.'),
'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'), 'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'),
'mealplan_autoexclude_onhand': _('Exclude ingredients that are on hand.'), 'mealplan_autoexclude_onhand': _('Exclude ingredients that are on hand.'),
'left_handed': _('Will optimize the UI for use with your left hand.') 'left_handed': _('Will optimize the UI for use with your left hand.'),
'show_step_ingredients': _('Add ingredients table next to recipe steps. Applies at creation time for manually created and URL imported recipes. Individual steps can be overridden in the edit recipe view.')
} }
widgets = { widgets = {

View File

@ -147,7 +147,7 @@ def get_from_scraper(scrape, request):
recipe_json['steps'] = [] recipe_json['steps'] = []
try: try:
for i in parse_instructions(scrape.instructions()): for i in parse_instructions(scrape.instructions()):
recipe_json['steps'].append({'instruction': i, 'ingredients': [], }) recipe_json['steps'].append({'instruction': i, 'ingredients': [], 'show_ingredients_table': request.user.userpreference.show_step_ingredients,})
except Exception: except Exception:
pass pass
if len(recipe_json['steps']) == 0: if len(recipe_json['steps']) == 0:

View File

@ -36,7 +36,7 @@ class ChefTap(Integration):
recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, space=self.request.space, ) recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, space=self.request.space, )
step = Step.objects.create(instruction='\n'.join(directions), space=self.request.space,) step = Step.objects.create(instruction='\n'.join(directions), space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,)
if source_url != '': if source_url != '':
step.instruction += '\n' + source_url step.instruction += '\n' + source_url

View File

@ -55,7 +55,7 @@ class Chowdown(Integration):
recipe.keywords.add(keyword) recipe.keywords.add(keyword)
step = Step.objects.create( step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n' + '\n'.join(descriptions), space=self.request.space, instruction='\n'.join(directions) + '\n\n' + '\n'.join(descriptions), space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)

View File

@ -47,7 +47,7 @@ class CookBookApp(Integration):
pass pass
# assuming import files only contain single step # assuming import files only contain single step
step = Step.objects.create(instruction=recipe_json['steps'][0]['instruction'], space=self.request.space, ) step = Step.objects.create(instruction=recipe_json['steps'][0]['instruction'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, )
if 'nutrition' in recipe_json: if 'nutrition' in recipe_json:
step.instruction = step.instruction + '\n\n' + recipe_json['nutrition'] step.instruction = step.instruction + '\n\n' + recipe_json['nutrition']

View File

@ -50,7 +50,7 @@ class Cookmate(Integration):
for step in recipe_text.getchildren(): for step in recipe_text.getchildren():
if step.text: if step.text:
step = Step.objects.create( step = Step.objects.create(
instruction=step.text.strip(), space=self.request.space, instruction=step.text.strip(), space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
recipe.steps.add(step) recipe.steps.add(step)

View File

@ -51,7 +51,7 @@ class CopyMeThat(Integration):
except AttributeError: except AttributeError:
pass pass
step = Step.objects.create(instruction='', space=self.request.space, ) step = Step.objects.create(instruction='', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)

View File

@ -28,7 +28,7 @@ class Domestica(Integration):
recipe.save() recipe.save()
step = Step.objects.create( step = Step.objects.create(
instruction=file['directions'], space=self.request.space, instruction=file['directions'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
if file['source'] != '': if file['source'] != '':

View File

@ -25,7 +25,7 @@ class Mealie(Integration):
created_by=self.request.user, internal=True, space=self.request.space) created_by=self.request.user, internal=True, space=self.request.space)
for s in recipe_json['recipe_instructions']: for s in recipe_json['recipe_instructions']:
step = Step.objects.create(instruction=s['text'], space=self.request.space, ) step = Step.objects.create(instruction=s['text'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, )
recipe.steps.add(step) recipe.steps.add(step)
step = recipe.steps.first() step = recipe.steps.first()

View File

@ -39,7 +39,7 @@ class MealMaster(Integration):
recipe.keywords.add(keyword) recipe.keywords.add(keyword)
step = Step.objects.create( step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n', space=self.request.space, instruction='\n'.join(directions) + '\n\n', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)

View File

@ -67,7 +67,7 @@ class MelaRecipes(Integration):
f = ingredient_parser.get_food(food) f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit) u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create( step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
)) ))
recipe.steps.add(step) recipe.steps.add(step)

View File

@ -54,11 +54,11 @@ class NextcloudCookbook(Integration):
instruction_text = '' instruction_text = ''
if 'text' in s: if 'text' in s:
step = Step.objects.create( step = Step.objects.create(
instruction=s['text'], name=s['name'], space=self.request.space, instruction=s['text'], name=s['name'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
else: else:
step = Step.objects.create( step = Step.objects.create(
instruction=s, space=self.request.space, instruction=s, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
if not ingredients_added: if not ingredients_added:
if len(recipe_json['description'].strip()) > 500: if len(recipe_json['description'].strip()) > 500:

View File

@ -51,7 +51,7 @@ class OpenEats(Integration):
recipe.image = f'recipes/openeats-import/{file["photo"]}' recipe.image = f'recipes/openeats-import/{file["photo"]}'
recipe.save() recipe.save()
step = Step.objects.create(instruction=instructions, space=self.request.space,) step = Step.objects.create(instruction=instructions, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,)
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)
for ingredient in file['ingredients']: for ingredient in file['ingredients']:

View File

@ -58,7 +58,7 @@ class Paprika(Integration):
pass pass
step = Step.objects.create( step = Step.objects.create(
instruction=instructions, space=self.request.space, instruction=instructions, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
if 'description' in recipe_json and len(recipe_json['description'].strip()) > 500: if 'description' in recipe_json and len(recipe_json['description'].strip()) > 500:

View File

@ -35,7 +35,7 @@ class Pepperplate(Integration):
recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space) recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space)
step = Step.objects.create( step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n', space=self.request.space, instruction='\n'.join(directions) + '\n\n', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)

View File

@ -46,7 +46,7 @@ class Plantoeat(Integration):
recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space) recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space)
step = Step.objects.create( step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n', space=self.request.space, instruction='\n'.join(directions) + '\n\n', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
if tags: if tags:

View File

@ -46,7 +46,7 @@ class RecetteTek(Integration):
if not instructions: if not instructions:
instructions = '' instructions = ''
step = Step.objects.create(instruction=instructions, space=self.request.space,) step = Step.objects.create(instruction=instructions, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,)
# Append the original import url to the step (if it exists) # Append the original import url to the step (if it exists)
try: try:

View File

@ -41,7 +41,7 @@ class RecipeKeeper(Integration):
except AttributeError: except AttributeError:
pass pass
step = Step.objects.create(instruction='', space=self.request.space, ) step = Step.objects.create(instruction='', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)
for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"): for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"):

View File

@ -49,7 +49,7 @@ class RecipeSage(Integration):
f = ingredient_parser.get_food(food) f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit) u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create( step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
)) ))
recipe.steps.add(step) recipe.steps.add(step)

View File

@ -37,7 +37,7 @@ class Rezeptsuitede(Integration):
try: try:
if prep.find('step').text: if prep.find('step').text:
step = Step.objects.create( step = Step.objects.create(
instruction=prep.find('step').text.strip(), space=self.request.space, instruction=prep.find('step').text.strip(), space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
recipe.steps.add(step) recipe.steps.add(step)
except Exception: except Exception:

View File

@ -38,7 +38,7 @@ class RezKonv(Integration):
recipe.keywords.add(keyword) recipe.keywords.add(keyword)
step = Step.objects.create( step = Step.objects.create(
instruction=' \n'.join(directions) + '\n\n', space=self.request.space, instruction=' \n'.join(directions) + '\n\n', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
) )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)

View File

@ -43,7 +43,7 @@ class Saffron(Integration):
recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space, ) recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space, )
step = Step.objects.create(instruction='\n'.join(directions), space=self.request.space, ) step = Step.objects.create(instruction='\n'.join(directions), space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, )
ingredient_parser = IngredientParser(self.request, True) ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients: for ingredient in ingredients:

View File

@ -394,6 +394,7 @@ class UserPreference(models.Model, PermissionModelMixin):
shopping_add_onhand = models.BooleanField(default=False) shopping_add_onhand = models.BooleanField(default=False)
filter_to_supermarket = models.BooleanField(default=False) filter_to_supermarket = models.BooleanField(default=False)
left_handed = models.BooleanField(default=False) left_handed = models.BooleanField(default=False)
show_step_ingredients = models.BooleanField(default=True)
default_delay = models.DecimalField(default=4, max_digits=8, decimal_places=4) default_delay = models.DecimalField(default=4, max_digits=8, decimal_places=4)
shopping_recent_days = models.PositiveIntegerField(default=7) shopping_recent_days = models.PositiveIntegerField(default=7)
csv_delim = models.CharField(max_length=2, default=",") csv_delim = models.CharField(max_length=2, default=",")
@ -738,6 +739,7 @@ class Step(ExportModelOperationsMixin('step'), models.Model, PermissionModelMixi
order = models.IntegerField(default=0) order = models.IntegerField(default=0)
file = models.ForeignKey('UserFile', on_delete=models.PROTECT, null=True, blank=True) file = models.ForeignKey('UserFile', on_delete=models.PROTECT, null=True, blank=True)
show_as_header = models.BooleanField(default=True) show_as_header = models.BooleanField(default=True)
show_ingredients_table = models.BooleanField(default=True)
search_vector = SearchVectorField(null=True) search_vector = SearchVectorField(null=True)
step_recipe = models.ForeignKey('Recipe', default=None, blank=True, null=True, on_delete=models.PROTECT) step_recipe = models.ForeignKey('Recipe', default=None, blank=True, null=True, on_delete=models.PROTECT)

View File

@ -376,7 +376,7 @@ class UserPreferenceSerializer(WritableNestedModelSerializer):
'food_inherit_default', 'default_delay', 'food_inherit_default', 'default_delay',
'mealplan_autoinclude_related', 'mealplan_autoexclude_onhand', 'shopping_share', 'shopping_recent_days', 'mealplan_autoinclude_related', 'mealplan_autoexclude_onhand', 'shopping_share', 'shopping_recent_days',
'csv_delim', 'csv_prefix', 'csv_delim', 'csv_prefix',
'filter_to_supermarket', 'shopping_add_onhand', 'left_handed', 'food_children_exist' 'filter_to_supermarket', 'shopping_add_onhand', 'left_handed', 'show_step_ingredients', 'food_children_exist'
) )
@ -771,7 +771,8 @@ class StepSerializer(WritableNestedModelSerializer, ExtendedRecipeMixin):
model = Step model = Step
fields = ( fields = (
'id', 'name', 'instruction', 'ingredients', 'ingredients_markdown', 'id', 'name', 'instruction', 'ingredients', 'ingredients_markdown',
'ingredients_vue', 'time', 'order', 'show_as_header', 'file', 'step_recipe', 'step_recipe_data', 'numrecipe' 'ingredients_vue', 'time', 'order', 'show_as_header', 'file', 'step_recipe',
'step_recipe_data', 'numrecipe', 'show_ingredients_table'
) )
@ -1362,7 +1363,7 @@ class StepExportSerializer(WritableNestedModelSerializer):
class Meta: class Meta:
model = Step model = Step
fields = ('name', 'instruction', 'ingredients', 'time', 'order', 'show_as_header') fields = ('name', 'instruction', 'ingredients', 'time', 'order', 'show_as_header', 'show_ingredients_table')
class RecipeExportSerializer(WritableNestedModelSerializer): class RecipeExportSerializer(WritableNestedModelSerializer):

View File

@ -334,6 +334,8 @@ class StepFactory(factory.django.DjangoModelFactory):
order = factory.Sequence(lambda x: x) order = factory.Sequence(lambda x: x)
# file = models.ForeignKey('UserFile', on_delete=models.PROTECT, null=True, blank=True) # file = models.ForeignKey('UserFile', on_delete=models.PROTECT, null=True, blank=True)
show_as_header = True show_as_header = True
# TODO: need to update to fetch from User's preferences
show_step_ingredients = True
step_recipe__has_recipe = False step_recipe__has_recipe = False
ingredients__food_recipe_count = 0 ingredients__food_recipe_count = 0
space = factory.SubFactory(SpaceFactory) space = factory.SubFactory(SpaceFactory)

View File

@ -37,7 +37,7 @@ class RecipeCreate(GroupRequiredMixin, CreateView):
obj.space = self.request.space obj.space = self.request.space
obj.internal = True obj.internal = True
obj.save() obj.save()
obj.steps.add(Step.objects.create(space=self.request.space, show_as_header=False)) obj.steps.add(Step.objects.create(space=self.request.space, show_as_header=False, show_ingredients_table=self.request.user.userpreference.show_step_ingredients))
return HttpResponseRedirect(reverse('edit_recipe', kwargs={'pk': obj.pk})) return HttpResponseRedirect(reverse('edit_recipe', kwargs={'pk': obj.pk}))
def get_success_url(self): def get_success_url(self):

View File

@ -103,6 +103,7 @@
import draggable from "vuedraggable"; import draggable from "vuedraggable";
import stringSimilarity from "string-similarity" import stringSimilarity from "string-similarity"
import {getUserPreference} from "@/utils/utils"
export default { export default {
name: "ImportViewStepEditor", name: "ImportViewStepEditor",
@ -117,6 +118,7 @@ export default {
recipe_json: undefined, recipe_json: undefined,
current_edit_ingredient: null, current_edit_ingredient: null,
current_edit_step: null, current_edit_step: null,
user_preferences: null,
} }
}, },
watch: { watch: {
@ -126,6 +128,7 @@ export default {
}, },
mounted() { mounted() {
this.recipe_json = this.recipe this.recipe_json = this.recipe
this.user_preferences = getUserPreference();
}, },
methods: { methods: {
/** /**
@ -138,7 +141,7 @@ export default {
let steps = [] let steps = []
step.instruction.split(split_character).forEach(part => { step.instruction.split(split_character).forEach(part => {
if (part.trim() !== '') { if (part.trim() !== '') {
steps.push({'instruction': part, 'ingredients': []}) steps.push({'instruction': part, 'ingredients': [], 'show_ingredients_table': this.user_preferences.show_step_ingredients})
} }
}) })
steps[0].ingredients = step.ingredients // put all ingredients from the original step in the ingredients of the first step of the split step list steps[0].ingredients = step.ingredients // put all ingredients from the original step in the ingredients of the first step of the split step list

View File

@ -240,6 +240,16 @@
v-if="step_index !== recipe.steps.length - 1"> v-if="step_index !== recipe.steps.length - 1">
<i class="fa fa-arrow-down fa-fw"></i> {{ $t("Move_Down") }} <i class="fa fa-arrow-down fa-fw"></i> {{ $t("Move_Down") }}
</button> </button>
<!-- Show "Hide step ingredients if state is currently set to shown" -->
<button class="dropdown-item" @click="setStepShowIngredientsTable(step, false)"
v-if="step.show_ingredients_table">
<i class="op-icon fa fa-mavon-eye-slash"></i> {{ $t("hide_step_ingredients") }}
</button>
<!-- Show "Show step ingredients if state is currently set to hidden" -->
<button class="dropdown-item" @click="setStepShowIngredientsTable(step, true)"
v-if="! step.show_ingredients_table">
<i class="op-icon fa fa-mavon-eye"></i> {{ $t("show_step_ingredients") }}
</button>
</div> </div>
</div> </div>
</div> </div>
@ -270,7 +280,6 @@
@click="step.time_visible = true" v-if="!step.time_visible"> @click="step.time_visible = true" v-if="!step.time_visible">
<i class="fas fa-plus-circle"></i> {{ $t("Time") }} <i class="fas fa-plus-circle"></i> {{ $t("Time") }}
</b-button> </b-button>
<b-button pill variant="primary" size="sm" class="ml-1 mb-1 mb-md-0" <b-button pill variant="primary" size="sm" class="ml-1 mb-1 mb-md-0"
@click="step.ingredients_visible = true" v-if="!step.ingredients_visible"> @click="step.ingredients_visible = true" v-if="!step.ingredients_visible">
<i class="fas fa-plus-circle"></i> {{ $t("Ingredients") }} <i class="fas fa-plus-circle"></i> {{ $t("Ingredients") }}
@ -770,7 +779,8 @@ import {
ResolveUrlMixin, ResolveUrlMixin,
StandardToasts, StandardToasts,
convertEnergyToCalories, convertEnergyToCalories,
energyHeading energyHeading,
getUserPreference
} from "@/utils/utils" } from "@/utils/utils"
import Multiselect from "vue-multiselect" import Multiselect from "vue-multiselect"
import {ApiApiFactory} from "@/utils/openapi/api" import {ApiApiFactory} from "@/utils/openapi/api"
@ -813,6 +823,7 @@ export default {
show_file_create: false, show_file_create: false,
step_for_file_create: undefined, step_for_file_create: undefined,
use_plural: false, use_plural: false,
user_preferences: undefined,
additional_visible: false, additional_visible: false,
create_food: undefined, create_food: undefined,
md_editor_toolbars: { md_editor_toolbars: {
@ -858,9 +869,9 @@ export default {
this.searchKeywords("") this.searchKeywords("")
this.searchFiles("") this.searchFiles("")
this.searchRecipes("") this.searchRecipes("")
this.$i18n.locale = window.CUSTOM_LOCALE this.$i18n.locale = window.CUSTOM_LOCALE
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
this.user_preferences = getUserPreference()
apiClient.retrieveSpace(window.ACTIVE_SPACE_ID).then(r => { apiClient.retrieveSpace(window.ACTIVE_SPACE_ID).then(r => {
this.use_plural = r.data.use_plural this.use_plural = r.data.use_plural
}) })
@ -925,7 +936,10 @@ export default {
// set default visibility style for each component of the step // set default visibility style for each component of the step
this.recipe.steps.forEach((s) => { this.recipe.steps.forEach((s) => {
this.$set(s, "time_visible", s.time !== 0) this.$set(s, "time_visible", s.time !== 0)
this.$set(s, "ingredients_visible", s.ingredients.length > 0 || this.recipe.steps.length === 1) // ingredients_visible determines whether or not the ingredients UI is shown in the edit view
// show_ingredients_table determine whether the ingredients table is shown in the read view
// these are seperate as one might want to add ingredients but not want the step-level view
this.$set(s, "ingredients_visible", s.show_ingredients_table && (s.ingredients.length > 0 || this.recipe.steps.length === 1))
this.$set(s, "instruction_visible", s.instruction !== "" || this.recipe.steps.length === 1) this.$set(s, "instruction_visible", s.instruction !== "" || this.recipe.steps.length === 1)
this.$set(s, "step_recipe_visible", s.step_recipe !== null) this.$set(s, "step_recipe_visible", s.step_recipe !== null)
this.$set(s, "file_visible", s.file !== null) this.$set(s, "file_visible", s.file !== null)
@ -1028,6 +1042,7 @@ export default {
show_as_header: false, show_as_header: false,
time_visible: false, time_visible: false,
ingredients_visible: true, ingredients_visible: true,
show_ingredients_table: this.user_preferences.show_step_ingredients,
instruction_visible: true, instruction_visible: true,
step_recipe_visible: false, step_recipe_visible: false,
file_visible: false, file_visible: false,
@ -1083,6 +1098,9 @@ export default {
this.recipe.steps.splice(new_index < 0 ? 0 : new_index, 0, step) this.recipe.steps.splice(new_index < 0 ? 0 : new_index, 0, step)
this.sortSteps() this.sortSteps()
}, },
setStepShowIngredientsTable: function (step, show_state) {
step.show_ingredients_table = show_state
},
moveIngredient: function (step, ingredient, new_index) { moveIngredient: function (step, ingredient, new_index) {
step.ingredients.splice(step.ingredients.indexOf(ingredient), 1) step.ingredients.splice(step.ingredients.indexOf(ingredient), 1)
step.ingredients.splice(new_index < 0 ? 0 : new_index, 0, ingredient) step.ingredients.splice(new_index < 0 ? 0 : new_index, 0, ingredient)

View File

@ -31,6 +31,12 @@
</b-form-checkbox> </b-form-checkbox>
</b-form-group> </b-form-group>
<b-form-group :description="$t('show_step_ingredients_setting_help')">
<b-form-checkbox v-model="user_preferences.show_step_ingredients" @change="updateSettings(false);">
{{ $t('show_step_ingredients_setting') }}
</b-form-checkbox>
</b-form-group>
<hr/> <hr/>

View File

@ -33,7 +33,7 @@
<div class="row"> <div class="row">
<!-- ingredients table --> <!-- ingredients table -->
<div class="col col-md-4" <div class="col col-md-4"
v-if="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"
@checked-state-changed="$emit('checked-state-changed', $event)"/> @checked-state-changed="$emit('checked-state-changed', $event)"/>
@ -124,10 +124,7 @@
</template> </template>
<script> <script>
import {calculateAmount} from "@/utils/utils" import {calculateAmount, GettextMixin, getUserPreference} from "@/utils/utils"
import {GettextMixin} from "@/utils/utils"
import CompileComponent from "@/components/CompileComponent" import CompileComponent from "@/components/CompileComponent"
import IngredientsCard from "@/components/IngredientsCard" import IngredientsCard from "@/components/IngredientsCard"
import Vue from "vue" import Vue from "vue"

View File

@ -369,6 +369,10 @@
"filter_name": "Filter Name", "filter_name": "Filter Name",
"left_handed": "Left-handed mode", "left_handed": "Left-handed mode",
"left_handed_help": "Will optimize the UI for use with your left hand.", "left_handed_help": "Will optimize the UI for use with your left hand.",
"show_step_ingredients_setting": "Show Ingredients Next To Recipe Steps",
"show_step_ingredients_setting_help": "Add ingredients table next to recipe steps. Applies at creation time. Can be overridden in the edit recipe view.",
"show_step_ingredients": "Show Step Ingredients",
"hide_step_ingredients": "Hide Step Ingredients",
"Custom Filter": "Custom Filter", "Custom Filter": "Custom Filter",
"shared_with": "Shared With", "shared_with": "Shared With",
"sort_by": "Sort By", "sort_by": "Sort By",
@ -424,6 +428,7 @@
"ChildInheritFields": "Children Inherit Fields", "ChildInheritFields": "Children Inherit Fields",
"ChildInheritFields_help": "Children will inherit these fields by default.", "ChildInheritFields_help": "Children will inherit these fields by default.",
"InheritFields_help": "The values of these fields will be inherited from parent (Exception: blank shopping categories are not inherited)", "InheritFields_help": "The values of these fields will be inherited from parent (Exception: blank shopping categories are not inherited)",
"show_ingredients_table": "Display a table of the ingredients next to the step's text",
"show_ingredient_overview": "Display a list of all ingredients at the start of the recipe.", "show_ingredient_overview": "Display a list of all ingredients at the start of the recipe.",
"Ingredient Overview": "Ingredient Overview", "Ingredient Overview": "Ingredient Overview",
"last_viewed": "Last Viewed", "last_viewed": "Last Viewed",

View File

@ -4575,6 +4575,12 @@ export interface Step {
* @memberof Step * @memberof Step
*/ */
numrecipe?: string; numrecipe?: string;
/**
*
* @type {boolean}
* @memberof Step
*/
show_ingredeints_table?: boolean;
} }
/** /**
* *
@ -5180,6 +5186,12 @@ export interface UserPreference {
* @memberof UserPreference * @memberof UserPreference
*/ */
left_handed?: boolean; left_handed?: boolean;
/**
*
* @type {boolean}
* @memberof UserPreference
*/
show_step_ingredients?: boolean;
/** /**
* *
* @type {string} * @type {string}