mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
update shopping performance
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-list-item class="swipe-container border-t-sm mt-0 mb-0 pt-0 pb-0 pe-0 pa-0 shopping-border" :id="itemContainerId" @touchend="handleSwipe()" @click="dialog = true;"
|
<v-list-item class="swipe-container border-t-sm mt-0 mb-0 pt-0 pb-0 pe-0 pa-0 shopping-border" :id="itemContainerId" @touchend="handleSwipe()" @click="dialog = true;"
|
||||||
v-if="isShoppingListFoodVisible(props.shoppingListFood, useUserPreferenceStore().deviceSettings)"
|
|
||||||
>
|
>
|
||||||
<!-- <div class="swipe-action" :class="{'bg-success': !isChecked , 'bg-warning': isChecked }">-->
|
<!-- <div class="swipe-action" :class="{'bg-success': !isChecked , 'bg-warning': isChecked }">-->
|
||||||
<!-- <i class="swipe-icon fa-fw fas" :class="{'fa-check': !isChecked , 'fa-cart-plus': isChecked }"></i>-->
|
<!-- <i class="swipe-icon fa-fw fas" :class="{'fa-check': !isChecked , 'fa-cart-plus': isChecked }"></i>-->
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
<span :style="{background: sl.color}" v-for="sl in shoppingList"></span>
|
<span :style="{background: sl.color}" v-for="sl in shoppingList"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-grow-1 p-2" >
|
<div class="flex-grow-1 p-2">
|
||||||
<div class="d-flex" >
|
<div class="d-flex">
|
||||||
<div class="d-flex flex-column pr-2 pl-4">
|
<div class="d-flex flex-column pr-2 pl-4">
|
||||||
<span v-for="a in amounts" v-bind:key="a.key">
|
<span v-for="a in amounts" v-bind:key="a.key">
|
||||||
<span>
|
<span>
|
||||||
@@ -59,7 +59,7 @@ import {computed, PropType, ref} from "vue";
|
|||||||
import {DateTime} from "luxon";
|
import {DateTime} from "luxon";
|
||||||
import {useShoppingStore} from "@/stores/ShoppingStore.js";
|
import {useShoppingStore} from "@/stores/ShoppingStore.js";
|
||||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore.js";
|
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore.js";
|
||||||
import {ApiApi, Food, ShoppingListEntry} from '@/openapi'
|
import {ApiApi, Food, ShoppingList, ShoppingListEntry} from '@/openapi'
|
||||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||||
import {IShoppingListFood, ShoppingLineAmount} from "@/types/Shopping";
|
import {IShoppingListFood, ShoppingLineAmount} from "@/types/Shopping";
|
||||||
import {isDelayed, isEntryVisible, isShoppingListFoodDelayed, isShoppingListFoodVisible} from "@/utils/logic_utils";
|
import {isDelayed, isEntryVisible, isShoppingListFoodDelayed, isShoppingListFoodVisible} from "@/utils/logic_utils";
|
||||||
@@ -86,9 +86,7 @@ const entries = computed(() => {
|
|||||||
*/
|
*/
|
||||||
const itemContainerId = computed(() => {
|
const itemContainerId = computed(() => {
|
||||||
let id = 'id_sli_'
|
let id = 'id_sli_'
|
||||||
for (let i in entries.value) {
|
entries.value.forEach(e => id += e.id + '_')
|
||||||
id += i + '_'
|
|
||||||
}
|
|
||||||
return id
|
return id
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -117,13 +115,18 @@ const actionButtonIcon = computed(() => {
|
|||||||
|
|
||||||
|
|
||||||
const shoppingList = computed(() => {
|
const shoppingList = computed(() => {
|
||||||
const lists = new Set()
|
const lists = [] as ShoppingList[]
|
||||||
for (let entry of entries.value) {
|
entries.value.forEach(e => {
|
||||||
if (entry.shoppingLists) {
|
if (e.shoppingLists) {
|
||||||
entry.shoppingLists.forEach(l => lists.add(l))
|
e.shoppingLists.forEach(l => {
|
||||||
|
if (lists.findIndex(sl => sl.id == l.id) == -1) {
|
||||||
|
lists.push(l)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
return Array.from(lists)
|
|
||||||
|
return lists
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -138,34 +141,34 @@ const amounts = computed((): ShoppingLineAmount[] => {
|
|||||||
for (let i in entries.value) {
|
for (let i in entries.value) {
|
||||||
let e = entries.value[i]
|
let e = entries.value[i]
|
||||||
|
|
||||||
if (isEntryVisible(e, useUserPreferenceStore().deviceSettings)) {
|
|
||||||
let unit = -1
|
|
||||||
if (e.unit !== undefined && e.unit !== null) {
|
|
||||||
unit = e.unit.id!
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.amount > 0) {
|
let unit = -1
|
||||||
|
if (e.unit !== undefined && e.unit !== null) {
|
||||||
|
unit = e.unit.id!
|
||||||
|
}
|
||||||
|
|
||||||
let uaMerged = false
|
if (e.amount > 0) {
|
||||||
unitAmounts.forEach(ua => {
|
|
||||||
if (((ua.unit == null && e.unit == null) || (ua.unit != null && ua.unit.id! == unit)) && ua.checked == e.checked && ua.delayed == isDelayed(e)) {
|
|
||||||
ua.amount += e.amount
|
|
||||||
uaMerged = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!uaMerged) {
|
let uaMerged = false
|
||||||
unitAmounts.push({
|
unitAmounts.forEach(ua => {
|
||||||
key: `${unit}_${e.checked}_${isDelayed(e)}`,
|
if (((ua.unit == null && e.unit == null) || (ua.unit != null && ua.unit.id! == unit)) && ua.checked == e.checked && ua.delayed == isDelayed(e)) {
|
||||||
amount: e.amount,
|
ua.amount += e.amount
|
||||||
unit: e.unit,
|
uaMerged = true
|
||||||
checked: e.checked,
|
|
||||||
delayed: isDelayed(e)
|
|
||||||
} as ShoppingLineAmount)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!uaMerged) {
|
||||||
|
unitAmounts.push({
|
||||||
|
key: `${unit}_${e.checked}_${isDelayed(e)}`,
|
||||||
|
amount: e.amount,
|
||||||
|
unit: e.unit,
|
||||||
|
checked: e.checked,
|
||||||
|
delayed: isDelayed(e)
|
||||||
|
} as ShoppingLineAmount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return unitAmounts
|
return unitAmounts
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -186,29 +189,28 @@ const infoRow = computed(() => {
|
|||||||
for (let i in entries.value) {
|
for (let i in entries.value) {
|
||||||
let e = entries.value[i]
|
let e = entries.value[i]
|
||||||
|
|
||||||
if (isEntryVisible(e, useUserPreferenceStore().deviceSettings)) {
|
|
||||||
|
|
||||||
if (authors.indexOf(e.createdBy.displayName) === -1) {
|
|
||||||
authors.push(e.createdBy.displayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.listRecipe != null) {
|
|
||||||
if (e.listRecipeData.recipe != null) {
|
|
||||||
let recipe_name = e.listRecipeData.recipeData.name
|
|
||||||
if (recipes.indexOf(recipe_name) === -1) {
|
|
||||||
recipes.push(recipe_name.substring(0, 14) + (recipe_name.length > 14 ? '..' : ''))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.listRecipeData.mealplan != null) {
|
|
||||||
let meal_plan_entry = (e.listRecipeData.mealPlanData.mealType.name.substring(0, 8) || '') + (e.listRecipeData.mealPlanData.mealType.name.length > 8 ? '..' : '') + ' (' + DateTime.fromJSDate(e.listRecipeData.mealPlanData.fromDate).toLocaleString(DateTime.DATE_SHORT) + ')'
|
|
||||||
if (meal_pans.indexOf(meal_plan_entry) === -1) {
|
|
||||||
meal_pans.push(meal_plan_entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (authors.indexOf(e.createdBy.displayName) === -1) {
|
||||||
|
authors.push(e.createdBy.displayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.listRecipe != null) {
|
||||||
|
if (e.listRecipeData.recipe != null) {
|
||||||
|
let recipe_name = e.listRecipeData.recipeData.name
|
||||||
|
if (recipes.indexOf(recipe_name) === -1) {
|
||||||
|
recipes.push(recipe_name.substring(0, 14) + (recipe_name.length > 14 ? '..' : ''))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.listRecipeData.mealplan != null) {
|
||||||
|
let meal_plan_entry = (e.listRecipeData.mealPlanData.mealType.name.substring(0, 8) || '') + (e.listRecipeData.mealPlanData.mealType.name.length > 8 ? '..' : '') + ' (' + DateTime.fromJSDate(e.listRecipeData.mealPlanData.fromDate).toLocaleString(DateTime.DATE_SHORT) + ')'
|
||||||
|
if (meal_pans.indexOf(meal_plan_entry) === -1) {
|
||||||
|
meal_pans.push(meal_plan_entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useUserPreferenceStore().deviceSettings.shopping_item_info_created_by && authors.length > 0) {
|
if (useUserPreferenceStore().deviceSettings.shopping_item_info_created_by && authors.length > 0) {
|
||||||
@@ -266,18 +268,18 @@ function handleSwipe() {
|
|||||||
|
|
||||||
/* 2. Container to wrap the color bars and place them to the far left */
|
/* 2. Container to wrap the color bars and place them to the far left */
|
||||||
.color-marker-container {
|
.color-marker-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-marker-container span {
|
.color-marker-container span {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<v-tabs v-model="currentTab">
|
<v-tabs v-model="currentTab">
|
||||||
<v-tab value="shopping"><i class="fas fa-fw"
|
<v-tab value="shopping"><i class="fas fa-fw"
|
||||||
:class="{'fa-circle-notch fa-spin':useShoppingStore().currentlyUpdating, 'fa-shopping-cart ': !useShoppingStore().currentlyUpdating}"></i> <span
|
:class="{'fa-circle-notch fa-spin':useShoppingStore().currentlyUpdating, 'fa-shopping-cart ': !useShoppingStore().currentlyUpdating}"></i> <span
|
||||||
class="d-none d-md-block ms-1">{{ $t('Shopping_list') }} ({{ useShoppingStore().stats.countUnchecked }})</span></v-tab>
|
class="d-none d-md-block ms-1">{{ $t('Shopping_list') }} ({{ useShoppingStore().totalFoods }})</span></v-tab>
|
||||||
<v-tab value="recipes"><i class="fas fa-book fa-fw"></i> <span class="d-none d-md-block ms-1">{{
|
<v-tab value="recipes"><i class="fas fa-book fa-fw"></i> <span class="d-none d-md-block ms-1">{{
|
||||||
$t('Recipes')
|
$t('Recipes')
|
||||||
}} ({{ useShoppingStore().getAssociatedRecipes().length }})</span></v-tab>
|
}} ({{ useShoppingStore().getAssociatedRecipes().length }})</span></v-tab>
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
</v-list>
|
</v-list>
|
||||||
<v-list class="mt-3" density="compact" v-else>
|
<v-list class="mt-3" density="compact" v-else>
|
||||||
<template v-for="category in useShoppingStore().getEntriesByGroup" :key="category.name">
|
<template v-for="category in useShoppingStore().getEntriesByGroup" :key="category.name">
|
||||||
<template v-if="isShoppingCategoryVisible(category)">
|
|
||||||
|
|
||||||
<v-list-subheader v-if="category.name === useShoppingStore().UNDEFINED_CATEGORY"><i>{{ $t('NoCategory') }}</i></v-list-subheader>
|
<v-list-subheader v-if="category.name === useShoppingStore().UNDEFINED_CATEGORY"><i>{{ $t('NoCategory') }}</i></v-list-subheader>
|
||||||
<v-list-subheader v-else>{{ category.name }}</v-list-subheader>
|
<v-list-subheader v-else>{{ category.name }}</v-list-subheader>
|
||||||
@@ -163,7 +163,6 @@
|
|||||||
<shopping-line-item :shopping-list-food="value"></shopping-line-item>
|
<shopping-line-item :shopping-list-food="value"></shopping-line-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,6 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
let supermarketCategories = ref([] as SupermarketCategory[])
|
let supermarketCategories = ref([] as SupermarketCategory[])
|
||||||
let supermarkets = ref([] as Supermarket[])
|
let supermarkets = ref([] as Supermarket[])
|
||||||
|
|
||||||
let stats = ref({
|
|
||||||
countChecked: 0,
|
|
||||||
countUnchecked: 0,
|
|
||||||
countCheckedFood: 0,
|
|
||||||
countUncheckedFood: 0,
|
|
||||||
countUncheckedDelayed: 0,
|
|
||||||
} as ShoppingListStats)
|
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
let currentlyUpdating = ref(false)
|
let currentlyUpdating = ref(false)
|
||||||
let initialized = ref(false)
|
let initialized = ref(false)
|
||||||
@@ -44,26 +36,21 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
let undoStack = ref([] as ShoppingOperationHistoryEntry[])
|
let undoStack = ref([] as ShoppingOperationHistoryEntry[])
|
||||||
let queueTimeoutId = ref(-1)
|
let queueTimeoutId = ref(-1)
|
||||||
let itemCheckSyncQueue = ref([] as IShoppingSyncQueueEntry[])
|
let itemCheckSyncQueue = ref([] as IShoppingSyncQueueEntry[])
|
||||||
|
let syncQueueRunning = ref(false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* build a multi-level data structure ready for display from shopping list entries
|
* build a multi-level data structure ready for display from shopping list entries
|
||||||
* group by selected grouping key
|
* group by selected grouping key
|
||||||
*/
|
*/
|
||||||
const getEntriesByGroup = computed(() => {
|
const getEntriesByGroup = computed(() => {
|
||||||
console.log("--> getEntriesByGroup called")
|
console.log('-> getEntriesByGroup called')
|
||||||
stats.value = {
|
|
||||||
countChecked: 0,
|
|
||||||
countUnchecked: 0,
|
|
||||||
countCheckedFood: 0,
|
|
||||||
countUncheckedFood: 0,
|
|
||||||
countUncheckedDelayed: 0,
|
|
||||||
} as ShoppingListStats
|
|
||||||
|
|
||||||
let structure = {} as IShoppingList
|
let structure = {} as IShoppingList
|
||||||
structure.categories = new Map<string, IShoppingListCategory>
|
structure.categories = new Map<string, IShoppingListCategory>
|
||||||
|
|
||||||
if (useUserPreferenceStore().deviceSettings.shopping_selected_grouping === ShoppingGroupingOptions.CATEGORY && useUserPreferenceStore().deviceSettings.shopping_selected_supermarket != null) {
|
const deviceSettings = useUserPreferenceStore().deviceSettings
|
||||||
useUserPreferenceStore().deviceSettings.shopping_selected_supermarket.categoryToSupermarket.forEach(cTS => {
|
|
||||||
|
if (deviceSettings.shopping_selected_grouping === ShoppingGroupingOptions.CATEGORY && deviceSettings.shopping_selected_supermarket != null) {
|
||||||
|
deviceSettings.shopping_selected_supermarket.categoryToSupermarket.forEach(cTS => {
|
||||||
structure.categories.set(cTS.category.name, {'name': cTS.category.name, 'foods': new Map<number, IShoppingListFood>} as IShoppingListCategory)
|
structure.categories.set(cTS.category.name, {'name': cTS.category.name, 'foods': new Map<number, IShoppingListFood>} as IShoppingListCategory)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -72,60 +59,50 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
|
|
||||||
// build structure
|
// build structure
|
||||||
entries.value.forEach(shoppingListEntry => {
|
entries.value.forEach(shoppingListEntry => {
|
||||||
structure = updateEntryInStructure(structure, shoppingListEntry)
|
if (isEntryVisible(shoppingListEntry, deviceSettings)) {
|
||||||
})
|
structure = updateEntryInStructure(structure, shoppingListEntry)
|
||||||
|
}
|
||||||
// statistics for UI conditions and display
|
|
||||||
structure.categories.forEach(category => {
|
|
||||||
let categoryStats = {
|
|
||||||
countChecked: 0,
|
|
||||||
countUnchecked: 0,
|
|
||||||
countCheckedFood: 0,
|
|
||||||
countUncheckedFood: 0,
|
|
||||||
countUncheckedDelayed: 0,
|
|
||||||
} as ShoppingListStats
|
|
||||||
|
|
||||||
category.foods.forEach(food => {
|
|
||||||
let food_checked = true
|
|
||||||
|
|
||||||
food.entries.forEach(entry => {
|
|
||||||
if (entry.checked) {
|
|
||||||
categoryStats.countChecked++
|
|
||||||
} else {
|
|
||||||
if (isDelayed(entry)) {
|
|
||||||
categoryStats.countUncheckedDelayed++
|
|
||||||
} else {
|
|
||||||
categoryStats.countUnchecked++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (food_checked) {
|
|
||||||
categoryStats.countCheckedFood++
|
|
||||||
} else {
|
|
||||||
categoryStats.countUncheckedFood++
|
|
||||||
}
|
|
||||||
})
|
|
||||||
category.stats = categoryStats
|
|
||||||
|
|
||||||
stats.value.countChecked += categoryStats.countChecked
|
|
||||||
stats.value.countUnchecked += categoryStats.countUnchecked
|
|
||||||
stats.value.countCheckedFood += categoryStats.countCheckedFood
|
|
||||||
stats.value.countUncheckedFood += categoryStats.countUncheckedFood
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// ordering
|
// ordering
|
||||||
let undefinedCategoryGroup = structure.categories.get(UNDEFINED_CATEGORY)
|
let undefinedCategoryGroup = structure.categories.get(UNDEFINED_CATEGORY)
|
||||||
if (undefinedCategoryGroup != null) {
|
if (undefinedCategoryGroup != null) {
|
||||||
|
totalFoods.value += undefinedCategoryGroup.foods.size
|
||||||
orderedStructure.push(undefinedCategoryGroup)
|
orderedStructure.push(undefinedCategoryGroup)
|
||||||
structure.categories.delete(UNDEFINED_CATEGORY)
|
structure.categories.delete(UNDEFINED_CATEGORY)
|
||||||
}
|
}
|
||||||
|
|
||||||
structure.categories.forEach(category => {
|
structure.categories.forEach(category => {
|
||||||
orderedStructure.push(category)
|
if (category.foods.size > 0) {
|
||||||
|
orderedStructure.push(category)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return orderedStructure
|
return orderedStructure
|
||||||
|
}, {
|
||||||
|
onTrack(e) {
|
||||||
|
// triggered when count.value is tracked as a dependency
|
||||||
|
|
||||||
|
},
|
||||||
|
onTrigger(e) {
|
||||||
|
// triggered when count.value is mutated
|
||||||
|
console.log('TRIGGER', e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the total number of foods in the shopping list
|
||||||
|
* since entries are always grouped by food, it makes no sense to display the entry count anywhere
|
||||||
|
*/
|
||||||
|
let totalFoods = computed(() => {
|
||||||
|
let count = 0
|
||||||
|
if (initialized.value){
|
||||||
|
getEntriesByGroup.value.forEach(category => {
|
||||||
|
count += category.foods.size
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return count
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,7 +153,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
function hasFailedItems() {
|
function hasFailedItems() {
|
||||||
for (let i in itemCheckSyncQueue.value) {
|
for (let i in itemCheckSyncQueue.value) {
|
||||||
if (itemCheckSyncQueue.value[i]['status'] === 'syncing_failed_before' || itemCheckSyncQueue.value[i]['status'] === 'waiting_failed_before') {
|
if (itemCheckSyncQueue.value[i]['status'] === 'syncing_failed_before' || itemCheckSyncQueue.value[i]['status'] === 'waiting_failed_before') {
|
||||||
return true
|
return !syncQueueRunning.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -198,6 +175,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
} else {
|
} else {
|
||||||
// only clear local entries when not given a meal plan to not accidentally filter the shopping list
|
// only clear local entries when not given a meal plan to not accidentally filter the shopping list
|
||||||
entries.value = new Map<number, ShoppingListEntry>
|
entries.value = new Map<number, ShoppingListEntry>
|
||||||
|
initialized.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
recLoadShoppingListEntries(requestParameters)
|
recLoadShoppingListEntries(requestParameters)
|
||||||
@@ -223,19 +201,28 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
function recLoadShoppingListEntries(requestParameters: ApiShoppingListEntryListRequest) {
|
function recLoadShoppingListEntries(requestParameters: ApiShoppingListEntryListRequest) {
|
||||||
let api = new ApiApi()
|
let api = new ApiApi()
|
||||||
return api.apiShoppingListEntryList(requestParameters).then((r) => {
|
return api.apiShoppingListEntryList(requestParameters).then((r) => {
|
||||||
|
let promises = [] as Promise<any>[]
|
||||||
|
let newMap = new Map<number, ShoppingListEntry>()
|
||||||
r.results.forEach((e) => {
|
r.results.forEach((e) => {
|
||||||
entries.value.set(e.id!, e)
|
newMap.set(e.id!, e)
|
||||||
})
|
})
|
||||||
|
// bulk assign to avoid unnecessary reactivity updates
|
||||||
|
entries.value = new Map([...entries.value, ...newMap])
|
||||||
|
|
||||||
if (requestParameters.page == 1 && r.next) {
|
if (requestParameters.page == 1) {
|
||||||
while (Math.ceil(r.count / requestParameters.pageSize) > requestParameters.page) {
|
if (r.next) {
|
||||||
requestParameters.page = requestParameters.page + 1
|
while (Math.ceil(r.count / requestParameters.pageSize) > requestParameters.page) {
|
||||||
recLoadShoppingListEntries(requestParameters)
|
requestParameters.page = requestParameters.page + 1
|
||||||
|
promises.push(recLoadShoppingListEntries(requestParameters))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
currentlyUpdating.value = false
|
Promise.allSettled(promises).then(() => {
|
||||||
initialized.value = true
|
currentlyUpdating.value = false
|
||||||
|
initialized.value = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
currentlyUpdating.value = false
|
currentlyUpdating.value = false
|
||||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
||||||
@@ -413,15 +400,18 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
let api = new ApiApi()
|
let api = new ApiApi()
|
||||||
let promises: Promise<void>[] = []
|
let promises: Promise<void>[] = []
|
||||||
|
|
||||||
itemCheckSyncQueue.value.forEach((entry, index) => {
|
let updatedEntries = new Map<number, ShoppingListEntry>()
|
||||||
entry['status'] = ((entry['status'] === 'waiting') ? 'syncing' : 'syncing_failed_before')
|
|
||||||
|
|
||||||
|
itemCheckSyncQueue.value.forEach((entry, index) => {
|
||||||
|
entry['status'] = ((entry['status'] === 'waiting_failed_before') ? 'syncing_failed_before' : 'syncing')
|
||||||
|
syncQueueRunning.value = true
|
||||||
let p = api.apiShoppingListEntryBulkCreate({shoppingListEntryBulk: entry}, {}).then((r) => {
|
let p = api.apiShoppingListEntryBulkCreate({shoppingListEntryBulk: entry}, {}).then((r) => {
|
||||||
entry.ids.forEach(id => {
|
entry.ids.forEach(id => {
|
||||||
let e = entries.value.get(id)
|
let e = entries.value.get(id)
|
||||||
e.updatedAt = r.timestamp
|
if (e) {
|
||||||
e.checked = r.checked
|
e.updatedAt = r.timestamp
|
||||||
entries.value.set(id, e)
|
updatedEntries.set(id, e)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
itemCheckSyncQueue.value.splice(index, 1)
|
itemCheckSyncQueue.value.splice(index, 1)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@@ -436,6 +426,8 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Promise.allSettled(promises).finally(() => {
|
Promise.allSettled(promises).finally(() => {
|
||||||
|
entries.value = new Map([...entries.value, ...updatedEntries])
|
||||||
|
syncQueueRunning.value = false
|
||||||
if (itemCheckSyncQueue.value.length > 0) {
|
if (itemCheckSyncQueue.value.length > 0) {
|
||||||
runSyncQueue(500)
|
runSyncQueue(500)
|
||||||
}
|
}
|
||||||
@@ -593,7 +585,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
hasFailedItems,
|
hasFailedItems,
|
||||||
itemCheckSyncQueue,
|
itemCheckSyncQueue,
|
||||||
undoStack,
|
undoStack,
|
||||||
stats,
|
totalFoods,
|
||||||
refreshFromAPI,
|
refreshFromAPI,
|
||||||
autoSync,
|
autoSync,
|
||||||
createObject,
|
createObject,
|
||||||
|
|||||||
Reference in New Issue
Block a user