Skip to content

feat: add board preset templates for status list columns#161

Merged
ryota-murakami merged 1 commit intomainfrom
feat/board-preset-templates
Mar 2, 2026
Merged

feat: add board preset templates for status list columns#161
ryota-murakami merged 1 commit intomainfrom
feat/board-preset-templates

Conversation

@ryota-murakami
Copy link
Contributor

@ryota-murakami ryota-murakami commented Mar 2, 2026

Summary

  • Add 6 board preset templates (Software Release, Web App, Electron Desktop, CLI Tool, Mobile, macOS) for selecting column layouts when creating a new board
  • Radio card grid UI with color-coded column previews on /boards/new
  • Web App preset selected by default; existing boards and createFirstBoardIfNeeded unaffected (still uses Software Release columns)

Changes

New Files

  • src/lib/constants/board-presets.ts — Preset definitions (shared by client + server)
  • src/components/ui/radio-group.tsx — shadcn/ui RadioGroup primitive
  • src/app/boards/new/PresetSelector.tsx — Radio card grid component

Modified Files

  • src/lib/validations/board.ts — Added presetIdSchema Zod enum
  • src/lib/actions/board.ts — Added createStatusListsFromPreset(), updated createBoard(name, presetId?) signature
  • src/app/boards/new/CreateBoardForm.tsx — Preset state + PresetSelector integration
  • src/app/boards/new/page.tsx — Wider container, updated subtitle
  • src/app/boards/new/CreateBoardForm.stories.tsx — Wider decorator
  • e2e/logged-in/create-board.spec.ts — 3 new preset selection tests

Test plan

  • TypeScript typecheck passes
  • ESLint passes (0 warnings)
  • Unit/Storybook tests pass (91 suites, 1290 tests)
  • Build passes
  • E2E create-board tests pass (11/11 including 3 new preset tests)
  • Manual: /boards/new shows Web App preset pre-selected
  • Manual: Click each preset — column preview updates correctly
  • Manual: Create board with different presets — correct columns created
  • Manual: Keyboard nav (Tab + arrow keys) between presets
  • Manual: Dark theme rendering

Summary by CodeRabbit

Release Notes

  • New Features

    • Added board template selection during board creation. Users can now choose from multiple preset templates, each with pre-configured columns and colors.
  • Tests

    • Added comprehensive test coverage for template selection and preset validation.
  • Chores

    • Updated dependencies to support new template selection UI component.

Add 6 platform-based preset templates (Web App, Electron, CLI, Mobile,
macOS, Software Release) selectable via radio card grid on /boards/new.
Replaces hardcoded default columns with a shared preset system.
@vercel
Copy link
Contributor

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gitbox Building Building Preview, Comment Mar 2, 2026 6:33pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Introduces a board preset system allowing users to select from multiple pre-configured templates during board creation. Adds new UI components with Radix UI radio buttons, backend functions for preset-based status list creation, preset constants and validation, and E2E tests validating the selection workflow.

Changes

Cohort / File(s) Summary
Preset UI Components
src/app/boards/new/PresetSelector.tsx, src/components/ui/radio-group.tsx, src/app/boards/new/CreateBoardForm.tsx
New PresetSelector component rendered as a radio group grid displaying 6 preset options with labels, descriptions, and color-coded columns. Updated CreateBoardForm to manage presetId state and pass it to createBoard action. Added Radix UI radio group wrapper components (RadioGroup, RadioGroupItem).
Page & Form Styling
src/app/boards/new/page.tsx, src/app/boards/new/CreateBoardForm.stories.tsx
Container width increased from w-150 to w-200 in stories. Page layout expanded from max-w-lg to max-w-2xl. Copy updated from "choose a theme" to "choose a template".
Preset System Constants & Validation
src/lib/constants/board-presets.ts, src/lib/validations/board.ts
New preset definitions with PresetId type, PRESET_IDS constant, DEFAULT_PRESET_ID ('web-app'), BOARD_PRESETS mapping, and getPresetById utility. Added presetIdSchema validation using Zod enum.
Backend Board Actions
src/lib/actions/board.ts
Updated createBoard signature to accept optional presetId parameter. Added createStatusListsFromPreset function to generate status lists from preset column definitions. Added createDefaultStatusLists helper. Modified board creation flow to use preset-based list generation instead of hard-coded defaults.
Dependencies
package.json
Added @radix-ui/react-radio-group ^1.3.8 to dependencies.
E2E Tests
e2e/logged-in/create-board.spec.ts
New Preset Selection test suite validating Web App preset pre-selection, visibility of 6 preset cards, switching to CLI Tool preset, and related column header visibility (Command, Linter).

Sequence Diagram

sequenceDiagram
    actor User
    participant CreateBoardForm
    participant PresetSelector
    participant Board Action
    participant Database

    User->>CreateBoardForm: Load create board page
    CreateBoardForm->>PresetSelector: Render with DEFAULT_PRESET_ID
    PresetSelector-->>User: Display 6 preset options (Web App selected)
    
    User->>PresetSelector: Click CLI Tool preset
    PresetSelector->>CreateBoardForm: onChange(cli-tool)
    CreateBoardForm->>CreateBoardForm: Update presetId state
    PresetSelector-->>User: Highlight CLI Tool, show Command/Linter columns

    User->>CreateBoardForm: Submit form with name & presetId
    CreateBoardForm->>Board Action: createBoard(name, presetId: cli-tool)
    
    Board Action->>Board Action: Validate presetId via presetIdSchema
    Board Action->>Board Action: getPresetById(cli-tool)
    Board Action->>Board Action: createStatusListsFromPreset(boardId, preset)
    
    Board Action->>Database: Insert board & status lists (Command, Linter columns)
    Database-->>Board Action: Success
    Board Action-->>User: Board created with CLI Tool preset columns
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🎨 Six templates bloom in preset grace,
Radio buttons guide your space,
Web App, CLI—take your pick,
Board creation, oh so quick! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main feature: adding board preset templates for status list columns, which aligns with the primary objective and all substantial changes in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/board-preset-templates

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/actions/board.ts (1)

