mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
various fixes
This commit is contained in:
@@ -1041,7 +1041,7 @@ class RecipeImageSerializer(WritableNestedModelSerializer):
|
|||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if 'image' in validated_data and not is_file_type_allowed(validated_data['image'].name, image_only=True):
|
if 'image' in validated_data and not is_file_type_allowed(validated_data['image'].name, image_only=True):
|
||||||
return None
|
return None
|
||||||
return super().create( validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
if 'image' in validated_data and not is_file_type_allowed(validated_data['image'].name, image_only=True):
|
if 'image' in validated_data and not is_file_type_allowed(validated_data['image'].name, image_only=True):
|
||||||
@@ -1151,6 +1151,13 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
|||||||
SLR.create(mealplan=mealplan, servings=validated_data['servings'])
|
SLR.create(mealplan=mealplan, servings=validated_data['servings'])
|
||||||
return mealplan
|
return mealplan
|
||||||
|
|
||||||
|
def update(self, obj, validated_data):
|
||||||
|
if sr := ShoppingListRecipe.objects.filter(mealplan=obj.id).first():
|
||||||
|
SLR = RecipeShoppingEditor(user=obj.created_by, space=obj.space, id=sr.id)
|
||||||
|
SLR.edit(mealplan=obj, servings=validated_data['servings'])
|
||||||
|
|
||||||
|
return super().update(obj, validated_data)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MealPlan
|
model = MealPlan
|
||||||
fields = (
|
fields = (
|
||||||
@@ -1311,7 +1318,8 @@ class ViewLogSerializer(serializers.ModelSerializer):
|
|||||||
validated_data['created_by'] = self.context['request'].user
|
validated_data['created_by'] = self.context['request'].user
|
||||||
validated_data['space'] = self.context['request'].space
|
validated_data['space'] = self.context['request'].space
|
||||||
|
|
||||||
view_log = ViewLog.objects.filter(recipe=validated_data['recipe'], created_by=self.context['request'].user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)), space=self.context['request'].space).first()
|
view_log = ViewLog.objects.filter(recipe=validated_data['recipe'], created_by=self.context['request'].user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)),
|
||||||
|
space=self.context['request'].space).first()
|
||||||
if not view_log:
|
if not view_log:
|
||||||
view_log = ViewLog.objects.create(recipe=validated_data['recipe'], created_by=self.context['request'].user, space=self.context['request'].space)
|
view_log = ViewLog.objects.create(recipe=validated_data['recipe'], created_by=self.context['request'].user, space=self.context['request'].space)
|
||||||
|
|
||||||
|
|||||||
@@ -533,14 +533,14 @@ def web_manifest(request):
|
|||||||
"url": "./mealplan",
|
"url": "./mealplan",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": static('logo_color_plan.svg'),
|
"src": static('assets/logo_color_plan.svg'),
|
||||||
"sizes": "any"
|
"sizes": "any"
|
||||||
}, {
|
}, {
|
||||||
"src": static('logo_color_plan_144.png'),
|
"src": static('assets/logo_color_plan_144.png'),
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "144x144"
|
"sizes": "144x144"
|
||||||
}, {
|
}, {
|
||||||
"src": static('logo_color_plan_512.png'),
|
"src": static('assets/logo_color_plan_512.png'),
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "512x512"
|
"sizes": "512x512"
|
||||||
}
|
}
|
||||||
@@ -552,14 +552,14 @@ def web_manifest(request):
|
|||||||
"url": "./shopping",
|
"url": "./shopping",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": static('logo_color_shopping.svg'),
|
"src": static('assets/logo_color_shopping.svg'),
|
||||||
"sizes": "any"
|
"sizes": "any"
|
||||||
}, {
|
}, {
|
||||||
"src": static('logo_color_shopping_144.png'),
|
"src": static('assets/logo_color_shopping_144.png'),
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "144x144"
|
"sizes": "144x144"
|
||||||
}, {
|
}, {
|
||||||
"src": static('logo_color_shopping_512.png'),
|
"src": static('assets/logo_color_shopping_512.png'),
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "512x512"
|
"sizes": "512x512"
|
||||||
}
|
}
|
||||||
@@ -568,6 +568,7 @@ def web_manifest(request):
|
|||||||
"share_target": {
|
"share_target": {
|
||||||
"action": "/recipe/import",
|
"action": "/recipe/import",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
|
"enctype": "application/x-www-form-urlencoded",
|
||||||
"params": {
|
"params": {
|
||||||
"title": "title",
|
"title": "title",
|
||||||
"url": "url",
|
"url": "url",
|
||||||
|
|||||||
@@ -87,24 +87,27 @@
|
|||||||
<!-- </template>-->
|
<!-- </template>-->
|
||||||
|
|
||||||
<v-btn-group divided border>
|
<v-btn-group divided border>
|
||||||
<v-btn icon="" @click="e.amount = e.amount / 2; updateEntryAmount(e)">
|
<v-btn icon="" @click="e.amount = e.amount / 2; updateEntryAmount(e)" v-if="!e.listRecipeData">
|
||||||
<v-icon icon="fa-solid fa-divide"></v-icon>
|
<v-icon icon="fa-solid fa-divide"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon="" @click="e.amount--; updateEntryAmount(e)">
|
<v-btn icon="" @click="e.amount--; updateEntryAmount(e)" v-if="!e.listRecipeData">
|
||||||
<v-icon icon="fa-solid fa-minus"></v-icon>
|
<v-icon icon="fa-solid fa-minus"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon="" @click="e.amount++; updateEntryAmount(e)">
|
<v-btn icon="" @click="e.amount++; updateEntryAmount(e)" v-if="!e.listRecipeData">
|
||||||
<v-icon icon="fa-solid fa-plus"></v-icon>
|
<v-icon icon="fa-solid fa-plus"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn icon="" @click="e.amount = e.amount * 2; updateEntryAmount(e)">
|
<v-btn icon="" @click="e.amount = e.amount * 2; updateEntryAmount(e)" v-if="!e.listRecipeData">
|
||||||
<v-icon icon="fa-solid fa-times"></v-icon>
|
<v-icon icon="fa-solid fa-times"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn color="edit" icon="$edit" v-if="!e.recipeMealplan">
|
<v-btn color="edit" icon="$edit" v-if="!e.listRecipeData">
|
||||||
<v-icon icon="$edit"></v-icon>
|
<v-icon icon="$edit"></v-icon>
|
||||||
<model-edit-dialog model="ShoppingListEntry" :item="e" @delete="useShoppingStore().entries.delete(e.id); shoppingListFood.entries.delete(e.id)"
|
<model-edit-dialog model="ShoppingListEntry" :item="e" @delete="useShoppingStore().entries.delete(e.id); shoppingListFood.entries.delete(e.id)"
|
||||||
@save="(args: ShoppingListEntry) => (shoppingListFood.entries.set(e.id, args))"></model-edit-dialog>
|
@save="(args: ShoppingListEntry) => (shoppingListFood.entries.set(e.id, args))"></model-edit-dialog>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<v-btn color="edit" icon="$recipes" v-if="e.listRecipe && e.listRecipeData.recipe" :to="{name: 'view_recipe', params: {id: e.listRecipeData.recipe}}">
|
||||||
|
<v-icon icon="$recipes"></v-icon>
|
||||||
|
</v-btn>
|
||||||
<v-btn icon="" @click="useShoppingStore().deleteObject(e, true); shoppingListFood.entries.delete(e.id)" color="delete">
|
<v-btn icon="" @click="useShoppingStore().deleteObject(e, true); shoppingListFood.entries.delete(e.id)" color="delete">
|
||||||
<v-icon icon="$delete"></v-icon>
|
<v-icon icon="$delete"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item v-for="r in useShoppingStore().getAssociatedRecipes()">
|
<v-list-item v-for="r in useShoppingStore().getAssociatedRecipes()">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-btn color="edit" icon>
|
<v-btn color="edit" icon :disabled="r.mealplan">
|
||||||
{{ r.servings }}
|
{{ r.servings }}
|
||||||
<number-scaler-dialog :number="r.servings"
|
<number-scaler-dialog :number="r.servings"
|
||||||
@confirm="(servings: number) => {updateRecipeServings(r, servings)}"></number-scaler-dialog>
|
@confirm="(servings: number) => {updateRecipeServings(r, servings)}"></number-scaler-dialog>
|
||||||
|
|||||||
@@ -10,16 +10,16 @@
|
|||||||
:close-on-back="false"
|
:close-on-back="false"
|
||||||
multi-line
|
multi-line
|
||||||
>
|
>
|
||||||
<small>{{ DateTime.fromSeconds(visibleMessage.createdAt).toLocaleString(DateTime.DATETIME_MED) }}</small> <br/>
|
<!-- <small>{{ DateTime.fromSeconds(visibleMessage.createdAt).toLocaleString(DateTime.DATETIME_MED) }}</small> <br/>-->
|
||||||
<h3 v-if="visibleMessage.msg.title">{{ visibleMessage.msg.title }}</h3>
|
<h3 v-if="visibleMessage.msg.title">{{ visibleMessage.msg.title }}</h3>
|
||||||
<span class="text-pre">{{ visibleMessage.msg.text }}</span>
|
<span class="text-pre">{{ visibleMessage.msg.text }}</span>
|
||||||
|
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
|
|
||||||
<v-btn ref="ref_btn_view">View</v-btn>
|
<v-btn ref="ref_btn_view">{{$t('View')}}</v-btn>
|
||||||
<v-btn variant="text" @click="removeItem()">
|
<v-btn variant="text" @click="removeItem()">
|
||||||
<span v-if="useMessageStore().snackbarQueue.length > 1">Next ({{ useMessageStore().snackbarQueue.length - 1 }})</span>
|
<span v-if="useMessageStore().snackbarQueue.length > 1">{{$t('Next')}} ({{ useMessageStore().snackbarQueue.length - 1 }})</span>
|
||||||
<span v-else>Close</span>
|
<span v-else>{{$t('Close')}}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
</v-snackbar>
|
</v-snackbar>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
|
||||||
<v-number-input v-model="mutable_number" @update:modelValue="updateNumber('set')" control-variant="split" :min="0">
|
<v-number-input v-model="mutableNumber" @update:modelValue="updateNumber('set')" control-variant="split" :min="0">
|
||||||
</v-number-input>
|
</v-number-input>
|
||||||
|
|
||||||
<v-btn-group divided class="d-flex">
|
<v-btn-group divided class="d-flex">
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn @click=" dialog=false">{{ $t('Close') }}</v-btn>
|
<v-btn @click=" dialog=false">{{ $t('Close') }}</v-btn>
|
||||||
<v-btn color="save" prepend-icon="$save" @click="emit('confirm', mutable_number); dialog=false">{{ $t('Save') }}</v-btn>
|
<v-btn color="save" prepend-icon="$save" @click="emit('confirm', mutableNumber); dialog=false">{{ $t('Save') }}</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
@@ -49,14 +49,15 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const dialog = ref(false)
|
const dialog = ref(false)
|
||||||
const mutable_number = ref(0)
|
const mutableNumber = ref(0)
|
||||||
|
|
||||||
watch(() => props.number, (newVal) => {
|
watch(() => props.number, (newVal) => {
|
||||||
mutable_number.value = newVal
|
mutableNumber.value = newVal
|
||||||
|
console.log('prop updated')
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
mutable_number.value = props.number
|
mutableNumber.value = props.number
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,19 +66,19 @@ onMounted(() => {
|
|||||||
*/
|
*/
|
||||||
function updateNumber(operation: string) {
|
function updateNumber(operation: string) {
|
||||||
if (operation === 'half') {
|
if (operation === 'half') {
|
||||||
mutable_number.value = props.number / 2
|
mutableNumber.value = mutableNumber.value / 2
|
||||||
}
|
}
|
||||||
if (operation === 'double') {
|
if (operation === 'double') {
|
||||||
mutable_number.value = props.number * 2
|
mutableNumber.value = mutableNumber.value * 2
|
||||||
}
|
}
|
||||||
if (operation === 'add') {
|
if (operation === 'add') {
|
||||||
mutable_number.value = props.number + 1
|
mutableNumber.value = mutableNumber.value + 1
|
||||||
}
|
}
|
||||||
if (operation === 'sub') {
|
if (operation === 'sub') {
|
||||||
mutable_number.value = props.number - 1
|
mutableNumber.value = mutableNumber.value - 1
|
||||||
}
|
}
|
||||||
|
console.log('change emitted')
|
||||||
emit('change', mutable_number.value)
|
emit('change', mutableNumber.value)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,7 @@
|
|||||||
@update:modelValue="step.ingredients[editingIngredientIndex].unit = null; step.ingredients[editingIngredientIndex].food = null; step.ingredients[editingIngredientIndex].amount = 0"
|
@update:modelValue="step.ingredients[editingIngredientIndex].unit = null; step.ingredients[editingIngredientIndex].food = null; step.ingredients[editingIngredientIndex].amount = 0"
|
||||||
></v-checkbox>
|
></v-checkbox>
|
||||||
</v-form>
|
</v-form>
|
||||||
|
<v-btn color="info" class="mt-2" @click="dialogIngredientEditor = false; dialogIngredientSorter = true" prepend-icon="fa-solid fa-sort">{{ $t('Move') }}</v-btn>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn @click="dialogIngredientEditor = false; deleteIngredientAtIndex(editingIngredientIndex); editingIngredientIndex = -1" color="delete" prepend-icon="$delete">
|
<v-btn @click="dialogIngredientEditor = false; deleteIngredientAtIndex(editingIngredientIndex); editingIngredientIndex = -1" color="delete" prepend-icon="$delete">
|
||||||
|
|||||||
@@ -138,19 +138,19 @@ export const useMessageStore = defineStore('message_store', () => {
|
|||||||
*/
|
*/
|
||||||
function addPreparedMessage(preparedMessage: PreparedMessage, data?: any) {
|
function addPreparedMessage(preparedMessage: PreparedMessage, data?: any) {
|
||||||
if (preparedMessage == PreparedMessage.UPDATE_SUCCESS) {
|
if (preparedMessage == PreparedMessage.UPDATE_SUCCESS) {
|
||||||
addMessage(MessageType.SUCCESS, {title: t('Updated'), text: ''} as StructuredMessage, 6000, data)
|
addMessage(MessageType.SUCCESS, {title: t('Updated'), text: ''} as StructuredMessage, 1500, data)
|
||||||
}
|
}
|
||||||
if (preparedMessage == PreparedMessage.DELETE_SUCCESS) {
|
if (preparedMessage == PreparedMessage.DELETE_SUCCESS) {
|
||||||
addMessage(MessageType.SUCCESS, {title: t('Deleted'), text: ''} as StructuredMessage, 6000, data)
|
addMessage(MessageType.SUCCESS, {title: t('Deleted'), text: ''} as StructuredMessage, 1500, data)
|
||||||
}
|
}
|
||||||
if (preparedMessage == PreparedMessage.CREATE_SUCCESS) {
|
if (preparedMessage == PreparedMessage.CREATE_SUCCESS) {
|
||||||
addMessage(MessageType.SUCCESS, {title: t('Created'), text: ''} as StructuredMessage, 6000, data)
|
addMessage(MessageType.SUCCESS, {title: t('Created'), text: ''} as StructuredMessage, 1500, data)
|
||||||
}
|
}
|
||||||
if (preparedMessage == PreparedMessage.MERGE_SUCCESS) {
|
if (preparedMessage == PreparedMessage.MERGE_SUCCESS) {
|
||||||
addMessage(MessageType.SUCCESS, {title: t('Merge'), text: ''} as StructuredMessage, 6000, data)
|
addMessage(MessageType.SUCCESS, {title: t('Merge'), text: ''} as StructuredMessage, 1500, data)
|
||||||
}
|
}
|
||||||
if (preparedMessage == PreparedMessage.MOVE_SUCCESS) {
|
if (preparedMessage == PreparedMessage.MOVE_SUCCESS) {
|
||||||
addMessage(MessageType.SUCCESS, {title: t('Move'), text: ''} as StructuredMessage, 6000, data)
|
addMessage(MessageType.SUCCESS, {title: t('Move'), text: ''} as StructuredMessage, 1500, data)
|
||||||
}
|
}
|
||||||
if (preparedMessage == PreparedMessage.NOT_FOUND) {
|
if (preparedMessage == PreparedMessage.NOT_FOUND) {
|
||||||
addMessage(MessageType.WARNING, {title: t('NotFound'), text: t('NotFoundHelp')} as StructuredMessage, 6000, data)
|
addMessage(MessageType.WARNING, {title: t('NotFound'), text: t('NotFoundHelp')} as StructuredMessage, 6000, data)
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ import {Ingredient} from "@/openapi";
|
|||||||
*/
|
*/
|
||||||
export function ingredientToString(ingredient: Ingredient) {
|
export function ingredientToString(ingredient: Ingredient) {
|
||||||
let content = []
|
let content = []
|
||||||
|
|
||||||
|
if(ingredient == undefined){
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
if(ingredient.amount != 0){
|
if(ingredient.amount != 0){
|
||||||
content.push(ingredient.amount)
|
content.push(ingredient.amount)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user