mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-09 14:35:35 -04:00
feat: Add days in the past selector on meal planner (#6857)
Co-authored-by: Michael Genson <genson.michael@gmail.com>
This commit is contained in:
@@ -22,6 +22,7 @@ export enum ImagePosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UserMealPlanPreferences {
|
export interface UserMealPlanPreferences {
|
||||||
|
numberOfDaysPast: number;
|
||||||
numberOfDays: number;
|
numberOfDays: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +77,7 @@ export function useUserMealPlanPreferences(): Ref<UserMealPlanPreferences> {
|
|||||||
const fromStorage = useLocalStorage(
|
const fromStorage = useLocalStorage(
|
||||||
"meal-planner-preferences",
|
"meal-planner-preferences",
|
||||||
{
|
{
|
||||||
|
numberOfDaysPast: 0,
|
||||||
numberOfDays: 7,
|
numberOfDays: 7,
|
||||||
},
|
},
|
||||||
{ mergeDefaults: true },
|
{ mergeDefaults: true },
|
||||||
|
|||||||
@@ -331,6 +331,8 @@
|
|||||||
"any-household": "Any Household",
|
"any-household": "Any Household",
|
||||||
"no-meal-plan-defined-yet": "No meal plan defined yet",
|
"no-meal-plan-defined-yet": "No meal plan defined yet",
|
||||||
"no-meal-planned-for-today": "No meal planned for today",
|
"no-meal-planned-for-today": "No meal planned for today",
|
||||||
|
"numberOfDaysPast-hint": "Number of days in the past on page load",
|
||||||
|
"numberOfDaysPast-label": "Default Days in the Past",
|
||||||
"numberOfDays-hint": "Number of days on page load",
|
"numberOfDays-hint": "Number of days on page load",
|
||||||
"numberOfDays-label": "Default Days",
|
"numberOfDays-label": "Default Days",
|
||||||
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Only recipes with these categories will be used in Meal Plans",
|
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Only recipes with these categories will be used in Meal Plans",
|
||||||
@@ -1471,4 +1473,4 @@
|
|||||||
"min-length": "Must Be At Least {min} Characters",
|
"min-length": "Must Be At Least {min} Characters",
|
||||||
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
|
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,18 @@
|
|||||||
:local="$i18n.locale"
|
:local="$i18n.locale"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-number-input
|
||||||
|
v-model="numberOfDaysPast"
|
||||||
|
:min="0"
|
||||||
|
control-variant="stacked"
|
||||||
|
inset
|
||||||
|
:label="$t('meal-plan.numberOfDaysPast-label')"
|
||||||
|
:hint="$t('meal-plan.numberOfDaysPast-hint')"
|
||||||
|
persistent-hint
|
||||||
|
/>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-number-input
|
<v-number-input
|
||||||
v-model="numberOfDays"
|
v-model="numberOfDays"
|
||||||
@@ -111,7 +123,11 @@ useSeoMeta({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mealPlanPreferences = useUserMealPlanPreferences();
|
const mealPlanPreferences = useUserMealPlanPreferences();
|
||||||
|
const numberOfDaysPast = ref<number>(mealPlanPreferences.value.numberOfDaysPast || 0);
|
||||||
const numberOfDays = ref<number>(mealPlanPreferences.value.numberOfDays || 7);
|
const numberOfDays = ref<number>(mealPlanPreferences.value.numberOfDays || 7);
|
||||||
|
watch(numberOfDaysPast, (val) => {
|
||||||
|
mealPlanPreferences.value.numberOfDaysPast = Number(val);
|
||||||
|
});
|
||||||
watch(numberOfDays, (val) => {
|
watch(numberOfDays, (val) => {
|
||||||
mealPlanPreferences.value.numberOfDays = Number(val);
|
mealPlanPreferences.value.numberOfDays = Number(val);
|
||||||
});
|
});
|
||||||
@@ -135,7 +151,7 @@ function safeParseISO(date: string, fallback: Date | undefined = undefined) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize dates from query parameters or defaults
|
// Initialize dates from query parameters or defaults
|
||||||
const initialStartDate = safeParseISO(route.query.start as string, new Date());
|
const initialStartDate = safeParseISO(route.query.start as string, addDays(new Date(), adjustForToday(-numberOfDaysPast.value)));
|
||||||
const initialEndDate = safeParseISO(route.query.end as string, addDays(new Date(), adjustForToday(numberOfDays.value)));
|
const initialEndDate = safeParseISO(route.query.end as string, addDays(new Date(), adjustForToday(numberOfDays.value)));
|
||||||
|
|
||||||
const state = ref({
|
const state = ref({
|
||||||
@@ -163,7 +179,7 @@ const weekRange = computed(() => {
|
|||||||
return { start, end };
|
return { start, end };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
start: new Date(),
|
start: addDays(new Date(), adjustForToday(-numberOfDaysPast.value)),
|
||||||
end: addDays(new Date(), adjustForToday(numberOfDays.value)),
|
end: addDays(new Date(), adjustForToday(numberOfDays.value)),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -193,9 +209,9 @@ function filterMealByDate(date: Date) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function adjustForToday(days: number) {
|
function adjustForToday(days: number) {
|
||||||
// The use case for this function is "how many days are we adding to 'today'?"
|
// e.g. If the user wants 7 days, we subtract one to do "today + 6"
|
||||||
// e.g. If the user wants 7 days, we substract one to do "today + 6"
|
// e.g. If the user wants 2 days in the past, we keep it the same to do "today - 2"
|
||||||
return days > 0 ? days - 1 : days + 1;
|
return days > 0 ? days - 1 : days;
|
||||||
}
|
}
|
||||||
|
|
||||||
const days = computed(() => {
|
const days = computed(() => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<v-container class="px-0 d-flex align-center" height="56px">
|
<v-container class="px-0 d-flex align-center" height="56px">
|
||||||
<v-row no-gutters style="width: 100%;">
|
<v-row no-gutters style="width: 100%;">
|
||||||
<v-col cols="10" class="d-flex align-center">
|
<v-col cols="10" class="d-flex align-center">
|
||||||
<p class="pl-2 my-1">
|
<p class="pl-2 my-1" :class="{ 'text-primary': isToday(day.date) }">
|
||||||
{{ $d(day.date, "short") }}
|
{{ $d(day.date, "short") }}
|
||||||
</p>
|
</p>
|
||||||
</v-col>
|
</v-col>
|
||||||
@@ -51,6 +51,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { isSameDay } from "date-fns";
|
||||||
|
|
||||||
import type { MealsByDate } from "./types";
|
import type { MealsByDate } from "./types";
|
||||||
import type { ReadPlanEntry } from "~/lib/api/types/meal-plan";
|
import type { ReadPlanEntry } from "~/lib/api/types/meal-plan";
|
||||||
import GroupMealPlanDayContextMenu from "~/components/Domain/Household/GroupMealPlanDayContextMenu.vue";
|
import GroupMealPlanDayContextMenu from "~/components/Domain/Household/GroupMealPlanDayContextMenu.vue";
|
||||||
@@ -126,4 +128,8 @@ const plan = computed<Days[]>(() => {
|
|||||||
return acc;
|
return acc;
|
||||||
}, [] as Days[]);
|
}, [] as Days[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isToday = (date: Date) => {
|
||||||
|
return isSameDay(date, new Date());
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user