Summary
In the Create Project modal, pressing Escape calls the raw onClose() (which does not reset form state) instead of the handleClose() used by every other close path. Worse, the nested cover-image / icon pickers register their own document Escape listener, so pressing Escape just to dismiss a picker tears down the entire project form and discards everything typed. Reopening then shows stale leftover values.
Severity
Medium — silent data loss during project creation.
Affected code
ui/src/components/CreateProjectModal.tsx:136 — document Escape handler calls onClose() (raw), not handleClose() (:89-100, which resets name/identifier/description/emoji/icon/cover/network/lead).
- All other close paths (backdrop
:178, X :187, Cancel :290) call handleClose.
- The nested
CoverImageModal/ProjectIconModal (shared Modal) add their own document Escape listener, with no guard like CreateWorkItemModal.tsx:332-336.
Live reproduction (verified)
- Open Add Project, type a project name ("MyImportantProjectData").
- Click Choose image to open the cover picker.
- Press Escape to dismiss the picker.
- Observed: the whole Create Project modal closes (URL drops from
?createProject=1 back to /acme/projects); typed data is lost.
- Reopen Add Project.
- Observed: the Project name field still contains the stale "MyImportantProjectData" (state was never reset because Escape used raw
onClose).
Suggested fix
Call handleClose() from the Escape handler, and make it a no-op while coverModalOpen || iconModalOpen so Escape only closes the child picker.
Summary
In the Create Project modal, pressing Escape calls the raw
onClose()(which does not reset form state) instead of thehandleClose()used by every other close path. Worse, the nested cover-image / icon pickers register their own document Escape listener, so pressing Escape just to dismiss a picker tears down the entire project form and discards everything typed. Reopening then shows stale leftover values.Severity
Medium — silent data loss during project creation.
Affected code
ui/src/components/CreateProjectModal.tsx:136— document Escape handler callsonClose()(raw), nothandleClose()(:89-100, which resets name/identifier/description/emoji/icon/cover/network/lead).:178, X:187, Cancel:290) callhandleClose.CoverImageModal/ProjectIconModal(sharedModal) add their own document Escape listener, with no guard likeCreateWorkItemModal.tsx:332-336.Live reproduction (verified)
?createProject=1back to/acme/projects); typed data is lost.onClose).Suggested fix
Call
handleClose()from the Escape handler, and make it a no-op whilecoverModalOpen || iconModalOpenso Escape only closes the child picker.