Merge branch 'develop' into feature/fulltext-search

# Conflicts:
#	cookbook/static/vue/js/chunk-vendors.js
#	cookbook/static/vue/js/import_response_view.js
#	cookbook/static/vue/js/offline_view.js
#	cookbook/static/vue/js/recipe_search_view.js
#	cookbook/static/vue/js/recipe_view.js
#	cookbook/static/vue/js/supermarket_view.js
#	cookbook/static/vue/js/user_file_view.js
#	requirements.txt
#	vue/src/apps/RecipeSearchView/RecipeSearchView.vue
#	vue/src/components/GenericMultiselect.vue
#	vue/src/locales/en.json
This commit is contained in:
vabene1111
2021-08-22 13:28:57 +02:00
86 changed files with 7258 additions and 3337 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.5 on 2021-07-29 14:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0141_auto_20210713_1042'),
]
operations = [
migrations.AlterField(
model_name='userpreference',
name='search_style',
field=models.CharField(choices=[('SMALL', 'Small'), ('LARGE', 'Large'), ('NEW', 'New')], default='NEW', max_length=64),
),
]

View File

@ -160,7 +160,7 @@ class UserPreference(models.Model, PermissionModelMixin):
choices=PAGES, max_length=64, default=SEARCH choices=PAGES, max_length=64, default=SEARCH
) )
search_style = models.CharField( search_style = models.CharField(
choices=SEARCH_STYLE, max_length=64, default=LARGE choices=SEARCH_STYLE, max_length=64, default=NEW
) )
show_recent = models.BooleanField(default=True) show_recent = models.BooleanField(default=True)
plan_share = models.ManyToManyField( plan_share = models.ManyToManyField(

View File

@ -370,15 +370,21 @@ class NutritionInformationSerializer(serializers.ModelSerializer):
class RecipeBaseSerializer(WritableNestedModelSerializer): class RecipeBaseSerializer(WritableNestedModelSerializer):
def get_recipe_rating(self, obj): def get_recipe_rating(self, obj):
rating = obj.cooklog_set.filter(created_by=self.context['request'].user, rating__gt=0).aggregate(Avg('rating')) try:
if rating['rating__avg']: rating = obj.cooklog_set.filter(created_by=self.context['request'].user, rating__gt=0).aggregate(Avg('rating'))
return rating['rating__avg'] if rating['rating__avg']:
return rating['rating__avg']
except TypeError:
pass
return 0 return 0
def get_recipe_last_cooked(self, obj): def get_recipe_last_cooked(self, obj):
last = obj.cooklog_set.filter(created_by=self.context['request'].user).last() try:
if last: last = obj.cooklog_set.filter(created_by=self.context['request'].user).last()
return last.created_at if last:
return last.created_at
except TypeError:
pass
return None return None
@ -456,6 +462,14 @@ class RecipeBookSerializer(SpacedModelSerializer):
class RecipeBookEntrySerializer(serializers.ModelSerializer): class RecipeBookEntrySerializer(serializers.ModelSerializer):
book_content = serializers.SerializerMethodField(method_name='get_book_content', read_only=True)
recipe_content = serializers.SerializerMethodField(method_name='get_recipe_content', read_only=True)
def get_book_content(self, obj):
return RecipeBookSerializer(context={'request': self.context['request']}).to_representation(obj.book)
def get_recipe_content(self, obj):
return RecipeOverviewSerializer(context={'request': self.context['request']}).to_representation(obj.recipe)
def create(self, validated_data): def create(self, validated_data):
book = validated_data['book'] book = validated_data['book']
@ -467,7 +481,7 @@ class RecipeBookEntrySerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecipeBookEntry model = RecipeBookEntry
fields = ('id', 'book', 'recipe',) fields = ('id', 'book', 'book_content', 'recipe', 'recipe_content',)
class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer): class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,7 +28,7 @@
</a> </a>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<div class="card-body"> <div class="card-body" style="padding: 16px">
<div class="d-flex"> <div class="d-flex">
<div class="flex-fill"> <div class="flex-fill">
<h5 class="card-title p-0 m-0">{{ row.cells.name }} <h5 class="card-title p-0 m-0">{{ row.cells.name }}

View File

@ -372,12 +372,30 @@ class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin):
class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet): class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet):
"""
list:
optional parameters
- **recipe**: id of recipe - only return books for that recipe
- **book**: id of book - only return recipes in that book
"""
queryset = RecipeBookEntry.objects queryset = RecipeBookEntry.objects
serializer_class = RecipeBookEntrySerializer serializer_class = RecipeBookEntrySerializer
permission_classes = [CustomIsOwner] permission_classes = [CustomIsOwner]
def get_queryset(self): def get_queryset(self):
return self.queryset.filter(book__created_by=self.request.user).filter(book__space=self.request.space) queryset = self.queryset.filter(Q(book__created_by=self.request.user) | Q(book__shared=self.request.user)).filter(book__space=self.request.space)
recipe_id = self.request.query_params.get('recipe', None)
if recipe_id is not None:
queryset = queryset.filter(recipe__pk=recipe_id)
book_id = self.request.query_params.get('book', None)
if book_id is not None:
queryset = queryset.filter(book__pk=book_id)
return queryset
class MealPlanViewSet(viewsets.ModelViewSet): class MealPlanViewSet(viewsets.ModelViewSet):

