mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
meal plan and recipe editor improvements
This commit is contained in:
59
vue3/src/components/display/ClosableHelpAlert.vue
Normal file
59
vue3/src/components/display/ClosableHelpAlert.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<v-alert :title="props.title" closable @click:close="closeAlert()" v-if="showAlert">
|
||||
<template #prepend>
|
||||
<v-icon icon="$help"></v-icon>
|
||||
</template>
|
||||
<p>
|
||||
{{ props.text}}
|
||||
<v-btn color="success" class="float-right" v-if="props.actionText != ''" @click="emit('click')">{{ actionText}}</v-btn>
|
||||
</p>
|
||||
</v-alert>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
import {MessageType, useMessageStore} from "@/stores/MessageStore";
|
||||
import {computed} from "vue";
|
||||
|
||||
// emit click if action is clicked, actual effect must come from parent component
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
const props = defineProps({
|
||||
title: {type: String, required: false,},
|
||||
text: {type: String, required: true},
|
||||
|
||||
// show an action button if any text is given and emit click event if button is pressed
|
||||
actionText: {type: String, required: false,},
|
||||
})
|
||||
|
||||
/**
|
||||
* somewhat unique hash of the given text to save which alerts have already been closed
|
||||
*/
|
||||
const alertHash = computed(() => {
|
||||
return props.text.split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0).toString()
|
||||
})
|
||||
|
||||
/**
|
||||
* only show the alert if it hasn't been closed on that device before
|
||||
*/
|
||||
const showAlert = computed(() => {
|
||||
return !useUserPreferenceStore().deviceSettings.general_closedHelpAlerts.includes(alertHash.value)
|
||||
})
|
||||
|
||||
/**
|
||||
* called when alert is closed to save this alert into the list of closed alerts
|
||||
*/
|
||||
function closeAlert() {
|
||||
if (!useUserPreferenceStore().deviceSettings.general_closedHelpAlerts.includes(alertHash.value)) {
|
||||
useUserPreferenceStore().deviceSettings.general_closedHelpAlerts.push(alertHash.value)
|
||||
} else {
|
||||
useMessageStore().addMessage(MessageType.ERROR, 'Trying to close already closed alert', 0, props.text)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
22
vue3/src/components/display/IngredientString.vue
Normal file
22
vue3/src/components/display/IngredientString.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<span v-if="ingredient.amount && !Number.isNaN(ingredient.amount)">{{$n(ingredient.amount)}}</span>
|
||||
<span class="ms-1" v-if="ingredient.unit">{{ ingredient.unit.name}}</span>
|
||||
<span class="ms-1" v-if="ingredient.food">{{ ingredient.food.name}}</span>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {Ingredient} from "@/openapi";
|
||||
import {PropType} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
ingredient: {type: {} as PropType<Ingredient>, required: true}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,34 +1,38 @@
|
||||
<template>
|
||||
<v-row class="h-100">
|
||||
<v-col>
|
||||
<!-- TODO add hint about CTRL key while drag/drop -->
|
||||
<calendar-view
|
||||
:show-date="calendarDate"
|
||||
:items="planItems"
|
||||
class="theme-default"
|
||||
:item-content-height="calendarItemHeight"
|
||||
:enable-drag-drop="true"
|
||||
@dropOnDate="dropCalendarItemOnDate"
|
||||
:display-period-uom="useUserPreferenceStore().deviceSettings.mealplan_displayPeriod"
|
||||
:display-period-count="useUserPreferenceStore().deviceSettings.mealplan_displayPeriodCount"
|
||||
:starting-day-of-week="useUserPreferenceStore().deviceSettings.mealplan_startingDayOfWeek"
|
||||
:display-week-numbers="useUserPreferenceStore().deviceSettings.mealplan_displayWeekNumbers"
|
||||
:current-period-label="$t('Today')"
|
||||
@click-date="(date : Date, calendarItems: [], windowEvent: any) => { newPlanDialogDefaultItem.fromDate = date; newPlanDialogDefaultItem.toDate = date; newPlanDialog = true }">
|
||||
<template #header="{ headerProps }">
|
||||
<calendar-view-header :header-props="headerProps" @input="(d:Date) => calendarDate = d"></calendar-view-header>
|
||||
</template>
|
||||
<template #item="{ value, weekStartDate, top }">
|
||||
<meal-plan-calendar-item
|
||||
:item-height="calendarItemHeight"
|
||||
:value="value"
|
||||
:item-top="top"
|
||||
@onDragStart="currentlyDraggedMealplan = value"
|
||||
@delete="(arg: MealPlan) => {useMealPlanStore().plans.delete(arg.id)}"
|
||||
:detailed-items="lgAndUp"
|
||||
></meal-plan-calendar-item>
|
||||
</template>
|
||||
</calendar-view>
|
||||
<v-col class="pb-0">
|
||||
<v-card class="h-100" :loading="useMealPlanStore().loading">
|
||||
<!-- TODO add hint about CTRL key while drag/drop -->
|
||||
<!-- TODO multi selection? date range selection ? -->
|
||||
<calendar-view
|
||||
:show-date="calendarDate"
|
||||
:items="planItems"
|
||||
class="theme-default"
|
||||
:item-content-height="calendarItemHeight"
|
||||
:enable-drag-drop="true"
|
||||
@dropOnDate="dropCalendarItemOnDate"
|
||||
:display-period-uom="useUserPreferenceStore().deviceSettings.mealplan_displayPeriod"
|
||||
:display-period-count="useUserPreferenceStore().deviceSettings.mealplan_displayPeriodCount"
|
||||
:starting-day-of-week="useUserPreferenceStore().deviceSettings.mealplan_startingDayOfWeek"
|
||||
:display-week-numbers="useUserPreferenceStore().deviceSettings.mealplan_displayWeekNumbers"
|
||||
:current-period-label="$t('Today')"
|
||||
@click-date="(date : Date, calendarItems: [], windowEvent: any) => { newPlanDialogDefaultItem.fromDate = date; newPlanDialogDefaultItem.toDate = date; newPlanDialog = true }">
|
||||
<template #header="{ headerProps }">
|
||||
<calendar-view-header :header-props="headerProps" @input="(d:Date) => calendarDate = d"></calendar-view-header>
|
||||
</template>
|
||||
<template #item="{ value, weekStartDate, top }">
|
||||
<meal-plan-calendar-item
|
||||
:item-height="calendarItemHeight"
|
||||
:value="value"
|
||||
:item-top="top"
|
||||
@onDragStart="currentlyDraggedMealplan = value"
|
||||
@delete="(arg: MealPlan) => {useMealPlanStore().plans.delete(arg.id)}"
|
||||
:detailed-items="lgAndUp"
|
||||
></meal-plan-calendar-item>
|
||||
</template>
|
||||
</calendar-view>
|
||||
</v-card>
|
||||
|
||||
|
||||
<model-edit-dialog model="MealPlan" v-model="newPlanDialog" :itemDefaults="newPlanDialogDefaultItem"
|
||||
@create="(arg: any) => useMealPlanStore().plans.set(arg.id, arg)"></model-edit-dialog>
|
||||
@@ -44,8 +48,8 @@ import "vue-simple-calendar/dist/css/default.css"
|
||||
|
||||
import MealPlanCalendarItem from "@/components/display/MealPlanCalendarItem.vue";
|
||||
import {IMealPlanCalendarItem, IMealPlanNormalizedCalendarItem} from "@/types/MealPlan";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {DateTime} from "luxon";
|
||||
import {computed, onMounted, ref, watch} from "vue";
|
||||
import {DateTime, Duration} from "luxon";
|
||||
import {useDisplay} from "vuetify";
|
||||
import {useMealPlanStore} from "@/stores/MealPlanStore";
|
||||
import ModelEditDialog from "@/components/dialogs/ModelEditDialog.vue";
|
||||
@@ -89,22 +93,47 @@ const calendarItemHeight = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
useMealPlanStore().refreshFromAPI() //TODO filter to visible date
|
||||
/**
|
||||
* watch calendar date and load entries accordingly
|
||||
*/
|
||||
watch(calendarDate, () => {
|
||||
let daysInPeriod = 7
|
||||
if (useUserPreferenceStore().deviceSettings.mealplan_displayPeriod == 'month') {
|
||||
daysInPeriod = 31
|
||||
} else if (useUserPreferenceStore().deviceSettings.mealplan_displayPeriod == 'year') {
|
||||
daysInPeriod = 365
|
||||
}
|
||||
|
||||
let days = useUserPreferenceStore().deviceSettings.mealplan_displayPeriodCount * daysInPeriod
|
||||
useMealPlanStore().refreshFromAPI(calendarDate.value, DateTime.now().plus({days: days}).toJSDate())
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// initial load for next 30 days
|
||||
useMealPlanStore().refreshFromAPI(calendarDate.value, DateTime.now().plus({days: 30}).toJSDate())
|
||||
})
|
||||
|
||||
/**
|
||||
* handle drop event for calendar items on fields
|
||||
* @param undefinedItem
|
||||
* @param targetDate
|
||||
* @param event
|
||||
*/
|
||||
function dropCalendarItemOnDate(undefinedItem: IMealPlanNormalizedCalendarItem, targetDate: Date, event: DragEvent) {
|
||||
//The item argument (first) is undefined because our custom calendar item cannot manipulate the calendar state so the item is unknown to the calendar (probably fixable by somehow binding state to the item)
|
||||
if (currentlyDraggedMealplan.value.originalItem.mealPlan.id != undefined) {
|
||||
let mealPlan = useMealPlanStore().plans.get(currentlyDraggedMealplan.value.originalItem.mealPlan.id)
|
||||
if (mealPlan != undefined) {
|
||||
let fromToDiff = DateTime.fromJSDate(mealPlan.toDate).diff(DateTime.fromJSDate(mealPlan.fromDate), 'days')
|
||||
let fromToDiff = {days: 1}
|
||||
if (mealPlan.toDate) {
|
||||
fromToDiff = DateTime.fromJSDate(mealPlan.toDate).diff(DateTime.fromJSDate(mealPlan.fromDate), 'days')
|
||||
}
|
||||
// create copy of item if control is pressed
|
||||
if (event.ctrlKey) {
|
||||
let new_entry = Object.assign({}, mealPlan)
|
||||
new_entry.fromDate = targetDate
|
||||
new_entry.toDate = DateTime.fromJSDate(targetDate).plus(fromToDiff).toJSDate()
|
||||
useMealPlanStore().createObject(new_entry)
|
||||
|
||||
} else {
|
||||
mealPlan.fromDate = targetDate
|
||||
mealPlan.toDate = DateTime.fromJSDate(targetDate).plus(fromToDiff).toJSDate()
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<v-input :hint="props.hint" persistent-hint :label="props.label" class="" >
|
||||
|
||||
<!-- TODO resolve-on-load false for now, race condition with model class, make prop once better solution is found -->
|
||||
|
||||
<Multiselect
|
||||
|
||||
:ref="`ref_${props.id}`"
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
<v-icon icon="fas fa-sliders-h"></v-icon>
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-item prepend-icon="fas fa-plus-circle" @click="showName = true" v-if="!showName && (step.name == null || step.name == '')">{{
|
||||
$t('Name')
|
||||
}}
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="fas fa-plus-circle" @click="showTime = true" v-if="!showTime && step.time == 0">{{ $t('Time') }}</v-list-item>
|
||||
<v-list-item prepend-icon="fas fa-plus-circle" @click="showFile = true" v-if="!showFile && step.file == null">{{ $t('File') }}</v-list-item>
|
||||
<v-list-item prepend-icon="fas fa-plus-circle" @click="showRecipe = true" v-if="!showRecipe && step.stepRecipe == null">{{ $t('Recipe') }}</v-list-item>
|
||||
|
||||
<v-list-item prepend-icon="$delete">{{ $t('Delete') }}</v-list-item>
|
||||
<v-list-item prepend-icon="$delete" @click="emit('delete')">{{ $t('Delete') }}</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
@@ -27,7 +31,8 @@
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="step.name"
|
||||
label="Step Name"
|
||||
:label="$t('Name')"
|
||||
v-if="showName || (step.name != null && step.name != '')"
|
||||
></v-text-field>
|
||||
|
||||
<v-row>
|
||||
@@ -46,20 +51,21 @@
|
||||
<v-col cols="12">
|
||||
<v-label>{{ $t('Ingredients') }}</v-label>
|
||||
|
||||
<vue-draggable v-model="step.ingredients" handle=".drag-handle" :on-sort="sortIngredients">
|
||||
<vue-draggable v-model="step.ingredients" handle=".drag-handle" :on-sort="sortIngredients" v-if="!mobile">
|
||||
<v-row v-for="(ingredient, index) in step.ingredients" dense>
|
||||
<v-col cols="2">
|
||||
<v-number-input :id="`id_input_amount_${step.id}_${index}`" :label="$t('Amount')" v-model="ingredient.amount" inset control-variant="stacked"
|
||||
hide-details
|
||||
:min="0"></v-number-input>
|
||||
</v-col>
|
||||
<v-col cols="3">
|
||||
<model-select model="Unit" v-model="ingredient.unit"></model-select>
|
||||
<model-select model="Unit" v-model="ingredient.unit" hide-details></model-select>
|
||||
</v-col>
|
||||
<v-col cols="3">
|
||||
<model-select model="Food" v-model="ingredient.food"></model-select>
|
||||
<model-select model="Food" v-model="ingredient.food" hide-details></model-select>
|
||||
</v-col>
|
||||
<v-col cols="3" @keydown.tab="event => handleIngredientNoteTab(event, index)">
|
||||
<v-text-field :label="$t('Note')" v-model="ingredient.note"></v-text-field>
|
||||
<v-text-field :label="$t('Note')" v-model="ingredient.note" hide-details></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="1">
|
||||
<v-btn variant="plain" icon>
|
||||
@@ -74,15 +80,36 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
</vue-draggable>
|
||||
<v-btn-group density="compact">
|
||||
|
||||
<v-list v-if="mobile">
|
||||
<vue-draggable v-model="step.ingredients" handle=".drag-handle" :on-sort="sortIngredients">
|
||||
<v-list-item v-for="(ingredient, index) in step.ingredients" border @click="editingIngredientIndex = index; dialogIngredientEditor = true">
|
||||
<ingredient-string :ingredient="ingredient"></ingredient-string>
|
||||
<template #append>
|
||||
<v-icon icon="$dragHandle" class="drag-handle"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
|
||||
</vue-draggable>
|
||||
</v-list>
|
||||
|
||||
<v-btn-group density="compact" class="mt-1">
|
||||
<v-btn color="success" @click="insertAndFocusIngredient()" prepend-icon="$add">{{ $t('Add') }}</v-btn>
|
||||
<v-btn color="warning" @click="dialogIngredientParser = true"><v-icon icon="$add"></v-icon> <v-icon icon="$add"></v-icon></v-btn>
|
||||
<v-btn color="warning" @click="dialogIngredientParser = true">
|
||||
<v-icon icon="$add"></v-icon>
|
||||
<v-icon icon="$add"></v-icon>
|
||||
</v-btn>
|
||||
</v-btn-group>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-label>{{ $t('Instructions') }}</v-label>
|
||||
<v-alert @click="dialogMarkdownEdit = true" class="mt-2 cursor-text" min-height="52px">
|
||||
{{ step.instruction }}
|
||||
<v-alert @click="dialogMarkdownEditor = true" class="mt-2 cursor-pointer" min-height="52px">
|
||||
<template v-if="step.instruction != '' && step.instruction != null">
|
||||
{{ step.instruction }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<i> {{ $t('InstructionsEditHelp') }} </i>
|
||||
</template>
|
||||
</v-alert>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -92,12 +119,15 @@
|
||||
</v-card>
|
||||
|
||||
<v-dialog
|
||||
v-model="dialogMarkdownEdit"
|
||||
v-model="dialogMarkdownEditor"
|
||||
:max-width="(mobile) ? '100vw': '75vw'"
|
||||
:fullscreen="mobile">
|
||||
<v-card>
|
||||
<v-closable-card-title :title="$t('Instructions')" v-model="dialogMarkdownEdit"></v-closable-card-title>
|
||||
<v-closable-card-title :title="$t('Instructions')" v-model="dialogMarkdownEditor"></v-closable-card-title>
|
||||
<step-markdown-editor class="h-100" v-model="step"></step-markdown-editor>
|
||||
<v-card-actions v-if="!mobile">
|
||||
<v-btn @click="dialogMarkdownEditor = false">{{ $t('Close') }}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
@@ -115,34 +145,59 @@
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog
|
||||
v-model="dialogIngredientEditor"
|
||||
:max-width="(mobile) ? '100vw': '75vw'"
|
||||
:fullscreen="mobile">
|
||||
<v-card>
|
||||
<v-closable-card-title :title="$t('Ingredient Editor')" v-model="dialogIngredientEditor"></v-closable-card-title>
|
||||
<v-card-text>
|
||||
<v-form>
|
||||
<v-number-input v-model="step.ingredients[editingIngredientIndex].amount" inset control-variant="stacked" :label="$t('Amount')"
|
||||
:min="0"></v-number-input>
|
||||
<model-select model="Unit" v-model="step.ingredients[editingIngredientIndex].unit" :label="$t('Unit')"></model-select>
|
||||
<model-select model="Food" v-model="step.ingredients[editingIngredientIndex].food" :label="$t('Food')"></model-select>
|
||||
<v-text-field :label="$t('Note')" v-model="step.ingredients[editingIngredientIndex].note" ></v-text-field>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn @click="dialogIngredientEditor = false">{{ $t('Close') }}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {nextTick, ref} from 'vue'
|
||||
import {ApiApi, Food, Ingredient, ParsedIngredient, Step} from "@/openapi";
|
||||
import {ApiApi, Ingredient, ParsedIngredient, Step} from "@/openapi";
|
||||
import StepMarkdownEditor from "@/components/inputs/StepMarkdownEditor.vue";
|
||||
import {VNumberInput} from 'vuetify/labs/VNumberInput' //TODO remove once component is out of labs
|
||||
import IngredientsTableRow from "@/components/display/IngredientsTableRow.vue";
|
||||
import {VNumberInput} from 'vuetify/labs/VNumberInput'
|
||||
import ModelSelect from "@/components/inputs/ModelSelect.vue";
|
||||
import {useDisplay} from "vuetify";
|
||||
import {VueDraggable} from "vue-draggable-plus";
|
||||
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
|
||||
import IngredientString from "@/components/display/IngredientString.vue";
|
||||
|
||||
const emit = defineEmits(['delete'])
|
||||
|
||||
const step = defineModel<Step>({required: true})
|
||||
|
||||
const props = defineProps({
|
||||
stepIndex: {type: Number, required: true},
|
||||
})
|
||||
|
||||
const {mobile} = useDisplay()
|
||||
|
||||
const showName = ref(false)
|
||||
const showTime = ref(false)
|
||||
const showRecipe = ref(false)
|
||||
const showFile = ref(false)
|
||||
|
||||
const dialogMarkdownEdit = ref(false)
|
||||
const dialogMarkdownEditor = ref(false)
|
||||
const dialogIngredientEditor = ref(false)
|
||||
const dialogIngredientParser = ref(false)
|
||||
|
||||
const editingIngredientIndex = ref({} as Ingredient)
|
||||
const ingredientTextInput = ref("")
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<closable-help-alert :text="$t('RecipeStepsHelp')" :action-text="$t('Steps')" @click="tab='steps'"></closable-help-alert>
|
||||
</v-form>
|
||||
|
||||
</v-tabs-window-item>
|
||||
@@ -64,13 +65,13 @@
|
||||
<v-form :disabled="loading || fileApiLoading">
|
||||
<v-row v-for="(s,i ) in editingObj.steps" :key="s.id">
|
||||
<v-col>
|
||||
<step-editor v-model="editingObj.steps[i]" :step-index="i"></step-editor>
|
||||
<step-editor v-model="editingObj.steps[i]" :step-index="i" @delete="deleteStepAtIndex(i)"></step-editor>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col class="text-center">
|
||||
<v-btn-group density="compact">
|
||||
<v-btn color="success" prepend-icon="fa-solid fa-plus">{{ $t('Add_Step') }}</v-btn>
|
||||
<v-btn color="success" prepend-icon="fa-solid fa-plus" @click="addStep()">{{ $t('Add_Step') }}</v-btn>
|
||||
<v-btn color="warning" @click="dialogStepManager = true">
|
||||
<v-icon icon="fa-solid fa-arrow-down-1-9"></v-icon>
|
||||
</v-btn>
|
||||
@@ -124,7 +125,7 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted, PropType, ref, shallowRef} from "vue";
|
||||
import {Recipe, Step} from "@/openapi";
|
||||
import {Ingredient, Recipe, Step} from "@/openapi";
|
||||
import ModelEditorBase from "@/components/model_editors/ModelEditorBase.vue";
|
||||
import {useModelEditorFunctions} from "@/composables/useModelEditorFunctions";
|
||||
import {useI18n} from "vue-i18n";
|
||||
@@ -134,6 +135,7 @@ import {VueDraggable} from "vue-draggable-plus";
|
||||
import PropertiesEditor from "@/components/inputs/PropertiesEditor.vue";
|
||||
import {useFileApi} from "@/composables/useFileApi";
|
||||
import {VFileUpload} from 'vuetify/labs/VFileUpload'
|
||||
import ClosableHelpAlert from "@/components/display/ClosableHelpAlert.vue";
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
@@ -183,6 +185,16 @@ function deleteImage() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new step to the recipe
|
||||
*/
|
||||
function addStep(){
|
||||
editingObj.value.steps.push({
|
||||
ingredients: [] as Ingredient[],
|
||||
time: 0,
|
||||
} as Step)
|
||||
}
|
||||
|
||||
/**
|
||||
* called by draggable in step manager dialog when steps are sorted
|
||||
*/
|
||||
@@ -192,6 +204,14 @@ function sortSteps() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a step at the given index of the steps array of the editingObject
|
||||
* @param index index to delete at
|
||||
*/
|
||||
function deleteStepAtIndex(index: number){
|
||||
editingObj.value.steps.splice(index, 1)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
<br/>
|
||||
|
||||
<p class="text-h6 mt-3">{{ $t('DeviceSettings') }}</p>
|
||||
<p class="text-disabled">{{$t('DeviceSettingsHelp')}}</p>
|
||||
<p class="text-disabled">{{ $t('DeviceSettingsHelp') }}</p>
|
||||
|
||||
<v-btn @click="useUserPreferenceStore().resetDeviceSettings()">{{$t('Reset')}}</v-btn>
|
||||
<v-btn @click="useUserPreferenceStore().resetDeviceSettings()" color="warning">{{ $t('Reset') }}</v-btn> <br/>
|
||||
<v-btn @click="useUserPreferenceStore().deviceSettings.general_closedHelpAlerts = []" color="warning" class="mt-1">{{ $t('ResetHelp') }}</v-btn>
|
||||
|
||||
</v-form>
|
||||
</template>
|
||||
@@ -51,9 +52,9 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
function save(){
|
||||
function save() {
|
||||
let api = new ApiApi()
|
||||
api.apiUserPartialUpdate({id: user.value.id!, patchedUser: user.value}).then(r => {
|
||||
api.apiUserPartialUpdate({id: user.value.id!, patchedUser: user.value}).then(r => {
|
||||
user.value = r
|
||||
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
|
||||
}).catch(err => {
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
"InheritFields_help": "",
|
||||
"InheritWarning": "",
|
||||
"Instructions": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "",
|
||||
@@ -246,6 +247,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "",
|
||||
"Recipe": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "",
|
||||
"Recipe_Image": "",
|
||||
"Recipes": "",
|
||||
@@ -255,6 +257,7 @@
|
||||
"RemoveFoodFromShopping": "",
|
||||
"Remove_nutrition_recipe": "",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
"InheritFields_help": "Стойностите на тези полета ще бъдат наследени от родител (Изключение: празни категории за пазаруване не се наследяват)",
|
||||
"InheritWarning": "{food} е настроен да наследява, промените може да не продължат.",
|
||||
"Instructions": "Инструкции",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Вътрешен",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Контрол",
|
||||
@@ -239,6 +240,7 @@
|
||||
"Ratings": "Рейтинги",
|
||||
"Recently_Viewed": "Наскоро разгледани",
|
||||
"Recipe": "Рецепта",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Книга с рецепти",
|
||||
"Recipe_Image": "Изображение на рецептата",
|
||||
"Recipes": "Рецепти",
|
||||
@@ -248,6 +250,7 @@
|
||||
"RemoveFoodFromShopping": "Премахнете {food} от списъка си за пазаруване",
|
||||
"Remove_nutrition_recipe": "Изтрийте хранителните стойности от рецептата",
|
||||
"Reset": "Нулиране",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Нулиране на търсенето",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
"Input": "",
|
||||
"Instruction_Replace": "Substituïu instrucció",
|
||||
"Instructions": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "",
|
||||
@@ -316,6 +317,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "Vistos recentment",
|
||||
"Recipe": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "",
|
||||
"Recipe_Image": "Imatge de la recepta",
|
||||
"Recipes": "",
|
||||
@@ -325,6 +327,7 @@
|
||||
"RemoveFoodFromShopping": "",
|
||||
"Remove_nutrition_recipe": "Esborreu nutrició de la recepta",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Reinicieu la cerca",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -191,6 +191,7 @@
|
||||
"InheritWarning": "{food} se propisuje, změny nemusí setrvat.",
|
||||
"Instruction_Replace": "Nahraď instrukce",
|
||||
"Instructions": "Instrukce",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interní",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Pozvánky",
|
||||
@@ -314,6 +315,7 @@
|
||||
"Ratings": "Hodnocení",
|
||||
"Recently_Viewed": "Naposledy prohlížené",
|
||||
"Recipe": "Recept",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Kuchařka",
|
||||
"Recipe_Image": "Obrázek k receptu",
|
||||
"Recipes": "Recepty",
|
||||
@@ -323,6 +325,7 @@
|
||||
"RemoveFoodFromShopping": "Odstranit {food} z nákupního seznamu",
|
||||
"Remove_nutrition_recipe": "Smazat nutriční hodnoty",
|
||||
"Reset": "Resetovat",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Zrušit filtry vyhledávání",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -179,6 +179,7 @@
|
||||
"InheritWarning": "{food} er sat til at nedarve, ændringer bliver måske ikke gemt.",
|
||||
"Instruction_Replace": "Erstat instruktion",
|
||||
"Instructions": "Instruktioner",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interne",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Invitationer",
|
||||
@@ -296,6 +297,7 @@
|
||||
"Ratings": "Bedømmelser",
|
||||
"Recently_Viewed": "Vist for nylig",
|
||||
"Recipe": "Opskrift",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Opskriftsbog",
|
||||
"Recipe_Image": "Opskriftsbillede",
|
||||
"Recipes": "Opskrifter",
|
||||
@@ -305,6 +307,7 @@
|
||||
"RemoveFoodFromShopping": "Fjern {food} fra indkøbsliste",
|
||||
"Remove_nutrition_recipe": "Fjern næringsindhold fra opskrift",
|
||||
"Reset": "Nulstil",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Nulstil søgning",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"Input": "Eingabe",
|
||||
"Instruction_Replace": "Anleitung ersetzen",
|
||||
"Instructions": "Anleitung",
|
||||
"InstructionsEditHelp": "Hier klicken um eine Anleitung hinzuzufügen.",
|
||||
"Internal": "Intern",
|
||||
"Invite_Link": "Einladungs Link",
|
||||
"Invites": "Einladungen",
|
||||
@@ -319,6 +320,7 @@
|
||||
"Ratings": "Bewertungen",
|
||||
"Recently_Viewed": "Kürzlich angesehen",
|
||||
"Recipe": "Rezept",
|
||||
"RecipeStepsHelp": "Zutaten, Anleitungen und mehr können unter dem Tab Schritte hinzugefügt werden.",
|
||||
"Recipe_Book": "Kochbuch",
|
||||
"Recipe_Image": "Rezeptbild",
|
||||
"Recipes": "Rezepte",
|
||||
@@ -328,6 +330,7 @@
|
||||
"RemoveFoodFromShopping": "{food} von der Einkaufsliste löschen",
|
||||
"Remove_nutrition_recipe": "Nährwerte aus Rezept löschen",
|
||||
"Reset": "Zurücksetzen",
|
||||
"ResetHelp": "Hilfe Zurücksetzen",
|
||||
"Reset_Search": "Suche zurücksetzen",
|
||||
"Reusable": "Wiederverwendbar",
|
||||
"Role": "Rolle",
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
"InheritWarning": "To φαγητό {food} έχει ρυθμιστεί να κληρονομεί, οι αλλαγές μπορεί να μην διατηρηθούν.",
|
||||
"Instruction_Replace": "Αλλαγή οδηγίας",
|
||||
"Instructions": "Οδηγίες",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Εσωτερική",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Προσκλήσεις",
|
||||
@@ -288,6 +289,7 @@
|
||||
"Ratings": "Βαθμολογίες",
|
||||
"Recently_Viewed": "Προβλήθηκαν πρόσφατα",
|
||||
"Recipe": "Συνταγή",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Βιβλίο συνταγών",
|
||||
"Recipe_Image": "Εικόνα συνταγής",
|
||||
"Recipes": "Συνταγές",
|
||||
@@ -297,6 +299,7 @@
|
||||
"RemoveFoodFromShopping": "Αφαίρεση του φαγητού {food} από τη λίστα αγορών σας",
|
||||
"Remove_nutrition_recipe": "Αφαίρεση διατροφικής αξίας από τη συνταγή",
|
||||
"Reset": "Επαναφορά",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Επαναφορά αναζήτησης",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Input": "Input",
|
||||
"Instruction_Replace": "Instruction Replace",
|
||||
"Instructions": "Instructions",
|
||||
"InstructionsEditHelp": "Click here to add instructions. ",
|
||||
"Internal": "Internal",
|
||||
"Invite_Link": "Invite Link",
|
||||
"Invites": "Invites",
|
||||
@@ -318,6 +319,7 @@
|
||||
"Ratings": "Ratings",
|
||||
"Recently_Viewed": "Recently Viewed",
|
||||
"Recipe": "Recipe",
|
||||
"RecipeStepsHelp": "Ingredients, Instructions and more can be edited in the tab Steps.",
|
||||
"Recipe_Book": "Recipe Book",
|
||||
"Recipe_Image": "Recipe Image",
|
||||
"Recipes": "Recipes",
|
||||
@@ -327,6 +329,7 @@
|
||||
"RemoveFoodFromShopping": "Remove {food} from your shopping list",
|
||||
"Remove_nutrition_recipe": "Delete nutrition from recipe",
|
||||
"Reset": "Reset",
|
||||
"ResetHelp": "Reset Help",
|
||||
"Reset_Search": "Reset Search",
|
||||
"Reusable": "Reusable",
|
||||
"Role": "Role",
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Input": "Entrada",
|
||||
"Instruction_Replace": "Reemplazar Instrucción",
|
||||
"Instructions": "Instrucciones",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interno",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Invitaciones",
|
||||
@@ -315,6 +316,7 @@
|
||||
"Ratings": "Calificaciones",
|
||||
"Recently_Viewed": "Visto recientemente",
|
||||
"Recipe": "Receta",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Libro de recetas",
|
||||
"Recipe_Image": "Imagen de la receta",
|
||||
"Recipes": "Recetas",
|
||||
@@ -324,6 +326,7 @@
|
||||
"RemoveFoodFromShopping": "Eliminar {food} de la lista de la compra",
|
||||
"Remove_nutrition_recipe": "Borrar nutrición de la canasta",
|
||||
"Reset": "Restablecer",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Resetear busqueda",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
"Information": "Tiedot",
|
||||
"Ingredients": "Ainesosat",
|
||||
"Instructions": "Ohjeet",
|
||||
"InstructionsEditHelp": "",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Ctrl",
|
||||
"Key_Shift": "Shift",
|
||||
@@ -176,12 +177,14 @@
|
||||
"Rating": "Luokitus",
|
||||
"Recently_Viewed": "Äskettäin katsotut",
|
||||
"Recipe": "Resepti",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Keittokirja",
|
||||
"Recipe_Image": "Reseptin Kuva",
|
||||
"Recipes": "Reseptit",
|
||||
"Recipes_per_page": "Reseptejä sivulla",
|
||||
"Remove": "",
|
||||
"Remove_nutrition_recipe": "Poista ravintoaine reseptistä",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Nollaa haku",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
"Input": "Entrée",
|
||||
"Instruction_Replace": "Instruction Remplacer",
|
||||
"Instructions": "Instructions",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interne",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Invitations",
|
||||
@@ -316,6 +317,7 @@
|
||||
"Ratings": "Notes",
|
||||
"Recently_Viewed": "Vu récemment",
|
||||
"Recipe": "Recette",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Livre de recettes",
|
||||
"Recipe_Image": "Image de la recette",
|
||||
"Recipes": "Recettes",
|
||||
@@ -325,6 +327,7 @@
|
||||
"RemoveFoodFromShopping": "Supprimer l’aliment {food} de votre liste de courses",
|
||||
"Remove_nutrition_recipe": "Supprimer les valeurs nutritionelles de la recette",
|
||||
"Reset": "Réinitialiser",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Réinitialiser la recherche",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Input": "קלט",
|
||||
"Instruction_Replace": "החלפת הוראות",
|
||||
"Instructions": "הוראות",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "פנימי",
|
||||
"Invite_Link": "",
|
||||
"Invites": "הזמנות",
|
||||
@@ -317,6 +318,7 @@
|
||||
"Ratings": "דירוג",
|
||||
"Recently_Viewed": "נצפו לאחרונה",
|
||||
"Recipe": "מתכון",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "ספר מתכון",
|
||||
"Recipe_Image": "תמונת מתכון",
|
||||
"Recipes": "מתכונים",
|
||||
@@ -326,6 +328,7 @@
|
||||
"RemoveFoodFromShopping": "הסר {מזון} מרשימת הקניות",
|
||||
"Remove_nutrition_recipe": "מחר ערכים תזונתיים מהמתכון",
|
||||
"Reset": "אפס",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "אפס חיפוש",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
"InheritWarning": "",
|
||||
"Instruction_Replace": "Elkészítési leírás cseréje",
|
||||
"Instructions": "Elkészítés",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Belső",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Meghívók",
|
||||
@@ -290,6 +291,7 @@
|
||||
"Ratings": "Értékelések",
|
||||
"Recently_Viewed": "Nemrég megtekintett",
|
||||
"Recipe": "Recept",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Szakácskönyv",
|
||||
"Recipe_Image": "Receptkép",
|
||||
"Recipes": "Receptek",
|
||||
@@ -299,6 +301,7 @@
|
||||
"RemoveFoodFromShopping": "{food} eltávolítása bevásárlólistáról",
|
||||
"Remove_nutrition_recipe": "Tápértékadatok törlése a receptből",
|
||||
"Reset": "Visszaállítás",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Keresés alaphelyzetbe állítása",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"Import_finished": "Ներմուծումն ավարտված է",
|
||||
"Information": "Տեղեկություն",
|
||||
"Ingredients": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Invite_Link": "",
|
||||
"Keywords": "",
|
||||
"Link": "",
|
||||
@@ -122,12 +123,14 @@
|
||||
"Rating": "",
|
||||
"Recently_Viewed": "Վերջերս դիտած",
|
||||
"Recipe": "Բաղադրատոմս",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Բաղադրատոմսերի գիրք",
|
||||
"Recipe_Image": "Բաղադրատոմսի նկար",
|
||||
"Recipes": "Բաղադրատոմսեր",
|
||||
"Recipes_per_page": "Բաղադրատոմս էջում",
|
||||
"Remove": "",
|
||||
"Remove_nutrition_recipe": "Հեռացնել բաղադրատոմսի սննդայնությունը",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Զրոյացնել որոնումը",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
"InheritFields_help": "",
|
||||
"InheritWarning": "",
|
||||
"Instructions": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "",
|
||||
@@ -266,6 +267,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "baru saja dilihat",
|
||||
"Recipe": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "",
|
||||
"Recipe_Image": "Gambar Resep",
|
||||
"Recipes": "Resep",
|
||||
@@ -275,6 +277,7 @@
|
||||
"RemoveFoodFromShopping": "",
|
||||
"Remove_nutrition_recipe": "Hapus nutrisi dari resep",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Setel Ulang Pencarian",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
"Input": "",
|
||||
"Instruction_Replace": "",
|
||||
"Instructions": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "",
|
||||
@@ -316,6 +317,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "",
|
||||
"Recipe": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "",
|
||||
"Recipe_Image": "",
|
||||
"Recipes": "",
|
||||
@@ -325,6 +327,7 @@
|
||||
"RemoveFoodFromShopping": "",
|
||||
"Remove_nutrition_recipe": "",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
"InheritWarning": "{food} è impostato per ereditare, i cambiamenti potrebbero non essere applicati.",
|
||||
"Instruction_Replace": "Sostituisci istruzioni",
|
||||
"Instructions": "Istruzioni",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interno",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Inviti",
|
||||
@@ -274,6 +275,7 @@
|
||||
"Ratings": "Valutazioni",
|
||||
"Recently_Viewed": "Visualizzato di recente",
|
||||
"Recipe": "Ricetta",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Libro di Ricette",
|
||||
"Recipe_Image": "Immagine ricetta",
|
||||
"Recipes": "Ricette",
|
||||
@@ -283,6 +285,7 @@
|
||||
"RemoveFoodFromShopping": "Rimuovi {food} dalla tua lista della spesa",
|
||||
"Remove_nutrition_recipe": "Elimina nutrienti dalla ricetta",
|
||||
"Reset": "Azzera",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Ripristina Ricerca",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
"InheritWarning": "",
|
||||
"Instruction_Replace": "",
|
||||
"Instructions": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "",
|
||||
@@ -294,6 +295,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "Neseniai Žiūrėta",
|
||||
"Recipe": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "",
|
||||
"Recipe_Image": "Recepto nuotrauka",
|
||||
"Recipes": "",
|
||||
@@ -303,6 +305,7 @@
|
||||
"RemoveFoodFromShopping": "",
|
||||
"Remove_nutrition_recipe": "Ištrinti mitybos informaciją iš recepto",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Iš naujo nustatyti paiešką",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -172,6 +172,7 @@
|
||||
"InheritWarning": "",
|
||||
"Instruction_Replace": "Erstatt instruksjoner",
|
||||
"Instructions": "Instruksjoner",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Invitasjoner",
|
||||
@@ -286,6 +287,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "Nylig vist",
|
||||
"Recipe": "Oppskrift",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Oppskriftsbok",
|
||||
"Recipe_Image": "Oppskriftsbilde",
|
||||
"Recipes": "Oppskrift",
|
||||
@@ -295,6 +297,7 @@
|
||||
"RemoveFoodFromShopping": "Fjern {food} fra handelisten din",
|
||||
"Remove_nutrition_recipe": "Fjern næringsinnhold fra oppskrift",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Nullstill søk",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
"InheritWarning": "{food} erft informatie, wijzigingen zijn mogelijk niet blijvend.",
|
||||
"Instruction_Replace": "Vervang instructie",
|
||||
"Instructions": "Instructies",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interne",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Uitnodigingen",
|
||||
@@ -290,6 +291,7 @@
|
||||
"Ratings": "Waardering",
|
||||
"Recently_Viewed": "Recent bekeken",
|
||||
"Recipe": "Recept",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Kookboek",
|
||||
"Recipe_Image": "Afbeelding Recept",
|
||||
"Recipes": "Recepten",
|
||||
@@ -299,6 +301,7 @@
|
||||
"RemoveFoodFromShopping": "Verwijder {food} van je boodschappenlijst",
|
||||
"Remove_nutrition_recipe": "Verwijder voedingswaarde van recept",
|
||||
"Reset": "Herstel",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Zoeken resetten",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"Input": "Wprowadź",
|
||||
"Instruction_Replace": "Zmień instrukcję",
|
||||
"Instructions": "Instrukcje",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Wewnętrzne",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Zaprasza",
|
||||
@@ -318,6 +319,7 @@
|
||||
"Ratings": "Oceny",
|
||||
"Recently_Viewed": "Ostatnio oglądane",
|
||||
"Recipe": "Przepis",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Książka z przepisami",
|
||||
"Recipe_Image": "Obrazek dla przepisu",
|
||||
"Recipes": "Przepisy",
|
||||
@@ -327,6 +329,7 @@
|
||||
"RemoveFoodFromShopping": "Usuń {food} z listy zakupów",
|
||||
"Remove_nutrition_recipe": "Usuń wartości odżywcze z przepisu",
|
||||
"Reset": "Resetowanie",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Resetuj wyszukiwanie",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
"InheritWarning": "{food} esta definida para herdar, alterações podem não persistir.",
|
||||
"Instruction_Replace": "Substituir Instrução",
|
||||
"Instructions": "Instruções",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interno",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Ctrl",
|
||||
@@ -236,6 +237,7 @@
|
||||
"Ratings": "Avaliações",
|
||||
"Recently_Viewed": "Vistos Recentemente",
|
||||
"Recipe": "Receita",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Livro de Receitas",
|
||||
"Recipe_Image": "Imagem da Receita",
|
||||
"Recipes": "Receitas",
|
||||
@@ -244,6 +246,7 @@
|
||||
"RemoveFoodFromShopping": "Remover {food} da sua lista de compras",
|
||||
"Remove_nutrition_recipe": "Remover valor nutricional da receita",
|
||||
"Reset": "Reiniciar",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Repor Pesquisa",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -187,6 +187,7 @@
|
||||
"Input": "Entrada",
|
||||
"Instruction_Replace": "Substituir Instrução",
|
||||
"Instructions": "Instruções",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Interno",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Convites",
|
||||
@@ -305,6 +306,7 @@
|
||||
"Ratings": "Classificações",
|
||||
"Recently_Viewed": "Visto recentemente",
|
||||
"Recipe": "Receita",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Livro de Receitas",
|
||||
"Recipe_Image": "Imagem da receita",
|
||||
"Recipes": "Receitas",
|
||||
@@ -314,6 +316,7 @@
|
||||
"RemoveFoodFromShopping": "Remover {food} da sua lista de compras",
|
||||
"Remove_nutrition_recipe": "Deletar dados nutricionais da receita",
|
||||
"Reset": "Reiniciar",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Resetar Busca",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
"InheritWarning": "{food} este setat să moștenească, este posibil ca modificările să nu persiste.",
|
||||
"Instruction_Replace": "Înlocuire instrucții",
|
||||
"Instructions": "Instrucțiuni",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Intern",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Invită",
|
||||
@@ -278,6 +279,7 @@
|
||||
"Ratings": "Evaluări",
|
||||
"Recently_Viewed": "Vizualizate recent",
|
||||
"Recipe": "Rețetă",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Carte de rețete",
|
||||
"Recipe_Image": "Imagine a rețetei",
|
||||
"Recipes": "Rețete",
|
||||
@@ -287,6 +289,7 @@
|
||||
"RemoveFoodFromShopping": "Șterge {food} din lista de cumpărături",
|
||||
"Remove_nutrition_recipe": "Ștergere a nutriției din rețetă",
|
||||
"Reset": "Resetare",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Resetarea căutării",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
"InheritFields": "Наследование значений полей",
|
||||
"InheritWarning": "{food} примет предыдущие настройки, изменения не будут приняты.",
|
||||
"Instructions": "Инструкции",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Внутренний",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Ctrl",
|
||||
@@ -221,6 +222,7 @@
|
||||
"Ratings": "Рейтинги",
|
||||
"Recently_Viewed": "Недавно просмотренные",
|
||||
"Recipe": "Рецепт",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Книга рецептов",
|
||||
"Recipe_Image": "Изображение рецепта",
|
||||
"Recipes": "Рецепты",
|
||||
@@ -229,6 +231,7 @@
|
||||
"RemoveFoodFromShopping": "Удалить {food} из вашего списка покупок",
|
||||
"Remove_nutrition_recipe": "Уберите питательные вещества из рецепта",
|
||||
"Reset": "Сбросить",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Очистить строку поиска",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
"InheritWarning": "{food} je nastavljena na dedovanje, spremembe morda ne bodo trajale.",
|
||||
"Instruction_Replace": "Zamenjaj Navodila",
|
||||
"Instructions": "Navodila",
|
||||
"InstructionsEditHelp": "",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Ctrl",
|
||||
"Key_Shift": "Shift",
|
||||
@@ -213,6 +214,7 @@
|
||||
"Rating": "Ocena",
|
||||
"Recently_Viewed": "Nazadnje videno",
|
||||
"Recipe": "Recept",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Knjiga receptov",
|
||||
"Recipe_Image": "Slika recepta",
|
||||
"Recipes": "Recepti",
|
||||
@@ -220,6 +222,7 @@
|
||||
"Remove": "",
|
||||
"RemoveFoodFromShopping": "Odstrani {food} iz nakupovalnega listka",
|
||||
"Remove_nutrition_recipe": "Receptu izbriši hranilno vrednost",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Ponastavi iskalnik",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"Input": "Inmatning",
|
||||
"Instruction_Replace": "Ersätt instruktion",
|
||||
"Instructions": "Instruktioner",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Intern",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Inbjudningar",
|
||||
@@ -318,6 +319,7 @@
|
||||
"Ratings": "Betyg",
|
||||
"Recently_Viewed": "Nyligen visade",
|
||||
"Recipe": "Recept",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Receptbok",
|
||||
"Recipe_Image": "Receptbild",
|
||||
"Recipes": "Recept",
|
||||
@@ -327,6 +329,7 @@
|
||||
"RemoveFoodFromShopping": "Ta bort {mat} från din inköpslista",
|
||||
"Remove_nutrition_recipe": "Ta bort näring från receptet",
|
||||
"Reset": "Återställ",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Rensa sök",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"Input": "Giriş",
|
||||
"Instruction_Replace": "Talimat Değiştir",
|
||||
"Instructions": "Talimatlar",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "Dahili",
|
||||
"Invite_Link": "",
|
||||
"Invites": "Davetler",
|
||||
@@ -317,6 +318,7 @@
|
||||
"Ratings": "Derecelendirmeler",
|
||||
"Recently_Viewed": "Son Görüntülenen",
|
||||
"Recipe": "Tarif",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Yemek Tarifi Kitabı",
|
||||
"Recipe_Image": "Tarif Resmi",
|
||||
"Recipes": "Tarifler",
|
||||
@@ -326,6 +328,7 @@
|
||||
"RemoveFoodFromShopping": "{food}'ı alışveriş listenizden çıkarın",
|
||||
"Remove_nutrition_recipe": "Tariften besin değeri sil",
|
||||
"Reset": "Sıfırla",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Aramayı Sıfırla",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -153,6 +153,7 @@
|
||||
"InheritWarning": "",
|
||||
"Instruction_Replace": "Замінити Інструкцію",
|
||||
"Instructions": "Інструкції",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "",
|
||||
"Invite_Link": "",
|
||||
"Key_Ctrl": "Ctrl",
|
||||
@@ -254,6 +255,7 @@
|
||||
"Ratings": "",
|
||||
"Recently_Viewed": "Нещодавно переглянуті",
|
||||
"Recipe": "Рецепт",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "Книга Рецептів",
|
||||
"Recipe_Image": "Зображення Рецепту",
|
||||
"Recipes": "Рецепти",
|
||||
@@ -263,6 +265,7 @@
|
||||
"RemoveFoodFromShopping": "Видалити {food} з вашого списку покупок",
|
||||
"Remove_nutrition_recipe": "Видалити харчову цінність з рецепта",
|
||||
"Reset": "",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "Скинути Пошук",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
"Input": "输入",
|
||||
"Instruction_Replace": "替换指令",
|
||||
"Instructions": "说明",
|
||||
"InstructionsEditHelp": "",
|
||||
"Internal": "内部",
|
||||
"Invite_Link": "",
|
||||
"Invites": "邀请",
|
||||
@@ -312,6 +313,7 @@
|
||||
"Ratings": "等级",
|
||||
"Recently_Viewed": "最近浏览",
|
||||
"Recipe": "食谱",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Book": "食谱书",
|
||||
"Recipe_Image": "食谱图像",
|
||||
"Recipes": "食谱",
|
||||
@@ -321,6 +323,7 @@
|
||||
"RemoveFoodFromShopping": "从购物清单中移除 {food}",
|
||||
"Remove_nutrition_recipe": "从食谱中删除营养信息",
|
||||
"Reset": "重置",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "重置搜索",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Import_finished": "匯入完成",
|
||||
"Information": "",
|
||||
"Ingredients": "",
|
||||
"InstructionsEditHelp": "",
|
||||
"Invite_Link": "",
|
||||
"Keywords": "",
|
||||
"Link": "",
|
||||
@@ -96,10 +97,12 @@
|
||||
"Proteins": "",
|
||||
"Rating": "",
|
||||
"Recently_Viewed": "",
|
||||
"RecipeStepsHelp": "",
|
||||
"Recipe_Image": "食譜圖片",
|
||||
"Recipes_per_page": "每頁食譜",
|
||||
"Remove": "",
|
||||
"Remove_nutrition_recipe": "從食譜中刪除營養資訊",
|
||||
"ResetHelp": "",
|
||||
"Reset_Search": "",
|
||||
"Reusable": "",
|
||||
"Role": "",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container class="h-100 pt-0 pl-0 pn-0" fluid>
|
||||
<v-container class="h-100 pt-0 pl-0 pb-0" fluid>
|
||||
<meal-plan-view></meal-plan-view>
|
||||
</v-container>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ export const useMealPlanStore = defineStore(_STORE_ID, () => {
|
||||
|
||||
let plans = ref(new Map<number, MealPlan>)
|
||||
let currently_updating = ref([new Date(0), new Date(0)])
|
||||
const loading = ref(false)
|
||||
let settings = ref({})
|
||||
|
||||
const planList = computed(() => {
|
||||
@@ -52,15 +53,17 @@ export const useMealPlanStore = defineStore(_STORE_ID, () => {
|
||||
function refreshFromAPI(from_date: Date, to_date: Date) {
|
||||
if (currently_updating.value[0] !== from_date || currently_updating.value[1] !== to_date) {
|
||||
currently_updating.value = [from_date, to_date] // certainly no perfect check but better than nothing
|
||||
|
||||
loading.value = true
|
||||
const api = new ApiApi()
|
||||
return api.apiMealPlanList({fromDate: DateTime.fromJSDate(from_date).toISODate() as string, toDate: DateTime.fromJSDate(to_date).toISODate() as string}).then(r => {
|
||||
return api.apiMealPlanList({fromDate: DateTime.fromJSDate(from_date).toISODate() as string, toDate: DateTime.fromJSDate(to_date).toISODate() as string, pageSize: 100}).then(r => {
|
||||
r.results.forEach((p) => {
|
||||
plans.value.set(p.id, p)
|
||||
})
|
||||
currently_updating.value = [new Date(0), new Date(0)]
|
||||
}).catch((err) => {
|
||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
return new Promise(() => {
|
||||
@@ -77,20 +80,23 @@ export const useMealPlanStore = defineStore(_STORE_ID, () => {
|
||||
|
||||
function createObject(object: MealPlan) {
|
||||
const api = new ApiApi()
|
||||
loading.value = true
|
||||
return api.apiMealPlanCreate({mealPlan: object}).then((r) => {
|
||||
useMessageStore().addMessage(MessageType.SUCCESS, 'Created successfully', 7000, object)
|
||||
plans.value.set(r.id, r)
|
||||
plans.value.set(r.id!, r)
|
||||
return r
|
||||
}).catch((err) => {
|
||||
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function updateObject(object: MealPlan) {
|
||||
const api = new ApiApi()
|
||||
return api.apiMealPlanUpdate({id: object.id, mealPlan: object}).then((r) => {
|
||||
return api.apiMealPlanUpdate({id: object.id!, mealPlan: object}).then((r) => {
|
||||
useMessageStore().addMessage(MessageType.SUCCESS, 'Updated successfully', 7000, object)
|
||||
plans.value.set(r.id, r)
|
||||
plans.value.set(r.id!, r)
|
||||
}).catch((err) => {
|
||||
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
|
||||
})
|
||||
@@ -98,11 +104,14 @@ export const useMealPlanStore = defineStore(_STORE_ID, () => {
|
||||
|
||||
function deleteObject(object: MealPlan) {
|
||||
const api = new ApiApi()
|
||||
return api.apiMealPlanDestroy({id: object.id}).then((r) => {
|
||||
loading.value = true
|
||||
return api.apiMealPlanDestroy({id: object.id!}).then((r) => {
|
||||
useMessageStore().addMessage(MessageType.INFO, 'Deleted successfully', 7000, object)
|
||||
plans.value.delete(object.id)
|
||||
plans.value.delete(object.id!)
|
||||
}).catch((err) => {
|
||||
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
@@ -124,7 +133,7 @@ export const useMealPlanStore = defineStore(_STORE_ID, () => {
|
||||
// return JSON.parse(s)
|
||||
// }
|
||||
// }
|
||||
return {plans, currently_updating, planList, refreshFromAPI, createObject, updateObject, deleteObject, createOrUpdate}
|
||||
return {plans, currently_updating, planList, loading, refreshFromAPI, createObject, updateObject, deleteObject, createOrUpdate}
|
||||
})
|
||||
|
||||
// enable hot reload for store
|
||||
|
||||
@@ -26,6 +26,7 @@ class DeviceSettings {
|
||||
mealplan_displayWeekNumbers = true
|
||||
|
||||
general_tableItemsPerPage = 10
|
||||
general_closedHelpAlerts: String[] = []
|
||||
}
|
||||
|
||||
export const useUserPreferenceStore = defineStore('user_preference_store', () => {
|
||||
|
||||
Reference in New Issue
Block a user