diff --git a/cookbook/models.py b/cookbook/models.py index a0a2cbf39..a8302f696 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -983,6 +983,8 @@ class RecipeBook(ExportModelOperationsMixin('book'), models.Model, PermissionMod shared = models.ManyToManyField(User, blank=True, related_name='shared_with') created_by = models.ForeignKey(User, on_delete=models.CASCADE) filter = models.ForeignKey('cookbook.CustomFilter', null=True, blank=True, on_delete=models.SET_NULL) + order = models.IntegerField(default=0) + space = models.ForeignKey(Space, on_delete=models.CASCADE) objects = ScopedManager(space='space') diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 4c7e2dfb8..873880d61 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -979,7 +979,7 @@ class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer) class Meta: model = RecipeBook - fields = ('id', 'name', 'description', 'shared', 'created_by', 'filter') + fields = ('id', 'name', 'description', 'shared', 'created_by', 'filter', 'order') read_only_fields = ('created_by',) diff --git a/cookbook/templates/recipe_view.html b/cookbook/templates/recipe_view.html index 2ec2b1179..c0f62d475 100644 --- a/cookbook/templates/recipe_view.html +++ b/cookbook/templates/recipe_view.html @@ -79,6 +79,7 @@ window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}' window.RECIPE_ID = {{recipe.pk}}; + window.RECIPE_SERVINGS = '{{ servings }}' window.SHARE_UID = '{{ share }}'; window.USER_PREF = { 'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %}, diff --git a/cookbook/views/api.py b/cookbook/views/api.py index e4c91b2ba..1b1bd29ab 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -662,8 +662,16 @@ class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [(CustomIsOwner | CustomIsShared) & CustomTokenHasReadWriteScope] def get_queryset(self): + order_field = self.request.GET.get('order_field') + order_direction = self.request.GET.get('order_direction') + + if not order_field: + order_field = 'id' + + ordering = f"{'' if order_direction == 'asc' else '-'}{order_field}" + self.queryset = self.queryset.filter(Q(created_by=self.request.user) | Q(shared=self.request.user)).filter( - space=self.request.space).distinct() + space=self.request.space).distinct().order_by(ordering) return super().get_queryset() diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 3ed22b4b1..55474494d 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -157,7 +157,11 @@ def recipe_view(request, pk, share=None): if not ViewLog.objects.filter(recipe=recipe, created_by=request.user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)), space=request.space).exists(): ViewLog.objects.create(recipe=recipe, created_by=request.user, space=request.space) - return render(request, 'recipe_view.html', {'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, }) + if request.method == "GET": + servings = request.GET.get("servings") + return render(request, 'recipe_view.html', + {'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, 'servings': servings }) + @group_required('user') diff --git a/requirements.txt b/requirements.txt index 796a27253..fd8765989 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ django-autocomplete-light==3.9.7 django-cleanup==8.0.0 django-crispy-forms==2.0 crispy-bootstrap4==2022.1 -django-tables2==2.5.3 +django-tables2==2.7.0 djangorestframework==3.14.0 drf-writable-nested==0.7.0 django-oauth-toolkit==2.3.0 @@ -40,8 +40,8 @@ django-storages==1.14.2 boto3==1.28.75 django-prometheus==2.2.0 django-hCaptcha==0.2.0 -python-ldap==3.4.3 -django-auth-ldap==4.4.0 +python-ldap==3.4.4 +django-auth-ldap==4.6.0 pytest-factoryboy==2.6.0 pyppeteer==1.0.2 validators==0.20.0 diff --git a/vue/package.json b/vue/package.json index 3e069f81c..c42298311 100644 --- a/vue/package.json +++ b/vue/package.json @@ -13,11 +13,11 @@ "@codemirror/commands": "^6.3.2", "@codemirror/lang-markdown": "^6.2.3", "@codemirror/state": "^6.3.3", - "@codemirror/view": "^6.22.2", + "@codemirror/view": "^6.23.1", "@popperjs/core": "^2.11.7", "@vue/cli": "^5.0.8", "@vue/composition-api": "1.7.1", - "axios": "^1.6.0", + "axios": "^1.6.7", "babel": "^6.23.0", "babel-core": "^6.26.3", "babel-loader": "^9.1.0", @@ -26,7 +26,7 @@ "lodash": "^4.17.21", "mavon-editor": "^2.10.4", "moment": "^2.29.4", - "pinia": "^2.0.30", + "pinia": "^2.1.7", "prismjs": "^1.29.0", "string-similarity": "^4.0.4", "vue": "^2.6.14", @@ -61,9 +61,9 @@ "babel-eslint": "^10.1.0", "eslint": "^8.46.0", "eslint-plugin-vue": "^8.7.1", - "typescript": "~5.1.6", + "typescript": "~5.3.3", "vue-cli-plugin-i18n": "^2.3.2", - "webpack-bundle-tracker": "1.8.1", + "webpack-bundle-tracker": "3.0.1", "workbox-background-sync": "^7.0.0", "workbox-expiration": "^6.5.4", "workbox-navigation-preload": "^7.0.0", diff --git a/vue/src/apps/CookbookView/CookbookView.vue b/vue/src/apps/CookbookView/CookbookView.vue index bc922d7e6..9ad465d53 100644 --- a/vue/src/apps/CookbookView/CookbookView.vue +++ b/vue/src/apps/CookbookView/CookbookView.vue @@ -11,50 +11,90 @@ + + oldest to newest + newest to oldest + alphabetical order + manually + + + {{submitText}} + -
-
-
-
- - - - - -
- {{ book.name }} -
-
{{ book.description }}
-
-
-
-
-
-
+
+
+
+
+
+ + + + + + +
+ {{ book.name }} +
+
{{ book.description }}
+
+
+
+
+
+
+
+
+ + + + + +
- - - - - - +
+
+ + + +
+
+ +
+
+
+ + #{{ index + 1 }} + + {{ book.name }} +
+
+
+
+
+
-
-