Skip to content

[Ideas] Redesign Idea Canvas and unify Idea Composer with publishing composer UX #676

Description

@yacosta738

Objective

Redesign the current Ideas experience so it behaves like a real content ideation workspace rather than a generic CRUD Kanban.

The target experience is an editorial Kanban workspace optimized for capturing, developing, organizing, and turning ideas into publishable content while remaining consistent with the Profile Tailors design system and existing architecture.

The redesign has four primary outcomes:

  1. Turn the current Ideas page into a proper horizontally scrollable Kanban workspace.
  2. Replace the current Quick Capture dialog + separate detail sheet with a single Idea Composer used for both create and edit.
  3. Make Idea creation visually consistent with the existing Publishing composer without coupling Ideas directly to CreatePostModal.vue.
  4. Change Idea → Post conversion so it opens the real publishing composer prefilled from the idea instead of immediately creating a publication on the first active channel.

This is a follow-up to #158. The Ideas bounded context and core CRUD/drag-and-drop capability already exist; this issue focuses on product UX, component boundaries, and the conversion flow.


Why this exists

The current Ideas capability is functionally present, but the UX does not match the intended product workflow.

Current problems:

  • Columns are rendered as large isolated cards instead of Kanban lanes inside a workspace.
  • The page wastes horizontal and vertical space and becomes visually heavy very quickly.
  • Quick Capture is an administrative form (Title, Column, Tags) rather than a content-creation surface.
  • Creating and editing an Idea use two different interaction models.
  • Idea cards under-represent the content already available in the domain (notes, tags, links).
  • The page-level component owns too many responsibilities: board rendering, DnD, quick capture, detail editing, column configuration, delete, convert, tags and links.
  • The current Idea → Post backend conversion creates a publication immediately and automatically selects the first active channel. This bypasses the real publishing composer and prevents the user from selecting channel, media, AI assistance, hashtags, schedule and other publishing controls.

The desired mental model is:

Capture idea
    ↓
Develop idea
    ↓
Create post from idea
    ↓
Complete post in Publishing composer
    ↓
Schedule / publish

Not:

Capture idea
    ↓
Backend automatically creates publication

Current implementation reality

Reviewed against the current profiletailors.com codebase.

Ideas domain already supports

Idea
├── id
├── workspaceId
├── title
├── notes
├── tags[]
├── links[]
├── columnId
├── orderInColumn
├── convertedToPublicationId
├── createdAt
└── updatedAt

The redesign must use this existing model rather than reducing Ideas to title-only cards.

Current board capabilities already exist

  • Load workspace-scoped columns and ideas.
  • Create idea.
  • Update idea.
  • Delete idea.
  • Move/reorder ideas with @atlaskit/pragmatic-drag-and-drop.
  • Configure columns.
  • Convert idea to publication.

Current frontend implementation concern

IdeasView.vue currently owns most Ideas UI and interaction logic in one component.

The redesign should decompose the presentation into smaller components instead of layering more conditional UI into the current monolith.

Current conversion concern

The current backend ConvertIdeaHandler:

  1. Reads the Idea.
  2. Builds publication body from title + notes + tags.
  3. Finds the first active connected social account.
  4. Creates a publication immediately.
  5. Stores convertedToPublicationId.

This behavior must not remain the default UX for Create Post from an Idea.

The publishing composer must remain authoritative for:

  • target channel/account
  • post content finalization
  • media
  • AI tooling
  • hashtags
  • scheduling
  • publication creation

Product decisions

1. Ideas is a workspace, not a collection of giant cards

The Kanban should fill the available application workspace and manage its own overflow.

  • Columns are fixed-width lanes.
  • Additional columns produce horizontal board scrolling.
  • Cards within a long column scroll vertically inside the board area where practical.
  • Do not compress 5–6 columns to fit the viewport.
  • Do not make the whole application page grow indefinitely because one column contains many ideas.

Recommended desktop lane width: approximately 280–320px, adjusted to the existing design system.

2. Create and edit use one Idea Composer

