From 8cc8c2ea614f2b4351672d2dd000947cb4411660 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:29:57 +0100 Subject: [PATCH 01/19] feat: Improve DatePickers and Forms to use contextual default dates based on the selected calendar year --- .changeset/fifty-frogs-float.md | 5 +++ .../blocks/fertilizer-applications/form.tsx | 5 ++- .../app/components/blocks/harvest/form.tsx | 40 ++++++++++++++++--- fdm-app/app/components/blocks/soil/form.tsx | 7 ++++ .../app/components/custom/date-picker-v2.tsx | 26 +++++++----- fdm-app/app/components/custom/date-picker.tsx | 14 ++++--- fdm-app/app/lib/calendar.ts | 25 ++++++++++++ ...ld.$b_id.cultivation.$b_lu.harvest.new.tsx | 6 +++ ...arm.$calendar.rotation_.harvest._index.tsx | 9 +++++ 9 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 .changeset/fifty-frogs-float.md diff --git a/.changeset/fifty-frogs-float.md b/.changeset/fifty-frogs-float.md new file mode 100644 index 000000000..6f8cff0db --- /dev/null +++ b/.changeset/fifty-frogs-float.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer, August 1st for harvest) when viewing past or future years, and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. diff --git a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx index ef2a4b300..7d896d109 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx @@ -9,6 +9,8 @@ import type { Navigation } from "react-router" import { Form, useNavigate, useSearchParams } from "react-router" import { RemixFormProvider, useRemixForm } from "remix-hook-form" import { useFieldFertilizerFormStore } from "@/app/store/field-fertilizer-form" +import { useCalendarStore } from "~/store/calendar" +import { getContextualDate } from "~/lib/calendar" import { Combobox } from "~/components/custom/combobox" import { DatePicker } from "~/components/custom/date-picker-v2" import { Button } from "~/components/ui/button" @@ -78,6 +80,7 @@ export function FertilizerApplicationForm({ const navigate = useNavigate() const [searchParams] = useSearchParams() const formId = useId() + const { calendar } = useCalendarStore() const form = useRemixForm({ mode: "onTouched", resolver: zodResolver( @@ -94,7 +97,7 @@ export function FertilizerApplicationForm({ ? fertilizerApplication.p_app_date : exampleFertilizerApplication ? undefined - : new Date(), + : getContextualDate(calendar, 3, 1), }, submitConfig: { method: fertilizerApplication ? "PUT" : "POST", diff --git a/fdm-app/app/components/blocks/harvest/form.tsx b/fdm-app/app/components/blocks/harvest/form.tsx index 46cc181e5..0a7a7458e 100644 --- a/fdm-app/app/components/blocks/harvest/form.tsx +++ b/fdm-app/app/components/blocks/harvest/form.tsx @@ -7,6 +7,7 @@ import { useEffect, useState } from "react" import { Controller } from "react-hook-form" import { Form, useFetcher, useNavigate } from "react-router" import { RemixFormProvider, useRemixForm } from "remix-hook-form" +import type { UseRemixFormReturn } from "remix-hook-form" import type { z } from "zod" import { cn } from "@/app/lib/utils" import { DatePicker } from "~/components/custom/date-picker-v2" @@ -34,6 +35,7 @@ import { } from "~/components/ui/field" import { Input } from "~/components/ui/input" import { Spinner } from "~/components/ui/spinner" +import { useCalendarStore } from "~/store/calendar" import { getHarvestParameterLabel } from "./parameters" import { FormSchema } from "./schema" @@ -42,6 +44,7 @@ type HarvestFormDialogProps = { exampleHarvestableAnalysis?: Partial example_b_lu_harvest_date?: Date | null b_lu_harvest_date: Date | string | null | undefined // Changed to allow Date or string + b_date_harvest_default?: string | null // MM-dd format from cultivation catalogue b_lu_yield: number | undefined b_lu_yield_fresh: number | undefined b_lu_yield_bruto: number | undefined @@ -62,6 +65,7 @@ type HarvestFormDialogProps = { function useHarvestRemixForm({ harvestParameters, b_lu_harvest_date, + b_date_harvest_default, b_lu_yield, b_lu_yield_fresh, b_lu_yield_bruto, @@ -77,6 +81,34 @@ function useHarvestRemixForm({ example_b_lu_harvest_date, handleConfirmation, }: HarvestFormDialogProps) { + const { calendar } = useCalendarStore() + const currentYear = new Date().getFullYear() + const calendarYear = calendar ? Number(calendar) : currentYear + + // Compute default harvest date from catalogue's MM-dd + calendar year + // Only apply when creating a new harvest (no existing date) and not in current year + function getDefaultHarvestDate(): Date | undefined { + if (b_lu_harvest_date) { + return new Date(b_lu_harvest_date) + } + if (example_b_lu_harvest_date) { + // Bulk edit: leave empty + return undefined + } + if (calendarYear === currentYear) { + // Current year: leave empty (calendar opens at today) + return undefined + } + if (b_date_harvest_default) { + // Parse MM-dd and combine with calendar year + const [month, day] = b_date_harvest_default.split("-").map(Number) + if (month && day) { + return new Date(calendarYear, month - 1, day) + } + } + return undefined + } + const form = useRemixForm>({ mode: "onSubmit", resolver: async (values, bypass, options) => { @@ -115,9 +147,7 @@ function useHarvestRemixForm({ return validation }, defaultValues: { - b_lu_harvest_date: b_lu_harvest_date - ? new Date(b_lu_harvest_date) - : undefined, + b_lu_harvest_date: getDefaultHarvestDate(), b_lu_yield: harvestParameters.includes("b_lu_yield") ? b_lu_yield : undefined, @@ -162,9 +192,9 @@ function HarvestFields({ example_b_lu_harvest_date, b_lu_harvest_date, }: HarvestFormDialogProps & { - form: ReturnType + form: UseRemixFormReturn> className: React.ComponentProps["className"] -}) { +}){ const formatted_b_lu_harvest_date = example_b_lu_harvest_date ? format(new Date(example_b_lu_harvest_date), "PP", { locale: nl }) : undefined diff --git a/fdm-app/app/components/blocks/soil/form.tsx b/fdm-app/app/components/blocks/soil/form.tsx index c621982a9..af993df18 100644 --- a/fdm-app/app/components/blocks/soil/form.tsx +++ b/fdm-app/app/components/blocks/soil/form.tsx @@ -26,6 +26,8 @@ import { } from "~/components/ui/select" import { Spinner } from "~/components/ui/spinner" import { cn } from "~/lib/utils" +import { getContextualDate } from "~/lib/calendar" +import { useCalendarStore } from "~/store/calendar" export function SoilAnalysisForm(props: { soilAnalysis: SoilAnalysis | undefined @@ -35,6 +37,7 @@ export function SoilAnalysisForm(props: { }) { const { soilAnalysis, soilParameterDescription, editable = true } = props + const { calendar } = useCalendarStore() const defaultValues: { [key: string]: string | number | Date | undefined | null } = {} @@ -50,6 +53,10 @@ export function SoilAnalysisForm(props: { defaultValue = "" } + if (defaultValue === undefined && x.type === "date" && !soilAnalysis) { + defaultValue = getContextualDate(calendar, 2, 1) + } + defaultValues[x.parameter] = defaultValue } defaultValues.a_id = undefined diff --git a/fdm-app/app/components/custom/date-picker-v2.tsx b/fdm-app/app/components/custom/date-picker-v2.tsx index 5ecdfe61c..8f2f3f300 100644 --- a/fdm-app/app/components/custom/date-picker-v2.tsx +++ b/fdm-app/app/components/custom/date-picker-v2.tsx @@ -26,6 +26,7 @@ import { PopoverTrigger, } from "~/components/ui/popover" import { endMonth } from "~/lib/calendar" +import { useCalendarStore } from "~/store/calendar" import { cn } from "~/lib/utils" type DatePickerProps = { @@ -49,30 +50,37 @@ export function DatePicker({ required, className, }: DatePickerProps) { + const { calendar } = useCalendarStore() + const calendarYear = calendar ? Number(calendar) : new Date().getFullYear() + const referenceDate = new Date(calendarYear, 0, 1) + const [open, setOpen] = useState(false) const initialDate = - (field.value && parseDateText(field.value)) || defaultValue + (field.value && parseDateText(field.value, referenceDate)) || + defaultValue const [inputValue, setInputValue] = useState( initialDate ? formatDate(initialDate) : "", ) const [selectedDate, setSelectedDate] = useState( initialDate || undefined, ) - const [month, setMonth] = useState(selectedDate) + const [month, setMonth] = useState( + selectedDate ?? referenceDate, + ) // biome-ignore lint/correctness/useExhaustiveDependencies: onChange is stable across renders for react-hook-form controllers useEffect(() => { if (field.value && field.value instanceof Date) { field.onChange(field.value.toISOString()) } else if (field.value) { - const date = parseDateText(field.value) + const date = parseDateText(field.value, referenceDate) setSelectedDate(date || undefined) setInputValue(date ? formatDate(date) : "") - setMonth(date || undefined) + setMonth(date || referenceDate) } else { setInputValue("") setSelectedDate(undefined) - setMonth(undefined) + setMonth(referenceDate) } }, [field.value]) @@ -87,7 +95,7 @@ export function DatePicker({ } const handleInputBlur = () => { - const date = parseDateText(inputValue) + const date = parseDateText(inputValue, referenceDate) if (date) { setSelectedDate(date) setMonth(date) @@ -177,7 +185,7 @@ function formatDate(date: Date | undefined) { return format(date, "PPP", { locale: nl }) } -function parseDateText(date: string | Date | undefined): Date | undefined { +function parseDateText(date: string | Date | undefined, referenceDate?: Date): Date | undefined { if (date instanceof Date) { return date } @@ -192,8 +200,8 @@ function parseDateText(date: string | Date | undefined): Date | undefined { } // Fallback to chrono-node for localized strings - const referenceDate = new Date() - const parsedDate = chrono.nl.parseDate(date, referenceDate) + const ref = referenceDate ?? new Date() + const parsedDate = chrono.nl.parseDate(date, ref) if (!parsedDate) { return undefined } diff --git a/fdm-app/app/components/custom/date-picker.tsx b/fdm-app/app/components/custom/date-picker.tsx index 68a807da6..0b033f81b 100644 --- a/fdm-app/app/components/custom/date-picker.tsx +++ b/fdm-app/app/components/custom/date-picker.tsx @@ -22,14 +22,14 @@ import { } from "~/components/ui/popover" import { endMonth } from "~/lib/calendar" +import { useCalendarStore } from "~/store/calendar" -function parseDateString(dateString: string): Date | undefined { +function parseDateString(dateString: string, referenceDate: Date): Date | undefined { if (!dateString) { return undefined } // Attempt to parse using chrono-node (Dutch) - const referenceDate = new Date() const parsedDate = chrono.nl.parseDate(dateString, referenceDate) if (parsedDate) { return parsedDate @@ -70,11 +70,15 @@ export function DatePicker({ description, disabled = false, }: DatePickerProps) { + const { calendar } = useCalendarStore() + const calendarYear = calendar ? Number(calendar) : new Date().getFullYear() + const referenceDate = new Date(calendarYear, 0, 1) + const [open, setOpen] = React.useState(false) const [date, setDate] = React.useState( form.getValues(name), ) - const [month, setMonth] = React.useState(date || new Date()) // Initialize month to current date if 'date' is undefined + const [month, setMonth] = React.useState(date || referenceDate) const [value, setValue] = React.useState(formatDate(date)) const [isInputValid, setIsInputValid] = React.useState(true) @@ -91,7 +95,7 @@ export function DatePicker({ } else if (date !== undefined) { // If formDate is undefined or invalid, and date was previously defined setDate(undefined) - setMonth(new Date()) // Reset month to current month + setMonth(referenceDate) // Reset month to calendar context month setValue("") // Clear input value setIsInputValid(true) } @@ -130,7 +134,7 @@ export function DatePicker({ return } - const newDate = parseDateString(text) + const newDate = parseDateString(text, referenceDate) if (newDate && isValidDate(newDate)) { setDate(newDate) setMonth(newDate) diff --git a/fdm-app/app/lib/calendar.ts b/fdm-app/app/lib/calendar.ts index bd5c2b4b1..e07570e43 100644 --- a/fdm-app/app/lib/calendar.ts +++ b/fdm-app/app/lib/calendar.ts @@ -39,6 +39,31 @@ export function getTimeframe(params: Params): Timeframe { return timeframe } +/** + * Returns a context-aware default date based on the active cultivation calendar year. + * + * - If the calendar year matches the current real-world year, returns today's date. + * - Otherwise, returns a fixed date (defaultMonth/defaultDay) within the calendar year. + * + * @param calendar - Active calendar year as a string (e.g. "2023"), or undefined. + * @param defaultMonth - 1-indexed month for the fallback date (e.g. 3 for March). + * @param defaultDay - Day of the month for the fallback date (e.g. 1 for the 1st). + */ +export function getContextualDate( + calendar: string | undefined, + defaultMonth: number, + defaultDay: number, +): Date { + const currentYear = new Date().getFullYear() + const calendarYear = calendar ? Number(calendar) : currentYear + + if (calendarYear === currentYear) { + return new Date() + } + + return new Date(calendarYear, defaultMonth - 1, defaultDay) +} + export function getCalendarSelection(): string[] { // Create array of years from 2020 to next year const years = [] diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.cultivation.$b_lu.harvest.new.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.cultivation.$b_lu.harvest.new.tsx index 516819101..83f52ed1f 100644 --- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.cultivation.$b_lu.harvest.new.tsx +++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.cultivation.$b_lu.harvest.new.tsx @@ -69,6 +69,10 @@ export async function loader({ request, params }: LoaderFunctionArgs) { cultivation.b_lu_catalogue, cultivationsCatalogue, ) + const b_date_harvest_default = + cultivationsCatalogue.find( + (item) => item.b_lu_catalogue === cultivation.b_lu_catalogue, + )?.b_date_harvest_default ?? null return { b_id_farm, @@ -76,6 +80,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) { cultivation, harvestParameters, defaultHarvestParameters, + b_date_harvest_default, } } catch (error) { throw handleLoaderError(error) @@ -89,6 +94,7 @@ export default function HarvestNewBlock() { + item.b_lu_catalogue === targetCultivation.b_lu_catalogue, + )?.b_date_harvest_default ?? null // Return user information from loader return { @@ -352,6 +357,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) { harvestParameters: harvestParameters, b_lu_start: b_lu_start, b_lu_end: b_lu_end, + b_date_harvest_default: b_date_harvest_default, create: url.searchParams.has("create"), } } catch (error) { @@ -720,6 +726,9 @@ export default function FarmRotationHarvestAddIndex() { loaderData.harvestApplication .b_lu_harvest_date } + b_date_harvest_default={ + loaderData.b_date_harvest_default + } b_lu_yield={ loaderData.harvestableAnalysis .b_lu_yield From 719626f5014c74d5fc1386c4ce251ceed2a8aeb9 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:32:42 +0100 Subject: [PATCH 02/19] fix: parsing dutch date notations --- .../app/components/custom/date-picker-v2.tsx | 74 ++++++++++++++++--- fdm-app/app/components/custom/date-picker.tsx | 60 ++++++++++++--- 2 files changed, 113 insertions(+), 21 deletions(-) diff --git a/fdm-app/app/components/custom/date-picker-v2.tsx b/fdm-app/app/components/custom/date-picker-v2.tsx index 8f2f3f300..7ad3a214d 100644 --- a/fdm-app/app/components/custom/date-picker-v2.tsx +++ b/fdm-app/app/components/custom/date-picker-v2.tsx @@ -56,7 +56,7 @@ export function DatePicker({ const [open, setOpen] = useState(false) const initialDate = - (field.value && parseDateText(field.value, referenceDate)) || + (field.value && parseDateText(field.value, calendarYear)) || defaultValue const [inputValue, setInputValue] = useState( initialDate ? formatDate(initialDate) : "", @@ -73,7 +73,7 @@ export function DatePicker({ if (field.value && field.value instanceof Date) { field.onChange(field.value.toISOString()) } else if (field.value) { - const date = parseDateText(field.value, referenceDate) + const date = parseDateText(field.value, calendarYear) setSelectedDate(date || undefined) setInputValue(date ? formatDate(date) : "") setMonth(date || referenceDate) @@ -95,7 +95,7 @@ export function DatePicker({ } const handleInputBlur = () => { - const date = parseDateText(inputValue, referenceDate) + const date = parseDateText(inputValue, calendarYear) if (date) { setSelectedDate(date) setMonth(date) @@ -185,7 +185,7 @@ function formatDate(date: Date | undefined) { return format(date, "PPP", { locale: nl }) } -function parseDateText(date: string | Date | undefined, referenceDate?: Date): Date | undefined { +function parseDateText(date: string | Date | undefined, calendarYear?: number): Date | undefined { if (date instanceof Date) { return date } @@ -193,18 +193,68 @@ function parseDateText(date: string | Date | undefined, referenceDate?: Date): D return undefined } - // Attempt to parse as ISO string first - const isoDate = new Date(date) - if (!Number.isNaN(isoDate.getTime())) { - return isoDate + const currentYear = new Date().getFullYear() + const targetYear = calendarYear ?? currentYear + + // Only treat as ISO string when it matches YYYY-MM-DD... to avoid JS's lenient Date parsing + // (e.g. new Date("1-4-2025") returns January 4th — American order — before Dutch pre-processor runs). + if (/^\d{4}-\d{2}-\d{2}/.test(date)) { + const isoDate = new Date(date) + if (!Number.isNaN(isoDate.getTime())) { + return isoDate + } + } + + // Dutch numeric format: DD-MM, DD-MM-YY, DD-MM-YYYY (e.g. "1-4", "1-4-25", "01-04-2025") + // Processed before chrono-node because chrono-node uses American MM-DD order for numeric dates. + const dutchNumeric = parseDutchNumericDate(date, targetYear) + if (dutchNumeric) { + return dutchNumeric } - // Fallback to chrono-node for localized strings - const ref = referenceDate ?? new Date() - const parsedDate = chrono.nl.parseDate(date, ref) - if (!parsedDate) { + // Chrono-node always uses actual today as reference so relative terms ("gisteren", "vandaag") + // resolve to the correct real-world date. + const results = chrono.nl.parse(date, new Date()) + if (!results?.length) { return undefined } + const result = results[0] + const parsedDate = result.start.date() + + // When a specific date was mentioned (month or day explicit) but no year was stated, + // override the year with the active calendar year. Skip for pure relative terms like + // "gisteren" where neither month nor day is explicit. + if ( + targetYear !== currentYear && + !result.start.isCertain("year") && + (result.start.isCertain("month") || result.start.isCertain("day")) + ) { + parsedDate.setFullYear(targetYear) + } return parsedDate } + +// Parses Dutch numeric date format DD-MM, DD-MM-YY or DD-MM-YYYY. +// Returns undefined when the input doesn't match or produces an invalid date. +function parseDutchNumericDate(text: string, targetYear: number): Date | undefined { + const match = text.trim().match(/^(\d{1,2})[./-](\d{1,2})(?:[./-](\d{2,4}))?$/) + if (!match) { + return undefined + } + const day = Number(match[1]) + const month = Number(match[2]) + if (day < 1 || day > 31 || month < 1 || month > 12) { + return undefined + } + let year = targetYear + if (match[3]) { + const y = Number(match[3]) + year = match[3].length <= 2 ? 2000 + y : y + } + const result = new Date(year, month - 1, day) + if (Number.isNaN(result.getTime()) || result.getMonth() !== month - 1) { + return undefined + } + return result +} diff --git a/fdm-app/app/components/custom/date-picker.tsx b/fdm-app/app/components/custom/date-picker.tsx index 0b033f81b..d7d292126 100644 --- a/fdm-app/app/components/custom/date-picker.tsx +++ b/fdm-app/app/components/custom/date-picker.tsx @@ -24,20 +24,62 @@ import { import { endMonth } from "~/lib/calendar" import { useCalendarStore } from "~/store/calendar" -function parseDateString(dateString: string, referenceDate: Date): Date | undefined { +function parseDateString(dateString: string, calendarYear: number): Date | undefined { if (!dateString) { return undefined } - // Attempt to parse using chrono-node (Dutch) - const parsedDate = chrono.nl.parseDate(dateString, referenceDate) - if (parsedDate) { - return parsedDate + const currentYear = new Date().getFullYear() + + // Dutch numeric format: DD-MM, DD-MM-YY, DD-MM-YYYY + const dutchNumeric = parseDutchNumericDate(dateString, calendarYear) + if (dutchNumeric) { + return dutchNumeric + } + + // Chrono-node always uses today as reference so relative terms ("gisteren") work correctly. + const results = chrono.nl.parse(dateString, new Date()) + if (!results?.length) { + // Fallback to default Date parsing for ISO-like strings + const defaultDate = new Date(dateString) + return isValidDate(defaultDate) ? defaultDate : undefined } + const result = results[0] + const parsedDate = result.start.date() + + // Override with calendar year only for explicit partial dates (month/day stated, year not). + if ( + calendarYear !== currentYear && + !result.start.isCertain("year") && + (result.start.isCertain("month") || result.start.isCertain("day")) + ) { + parsedDate.setFullYear(calendarYear) + } + + return isValidDate(parsedDate) ? parsedDate : undefined +} - // Fallback to default Date parsing for other formats - const defaultDate = new Date(dateString) - return isValidDate(defaultDate) ? defaultDate : undefined +// Parses Dutch numeric date format DD-MM, DD-MM-YY or DD-MM-YYYY. +function parseDutchNumericDate(text: string, targetYear: number): Date | undefined { + const match = text.trim().match(/^(\d{1,2})[./-](\d{1,2})(?:[./-](\d{2,4}))?$/) + if (!match) { + return undefined + } + const day = Number(match[1]) + const month = Number(match[2]) + if (day < 1 || day > 31 || month < 1 || month > 12) { + return undefined + } + let year = targetYear + if (match[3]) { + const y = Number(match[3]) + year = match[3].length <= 2 ? 2000 + y : y + } + const result = new Date(year, month - 1, day) + if (Number.isNaN(result.getTime()) || result.getMonth() !== month - 1) { + return undefined + } + return result } function formatDate(date: Date | undefined) { @@ -134,7 +176,7 @@ export function DatePicker({ return } - const newDate = parseDateString(text, referenceDate) + const newDate = parseDateString(text, calendarYear) if (newDate && isValidDate(newDate)) { setDate(newDate) setMonth(newDate) From 4b9ebd1f89952699c646e871731f716dc9afdefa Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:08:36 +0100 Subject: [PATCH 03/19] refactor: Increase navigation progress time from 300 to 500ms --- .changeset/dirty-rooms-doubt.md | 5 +++++ fdm-app/app/components/custom/navigation-progress.tsx | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/dirty-rooms-doubt.md diff --git a/.changeset/dirty-rooms-doubt.md b/.changeset/dirty-rooms-doubt.md new file mode 100644 index 000000000..649bd24e3 --- /dev/null +++ b/.changeset/dirty-rooms-doubt.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Increase navigation progress time from 300 to 500ms diff --git a/fdm-app/app/components/custom/navigation-progress.tsx b/fdm-app/app/components/custom/navigation-progress.tsx index a6a59e73a..6b8b316c3 100644 --- a/fdm-app/app/components/custom/navigation-progress.tsx +++ b/fdm-app/app/components/custom/navigation-progress.tsx @@ -6,7 +6,7 @@ import { useNavigation } from "react-router" import { clientConfig } from "~/lib/config" /** - * Shows a blurred overlay with a loading card when navigation takes longer than 300ms. + * Shows a blurred overlay with a loading card when navigation takes longer than 500ms. * Fast navigations never trigger the indicator. * Tracks show frequency and duration as Sentry metrics. */ @@ -15,7 +15,7 @@ export function NavigationProgress() { const [show, setShow] = useState(false) const startTimeRef = useRef(null) - // Show after 300ms — emit a count metric when it appears + // Show after 500ms — emit a count metric when it appears useEffect(() => { if (state !== "idle") { if (startTimeRef.current === null) { @@ -26,7 +26,7 @@ export function NavigationProgress() { if (clientConfig.analytics.sentry) { Sentry.metrics.count("navigation_progress.shown", 1) } - }, 300) + }, 500) return () => clearTimeout(timer) } From ad1ebbf3ba26a3d827d35d9c09f3d982c91bb492 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:16:36 +0100 Subject: [PATCH 04/19] fix: Do not show the NavigationProgress for pages with their own loaders, like uploading files --- .changeset/brave-eagles-hide.md | 5 +++++ .../app/components/custom/navigation-progress.tsx | 14 ++++++++++++-- .../routes/farm.$b_id_farm.soil-analysis.bulk.tsx | 2 ++ ...ate.$b_id_farm.$calendar.soil-analysis.bulk.tsx | 2 ++ .../farm.create.$b_id_farm.$calendar.upload.tsx | 2 ++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .changeset/brave-eagles-hide.md diff --git a/.changeset/brave-eagles-hide.md b/.changeset/brave-eagles-hide.md new file mode 100644 index 000000000..90a921b39 --- /dev/null +++ b/.changeset/brave-eagles-hide.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Do not show the NavigationProgress for pages with their own loaders, like uploading files diff --git a/fdm-app/app/components/custom/navigation-progress.tsx b/fdm-app/app/components/custom/navigation-progress.tsx index 6b8b316c3..32ef3fa5a 100644 --- a/fdm-app/app/components/custom/navigation-progress.tsx +++ b/fdm-app/app/components/custom/navigation-progress.tsx @@ -2,22 +2,32 @@ import * as Sentry from "@sentry/react-router" import { AnimatePresence, motion } from "framer-motion" import { Loader2 } from "lucide-react" import { useEffect, useRef, useState } from "react" -import { useNavigation } from "react-router" +import { useMatches, useNavigation } from "react-router" import { clientConfig } from "~/lib/config" /** * Shows a blurred overlay with a loading card when navigation takes longer than 500ms. * Fast navigations never trigger the indicator. * Tracks show frequency and duration as Sentry metrics. + * + * Routes can opt out by exporting `export const handle = { hideNavigationProgress: true }`. */ export function NavigationProgress() { const { state } = useNavigation() + const matches = useMatches() + const hideProgress = matches.some( + (m) => + m.handle !== null && + typeof m.handle === "object" && + (m.handle as Record).hideNavigationProgress === + true, + ) const [show, setShow] = useState(false) const startTimeRef = useRef(null) // Show after 500ms — emit a count metric when it appears useEffect(() => { - if (state !== "idle") { + if (state !== "idle" && !hideProgress) { if (startTimeRef.current === null) { startTimeRef.current = Date.now() } diff --git a/fdm-app/app/routes/farm.$b_id_farm.soil-analysis.bulk.tsx b/fdm-app/app/routes/farm.$b_id_farm.soil-analysis.bulk.tsx index f642e26a4..45652609d 100644 --- a/fdm-app/app/routes/farm.$b_id_farm.soil-analysis.bulk.tsx +++ b/fdm-app/app/routes/farm.$b_id_farm.soil-analysis.bulk.tsx @@ -30,6 +30,8 @@ import { getSession } from "~/lib/auth.server" import { handleActionError, handleLoaderError } from "~/lib/error" import { fdm } from "~/lib/fdm.server" +export const handle = { hideNavigationProgress: true } + export async function loader({ request, params }: LoaderFunctionArgs) { try { const b_id_farm = params.b_id_farm diff --git a/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.soil-analysis.bulk.tsx b/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.soil-analysis.bulk.tsx index 0940c62b4..d15699aa3 100644 --- a/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.soil-analysis.bulk.tsx +++ b/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.soil-analysis.bulk.tsx @@ -29,6 +29,8 @@ import { getCalendar, getTimeframe } from "~/lib/calendar" import { handleActionError, handleLoaderError } from "~/lib/error" import { fdm } from "~/lib/fdm.server" +export const handle = { hideNavigationProgress: true } + export async function loader({ request, params }: LoaderFunctionArgs) { try { const b_id_farm = params.b_id_farm diff --git a/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.upload.tsx b/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.upload.tsx index 60449e523..83d3abe12 100644 --- a/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.upload.tsx +++ b/fdm-app/app/routes/farm.create.$b_id_farm.$calendar.upload.tsx @@ -29,6 +29,8 @@ import { clientConfig } from "~/lib/config" import { handleActionError } from "~/lib/error" import { fdm } from "~/lib/fdm.server" +export const handle = { hideNavigationProgress: true } + // Meta export const meta: MetaFunction = () => { return [ From bb6703bff65281a967c544880631a15e215903fa Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:21:38 +0100 Subject: [PATCH 05/19] fix: going to Fertilizers page does not reset the selected calender year to current year --- .changeset/seven-days-nail.md | 5 +++++ fdm-app/app/routes/farm.tsx | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/seven-days-nail.md diff --git a/.changeset/seven-days-nail.md b/.changeset/seven-days-nail.md new file mode 100644 index 000000000..b23de21be --- /dev/null +++ b/.changeset/seven-days-nail.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Fix that going to Fertilizers page does not reset the selected calender year to current year diff --git a/fdm-app/app/routes/farm.tsx b/fdm-app/app/routes/farm.tsx index 629e3a448..7a055ce1e 100644 --- a/fdm-app/app/routes/farm.tsx +++ b/fdm-app/app/routes/farm.tsx @@ -106,7 +106,9 @@ export default function App() { const setCalendar = useCalendarStore((state) => state.setCalendar) useEffect(() => { - setCalendar(initialCalendar) + if (initialCalendar !== undefined) { + setCalendar(initialCalendar) + } }, [initialCalendar, setCalendar]) // Identify user if PostHog is configured From 06fafd1e67f0997f8da31ced50af3416c2dc3aab Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:30:16 +0100 Subject: [PATCH 06/19] fix: link for going back for fertilizer application modification goes back to rotation --- .changeset/nine-cups-start.md | 5 +++++ ...b_id_farm.$calendar.field.fertilizer._index.tsx | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 .changeset/nine-cups-start.md diff --git a/.changeset/nine-cups-start.md b/.changeset/nine-cups-start.md new file mode 100644 index 000000000..445f2bc0d --- /dev/null +++ b/.changeset/nine-cups-start.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Fix that link for going back for fertilizer application modification goes back to rotation diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.fertilizer._index.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.fertilizer._index.tsx index 4dcea15d2..189ce8e74 100644 --- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.fertilizer._index.tsx +++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.field.fertilizer._index.tsx @@ -89,6 +89,13 @@ export async function loader({ request, params }: LoaderFunctionArgs) { const url = new URL(request.url) + // Determine where to return after saving/cancelling + const returnUrlParam = url.searchParams.get("returnUrl") + const returnUrl = + returnUrlParam && isOfOrigin(returnUrlParam, url.origin) + ? returnUrlParam + : `/farm/${b_id_farm}/${params.calendar}/field` + // Get appIds from search params const applicationRefs = parseAppIds( url.searchParams.get("appIds") ?? "", @@ -308,6 +315,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) { fieldOptions: fieldOptions, fertilizerApplication: loaderFertilizerApplication, exampleFertilizerApplication: loaderExampleFertilizerApplication, + returnUrl: returnUrl, } } catch (error) { throw handleLoaderError(error) @@ -351,8 +359,10 @@ export default function FarmFieldFertilizerAddIndex() {
From 5ffc4b8f09cbb698a179d1f9fcb2d37e3e2ab855 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 14:57:44 +0100 Subject: [PATCH 07/19] docs: fix typo --- .changeset/fifty-frogs-float.md | 2 +- .changeset/seven-days-nail.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/fifty-frogs-float.md b/.changeset/fifty-frogs-float.md index 6f8cff0db..2f4d23a23 100644 --- a/.changeset/fifty-frogs-float.md +++ b/.changeset/fifty-frogs-float.md @@ -2,4 +2,4 @@ "@nmi-agro/fdm-app": patch --- -Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer, August 1st for harvest) when viewing past or future years, and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. +Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. \ No newline at end of file diff --git a/.changeset/seven-days-nail.md b/.changeset/seven-days-nail.md index b23de21be..816e3f7b5 100644 --- a/.changeset/seven-days-nail.md +++ b/.changeset/seven-days-nail.md @@ -2,4 +2,4 @@ "@nmi-agro/fdm-app": patch --- -Fix that going to Fertilizers page does not reset the selected calender year to current year +Fix that going to Fertilizers page does not reset the selected calendar year to current year From e55337f07b1dfc33982910b10d5ad5932e096f0f Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 14:59:03 +0100 Subject: [PATCH 08/19] fix: potential NaN issue when calendar is non-numeric (e.g., "all") --- fdm-app/app/components/blocks/harvest/form.tsx | 7 +++++-- fdm-app/app/lib/calendar.ts | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fdm-app/app/components/blocks/harvest/form.tsx b/fdm-app/app/components/blocks/harvest/form.tsx index 0a7a7458e..cfd4eeb45 100644 --- a/fdm-app/app/components/blocks/harvest/form.tsx +++ b/fdm-app/app/components/blocks/harvest/form.tsx @@ -83,7 +83,10 @@ function useHarvestRemixForm({ }: HarvestFormDialogProps) { const { calendar } = useCalendarStore() const currentYear = new Date().getFullYear() - const calendarYear = calendar ? Number(calendar) : currentYear + const parsedCalendar = calendar ? Number(calendar) : Number.NaN + const calendarYear = Number.isNaN(parsedCalendar) + ? currentYear + : parsedCalendar // Compute default harvest date from catalogue's MM-dd + calendar year // Only apply when creating a new harvest (no existing date) and not in current year @@ -194,7 +197,7 @@ function HarvestFields({ }: HarvestFormDialogProps & { form: UseRemixFormReturn> className: React.ComponentProps["className"] -}){ +}) { const formatted_b_lu_harvest_date = example_b_lu_harvest_date ? format(new Date(example_b_lu_harvest_date), "PP", { locale: nl }) : undefined diff --git a/fdm-app/app/lib/calendar.ts b/fdm-app/app/lib/calendar.ts index e07570e43..907e5ab41 100644 --- a/fdm-app/app/lib/calendar.ts +++ b/fdm-app/app/lib/calendar.ts @@ -55,7 +55,10 @@ export function getContextualDate( defaultDay: number, ): Date { const currentYear = new Date().getFullYear() - const calendarYear = calendar ? Number(calendar) : currentYear + const parsedYear = calendar ? Number(calendar) : currentYear + const calendarYear = Number.isInteger(parsedYear) + ? parsedYear + : currentYear if (calendarYear === currentYear) { return new Date() From 8fd47a6c288e849272ba444b8fcb4b2babbf1156 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:05:46 +0100 Subject: [PATCH 09/19] fix: Make the saved fertilizer draft calendar-aware --- .../blocks/fertilizer-applications/form.tsx | 4 +++- fdm-app/app/store/field-fertilizer-form.tsx | 20 ++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx index 7d896d109..28b8a7678 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx @@ -123,6 +123,7 @@ export function FertilizerApplicationForm({ const savedFormValues = fieldFertilizerFormStore.load( b_id_farm, b_id_or_b_lu_catalogue, + calendar, ) if (savedFormValues) { for (const [k, v] of Object.entries(savedFormValues)) { @@ -159,7 +160,7 @@ export function FertilizerApplicationForm({ useEffect(() => { if (form.formState.isSubmitSuccessful) { - fieldFertilizerFormStore.delete(b_id_farm, b_id_or_b_lu_catalogue) + fieldFertilizerFormStore.delete(b_id_farm, b_id_or_b_lu_catalogue, calendar) } }, [ form.formState.isSubmitSuccessful, @@ -174,6 +175,7 @@ export function FertilizerApplicationForm({ b_id_farm, b_id_or_b_lu_catalogue, form.getValues(), + calendar, ) } navigate( diff --git a/fdm-app/app/store/field-fertilizer-form.tsx b/fdm-app/app/store/field-fertilizer-form.tsx index 75dedf5f7..383b23d9f 100644 --- a/fdm-app/app/store/field-fertilizer-form.tsx +++ b/fdm-app/app/store/field-fertilizer-form.tsx @@ -8,34 +8,36 @@ interface FieldFertilizerFormStore { b_id_farm: string, b_id_or_b_lu_catalogue: string, formData: Partial, + calendar?: string, ): void load( b_id_farm: string, b_id_or_b_lu_catalogue: string, + calendar?: string, ): Partial | undefined - delete(b_id_farm: string, b_id_or_b_lu_catalogue: string): void + delete(b_id_farm: string, b_id_or_b_lu_catalogue: string, calendar?: string): void } -function makeId(b_id_farm: string, b_id: string) { - return `${b_id_farm}/${b_id}` +function makeId(b_id_farm: string, b_id: string, calendar?: string) { + return calendar ? `${b_id_farm}/${b_id}/${calendar}` : `${b_id_farm}/${b_id}` } export const useFieldFertilizerFormStore = create()( persist( (set, get) => ({ db: {}, - save(b_id_farm, b_id_or_b_lu_catalogue, formData) { + save(b_id_farm, b_id_or_b_lu_catalogue, formData, calendar) { const db = { ...get().db, - [makeId(b_id_farm, b_id_or_b_lu_catalogue)]: formData, + [makeId(b_id_farm, b_id_or_b_lu_catalogue, calendar)]: formData, } set({ db }) }, - load(b_id_farm, b_id_or_b_lu_catalogue) { - return get().db[makeId(b_id_farm, b_id_or_b_lu_catalogue)] + load(b_id_farm, b_id_or_b_lu_catalogue, calendar) { + return get().db[makeId(b_id_farm, b_id_or_b_lu_catalogue, calendar)] }, - delete(b_id_farm, b_id_or_b_lu_catalogue) { + delete(b_id_farm, b_id_or_b_lu_catalogue, calendar) { const db = { ...get().db } - delete db[makeId(b_id_farm, b_id_or_b_lu_catalogue)] + delete db[makeId(b_id_farm, b_id_or_b_lu_catalogue, calendar)] set({ db }) }, }), From 1284d9f101a0176708f5c4c05c860d93289046b7 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:06:33 +0100 Subject: [PATCH 10/19] fix: Add hideProgress to the effect's dependency array --- fdm-app/app/components/custom/navigation-progress.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdm-app/app/components/custom/navigation-progress.tsx b/fdm-app/app/components/custom/navigation-progress.tsx index 32ef3fa5a..e261d9aee 100644 --- a/fdm-app/app/components/custom/navigation-progress.tsx +++ b/fdm-app/app/components/custom/navigation-progress.tsx @@ -52,7 +52,7 @@ export function NavigationProgress() { } setShow(false) startTimeRef.current = null - }, [state, show]) + }, [state, show, hideProgress]) return ( From c3dfb27cbbf4d1c28ef2fb6aa9dce89be60f8203 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:09:04 +0100 Subject: [PATCH 11/19] fix: useEffect dependency --- .../components/blocks/fertilizer-applications/form.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx index 28b8a7678..4cc2eac36 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx @@ -141,6 +141,7 @@ export function FertilizerApplicationForm({ b_id_or_b_lu_catalogue, form.setValue, fieldFertilizerFormStore.load, + calendar, ]) useEffect(() => { @@ -160,13 +161,18 @@ export function FertilizerApplicationForm({ useEffect(() => { if (form.formState.isSubmitSuccessful) { - fieldFertilizerFormStore.delete(b_id_farm, b_id_or_b_lu_catalogue, calendar) + fieldFertilizerFormStore.delete( + b_id_farm, + b_id_or_b_lu_catalogue, + calendar, + ) } }, [ form.formState.isSubmitSuccessful, b_id_farm, b_id_or_b_lu_catalogue, fieldFertilizerFormStore.delete, + calendar, ]) function handleManageFertilizers(_e: MouseEvent) { From c6dfd076c87daf5fab8ee4ba37aac08c1e858893 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:19:47 +0100 Subject: [PATCH 12/19] feat: At the Sentry metric for NavigationProgress include a tag for the page --- .changeset/social-cycles-stare.md | 5 +++ .../components/custom/navigation-progress.tsx | 34 ++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 .changeset/social-cycles-stare.md diff --git a/.changeset/social-cycles-stare.md b/.changeset/social-cycles-stare.md new file mode 100644 index 000000000..1bbf7e710 --- /dev/null +++ b/.changeset/social-cycles-stare.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +At the Sentry metric for NavigationProgress include a tag for the page diff --git a/fdm-app/app/components/custom/navigation-progress.tsx b/fdm-app/app/components/custom/navigation-progress.tsx index e261d9aee..fa5848c2e 100644 --- a/fdm-app/app/components/custom/navigation-progress.tsx +++ b/fdm-app/app/components/custom/navigation-progress.tsx @@ -2,18 +2,19 @@ import * as Sentry from "@sentry/react-router" import { AnimatePresence, motion } from "framer-motion" import { Loader2 } from "lucide-react" import { useEffect, useRef, useState } from "react" -import { useMatches, useNavigation } from "react-router" +import { useLocation, useMatches, useNavigation } from "react-router" import { clientConfig } from "~/lib/config" /** * Shows a blurred overlay with a loading card when navigation takes longer than 500ms. * Fast navigations never trigger the indicator. - * Tracks show frequency and duration as Sentry metrics. + * Tracks show frequency and duration as Sentry metrics, tagged with the source page pathname. * * Routes can opt out by exporting `export const handle = { hideNavigationProgress: true }`. */ export function NavigationProgress() { const { state } = useNavigation() + const { pathname } = useLocation() const matches = useMatches() const hideProgress = matches.some( (m) => @@ -24,17 +25,25 @@ export function NavigationProgress() { ) const [show, setShow] = useState(false) const startTimeRef = useRef(null) + const startPathnameRef = useRef(null) // Show after 500ms — emit a count metric when it appears useEffect(() => { if (state !== "idle" && !hideProgress) { if (startTimeRef.current === null) { startTimeRef.current = Date.now() + startPathnameRef.current = pathname } const timer = setTimeout(() => { setShow(true) if (clientConfig.analytics.sentry) { - Sentry.metrics.count("navigation_progress.shown", 1) + Sentry.withScope((scope) => { + scope.setTag( + "page", + startPathnameRef.current ?? pathname, + ) + Sentry.metrics.count("navigation_progress.shown", 1) + }) } }, 500) return () => clearTimeout(timer) @@ -44,15 +53,22 @@ export function NavigationProgress() { if (show && startTimeRef.current !== null) { const duration = Date.now() - startTimeRef.current if (clientConfig.analytics.sentry) { - Sentry.metrics.distribution( - "navigation_progress.duration_ms", - duration, - ) - } + Sentry.withScope((scope) => { + scope.setTag( + "page", + startPathnameRef.current ?? pathname, + ) + Sentry.metrics.distribution( + "navigation_progress.duration_ms", + duration, + ) + }) + } } setShow(false) startTimeRef.current = null - }, [state, show, hideProgress]) + startPathnameRef.current = null + }, [state, show, hideProgress, pathname]) return ( From ac0342d01e138f6bf5f30670024aa89b8fb91e70 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:58:09 +0100 Subject: [PATCH 13/19] fix: added a useEffect in useHarvestRemixForm --- fdm-app/app/components/blocks/harvest/form.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fdm-app/app/components/blocks/harvest/form.tsx b/fdm-app/app/components/blocks/harvest/form.tsx index cfd4eeb45..e8cec4448 100644 --- a/fdm-app/app/components/blocks/harvest/form.tsx +++ b/fdm-app/app/components/blocks/harvest/form.tsx @@ -184,6 +184,21 @@ function useHarvestRemixForm({ }, }) + // When the calendar store is populated after initial render, re-evaluate the + // default harvest date and reset the form so the catalogue default is applied. + useEffect(() => { + if (!b_lu_harvest_date && !example_b_lu_harvest_date) { + form.reset( + { + ...form.getValues(), + b_lu_harvest_date: getDefaultHarvestDate(), + }, + { keepErrors: false }, + ) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [calendar]) + return form } From b2d17cd4428f3be1bec85b425f3d426de67dfe5b Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:01:53 +0100 Subject: [PATCH 14/19] fix: set default date --- .../blocks/fertilizer-applications/form.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx index 4cc2eac36..3e32a11c1 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx @@ -116,6 +116,20 @@ export function FertilizerApplicationForm({ } }, [p_id, fertilizerApplication, form.setValue]) + useEffect(() => { + if ( + !fertilizerApplication?.p_app_date && + !exampleFertilizerApplication + ) { + form.setValue("p_app_date", getContextualDate(calendar, 3, 1)) + } + }, [ + calendar, + exampleFertilizerApplication, + fertilizerApplication?.p_app_date, + form.setValue, + ]) + const fieldFertilizerFormStore = useFieldFertilizerFormStore() useEffect(() => { From 65ebf420afd0e0d6d45dbf804a02947f6ecabc02 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:48:20 +0100 Subject: [PATCH 15/19] fix: farm nitrogen balance to exclude nitrate leaching --- .changeset/easy-bikes-invent.md | 5 +++++ fdm-calculator/src/balance/nitrogen/index.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/easy-bikes-invent.md diff --git a/.changeset/easy-bikes-invent.md b/.changeset/easy-bikes-invent.md new file mode 100644 index 000000000..e15251d89 --- /dev/null +++ b/.changeset/easy-bikes-invent.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-calculator": patch +--- + +Fixes for farm nitrogen balance to exclude nitrate leaching diff --git a/fdm-calculator/src/balance/nitrogen/index.ts b/fdm-calculator/src/balance/nitrogen/index.ts index ce3b1e6dd..511dfe273 100644 --- a/fdm-calculator/src/balance/nitrogen/index.ts +++ b/fdm-calculator/src/balance/nitrogen/index.ts @@ -488,10 +488,10 @@ export function calculateNitrogenBalancesFieldToFarm( : ammoniaByFertilizerType[fertilizerType].dividedBy(totalFarmArea) } - // Calculate the average balance at farm level (Supply + Removal + Emission) + // Calculate the average balance at farm level (Supply + Removal + Ammonia Emission) const avgFarmBalance = avgFarmSupply .add(avgFarmRemoval) - .add(avgFarmEmission) + .add(avgFarmEmissionAmmonia) // Return the farm with average balances per hectare const farmWithBalance = { From 4a3bd508116262822d0d48b43f78eeeb3c26eec7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Mar 2026 15:51:08 +0000 Subject: [PATCH 16/19] chore: bump version of packages for release --- .changeset/brave-eagles-hide.md | 5 ----- .changeset/dirty-rooms-doubt.md | 5 ----- .changeset/easy-bikes-invent.md | 5 ----- .changeset/fifty-frogs-float.md | 5 ----- .changeset/nine-cups-start.md | 5 ----- .changeset/seven-days-nail.md | 5 ----- .changeset/social-cycles-stare.md | 5 ----- fdm-app/CHANGELOG.md | 19 +++++++++++++++++++ fdm-app/package.json | 2 +- fdm-calculator/CHANGELOG.md | 6 ++++++ fdm-calculator/package.json | 2 +- 11 files changed, 27 insertions(+), 37 deletions(-) delete mode 100644 .changeset/brave-eagles-hide.md delete mode 100644 .changeset/dirty-rooms-doubt.md delete mode 100644 .changeset/easy-bikes-invent.md delete mode 100644 .changeset/fifty-frogs-float.md delete mode 100644 .changeset/nine-cups-start.md delete mode 100644 .changeset/seven-days-nail.md delete mode 100644 .changeset/social-cycles-stare.md diff --git a/.changeset/brave-eagles-hide.md b/.changeset/brave-eagles-hide.md deleted file mode 100644 index 90a921b39..000000000 --- a/.changeset/brave-eagles-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Do not show the NavigationProgress for pages with their own loaders, like uploading files diff --git a/.changeset/dirty-rooms-doubt.md b/.changeset/dirty-rooms-doubt.md deleted file mode 100644 index 649bd24e3..000000000 --- a/.changeset/dirty-rooms-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Increase navigation progress time from 300 to 500ms diff --git a/.changeset/easy-bikes-invent.md b/.changeset/easy-bikes-invent.md deleted file mode 100644 index e15251d89..000000000 --- a/.changeset/easy-bikes-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-calculator": patch ---- - -Fixes for farm nitrogen balance to exclude nitrate leaching diff --git a/.changeset/fifty-frogs-float.md b/.changeset/fifty-frogs-float.md deleted file mode 100644 index 2f4d23a23..000000000 --- a/.changeset/fifty-frogs-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. \ No newline at end of file diff --git a/.changeset/nine-cups-start.md b/.changeset/nine-cups-start.md deleted file mode 100644 index 445f2bc0d..000000000 --- a/.changeset/nine-cups-start.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Fix that link for going back for fertilizer application modification goes back to rotation diff --git a/.changeset/seven-days-nail.md b/.changeset/seven-days-nail.md deleted file mode 100644 index 816e3f7b5..000000000 --- a/.changeset/seven-days-nail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Fix that going to Fertilizers page does not reset the selected calendar year to current year diff --git a/.changeset/social-cycles-stare.md b/.changeset/social-cycles-stare.md deleted file mode 100644 index 1bbf7e710..000000000 --- a/.changeset/social-cycles-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -At the Sentry metric for NavigationProgress include a tag for the page diff --git a/fdm-app/CHANGELOG.md b/fdm-app/CHANGELOG.md index 682fb2815..f271b5014 100644 --- a/fdm-app/CHANGELOG.md +++ b/fdm-app/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog fdm-app +## 0.28.1 + +### Patch Changes + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`ad1ebbf`](https://github.com/nmi-agro/fdm/commit/ad1ebbf3ba26a3d827d35d9c09f3d982c91bb492) Thanks [@SvenVw](https://github.com/SvenVw)! - Do not show the NavigationProgress for pages with their own loaders, like uploading files + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`4b9ebd1`](https://github.com/nmi-agro/fdm/commit/4b9ebd1f89952699c646e871731f716dc9afdefa) Thanks [@SvenVw](https://github.com/SvenVw)! - Increase navigation progress time from 300 to 500ms + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`8cc8c2e`](https://github.com/nmi-agro/fdm/commit/8cc8c2ea614f2b4351672d2dd000947cb4411660) Thanks [@SvenVw](https://github.com/SvenVw)! - Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`06fafd1`](https://github.com/nmi-agro/fdm/commit/06fafd1e67f0997f8da31ced50af3416c2dc3aab) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that link for going back for fertilizer application modification goes back to rotation + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`bb6703b`](https://github.com/nmi-agro/fdm/commit/bb6703bff65281a967c544880631a15e215903fa) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that going to Fertilizers page does not reset the selected calendar year to current year + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`c6dfd07`](https://github.com/nmi-agro/fdm/commit/c6dfd076c87daf5fab8ee4ba37aac08c1e858893) Thanks [@SvenVw](https://github.com/SvenVw)! - At the Sentry metric for NavigationProgress include a tag for the page + +- Updated dependencies [[`65ebf42`](https://github.com/nmi-agro/fdm/commit/65ebf420afd0e0d6d45dbf804a02947f6ecabc02)]: + - @nmi-agro/fdm-calculator@0.12.1 + ## 0.28.0 ### Minor Changes diff --git a/fdm-app/package.json b/fdm-app/package.json index 20c510389..5b4a2a710 100644 --- a/fdm-app/package.json +++ b/fdm-app/package.json @@ -1,6 +1,6 @@ { "name": "@nmi-agro/fdm-app", - "version": "0.28.0", + "version": "0.28.1", "private": true, "sideEffects": false, "type": "module", diff --git a/fdm-calculator/CHANGELOG.md b/fdm-calculator/CHANGELOG.md index d635aa58b..bb51ad3d4 100644 --- a/fdm-calculator/CHANGELOG.md +++ b/fdm-calculator/CHANGELOG.md @@ -1,5 +1,11 @@ # fdm-calculator +## 0.12.1 + +### Patch Changes + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`65ebf42`](https://github.com/nmi-agro/fdm/commit/65ebf420afd0e0d6d45dbf804a02947f6ecabc02) Thanks [@SvenVw](https://github.com/SvenVw)! - Fixes for farm nitrogen balance to exclude nitrate leaching + ## 0.12.0 ### Minor Changes diff --git a/fdm-calculator/package.json b/fdm-calculator/package.json index 4afd02159..f87e80fea 100644 --- a/fdm-calculator/package.json +++ b/fdm-calculator/package.json @@ -1,7 +1,7 @@ { "name": "@nmi-agro/fdm-calculator", "private": false, - "version": "0.12.0", + "version": "0.12.1", "description": "Calculate various insights based on the Farm Data Model", "license": "MIT", "homepage": "https://github.com/nmi-agro/fdm", From a70558c4b4699a4fe0840c9766403f55894f2820 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:18:56 +0100 Subject: [PATCH 17/19] refactor: implement review feedback --- .../blocks/fertilizer-applications/card.tsx | 5 +++++ .../blocks/fertilizer-applications/form.tsx | 6 +++++- .../app/components/blocks/harvest/form.tsx | 19 ++++++++++--------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/fdm-app/app/components/blocks/fertilizer-applications/card.tsx b/fdm-app/app/components/blocks/fertilizer-applications/card.tsx index f504b6e3b..624113312 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/card.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/card.tsx @@ -5,6 +5,7 @@ import { Plus } from "lucide-react" import { useEffect, useRef, useState } from "react" import { useFetcher, useLocation, useNavigation, useParams } from "react-router" import { useFieldFertilizerFormStore } from "@/app/store/field-fertilizer-form" +import { useCalendarStore } from "~/store/calendar" import { Button } from "~/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" import { @@ -75,11 +76,13 @@ export function FertilizerApplicationCard({ }, [navigation.state]) const fieldFertilizerFormStore = useFieldFertilizerFormStore() + const { calendar } = useCalendarStore() const savedFormValues = params.b_id_farm && b_id_or_b_lu_catalogue ? fieldFertilizerFormStore.load( params.b_id_farm, b_id_or_b_lu_catalogue, + calendar, ) : null @@ -98,6 +101,7 @@ export function FertilizerApplicationCard({ fieldFertilizerFormStore.delete( params.b_id_farm || "", b_id_or_b_lu_catalogue || "", + calendar, ) } }, [ @@ -139,6 +143,7 @@ export function FertilizerApplicationCard({ fieldFertilizerFormStore.delete( params.b_id_farm, b_id_or_b_lu_catalogue, + calendar, ) } diff --git a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx index 3e32a11c1..061ac8ed8 100644 --- a/fdm-app/app/components/blocks/fertilizer-applications/form.tsx +++ b/fdm-app/app/components/blocks/fertilizer-applications/form.tsx @@ -117,9 +117,13 @@ export function FertilizerApplicationForm({ }, [p_id, fertilizerApplication, form.setValue]) useEffect(() => { + const currentValue = form.getValues("p_app_date") + const { isDirty } = form.getFieldState("p_app_date") if ( !fertilizerApplication?.p_app_date && - !exampleFertilizerApplication + !exampleFertilizerApplication && + !currentValue && + !isDirty ) { form.setValue("p_app_date", getContextualDate(calendar, 3, 1)) } diff --git a/fdm-app/app/components/blocks/harvest/form.tsx b/fdm-app/app/components/blocks/harvest/form.tsx index e8cec4448..bceb83841 100644 --- a/fdm-app/app/components/blocks/harvest/form.tsx +++ b/fdm-app/app/components/blocks/harvest/form.tsx @@ -185,16 +185,17 @@ function useHarvestRemixForm({ }) // When the calendar store is populated after initial render, re-evaluate the - // default harvest date and reset the form so the catalogue default is applied. + // default harvest date, but only if the user has not already entered a value. useEffect(() => { - if (!b_lu_harvest_date && !example_b_lu_harvest_date) { - form.reset( - { - ...form.getValues(), - b_lu_harvest_date: getDefaultHarvestDate(), - }, - { keepErrors: false }, - ) + const currentValue = form.getValues("b_lu_harvest_date") + const { isDirty } = form.getFieldState("b_lu_harvest_date") + if ( + !b_lu_harvest_date && + !example_b_lu_harvest_date && + !currentValue && + !isDirty + ) { + form.setValue("b_lu_harvest_date", getDefaultHarvestDate()) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [calendar]) From 9d5050aef5f70636be638d2f1a4027ccd22f4189 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:19:25 +0100 Subject: [PATCH 18/19] Revert "chore: bump version of packages for release" This reverts commit 4a3bd508116262822d0d48b43f78eeeb3c26eec7. --- .changeset/brave-eagles-hide.md | 5 +++++ .changeset/dirty-rooms-doubt.md | 5 +++++ .changeset/easy-bikes-invent.md | 5 +++++ .changeset/fifty-frogs-float.md | 5 +++++ .changeset/nine-cups-start.md | 5 +++++ .changeset/seven-days-nail.md | 5 +++++ .changeset/social-cycles-stare.md | 5 +++++ fdm-app/CHANGELOG.md | 19 ------------------- fdm-app/package.json | 2 +- fdm-calculator/CHANGELOG.md | 6 ------ fdm-calculator/package.json | 2 +- 11 files changed, 37 insertions(+), 27 deletions(-) create mode 100644 .changeset/brave-eagles-hide.md create mode 100644 .changeset/dirty-rooms-doubt.md create mode 100644 .changeset/easy-bikes-invent.md create mode 100644 .changeset/fifty-frogs-float.md create mode 100644 .changeset/nine-cups-start.md create mode 100644 .changeset/seven-days-nail.md create mode 100644 .changeset/social-cycles-stare.md diff --git a/.changeset/brave-eagles-hide.md b/.changeset/brave-eagles-hide.md new file mode 100644 index 000000000..90a921b39 --- /dev/null +++ b/.changeset/brave-eagles-hide.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Do not show the NavigationProgress for pages with their own loaders, like uploading files diff --git a/.changeset/dirty-rooms-doubt.md b/.changeset/dirty-rooms-doubt.md new file mode 100644 index 000000000..649bd24e3 --- /dev/null +++ b/.changeset/dirty-rooms-doubt.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Increase navigation progress time from 300 to 500ms diff --git a/.changeset/easy-bikes-invent.md b/.changeset/easy-bikes-invent.md new file mode 100644 index 000000000..e15251d89 --- /dev/null +++ b/.changeset/easy-bikes-invent.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-calculator": patch +--- + +Fixes for farm nitrogen balance to exclude nitrate leaching diff --git a/.changeset/fifty-frogs-float.md b/.changeset/fifty-frogs-float.md new file mode 100644 index 000000000..2f4d23a23 --- /dev/null +++ b/.changeset/fifty-frogs-float.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. \ No newline at end of file diff --git a/.changeset/nine-cups-start.md b/.changeset/nine-cups-start.md new file mode 100644 index 000000000..445f2bc0d --- /dev/null +++ b/.changeset/nine-cups-start.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Fix that link for going back for fertilizer application modification goes back to rotation diff --git a/.changeset/seven-days-nail.md b/.changeset/seven-days-nail.md new file mode 100644 index 000000000..816e3f7b5 --- /dev/null +++ b/.changeset/seven-days-nail.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +Fix that going to Fertilizers page does not reset the selected calendar year to current year diff --git a/.changeset/social-cycles-stare.md b/.changeset/social-cycles-stare.md new file mode 100644 index 000000000..1bbf7e710 --- /dev/null +++ b/.changeset/social-cycles-stare.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-app": patch +--- + +At the Sentry metric for NavigationProgress include a tag for the page diff --git a/fdm-app/CHANGELOG.md b/fdm-app/CHANGELOG.md index f271b5014..682fb2815 100644 --- a/fdm-app/CHANGELOG.md +++ b/fdm-app/CHANGELOG.md @@ -1,24 +1,5 @@ # Changelog fdm-app -## 0.28.1 - -### Patch Changes - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`ad1ebbf`](https://github.com/nmi-agro/fdm/commit/ad1ebbf3ba26a3d827d35d9c09f3d982c91bb492) Thanks [@SvenVw](https://github.com/SvenVw)! - Do not show the NavigationProgress for pages with their own loaders, like uploading files - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`4b9ebd1`](https://github.com/nmi-agro/fdm/commit/4b9ebd1f89952699c646e871731f716dc9afdefa) Thanks [@SvenVw](https://github.com/SvenVw)! - Increase navigation progress time from 300 to 500ms - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`8cc8c2e`](https://github.com/nmi-agro/fdm/commit/8cc8c2ea614f2b4351672d2dd000947cb4411660) Thanks [@SvenVw](https://github.com/SvenVw)! - Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`06fafd1`](https://github.com/nmi-agro/fdm/commit/06fafd1e67f0997f8da31ced50af3416c2dc3aab) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that link for going back for fertilizer application modification goes back to rotation - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`bb6703b`](https://github.com/nmi-agro/fdm/commit/bb6703bff65281a967c544880631a15e215903fa) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that going to Fertilizers page does not reset the selected calendar year to current year - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`c6dfd07`](https://github.com/nmi-agro/fdm/commit/c6dfd076c87daf5fab8ee4ba37aac08c1e858893) Thanks [@SvenVw](https://github.com/SvenVw)! - At the Sentry metric for NavigationProgress include a tag for the page - -- Updated dependencies [[`65ebf42`](https://github.com/nmi-agro/fdm/commit/65ebf420afd0e0d6d45dbf804a02947f6ecabc02)]: - - @nmi-agro/fdm-calculator@0.12.1 - ## 0.28.0 ### Minor Changes diff --git a/fdm-app/package.json b/fdm-app/package.json index 5b4a2a710..20c510389 100644 --- a/fdm-app/package.json +++ b/fdm-app/package.json @@ -1,6 +1,6 @@ { "name": "@nmi-agro/fdm-app", - "version": "0.28.1", + "version": "0.28.0", "private": true, "sideEffects": false, "type": "module", diff --git a/fdm-calculator/CHANGELOG.md b/fdm-calculator/CHANGELOG.md index bb51ad3d4..d635aa58b 100644 --- a/fdm-calculator/CHANGELOG.md +++ b/fdm-calculator/CHANGELOG.md @@ -1,11 +1,5 @@ # fdm-calculator -## 0.12.1 - -### Patch Changes - -- [#495](https://github.com/nmi-agro/fdm/pull/495) [`65ebf42`](https://github.com/nmi-agro/fdm/commit/65ebf420afd0e0d6d45dbf804a02947f6ecabc02) Thanks [@SvenVw](https://github.com/SvenVw)! - Fixes for farm nitrogen balance to exclude nitrate leaching - ## 0.12.0 ### Minor Changes diff --git a/fdm-calculator/package.json b/fdm-calculator/package.json index f87e80fea..4afd02159 100644 --- a/fdm-calculator/package.json +++ b/fdm-calculator/package.json @@ -1,7 +1,7 @@ { "name": "@nmi-agro/fdm-calculator", "private": false, - "version": "0.12.1", + "version": "0.12.0", "description": "Calculate various insights based on the Farm Data Model", "license": "MIT", "homepage": "https://github.com/nmi-agro/fdm", From 7110a532bbbfe4e318a87ca3df8b11282bff8d38 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Mar 2026 17:28:39 +0000 Subject: [PATCH 19/19] chore: bump version of packages for release --- .changeset/brave-eagles-hide.md | 5 ----- .changeset/dirty-rooms-doubt.md | 5 ----- .changeset/easy-bikes-invent.md | 5 ----- .changeset/fifty-frogs-float.md | 5 ----- .changeset/nine-cups-start.md | 5 ----- .changeset/seven-days-nail.md | 5 ----- .changeset/social-cycles-stare.md | 5 ----- fdm-app/CHANGELOG.md | 19 +++++++++++++++++++ fdm-app/package.json | 2 +- fdm-calculator/CHANGELOG.md | 6 ++++++ fdm-calculator/package.json | 2 +- 11 files changed, 27 insertions(+), 37 deletions(-) delete mode 100644 .changeset/brave-eagles-hide.md delete mode 100644 .changeset/dirty-rooms-doubt.md delete mode 100644 .changeset/easy-bikes-invent.md delete mode 100644 .changeset/fifty-frogs-float.md delete mode 100644 .changeset/nine-cups-start.md delete mode 100644 .changeset/seven-days-nail.md delete mode 100644 .changeset/social-cycles-stare.md diff --git a/.changeset/brave-eagles-hide.md b/.changeset/brave-eagles-hide.md deleted file mode 100644 index 90a921b39..000000000 --- a/.changeset/brave-eagles-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Do not show the NavigationProgress for pages with their own loaders, like uploading files diff --git a/.changeset/dirty-rooms-doubt.md b/.changeset/dirty-rooms-doubt.md deleted file mode 100644 index 649bd24e3..000000000 --- a/.changeset/dirty-rooms-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Increase navigation progress time from 300 to 500ms diff --git a/.changeset/easy-bikes-invent.md b/.changeset/easy-bikes-invent.md deleted file mode 100644 index e15251d89..000000000 --- a/.changeset/easy-bikes-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-calculator": patch ---- - -Fixes for farm nitrogen balance to exclude nitrate leaching diff --git a/.changeset/fifty-frogs-float.md b/.changeset/fifty-frogs-float.md deleted file mode 100644 index 2f4d23a23..000000000 --- a/.changeset/fifty-frogs-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. \ No newline at end of file diff --git a/.changeset/nine-cups-start.md b/.changeset/nine-cups-start.md deleted file mode 100644 index 445f2bc0d..000000000 --- a/.changeset/nine-cups-start.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Fix that link for going back for fertilizer application modification goes back to rotation diff --git a/.changeset/seven-days-nail.md b/.changeset/seven-days-nail.md deleted file mode 100644 index 816e3f7b5..000000000 --- a/.changeset/seven-days-nail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -Fix that going to Fertilizers page does not reset the selected calendar year to current year diff --git a/.changeset/social-cycles-stare.md b/.changeset/social-cycles-stare.md deleted file mode 100644 index 1bbf7e710..000000000 --- a/.changeset/social-cycles-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nmi-agro/fdm-app": patch ---- - -At the Sentry metric for NavigationProgress include a tag for the page diff --git a/fdm-app/CHANGELOG.md b/fdm-app/CHANGELOG.md index 682fb2815..48169a190 100644 --- a/fdm-app/CHANGELOG.md +++ b/fdm-app/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog fdm-app +## 0.28.1 + +### Patch Changes + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Do not show the NavigationProgress for pages with their own loaders, like uploading files + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Increase navigation progress time from 300 to 500ms + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Improve DatePickers and Forms to use contextual default dates based on the selected calendar year. Forms now default to domain-specific dates (e.g., March 1st for fertilizer and cultivation-specific harvest defaults in non-current years), and DatePickers now resolve partial text entries (like "15 april") to the active calendar year instead of the current real-world year. + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that link for going back for fertilizer application modification goes back to rotation + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix that going to Fertilizers page does not reset the selected calendar year to current year + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - At the Sentry metric for NavigationProgress include a tag for the page + +- Updated dependencies [[`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189)]: + - @nmi-agro/fdm-calculator@0.12.1 + ## 0.28.0 ### Minor Changes diff --git a/fdm-app/package.json b/fdm-app/package.json index 20c510389..5b4a2a710 100644 --- a/fdm-app/package.json +++ b/fdm-app/package.json @@ -1,6 +1,6 @@ { "name": "@nmi-agro/fdm-app", - "version": "0.28.0", + "version": "0.28.1", "private": true, "sideEffects": false, "type": "module", diff --git a/fdm-calculator/CHANGELOG.md b/fdm-calculator/CHANGELOG.md index d635aa58b..bdccbf3b2 100644 --- a/fdm-calculator/CHANGELOG.md +++ b/fdm-calculator/CHANGELOG.md @@ -1,5 +1,11 @@ # fdm-calculator +## 0.12.1 + +### Patch Changes + +- [#495](https://github.com/nmi-agro/fdm/pull/495) [`9d5050a`](https://github.com/nmi-agro/fdm/commit/9d5050aef5f70636be638d2f1a4027ccd22f4189) Thanks [@SvenVw](https://github.com/SvenVw)! - Fixes for farm nitrogen balance to exclude nitrate leaching + ## 0.12.0 ### Minor Changes diff --git a/fdm-calculator/package.json b/fdm-calculator/package.json index 4afd02159..f87e80fea 100644 --- a/fdm-calculator/package.json +++ b/fdm-calculator/package.json @@ -1,7 +1,7 @@ { "name": "@nmi-agro/fdm-calculator", "private": false, - "version": "0.12.0", + "version": "0.12.1", "description": "Calculate various insights based on the Farm Data Model", "license": "MIT", "homepage": "https://github.com/nmi-agro/fdm",