Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

A Build tab edit is lost if the page reloads or closes within a second of typing

Abierto
#598 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@richshaw ya está trabajando en esto.

Desde el 26/10/2026.

  • #669 de @richshaw — abierto

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
typescript
Área
frontend

Línea de trabajo

Start with src/components/build-shared/useBuildState.ts and its tests, especially the debounce, flushPendingSaves from #580, request sending, and unmount cleanup. Check how the Build tab tracks save status and handles pagehide and hidden visibility events. Done means pending edits are sent with keepalive: true on both events, the rail reflects waiting saves, the unmount test still passes, and the listed checks succeed.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug pipeline:ready pipeline:ux

What happens

The Build tab saves an edit 800 ms after the last keystroke (DEBOUNCE_MS and flushTimer in src/components/build-shared/useBuildState.ts). The wait is a setTimeout in the page. If the organizer reloads, closes the tab or leaves the site in that time, the timer never fires. The edit is lost, and nothing warns them. In the walkthrough, an organizer edited a slot and reloaded within about a second. The edit was gone both times they tried.

  • Every debounced save is affected: a slot's values (editCell), its spots (setCapacity), and the signup's title and description (updateSignupMeta).
  • Links inside the app are safe. Going to another tab or page unmounts the builder, and the hook's unmount cleanup sends every waiting save. A reload or a closed tab doesn't unmount React, so that cleanup never runs.
  • A save already sent can be lost too. send uses a plain fetch, which the browser can cancel as the page unloads.
  • The rail can say "Saved" over an unsent edit. "Saving…" shows only when the timer fires (withSave). "Saved" stays up for 3 s (SAVED_CLEAR_MS), so the next edit in that time still reads "Saved" for its first 800 ms. That is when someone reloads to check.

The help article says "Your changes save as you go." #504 notes the same gap for the review page.

To see it: create a signup by hand, open its slot, type in What, and reload at once. After the reload, the slot is empty.

Fix, in outline

  • Send waiting saves when the page goes away. On pagehide, and on visibilitychange to hidden (a phone can drop a tab in the background without pagehide), send every save still waiting out its debounce. #580 adds flushPendingSaves to useBuildState; call it, not a second loop over timersRef.
  • Let those requests outlive the page. Give the builder's PATCH requests keepalive: true (an option on send), so the browser finishes them after the page unloads. A slot or signup PATCH body is a few hundred bytes, well under keepalive's 64 KiB limit.
  • Show "Saving…" from the first keystroke. Mark the rail as saving when an edit starts its wait in flushTimer, not when the request starts. "Saved" then shows only when nothing is waiting.
  • No "Leave site?" prompt. With the flush, it isn't needed, and it would appear on every reload while typing.

Watch for

  • Keep the unmount flush. In-app navigation still uses it, and its test in useBuildState.test.ts must keep passing.
  • The back-forward cache. Don't use unload or beforeunload: they keep pages out of the cache in some browsers. A pagehide with persisted: true means the page may come back, so the builder must still work after it does.
  • A save refused during unload can't show its error. That's fine: the next load shows what the server holds.
  • Overlap with #580 and #581, which change useBuildState.ts.
  • CHANGELOG entry.

Order

After #580, which adds flushPendingSaves and tracks saves in flight in useBuildState.ts. Built on main first, this would add a second flush that #580 must then merge with.

Done when

  • A unit test: an edit waiting out its debounce is sent at once, with keepalive: true, when pagehide fires, and again when visibilitychange reports hidden.
  • A unit test: the rail shows "Saving…" as soon as an edit is made, and "Saved" only when nothing is waiting.
  • In the running app, typing in a slot's What and reloading within half a second keeps the value.
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test pass.

Found by the UX walkthrough (scenario O1) on 2026-10-24, and checked against the code on main at 4ed27a9.


Generated by Claude Code

Lenguaje dominante
TypeScript
Estrellas
19
Forks
4
Merge medio
20 h 9 min
PR fusionados (30 d)
156

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de richshaw/OpenSignup

Todos los issues de richshaw/OpenSignup

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.