mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-03 05:11:31 -05:00
strange
This commit is contained in:
@@ -10,13 +10,13 @@
|
||||
|
||||
<v-row>
|
||||
<v-col class="pr-0">
|
||||
<v-btn height="80px" color="info" density="compact" size="small" block stacked>
|
||||
<v-btn height="80px" color="info" density="compact" size="small" block stacked @click="useShoppingStore().delayEntries(entriesList, !isDelayed, true); ">
|
||||
<i class="fa-solid fa-clock-rotate-left fa-2x mb-2"></i>
|
||||
{{ $t('Postpone') }}
|
||||
{{ $t('Postpone') }} {{isDelayed}}
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn height="80px" color="secondary" density="compact" size="small" block stacked>
|
||||
<v-btn height="80px" color="secondary" density="compact" size="small" block stacked @click="useShoppingStore().setFoodIgnoredState(entriesList,true, true); showDialog = false">
|
||||
<i class="fa-solid fa-eye-slash fa-2x mb-2"></i>
|
||||
{{ $t('Ignore_Shopping') }}
|
||||
</v-btn>
|
||||
@@ -24,7 +24,7 @@
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col class="pr-0 pt-0">
|
||||
<v-btn height="80px" color="primary" density="compact" size="small" block stacked>
|
||||
<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>
|
||||
<i class="fa-solid fa-pencil fa-2x mb-2"></i>
|
||||
{{ $t('Edit_Food') }}
|
||||
</v-btn>
|
||||
@@ -67,7 +67,7 @@
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<!-- TODO make properly reactive or delete from the food instance in this component as well-->
|
||||
<!-- TODO make properly reactive or delete from the food instance in this component as well | ADD functionality once reactive -->
|
||||
<model-edit-dialog model="ShoppingListEntry" :item="e" @delete="useShoppingStore().entries.delete(e.id!);" v-if="!e.recipeMealplan"></model-edit-dialog>
|
||||
</v-list-item>
|
||||
</template>
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {PropType} from "vue";
|
||||
import {compile, computed, PropType, watch} from "vue";
|
||||
import {ShoppingListEntry} from "@/openapi";
|
||||
import ModelSelect from "@/components/inputs/ModelSelect.vue";
|
||||
import {IShoppingList, IShoppingListFood} from "@/types/Shopping";
|
||||
@@ -96,6 +96,7 @@ import {DateTime} from "luxon";
|
||||
import {useDisplay} from "vuetify";
|
||||
import ModelEditDialog from "@/components/dialogs/ModelEditDialog.vue";
|
||||
import {useShoppingStore} from "@/stores/ShoppingStore";
|
||||
import ShoppingListEntryEditor from "@/components/model_editors/ShoppingListEntryEditor.vue";
|
||||
|
||||
const {mobile} = useDisplay()
|
||||
|
||||
@@ -105,6 +106,28 @@ const props = defineProps({
|
||||
shoppingListFood: {type: {} as PropType<IShoppingListFood>, required: true},
|
||||
})
|
||||
|
||||
watch(() => {props.shoppingListFood}, () => {
|
||||
console.log('PROP WATCH')
|
||||
})
|
||||
|
||||
const entriesList = computed(() => {
|
||||
let list = [] as ShoppingListEntry[]
|
||||
props.shoppingListFood?.entries.forEach(e => {
|
||||
list.push(e)
|
||||
})
|
||||
return list
|
||||
})
|
||||
|
||||
const isDelayed = computed(() => {
|
||||
|
||||
let isDelayed = false
|
||||
props.shoppingListFood.entries.forEach(e => {
|
||||
isDelayed = isDelayed || e.delayUntil != null
|
||||
})
|
||||
console.log('computing is delayed', isDelayed)
|
||||
return isDelayed
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -6,20 +6,15 @@
|
||||
<!-- <i class="swipe-icon fa-fw fas" :class="{'fa-check': !isChecked , 'fa-cart-plus': isChecked }"></i>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<template #prepend>
|
||||
<v-btn color="primary" v-if="isDelayed">
|
||||
<i class="fa-fw fas fa-hourglass-half"></i>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
|
||||
<div class="flex-grow-1 p-2">
|
||||
<div class="d-flex">
|
||||
<div class="d-flex flex-column pr-2">
|
||||
<span v-for="[i, a] in amounts" v-bind:key="a.key">
|
||||
|
||||
<span>
|
||||
<i class="fas fa-check" v-if="a.checked && !isChecked"></i>
|
||||
<i class="fas fa-hourglass-half" v-if="a.delayed && !a.checked"></i> <b>
|
||||
<i class="fas fa-check text-warning" v-if="a.checked && !isChecked"></i>
|
||||
<i class="fas fa-hourglass-half text-primary" v-if="a.delayed && !a.checked"></i> <b>
|
||||
{{ a.amount }}
|
||||
<span v-if="a.unit">{{ a.unit.name }}</span>
|
||||
</b>
|
||||
@@ -58,12 +53,13 @@ import {useShoppingStore} from "@/stores/ShoppingStore.js";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore.js";
|
||||
import {ApiApi, Food, ShoppingListEntry} from '@/openapi'
|
||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {ShoppingLineAmount} from "@/types/Shopping";
|
||||
import {IShoppingListFood, ShoppingLineAmount} from "@/types/Shopping";
|
||||
|
||||
const emit = defineEmits(['clicked'])
|
||||
|
||||
const props = defineProps({
|
||||
entries: {type: Array as PropType<Array<ShoppingListEntry>>, required: true},
|
||||
shoppingListFood: {type: {} as PropType<IShoppingListFood>, required: true},
|
||||
})
|
||||
|
||||
const itemContainerId = computed(() => {
|
||||
|
||||
@@ -1,7 +1,33 @@
|
||||
<template>
|
||||
<v-tabs v-model="currentTab" >
|
||||
<v-tabs v-model="currentTab">
|
||||
<v-tab value="shopping"><i class="fas fa-shopping-cart fa-fw"></i> <span class="d-none d-md-block ms-1">{{ $t('Shopping_list') }}</span></v-tab>
|
||||
<v-tab value="recipes"><i class="fas fa-book fa-fw"></i> <span class="d-none d-md-block ms-1">{{ $t('Recipes') }}</span></v-tab>
|
||||
|
||||
<v-menu :close-on-content-click="false">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn
|
||||
class="me-4 float-right"
|
||||
height="100%"
|
||||
rounded="0"
|
||||
variant="plain"
|
||||
v-bind="props"
|
||||
|
||||
>
|
||||
<i class="fa-solid fa-sliders"></i>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<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-switch color="primary" hide-details :label="$t('ShowDelayed')" v-model="useUserPreferenceStore().deviceSettings.shopping_show_delayed_entries"></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch color="primary" hide-details :label="$t('ShowRecentlyCompleted')" v-model="useUserPreferenceStore().deviceSettings.shopping_show_checked_entries"></v-switch>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-tabs>
|
||||
|
||||
<v-window v-model="currentTab">
|
||||
@@ -31,7 +57,8 @@
|
||||
<v-divider></v-divider>
|
||||
|
||||
<template v-for="[i, value] in category.foods" :key="value.food.id">
|
||||
<shopping-line-item :entries="Array.from(value.entries.values())" @clicked="args => {shoppingLineItemDialog = true; shoppingLineItemDialogFood = value;}"></shopping-line-item>
|
||||
<shopping-line-item :shopping-list-food="value" :entries="Array.from(value.entries.values())"
|
||||
@clicked="args => {shoppingLineItemDialog = true; shoppingLineItemDialogFood = value; console.log('SETTING ITEMS')}"></shopping-line-item>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
@@ -52,7 +79,7 @@
|
||||
<v-label>{{ $t('Recipes') }}</v-label>
|
||||
<v-list>
|
||||
<v-list-item v-for="r in useShoppingStore().getAssociatedRecipes()">
|
||||
{{r}}
|
||||
{{ r }}
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {acceptHMRUpdate, defineStore} from "pinia"
|
||||
import {ApiApi, ShoppingListEntry, Supermarket, SupermarketCategory} from "@/openapi";
|
||||
import {ApiApi, Food, ShoppingListEntry, Supermarket, SupermarketCategory} from "@/openapi";
|
||||
import {computed, ref} from "vue";
|
||||
import {
|
||||
IShoppingExportEntry,
|
||||
@@ -7,11 +7,12 @@ import {
|
||||
IShoppingListCategory,
|
||||
IShoppingListFood,
|
||||
IShoppingSyncQueueEntry,
|
||||
ShoppingGroupingOptions, ShoppingListStats,
|
||||
ShoppingGroupingOptions,
|
||||
ShoppingListStats,
|
||||
ShoppingOperationHistoryEntry,
|
||||
ShoppingOperationHistoryType
|
||||
} from "@/types/Shopping";
|
||||
import {ErrorMessageType, MessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
|
||||
const _STORE_ID = "shopping_store"
|
||||
@@ -72,7 +73,7 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
categoryStats.countChecked++
|
||||
} else {
|
||||
categoryStats.countUnchecked++
|
||||
if(entry.delayUntil != null) {
|
||||
if (entry.delayUntil != null) {
|
||||
categoryStats.countUncheckedDelayed++
|
||||
}
|
||||
}
|
||||
@@ -418,18 +419,48 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
* @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
|
||||
*/
|
||||
function delayEntries(entries: ShoppingListEntry[], delay: boolean, undo: boolean) {
|
||||
function setEntriesDelayedState(entries: ShoppingListEntry[], delay: boolean, undo: boolean) {
|
||||
let delay_hours = useUserPreferenceStore().userSettings.defaultDelay!
|
||||
let delayDate = new Date(Date.now() + delay_hours * (60 * 60 * 1000))
|
||||
|
||||
if (undo) {
|
||||
registerChange((delay ? 'DELAY' : 'UNDELAY'), entries)
|
||||
}
|
||||
entries.forEach(entry => {
|
||||
entry.delayUntil = (delay ? delayDate : null)
|
||||
console.log('DELAY: ', delay, entry.delayUntil, entry)
|
||||
updateObject(entry)
|
||||
})
|
||||
}
|
||||
|
||||
for (let i in entries) {
|
||||
entries[i].delayUntil = (delay ? delayDate : null)
|
||||
updateObject(entries[i])
|
||||
/**
|
||||
* ignore all foods of the given entries for shopping in the future and check associated entries from the list
|
||||
* @param ignored if the food should be ignored or not ignored (for undo)
|
||||
* @param {{}} entries set of entries associated with food to set checked
|
||||
* @param undo if the user should be able to undo the change or not
|
||||
*/
|
||||
function setFoodIgnoredState(entries: ShoppingListEntry[], ignored: boolean, undo: boolean) {
|
||||
const api = new ApiApi()
|
||||
if (undo) {
|
||||
registerChange((ignored ? 'IGNORE' : 'UNIGNORE'), entries)
|
||||
}
|
||||
|
||||
let foods = [] as Food[]
|
||||
|
||||
entries.forEach(e => {
|
||||
if (!foods.includes(e.food!)) {
|
||||
foods.push(e.food!)
|
||||
}
|
||||
})
|
||||
|
||||
setEntriesCheckedState(entries, ignored, false)
|
||||
|
||||
foods.forEach(food => {
|
||||
food.ignoreShopping = ignored
|
||||
api.apiFoodUpdate({food: food, id: food.id!}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,12 +513,14 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
if (type === 'CHECKED' || type === 'UNCHECKED') {
|
||||
setEntriesCheckedState(entries, (type === 'UNCHECKED'), false)
|
||||
} else if (type === 'DELAY' || type === 'UNDELAY') {
|
||||
delayEntries(entries, (type === 'UNDELAY'), false)
|
||||
setEntriesDelayedState(entries, (type === 'UNDELAY'), false)
|
||||
} else if (type === 'CREATED') {
|
||||
for (let i in entries) {
|
||||
let e = entries[i]
|
||||
deleteObject(e)
|
||||
}
|
||||
} else if (type === 'IGNORE' || type === 'UNIGNORE') {
|
||||
setFoodIgnoredState(entries, (type === 'UNIGNORE'), false)
|
||||
}
|
||||
} else {
|
||||
// can use localization in store
|
||||
@@ -509,7 +542,8 @@ export const useShoppingStore = defineStore(_STORE_ID, () => {
|
||||
updateObject,
|
||||
undoChange,
|
||||
setEntriesCheckedState,
|
||||
delayEntries,
|
||||
setFoodIgnoredState,
|
||||
delayEntries: setEntriesDelayedState,
|
||||
getAssociatedRecipes,
|
||||
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export type ShoppingListStats = {
|
||||
* DELAY: ShoppingListEntry was postponed/delayed
|
||||
* UNDELAY: ShoppingListEntry delay was removed
|
||||
*/
|
||||
export type ShoppingOperationHistoryType = 'CREATED' | 'CHECKED' | 'UNCHECKED' | 'DELAY' | 'UNDELAY'
|
||||
export type ShoppingOperationHistoryType = 'CREATED' | 'CHECKED' | 'UNCHECKED' | 'DELAY' | 'UNDELAY' | 'IGNORE' | 'UNIGNORE'
|
||||
|
||||
/**
|
||||
* history event consisting of a type and affected entries
|
||||
|
||||
Reference in New Issue
Block a user