View File

@ -129,6 +129,7 @@ server {
location / { location / {
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_pass http://unix:/var/www/recipes/recipes.sock; proxy_pass http://unix:/var/www/recipes/recipes.sock;
proxy_set_header X-Forwarded-Proto $scheme;
} }
} }
``` ```

View File

@ -4,8 +4,13 @@
Many people appear to host this application on their Synology NAS. The following documentation was provided by Many people appear to host this application on their Synology NAS. The following documentation was provided by
@therealschimmi in [this issue discussion](https://github.com/vabene1111/recipes/issues/98#issuecomment-643062907). @therealschimmi in [this issue discussion](https://github.com/vabene1111/recipes/issues/98#issuecomment-643062907).
There is also this
([word](https://github.com/vabene1111/recipes/files/6708738/Tandoor.on.a.Synology.Disk.Station.docx),
[pdf](https://github.com/vabene1111/recipes/files/6901601/Tandoor.on.a.Synology.Disk.Station.pdf)) awesome and
very detailed guide provided by @DiversityBug.
There are, as always, most likely other ways to do this but this can be used as a starting point for your There are, as always, most likely other ways to do this but this can be used as a starting point for your
setup. Since i cannot test it myself feedback and improvements are always very welcome. setup. Since I cannot test it myself feedback and improvements are always very welcome.
## Instructions ## Instructions
@ -15,7 +20,7 @@ Basic guide to setup `vabenee1111/recipes docker` container on Synology NAS
- Install Docker through package center - Install Docker through package center
- Optional: Create a shared folder for your docker projects, they have to store data somewhere outside the containers - Optional: Create a shared folder for your docker projects, they have to store data somewhere outside the containers
- Create a folder somewhere, i suggest naming it 'recipes' and storing it in the dedicated docker folder - Create a folder somewhere, I suggest naming it 'recipes' and storing it in the dedicated docker folder
- Within, create the necessary folder structure. You will need these folders: - Within, create the necessary folder structure. You will need these folders:
![grafik](https://user-images.githubusercontent.com/66269214/84472395-63042580-ac87-11ea-8779-37555210e47a.png) ![grafik](https://user-images.githubusercontent.com/66269214/84472395-63042580-ac87-11ea-8779-37555210e47a.png)

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "Englisch" msgstr "Englisch"
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "Deutsch" msgstr "Deutsch"
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,42 +17,42 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -19,42 +19,42 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : "
"2);\n" "2);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,42 +17,42 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,42 +18,42 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-12 20:30+0200\n" "POT-Creation-Date: 2021-08-17 08:44+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,42 +17,42 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: .\recipes\settings.py:303 #: .\recipes\settings.py:317
msgid "Armenian " msgid "Armenian "
msgstr "" msgstr ""
#: .\recipes\settings.py:304 #: .\recipes\settings.py:318
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: .\recipes\settings.py:305 #: .\recipes\settings.py:319
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: .\recipes\settings.py:306 #: .\recipes\settings.py:320
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: .\recipes\settings.py:307 #: .\recipes\settings.py:321
msgid "English" msgid "English"
msgstr "" msgstr ""
#: .\recipes\settings.py:308 #: .\recipes\settings.py:322
msgid "French" msgid "French"
msgstr "" msgstr ""
#: .\recipes\settings.py:309 #: .\recipes\settings.py:323
msgid "German" msgid "German"
msgstr "" msgstr ""
#: .\recipes\settings.py:310 #: .\recipes\settings.py:324
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: .\recipes\settings.py:311 #: .\recipes\settings.py:325
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr ""
#: .\recipes\settings.py:312 #: .\recipes\settings.py:326
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""

View File

@ -1,4 +1,4 @@
Django==3.2.5 Django==3.2.6
cryptography==3.4.7 cryptography==3.4.7
django-annoying==0.10.6 django-annoying==0.10.6
django-autocomplete-light==3.8.2 django-autocomplete-light==3.8.2
@ -9,18 +9,18 @@ django-filter==2.4.0
django-tables2==2.4.0 django-tables2==2.4.0
djangorestframework==3.12.4 djangorestframework==3.12.4
drf-writable-nested==0.6.3 drf-writable-nested==0.6.3
bleach==3.3.1 bleach==4.0.0
bleach-allowlist==1.0.3 bleach-allowlist==1.0.3
gunicorn==20.1.0 gunicorn==20.1.0
lxml==4.6.3 lxml==4.6.3
Markdown==3.3.4 Markdown==3.3.4
Pillow==8.3.1 Pillow==8.3.1
psycopg2-binary==2.9.1 psycopg2-binary==2.9.1
python-dotenv==0.18.0 python-dotenv==0.19.0
requests==2.26.0 requests==2.26.0
simplejson==3.17.3 simplejson==3.17.3
six==1.16.0 six==1.16.0
webdavclient3==3.14.5 webdavclient3==3.14.6
whitenoise==5.3.0 whitenoise==5.3.0
icalendar==4.0.7 icalendar==4.0.7
pyyaml==5.4.1 pyyaml==5.4.1
@ -31,13 +31,13 @@ Jinja2==3.0.1
django-webpack-loader==1.1.0 django-webpack-loader==1.1.0
django-js-reverse==0.9.1 django-js-reverse==0.9.1
django-allauth==0.45.0 django-allauth==0.45.0
recipe-scrapers==13.3.4 recipe-scrapers==13.3.5
django-scopes==1.2.0 django-scopes==1.2.0
pytest==6.2.4 pytest==6.2.4
pytest-django==4.4.0 pytest-django==4.4.0
django-cors-headers==3.7.0
django-treebeard==4.5.1 django-treebeard==4.5.1
django-cors-headers==3.8.0
django-storages==1.11.1 django-storages==1.11.1
boto3==1.18.4 boto3==1.18.25
django-prometheus==2.1.0 django-prometheus==2.1.0
django-hCaptcha==0.1.0 django-hCaptcha==0.1.0

View File

@ -174,7 +174,7 @@
:initial_selection="settings.search_foods" :initial_selection="settings.search_foods"
search_function="listFoods" label="name" search_function="listFoods" label="name"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0" style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
v-bind:placeholder="$t('Ingredients')"></generic-multiselect> v-bind:placeholder="$t('Ingredients')" :limit="20"></generic-multiselect>
<b-input-group-append> <b-input-group-append>
<b-input-group-text> <b-input-group-text>
<b-form-checkbox v-model="settings.search_foods_or" name="check-button" <b-form-checkbox v-model="settings.search_foods_or" name="check-button"
@ -196,7 +196,7 @@
:initial_selection="settings.search_books" :initial_selection="settings.search_books"
search_function="listRecipeBooks" label="name" search_function="listRecipeBooks" label="name"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0" style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
v-bind:placeholder="$t('Books')"></generic-multiselect> v-bind:placeholder="$t('Books')" :limit="50"></generic-multiselect>
<b-input-group-append> <b-input-group-append>
<b-input-group-text> <b-input-group-text>
<b-form-checkbox v-model="settings.search_books_or" name="check-button" <b-form-checkbox v-model="settings.search_books_or" name="check-button"

View File

@ -1,21 +1,32 @@
<template> <template>
<div> <div>
<b-modal class="modal" :id="`id_modal_add_book_${modal_id}`" :title="$t('Add_to_Book')" :ok-title="$t('Add')" <b-modal class="modal" :id="`id_modal_add_book_${modal_id}`" :title="$t('Manage_Books')" :ok-title="$t('Add')"
:cancel-title="$t('Close')" @ok="addToBook()"> :cancel-title="$t('Close')" @ok="addToBook()" @shown="loadBookEntries">
<table>
<tr v-for="be in this.recipe_book_list" v-bind:key="be.id">
<td>
<button class="btn btn-sm btn-danger" @click="removeFromBook(be)"><i class="fa fa-trash-alt"></i></button>
</td>
<td> {{ be.book_content.name }}</td>
</tr>
</table>
<multiselect <multiselect
style="margin-top: 1vh"
v-model="selected_book" v-model="selected_book"
:options="books" :options="books_filtered"
:taggable="true"
:preserve-search="true" @tag="createBook"
v-bind:tag-placeholder="$t('Create')"
:placeholder="$t('Select_Book')" :placeholder="$t('Select_Book')"
label="name" label="name"
track-by="id" track-by="id"
id="id_books" id="id_books"
:multiple="false" :multiple="false"
:loading="books_loading"
@search-change="loadBook"> @search-change="loadBooks">
</multiselect> </multiselect>
</b-modal> </b-modal>
</div> </div>
@ -31,7 +42,8 @@ Vue.prototype.moment = moment
import Vue from "vue"; import Vue from "vue";
import {BootstrapVue} from "bootstrap-vue"; import {BootstrapVue} from "bootstrap-vue";
import {apiAddRecipeBookEntry, apiLoadCookBooks, apiLogCooking} from "@/utils/api"; import {ApiApiFactory} from "@/utils/openapi/api";
import {makeStandardToast, StandardToasts} from "@/utils/utils";
Vue.use(BootstrapVue) Vue.use(BootstrapVue)
@ -47,21 +59,66 @@ export default {
data() { data() {
return { return {
books: [], books: [],
books_loading: false,
recipe_book_list: [],
selected_book: null, selected_book: null,
} }
}, },
computed: {
books_filtered: function () {
let books_filtered = []
this.books.forEach(b => {
if (this.recipe_book_list.filter(e => e.book === b.id).length === 0) {
books_filtered.push(b)
}
})
return books_filtered
}
},
mounted() { mounted() {
this.loadBook('')
}, },
methods: { methods: {
loadBook: function (query) { loadBooks: function (query) {
apiLoadCookBooks(query).then(results => { this.books_loading = true
this.books = results let apiFactory = new ApiApiFactory()
apiFactory.listRecipeBooks({query: {query: query}}).then(results => {
this.books = results.data.filter(e => this.recipe_book_list.indexOf(e) === -1)
this.books_loading = false
}) })
}, },
addToBook() { createBook: function (name) {
apiAddRecipeBookEntry({'recipe': this.recipe.id, 'book': this.selected_book.id}) let apiFactory = new ApiApiFactory()
apiFactory.createRecipeBook({name: name}).then(r => {
this.books.push(r.data)
this.selected_book = r.data
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
})
}, },
addToBook: function () {
let apiFactory = new ApiApiFactory()
apiFactory.createRecipeBookEntry({book: this.selected_book.id, recipe: this.recipe.id}).then(r => {
this.recipe_book_list.push(r.data)
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
})
},
removeFromBook: function (book_entry) {
let apiFactory = new ApiApiFactory()
apiFactory.destroyRecipeBookEntry(book_entry.id).then(r => {
this.recipe_book_list = this.recipe_book_list.filter(e => e.id !== book_entry.id)
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_DELETE)
})
},
loadBookEntries: function () {
let apiFactory = new ApiApiFactory()
apiFactory.listRecipeBookEntrys({query: {recipe: this.recipe.id}}).then(r => {
this.recipe_book_list = r.data
this.loadBooks('')
})
}
} }
} }
</script> </script>

View File

@ -36,6 +36,10 @@ export default {
search_function: String, search_function: String,
label: String, label: String,
parent_variable: {type: String, default: undefined}, parent_variable: {type: String, default: undefined},
limit: {
type: Number,
default: 10,
}
sticky_options: {type:Array, default(){return []}}, sticky_options: {type:Array, default(){return []}},
initial_selection: {type:Array, default(){return []}}, initial_selection: {type:Array, default(){return []}},
multiple: {type: Boolean, default: true}, multiple: {type: Boolean, default: true},
@ -79,4 +83,4 @@ export default {
<style scoped> <style scoped>
</style> </style>

View File

@ -17,7 +17,7 @@
<a href="#"> <a href="#">
<button class="dropdown-item" @click="$bvModal.show(`id_modal_add_book_${modal_id}`)"> <button class="dropdown-item" @click="$bvModal.show(`id_modal_add_book_${modal_id}`)">
<i class="fas fa-bookmark fa-fw"></i> {{ $t('Add_to_Book') }} <i class="fas fa-bookmark fa-fw"></i> {{ $t('Manage_Books') }}
</button> </button>
</a> </a>

View File

@ -16,13 +16,13 @@
"Log_Recipe_Cooking": "Log Recipe Cooking", "Log_Recipe_Cooking": "Log Recipe Cooking",
"External_Recipe_Image": "External Recipe Image", "External_Recipe_Image": "External Recipe Image",
"Add_to_Book": "Add to Book",
"Add_to_Shopping": "Add to Shopping", "Add_to_Shopping": "Add to Shopping",
"Add_to_Plan": "Add to Plan", "Add_to_Plan": "Add to Plan",
"Step_start_time": "Step start time", "Step_start_time": "Step start time",
"Sort_by_new": "Sort by new", "Sort_by_new": "Sort by new",
"Recipes_per_page": "Recipes per Page", "Recipes_per_page": "Recipes per Page",
"Manage_Books": "Manage Books",
"Meal_Plan": "Meal Plan", "Meal_Plan": "Meal Plan",
"Select_Book": "Select Book", "Select_Book": "Select Book",
"Recipe_Image": "Recipe Image", "Recipe_Image": "Recipe Image",
@ -60,6 +60,7 @@
"Add": "Add", "Add": "Add",
"New": "New", "New": "New",
"Success": "Success", "Success": "Success",
"Failure": "Failure",
"Ingredients": "Ingredients", "Ingredients": "Ingredients",
"Supermarket": "Supermarket", "Supermarket": "Supermarket",
"Categories": "Categories", "Categories": "Categories",
@ -86,6 +87,8 @@
"or": "or", "or": "or",
"and": "and", "and": "and",
"Information": "Information", "Information": "Information",
"Download": "Download",
"Create": "Create",
"Advanced Search Settings": "Advanced Search Settings", "Advanced Search Settings": "Advanced Search Settings",
"View": "View", "View": "View",
"Recipes": "Recipes", "Recipes": "Recipes",

80
vue/src/locales/fr.json Normal file
View File

@ -0,0 +1,80 @@
{
"err_fetching_resource": "Il y a eu une erreur pour récupérer une ressource !",
"err_creating_resource": "Il y a eu une erreur pour créer une ressource !",
"err_updating_resource": "Il y a eu une erreur pour mettre à jour une ressource !",
"err_deleting_resource": "Il y a eu une erreur pour supprimer une ressource !",
"success_fetching_resource": "Ressource correctement récupérée !",
"success_creating_resource": "Ressource correctement créée !",
"success_updating_resource": "Ressource correctement mise à jour !",
"success_deleting_resource": "Ressource correctement supprimée !",
"import_running": "Importation en cours, veuillez patienter !",
"all_fields_optional": "Tous les champs sont optionnels et peuvent être laissés vides.",
"convert_internal": "Convertir en recette interne",
"show_only_internal": "Montrer uniquement les recettes internes",
"Log_Recipe_Cooking": "Marquer la recette comme cuisinée",
"External_Recipe_Image": "Image externe de recette",
"Add_to_Shopping": "Ajouter à la liste de courses",
"Add_to_Plan": "Ajouter au menu",
"Step_start_time": "Heure de départ de l'étape",
"Sort_by_new": "Trier par nouveautés",
"Recipes_per_page": "Nombre de recettes par page",
"Manage_Books": "Gérer les favoris",
"Meal_Plan": "Menu de la semaine",
"Select_Book": "Sélectionnez livre",
"Recipe_Image": "Image de la recette",
"Import_finished": "Importation finie",
"View_Recipes": "Voir les recettes",
"Log_Cooking": "Marquer comme cuisiné",
"New_Recipe": "Nouvelle recette",
"Url_Import": "Importation de l'url",
"Reset_Search": "Réinitialiser la recherche",
"Recently_Viewed": "Vu récemment",
"Load_More": "Charger plus",
"Keywords": "Mots-clés",
"Books": "Livres",
"Proteins": "Protéines",
"Fats": "Matières grasses",
"Carbohydrates": "Glucides",
"Calories": "Calories",
"Nutrition": "Informations nutritionnelles",
"Date": "Date",
"Share": "Partager",
"Export": "Exporter",
"Copy": "Copier",
"Rating": "Note",
"Close": "Fermer",
"Link": "Lien",
"Add": "Ajouter",
"New": "Nouveau",
"Success": "Réussite",
"Failure": "Échec",
"Ingredients": "Ingrédients",
"Supermarket": "Supermarché",
"Categories": "Catégories",
"Category": "Catégorie",
"Selected": "Sélectionné",
"min": "min",
"Servings": "Portions",
"Waiting": "Attente",
"Preparation": "Préparation",
"External": "Externe",
"Size": "Taille",
"Files": "Fichiers",
"File": "Fichier",
"Edit": "Modifier",
"Cancel": "Annuler",
"Delete": "Supprimer",
"Open": "Ouvrir",
"Ok": "Ouvrir",
"Save": "Sauvegarder",
"Step": "Étape",
"Search": "Rechercher",
"Import": "Importer",
"Print": "Imprimer",
"Settings": "Paramètres",
"or": "ou",
"and": "et",
"Information": "Information",
"Download": "Télécharger",
"Create": "Créer"
}

View File

@ -0,0 +1,80 @@
{
"err_fetching_resource": "",
"err_creating_resource": "",
"err_updating_resource": "",
"err_deleting_resource": "",
"success_fetching_resource": "",
"success_creating_resource": "",
"success_updating_resource": "",
"success_deleting_resource": "",
"import_running": "",
"all_fields_optional": "",
"convert_internal": "",
"show_only_internal": "",
"Log_Recipe_Cooking": "",
"External_Recipe_Image": "外部菜谱图像",
"Add_to_Shopping": "添加到购物",
"Add_to_Plan": "添加到计划",
"Step_start_time": "",
"Sort_by_new": "",
"Recipes_per_page": "",
"Manage_Books": "管理书籍",
"Meal_Plan": "",
"Select_Book": "",
"Recipe_Image": "菜谱图像",
"Import_finished": "导入完成",
"View_Recipes": "",
"Log_Cooking": "",
"New_Recipe": "新菜谱",
"Url_Import": "导入网址",
"Reset_Search": "重置搜索",
"Recently_Viewed": "最近浏览",
"Load_More": "加载更多",
"Keywords": "关键字",
"Books": "书籍",
"Proteins": "蛋白质",
"Fats": "脂肪",
"Carbohydrates": "碳水化合物",
"Calories": "卡路里",
"Nutrition": "营养",
"Date": "日期",
"Share": "分享",
"Export": "导出",
"Copy": "拷贝",
"Rating": "评分",
"Close": "关闭",
"Link": "链接",
"Add": "添加",
"New": "新",
"Success": "成功",
"Failure": "失败",
"Ingredients": "材料",
"Supermarket": "超级市场",
"Categories": "分类",
"Category": "分类",
"Selected": "选定",
"min": "",
"Servings": "份量",
"Waiting": "等待",
"Preparation": "准备",
"External": "外部",
"Size": "大小",
"Files": "文件",
"File": "文件",
"Edit": "编辑",
"Cancel": "取消",
"Delete": "删除",
"Open": "打开",
"Ok": "打开",
"Save": "储存",
"Step": "步骤",
"Search": "搜索",
"Import": "导入",
"Print": "打印",
"Settings": "设置",
"or": "或",
"and": "与",
"Information": "更多资讯",
"Download": "下载",
"Create": "创立"
}

View File

@ -0,0 +1,80 @@
{
"err_fetching_resource": "",
"err_creating_resource": "",
"err_updating_resource": "",
"err_deleting_resource": "",
"success_fetching_resource": "",
"success_creating_resource": "",
"success_updating_resource": "",
"success_deleting_resource": "",
"import_running": "",
"all_fields_optional": "",
"convert_internal": "",
"show_only_internal": "",
"Log_Recipe_Cooking": "",
"External_Recipe_Image": "",
"Add_to_Shopping": "",
"Add_to_Plan": "",
"Step_start_time": "",
"Sort_by_new": "",
"Recipes_per_page": "",
"Manage_Books": "",
"Meal_Plan": "",
"Select_Book": "",
"Recipe_Image": "",
"Import_finished": "",
"View_Recipes": "",
"Log_Cooking": "",
"New_Recipe": "",
"Url_Import": "",
"Reset_Search": "",
"Recently_Viewed": "",
"Load_More": "",
"Keywords": "",
"Books": "",
"Proteins": "",
"Fats": "",
"Carbohydrates": "",
"Calories": "",
"Nutrition": "",
"Date": "",
"Share": "",
"Export": "",
"Copy": "",
"Rating": "",
"Close": "",
"Link": "",
"Add": "",
"New": "",
"Success": "",
"Failure": "",
"Ingredients": "",
"Supermarket": "",
"Categories": "",
"Category": "",
"Selected": "",
"min": "",
"Servings": "",
"Waiting": "",
"Preparation": "",
"External": "",
"Size": "",
"Files": "",
"File": "",
"Edit": "",
"Cancel": "",
"Delete": "",
"Open": "",
"Ok": "",
"Save": "",
"Step": "",
"Search": "",
"Import": "",
"Print": "",
"Settings": "",
"or": "",
"and": "",
"Information": "",
"Download": "",
"Create": ""
}

View File

@ -37,23 +37,6 @@ export function apiLogCooking(cook_log) {
}) })
} }
export function apiLoadCookBooks(query) {
return axios.get(resolveDjangoUrl('api:recipebook-list') + '?query=' + query).then((response) => {
return response.data
}).catch((err) => {
//handleError(err, 'There was an error loading a resource!', 'danger')
})
}
export function apiAddRecipeBookEntry(entry) {
return axios.post(resolveDjangoUrl('api:recipebookentry-list',), entry).then((response) => {
makeToast('Saved', 'Recipe Book entry saved!', 'success')
}).catch((err) => {
handleError(err, 'There was an error creating a resource!', 'danger')
})
}
function handleError(error, message) { function handleError(error, message) {
if ('response' in error) { if ('response' in error) {
console.log(error.response) console.log(error.response)

View File

@ -1,6 +1,6 @@
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */ /* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
/*https://developer.aliyun.com/mirror/npm/package/frac/v/0.3.0 Apache license*/ /* https://www.npmjs.com/package/frac Apache license*/
export function frac(x, D, mixed) { export function frac(x, D, mixed) {
var n1 = Math.floor(x), d1 = 1; var n1 = Math.floor(x), d1 = 1;
var n2 = n1 + 1, d2 = 1; var n2 = n1 + 1, d2 = 1;

View File

@ -2,6 +2,7 @@
* Utility functions to call bootstrap toasts * Utility functions to call bootstrap toasts
* */ * */
import {BToast} from 'bootstrap-vue' import {BToast} from 'bootstrap-vue'
import i18n from "@/i18n";
export const ToastMixin = { export const ToastMixin = {
methods: { methods: {
@ -21,6 +22,49 @@ export function makeToast(title, message, variant = null) {
}) })
} }
export class StandardToasts {
static SUCCESS_CREATE = 'SUCCESS_CREATE'
static SUCCESS_FETCH = 'SUCCESS_FETCH'
static SUCCESS_UPDATE = 'SUCCESS_UPDATE'
static SUCCESS_DELETE = 'SUCCESS_DELETE'
static FAIL_CREATE = 'FAIL_CREATE'
static FAIL_FETCH = 'FAIL_FETCH'
static FAIL_UPDATE = 'FAIL_UPDATE'
static FAIL_DELETE = 'FAIL_DELETE'
static makeStandardToast(toast) {
switch (toast) {
case StandardToasts.SUCCESS_CREATE:
makeToast(i18n.tc('Success'), i18n.tc('success_creating_resource'), 'success')
break;
case StandardToasts.SUCCESS_FETCH:
makeToast(i18n.tc('Success'), i18n.tc('success_fetching_resource'), 'success')
break;
case StandardToasts.SUCCESS_UPDATE:
makeToast(i18n.tc('Success'), i18n.tc('success_updating_resource'), 'success')
break;
case StandardToasts.SUCCESS_DELETE:
makeToast(i18n.tc('Success'), i18n.tc('success_deleting_resource'), 'success')
break;
case StandardToasts.FAIL_CREATE:
makeToast(i18n.tc('Failure'), i18n.tc('success_creating_resource'), 'danger')
break;
case StandardToasts.FAIL_FETCH:
makeToast(i18n.tc('Failure'), i18n.tc('err_fetching_resource'), 'danger')
break;
case StandardToasts.FAIL_UPDATE:
makeToast(i18n.tc('Failure'), i18n.tc('err_updating_resource'), 'danger')
break;
case StandardToasts.FAIL_DELETE:
makeToast(i18n.tc('Failure'), i18n.tc('err_deleting_resource'), 'danger')
break;
}
}
}
/* /*
* Utility functions to use djangos gettext * Utility functions to use djangos gettext
* */ * */
@ -88,7 +132,7 @@ import {frac} from "@/utils/fractions";
export function calculateAmount(amount, factor) { export function calculateAmount(amount, factor) {
if (getUserPreference('use_fractions')) { if (getUserPreference('use_fractions')) {
let return_string = '' let return_string = ''
let fraction = frac((amount * factor), 9, true) let fraction = frac((amount * factor), 10, true)
if (fraction[0] > 0) { if (fraction[0] > 0) {
return_string += fraction[0] return_string += fraction[0]

View File

@ -71,17 +71,17 @@ module.exports = {
chainWebpack: config => { chainWebpack: config => {
config.optimization.splitChunks({ config.optimization.splitChunks({
cacheGroups: { cacheGroups: {
vendor: { vendor: {
test: /[\\/]node_modules[\\/]/, test: /[\\/]node_modules[\\/]/,
name: "chunk-vendors", name: "chunk-vendors",
chunks: "all", chunks: "all",
priority: 1 priority: 1
},
}, },
}, },
}, // TODO make this conditional on .env DEBUG = TRUE
// TODO make this conditional on .env DEBUG = TRUE config.optimization.minimize(true)
// config.optimization.minimize(false)
); );
//TODO somehow remov them as they are also added to the manifest config of the service worker //TODO somehow remov them as they are also added to the manifest config of the service worker

View File

@ -9296,9 +9296,9 @@ url-loader@^2.2.0:
schema-utils "^2.5.0" schema-utils "^2.5.0"
url-parse@^1.4.3, url-parse@^1.5.1: url-parse@^1.4.3, url-parse@^1.5.1:
version "1.5.1" version "1.5.3"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"