Replace:

Create → Quick Capture Dialog
Edit   → Detail Sheet

with:

IdeaComposerModal
    mode = create | edit

The same content surface, hierarchy, field behavior, validation and actions should be used for both modes.

3. Idea Composer and Post Composer belong to the same UX family

Idea creation is conceptually close to post creation.

However, do not make CreatePostModal.vue branch into idea/post/editIdea/editPost modes.

Prefer extracting reusable presentation primitives where doing so reduces duplication without coupling Ideas to Publishing domain logic.

Conceptually:

                 ComposerDialogShell
                         │
               ComposerEditorSurface
                         │
          ┌──────────────┴───────────────┐
          │                              │
   IdeaComposerModal              CreatePostModal
          │                              │
      Ideas domain                 Publishing domain

Exact component names are implementation details.

4. Create Post is a handoff, not an automatic publication

Clicking Create Post from an Idea must:

  1. Persist current Idea edits if necessary.
  2. Open the real Publishing composer.
  3. Prefill post content from the Idea.
  4. Let the user select channel/account and all normal Publishing options.
  5. Create the publication only when the user explicitly submits the Publishing composer.
  6. Associate the resulting publication with the Idea after successful creation.

The implementation may introduce/refactor an Ideas application command/API for associating an existing publication with an Idea.

Do not preserve an API contract where Ideas silently chooses the first active channel and creates a publication immediately for this UX.

5. Product scope follows persisted capabilities

Do not add functionality that Profile Tailors cannot persist or support.

In particular, the current Idea model does not persist media assets. Media attachments are out of scope for this iteration unless this issue is explicitly expanded with a persisted Idea media contract.


UX specification / text mockups

The mockups define hierarchy, layout and interaction intent. They are not pixel-perfect specifications. Use existing Profile Tailors components, design tokens, typography, dark/light themes, focus states and spacing rules.

Screen 1 — Ideas Board

Route remains:

/ideas

Target structure:

┌──────────────────────────────────────────────────────────────────────────────┐
│ Ideas                                                                        │
│ Capture, develop and turn ideas into content.                                │
│                                                      [ Columns ] [ + Add Idea]│
├──────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐         │
│ │ Raw             12 │ │ In Progress      4 │ │ Done             8 │         │
│ │              +  ⋯  │ │              +  ⋯  │ │              +  ⋯  │         │
│ │                    │ │                    │ │                    │         │
│ │ ┌────────────────┐ │ │ ┌────────────────┐ │ │ ┌────────────────┐ │         │
│ │ │ Architecture   │ │ │ │ Kafka: three   │ │ │ │ Hexagonal      │ │         │
│ │ │ boundaries...  │ │ │ │ mistakes...    │ │ │ │ Architecture   │ │         │
│ │ │                │ │ │ │                │ │ │ │                │         │
│ │ │ Short excerpt  │ │ │ │ Short excerpt  │ │ │ │ Short excerpt  │         │
│ │ │ from notes...  │ │ │ │ from notes...  │ │ │ │ from notes...  │         │
│ │ │                │ │ │ │                │ │ │ │                │         │
│ │ │ #architecture  │ │ │ │ #kafka #event  │ │ │ │ #spring       │         │
│ │ │ 🔗 2           │ │ │ │ 🔗 1           │ │ │ │                │         │
│ │ └────────────────┘ │ │ └────────────────┘ │ │ └────────────────┘ │         │
│ │                    │ │                    │ │                    │         │
│ │ ┌────────────────┐ │ │                    │ │ ┌────────────────┐ │         │
│ │ │ Another idea   │ │ │                    │ │ │ Another idea   │         │
│ │ │ ...            │ │ │                    │ │ │ ...            │         │
│ │ └────────────────┘ │ │                    │ │ └────────────────┘ │         │
│ │                    │ │                    │ │                    │         │
│ │ + New idea         │ │ + New idea         │ │ + New idea         │         │
│ └────────────────────┘ └────────────────────┘ └────────────────────┘         │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

