From b1b770c9e571cc04252ec3b668604ff4bd6ae65f Mon Sep 17 00:00:00 2001 From: xeals Date: Mon, 25 Oct 2021 17:25:35 +1100 Subject: [PATCH 01/10] Add KJ user preference --- cookbook/forms.py | 3 ++- .../migrations/0158_userpreference_use_kj.py | 18 ++++++++++++++++++ cookbook/models.py | 4 +++- cookbook/views/views.py | 1 + recipes/settings.py | 1 + 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 cookbook/migrations/0158_userpreference_use_kj.py diff --git a/cookbook/forms.py b/cookbook/forms.py index 60c9691b1..55aa1a0ad 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -39,7 +39,7 @@ class UserPreferenceForm(forms.ModelForm): class Meta: model = UserPreference fields = ( - 'default_unit', 'use_fractions', 'theme', 'nav_color', + 'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color', 'sticky_navbar', 'default_page', 'show_recent', 'search_style', 'plan_share', 'ingredient_decimals', 'shopping_auto_sync', 'comments' @@ -52,6 +52,7 @@ class UserPreferenceForm(forms.ModelForm): 'use_fractions': _( 'Enables support for fractions in ingredient amounts (e.g. convert decimals to fractions automatically)'), # noqa: E501 + 'use_kj': _('Display nutritional energy amounts in joules instead of calories'), # noqa: E501 'plan_share': _( 'Users with whom newly created meal plan/shopping list entries should be shared by default.'), # noqa: E501 diff --git a/cookbook/migrations/0158_userpreference_use_kj.py b/cookbook/migrations/0158_userpreference_use_kj.py new file mode 100644 index 000000000..bd2a27d79 --- /dev/null +++ b/cookbook/migrations/0158_userpreference_use_kj.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.7 on 2021-10-25 05:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0157_alter_searchpreference_trigram'), + ] + + operations = [ + migrations.AddField( + model_name='userpreference', + name='use_kj', + field=models.BooleanField(default=False), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 228c45be3..1e682f3a1 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -19,7 +19,8 @@ from treebeard.mp_tree import MP_Node, MP_NodeManager from django_scopes import ScopedManager, scopes_disabled from django_prometheus.models import ExportModelOperationsMixin from recipes.settings import (COMMENT_PREF_DEFAULT, FRACTION_PREF_DEFAULT, - STICKY_NAV_PREF_DEFAULT, SORT_TREE_BY_NAME) + KJ_PREF_DEFAULT, STICKY_NAV_PREF_DEFAULT, + SORT_TREE_BY_NAME) def get_user_name(self): @@ -217,6 +218,7 @@ class UserPreference(models.Model, PermissionModelMixin): ) default_unit = models.CharField(max_length=32, default='g') use_fractions = models.BooleanField(default=FRACTION_PREF_DEFAULT) + use_kj = models.BooleanField(default=KJ_PREF_DEFAULT) default_page = models.CharField( choices=PAGES, max_length=64, default=SEARCH ) diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 0ccd54612..5a94412b9 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -307,6 +307,7 @@ def user_settings(request): up.ingredient_decimals = form.cleaned_data['ingredient_decimals'] # noqa: E501 up.comments = form.cleaned_data['comments'] up.use_fractions = form.cleaned_data['use_fractions'] + up.use_kj = form.cleaned_data['use_kj'] up.sticky_navbar = form.cleaned_data['sticky_navbar'] up.shopping_auto_sync = form.cleaned_data['shopping_auto_sync'] diff --git a/recipes/settings.py b/recipes/settings.py index ebccbfa5e..5460d4818 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -44,6 +44,7 @@ REVERSE_PROXY_AUTH = bool(int(os.getenv('REVERSE_PROXY_AUTH', False))) # default value for user preference 'comment' COMMENT_PREF_DEFAULT = bool(int(os.getenv('COMMENT_PREF_DEFAULT', True))) FRACTION_PREF_DEFAULT = bool(int(os.getenv('FRACTION_PREF_DEFAULT', False))) +KJ_PREF_DEFAULT = bool(int(os.getenv('KJ_PREF_DEFAULT', False))) STICKY_NAV_PREF_DEFAULT = bool(int(os.getenv('STICKY_NAV_PREF_DEFAULT', True))) # minimum interval that users can set for automatic sync of shopping lists From 3d830a44493118dab06baeb9120a80d6501056d3 Mon Sep 17 00:00:00 2001 From: xeals Date: Mon, 25 Oct 2021 17:27:47 +1100 Subject: [PATCH 02/10] Display nutritional energy in KJ with preference --- cookbook/templates/recipe_view.html | 1 + vue/src/components/Nutrition.vue | 7 +++++-- vue/src/utils/utils.js | 11 +++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cookbook/templates/recipe_view.html b/cookbook/templates/recipe_view.html index b5f0d4c46..70ec627e8 100644 --- a/cookbook/templates/recipe_view.html +++ b/cookbook/templates/recipe_view.html @@ -69,6 +69,7 @@ window.USER_PREF = { 'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %}, 'ingredient_decimals': {% if request.user.userpreference.use_fractions %} {{ request.user.userpreference.ingredient_decimals }} {% else %} 2 {% endif %}, + 'use_kj': {% if request.user.userpreference.use_kj %} true {% else %} false {% endif %}, } diff --git a/vue/src/components/Nutrition.vue b/vue/src/components/Nutrition.vue index 9a3da1b3c..ec1c1da52 100644 --- a/vue/src/components/Nutrition.vue +++ b/vue/src/components/Nutrition.vue @@ -15,7 +15,7 @@ {{ $t('Calories') }}
- kcal +
@@ -54,7 +54,7 @@ diff --git a/vue/src/apps/RecipeEditView/RecipeEditView.vue b/vue/src/apps/RecipeEditView/RecipeEditView.vue index 076656648..f516a99c2 100644 --- a/vue/src/apps/RecipeEditView/RecipeEditView.vue +++ b/vue/src/apps/RecipeEditView/RecipeEditView.vue @@ -481,7 +481,7 @@ import {BootstrapVue} from 'bootstrap-vue' import 'bootstrap-vue/dist/bootstrap-vue.css' import draggable from 'vuedraggable' -import {ApiMixin, resolveDjangoUrl, ResolveUrlMixin, StandardToasts} from "@/utils/utils"; +import {ApiMixin, resolveDjangoUrl, ResolveUrlMixin, StandardToasts, convertEnergyToCalories} from "@/utils/utils"; import Multiselect from "vue-multiselect"; import {ApiApiFactory} from "@/utils/openapi/api"; import LoadingSpinner from "@/components/LoadingSpinner"; @@ -605,11 +605,13 @@ export default { updateRecipe: function (view_after) { let apiFactory = new ApiApiFactory() + this.normalizeEnergy() + this.sortSteps() for (let s of this.recipe.steps) { this.sortIngredients(s) - } + apiFactory.updateRecipe(this.recipe_id, this.recipe, {}).then((response) => { console.log(response) @@ -812,6 +814,11 @@ export default { el.select(); document.execCommand('copy'); document.body.removeChild(el); + }, + normalizeEnergy: function () { + if (this.recipe.nutrition && this.recipe.nutrition.calories) { + this.recipe.nutrition.calories = convertEnergyToCalories(this.recipe.nutrition.calories) + } } } diff --git a/vue/src/utils/utils.js b/vue/src/utils/utils.js index 8415f8163..3ad19b733 100644 --- a/vue/src/utils/utils.js +++ b/vue/src/utils/utils.js @@ -167,6 +167,14 @@ export function calculateEnergy(amount, factor) { } } +export function convertEnergyToCalories(amount) { + if (getUserPreference('use_kj')) { + return amount / KILOJOULES_PER_CALORIE + } else { + return amount + } +} + /* * Utility functions to use OpenAPIs generically * */ From 15eec9d3737487b779f857befc0e0a94476239e9 Mon Sep 17 00:00:00 2001 From: xeals Date: Mon, 25 Oct 2021 17:37:49 +1100 Subject: [PATCH 04/10] Set calories heading based on user preference --- vue/src/apps/RecipeEditView/RecipeEditView.vue | 7 +++++-- vue/src/components/Nutrition.vue | 7 +++++-- vue/src/utils/utils.js | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/vue/src/apps/RecipeEditView/RecipeEditView.vue b/vue/src/apps/RecipeEditView/RecipeEditView.vue index f516a99c2..7883f192e 100644 --- a/vue/src/apps/RecipeEditView/RecipeEditView.vue +++ b/vue/src/apps/RecipeEditView/RecipeEditView.vue @@ -108,7 +108,7 @@
- + @@ -481,7 +481,7 @@ import {BootstrapVue} from 'bootstrap-vue' import 'bootstrap-vue/dist/bootstrap-vue.css' import draggable from 'vuedraggable' -import {ApiMixin, resolveDjangoUrl, ResolveUrlMixin, StandardToasts, convertEnergyToCalories} from "@/utils/utils"; +import {ApiMixin, resolveDjangoUrl, ResolveUrlMixin, StandardToasts, convertEnergyToCalories, energyHeading} from "@/utils/utils"; import Multiselect from "vue-multiselect"; import {ApiApiFactory} from "@/utils/openapi/api"; import LoadingSpinner from "@/components/LoadingSpinner"; @@ -819,6 +819,9 @@ export default { if (this.recipe.nutrition && this.recipe.nutrition.calories) { this.recipe.nutrition.calories = convertEnergyToCalories(this.recipe.nutrition.calories) } + }, + energy: function () { + return energyHeading() } } diff --git a/vue/src/components/Nutrition.vue b/vue/src/components/Nutrition.vue index ec1c1da52..09e4da5c8 100644 --- a/vue/src/components/Nutrition.vue +++ b/vue/src/components/Nutrition.vue @@ -12,7 +12,7 @@
- {{ $t('Calories') }} + {{ energy() }}
@@ -54,7 +54,7 @@