diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc64a0ea..8be69ed05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project are documented in this file. The format is b installed, otherwise run the durable handlers inline in `db`'s transaction (#583). ### Changed +- Frontend: every page that posts through the Inertia router now shows a toast on failure (sharing revoke, dashboard Doctor rerun included); `useLeaveGuard` lives in `@simple-module-py/ui`, the background-tasks outbox confirms through the shared dialog instead of `window.confirm`, and `reportClientError()` is the single hook the error boundary reports through (#601). - Users: lockout, registration and bulk-invite writes that must land before the request ends now commit through `simple_module_db.independent_session` (its own short-lived session) instead of committing the request session. Failed or unverified password logins now roll @@ -71,6 +72,9 @@ All notable changes to this project are documented in this file. The format is b `file_storage.reconcile_checksums` beat task that re-enqueues checksums for files left without one for 30 minutes, up to 500 per run (#590). +### Removed +- Frontend: `@simple-module-py/ui` no longer depends on `react-hook-form`/`@hookform/resolvers`, and the unused shadcn `form` component is removed; `host/client_app` drops the unused `zod` and `date-fns` (#601). **Behaviour change** for anyone importing `@simple-module-py/ui/components/ui/form`. + ## [0.0.38] — 2026-10-23 ### Fixed diff --git a/docs/frontend/inertia.md b/docs/frontend/inertia.md index 6baf20240..cbee069e4 100644 --- a/docs/frontend/inertia.md +++ b/docs/frontend/inertia.md @@ -39,25 +39,30 @@ Breakdown: ## Responding with JSON vs. Inertia -- **`endpoints/api.py`** — returns JSON. Called by background/non-Inertia code, or by Inertia's `router.get/post` on the client (which sends `X-Inertia: true` and receives a full Inertia response, **not** raw JSON). -- **`endpoints/views.py`** — returns Inertia pages. Routed at `view_prefix`, rendered as full HTML on the first request and as JSON page updates on client-side navigation. - -The split is convention: keep GET-for-page-data calls in `views.py`, keep POST/PATCH/DELETE data mutations in `api.py` even if triggered from Inertia forms. This way JSON APIs are usable from scripts and Inertia pages route cleanly. +- **`endpoints/api.py`** returns JSON. Use the typed `createApi` client wrapped in + `apiResult` for JSON actions, and toast failed results (including network failures). +- **`endpoints/views.py`** returns Inertia pages or redirects. View-route forms use + Inertia `useForm` for data, validation errors and processing state. Small actions + without form fields may use `router.post/delete` with an `onError` toast. + Handle `onHttpException` and `onNetworkError` too when an action should toast + HTTP or connection failures; returning `false` suppresses Inertia's default handler. ## Inertia form submission -From a page, use Inertia's `router.post`: +Submit to the module's view route: ```tsx -import { router } from "@inertiajs/react"; +import { useForm } from "@inertiajs/react"; function CreateOrder() { - const [data, setData] = useState({ customer_email: "", total: "" }); + const form = useForm({ customer_email: "", total: "" }); return (