mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-05 06:08:46 -05:00
lots of WIP stuff
This commit is contained in:
@@ -945,8 +945,8 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
|
|||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
|
||||||
def __str__(self):
|
# def __str__(self):
|
||||||
return f'{self.pk}: {self.amount} ' + (self.food.name if self.food else ' ') + (self.unit.name if self.unit else '')
|
# return f'{self.pk}: {self.amount} ' + (self.food.name if self.food else ' ') + (self.unit.name if self.unit else '')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['order', 'pk']
|
ordering = ['order', 'pk']
|
||||||
@@ -1299,8 +1299,8 @@ class ShoppingListRecipe(ExportModelOperationsMixin('shopping_list_recipe'), mod
|
|||||||
|
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
|
||||||
def __str__(self):
|
# def __str__(self):
|
||||||
return f'Shopping list recipe {self.id} - {self.recipe}'
|
# return f'Shopping list recipe {self.id} - {self.recipe}'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('pk',)
|
ordering = ('pk',)
|
||||||
@@ -1317,6 +1317,9 @@ class ShoppingList(ExportModelOperationsMixin('shopping_list'), models.Model, Pe
|
|||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ('pk',)
|
||||||
|
|
||||||
|
|
||||||
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
|
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
|
||||||
shopping_lists = models.ManyToManyField(ShoppingList, blank=True)
|
shopping_lists = models.ManyToManyField(ShoppingList, blank=True)
|
||||||
|
|||||||
@@ -186,11 +186,29 @@ class SpaceFilterSerializer(serializers.ListSerializer):
|
|||||||
if isinstance(self.context['request'].user, AnonymousUser):
|
if isinstance(self.context['request'].user, AnonymousUser):
|
||||||
data = []
|
data = []
|
||||||
else:
|
else:
|
||||||
data = data.filter(userspace__space=self.context['request'].user.get_active_space()).all()
|
iterable = data.all() if hasattr(data, 'all') else data
|
||||||
|
if isinstance(iterable, list) or (isinstance(iterable, QuerySet) and getattr(iterable, '_result_cache', None) is not None):
|
||||||
|
data = [d for d in iterable if d.userspace.space.id == self.context['request'].space.id]
|
||||||
|
else:
|
||||||
|
if hasattr(self.context['request'], 'space'):
|
||||||
|
data = data.filter(userspace__space=self.context['request'].space).all()
|
||||||
|
else:
|
||||||
|
# not sure why but this branch can be hit (just normal page load, need to see why)
|
||||||
|
data = data.filter(userspace__space=self.context['request'].user.get_active_space()).all()
|
||||||
|
|
||||||
elif isinstance(data, list):
|
elif isinstance(data, list):
|
||||||
data = [d for d in data if getattr(d, self.child.Meta.model.get_space_key()[0]) == self.context['request'].space]
|
data = [d for d in data if getattr(d, self.child.Meta.model.get_space_key()[0]) == self.context['request'].space]
|
||||||
else:
|
else:
|
||||||
data = data.filter(**{'__'.join(self.child.Meta.model.get_space_key()): self.context['request'].space})
|
iterable = data.all() if hasattr(data, 'all') else data
|
||||||
|
if isinstance(iterable, list) or (isinstance(iterable, QuerySet) and getattr(iterable, '_result_cache', None) is not None):
|
||||||
|
keys = self.child.Meta.model.get_space_key()
|
||||||
|
if keys == ('space',):
|
||||||
|
data = [d for d in iterable if getattr(d, 'space_id') == self.context['request'].space.id]
|
||||||
|
else:
|
||||||
|
# use cached results here too, just dont have time to test this now, probably obj.get_space()
|
||||||
|
data = data.filter(**{'__'.join(self.child.Meta.model.get_space_key()): self.context['request'].space})
|
||||||
|
else:
|
||||||
|
data = data.filter(**{'__'.join(self.child.Meta.model.get_space_key()): self.context['request'].space})
|
||||||
return super().to_representation(data)
|
return super().to_representation(data)
|
||||||
|
|
||||||
|
|
||||||
@@ -648,7 +666,7 @@ class KeywordLabelSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
@extend_schema_field(str)
|
@extend_schema_field(str)
|
||||||
def get_label(self, obj):
|
def get_label(self, obj):
|
||||||
return str(obj)
|
return obj.name
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
list_serializer_class = SpaceFilterSerializer
|
list_serializer_class = SpaceFilterSerializer
|
||||||
@@ -665,7 +683,7 @@ class KeywordSerializer(UniqueFieldsMixin, ExtendedRecipeMixin):
|
|||||||
|
|
||||||
@extend_schema_field(str)
|
@extend_schema_field(str)
|
||||||
def get_label(self, obj):
|
def get_label(self, obj):
|
||||||
return str(obj)
|
return obj.name
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
# since multi select tags dont have id's
|
# since multi select tags dont have id's
|
||||||
@@ -1327,7 +1345,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
|||||||
|
|
||||||
@extend_schema_field(bool)
|
@extend_schema_field(bool)
|
||||||
def in_shopping(self, obj):
|
def in_shopping(self, obj):
|
||||||
return ShoppingListRecipe.objects.filter(mealplan=obj.id).exists()
|
return obj.shoppinglistrecipe_set.count() > 0
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
validated_data['created_by'] = self.context['request'].user
|
validated_data['created_by'] = self.context['request'].user
|
||||||
@@ -1393,7 +1411,7 @@ class ShoppingListRecipeSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ShoppingListRecipe
|
model = ShoppingListRecipe
|
||||||
fields = ('id', 'name', 'recipe', 'recipe_data', 'mealplan', 'meal_plan_data', 'servings', 'created_by',)
|
fields = ('id', 'name', 'recipe', 'recipe_data', 'meal_plan_data', 'mealplan', 'servings', 'created_by',)
|
||||||
read_only_fields = ('id', 'created_by',)
|
read_only_fields = ('id', 'created_by',)
|
||||||
|
|
||||||
|
|
||||||
@@ -1412,7 +1430,7 @@ class ShoppingListSerializer(SpacedModelSerializer, WritableNestedModelSerialize
|
|||||||
|
|
||||||
|
|
||||||
class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
||||||
food = FoodSerializer(allow_null=True)
|
food = FoodSimpleSerializer(allow_null=True)
|
||||||
unit = UnitSerializer(allow_null=True, required=False)
|
unit = UnitSerializer(allow_null=True, required=False)
|
||||||
shopping_lists = ShoppingListSerializer(many=True, required=False)
|
shopping_lists = ShoppingListSerializer(many=True, required=False)
|
||||||
list_recipe_data = ShoppingListRecipeSerializer(source='list_recipe', read_only=True)
|
list_recipe_data = ShoppingListRecipeSerializer(source='list_recipe', read_only=True)
|
||||||
|
|||||||
@@ -2043,17 +2043,18 @@ class ShoppingListEntryViewSet(LoggingMixin, viewsets.ModelViewSet):
|
|||||||
|
|
||||||
self.queryset = self.queryset.filter(
|
self.queryset = self.queryset.filter(
|
||||||
Q(created_by=self.request.user)
|
Q(created_by=self.request.user)
|
||||||
| Q(created_by__in=list(self.request.user.get_shopping_share()))).prefetch_related('created_by', 'food',
|
| Q(created_by__in=list(self.request.user.get_shopping_share()))).prefetch_related('created_by',
|
||||||
'food__properties',
|
'food',
|
||||||
'food__properties__property_type',
|
'shopping_lists',
|
||||||
'food__inherit_fields',
|
'unit',
|
||||||
'food__supermarket_category',
|
'list_recipe',
|
||||||
'food__onhand_users',
|
'list_recipe__recipe__keywords',
|
||||||
'food__substitute',
|
'list_recipe__recipe__created_by',
|
||||||
'food__child_inherit_fields',
|
|
||||||
'unit', 'list_recipe',
|
|
||||||
'list_recipe__mealplan',
|
'list_recipe__mealplan',
|
||||||
|
'list_recipe__mealplan__shared',
|
||||||
|
'list_recipe__mealplan__shoppinglistrecipe_set',
|
||||||
'list_recipe__mealplan__recipe',
|
'list_recipe__mealplan__recipe',
|
||||||
|
'list_recipe__mealplan__recipe__keywords',
|
||||||
).distinct().all()
|
).distinct().all()
|
||||||
|
|
||||||
updated_after = self.request.query_params.get('updated_after', None)
|
updated_after = self.request.query_params.get('updated_after', None)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-list-item class="swipe-container border-t-sm mt-0 mb-0 pt-0 pb-0 pe-0 pa-0" :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)"
|
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>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<div class="color-marker-container">
|
||||||
|
<span :style="{background: sl.color}" v-for="sl in shoppingList"></span>
|
||||||
|
</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>
|
||||||
@@ -113,6 +116,17 @@ const actionButtonIcon = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const shoppingList = computed(() => {
|
||||||
|
const lists = new Set()
|
||||||
|
for (let entry of entries.value) {
|
||||||
|
if (entry.shoppingLists) {
|
||||||
|
entry.shoppingLists.forEach(l => lists.add(l))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array.from(lists)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate the amounts for the given line
|
* calculate the amounts for the given line
|
||||||
* can combine 1 to n entries with the same unit
|
* can combine 1 to n entries with the same unit
|
||||||
@@ -248,4 +262,22 @@ function handleSwipe() {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* TODO swipe system classes removed because not working (visually, touch detection was working), retrieve from old ShoppingLineItem VCS */
|
/* TODO swipe system classes removed because not working (visually, touch detection was working), retrieve from old ShoppingLineItem VCS */
|
||||||
|
|
||||||
|
|
||||||
|
/* 2. Container to wrap the color bars and place them to the far left */
|
||||||
|
.color-marker-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 3px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-marker-container span {
|
||||||
|
width: 100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -89,7 +89,6 @@
|
|||||||
|
|
||||||
<v-row class="pa-0" dense>
|
<v-row class="pa-0" dense>
|
||||||
<v-col class="pa-0" cols="6">
|
<v-col class="pa-0" cols="6">
|
||||||
|
|
||||||
<v-chip label density="compact" variant="outlined" :prepend-icon="TSupermarket.icon" append-icon="fa-solid fa-caret-down">
|
<v-chip label density="compact" variant="outlined" :prepend-icon="TSupermarket.icon" append-icon="fa-solid fa-caret-down">
|
||||||
<template v-if="useUserPreferenceStore().deviceSettings.shopping_selected_supermarket != null">
|
<template v-if="useUserPreferenceStore().deviceSettings.shopping_selected_supermarket != null">
|
||||||
{{useUserPreferenceStore().deviceSettings.shopping_selected_supermarket.name}}
|
{{useUserPreferenceStore().deviceSettings.shopping_selected_supermarket.name}}
|
||||||
@@ -101,11 +100,34 @@
|
|||||||
<v-list-item v-for="s in supermarkets" :key="s.id" @click="useUserPreferenceStore().deviceSettings.shopping_selected_supermarket = s">
|
<v-list-item v-for="s in supermarkets" :key="s.id" @click="useUserPreferenceStore().deviceSettings.shopping_selected_supermarket = s">
|
||||||
{{ s.name }}
|
{{ s.name }}
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item prepend-icon="$create" :to="{name: 'ModelEditPage', params: {model: 'Supermarket'}}">
|
||||||
|
{{$t('Create')}}
|
||||||
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</v-chip>
|
</v-chip>
|
||||||
|
</v-col>
|
||||||
|
<v-col class="pa-0" cols="6">
|
||||||
|
<v-chip label density="compact" variant="outlined" :prepend-icon="TShoppingList.icon" append-icon="fa-solid fa-caret-down">
|
||||||
|
<template v-if="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list != null">
|
||||||
|
{{useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list.name}}
|
||||||
|
</template>
|
||||||
|
<template v-else>{{ $t('ShoppingList') }}</template>
|
||||||
|
|
||||||
|
<v-menu activator="parent">
|
||||||
|
<v-list density="compact">
|
||||||
|
<v-list-item @click="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list = null">
|
||||||
|
{{$t('All')}}
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-for="s in shoppingLists" :key="s.id" @click="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list = s">
|
||||||
|
{{ s.name }}
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item prepend-icon="$create" :to="{name: 'ModelEditPage', params: {model: 'ShoppingList'}}">
|
||||||
|
{{$t('Create')}}
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-chip>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
@@ -270,7 +292,7 @@
|
|||||||
|
|
||||||
import {computed, onMounted, ref} from "vue";
|
import {computed, onMounted, ref} from "vue";
|
||||||
import {useShoppingStore} from "@/stores/ShoppingStore";
|
import {useShoppingStore} from "@/stores/ShoppingStore";
|
||||||
import {ApiApi, Recipe, ResponseError, ShoppingListEntry, ShoppingListRecipe, Supermarket} from "@/openapi";
|
import {ApiApi, Recipe, ResponseError, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Supermarket} from "@/openapi";
|
||||||
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||||
import ShoppingLineItem from "@/components/display/ShoppingLineItem.vue";
|
import ShoppingLineItem from "@/components/display/ShoppingLineItem.vue";
|
||||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||||
@@ -287,12 +309,13 @@ import {onBeforeRouteLeave} from "vue-router";
|
|||||||
import {isShoppingCategoryVisible} from "@/utils/logic_utils.ts";
|
import {isShoppingCategoryVisible} from "@/utils/logic_utils.ts";
|
||||||
import ShoppingExportDialog from "@/components/dialogs/ShoppingExportDialog.vue";
|
import ShoppingExportDialog from "@/components/dialogs/ShoppingExportDialog.vue";
|
||||||
import AddToShoppingDialog from "@/components/dialogs/AddToShoppingDialog.vue";
|
import AddToShoppingDialog from "@/components/dialogs/AddToShoppingDialog.vue";
|
||||||
import {TSupermarket} from "@/types/Models.ts";
|
import {TShoppingList, TSupermarket} from "@/types/Models.ts";
|
||||||
|
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
|
|
||||||
const currentTab = ref("shopping")
|
const currentTab = ref("shopping")
|
||||||
const supermarkets = ref([] as Supermarket[])
|
const supermarkets = ref([] as Supermarket[])
|
||||||
|
const shoppingLists = ref([] as ShoppingList[])
|
||||||
const manualAddRecipe = ref<undefined | Recipe>(undefined)
|
const manualAddRecipe = ref<undefined | Recipe>(undefined)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -327,6 +350,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadSupermarkets()
|
loadSupermarkets()
|
||||||
|
loadShoppingLists()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -401,6 +425,20 @@ function loadSupermarkets() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load a list of supermarkets
|
||||||
|
*/
|
||||||
|
function loadShoppingLists() {
|
||||||
|
let api = new ApiApi()
|
||||||
|
|
||||||
|
api.apiShoppingListList().then(r => {
|
||||||
|
shoppingLists.value = r.results
|
||||||
|
// TODO either recursive or add a "favorite" attribute to supermarkets for them to display at all
|
||||||
|
}).catch(err => {
|
||||||
|
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"AiModelHelp": "",
|
"AiModelHelp": "",
|
||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
|
"All": "",
|
||||||
"App": "",
|
"App": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
"Are_You_Sure": "",
|
"Are_You_Sure": "",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"AiModelHelp": "",
|
"AiModelHelp": "",
|
||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
|
"All": "",
|
||||||
"App": "Приложение",
|
"App": "Приложение",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
"Are_You_Sure": "Сигурен ли си?",
|
"Are_You_Sure": "Сигурен ли си?",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Alineació",
|
"Alignment": "Alineació",
|
||||||
|
"All": "",
|
||||||
"Amount": "Quantitat",
|
"Amount": "Quantitat",
|
||||||
"App": "Aplicació",
|
"App": "Aplicació",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Zarovnání",
|
"Alignment": "Zarovnání",
|
||||||
|
"All": "",
|
||||||
"Amount": "Množství",
|
"Amount": "Množství",
|
||||||
"App": "Aplikace",
|
"App": "Aplikace",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Justering",
|
"Alignment": "Justering",
|
||||||
|
"All": "",
|
||||||
"Amount": "Mængde",
|
"Amount": "Mængde",
|
||||||
"App": "App",
|
"App": "App",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
"AiProvider": "AI Anbieter",
|
"AiProvider": "AI Anbieter",
|
||||||
"AiProviderHelp": "Je nach Präferenz können verschiedene AI Anbieter angelegt werden. Diese können auch Space übergreifend sein.",
|
"AiProviderHelp": "Je nach Präferenz können verschiedene AI Anbieter angelegt werden. Diese können auch Space übergreifend sein.",
|
||||||
"Alignment": "Ausrichtung",
|
"Alignment": "Ausrichtung",
|
||||||
|
"All": "Alle",
|
||||||
"AllRecipes": "Alle Rezepte",
|
"AllRecipes": "Alle Rezepte",
|
||||||
"Amount": "Menge",
|
"Amount": "Menge",
|
||||||
"App": "App",
|
"App": "App",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Ευθυγράμμιση",
|
"Alignment": "Ευθυγράμμιση",
|
||||||
|
"All": "",
|
||||||
"Amount": "Ποσότητα",
|
"Amount": "Ποσότητα",
|
||||||
"App": "Εφαρμογή",
|
"App": "Εφαρμογή",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"AiProvider": "AI Provider",
|
"AiProvider": "AI Provider",
|
||||||
"AiProviderHelp": "You can configure multiple AI providers according to your preferences. They can even be configured to work across multiple spaces.",
|
"AiProviderHelp": "You can configure multiple AI providers according to your preferences. They can even be configured to work across multiple spaces.",
|
||||||
"Alignment": "Alignment",
|
"Alignment": "Alignment",
|
||||||
|
"All": "All",
|
||||||
"AllRecipes": "All Recipes",
|
"AllRecipes": "All Recipes",
|
||||||
"Amount": "Amount",
|
"Amount": "Amount",
|
||||||
"App": "App",
|
"App": "App",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Alineación",
|
"Alignment": "Alineación",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Todas las recetas",
|
"AllRecipes": "Todas las recetas",
|
||||||
"Amount": "Cantidad",
|
"Amount": "Cantidad",
|
||||||
"App": "Aplicación",
|
"App": "Aplicación",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Tasaus",
|
"Alignment": "Tasaus",
|
||||||
|
"All": "",
|
||||||
"Amount": "Määrä",
|
"Amount": "Määrä",
|
||||||
"App": "Applikaatio",
|
"App": "Applikaatio",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Alignement",
|
"Alignment": "Alignement",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Toutes les recettes",
|
"AllRecipes": "Toutes les recettes",
|
||||||
"Amount": "Quantité",
|
"Amount": "Quantité",
|
||||||
"App": "Appli",
|
"App": "Appli",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "יישור",
|
"Alignment": "יישור",
|
||||||
|
"All": "",
|
||||||
"Amount": "כמות",
|
"Amount": "כמות",
|
||||||
"App": "אפליקציה",
|
"App": "אפליקציה",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Poravnanje",
|
"Alignment": "Poravnanje",
|
||||||
|
"All": "",
|
||||||
"Amount": "Količina",
|
"Amount": "Količina",
|
||||||
"App": "Aplikacija",
|
"App": "Aplikacija",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Igazítás",
|
"Alignment": "Igazítás",
|
||||||
|
"All": "",
|
||||||
"Amount": "Összeg",
|
"Amount": "Összeg",
|
||||||
"App": "Applikáció",
|
"App": "Applikáció",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"AiModelHelp": "",
|
"AiModelHelp": "",
|
||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
|
"All": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
"Automate": "Ավտոմատացնել",
|
"Automate": "Ավտոմատացնել",
|
||||||
"BatchDeleteConfirm": "",
|
"BatchDeleteConfirm": "",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"AiModelHelp": "",
|
"AiModelHelp": "",
|
||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
|
"All": "",
|
||||||
"App": "",
|
"App": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
"Are_You_Sure": "",
|
"Are_You_Sure": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "",
|
"Alignment": "",
|
||||||
|
"All": "",
|
||||||
"Amount": "",
|
"Amount": "",
|
||||||
"App": "",
|
"App": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "",
|
"Alignment": "",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "",
|
"AllRecipes": "",
|
||||||
"Amount": "",
|
"Amount": "",
|
||||||
"App": "",
|
"App": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "",
|
"Alignment": "",
|
||||||
|
"All": "",
|
||||||
"Amount": "Suma",
|
"Amount": "Suma",
|
||||||
"App": "",
|
"App": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "",
|
"Alignment": "",
|
||||||
|
"All": "",
|
||||||
"Amount": "",
|
"Amount": "",
|
||||||
"App": "",
|
"App": "",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Justering",
|
"Alignment": "Justering",
|
||||||
|
"All": "",
|
||||||
"Amount": "Mengde",
|
"Amount": "Mengde",
|
||||||
"App": "App",
|
"App": "App",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"AiProvider": "AI-provider",
|
"AiProvider": "AI-provider",
|
||||||
"AiProviderHelp": "Je kunt meerdere AI-providers configureren naar jouw voorkeuren. Ze kunnen zelfs werken in meerdere ruimtes.",
|
"AiProviderHelp": "Je kunt meerdere AI-providers configureren naar jouw voorkeuren. Ze kunnen zelfs werken in meerdere ruimtes.",
|
||||||
"Alignment": "Afstemming",
|
"Alignment": "Afstemming",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Alle recepten",
|
"AllRecipes": "Alle recepten",
|
||||||
"Amount": "Hoeveelheid",
|
"Amount": "Hoeveelheid",
|
||||||
"App": "App",
|
"App": "App",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Wyrównanie",
|
"Alignment": "Wyrównanie",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Wszystkie przepisy",
|
"AllRecipes": "Wszystkie przepisy",
|
||||||
"Amount": "Ilość",
|
"Amount": "Ilość",
|
||||||
"App": "Aplikacja",
|
"App": "Aplikacja",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"Added_on": "Adicionado a",
|
"Added_on": "Adicionado a",
|
||||||
"Advanced": "Avançado",
|
"Advanced": "Avançado",
|
||||||
"Alignment": "Alinhamento",
|
"Alignment": "Alinhamento",
|
||||||
|
"All": "",
|
||||||
"Amount": "Quantidade",
|
"Amount": "Quantidade",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
"Auto_Planner": "",
|
"Auto_Planner": "",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Alinhamento",
|
"Alignment": "Alinhamento",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Todas Receitas",
|
"AllRecipes": "Todas Receitas",
|
||||||
"Amount": "Quantidade",
|
"Amount": "Quantidade",
|
||||||
"App": "Aplicação",
|
"App": "Aplicação",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiModelHelp": "",
|
"AiModelHelp": "",
|
||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
|
"All": "",
|
||||||
"Amount": "Cantitate",
|
"Amount": "Cantitate",
|
||||||
"App": "Aplicație",
|
"App": "Aplicație",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Выравнивание",
|
"Alignment": "Выравнивание",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Все рецепты",
|
"AllRecipes": "Все рецепты",
|
||||||
"Amount": "Количество",
|
"Amount": "Количество",
|
||||||
"App": "Приложение",
|
"App": "Приложение",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"AiProvider": "Ponudnik umetne inteligence",
|
"AiProvider": "Ponudnik umetne inteligence",
|
||||||
"AiProviderHelp": "Več ponudnikov umetne inteligence lahko konfigurirate glede na svoje nastavitve. Konfigurirate jih lahko celo za delovanje v več prostorih.",
|
"AiProviderHelp": "Več ponudnikov umetne inteligence lahko konfigurirate glede na svoje nastavitve. Konfigurirate jih lahko celo za delovanje v več prostorih.",
|
||||||
"Alignment": "Poravnava",
|
"Alignment": "Poravnava",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Vsi recepti",
|
"AllRecipes": "Vsi recepti",
|
||||||
"Amount": "Količina",
|
"Amount": "Količina",
|
||||||
"App": "Aplikacija",
|
"App": "Aplikacija",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "Hizalama",
|
"Alignment": "Hizalama",
|
||||||
|
"All": "",
|
||||||
"Amount": "Miktar",
|
"Amount": "Miktar",
|
||||||
"App": "Uygulama",
|
"App": "Uygulama",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"AiProvider": "Постачальник ШІ",
|
"AiProvider": "Постачальник ШІ",
|
||||||
"AiProviderHelp": "Ви можете налаштувати декількох постачальників штучного інтелекту відповідно до своїх уподобань. Їх навіть можна налаштувати для роботи в декількох просторах.",
|
"AiProviderHelp": "Ви можете налаштувати декількох постачальників штучного інтелекту відповідно до своїх уподобань. Їх навіть можна налаштувати для роботи в декількох просторах.",
|
||||||
"Alignment": "Вирівнювання",
|
"Alignment": "Вирівнювання",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "Всі рецепти",
|
"AllRecipes": "Всі рецепти",
|
||||||
"Amount": "Кількість",
|
"Amount": "Кількість",
|
||||||
"App": "Додаток",
|
"App": "Додаток",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "校准",
|
"Alignment": "校准",
|
||||||
|
"All": "",
|
||||||
"Amount": "数量",
|
"Amount": "数量",
|
||||||
"App": "应用",
|
"App": "应用",
|
||||||
"Apply": "",
|
"Apply": "",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
"AiProvider": "",
|
"AiProvider": "",
|
||||||
"AiProviderHelp": "",
|
"AiProviderHelp": "",
|
||||||
"Alignment": "對齊",
|
"Alignment": "對齊",
|
||||||
|
"All": "",
|
||||||
"AllRecipes": "所有食譜",
|
"AllRecipes": "所有食譜",
|
||||||
"Amount": "數量",
|
"Amount": "數量",
|
||||||
"App": "應用程式",
|
"App": "應用程式",
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
* group by selected grouping key
|
* group by selected grouping key
|
||||||
*/
|
*/
|
||||||
const getEntriesByGroup = computed(() => {
|
const getEntriesByGroup = computed(() => {
|
||||||
|
console.log("--> getEntriesByGroup called")
|
||||||
stats.value = {
|
stats.value = {
|
||||||
countChecked: 0,
|
countChecked: 0,
|
||||||
countUnchecked: 0,
|
countUnchecked: 0,
|
||||||
@@ -221,13 +222,16 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
|||||||
*/
|
*/
|
||||||
function recLoadShoppingListEntries(requestParameters: ApiShoppingListEntryListRequest) {
|
function recLoadShoppingListEntries(requestParameters: ApiShoppingListEntryListRequest) {
|
||||||
let api = new ApiApi()
|
let api = new ApiApi()
|
||||||
api.apiShoppingListEntryList(requestParameters).then((r) => {
|
return api.apiShoppingListEntryList(requestParameters).then((r) => {
|
||||||
r.results.forEach((e) => {
|
r.results.forEach((e) => {
|
||||||
entries.value.set(e.id!, e)
|
entries.value.set(e.id!, e)
|
||||||
})
|
})
|
||||||
if (r.next) {
|
|
||||||
requestParameters.page = requestParameters.page + 1
|
if (requestParameters.page == 1 && r.next) {
|
||||||
recLoadShoppingListEntries(requestParameters)
|
while (Math.ceil(r.count / requestParameters.pageSize) > requestParameters.page) {
|
||||||
|
requestParameters.page = requestParameters.page + 1
|
||||||
|
recLoadShoppingListEntries(requestParameters)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
currentlyUpdating.value = false
|
currentlyUpdating.value = false
|
||||||
initialized.value = true
|
initialized.value = true
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
|||||||
shopping_show_selected_supermarket_only: false,
|
shopping_show_selected_supermarket_only: false,
|
||||||
shopping_selected_grouping: ShoppingGroupingOptions.CATEGORY,
|
shopping_selected_grouping: ShoppingGroupingOptions.CATEGORY,
|
||||||
shopping_selected_supermarket: null,
|
shopping_selected_supermarket: null,
|
||||||
|
shopping_selected_shopping_list: null,
|
||||||
shopping_item_info_created_by: false,
|
shopping_item_info_created_by: false,
|
||||||
shopping_item_info_mealplan: true,
|
shopping_item_info_mealplan: true,
|
||||||
shopping_item_info_recipe: true,
|
shopping_item_info_recipe: true,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Supermarket} from "@/openapi";
|
import {ShoppingList, Supermarket} from "@/openapi";
|
||||||
|
|
||||||
export type DeviceSettings = {
|
export type DeviceSettings = {
|
||||||
shopping_show_checked_entries: boolean
|
shopping_show_checked_entries: boolean
|
||||||
@@ -6,6 +6,7 @@ export type DeviceSettings = {
|
|||||||
shopping_show_selected_supermarket_only: boolean
|
shopping_show_selected_supermarket_only: boolean
|
||||||
shopping_selected_grouping: string
|
shopping_selected_grouping: string
|
||||||
shopping_selected_supermarket: Supermarket | null
|
shopping_selected_supermarket: Supermarket | null
|
||||||
|
shopping_selected_shopping_list: ShoppingList | null
|
||||||
shopping_item_info_created_by: boolean
|
shopping_item_info_created_by: boolean
|
||||||
shopping_item_info_mealplan: boolean
|
shopping_item_info_mealplan: boolean
|
||||||
shopping_item_info_recipe: boolean
|
shopping_item_info_recipe: boolean
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ export function isEntryVisible(entry: ShoppingListEntry, deviceSettings: DeviceS
|
|||||||
if (entry.checked && !deviceSettings.shopping_show_checked_entries) {
|
if (entry.checked && !deviceSettings.shopping_show_checked_entries) {
|
||||||
entryVisible = false
|
entryVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(deviceSettings.shopping_selected_shopping_list != null && entry.shoppingLists?.findIndex(sl => sl.id == deviceSettings.shopping_selected_shopping_list.id) == -1){
|
||||||
|
entryVisible = false
|
||||||
|
}
|
||||||
return entryVisible
|
return entryVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,16 +64,15 @@ export function isShoppingListFoodDelayed(slf: IShoppingListFood) {
|
|||||||
* @param category
|
* @param category
|
||||||
*/
|
*/
|
||||||
export function isShoppingCategoryVisible(category: IShoppingListCategory) {
|
export function isShoppingCategoryVisible(category: IShoppingListCategory) {
|
||||||
let entryCount = category.stats.countUnchecked
|
console.log('checking if category is visible')
|
||||||
|
let categoryVisible = false
|
||||||
|
category.foods.forEach(food => {
|
||||||
|
if(isShoppingListFoodVisible(food, useUserPreferenceStore().deviceSettings)){
|
||||||
|
categoryVisible = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (useUserPreferenceStore().deviceSettings.shopping_show_checked_entries) {
|
return categoryVisible
|
||||||
entryCount += category.stats.countChecked
|
|
||||||
}
|
|
||||||
if (useUserPreferenceStore().deviceSettings.shopping_show_delayed_entries) {
|
|
||||||
entryCount += category.stats.countUncheckedDelayed
|
|
||||||
}
|
|
||||||
|
|
||||||
return entryCount > 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------- SPACE RELATED ----------------------
|
// -------------- SPACE RELATED ----------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user