Compare commits

...

5 Commits
2.2.5 ... 2.2.7

Author SHA1 Message Date
vabene1111
8572f338ad fixed ingredient insert focus error 2025-09-25 21:03:35 +02:00
vabene1111
920ec8e74b fixed missing pg extensions 2025-09-25 20:56:53 +02:00
vabene1111
2328bf2342 fixed mealie edgecases 2025-09-25 20:48:20 +02:00
vabene1111
85620a1431 Merge branch 'master' into develop 2025-09-25 12:33:43 +02:00
vabene1111
0037858885 fixed step editor layout 2025-09-25 12:33:39 +02:00
4 changed files with 77 additions and 48 deletions

View File

@@ -138,6 +138,16 @@ class Mealie1(Integration):
if s['recipe_id'] not in first_step_of_recipe_dict:
first_step_of_recipe_dict[s['recipe_id']] = step.pk
# it is possible for a recipe to not have steps but have ingredients, in that case create an empty step to add them to later
for r in recipes_dict.keys():
if r not in first_step_of_recipe_dict:
step = Step.objects.create(instruction='',
order=0,
name='',
space=self.request.space)
steps_relation.append(Recipe.steps.through(recipe_id=recipes_dict[r], step_id=step.pk))
first_step_of_recipe_dict[r] = step.pk
for n in mealie_database['notes']:
if n['recipe_id'] in recipes_dict:
step = Step.objects.create(instruction=n['text'],
@@ -169,7 +179,7 @@ class Mealie1(Integration):
unit_id=units_dict[i['unit_id']] if i['unit_id'] in units_dict else None,
original_text=i['original_text'],
order=i['position'],
amount=i['quantity'],
amount=i['quantity'] if i['quantity'] else 0,
note=i['note'],
space=self.request.space,
)

View File

