todo: one file per item, grouped by theme, with a generated index
TODO.md had reached 1050 lines and 72 open items across 28 sections, read mostly on a phone. It is now a directory: todo/<theme>/<item>.md, one card per file, with frontmatter carrying id, status, created date and order, and the prose body copied across verbatim. TODO.md becomes a generated index (bun run todo:index). Dates: where an item's prose stated one it is used; otherwise its old section's; otherwise 2026-08-20, floored at the day before the split rather than invented. date_source records which. Shaped for a two-way Kanban board, filed as todo/tooling — a card is a file, id is the identity, frontmatter is the machine's half and the body is the owner's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
---
|
||||
theme: inputs-outside-forms
|
||||
heading: "Inputs outside forms (2026-08-19) — swept, fixed, closed"
|
||||
kind: theme
|
||||
---
|
||||
|
||||
The "19 files" count in the previous version of this entry came from one grep
|
||||
(`components/ui/input`) and was a starting point, not the answer. A wider sweep — bare `<input>` and
|
||||
`<textarea>` too, across the platform and every installed plugin — found **87 files with a matching
|
||||
element and no enclosing `<form>`**. Three were false positives (the `Input`/`Textarea` primitives
|
||||
themselves, and a `DataTable` test file). Of the remaining 84, **41 were fixed** (real forms, single
|
||||
fields with an obvious action, or multi-field editors) and **43 were left alone**, almost all because
|
||||
they're a search/filter box with nothing to submit.
|
||||
|
||||
**Fixed — platform (24 files, one commit):** `CapabilityPage`, `ApifyConfig`, `ApiKeys`,
|
||||
`DavAppPasswords`, `GoogleOAuthConfig`, `AIHarnessesSection` (local-provider connect, its auth step,
|
||||
and both API-key edit rows), `OCRSection`, `SMTPSection` (split into two independent forms — save vs.
|
||||
send-test-email, since one form would have made Enter in the test-email field trigger Save),
|
||||
`STTSection`, `TTSSection`, `AppStoreDetail`, `ChatHeader`, `BackgroundJobDialog`, `QuestionActivity`,
|
||||
`WebpageDialog`, `DirPickerModal`, `SessionRow`, `CommandHqCategories`, `FileItem`, `NewEntryDialog`,
|
||||
`TaskRunnerModal` (the Agentic and Pipeline ready phases), `PreviewHeader`, `widgets/DailyGoals`,
|
||||
`widgets/Pomodoro`.
|
||||
|
||||
**Fixed — plugins (17 files, one commit per plugin, each pushed to its own remote):**
|
||||
`bitcoin-wallet` (`ChainSourceCard`, `RescanCard`, `WalletSettingsView`), `email` (`Compose`,
|
||||
`EmailAccounts`), `invoices` (`DocumentEditor`, `RecordEditors`, `SendDocumentDialog`), `offscale`
|
||||
(`NodesView` — rename and tags fields), `soulseek` (`SoulseekConnection`), `transmission`
|
||||
(`ConnectionView`, `SettingsView`, `AddTorrentDialog`, `MoveTorrentDialog`, `RenameDialog`,
|
||||
`TorrentOptionsDialog`), `vault` (`VaultPanel`). `jellyfin` and `music` needed no changes.
|
||||
|
||||
**Left alone — search/filter boxes with no submit action** (the large majority of the 43): `JobsPage`,
|
||||
`SettingsPanel`, `SearchInput`, `sounds/Catalog`, `widgets/QuickNotes`, `Dashboards/DashboardListApp`,
|
||||
`SystemMonitor/DockerView`, `FileBrowser*` toolbar/header/view-container files, `ChatHistory` list
|
||||
filters, `invoices`' six list views (`CustomersListView`, `EstimatesListView`, `ExpensesListView`,
|
||||
`InvoicesListView`, `ItemsListView`, `ReportsView`, `components.tsx`), `jellyfin` (`PlayerControls` —
|
||||
range sliders, not text fields — and `SearchSection`), `music` (`MusicBrowser`, `MusicPlayerHost`),
|
||||
`offscale` (`Cards`, `PolicyAssistant` — already handles Enter/Shift+Enter correctly, `PolicyView` — a
|
||||
textarea, never auto-submits), `soulseek` (`SearchResults`, `SharesBrowser`), `transmission`
|
||||
(`TorrentToolbar`), `FileViewer` renderers (`AudioRenderer`/`VideoRenderer` — volume/seek sliders), and
|
||||
the main chat composers (`InputArea`, `ChatLauncher`, `SoulseekChat`) — all textareas with their own
|
||||
Enter-sends/Shift+Enter-newlines handling, where a `<form>` would add nothing and risks regressing that
|
||||
handling.
|
||||
|
||||
**Left alone — genuinely ambiguous, flagged rather than guessed:**
|
||||
|
||||
- `TaskRunnerModal`'s `ScriptRunner` ready phase offers three simultaneously-visible, non-equivalent
|
||||
primary actions ("Run here" / "Queue" / "Run as job"); there's no single canonical action for Enter to
|
||||
trigger.
|
||||
- `Dashboards/DashboardPreview`'s `NamePanel` (name + description) has its submit button in a
|
||||
_different_, independently-mounted panel (`CreatePanel`) elsewhere in the workspace layout tree — a
|
||||
`<form>` can't span two panels without restructuring the wizard.
|
||||
- `ColorPicker` and `MarkdownEditor` have zero call sites anywhere in the repo right now; both are
|
||||
shaped to be embedded in a future caller's own form (uncontrolled inputs with `name` attributes, or a
|
||||
plain controlled textarea with no submit of its own), so there's nothing to wrap yet.
|
||||
- `widgets/Weather`'s `LocationSetup` is a live autocomplete with several result rows and no single
|
||||
obvious Enter target (which of N matches?).
|
||||
|
||||
**Noticed, out of scope, not fixed:**
|
||||
|
||||
- `ModelSelector`'s provider-picker button has no `type` attribute — harmless today only because it
|
||||
currently sits outside every `<form>`; a landmine if that layout changes.
|
||||
- `MusicBrowser`'s filter input uses `(e) =>` instead of the house `ev` convention — pre-existing, not
|
||||
touched since the file needed no fix.
|
||||
- `EmailList.tsx`, and a few plugin files touched by this sweep (`VaultPanel`, `ConnectionView`,
|
||||
`SoulseekConnection`, `ChainSourceCard`), have pre-existing `prettier --check` drift outside the lines
|
||||
this pass touched — left as found, not reformatted, per "don't reformat what you're not fixing."
|
||||
Relatedly: **`prettier --write` on a `plugins/<name>/…` path silently no-ops when run from the
|
||||
platform root**, because Prettier v3 respects the root `.gitignore` and `/plugins/*/` is in it — it
|
||||
exits 0 with no diff and no error. Formatting a plugin file requires running prettier from inside
|
||||
that plugin's own directory (still resolves the platform's `.prettierrc` by walking up).
|
||||
- A few "Save"/"I've saved it"-style buttons (`ApiKeys`, `DavAppPasswords`, `DirPickerModal`) have no
|
||||
`type` attribute but currently sit outside any `<form>`, so it's harmless today — worth remembering if
|
||||
a future edit wraps that region.
|
||||
Reference in New Issue
Block a user