fix(web): restore PM wizard styling regression from specs 010-012#1152
Merged
zbigniewsobiecki merged 5 commits intodevfrom Apr 18, 2026
Merged
fix(web): restore PM wizard styling regression from specs 010-012#1152zbigniewsobiecki merged 5 commits intodevfrom
zbigniewsobiecki merged 5 commits intodevfrom
Conversation
SSR-safe `<select>` wrapper matching shadcn SelectTrigger's utility
classes — shadcn's radix-based Select breaks renderToStaticMarkup,
so the PM wizards need a plain styled select they can use in
createElement paths.
DataProps is a tiny index-signature widener restoring the
`[key: \`data-\${string}\`]: unknown` shape that @types/react 19.1
dropped from HTMLAttributes — it's needed so createElement(Button,
{ 'data-action': 'x' }) typechecks under strict mode.
Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Moved the previously cross-file-imported CopyButton from integration-scm-tab.tsx into its own primitive under ui/copy-button.tsx. The alerting tab and PM webhook adapters now import from the canonical location instead of reaching into a sibling tab module. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Swap raw <input>, <button>, <select>, <label> elements — all of which shipped with pm-wizard-* BEM class names that have zero CSS definitions anywhere — to shadcn Input/Button/NativeSelect/Label + Tailwind utility classes across the seven shared StandardStepKind components. The Linear API-key password field was invisible on the dark theme because the raw <input> had no border, no padding, and browser-default transparent background. Status/label/custom-field selects were borderless. Credentials verify button and Create-label button were unstyled. This commit brings them back to the legacy pre-spec-010/3 visual baseline without touching SSR-level behavior. SSR tests in tests/unit/web/steps/ were loosened to match shadcn's attribute-order-agnostic output and to walk by prop id rather than raw element tag. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Swap raw <button>, <select>, <label>, <input> elements to shadcn primitives + Tailwind utility classes across the Trello, JIRA, and Linear webhook-step adapters plus the JIRA issue-type step. Visible fix: active-webhooks list now has bordered rows, delete button is a real ghost-icon Button with a Trash2 icon, Create Webhook is a primary Button with a spinner during creation, the curl fallback sits inside a styled <details>/<summary> block, and the Linear info banner uses the themed blue surface from the legacy component instead of raw divs. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
New regression test walks every .tsx under pm-providers/** and fails
CI if any file contains createElement('input'|'button'|'select'|'label')
or <input/<button/<select/<label in JSX. Comments are stripped before
matching to avoid false positives on JSDoc prose.
This is the structural guard that was missing when specs 010/3, 011,
and 012 silently stripped the PM wizard styling — root tsc and SSR
tests passed because neither asserts visual output.
Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
zbigniewsobiecki
added a commit
that referenced
this pull request
Apr 18, 2026
Eight new tests, one per (provider × scenario) combo. Fresh setup → false; edit with stored creds + empty API-key → true; edit with re-typed API-key → false; edit without stored creds → false. Locks in the #1152-follow-up contract that stored-creds-aware mutations route through projectId instead of throwing "Missing credentials". Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
zbigniewsobiecki
added a commit
that referenced
this pull request
Apr 18, 2026
* fix(pm-wizard): route edit-mode mutations through projectId buildEditState intentionally leaves raw API credentials blank when re-opening an existing integration (security), but the verify, create-label, and create-custom-field hooks required form-state credentials and threw "Missing credentials or team selection" client-side before reaching the backend. The discovery hooks already had the projectId fallback — now the mutation hooks do too. Introduces shouldUseStoredCredentials(state) in pm-wizard-state.ts as the single source of truth for "send projectId vs send credentials". Each hook (useVerification, useTrello/LinearLabelCreation, useTrello/JiraCustomFieldCreation) now picks the correct path. Team / board / project-key checks stay — those come from config state, not credentials, so their error messages are split out. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com> * fix(pm-wizard): always render Verify Connection button The gate `(!state.isEditing || !state.hasStoredCredentials || credsReady)` hid the button precisely when it was most useful — editing an existing integration with stored credentials but an empty API-key field. User had no way to test that the stored key still works. Drop the gate. Enable the button whenever credentials are ready OR the user is editing with stored credentials (backend resolves them via projectId path). Add a muted "Using stored credentials" hint when taking the stored-creds path so it's obvious what's happening. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com> * test(pm-wizard): cover shouldUseStoredCredentials edit-mode paths Eight new tests, one per (provider × scenario) combo. Fresh setup → false; edit with stored creds + empty API-key → true; edit with re-typed API-key → false; edit without stored creds → false. Locks in the #1152-follow-up contract that stored-creds-aware mutations route through projectId instead of throwing "Missing credentials". Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Specs 010/3, 011, and 012 migrated the PM wizards (Trello/JIRA/Linear) off legacy per-provider step components onto shared step components + per-provider adapters. The migration preserved structure and SSR test coverage but stripped every visual style — the new components rendered raw
<input>,<button>,<select>,<label>with BEM-style class names (pm-wizard-*) that are never defined in any CSS file anywhere.User-visible symptom: the Linear API-key input was invisible (raw
<input type="password">, no border, no padding, browser-default transparent background on the dark theme). Status/label/custom-field selects were borderless. Create/delete webhook buttons were unstyled. Linear info banner was a plain div.This PR restores shadcn primitives + Tailwind throughout the PM wizard to match the legacy baseline, and adds a regression guard so this class of bug cannot silently recur.
StandardStepKindcomponents (steps/*.tsx) and the four provider adapters ({trello,jira,linear}/webhook-step.tsx+jira/issue-type-step.tsx).NativeSelectprimitive (ui/native-select.tsx) — SSR-safe<select>wrapper matching shadcnSelectTrigger's utility classes. Can't use shadcnSelect(radix portal breaksrenderToStaticMarkup).DataPropshelper (lib/data-props.ts) — restores the[key: \data-${string}`]: unknownindex signature that@types/react19.1 dropped fromHTMLAttributes, needed socreateElement(Button, { 'data-action': 'x' })` typechecks under strict mode.CopyButtontoui/copy-button.tsx(was awkwardly cross-file-imported fromintegration-scm-tab.tsx).tests/unit/web/pm-wizard-styling-guard.test.ts) greps every.tsxunderpm-providers/**for raw HTML interactive elements and fails CI if any slip back in.5 atomic commits — reviewable each in isolation.
Test plan
npm test— 8202 / 8202 unit tests passnpm run lint— cleannpm run typecheck— cleancd web && npm run build— builds (the check that was hidden-failing before PR fix: web build + dev deploy failing on tsc strict checks #1151)npx vitest run --project unit-core tests/unit/web/pm-wizard-styling-guard.test.ts— 15 / 15 pass🤖 Generated with Claude Code