@@ -16,7 +16,7 @@ import uuid
from django.conf import settings
from django.db import migrations, models
from cookbook.models import SearchFields
from django.contrib.postgres.operations import TrigramExtension, UnaccentExtension
def allSearchFields():
return list(SearchFields.objects.values_list('id', flat=True))
@@ -141,6 +141,8 @@ class Migration(migrations.Migration):
]
operations = [
TrigramExtension(),
UnaccentExtension(),
migrations.RunPython(create_default_groups),
migrations.CreateModel(
name='AiProvider',

View File

@@ -0,0 +1,15 @@
# Generated by Django 5.2.6 on 2025-09-25 18:56
from django.db import migrations
from django.contrib.postgres.operations import TrigramExtension, UnaccentExtension
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0229_alter_ailog_options_alter_aiprovider_options_and_more'),
]
operations = [
TrigramExtension(),
UnaccentExtension(),
]

View File

@@ -60,56 +60,58 @@
<v-label>{{ $t('Ingredients') }}</v-label>
<div v-if="!mobile">
<vue-draggable v-model="step.ingredients" handle=".drag-handle" :on-sort="sortIngredients" :empty-insert-threshold="25" group="ingredients">
<v-row v-for="(ingredient, index) in step.ingredients" :key="ingredient.id" class="d-flex flex-nowrap" dense>
<v-col cols="12" class="pa-0 ma-0 text-center text-disabled" v-if="ingredient.originalText">
<div v-for="(ingredient, index) in step.ingredients" :key="ingredient.id" dense>
<div class="pa-0 ma-0 text-center text-disabled" v-if="ingredient.originalText">
<v-icon icon="$import" size="x-small"></v-icon>
{{ ingredient.originalText }}
</v-col>
<div class="flex-col flex-grow-0 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader">
<v-text-field :id="`id_input_amount_${step.id}_${index}`" :label="$t('Amount')" type="number" v-model="ingredient.amount" density="compact"
hide-details :disabled="ingredient.noAmount">
</div>
<div class="d-flex flex-nowrap">
<div class="flex-col flex-grow-0 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader">
<v-text-field :id="`id_input_amount_${props.stepIndex}_${index}`" :label="$t('Amount')" type="number" v-model="ingredient.amount" density="compact"
hide-details :disabled="ingredient.noAmount">
<template #prepend>
<v-icon icon="$dragHandle" class="drag-handle cursor-grab"></v-icon>
</template>
</v-text-field>
</div>
<div class="flex-col flex-grow-0 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader ">
<model-select model="Unit" v-model="ingredient.unit" density="compact" allow-create hide-details :disabled="ingredient.noAmount"></model-select>
</div>
<div class="flex-col flex-grow-1 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader">
<model-select model="Food" v-model="ingredient.food" density="compact" allow-create hide-details></model-select>
</div>
<div class="flex-col ma-1" style="min-width: 15%" :class="{'flex-grow-1': ingredient.isHeader, 'flex-grow-0': !ingredient.isHeader}" @keydown.tab="event => handleIngredientNoteTab(event, index)">
<v-text-field :label="(ingredient.isHeader) ? $t('Headline') : $t('Note')" v-model="ingredient.note" density="compact" hide-details>
<template #prepend v-if="ingredient.isHeader">
<v-icon icon="$dragHandle" class="drag-handle cursor-grab"></v-icon>
</template>
</v-text-field>
</div>
<div class="flex-col flex-grow-0 d-flex ma-1">
<div class="d-flex align-center justify-center">
<v-btn variant="plain" class="" density="compact" tabindex="-1" icon>
<v-icon icon="$menu"></v-icon>
<v-menu activator="parent">
<v-list>
<v-list-item link>
<v-switch v-model="step.ingredients[index].isHeader" :label="$t('Headline')" hide-details></v-switch>
</v-list-item>
<v-list-item link>
<v-switch v-model="step.ingredients[index].noAmount" :label="$t('Disable_Amount')" hide-details></v-switch>
</v-list-item>
<v-list-item @click="editingIngredientIndex = index; dialogIngredientSorter = true" prepend-icon="fa-solid fa-sort">
{{ $t('Move') }}
</v-list-item>
<v-list-item @click="step.ingredients.splice(index, 1)" prepend-icon="$delete">{{ $t('Delete') }}</v-list-item>
</v-list>
</v-menu>
</v-btn>
<template #prepend>
<v-icon icon="$dragHandle" class="drag-handle cursor-grab"></v-icon>
</template>
</v-text-field>
</div>
<div class="flex-col flex-grow-0 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader ">
<model-select model="Unit" v-model="ingredient.unit" density="compact" allow-create hide-details :disabled="ingredient.noAmount"></model-select>
</div>
<div class="flex-col flex-grow-1 ma-1" style="min-width: 15%" v-if="!ingredient.isHeader">
<model-select model="Food" v-model="ingredient.food" density="compact" allow-create hide-details></model-select>
</div>
<div class="flex-col ma-1" style="min-width: 15%" :class="{'flex-grow-1': ingredient.isHeader, 'flex-grow-0': !ingredient.isHeader}"
@keydown.tab="event => handleIngredientNoteTab(event, index)">
<v-text-field :label="(ingredient.isHeader) ? $t('Headline') : $t('Note')" v-model="ingredient.note" density="compact" hide-details>
<template #prepend v-if="ingredient.isHeader">
<v-icon icon="$dragHandle" class="drag-handle cursor-grab"></v-icon>
</template>
</v-text-field>
</div>
<div class="flex-col flex-grow-0 d-flex ma-1">
<div class="d-flex align-center justify-center">
<v-btn variant="plain" class="" density="compact" tabindex="-1" icon>
<v-icon icon="$menu"></v-icon>
<v-menu activator="parent">
<v-list>
<v-list-item link>
<v-switch v-model="step.ingredients[index].isHeader" :label="$t('Headline')" hide-details></v-switch>
</v-list-item>
<v-list-item link>
<v-switch v-model="step.ingredients[index].noAmount" :label="$t('Disable_Amount')" hide-details></v-switch>
</v-list-item>
<v-list-item @click="editingIngredientIndex = index; dialogIngredientSorter = true" prepend-icon="fa-solid fa-sort">
{{ $t('Move') }}
</v-list-item>
<v-list-item @click="step.ingredients.splice(index, 1)" prepend-icon="$delete">{{ $t('Delete') }}</v-list-item>
</v-list>
</v-menu>
</v-btn>
</div>
</div>
</div>
</v-row>
</div>
</vue-draggable>
</div>
@@ -347,7 +349,7 @@ function insertAndFocusIngredient() {
editingIngredientIndex.value = step.value.ingredients.length - 1
dialogIngredientEditor.value = true
} else {
document.getElementById(`id_input_amount_${step.value.id}_${step.value.ingredients.length - 1}`).select()
document.getElementById(`id_input_amount_${props.stepIndex}_${step.value.ingredients.length - 1}`).select()
}
})
}