Board layout rules

  • Board uses available horizontal workspace.
  • Columns are lanes, not isolated full-height cards floating over the decorative background.
  • Lane header remains visible while scanning the lane where practical.
  • Horizontal board overflow is owned by the board.
  • A large number of cards must not force unrelated app-shell content to scroll excessively.
  • Preserve drag-and-drop between columns and within a column.
  • Provide clear drag affordance and drop feedback without adding visual noise.

Screen 2 — Idea Card

┌──────────────────────────────┐
│ Event-Driven con Kafka:      │
│ errores que cuestan caro     │
│                              │
│ Tres errores recurrentes     │
│ que terminan afectando...    │
│                              │
│ #kafka  #architecture        │
│                              │
│ 🔗 2                         │
└──────────────────────────────┘

Card hierarchy

  1. Title — primary content.
  2. Notes excerpt — only if notes exist; clamp to a small number of lines.
  3. Tags — show a bounded number, e.g. #kotlin #testing +3.
  4. Links count — only if links exist.
  5. Converted state may be shown when convertedToPublicationId exists, but it must remain visually secondary.

Do not fill cards with metadata that is not useful for scanning.

Clicking a card opens IdeaComposerModal in edit mode.


Screen 3 — Create Idea Composer

Opened from either:

  • top-level + Add Idea
  • lane-level +
  • lane-level + New idea

When opened from a lane, that lane is the default selected column.

┌────────────────────────────────────────────────────────────────────┐
│ Create Idea                                                     × │
│                                                                    │
│                              [ Raw ▾ ]   [ Tags ▾ ]                │
│                                                                    │
│ Give your idea a title                                             │
│                                                                    │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Architecture Hexagonal: tres errores que todos cometen         │ │
│ └────────────────────────────────────────────────────────────────┘ │
│                                                                    │
│ Develop your idea                                                  │
│                                                                    │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │                                                              │ │
│ │ Empieza explicando por qué la arquitectura hexagonal...       │ │
│ │                                                              │ │
│ │                                                              │ │
│ │                                                              │ │
│ │                                                              │ │
│ │                                                              │ │
│ ├────────────────────────────────────────────────────────────────┤ │
│ │  🔗 Add link                  ✨ AI Assistant                  │ │
│ └────────────────────────────────────────────────────────────────┘ │
│                                                                    │
│                                      [ Create Post ] [ Save Idea ] │
└────────────────────────────────────────────────────────────────────┘

Create behavior

  • title is required.
  • notes maps to the main idea-development surface.
  • column selection is available but visually secondary.
  • tags should use a proper chip/popover/select UX rather than a raw comma-separated text field where practical.
  • links should use structured add/remove interactions rather than a newline-delimited raw parser in the UI.
  • Save Idea persists and closes on success.
  • Create Post must first ensure the Idea exists, then transition to the Publishing composer.

AI Assistant

An AI affordance may be surfaced only if it can cleanly reuse an existing supported AI capability without coupling Ideas directly to Publishing implementation details.

If that boundary is not ready, AI support may be deferred without blocking the redesign.


Screen 4 — Edit Idea Composer

Same component and visual language as Create.

┌────────────────────────────────────────────────────────────────────┐
│ Edit Idea                                                       × │
│                                                                    │
│                         [ In Progress ▾ ]   [ Tags ▾ ]             │
│                                                                    │
│ Title                                                              │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Event-Driven con Kafka: errores que cuestan caro               │ │
│ └────────────────────────────────────────────────────────────────┘ │
│                                                                    │
│ Content                                                            │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Tres errores recurrentes...                                   │ │
│ │                                                              │ │
│ │ ...                                                          │ │
│ ├────────────────────────────────────────────────────────────────┤ │
│ │ 🔗 2 links                     ✨ AI Assistant                 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│                                                                    │
│ [ Delete ]                         [ Create Post ] [ Save Changes ] │
└────────────────────────────────────────────────────────────────────┘

