mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-10 00:28:22 -05:00
fixesa
This commit is contained in:
@@ -775,7 +775,7 @@ class SupermarketCategoryRelationSerializer(WritableNestedModelSerializer):
|
||||
fields = ('id', 'category', 'supermarket', 'order')
|
||||
|
||||
|
||||
class SupermarketSerializer(UniqueFieldsMixin, SpacedModelSerializer, OpenDataModelMixin):
|
||||
class SupermarketSerializer(UniqueFieldsMixin, SpacedModelSerializer, WritableNestedModelSerializer, OpenDataModelMixin):
|
||||
category_to_supermarket = SupermarketCategoryRelationSerializer(many=True, read_only=True)
|
||||
shopping_lists = ShoppingListSerializer(many=True, required=False)
|
||||
|
||||
@@ -1433,8 +1433,17 @@ class ShoppingListRecipeSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ('id', 'created_by',)
|
||||
|
||||
|
||||
class FoodShoppingSerializer(serializers.ModelSerializer):
|
||||
supermarket_category = SupermarketCategorySerializer(read_only=True)
|
||||
shopping_lists = ShoppingListSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Food
|
||||
fields = ('id', 'name', 'plural_name', 'supermarket_category', 'shopping_lists')
|
||||
|
||||
|
||||
class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
||||
food = FoodSimpleSerializer(allow_null=True)
|
||||
food = FoodShoppingSerializer(allow_null=True)
|
||||
unit = UnitSerializer(allow_null=True, required=False)
|
||||
shopping_lists = ShoppingListSerializer(many=True, required=False)
|
||||
list_recipe_data = ShoppingListRecipeSerializer(source='list_recipe', read_only=True)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<v-divider></v-divider>
|
||||
<v-list-item>
|
||||
<v-select hide-details :items="groupingOptionsItems" v-model="useUserPreferenceStore().deviceSettings.shopping_selected_grouping"
|
||||
@update:modelValue="useShoppingStore().updateEntriesStructure()" :label="$t('GroupBy')">
|
||||
:label="$t('GroupBy')">
|
||||
</v-select>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="useUserPreferenceStore().deviceSettings.shopping_selected_grouping == ShoppingGroupingOptions.CATEGORY">
|
||||
@@ -117,17 +117,26 @@
|
||||
</v-chip>
|
||||
|
||||
<v-chip label density="compact" variant="outlined" style="max-width: 50%;" :prepend-icon="TShoppingList.icon" append-icon="fa-solid fa-caret-down">
|
||||
<template v-if="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list.length > 0">
|
||||
{{ shoppingLists.filter(sl => useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list.includes(sl.id)).flatMap(sl => sl.name).join(', ') }}
|
||||
<template v-if="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list.filter(sl => sl != -1).length > 0">
|
||||
{{
|
||||
shoppingLists.filter(sl => useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list.includes(sl.id)).flatMap(sl => sl.name).join(', ')
|
||||
}}
|
||||
</template>
|
||||
<template v-else>{{ $t('ShoppingList') }}</template>
|
||||
|
||||
<v-menu activator="parent" :close-on-content-click="false">
|
||||
<v-list density="compact" v-model:selected="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list"
|
||||
@update:selected="useShoppingStore().updateEntriesStructure()" select-strategy="leaf">
|
||||
<v-list-item @click="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list = []; useShoppingStore().updateEntriesStructure()">
|
||||
<v-list density="compact" v-model:selected="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list" select-strategy="leaf">
|
||||
<v-list-item @click="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list = [] ">
|
||||
{{ $t('All') }}
|
||||
</v-list-item>
|
||||
<v-list-item :value="-1" @click="useUserPreferenceStore().deviceSettings.shopping_selected_shopping_list = [-1];">
|
||||
<template v-slot:prepend="{ isSelected, select }">
|
||||
<v-list-item-action start>
|
||||
<v-checkbox-btn :model-value="isSelected" @update:model-value="select"></v-checkbox-btn>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
{{ $t('None') }}
|
||||
</v-list-item>
|
||||
<v-list-item v-for="s in shoppingLists" :key="s.id" :value="s.id">
|
||||
<template v-slot:prepend="{ isSelected, select }">
|
||||
<v-list-item-action start>
|
||||
@@ -303,7 +312,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {computed, onMounted, ref, toRef} from "vue";
|
||||
import {computed, onMounted, ref, toRef, watch} from "vue";
|
||||
import {useShoppingStore} from "@/stores/ShoppingStore";
|
||||
import {ApiApi, Recipe, ResponseError, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Supermarket} from "@/openapi";
|
||||
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||
@@ -343,6 +352,10 @@ const groupingOptionsItems = computed(() => {
|
||||
return items
|
||||
})
|
||||
|
||||
watch(() => useUserPreferenceStore().deviceSettings, () => {
|
||||
useShoppingStore().updateEntriesStructure()
|
||||
}, {deep: true})
|
||||
|
||||
onMounted(() => {
|
||||
addEventListener("visibilitychange", (event) => {
|
||||
useShoppingStore().autoSyncHasFocus = (document.visibilityState === 'visible')
|
||||
|
||||
@@ -377,6 +377,7 @@
|
||||
"NoUnit": "Keine Einheit",
|
||||
"No_ID": "ID nicht gefunden und kann nicht gelöscht werden.",
|
||||
"No_Results": "Keine Ergebnisse",
|
||||
"None": "Keine",
|
||||
"NotFound": "Nicht gefunden",
|
||||
"NotFoundHelp": "Die gesuchte Seite konnte nicht gefunden werden.",
|
||||
"NotInShopping": "{food} befindet sich nicht auf Ihrer Einkaufsliste.",
|
||||
|
||||
@@ -375,6 +375,7 @@
|
||||
"NoUnit": "No Unit",
|
||||
"No_ID": "ID not found, cannot delete.",
|
||||
"No_Results": "No Results",
|
||||
"None": "None",
|
||||
"NotFound": "Not found",
|
||||
"NotFoundHelp": "The page or object you are looking for could not be found.",
|
||||
"NotInShopping": "{food} is not in your shopping list.",
|
||||
|
||||
@@ -31,6 +31,7 @@ models/FdcQueryFoods.ts
|
||||
models/Food.ts
|
||||
models/FoodBatchUpdate.ts
|
||||
models/FoodInheritField.ts
|
||||
models/FoodShopping.ts
|
||||
models/FoodShoppingUpdate.ts
|
||||
models/FoodSimple.ts
|
||||
models/GenericModelReference.ts
|
||||
|
||||
106
vue3/src/openapi/models/FoodShopping.ts
Normal file
106
vue3/src/openapi/models/FoodShopping.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Tandoor
|
||||
* Tandoor API Docs
|
||||
*
|
||||
* The version of the OpenAPI document: 0.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { mapValues } from '../runtime';
|
||||
import type { ShoppingList } from './ShoppingList';
|
||||
import {
|
||||
ShoppingListFromJSON,
|
||||
ShoppingListFromJSONTyped,
|
||||
ShoppingListToJSON,
|
||||
} from './ShoppingList';
|
||||
import type { SupermarketCategory } from './SupermarketCategory';
|
||||
import {
|
||||
SupermarketCategoryFromJSON,
|
||||
SupermarketCategoryFromJSONTyped,
|
||||
SupermarketCategoryToJSON,
|
||||
} from './SupermarketCategory';
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface FoodShopping
|
||||
*/
|
||||
export interface FoodShopping {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof FoodShopping
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof FoodShopping
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof FoodShopping
|
||||
*/
|
||||
pluralName?: string;
|
||||
/**
|
||||
*
|
||||
* @type {SupermarketCategory}
|
||||
* @memberof FoodShopping
|
||||
*/
|
||||
readonly supermarketCategory: SupermarketCategory;
|
||||
/**
|
||||
*
|
||||
* @type {ShoppingList}
|
||||
* @memberof FoodShopping
|
||||
*/
|
||||
readonly shoppingLists: ShoppingList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given object implements the FoodShopping interface.
|
||||
*/
|
||||
export function instanceOfFoodShopping(value: object): value is FoodShopping {
|
||||
if (!('name' in value) || value['name'] === undefined) return false;
|
||||
if (!('supermarketCategory' in value) || value['supermarketCategory'] === undefined) return false;
|
||||
if (!('shoppingLists' in value) || value['shoppingLists'] === undefined) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
export function FoodShoppingFromJSON(json: any): FoodShopping {
|
||||
return FoodShoppingFromJSONTyped(json, false);
|
||||
}
|
||||
|
||||
export function FoodShoppingFromJSONTyped(json: any, ignoreDiscriminator: boolean): FoodShopping {
|
||||
if (json == null) {
|
||||
return json;
|
||||
}
|
||||
return {
|
||||
|
||||
'id': json['id'] == null ? undefined : json['id'],
|
||||
'name': json['name'],
|
||||
'pluralName': json['plural_name'] == null ? undefined : json['plural_name'],
|
||||
'supermarketCategory': SupermarketCategoryFromJSON(json['supermarket_category']),
|
||||
'shoppingLists': ShoppingListFromJSON(json['shopping_lists']),
|
||||
};
|
||||
}
|
||||
|
||||
export function FoodShoppingToJSON(value?: Omit<FoodShopping, 'supermarketCategory'|'shoppingLists'> | null): any {
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
|
||||
'id': value['id'],
|
||||
'name': value['name'],
|
||||
'plural_name': value['pluralName'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,6 +19,12 @@ import {
|
||||
UserFromJSONTyped,
|
||||
UserToJSON,
|
||||
} from './User';
|
||||
import type { FoodShopping } from './FoodShopping';
|
||||
import {
|
||||
FoodShoppingFromJSON,
|
||||
FoodShoppingFromJSONTyped,
|
||||
FoodShoppingToJSON,
|
||||
} from './FoodShopping';
|
||||
import type { ShoppingList } from './ShoppingList';
|
||||
import {
|
||||
ShoppingListFromJSON,
|
||||
@@ -37,12 +43,6 @@ import {
|
||||
UnitFromJSONTyped,
|
||||
UnitToJSON,
|
||||
} from './Unit';
|
||||
import type { FoodSimple } from './FoodSimple';
|
||||
import {
|
||||
FoodSimpleFromJSON,
|
||||
FoodSimpleFromJSONTyped,
|
||||
FoodSimpleToJSON,
|
||||
} from './FoodSimple';
|
||||
|
||||
/**
|
||||
* Adds nested create feature
|
||||
@@ -70,10 +70,10 @@ export interface PatchedShoppingListEntry {
|
||||
shoppingLists?: Array<ShoppingList>;
|
||||
/**
|
||||
*
|
||||
* @type {FoodSimple}
|
||||
* @type {FoodShopping}
|
||||
* @memberof PatchedShoppingListEntry
|
||||
*/
|
||||
food?: FoodSimple;
|
||||
food?: FoodShopping;
|
||||
/**
|
||||
*
|
||||
* @type {Unit}
|
||||
@@ -168,7 +168,7 @@ export function PatchedShoppingListEntryFromJSONTyped(json: any, ignoreDiscrimin
|
||||
'id': json['id'] == null ? undefined : json['id'],
|
||||
'listRecipe': json['list_recipe'] == null ? undefined : json['list_recipe'],
|
||||
'shoppingLists': json['shopping_lists'] == null ? undefined : ((json['shopping_lists'] as Array<any>).map(ShoppingListFromJSON)),
|
||||
'food': json['food'] == null ? undefined : FoodSimpleFromJSON(json['food']),
|
||||
'food': json['food'] == null ? undefined : FoodShoppingFromJSON(json['food']),
|
||||
'unit': json['unit'] == null ? undefined : UnitFromJSON(json['unit']),
|
||||
'amount': json['amount'] == null ? undefined : json['amount'],
|
||||
'order': json['order'] == null ? undefined : json['order'],
|
||||
@@ -193,7 +193,7 @@ export function PatchedShoppingListEntryToJSON(value?: Omit<PatchedShoppingListE
|
||||
'id': value['id'],
|
||||
'list_recipe': value['listRecipe'],
|
||||
'shopping_lists': value['shoppingLists'] == null ? undefined : ((value['shoppingLists'] as Array<any>).map(ShoppingListToJSON)),
|
||||
'food': FoodSimpleToJSON(value['food']),
|
||||
'food': FoodShoppingToJSON(value['food']),
|
||||
'unit': UnitToJSON(value['unit']),
|
||||
'amount': value['amount'],
|
||||
'order': value['order'],
|
||||
|
||||
@@ -19,6 +19,12 @@ import {
|
||||
UserFromJSONTyped,
|
||||
UserToJSON,
|
||||
} from './User';
|
||||
import type { FoodShopping } from './FoodShopping';
|
||||
import {
|
||||
FoodShoppingFromJSON,
|
||||
FoodShoppingFromJSONTyped,
|
||||
FoodShoppingToJSON,
|
||||
} from './FoodShopping';
|
||||
import type { ShoppingList } from './ShoppingList';
|
||||
import {
|
||||
ShoppingListFromJSON,
|
||||
@@ -37,12 +43,6 @@ import {
|
||||
UnitFromJSONTyped,
|
||||
UnitToJSON,
|
||||
} from './Unit';
|
||||
import type { FoodSimple } from './FoodSimple';
|
||||
import {
|
||||
FoodSimpleFromJSON,
|
||||
FoodSimpleFromJSONTyped,
|
||||
FoodSimpleToJSON,
|
||||
} from './FoodSimple';
|
||||
|
||||
/**
|
||||
* Adds nested create feature
|
||||
@@ -70,10 +70,10 @@ export interface ShoppingListEntry {
|
||||
shoppingLists?: Array<ShoppingList>;
|
||||
/**
|
||||
*
|
||||
* @type {FoodSimple}
|
||||
* @type {FoodShopping}
|
||||
* @memberof ShoppingListEntry
|
||||
*/
|
||||
food: FoodSimple | null;
|
||||
food: FoodShopping | null;
|
||||
/**
|
||||
*
|
||||
* @type {Unit}
|
||||
@@ -174,7 +174,7 @@ export function ShoppingListEntryFromJSONTyped(json: any, ignoreDiscriminator: b
|
||||
'id': json['id'] == null ? undefined : json['id'],
|
||||
'listRecipe': json['list_recipe'] == null ? undefined : json['list_recipe'],
|
||||
'shoppingLists': json['shopping_lists'] == null ? undefined : ((json['shopping_lists'] as Array<any>).map(ShoppingListFromJSON)),
|
||||
'food': FoodSimpleFromJSON(json['food']),
|
||||
'food': FoodShoppingFromJSON(json['food']),
|
||||
'unit': json['unit'] == null ? undefined : UnitFromJSON(json['unit']),
|
||||
'amount': json['amount'],
|
||||
'order': json['order'] == null ? undefined : json['order'],
|
||||
@@ -199,7 +199,7 @@ export function ShoppingListEntryToJSON(value?: Omit<ShoppingListEntry, 'listRec
|
||||
'id': value['id'],
|
||||
'list_recipe': value['listRecipe'],
|
||||
'shopping_lists': value['shoppingLists'] == null ? undefined : ((value['shoppingLists'] as Array<any>).map(ShoppingListToJSON)),
|
||||
'food': FoodSimpleToJSON(value['food']),
|
||||
'food': FoodShoppingToJSON(value['food']),
|
||||
'unit': UnitToJSON(value['unit']),
|
||||
'amount': value['amount'],
|
||||
'order': value['order'],
|
||||
|
||||
@@ -29,6 +29,7 @@ export * from './FdcQueryFoods';
|
||||
export * from './Food';
|
||||
export * from './FoodBatchUpdate';
|
||||
export * from './FoodInheritField';
|
||||
export * from './FoodShopping';
|
||||
export * from './FoodShoppingUpdate';
|
||||
export * from './FoodSimple';
|
||||
export * from './GenericModelReference';
|
||||
|
||||
@@ -68,7 +68,6 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
// ordering
|
||||
let undefinedCategoryGroup = structure.categories.get(UNDEFINED_CATEGORY)
|
||||
if (undefinedCategoryGroup != null) {
|
||||
totalFoods.value += undefinedCategoryGroup.foods.size
|
||||
orderedStructure.push(undefinedCategoryGroup)
|
||||
structure.categories.delete(UNDEFINED_CATEGORY)
|
||||
}
|
||||
@@ -444,6 +443,8 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
Promise.allSettled(promises).finally(() => {
|
||||
entries.value = new Map([...entries.value, ...updatedEntries])
|
||||
syncQueueRunning.value = false
|
||||
//TODO proper function to splice/update structure as needed
|
||||
useShoppingStore().updateEntriesStructure()
|
||||
if (itemCheckSyncQueue.value.length > 0) {
|
||||
runSyncQueue(500)
|
||||
}
|
||||
|
||||
@@ -19,8 +19,11 @@ export function isEntryVisible(entry: ShoppingListEntry, deviceSettings: DeviceS
|
||||
entryVisible = false
|
||||
}
|
||||
|
||||
// if no list is selected show all entries
|
||||
// if -1 is selected show entries without shopping lists
|
||||
// otherwise check if at least one of the entries lists is selected
|
||||
if(deviceSettings.shopping_selected_shopping_list.length > 0){
|
||||
if(!deviceSettings.shopping_selected_shopping_list.some(sl => (entry.shoppingLists?.findIndex(eSl => eSl.id == sl) != -1))){
|
||||
if(!(deviceSettings.shopping_selected_shopping_list.includes(-1) && entry.shoppingLists?.length == 0) && !deviceSettings.shopping_selected_shopping_list.some(sl => (entry.shoppingLists?.findIndex(eSl => eSl.id == sl) != -1))){
|
||||
entryVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user