mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 20:28:46 -05:00
some fixes and changes
This commit is contained in:
82
vue3/src/components/dialogs/StepIngredientSorterDialog.vue
Normal file
82
vue3/src/components/dialogs/StepIngredientSorterDialog.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
:max-width="(mobile) ? '100vw': '25vw'"
|
||||
:fullscreen="mobile">
|
||||
<v-card>
|
||||
<v-closable-card-title :title="$t('Move')" v-model="dialog"
|
||||
:sub-title="ingredientToString(step.ingredients[editingIngredientIndex])"></v-closable-card-title>
|
||||
<v-card-text>
|
||||
<v-btn block :disabled="editingIngredientIndex== 0" @click="moveIngredient(editingIngredientIndex, props.stepIndex, 0)">{{ $t('First') }}</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex == 0" class="mt-1" @click="moveIngredient(editingIngredientIndex, props.stepIndex, editingIngredientIndex - 1)">{{
|
||||
$t('Up')
|
||||
}}
|
||||
</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex + 1 == step.ingredients.length" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, props.stepIndex, editingIngredientIndex + 1)"> {{ $t('Down') }}
|
||||
</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex + 1 == step.ingredients.length" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, props.stepIndex, step.ingredients.length - 1)">{{ $t('Last') }}
|
||||
</v-btn>
|
||||
{{ $t('Step') }}
|
||||
<v-btn block v-for="(s,i) in recipe.steps" :disabled="i == props.stepIndex" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, i, recipe.steps[i].ingredients.length)">{{ i + 1 }} <span v-if="'name' in s">{{ s.name }}</span>
|
||||
</v-btn>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn @click="dialog = false">{{$t('Close')}}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {Recipe, SourceImportRecipe, SourceImportStep, Step} from "@/openapi";
|
||||
import {ingredientToString} from "@/utils/model_utils.ts";
|
||||
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
|
||||
import {ref, watch} from "vue";
|
||||
import {useDisplay} from "vuetify/framework";
|
||||
|
||||
const dialog = defineModel<Boolean>({required: true, default: false})
|
||||
const step = defineModel<Step|SourceImportStep>('step', {required: true})
|
||||
const recipe = defineModel<Recipe|SourceImportRecipe>('recipe', {required: true})
|
||||
const props = defineProps({
|
||||
stepIndex: {type: Number, required: true},
|
||||
ingredientIndex: {type: Number, required: true},
|
||||
})
|
||||
|
||||
const {mobile} = useDisplay()
|
||||
|
||||
watch(() => props.ingredientIndex, () => {
|
||||
console.log('updated ingredient inex')
|
||||
editingIngredientIndex.value = props.ingredientIndex
|
||||
})
|
||||
|
||||
const editingIngredientIndex = ref(0)
|
||||
|
||||
/**
|
||||
* move the ingredient at the given index of this step to the step and index at that step given in the target
|
||||
* @param sourceIngredientIndex index of the ingredient to move
|
||||
* @param targetStepIndex index of the step to place ingredient into
|
||||
* @param targetIngredientIndex place in the target steps ingredient list to insert into
|
||||
*/
|
||||
function moveIngredient(sourceIngredientIndex: number, targetStepIndex: number, targetIngredientIndex: number,) {
|
||||
let ingredient = step.value.ingredients[sourceIngredientIndex]
|
||||
step.value.ingredients.splice(sourceIngredientIndex, 1)
|
||||
recipe.value.steps[targetStepIndex].ingredients.splice(targetIngredientIndex, 0, ingredient)
|
||||
|
||||
// close dialog if moved to a new step, update index if its in the same step
|
||||
if (targetStepIndex != props.stepIndex) {
|
||||
dialog.value = false
|
||||
} else {
|
||||
editingIngredientIndex.value = targetIngredientIndex
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -42,7 +42,13 @@
|
||||
<template v-if="i.unit"> {{ ingredientToUnitString(i, ingredientFactor) }}</template>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="i.food"> {{ ingredientToFoodString(i, ingredientFactor) }}</template>
|
||||
<template v-if="i.food">
|
||||
<router-link v-if="i.food.recipe" :to="{name: 'RecipeViewPage', params: {id: i.food.recipe.id}}">
|
||||
{{ ingredientToFoodString(i, ingredientFactor) }}
|
||||
</router-link>
|
||||
<a v-else-if="i.food.url" :href="i.food.url" target="_blank">{{ ingredientToFoodString(i, ingredientFactor) }}</a>
|
||||
<span v-else>{{ ingredientToFoodString(i, ingredientFactor) }}</span>
|
||||
</template>
|
||||
</td>
|
||||
|
||||
<td style="width: 1%; text-wrap: nowrap">
|
||||
|
||||
@@ -171,35 +171,7 @@
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog
|
||||
v-model="dialogIngredientSorter"
|
||||
:max-width="(mobile) ? '100vw': '25vw'"
|
||||
:fullscreen="mobile">
|
||||
<v-card>
|
||||
<v-closable-card-title :title="$t('Move')" v-model="dialogIngredientSorter"
|
||||
:sub-title="ingredientToString(step.ingredients[editingIngredientIndex])"></v-closable-card-title>
|
||||
<v-card-text>
|
||||
<v-btn block :disabled="editingIngredientIndex== 0" @click="moveIngredient(editingIngredientIndex, props.stepIndex, 0)">{{ $t('First') }}</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex == 0" class="mt-1" @click="moveIngredient(editingIngredientIndex, props.stepIndex, editingIngredientIndex - 1)">{{
|
||||
$t('Up')
|
||||
}}
|
||||
</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex + 1 == step.ingredients.length" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, props.stepIndex, editingIngredientIndex + 1)"> {{ $t('Down') }}
|
||||
</v-btn>
|
||||
<v-btn block :disabled="editingIngredientIndex + 1 == step.ingredients.length" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, props.stepIndex, step.ingredients.length - 1)">{{ $t('Last') }}
|
||||
</v-btn>
|
||||
{{ $t('Step') }}
|
||||
<v-btn block v-for="(s,i) in recipe.steps" :disabled="i == props.stepIndex" class="mt-1"
|
||||
@click="moveIngredient(editingIngredientIndex, i, recipe.steps[i].ingredients.length)">{{ i + 1 }} {{ s.name }}
|
||||
</v-btn>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<step-ingredient-sorter-dialog :step-index="props.stepIndex" :step="step" :recipe="recipe" v-model="dialogIngredientSorter" :ingredient-index="editingIngredientIndex"></step-ingredient-sorter-dialog>
|
||||
|
||||
<v-bottom-sheet v-model="dialogIngredientEditor">
|
||||
<v-card v-if="editingIngredientIndex >= 0">
|
||||
@@ -247,6 +219,7 @@ import IngredientString from "@/components/display/IngredientString.vue";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {ingredientToString} from "@/utils/model_utils";
|
||||
import StepIngredientSorterDialog from "@/components/dialogs/StepIngredientSorterDialog.vue";
|
||||
|
||||
const emit = defineEmits(['delete'])
|
||||
|
||||
@@ -289,25 +262,6 @@ onMounted(() => {
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* move the ingredient at the given index of this step to the step and index at that step given in the target
|
||||
* @param sourceIngredientIndex index of the ingredient to move
|
||||
* @param targetStepIndex index of the step to place ingredient into
|
||||
* @param targetIngredientIndex place in the target steps ingredient list to insert into
|
||||
*/
|
||||
function moveIngredient(sourceIngredientIndex: number, targetStepIndex: number, targetIngredientIndex: number,) {
|
||||
let ingredient = step.value.ingredients[sourceIngredientIndex]
|
||||
step.value.ingredients.splice(sourceIngredientIndex, 1)
|
||||
recipe.value.steps[targetStepIndex].ingredients.splice(targetIngredientIndex, 0, ingredient)
|
||||
|
||||
// close dialog if moved to a new step, update index if its in the same step
|
||||
if (targetStepIndex != props.stepIndex) {
|
||||
dialogIngredientSorter.value = false
|
||||
} else {
|
||||
editingIngredientIndex.value = targetIngredientIndex
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sort function called by draggable when ingredient table is sorted
|
||||
*/
|
||||
|
||||
@@ -65,7 +65,7 @@ import {VDataTableUpdateOptions} from "@/vuetify";
|
||||
import {useModelEditorFunctions} from "@/composables/useModelEditorFunctions";
|
||||
import ModelEditorBase from "@/components/model_editors/ModelEditorBase.vue";
|
||||
import ModelSelect from "@/components/inputs/ModelSelect.vue";
|
||||
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||
import {ErrorMessageType, MessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
@@ -113,12 +113,25 @@ function addRecipeToBook() {
|
||||
let api = new ApiApi()
|
||||
|
||||
if (Object.keys(selectedRecipe.value).length > 0) {
|
||||
api.apiRecipeBookEntryCreate({recipeBookEntry: {book: editingObj.value.id!, recipe: selectedRecipe.value.id!}}).then(r => {
|
||||
recipeBookEntries.value.push(r)
|
||||
selectedRecipe.value = {} as Recipe
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
|
||||
let duplicateFound = false
|
||||
|
||||
recipeBookEntries.value.forEach(rBE => {
|
||||
if (rBE.recipe == selectedRecipe.value.id){
|
||||
duplicateFound = true
|
||||
}
|
||||
})
|
||||
|
||||
if (!duplicateFound){
|
||||
api.apiRecipeBookEntryCreate({recipeBookEntry: {book: editingObj.value.id!, recipe: selectedRecipe.value.id!}}).then(r => {
|
||||
recipeBookEntries.value.push(r)
|
||||
selectedRecipe.value = {} as Recipe
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
|
||||
})
|
||||
} else {
|
||||
selectedRecipe.value = {} as Recipe
|
||||
useMessageStore().addMessage(MessageType.WARNING, $t('WarningRecipeBookEntryDuplicate'), 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user