Edit behavior

  • Save Changes updates the current Idea.
  • changing column from the composer updates the Idea state consistently with the board.
  • delete requires explicit confirmation.
  • Create Post performs the composer handoff defined below.

Screen 5 — Idea → Post transition

IDEAS BOARD

┌───────────────────┐
│ Kafka post idea   │
│ #kafka #backend   │
└─────────┬─────────┘
          │ click
          ▼
┌────────────────────────────────────────────┐
│ Edit Idea                                  │
│                                            │
│ Kafka post idea                            │
│ Explain back-pressure...                   │
│                                            │
│               [Create Post] [Save Changes] │
└───────────────────┬────────────────────────┘
                    │ Create Post
                    ▼
┌──────────────────────────────────────────────────────────┐
│ Create Post                                              │
│                                                          │
│ [Channel selector]                                       │
│                                                          │
│ Kafka post idea                                          │
│                                                          │
│ Explain back-pressure...                                 │
│                                                          │
│ [media] [AI] [hashtags]                                  │
│                                                          │
│                                Schedule / Publish controls│
└──────────────────────────────────────────────────────────┘

Prefill mapping

At minimum:

Idea.title
+ blank line
+ Idea.notes
+ optional tags representation
        ↓
Publishing composer initial content

The final mapping should avoid duplicating hashtags if the Idea notes already contain them.

The Publishing composer remains authoritative after handoff.

After publication creation

On successful publication creation:

  • associate the created publicationId with the source Idea.
  • update convertedToPublicationId or its successor contract.
  • do not delete the Idea automatically.
  • do not move the Idea to a different column automatically unless that behavior is explicitly added later.

Screen 6 — Empty column

┌────────────────────┐
│ In Progress      0 │
│              +  ⋯  │
│                    │
│ No ideas yet.      │
│                    │
│ + Add idea         │
└────────────────────┘

The empty state must remain useful without becoming visually dominant.


Screen 7 — Loading state

Do not replace the whole application shell with a generic spinner.

Preferred behavior:

Ideas
Capture, develop and turn ideas into content.

[ skeleton lane ] [ skeleton lane ] [ skeleton lane ]

Board geometry should remain stable while data loads.


Column management

Existing configurable columns remain supported.

Each lane header should provide clear creation affordances:

Raw   12                        +   ⋯

The top-level Columns action remains the canonical board-configuration entry point for this iteration.

Do not duplicate every column-management feature into the lane menu unless doing so removes complexity rather than adding it.

Existing requirements remain:

  • minimum one column
  • add column
  • rename column
  • reorder columns
  • delete column according to existing backend semantics
  • preserve ideas when a configured column is removed according to the current fallback behavior

Drag-and-drop UX

Preserve current functionality while improving visual feedback.

Required states:

Idle
  ↓
Pointer/focus identifies draggable card
  ↓
Drag starts
  ↓
Card visually lifts / source becomes distinguishable
  ↓
Valid target lane/card provides insertion feedback
  ↓
Drop
  ↓
Optimistic board update
  ↓
Persist
     ├── success → keep state
     └── failure → rollback + visible error

Do not make the entire card depend on an invisible drag interaction. Cards must remain clickable/editable.

Keyboard accessibility must not regress.


Component direction

The implementation should move away from the current single-component concentration.

A reasonable decomposition is:

ideas/presentation/
├── IdeasView.vue
├── IdeaBoard.vue
├── IdeaLane.vue
├── IdeaCard.vue
├── IdeaComposerModal.vue
├── IdeaTagsControl.vue
├── IdeaLinksControl.vue
└── ColumnSettingsDialog.vue

Exact names are not contractual.

Responsibilities should be separated so that:

  • board layout does not own composer form logic
  • a lane does not own Ideas API calls
  • cards do not own mutation orchestration
  • create/edit use the same composer implementation
  • Publishing-specific logic remains outside the Ideas presentation module

For shared composer UI, extract only primitives that are genuinely domain-neutral.


Idea → Publication application boundary

The current POST /api/ideas/{id}/convert semantics are not suitable for the desired interactive flow because they immediately create a publication.

