diff --git a/app/admin/components/FormGridSection.tsx b/app/admin/components/FormGridSection.tsx index ca9dde1d..edc47013 100644 --- a/app/admin/components/FormGridSection.tsx +++ b/app/admin/components/FormGridSection.tsx @@ -3,7 +3,7 @@ 'use client'; -import { useState, useTransition } from 'react'; +import { useEffect, useState, useTransition } from 'react'; import { FormProvider, useForm } from '@proxy/react-hook-form-mui'; import { useRouter } from 'next/navigation'; @@ -28,7 +28,11 @@ interface FormGridSectionOwnProps { */ action: ServerAction; - // TODO: defaultValues + /** + * Default values that should be provided to the form. Can be updated while the form is visible, + * in which case all non-dirty fields will have their values updated. + */ + defaultValues?: Record; } /** @@ -48,26 +52,30 @@ export type FormGridSectionProps = * https://github.com/dohomi/react-hook-form-mui/blob/master/packages/rhf-mui/src/FormContainer.tsx */ export function FormGridSection(props: React.PropsWithChildren) { - const { action, children, ...sectionHeaderProps } = props; + const { action, children, defaultValues, ...sectionHeaderProps } = props; const [ isPending, startTransition ] = useTransition(); const [ state, setState ] = useState(); - // TODO: Provide `defaultValues` to the form. - - // TODO: Update the form with new `defaultValues` when they have changed, e.g. because the - // router has been refreshed by another update. - // TODO: Convert DayJS values to something that can be read as a ZonedDateTime on the server. - const form = useForm(); + const form = useForm({ defaultValues }); const router = useRouter(); + useEffect(() => { + form.reset(defaultValues, { + keepDirtyValues: true, + }); + }, [ defaultValues, form ]); + const handleSubmit = form.handleSubmit(async (data: unknown) => { await startTransition(async () => { const result = await action(data); if (!!result.success) { - form.reset({ /* fields */ }, { keepValues: true }); + form.reset({ /* fields */ }, { + keepDirtyValues: true, + keepValues: true, + }); if (!!result.redirect) router.push(result.redirect); diff --git a/app/admin/system/debug/DebugOptions.tsx b/app/admin/system/debug/DebugOptions.tsx index f68a87a3..947685b6 100644 --- a/app/admin/system/debug/DebugOptions.tsx +++ b/app/admin/system/debug/DebugOptions.tsx @@ -3,6 +3,8 @@ 'use client'; +import { useRouter } from 'next/navigation'; + import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; @@ -13,6 +15,8 @@ import { Section } from '@app/admin/components/Section'; * JavaScript code and event handlers. */ export function DebugOptions() { + const router = useRouter(); + const triggerJavaScriptError = () => { /// @ts-ignore callFunctionThatDoesNotExist(); @@ -22,6 +26,10 @@ export function DebugOptions() { throw new Error('Name of the exception'); }; + const refresh = () => { + router.refresh(); + }; + return (
@@ -31,6 +39,9 @@ export function DebugOptions() { +
); diff --git a/app/admin/system/debug/page.tsx b/app/admin/system/debug/page.tsx index 62765fc8..0510e69d 100644 --- a/app/admin/system/debug/page.tsx +++ b/app/admin/system/debug/page.tsx @@ -36,6 +36,11 @@ const kDebugActionScheme = z.object({ notes: z.string().optional(), }); +/** + * Refresh counter showing how often the component has ran. + */ +let globalRefreshCounter = 0; + /** * Server action that will be invoked when the form section demo has been submitted. Reflects the * submitted data back to the client after a slight delay. @@ -44,7 +49,7 @@ async function debugAction(formData: unknown) { 'use server'; return executeServerAction(formData, kDebugActionScheme, async (data, props) => { await new Promise(resolve => setTimeout(resolve, 1500)); - return { success: false, error: `Not yet implemented (${props.user?.name})` }; + return { success: true, refresh: true }; }); } @@ -62,10 +67,14 @@ export default async function DebugPage() { debugValues['Cookies'] = [ ...cookies() ]; debugValues['Headers'] = [ ...headers() ]; + const values = { + notes: `Example notes (count: ${++globalRefreshCounter})`, + }; + return ( <> - +