@@ -77,4 +78,4 @@
$('#id_rating_show').html(rating.val() + '/5')
});
-
\ No newline at end of file
+
diff --git a/cookbook/templates/shopping_list.html b/cookbook/templates/shopping_list.html
index be33aafe..22d24875 100644
--- a/cookbook/templates/shopping_list.html
+++ b/cookbook/templates/shopping_list.html
@@ -1,5 +1,12 @@
-{% extends "base.html" %} {% comment %} TODO: Deprecate {% endcomment %} {% load django_tables2 %} {% load crispy_forms_tags %} {% load static %} {% load i18n %} {% block title
-%}{% trans "Shopping List" %}{% endblock %} {% block extra_head %} {% include 'include/vue_base.html' %}
+{% extends "base.html" %}
+{% comment %} TODO: Deprecate {% endcomment %}
+{% load django_tables2 %}
+{% load crispy_forms_tags %}
+{% load static %}
+{% load i18n %}
+{% block title %}{% trans "Shopping List" %}{% endblock %}
+{% block extra_head %}
+{% include 'include/vue_base.html' %}
@@ -907,7 +914,7 @@
this.makeToast(gettext('Error'), gettext("There was an error loading a resource!") + err.bodyText, 'danger')
})
},
- searchSupermarket: function (query) { //TODO move to central component
+ searchSupermarket: function (query) {
this.supermarkets_loading = true
this.$http.get("{% url 'api:supermarket-list' %}" + '?query=' + query + '&limit=10').then((response) => {
this.supermarkets = response.data
diff --git a/cookbook/templates/url_import.html b/cookbook/templates/url_import.html
index 6457f876..4850cb82 100644
--- a/cookbook/templates/url_import.html
+++ b/cookbook/templates/url_import.html
@@ -714,7 +714,6 @@
},
methods: {
makeToast: function (title, message, variant = null) {
- //TODO remove duplicate function in favor of central one
this.$bvToast.toast(message, {
title: title,
variant: variant,
diff --git a/cookbook/views/api.py b/cookbook/views/api.py
index e171ea20..a1d85102 100644
--- a/cookbook/views/api.py
+++ b/cookbook/views/api.py
@@ -657,7 +657,6 @@ class RecipeViewSet(viewsets.ModelViewSet):
servings = request.data.get('servings', obj.servings)
list_recipe = request.data.get('list_recipe', None)
content = {'msg': _(f'{obj.name} was added to the shopping list.')}
- # TODO: Consider if this should be a Recipe method
list_from_recipe(list_recipe=list_recipe, recipe=obj, ingredients=ingredients, servings=servings, space=request.space, created_by=request.user)
return Response(content, status=status.HTTP_204_NO_CONTENT)
diff --git a/vue/src/apps/ModelListView/ModelListView.vue b/vue/src/apps/ModelListView/ModelListView.vue
index f0d6ab18..35402456 100644
--- a/vue/src/apps/ModelListView/ModelListView.vue
+++ b/vue/src/apps/ModelListView/ModelListView.vue
@@ -90,7 +90,7 @@ export default {
left_counts: { max: 9999, current: 0 },
this_model: undefined,
model_menu: undefined,
- this_action: undefined,
+ this_action: {},
this_recipe_param: undefined,
this_item: {},
this_target: {},
@@ -193,6 +193,13 @@ export default {
this.getRecipes(param, source)
}
break
+ case "add-shopping":
+ //TODO: add modal to edit units and amount
+ this.addShopping(e.source)
+ break
+ case "add-onhand":
+ this.addOnhand(e.source)
+ break
}
},
finishAction: function (e) {
@@ -232,26 +239,6 @@ export default {
let results = result.data?.results ?? result.data
if (results?.length) {
- // let secondaryRequest = undefined;
- // if (this['items_' + column]?.length < getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1)) {
- // // the item list is smaller than it should be based on the site the user is own
- // // this happens when an item is deleted (or merged)
- // // to prevent issues insert the last item of the previous search page before loading the new results
- // params.page = params.page - 1
- // secondaryRequest = this.genericAPI(this.this_model, this.Actions.LIST, params).then((result) => {
- // let prev_page_results = result.data?.results ?? result.data
- // if (prev_page_results?.length) {
- // results = [prev_page_results[prev_page_results.length]].concat(results)
- //
- // this['items_' + column] = this['items_' + column].concat(results) //TODO duplicate code, find some elegant workaround
- // this[column + '_counts']['current'] = getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1) + results.length
- // this[column + '_counts']['max'] = result.data?.count ?? 0
- // }
- // })
- // } else {
- //
- // }
-
this["items_" + column] = this["items_" + column].concat(results)
this[column + "_counts"]["current"] = getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1) + results.length
this[column + "_counts"]["max"] = result.data?.count ?? 0
@@ -276,6 +263,21 @@ export default {
// this creates a deep copy to make sure that columns stay independent
this.items_right = [{ ...item }].concat(this.destroyCard(item?.id, this.items_right))
},
+ // this currently assumes shopping is only applicable on FOOD model
+ addShopping: function (food) {
+ let api = new ApiApiFactory()
+ food.shopping = true
+ api.createShoppingListEntry({ food: food, amount: 1 }).then(() => {
+ StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
+ this.refreshCard(food, this.items_left)
+ this.refreshCard({ ...food }, this.items_right)
+ })
+ },
+ addOnhand: function (item) {
+ item.on_hand = true
+ this.saveThis(item)
+ },
+
updateThis: function (item) {
this.refreshThis(item.id)
},
@@ -300,7 +302,7 @@ export default {
})
.catch((err) => {
console.log(err)
- makeToast(this.$t("Error"), err.bodyText, "danger")
+ StandardToasts.makeStandardToast(StandardToasts.FAIL_MOVE, err?.bodyText)
})
},
moveUpdateItem: function (source_id, target_id) {
@@ -336,12 +338,12 @@ export default {
.then((result) => {
this.mergeUpdateItem(source_id, target_id)
// TODO make standard toast
- makeToast(this.$t("Success"), "Succesfully merged resource", "success")
+ StandardToasts.makeStandardToast(StandardToasts.SUCCESS_MERGE)
})
.catch((err) => {
//TODO error checking not working with OpenAPI methods
console.log("Error", err)
- makeToast(this.$t("Error"), err.bodyText, "danger")
+ StandardToasts.makeStandardToast(StandardToasts.FAIL_MOVE, err?.bodyText)
})
if (automate) {
@@ -425,7 +427,7 @@ export default {
},
clearState: function () {
this.show_modal = false
- this.this_action = undefined
+ this.this_action = {}
this.this_item = undefined
this.this_target = undefined
},
diff --git a/vue/src/components/Badges/OnHand.vue b/vue/src/components/Badges/OnHand.vue
index 5aff2111..9f851af1 100644
--- a/vue/src/components/Badges/OnHand.vue
+++ b/vue/src/components/Badges/OnHand.vue
@@ -1,40 +1,45 @@
-
-
+
-
+
\ No newline at end of file
+
diff --git a/vue/src/components/Badges/Shopping.vue b/vue/src/components/Badges/Shopping.vue
index 9c2b8576..9bbe061a 100644
--- a/vue/src/components/Badges/Shopping.vue
+++ b/vue/src/components/Badges/Shopping.vue
@@ -1,94 +1,96 @@
-
-
-
-
-
- {{DeleteConfirmation}}
-
- {{$t("Cancel")}}
- {{$t("Confirm")}}
-
-
-
+
+
+
+
+
+ {{ DeleteConfirmation }}
+
+ {{ $t("Cancel") }}
+ {{ $t("Confirm") }}
+
+
+
\ No newline at end of file
+
diff --git a/vue/src/components/ContextMenu/GenericContextMenu.vue b/vue/src/components/ContextMenu/GenericContextMenu.vue
index 166b798e..b513bc64 100644
--- a/vue/src/components/ContextMenu/GenericContextMenu.vue
+++ b/vue/src/components/ContextMenu/GenericContextMenu.vue
@@ -1,42 +1,38 @@
-
-
-
-
-
-
- {{ $t('Edit') }}
-
-
-
- {{ $t('Delete') }}
-
+
+
+
+
+
+ {{ $t("Edit") }}
-
- {{ $t('Move') }}
-
-
-
- {{ $t('Merge') }}
-
+ {{ $t("Delete") }}
+
+ {{ $t("Add_to_Shopping") }}
+
+ {{ $t("OnHand") }}
-
- {{$t('Merge')}} & {{$t('Automate')}} BETA
-
+ {{ $t("Move") }}
-
-
+ {{ $t("Merge") }}
+
+
+ {{ $t("Merge") }} & {{ $t("Automate") }} BETA
+
+
+
\ No newline at end of file
+
diff --git a/vue/src/components/GenericHorizontalCard.vue b/vue/src/components/GenericHorizontalCard.vue
index c5448b29..6ea8e558 100644
--- a/vue/src/components/GenericHorizontalCard.vue
+++ b/vue/src/components/GenericHorizontalCard.vue
@@ -24,7 +24,7 @@
{{ item[title] }}
{{ item[subtitle] }}
-
+
@@ -126,8 +128,6 @@
{{ $t("Cancel") }}
-
-
@@ -185,6 +185,12 @@ export default {
useMerge: function() {
return this.model?.["merge"] ?? false ? true : false
},
+ useShopping: function() {
+ return this.model?.["shop"] ?? false ? true : false
+ },
+ useOnhand: function() {
+ return this.model?.["onhand"] ?? false ? true : false
+ },
useDrag: function() {
return this.useMove || this.useMerge
},
diff --git a/vue/src/components/GenericOrderedPill.vue b/vue/src/components/GenericOrderedPill.vue
index 27197b31..2d2db871 100644
--- a/vue/src/components/GenericOrderedPill.vue
+++ b/vue/src/components/GenericOrderedPill.vue
@@ -1,72 +1,75 @@
-
-
diff --git a/vue/src/components/Modals/GenericModalForm.vue b/vue/src/components/Modals/GenericModalForm.vue
index 4855f89b..26ede38b 100644
--- a/vue/src/components/Modals/GenericModalForm.vue
+++ b/vue/src/components/Modals/GenericModalForm.vue
@@ -83,7 +83,6 @@ export default {
show: function () {
if (this.show) {
this.form = getForm(this.model, this.action, this.item1, this.item2)
- // TODO: I don't know how to generalize this, but Food needs default values to drive inheritance
if (this.form?.form_function) {
this.form = formFunctions[this.form.form_function](this.form)
}
diff --git a/vue/src/components/RecipeCard.vue b/vue/src/components/RecipeCard.vue
index 1728670d..f49c3d9c 100755
--- a/vue/src/components/RecipeCard.vue
+++ b/vue/src/components/RecipeCard.vue
@@ -82,6 +82,9 @@ export default {
footer_text: String,
footer_icon: String,
},
+ mounted() {
+ console.log(this.recipe)
+ },
computed: {
detailed: function() {
return this.recipe?.steps !== undefined
diff --git a/vue/src/utils/models.js b/vue/src/utils/models.js
index ab94efdc..cb63ec50 100644
--- a/vue/src/utils/models.js
+++ b/vue/src/utils/models.js
@@ -65,6 +65,8 @@ export class Models {
paginated: true,
move: true,
merge: true,
+ shop: true,
+ onhand: true,
badges: {
linked_recipe: true,
on_hand: true,
diff --git a/vue/src/utils/openapi/api.ts b/vue/src/utils/openapi/api.ts
index 060f02eb..08ea4ab6 100644
--- a/vue/src/utils/openapi/api.ts
+++ b/vue/src/utils/openapi/api.ts
@@ -2160,7 +2160,7 @@ export interface ShoppingListEntries {
* @type {string}
* @memberof ShoppingListEntries
*/
- completed_at: string | null;
+ completed_at?: string | null;
/**
*
* @type {string}
@@ -2251,7 +2251,7 @@ export interface ShoppingListEntry {
* @type {string}
* @memberof ShoppingListEntry
*/
- completed_at: string | null;
+ completed_at?: string | null;
/**
*
* @type {string}
@@ -3014,10 +3014,10 @@ export interface UserPreference {
food_ignore_default?: string;
/**
*
- * @type {number}
+ * @type {string}
* @memberof UserPreference
*/
- default_delay?: number;
+ default_delay?: string;
/**
*
* @type {boolean}
@@ -3036,6 +3036,12 @@ export interface UserPreference {
* @memberof UserPreference
*/
shopping_share?: Array