mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
shopping list improvements
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<v-dialog :fullscreen="mobile" v-model="showDialog" max-width="500px">
|
||||
<v-card>
|
||||
<v-closable-card-title :title="props.shoppingListFood.food.name" v-model="showDialog"></v-closable-card-title>
|
||||
<v-closable-card-title :title="shoppingListFood.food.name" v-model="showDialog"></v-closable-card-title>
|
||||
|
||||
<v-card-text class="pt-0 pr-4 pl-4">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<v-row>
|
||||
<v-col class="pr-0 pt-0">
|
||||
<v-btn height="80px" color="primary" density="compact" size="small"
|
||||
:to="{name: 'ModelEditPage', params: {model: 'Food', id: props.shoppingListFood?.food.id!}}" target="_blank" block stacked>
|
||||
:to="{name: 'ModelEditPage', params: {model: 'Food', id: shoppingListFood?.food.id!}}" target="_blank" block stacked>
|
||||
<i class="fa-solid fa-pencil fa-2x mb-2"></i>
|
||||
{{ $t('Edit_Food') }}
|
||||
</v-btn>
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<v-label class="mt-3">{{ $t('Entries') }}</v-label>
|
||||
<v-list density="compact">
|
||||
<template v-for="[i, e] in props.shoppingListFood.entries" :key="e.id">
|
||||
<template v-for="[i, e] in shoppingListFood.entries" :key="e.id">
|
||||
<v-list-item border class="mt-1" :class="{'cursor-pointer': !e.recipeMealplan}">
|
||||
<v-list-item-title>
|
||||
<b>
|
||||
@@ -106,17 +106,14 @@ import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
const {mobile} = useDisplay()
|
||||
|
||||
const showDialog = defineModel<Boolean>()
|
||||
|
||||
const props = defineProps({
|
||||
shoppingListFood: {type: {} as PropType<IShoppingListFood>, required: true},
|
||||
})
|
||||
const shoppingListFood = defineModel<IShoppingListFood>('shoppingListFood')
|
||||
|
||||
/**
|
||||
* returns a flat list of entries for the given shopping list food
|
||||
*/
|
||||
const entriesList = computed(() => {
|
||||
let list = [] as ShoppingListEntry[]
|
||||
props.shoppingListFood?.entries.forEach(e => {
|
||||
shoppingListFood.value.entries.forEach(e => {
|
||||
list.push(e)
|
||||
})
|
||||
return list
|
||||
@@ -126,15 +123,13 @@ const entriesList = computed(() => {
|
||||
* checks all entries associated with shopping line, if any is delayed return true else false
|
||||
*/
|
||||
const isShoppingLineDelayed = computed(() => {
|
||||
return isShoppingListFoodDelayed(props.shoppingListFood)
|
||||
return isShoppingListFoodDelayed(shoppingListFood.value)
|
||||
})
|
||||
|
||||
function categoryUpdate(category: SupermarketCategory) {
|
||||
const api = new ApiApi()
|
||||
// TODO updating prop is not good, make properly reactive
|
||||
let food = props.shoppingListFood.food
|
||||
food.supermarketCategory = category
|
||||
api.apiFoodUpdate({id: food.id, food: food}).then(r => {
|
||||
shoppingListFood.value.food.supermarketCategory = category
|
||||
api.apiFoodUpdate({id: shoppingListFood.value.food.id, food: shoppingListFood.value.food}).then(r => {
|
||||
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
<v-list density="compact">
|
||||
<v-list-item @click="useShoppingStore().undoChange()" prepend-icon="fa-solid fa-arrow-rotate-left">{{ $t('Undo') }}</v-list-item>
|
||||
<v-divider></v-divider>
|
||||
<v-list-item>
|
||||
<v-select hide-details :items="groupingOptionsItems" v-model="useUserPreferenceStore().deviceSettings.shopping_selected_grouping" :label="$t('GroupBy')">
|
||||
</v-select>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<model-select model="Supermarket"></model-select>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item>
|
||||
<v-switch color="primary" hide-details :label="$t('ShowDelayed')" v-model="useUserPreferenceStore().deviceSettings.shopping_show_delayed_entries"></v-switch>
|
||||
</v-list-item>
|
||||
@@ -87,13 +95,13 @@
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
|
||||
<shopping-line-item-dialog v-model="shoppingLineItemDialog" :shopping-list-food="shoppingLineItemDialogFood"></shopping-line-item-dialog>
|
||||
<shopping-line-item-dialog v-model="shoppingLineItemDialog" v-model:shopping-list-food="shoppingLineItemDialogFood"></shopping-line-item-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted, ref} from "vue";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {useShoppingStore} from "@/stores/ShoppingStore";
|
||||
import {ApiApi, Food, IngredientString, ShoppingListEntry, Unit} from "@/openapi";
|
||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
@@ -101,7 +109,10 @@ import ShoppingLineItem from "@/components/display/ShoppingLineItem.vue";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import ModelSelect from "@/components/inputs/ModelSelect.vue";
|
||||
import ShoppingLineItemDialog from "@/components/dialogs/ShoppingLineItemDialog.vue";
|
||||
import {IShoppingListFood} from "@/types/Shopping";
|
||||
import {IShoppingListFood, ShoppingGroupingOptions} from "@/types/Shopping";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const {t} = useI18n()
|
||||
|
||||
const currentTab = ref("shopping")
|
||||
|
||||
@@ -111,6 +122,17 @@ const ingredientInputIcon = ref('fa-solid fa-plus')
|
||||
const shoppingLineItemDialog = ref(false)
|
||||
const shoppingLineItemDialogFood = ref({} as IShoppingListFood)
|
||||
|
||||
/**
|
||||
* VSelect items for shopping list grouping options with localized names
|
||||
*/
|
||||
const groupingOptionsItems = computed(() => {
|
||||
let items = []
|
||||
Object.keys(ShoppingGroupingOptions).forEach(x => {
|
||||
items.push({'title': t(x), 'value': x})
|
||||
})
|
||||
return items
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
useShoppingStore().refreshFromAPI()
|
||||
})
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {onBeforeMount, onMounted, PropType, ref, useTemplateRef} from "vue"
|
||||
import {GenericModel, getGenericModelFromString} from "@/types/Models"
|
||||
import {EditorSupportedModels, GenericModel, getGenericModelFromString} from "@/types/Models"
|
||||
import Multiselect from '@vueform/multiselect'
|
||||
import {ErrorMessageType, MessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {useI18n} from "vue-i18n";
|
||||
@@ -48,7 +48,7 @@ const {t} = useI18n()
|
||||
const emit = defineEmits(['update:modelValue', 'create'])
|
||||
|
||||
const props = defineProps({
|
||||
model: {type: String, required: true},
|
||||
model: {type: String as PropType<EditorSupportedModels>, required: true},
|
||||
|
||||
id: {type: String, required: false, default: Math.floor(Math.random()*10000).toString()},
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from "@/types/Shopping";
|
||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import {isDelayed} from "@/utils/logic_utils";
|
||||
|
||||
const _STORE_ID = "shopping_store"
|
||||
const UNDEFINED_CATEGORY = 'shopping_undefined_category'
|
||||
@@ -73,7 +74,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
categoryStats.countChecked++
|
||||
} else {
|
||||
categoryStats.countUnchecked++
|
||||
if (entry.delayUntil != null) {
|
||||
if (isDelayed(entry)) {
|
||||
categoryStats.countUncheckedDelayed++
|
||||
}
|
||||
}
|
||||
@@ -428,7 +429,6 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
}
|
||||
entries.forEach(entry => {
|
||||
entry.delayUntil = (delay ? delayDate : new Date('1970-01-01'))
|
||||
console.log('DELAY: ', delay, entry.delayUntil, entry)
|
||||
updateObject(entry)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import {Food, ShoppingListEntry, Unit} from "@/openapi";
|
||||
* enum of different options a shopping list can be grouped by
|
||||
*/
|
||||
export enum ShoppingGroupingOptions {
|
||||
CATEGORY = 'CATEGORY',
|
||||
CREATED_BY = 'CREATED_BY',
|
||||
RECIPE = 'RECIPE',
|
||||
CATEGORY = 'Category',
|
||||
CREATED_BY = 'CreatedBy',
|
||||
RECIPE = 'Recipe',
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user