The implementation should establish a clearer boundary. One acceptable shape is:

Idea
  │
  │ Create Post
  ▼
Frontend maps Idea → Publishing composer draft
  │
  ▼
User completes Publishing flow
  │
  ▼
Publication created
  │
  ▼
Associate publicationId with Idea

The exact API may differ, but these invariants are required:

  • no social account is silently chosen by Ideas
  • no publication is created before explicit Publishing-composer submission
  • the source Idea remains identifiable during the handoff
  • the final publication association is persisted
  • failed/cancelled Publishing flow does not incorrectly mark the Idea as converted

Accessibility and interaction requirements

  • Modal uses an accessible dialog primitive or equivalent correct semantics.
  • Focus is trapped while composer is open.
  • Escape closes when it is safe to do so.
  • Closing with unsaved changes must not silently discard meaningful user input.
  • All form controls have programmatic labels.
  • Tags and column selectors are keyboard-operable.
  • Drag-and-drop must preserve a usable non-pointer interaction path.
  • Visible focus states use existing design tokens.
  • Board and composer must work in supported light/dark themes.
  • Mobile/narrow viewport behavior must not introduce horizontal application-shell overflow.

Acceptance Criteria

  1. /ideas renders an editorial Kanban workspace rather than three oversized isolated cards.
  2. Columns use a consistent fixed/minimum width and the board owns horizontal overflow.
  3. A long column does not make unrelated application-shell content grow indefinitely.
  4. Existing within-column reorder continues to work.
  5. Existing cross-column movement continues to work.
  6. Failed move persistence rolls the optimistic state back and surfaces an error.
  7. Idea cards render the title prominently.
  8. Idea cards render a bounded notes excerpt when notes exist.
  9. Idea cards render a bounded set of tags and collapse excess tags into a compact count.
  10. Idea cards render a link count only when links exist.
  11. Clicking an Idea card opens the unified Idea Composer in edit mode.
  12. Top-level Add Idea opens the unified Idea Composer in create mode.
  13. Lane-level add actions open the same composer with that lane preselected.
  14. Quick Capture and the old separate detail-sheet editing model are removed from the primary UX.
  15. Create and Edit share the same composer form component and validation behavior.
  16. Idea title is required.
  17. Idea notes/content can be created and edited from the composer.
  18. Column can be changed from the composer.
  19. Tags use a structured interaction rather than requiring users to understand comma-separated storage syntax.
  20. Links use structured add/remove interaction rather than newline parsing as the primary UX.
  21. Delete from edit mode requires explicit confirmation.
  22. Save actions prevent duplicate submission and expose loading/error/success state.
  23. Create Post from a new unsaved Idea first persists enough Idea state to establish a source Idea.
  24. Create Post opens the real Publishing composer.
  25. Publishing composer content is prefilled from the Idea.
  26. Publishing composer remains responsible for channel/account selection.
  27. Publishing composer remains responsible for media, AI, hashtags and scheduling capabilities already supported there.
  28. Ideas does not automatically choose the first active channel during this interactive handoff.
  29. No publication is created until the user explicitly submits the Publishing composer.
  30. Cancelling the Publishing composer does not mark the Idea as converted.
  31. Successful publication creation is associated with the source Idea.
  32. The source Idea is not automatically deleted after publication creation.
  33. The source Idea is not automatically moved to another lane unless a future explicit rule introduces that behavior.
  34. Existing column configuration capability continues to work.
  35. At least one column remains required.
  36. Current workspace scoping is preserved.
  37. Existing Ideas authorization boundaries are preserved.
  38. The new presentation is covered by component/integration tests.
  39. Critical create/edit/move/convert-handoff paths are covered by Playwright E2E tests.
  40. Existing Ideas tests are updated rather than bypassed or broadly deleted.
  41. No media-attachment capability is added to Ideas without a persisted domain/API contract.
  42. No external product or competitor branding/references appear in production UI, code comments, acceptance copy, or user-facing documentation introduced by this issue.