517-533: ⚠️ Potential issue | 🟠 Major

Prevent partial board creation when preset list insertion fails.

If board insert succeeds and createStatusListsFromPreset fails, the action returns failure but leaves a created board behind. Add compensation (or transaction/RPC) to keep writes atomic.

🛠️ Suggested rollback guard
     if (error || !data) {
       throw new Error('Failed to create board')
     }

-    // Create status lists from selected preset
-    await createStatusListsFromPreset(data.id, presetValidation.data)
+    // Create status lists from selected preset
+    try {
+      await createStatusListsFromPreset(data.id, presetValidation.data)
+    } catch (statusListError) {
+      Sentry.captureException(statusListError, {
+        extra: {
+          context: 'Create board: rollback after preset status list failure',
+          boardId: data.id,
+          presetId: presetValidation.data,
+        },
+      })
+
+      await supabase.from('board').delete().eq('id', data.id).eq('user_id', user.id)
+      throw new Error('Failed to initialize board')
+    }

     return { id: data.id, name: data.name }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/actions/board.ts` around lines 517 - 533, The board creation
currently inserts into supabase then calls createStatusListsFromPreset(data.id)
which, if it fails, leaves an orphaned board; modify createBoard flow to make
the write atomic by either using a Supabase/RPC transaction to perform both the
board insert and status-list inserts server-side, or add a rollback guard: after
the .insert().select(...).single() success, call
createStatusListsFromPreset(data.id, presetValidation.data) inside a try/catch
and on any error call a compensating delete of the newly created board (e.g.,
delete from 'board' where id = data.id) before rethrowing the error; reference
the existing insert block that creates the board and the
createStatusListsFromPreset call to locate where to add the transaction or
try/catch + delete.
🧹 Nitpick comments (1)
src/lib/constants/board-presets.ts (1)

28-31: Tighten BoardPreset.id to PresetId for compile-time consistency.

Using string here weakens the contract and allows silent drift between PRESET_IDS and preset objects. Reuse PresetId on the interface.

♻️ Suggested refactor
 export interface BoardPreset {
   /** Unique identifier (kebab-case) */
-  id: string
+  id: PresetId

As per coding guidelines, "Prefer reusing existing types over creating new ones".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/constants/board-presets.ts` around lines 28 - 31, Update the
BoardPreset interface so its id property uses the existing PresetId type instead
of a plain string: change BoardPreset.id: string to BoardPreset.id: PresetId,
and import or reference PresetId from its declaration to ensure compile-time
consistency with PRESET_IDS and other preset objects; then run a quick compile
to fix any callsites that rely on string (adjust types where needed) so all
preset objects and PRESET_IDS remain type-aligned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/lib/actions/board.ts`:
- Around line 517-533: The board creation currently inserts into supabase then
calls createStatusListsFromPreset(data.id) which, if it fails, leaves an
orphaned board; modify createBoard flow to make the write atomic by either using
a Supabase/RPC transaction to perform both the board insert and status-list
inserts server-side, or add a rollback guard: after the
.insert().select(...).single() success, call
createStatusListsFromPreset(data.id, presetValidation.data) inside a try/catch
and on any error call a compensating delete of the newly created board (e.g.,
delete from 'board' where id = data.id) before rethrowing the error; reference
the existing insert block that creates the board and the
createStatusListsFromPreset call to locate where to add the transaction or
try/catch + delete.

---

Nitpick comments:
In `@src/lib/constants/board-presets.ts`:
- Around line 28-31: Update the BoardPreset interface so its id property uses
the existing PresetId type instead of a plain string: change BoardPreset.id:
string to BoardPreset.id: PresetId, and import or reference PresetId from its
declaration to ensure compile-time consistency with PRESET_IDS and other preset
objects; then run a quick compile to fix any callsites that rely on string
(adjust types where needed) so all preset objects and PRESET_IDS remain
type-aligned.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04852e4 and 54ed200.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !pnpm-lock.yaml
📒 Files selected for processing (10)
  • e2e/logged-in/create-board.spec.ts
  • package.json
  • src/app/boards/new/CreateBoardForm.stories.tsx
  • src/app/boards/new/CreateBoardForm.tsx
  • src/app/boards/new/PresetSelector.tsx
  • src/app/boards/new/page.tsx
  • src/components/ui/radio-group.tsx
  • src/lib/actions/board.ts
  • src/lib/constants/board-presets.ts
  • src/lib/validations/board.ts

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 85.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.45%. Comparing base (04852e4) to head (54ed200).

Files with missing lines Patch % Lines
src/lib/constants/board-presets.ts 60.00% 2 Missing ⚠️
src/app/boards/new/CreateBoardForm.tsx 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #161      +/-   ##
==========================================
+ Coverage   69.37%   69.45%   +0.08%     
==========================================
  Files         155      157       +2     
  Lines        4696     4715      +19     
  Branches     1259     1262       +3     
==========================================
+ Hits         3258     3275      +17     
- Misses       1415     1417       +2     
  Partials       23       23              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

🧪 E2E Coverage Report (Sharded: 12 parallel jobs)

Metric Coverage
Lines 93.84%
Functions 18.79%
Branches 18.34%
Statements 31.72%

📊 Full report available in workflow artifacts

@ryota-murakami ryota-murakami merged commit 65e6bb8 into main Mar 2, 2026
20 checks passed
@ryota-murakami ryota-murakami deleted the feat/board-preset-templates branch March 2, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants