mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
small fixes
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<v-window-item v-for="w in recipeWindows" class="pt-1 pb-1">
|
||||
<v-row dense>
|
||||
<v-col class="pr-0 pl-0" v-for="r in w" :key="r.id">
|
||||
<recipe-card :recipe="r" :show_description="true" :show_keywords="true" style="height: 20vh"></recipe-card>
|
||||
<recipe-card :recipe="r" :show_description="true" :show_keywords="true" ></recipe-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-window-item>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<template v-if="!props.loading">
|
||||
|
||||
<router-link :to="{name: 'view_recipe', params: {id: props.recipe.id}}">
|
||||
<recipe-image :style="{'height': props.height}" :recipe="props.recipe" rounded="lg" class="mr-3 ml-3">
|
||||
<recipe-image :style="{height: props.height}" :recipe="props.recipe" rounded="lg" class="mr-3 ml-3">
|
||||
|
||||
</recipe-image>
|
||||
</router-link>
|
||||
@@ -19,7 +19,7 @@
|
||||
<!-- <p class="text-disabled">{{ props.recipe.createdBy.displayName}}</p>-->
|
||||
<keywords-component variant="outlined" :keywords="props.recipe.keywords" :max-keywords="3">
|
||||
<template #prepend>
|
||||
<v-chip class="mb-1 me-1" size="x-small" label variant="outlined" color="info"
|
||||
<v-chip class="mb-1 me-1" size="x-small" label variant="outlined" color="info"
|
||||
v-if="!props.recipe.internal">
|
||||
{{ $t('External') }}
|
||||
</v-chip>
|
||||
|
||||
@@ -17,7 +17,7 @@ const props = defineProps({
|
||||
height: {type: String},
|
||||
width: {type: String},
|
||||
cover: {type: Boolean, default: true},
|
||||
rounded: {type: Boolean as PropType<Boolean|String>, default: false},
|
||||
rounded: {type: [Boolean, String], default: false},
|
||||
})
|
||||
|
||||
const image = computed(() => {
|
||||
|
||||
@@ -78,27 +78,19 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {computed, defineComponent, PropType, ref, watch} from 'vue'
|
||||
import {ApiApi, Ingredient, Recipe} from "@/openapi"
|
||||
import KeywordsBar from "@/components/display/KeywordsBar.vue"
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {Recipe} from "@/openapi"
|
||||
import NumberScalerDialog from "@/components/inputs/NumberScalerDialog.vue"
|
||||
import IngredientsTable from "@/components/display/IngredientsTable.vue";
|
||||
import StepsOverview from "@/components/display/StepsOverview.vue";
|
||||
import Step from "@/components/display/Step.vue";
|
||||
import RecipeActivity from "@/components/display/RecipeActivity.vue";
|
||||
import RecipeContextMenu from "@/components/inputs/RecipeContextMenu.vue";
|
||||
import KeywordsComponent from "@/components/display/KeywordsBar.vue";
|
||||
import RecipeImage from "@/components/display/RecipeImage.vue";
|
||||
import PdfViewer from "../../../../vue/src/components/PdfViewer.vue";
|
||||
import ImageViewer from "../../../../vue/src/components/ImageViewer.vue";
|
||||
import ExternalRecipeViewer from "@/components/display/ExternalRecipeViewer.vue";
|
||||
|
||||
const recipe = defineModel<Recipe>({required: true})
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
})
|
||||
|
||||
const servings = ref(1)
|
||||
const showFullRecipeName = ref(false)
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import {acceptHMRUpdate, defineStore} from 'pinia'
|
||||
import {useStorage} from "@vueuse/core";
|
||||
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
|
||||
import {ApiApi, ServerSettings, Space, Supermarket, UserPreference} from "@/openapi";
|
||||
import {ApiApi, ServerSettings, Space, Supermarket, UserPreference, UserSpace} from "@/openapi";
|
||||
import {ShoppingGroupingOptions} from "@/types/Shopping";
|
||||
import {computed, ComputedRef} from "vue";
|
||||
|
||||
const DEVICE_SETTINGS_KEY = 'TANDOOR_DEVICE_SETTINGS'
|
||||
const USER_PREFERENCE_KEY = 'TANDOOR_USER_PREFERENCE'
|
||||
const SERVER_SETTINGS_KEY = 'TANDOOR_SERVER_SETTINGS'
|
||||
const ACTIVE_SPACE_KEY = 'TANDOOR_ACTIVE_SPACE'
|
||||
const USER_SPACES_KEY = 'TANDOOR_USER_SPACES'
|
||||
|
||||
class DeviceSettings {
|
||||
shopping_show_checked_entries = false
|
||||
shopping_show_delayed_entries = false
|
||||
shopping_show_selected_supermarket_only = false
|
||||
shopping_selected_grouping = ShoppingGroupingOptions.CATEGORY
|
||||
shopping_selected_supermarket: Supermarket|null = null
|
||||
shopping_selected_supermarket: Supermarket | null = null
|
||||
shopping_item_info_created_by = false
|
||||
shopping_item_info_mealplan = true
|
||||
shopping_item_info_recipe = true
|
||||
@@ -46,6 +48,24 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
* database user settings, cache in local storage in case application is started offline
|
||||
*/
|
||||
let activeSpace = useStorage(ACTIVE_SPACE_KEY, {} as Space)
|
||||
/**
|
||||
* list of spaces the user has access to and the relevant permissions, cache in local storage in case application is started offline
|
||||
*/
|
||||
let userSpaces = useStorage(USER_SPACES_KEY, [] as UserSpace[])
|
||||
|
||||
|
||||
/**
|
||||
* holds the active user space if there is one or null if not
|
||||
*/
|
||||
let activeUserSpace: ComputedRef<null | UserSpace> = computed(() => {
|
||||
let userSpace: null | UserSpace = null
|
||||
userSpaces.value.forEach(us => {
|
||||
if (us.space == activeSpace.value.id) {
|
||||
userSpace = us
|
||||
}
|
||||
})
|
||||
return userSpace
|
||||
})
|
||||
|
||||
/**
|
||||
* retrieve user settings from DB
|
||||
@@ -102,6 +122,18 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* load user spaces
|
||||
*/
|
||||
function loadUserSpaces() {
|
||||
let api = new ApiApi()
|
||||
api.apiUserSpaceList().then(r => {
|
||||
userSpaces.value = r.results
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* switch to the given space
|
||||
*/
|
||||
@@ -119,18 +151,29 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
/**
|
||||
* resets all device settings to their default value
|
||||
*/
|
||||
function resetDeviceSettings(){
|
||||
function resetDeviceSettings() {
|
||||
deviceSettings.value = new DeviceSettings()
|
||||
}
|
||||
|
||||
// always load user settings on first initialization of store
|
||||
// always load settings on first initialization of store
|
||||
loadUserSettings()
|
||||
// always load server settings on first initialization of store
|
||||
loadServerSettings()
|
||||
// always load active space on first initialization of store
|
||||
loadActiveSpace()
|
||||
loadUserSpaces()
|
||||
|
||||
return {deviceSettings, userSettings, serverSettings, activeSpace, loadUserSettings, loadServerSettings, updateUserSettings, switchSpace, resetDeviceSettings}
|
||||
return {
|
||||
deviceSettings,
|
||||
userSettings,
|
||||
serverSettings,
|
||||
activeSpace,
|
||||
userSpaces,
|
||||
activeUserSpace,
|
||||
loadUserSettings,
|
||||
loadServerSettings,
|
||||
updateUserSettings,
|
||||
switchSpace,
|
||||
resetDeviceSettings
|
||||
}
|
||||
})
|
||||
|
||||
// enable hot reload for store
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {ShoppingListEntry} from "@/openapi";
|
||||
import {ShoppingListEntry, Space} from "@/openapi";
|
||||
import {IShoppingListFood} from "@/types/Shopping";
|
||||
|
||||
/**
|
||||
* determine if a shopping list entry is delayed
|
||||
* @param entry
|
||||
*/
|
||||
export function isDelayed(entry: ShoppingListEntry){
|
||||
export function isDelayed(entry: ShoppingListEntry) {
|
||||
// this function is needed because the openapi typescript fetch client always replaces null with undefined, so delayUntil cant be
|
||||
// set back to null once it has been delayed once. This will hopefully be fixed at some point, until then un-delaying will set the date to 1997-1-1 00:00
|
||||
return entry.delayUntil != null && entry.delayUntil > new Date()
|
||||
@@ -14,10 +14,42 @@ export function isDelayed(entry: ShoppingListEntry){
|
||||
/**
|
||||
* determine if any entry in a given IShoppingListFood is delayed, if so return true
|
||||
*/
|
||||
export function isShoppingListFoodDelayed(slf: IShoppingListFood){
|
||||
export function isShoppingListFoodDelayed(slf: IShoppingListFood) {
|
||||
let hasDelayedEntry = false
|
||||
slf.entries.forEach(sle => {
|
||||
hasDelayedEntry = hasDelayedEntry || isDelayed(sle)
|
||||
})
|
||||
return hasDelayedEntry
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the given space is above any of the configured limits
|
||||
* @param space space to check limit for
|
||||
*/
|
||||
export function isSpaceAtLimit(space: Space) {
|
||||
return isSpaceAtUserLimit(space) || isSpaceAtRecipeLimit(space) || isSpaceAtStorageLimit(space)
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the given space is above the user limit
|
||||
* @param space space to check limit for
|
||||
*/
|
||||
export function isSpaceAtUserLimit(space: Space) {
|
||||
return space.maxUsers > space.userCount && space.maxUsers > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the given space is above the recipe limit
|
||||
* @param space space to check limit for
|
||||
*/
|
||||
export function isSpaceAtRecipeLimit(space: Space) {
|
||||
return space.maxRecipes > space.recipeCount && space.maxRecipes > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the given space is above the file storage limit
|
||||
* @param space space to check limit for
|
||||
*/
|
||||
export function isSpaceAtStorageLimit(space: Space) {
|
||||
return space.maxFileStorageMb > space.fileSizeMb && space.maxFileStorageMb > 0
|
||||
}
|
||||
Reference in New Issue
Block a user