Gherkin scenarios

Feature: Ideas board workspace

  Scenario: Render ideas as Kanban lanes
    Given the user has an active workspace
    And the workspace has configured idea columns
    When the user opens the Ideas page
    Then each configured column should be rendered as a Kanban lane
    And each lane should display its idea count
    And the board should own horizontal overflow when all lanes do not fit

  Scenario: A long lane owns its content overflow
    Given a lane contains many ideas
    When the Ideas board is displayed
    Then the application shell should not grow indefinitely because of that lane
    And the lane or board content region should remain independently navigable

  Scenario: Move an idea between lanes
    Given an idea exists in the Raw lane
    When the user moves it to In Progress
    Then the board should optimistically show it in In Progress
    And the new position should be persisted

  Scenario: Roll back a failed move
    Given an idea move is performed optimistically
    When persistence fails
    Then the idea should return to its previous lane and position
    And the user should see an error
Feature: Unified Idea Composer

  Scenario: Create an idea from the page action
    Given the user is on the Ideas page
    When the user selects Add Idea
    Then the Idea Composer should open in create mode
    And the first configured lane should be selected by default

  Scenario: Create an idea from a lane
    Given the user is viewing the In Progress lane
    When the user selects Add Idea from that lane
    Then the Idea Composer should open in create mode
    And In Progress should be selected by default

  Scenario: Edit an existing idea
    Given an idea already exists
    When the user selects its card
    Then the same Idea Composer should open in edit mode
    And the existing title, notes, tags, links and column should be populated

  Scenario: Prevent empty idea title
    Given the Idea Composer is open
    And the title is empty
    When the user attempts to save
    Then the idea should not be submitted
    And a validation error should be presented

  Scenario: Confirm deletion
    Given the user is editing an existing idea
    When the user selects Delete
    Then an explicit destructive confirmation should be required
    And cancelling the confirmation should preserve the idea
Feature: Create a post from an idea

  Scenario: Open Publishing composer from a saved idea
    Given an existing idea has a title and notes
    When the user selects Create Post
    Then the Publishing composer should open
    And its initial content should be derived from the idea
    And no publication should have been created yet

  Scenario: Choose publishing target explicitly
    Given the Publishing composer was opened from an idea
    When the composer is displayed
    Then the user should choose or confirm the publishing account using the normal Publishing flow
    And Ideas should not silently select a social account on the user's behalf

  Scenario: Cancel post creation
    Given the Publishing composer was opened from an idea
    When the user cancels the composer without creating a publication
    Then the idea should remain available
    And it should not be marked as converted

  Scenario: Associate successful publication
    Given the Publishing composer was opened from an idea
    When the user successfully creates the publication
    Then the resulting publication ID should be associated with the source idea
    And the idea should remain on the board

Out of scope

Unless explicitly expanded later:

  • persisted media attachments on Ideas
  • Gallery view for Ideas
  • Templates/Feeds sub-navigation
  • AI-generated idea campaigns
  • automatic movement to Done after creating a publication
  • automatic deletion/archive after creating a publication
  • multi-publication relationship per Idea
  • collaborative comments
  • assignments
  • due dates
  • approval workflow
  • analytics for Idea conversion
  • new social providers
  • redesign of the Publishing composer beyond extracting genuinely reusable presentation primitives

Definition of Done

The issue is complete when:

  1. The Kanban workspace is visually coherent and manages its own overflow.
  2. Create and edit use one Idea Composer.
  3. Existing domain data (notes, tags, links) is meaningfully represented in the UI.
  4. Idea → Post is an explicit handoff to the real Publishing composer.
  5. Publishing remains authoritative for publication creation.
  6. The source Idea is correctly associated after successful publication creation.
  7. Existing board/column functionality remains intact.
  8. Accessibility and responsive behavior are verified.
  9. Unit/component/integration tests pass.
  10. Playwright covers the critical user journeys.
  11. No unsupported functionality is presented as if it exists.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:frontendChanges in frontend marketing site (apps/web/marketing/**)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions