Skip to content

Commit 49654cd

Browse files
committed
docs(web): the help text stops describing a cap the filters no longer have (#666, #667)
1 parent 7e01864 commit 49654cd

6 files changed

Lines changed: 48 additions & 35 deletions

File tree

‎docs/designs/666-667-spa-date-range-filters.md‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ serialises `from`/`to`. The client, the endpoint and the repository are all read
164164
is in flight and still withheld when `meta` is null (`ExpensesPage.tsx:508-520`). Those two guards
165165
exist because a figure from the previous window under the new window's control is the defect this
166166
screen was fixed for. **Do not simplify them.**
167+
7. **`from`/`to` live in `useState`, not the URL — a deliberate choice nobody had stated.** This mirrors
168+
Feed, Water and History, which all hold their filters the same way; Audit is the outlier, and it is an
169+
outlier for a reason already on record — its own header comment made the URL the single source of truth
170+
for `action` and `entityId` before this PR touched it, so `from`/`to` joining that same source keeps one
171+
screen's existing contract rather than establishing a new one. The consequence is real and user-visible:
172+
an Audit window survives a refresh, Back, and a shared link; an Expenses window survives none of them.
173+
Recorded here so the next reader does not rediscover the asymmetry as a bug.
167174

168175
### Files
169176

@@ -238,8 +245,7 @@ clamps.
238245
**Decision: no client-side validation, and no new error state.** An inverted range renders the
239246
filtered-empty message this slice is already adding, which is a true statement about that window. Adding
240247
a bespoke "your dates are backwards" path would be a fifth code path on two screens for a state the user
241-
resolves by looking at the two controls they just set. `max={today}` is kept on both inputs on Expenses,
242-
preserving the cap the month picker had. What is *not* acceptable is the current Audit behaviour of
248+
resolves by looking at the two controls they just set. What is *not* acceptable is the current Audit behaviour of
243249
saying "No audit events yet." to a user who inverted a range — that is INV-4, and it is why the third
244250
message is required rather than optional.
245251

‎web/src/i18n/en.ts‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,7 +2828,8 @@ export const en = {
28282828
expensesHeading: "Expenses (admin)",
28292829
expensesRecording:
28302830
"Record money going out: date, category, description, and amount (in the farm's currency), optionally "
2831-
+ "tied to a flock. The date range shows a running total for the period you pick; categories are managed on the same screen "
2831+
+ "tied to a flock. The date range — the farm's own dates, not a browser clock elsewhere — shows a running "
2832+
+ "total for the period you pick; categories are managed on the same screen "
28322833
+ "(deactivating one hides it from new expenses — recorded ones keep it).",
28332834
expensesCorrections:
28342835
"Corrections edit the expense in place (<strong>correct</strong> on the row). If someone else "
@@ -2931,10 +2932,10 @@ export const en = {
29312932
farmSettingsTimezone:
29322933
"The <strong>timezone</strong> is the farm's day. Every field that records <em>when something "
29332934
+ "happened</em> — daily entry, flocks, water, feed usage and purchases, expenses, orders and payments "
2934-
+ "— opens on it and refuses to go past it, whatever day the phone or laptop in your hand is on, so a "
2935-
+ "device travelling ahead of the farm can no longer offer a date the save then refuses. Dates that are "
2936-
+ "meant to be in the future are not capped: a feed batch's <strong>expiry</strong>, and the date "
2937-
+ "ranges you filter History and Water by.",
2935+
+ "— opens on it and refuses to go past it for what you record, whatever day the phone or laptop in "
2936+
+ "your hand is on, so a device travelling ahead of the farm can no longer offer a date the save then "
2937+
+ "refuses. That cap is on recording, not on filtering: dates that are meant to be in the future are "
2938+
+ "not capped — a feed batch's <strong>expiry</strong>, and the date ranges you filter a list by.",
29382939
farmSettingsCurrency:
29392940
"The <strong>currency</strong> locks the moment the farm records its first amount — a sale, a payment, "
29402941
+ "an expense, a priced product, or money spent on feed. The field shows as locked with the reason "
@@ -3134,8 +3135,9 @@ export const en = {
31343135
+ "somewhere else. It is the same \"today\" everywhere: what counts as a future date when you record "
31353136
+ "work, when eggs leave a withdrawal period, which eggs a sale can take, the day a flock is depleted "
31363137
+ "or archived on, and the range reports open on. Every field that records WHEN SOMETHING HAPPENED "
3137-
+ "opens on it and will not go past it, whatever day the device in your hand is on. Dates meant to "
3138-
+ "fall in the future are not capped — a feed batch's expiry, and the History and Water filters.",
3138+
+ "opens on it and will not go past it, whatever day the device in your hand is on — that cap is on "
3139+
+ "recording, not on filtering. Dates meant to fall in the future are not capped — a feed batch's "
3140+
+ "expiry, and the date ranges you filter a list by.",
31393141

31403142
glossaryInstallToHomeScreenTerm: "Install to home screen",
31413143
glossaryInstallToHomeScreenDef:

‎web/src/i18n/es.ts‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,8 +2305,8 @@ export const es = {
23052305
expensesHeading: "Gastos (admin)",
23062306
expensesRecording:
23072307
"Registre el dinero que sale: fecha, categoría, descripción y monto (en la moneda de la granja), "
2308-
+ "opcionalmente vinculado a un lote. El rango de fechas muestra un total acumulado para el período "
2309-
+ "elegido; las categorías "
2308+
+ "opcionalmente vinculado a un lote. El rango de fechas — las fechas propias de la granja, no un "
2309+
+ "reloj del navegador en otro lugar — muestra un total acumulado para el período elegido; las categorías "
23102310
+ "se administran en la misma pantalla (desactivar una la oculta de los gastos nuevos — los ya "
23112311
+ "registrados la conservan).",
23122312
expensesCorrections:
@@ -2410,11 +2410,12 @@ export const es = {
24102410
farmSettingsTimezone:
24112411
"La <strong>zona horaria</strong> es el día de la granja. Cada campo que registra <em>cuándo sucedió "
24122412
+ "algo</em> — entrada diaria, lotes, agua, uso y compras de alimento, gastos, pedidos y pagos — se "
2413-
+ "abre en ella y se niega a ir más allá, sea cual sea el día en el teléfono o la laptop que tiene en "
2414-
+ "la mano, para que un dispositivo adelantado a la granja ya no pueda ofrecer una fecha que el "
2415-
+ "guardado luego rechace. Las fechas que están destinadas a estar en el futuro no tienen tope: la "
2416-
+ "<strong>caducidad</strong> de un lote de alimento, y los rangos de fechas por los que filtra "
2417-
+ "Historial y Agua.",
2413+
+ "abre en ella y se niega a ir más allá para lo que usted registra, sea cual sea el día en el "
2414+
+ "teléfono o la laptop que tiene en la mano, para que un dispositivo adelantado a la granja ya no "
2415+
+ "pueda ofrecer una fecha que el guardado luego rechace. Ese tope es sobre el registro, no sobre el "
2416+
+ "filtrado: las fechas que están destinadas a estar en el futuro no tienen tope — la "
2417+
+ "<strong>caducidad</strong> de un lote de alimento, y los rangos de fechas por los que filtra una "
2418+
+ "lista.",
24182419
farmSettingsCurrency:
24192420
"La <strong>moneda</strong> se bloquea en el momento en que la granja registra su primer monto — una "
24202421
+ "venta, un pago, un gasto, un producto con precio, o dinero gastado en alimento. El campo se "
@@ -2615,9 +2616,9 @@ export const es = {
26152616
+ "fecha futura al registrar trabajo, cuándo salen los huevos de un período de retiro, qué huevos "
26162617
+ "puede tomar una venta, el día en que se agota o archiva un lote, y el rango en que se abren los "
26172618
+ "informes. Todo campo que registra CUÁNDO OCURRIÓ ALGO se abre en ese día y no permite ir más "
2618-
+ "allá, sin importar en qué día esté el dispositivo que tiene en la mano. Las fechas que deben caer "
2619-
+ "en el futuro no tienen ese límite — el vencimiento de un lote de alimento, y los filtros de "
2620-
+ "Historial y Agua.",
2619+
+ "allá, sin importar en qué día esté el dispositivo que tiene en la mano — ese límite es sobre el "
2620+
+ "registro, no sobre el filtrado. Las fechas que deben caer en el futuro no tienen ese límite — el "
2621+
+ "vencimiento de un lote de alimento, y los rangos de fechas por los que filtra una lista.",
26212622

26222623
glossaryInstallToHomeScreenTerm: "Instalar en la pantalla de inicio",
26232624
glossaryInstallToHomeScreenDef:

‎web/src/i18n/tl.ts‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,8 +2393,8 @@ export const tl = {
23932393
expensesHeading: "Mga Gastos (admin)",
23942394
expensesRecording:
23952395
"Itala ang lumalabas na pera: petsa, kategorya, deskripsyon, at halaga (sa currency ng bukid), "
2396-
+ "opsyonal na naka-link sa isang kawan. Ipinapakita ng hanay ng petsa ang tumatakbong total para sa "
2397-
+ "panahong pinili mo; "
2396+
+ "opsyonal na naka-link sa isang kawan. Ipinapakita ng hanay ng petsa — ang sariling petsa ng bukid, "
2397+
+ "hindi ng orasan ng browser sa ibang lugar — ang tumatakbong total para sa panahong pinili mo; "
23982398
+ "pinapamahalaan ang mga kategorya sa parehong screen (ang pag-deactivate ng isa ay nagtatago nito "
23992399
+ "mula sa mga bagong gastos — pinapanatili ito ng mga naitala na).",
24002400
expensesCorrections:
@@ -2502,11 +2502,12 @@ export const tl = {
25022502
farmSettingsTimezone:
25032503
"Ang <strong>time zone</strong> ang araw ng bukid. Ang bawat field na nagtatala ng <em>kung kailan "
25042504
+ "nangyari ang isang bagay</em> — araw-araw na entry, kawan, tubig, paggamit at pagbili ng feed, "
2505-
+ "gastos, order at bayad — ay bumubukas dito at tumatanggi lumampas dito, anuman ang araw sa "
2506-
+ "telepono o laptop na hawak mo, para hindi na makapag-alok ang isang device na nauuna sa bukid ng "
2507-
+ "petsang tatanggihan din naman ng pag-save. Ang mga petsang nakatakdang mangyari sa hinaharap ay "
2508-
+ "walang cap: ang <strong>expiry</strong> ng isang lote ng feed, at ang mga date range na ginagamit "
2509-
+ "mo para i-filter ang History at Tubig.",
2505+
+ "gastos, order at bayad — ay bumubukas dito at tumatanggi lumampas dito para sa itinatala mo, "
2506+
+ "anuman ang araw sa telepono o laptop na hawak mo, para hindi na makapag-alok ang isang device na "
2507+
+ "nauuna sa bukid ng petsang tatanggihan din naman ng pag-save. Ang cap na iyon ay para sa "
2508+
+ "pagtatala, hindi sa pag-filter: ang mga petsang nakatakdang mangyari sa hinaharap ay walang cap "
2509+
+ "— ang <strong>expiry</strong> ng isang lote ng feed, at ang mga date range na ginagamit mo para "
2510+
+ "i-filter ang isang listahan.",
25102511
farmSettingsCurrency:
25112512
"Naka-lock ang <strong>currency</strong> sa sandaling itala ng bukid ang una nitong halaga — isang "
25122513
+ "benta, isang bayad, isang gastos, isang produktong may presyo, o perang ginastos sa feed. "
@@ -2713,9 +2714,10 @@ export const tl = {
27132714
+ "darating kapag nagtatala ka ng trabaho, kailan aalis ang itlog sa withdrawal period, kung aling "
27142715
+ "itlog ang puwedeng kunin ng isang benta, ang araw na na-deplete o na-archive ang isang kawan, at "
27152716
+ "ang range na binubuksan ng mga report. Bawat field na nagtatala kung KAILAN NANGYARI ANG ISANG "
2716-
+ "BAGAY ay nagbubukas dito at hindi ito lalagpasan, kahit anong araw ang nasa device mo. Hindi "
2717-
+ "limitado ang mga petsang dapat mahulog sa hinaharap — ang expiry ng isang batch ng feed, at ang "
2718-
+ "mga filter ng History at Tubig.",
2717+
+ "BAGAY ay nagbubukas dito at hindi ito lalagpasan, kahit anong araw ang nasa device mo — ang limitasyong "
2718+
+ "iyon ay para sa pagtatala, hindi sa pag-filter. Hindi limitado ang mga petsang dapat mahulog sa "
2719+
+ "hinaharap — ang expiry ng isang batch ng feed, at ang mga date range na ginagamit mo para "
2720+
+ "i-filter ang isang listahan.",
27192721

27202722
glossaryInstallToHomeScreenTerm: "Pag-install sa home screen",
27212723
glossaryInstallToHomeScreenDef:

‎web/src/lib/dates.test.ts‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,13 @@ const REJECTED = [
193193
"abcd-ef-gh", // non-numeric
194194
"10000-01-01", // five-digit year
195195
// Whitespace is URL-reachable: searchParams.get() decodes "+" and "%20" to a
196-
// space, so ?from=+2026-08-01 arrives as " 2026-08-01". These rows exist to
197-
// fail the tempting future edit — trim the input, or allow \s* in the regex —
198-
// which every other row in this table survives. .NET binds a padded date
199-
// fine (DateTimeStyles.AllowWhiteSpaces is the default), so a lenient client
200-
// would send a value the server accepts and the control cannot display.
196+
// space, so ?from=+2026-08-01 arrives as " 2026-08-01" and ?from=2026+-08-01
197+
// as "2026 -08-01". These rows exist to fail the tempting future edit — trim
198+
// the input, or allow \s* at the anchors — which every other row in this
199+
// table survives. What the server would do with a padded value is not
200+
// asserted here: this function's contract is that the client sends only what
201+
// the CONTROL can display, and <input type="date"> cannot display any of
202+
// these three.
201203
" 2026-08-01", // leading space, the "+" decoding
202204
"2026-08-01 ", // trailing space
203205
"2026 -08-01", // interior space

‎web/src/routes/AuditPage.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export function AuditPage() {
178178
? rawActionFilter
179179
: "";
180180

181-
// The non-scope narrowings. `entityId` is the fourth axis that can empty this
181+
// The non-scope narrowings. `entityId` is the scope axis that can empty this
182182
// view and is deliberately NOT here — it selects which of the two sentence
183183
// families applies, in the ternary below, rather than whether the view is
184184
// narrowed at all.

0 commit comments

Comments
 (0)