mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-03 13:19:16 -05:00
improved meal plan editor shopping integration
This commit is contained in:
@@ -27,10 +27,10 @@
|
|||||||
</v-expansion-panel-text>
|
</v-expansion-panel-text>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</v-expansion-panels>
|
</v-expansion-panels>
|
||||||
<v-number-input v-model="servings" class="mt-3" control-variant="split" :label="$t('Servings')" :precision="2"></v-number-input>
|
<v-number-input v-model="servings" class="mt-3" control-variant="split" :label="$t('Servings')" :precision="2" :disabled="loading"></v-number-input>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn class="float-right" prepend-icon="$create" color="create" @click="createShoppingListRecipe()">{{ $t('Add_to_Shopping') }}</v-btn>
|
<v-btn class="float-right" prepend-icon="$create" color="create" @click="createShoppingListRecipe()" :disabled="loading">{{ $t('Add_to_Shopping') }}</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
import {computed, onMounted, PropType, ref} from "vue";
|
import {computed, onMounted, PropType, ref} from "vue";
|
||||||
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
|
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
|
||||||
import {ApiApi, Recipe, RecipeFlat, RecipeOverview, type ShoppingListEntryBulkCreate, ShoppingListRecipe} from "@/openapi";
|
import {ApiApi, MealPlan, Recipe, RecipeFlat, RecipeOverview, type ShoppingListEntryBulkCreate, ShoppingListRecipe} from "@/openapi";
|
||||||
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||||
import {ShoppingDialogRecipe, ShoppingDialogRecipeEntry} from "@/types/Shopping";
|
import {ShoppingDialogRecipe, ShoppingDialogRecipeEntry} from "@/types/Shopping";
|
||||||
import {calculateFoodAmount} from "@/utils/number_utils";
|
import {calculateFoodAmount} from "@/utils/number_utils";
|
||||||
@@ -51,6 +51,7 @@ const emit = defineEmits(['created'])
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
recipe: {type: Object as PropType<Recipe | RecipeFlat | RecipeOverview>, required: true},
|
recipe: {type: Object as PropType<Recipe | RecipeFlat | RecipeOverview>, required: true},
|
||||||
|
mealPlan: {type: Object as PropType<MealPlan>, required: false},
|
||||||
})
|
})
|
||||||
|
|
||||||
const dialog = ref(false)
|
const dialog = ref(false)
|
||||||
@@ -77,6 +78,7 @@ onMounted(() => {
|
|||||||
function loadRecipeData() {
|
function loadRecipeData() {
|
||||||
let api = new ApiApi()
|
let api = new ApiApi()
|
||||||
let promises: Promise<any>[] = []
|
let promises: Promise<any>[] = []
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
let recipeRequest = api.apiRecipeRetrieve({id: props.recipe.id!}).then(r => {
|
let recipeRequest = api.apiRecipeRetrieve({id: props.recipe.id!}).then(r => {
|
||||||
recipe.value = r
|
recipe.value = r
|
||||||
@@ -108,7 +110,7 @@ function loadRecipeData() {
|
|||||||
|
|
||||||
recipe.steps.forEach(step => {
|
recipe.steps.forEach(step => {
|
||||||
step.ingredients.forEach(ingredient => {
|
step.ingredients.forEach(ingredient => {
|
||||||
if(!ingredient.isHeader){
|
if (!ingredient.isHeader) {
|
||||||
dialogRecipe.entries.push({
|
dialogRecipe.entries.push({
|
||||||
amount: ingredient.amount,
|
amount: ingredient.amount,
|
||||||
food: ingredient.food,
|
food: ingredient.food,
|
||||||
@@ -138,6 +140,10 @@ function createShoppingListRecipe() {
|
|||||||
servings: servings.value,
|
servings: servings.value,
|
||||||
} as ShoppingListRecipe
|
} as ShoppingListRecipe
|
||||||
|
|
||||||
|
if (props.mealPlan && props.mealPlan.id) {
|
||||||
|
shoppingListRecipe.mealplan = props.mealPlan.id!
|
||||||
|
}
|
||||||
|
|
||||||
let shoppingListEntries = {
|
let shoppingListEntries = {
|
||||||
entries: []
|
entries: []
|
||||||
} as ShoppingListEntryBulkCreate
|
} as ShoppingListEntryBulkCreate
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ const planItems = computed(() => {
|
|||||||
startDate.setHours(hour, minutes, seconds)
|
startDate.setHours(hour, minutes, seconds)
|
||||||
endDate.setHours(hour, minutes, seconds)
|
endDate.setHours(hour, minutes, seconds)
|
||||||
}
|
}
|
||||||
console.log(startDate, endDate)
|
|
||||||
items.push({
|
items.push({
|
||||||
startDate: startDate,
|
startDate: startDate,
|
||||||
endDate: endDate,
|
endDate: endDate,
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ const image = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.recipe, () => {
|
|
||||||
console.log('changed')
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -23,6 +23,19 @@
|
|||||||
<v-form :disabled="loading">
|
<v-form :disabled="loading">
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
|
<v-col cols="12" md="6">
|
||||||
|
<ModelSelect model="Recipe" v-model="editingObj.recipe"
|
||||||
|
@update:modelValue="editingObj.servings = editingObj.recipe ? editingObj.recipe.servings : 1"></ModelSelect>
|
||||||
|
<!-- <v-number-input label="Days" control-variant="split" :min="1"></v-number-input>-->
|
||||||
|
<!--TODO create days input with +/- synced to date -->
|
||||||
|
<recipe-card :recipe="editingObj.recipe" v-if="editingObj && editingObj.recipe"></recipe-card>
|
||||||
|
<v-btn prepend-icon="$shopping" color="create" class="mt-1" v-if="!editingObj.shopping && editingObj.recipe && isUpdate()">
|
||||||
|
{{$t('Add')}}
|
||||||
|
<add-to-shopping-dialog :recipe="editingObj.recipe" :meal-plan="editingObj" @created="loadShoppingListEntries(); editingObj.shopping = true;"></add-to-shopping-dialog>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-checkbox :label="$t('AddToShopping')" v-model="editingObj.addshopping" hide-details v-if="editingObj.recipe && !isUpdate()"></v-checkbox>
|
||||||
|
</v-col>
|
||||||
<v-col cols="12" md="6">
|
<v-col cols="12" md="6">
|
||||||
<v-text-field :label="$t('Title')" v-model="editingObj.title"></v-text-field>
|
<v-text-field :label="$t('Title')" v-model="editingObj.title"></v-text-field>
|
||||||
<v-date-input
|
<v-date-input
|
||||||
@@ -51,16 +64,7 @@
|
|||||||
<v-number-input control-variant="split" :min="0" v-model="editingObj.servings" :label="$t('Servings')" :precision="2"></v-number-input>
|
<v-number-input control-variant="split" :min="0" v-model="editingObj.servings" :label="$t('Servings')" :precision="2"></v-number-input>
|
||||||
<ModelSelect model="User" :allow-create="false" v-model="editingObj.shared" item-label="displayName" mode="tags"></ModelSelect>
|
<ModelSelect model="User" :allow-create="false" v-model="editingObj.shared" item-label="displayName" mode="tags"></ModelSelect>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" md="6">
|
|
||||||
<ModelSelect model="Recipe" v-model="editingObj.recipe"
|
|
||||||
@update:modelValue="editingObj.servings = editingObj.recipe ? editingObj.recipe.servings : 1"></ModelSelect>
|
|
||||||
<!-- <v-number-input label="Days" control-variant="split" :min="1"></v-number-input>-->
|
|
||||||
<!--TODO create days input with +/- synced to date -->
|
|
||||||
<recipe-card :recipe="editingObj.recipe" v-if="editingObj && editingObj.recipe"></recipe-card>
|
|
||||||
|
|
||||||
<v-checkbox :label="$t('AddToShopping')" v-model="editingObj.addshopping" hide-details v-if="editingObj.recipe && !isUpdate()"></v-checkbox>
|
|
||||||
<!-- TODO review shopping before add -->
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row dense>
|
<v-row dense>
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
@@ -112,6 +116,7 @@ import {useShoppingStore} from "@/stores/ShoppingStore";
|
|||||||
import ShoppingListEntryInput from "@/components/inputs/ShoppingListEntryInput.vue";
|
import ShoppingListEntryInput from "@/components/inputs/ShoppingListEntryInput.vue";
|
||||||
import ClosableHelpAlert from "@/components/display/ClosableHelpAlert.vue";
|
import ClosableHelpAlert from "@/components/display/ClosableHelpAlert.vue";
|
||||||
import {useMealPlanStore} from "@/stores/MealPlanStore";
|
import {useMealPlanStore} from "@/stores/MealPlanStore";
|
||||||
|
import AddToShoppingDialog from "@/components/dialogs/AddToShoppingDialog.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {type: {} as PropType<MealPlan>, required: false, default: null},
|
item: {type: {} as PropType<MealPlan>, required: false, default: null},
|
||||||
|
|||||||
Reference in New Issue
Block a user