diff --git a/vue/src/components/ShoppingLineItem.vue b/vue/src/components/ShoppingLineItem.vue
index f6f080062..a5560f6a9 100644
--- a/vue/src/components/ShoppingLineItem.vue
+++ b/vue/src/components/ShoppingLineItem.vue
@@ -1,7 +1,12 @@
-
@@ -186,7 +207,7 @@ export default {
if (e.recipe_mealplan !== null) {
let recipe_name = e.recipe_mealplan.recipe_name
if (recipes.indexOf(recipe_name) === -1) {
- recipes.push(recipe_name)
+ recipes.push(recipe_name.substring(0, 14) + (recipe_name.length > 14 ? '..' : ''))
}
if ('mealplan_from_date' in e.recipe_mealplan) {
@@ -196,14 +217,6 @@ export default {
}
}
}
-
- if (recipes.length > 1) {
- let short_recipes = []
- recipes.forEach(r => {
- short_recipes.push(r.substring(0, 14) + (r.length > 14 ? '..' : ''))
- })
- recipes = short_recipes
- }
}
if (useUserPreferenceStore().device_settings.shopping_item_info_created_by && authors.length > 0) {
@@ -236,9 +249,12 @@ export default {
dateStyle: "short",
}).format(Date.parse(datetime))
},
-
+ /**
+ * update the food after the category was changed
+ * handle changing category to category ID as a workaround
+ * @param food
+ */
updateFoodCategory: function (food) {
-
if (typeof food.supermarket_category === "number") { // not the best solution, but as long as generic multiselect does not support caching, I don't want to use a proper model
food.supermarket_category = this.useShoppingListStore().supermarket_categories.filter(sc => sc.id === food.supermarket_category)[0]
}
@@ -249,14 +265,66 @@ export default {
}).catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
+ },
+ /**
+ * function triggered by touchend event of swipe container
+ * check if min distance is reached and execute desired action
+ */
+ handleSwipe: function () {
+ const minDistance = 80;
+ const container = document.querySelector('.swipe-container');
+ // get the distance the user swiped
+ const swipeDistance = container.scrollLeft - container.clientWidth;
+ if (swipeDistance < minDistance * -1) {
+ useShoppingListStore().setEntriesCheckedState(this.entries, !this.is_checked)
+ } else if (swipeDistance > minDistance) {
+ useShoppingListStore().delayEntries(this.entries, !this.is_delayed, true)
+ }
}
-
-
},
}
diff --git a/vue/src/stores/ShoppingListStore.js b/vue/src/stores/ShoppingListStore.js
index 488b40ee8..f13076a6a 100644
--- a/vue/src/stores/ShoppingListStore.js
+++ b/vue/src/stores/ShoppingListStore.js
@@ -291,27 +291,34 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
* function to handle user checking or unchecking a set of entries
* @param {{}} entries set of entries
* @param checked boolean to set checked state of entry to
+ * @param undo if the user should be able to undo the change or not
*/
- setEntriesCheckedState(entries, checked) {
- this.registerChange((checked ? 'CHECKED' : 'UNCHECKED'), entries)
+ setEntriesCheckedState(entries, checked, undo) {
+ if (undo) {
+ this.registerChange((checked ? 'CHECKED' : 'UNCHECKED'), entries)
+ }
+
for (let i in entries) {
this.entries[i].checked = checked
this.updateObject(this.entries[i])
}
},
/**
- * function to handle user "delaying" shopping entries
+ * function to handle user "delaying" and "undelaying" shopping entries
* @param {{}} entries set of entries
+ * @param delay if entries should be delayed or if delay should be removed
+ * @param undo if the user should be able to undo the change or not
*/
- delayEntries(entries) {
- let delay = 4 //TODO get delay from settings in an offline friendly way
- let delay_date = new Date(Date.now() + delay * (60 * 60 * 1000))
+ delayEntries(entries, delay, undo) {
+ let delay_hours = 4 //TODO get delay from settings in an offline friendly way
+ let delay_date = new Date(Date.now() + delay_hours * (60 * 60 * 1000))
- this.registerChange('DELAY', entries)
+ if (undo) {
+ this.registerChange((delay ? 'DELAY' : 'UNDELAY'), entries)
+ }
for (let i in entries) {
- console.log('DELAYING ', i, ' until ', delay_date)
- this.entries[i].delay_until = delay_date
+ this.entries[i].delay_until = (delay ? delay_date : null)
this.updateObject(this.entries[i])
}
},
@@ -332,7 +339,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
* @param {{}} entries set of entries
*/
registerChange(type, entries) {
- if (!['CREATED', 'CHECKED', 'UNCHECKED', 'DELAY'].includes(type)) {
+ if (!['CREATED', 'CHECKED', 'UNCHECKED', 'DELAY', 'UNDELAY'].includes(type)) {
throw Error('Tried to register unknown change type')
}
this.undo_stack.push({'type': type, 'entries': entries})
@@ -346,18 +353,15 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
let type = last_item['type']
let entries = last_item['entries']
- for (let i in entries) {
- let e = entries[i]
- if (type === 'CREATED') {
+ if (type === 'CHECKED' || type === 'UNCHECKED') {
+ this.setEntriesCheckedState(entries, (type === 'UNCHECKED'), false)
+ } else if (type === 'DELAY' || type === 'UNDELAY') {
+ this.delayEntries(entries, (type === 'UNDELAY'), false)
+ } else if (type === 'CREATED') {
+ for (let i in entries) {
+ let e = entries[i]
this.deleteObject(e)
- } else if (type === 'CHECKED' || type === 'UNCHECKED') {
- e.checked = (type === 'UNCHECKED')
- this.updateObject(e)
- } else if (type === 'DELAY') {
- e.delay_until = null
- this.updateObject(e)
}
-
}
} else {
// can use localization in store