Skip to content

Custom Dashboard Improvements#1359

Merged
nams1570 merged 2 commits intoai-analyticsfrom
custom-dashboard-improvements
Apr 24, 2026
Merged

Custom Dashboard Improvements#1359
nams1570 merged 2 commits intoai-analyticsfrom
custom-dashboard-improvements

Conversation

@aadesh18
Copy link
Copy Markdown
Collaborator

@aadesh18 aadesh18 commented Apr 21, 2026

This PR introduces a context chip bar for the AI dashboard chat panel — users can click widgets in the sandbox iframe, trigger "Add a component", or auto-capture runtime errors as chips that are prepended to the next AI request. It also adds a patchDashboard tool for surgical find-and-replace edits alongside the existing updateDashboard, streaming dashboard generation, and an improved system prompt with hook-ordering guidance for generated components.

@aadesh18 aadesh18 self-assigned this Apr 21, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 21, 2026

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

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-backend Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-dashboard Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-demo Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-docs Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-preview-backend Ready Ready Preview, Comment Apr 21, 2026 8:02pm
stack-preview-dashboard Ready Ready Preview, Comment Apr 21, 2026 8:02pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9e0bbbf-91d6-40f6-b0b6-df2d3b71cd90

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch custom-dashboard-improvements

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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 21, 2026

Greptile Summary

This PR introduces a context chip bar for the AI dashboard chat panel — users can click widgets in the sandbox iframe, trigger "Add a component", or auto-capture runtime errors as chips that are prepended to the next AI request. It also adds a patchDashboard tool for surgical find-and-replace edits alongside the existing updateDashboard, streaming dashboard generation, and an improved system prompt with hook-ordering guidance for generated components.

Confidence Score: 5/5

Safe to merge; all findings are P2 style/UX improvements with no blocking correctness issues.

All three inline comments are P2: chip consumption timing is a minor UX annoyance (chips can be re-added), the module-level singleton only breaks in an edge case not present in the current UI, and the stale-ref window is extremely small. No data loss, security, or primary-path breakage.

chat-adapters.ts (chip consumption timing) and dashboard-tool-components.tsx (module-level singletons)

Important Files Changed

Filename Overview
apps/dashboard/src/components/vibe-coding/chat-adapters.ts Adds DashboardChip types, applyDashboardPatches logic, and createDashboardChatAdapter with streaming; chips are consumed before stream success, risking chip loss on error
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/dashboards/[dashboardId]/page-client.tsx Adds full chip-bar state management (widget/error/action chips), runtime error auto-fill, ChipBar UI component; minor stale-ref edge case in removePendingChip
apps/dashboard/src/components/vibe-coding/dashboard-tool-components.tsx Adds PatchToolRender, QueryAnalyticsToolUI, and patch snapshot registry; uses module-level mutable singletons that break with simultaneous DashboardToolUI instances
apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx Adds widget-selection overlay, "Add a component" button, and onAddComponentClicked/onWidgetSelected callbacks; postMessage origin checks and token handling look correct
apps/backend/src/lib/ai/tools/create-dashboard.ts Extracts updateDashboard into its own file and adds patchDashboard tool for surgical text edits; tool definitions are inert (no server execution) as intended
apps/backend/src/lib/ai/tools/index.ts Registers the new patch-dashboard ToolName and getTools case; exhaustiveness check preserved
apps/backend/src/lib/ai/prompts.ts Expands the create-dashboard system prompt with useDataSource hook ordering guidance and a detailed patchDashboard vs. updateDashboard decision tree; prompt-only change
apps/dashboard/src/components/assistant-ui/thread.tsx Threads composerTopContent prop through Thread → Composer; straightforward prop addition, no issues
apps/dashboard/src/components/vibe-coding/assistant-chat.tsx Forwards composerTopContent to Thread component; clean and minimal change

Sequence Diagram

sequenceDiagram
    participant U as User
    participant IFrame as Sandbox iframe
    participant Host as DashboardSandboxHost
    participant Page as page-client
    participant Chat as AssistantChat / ChipBar
    participant Adapter as createDashboardChatAdapter
    participant AI as AI Stream API

    U->>IFrame: hover widget / click Add to chat
    IFrame->>Host: postMessage(dashboard-widget-selected)
    Host->>Page: onWidgetSelected(selection)
    Page->>Page: setPendingChips([...prev, widgetChip])

    IFrame->>Host: postMessage(dashboard-error-boundary)
    Host->>Page: onRuntimeError(err)
    Page->>Page: setPendingChips([...prev, errorChip])
    Page->>Chat: composerTopContent=ChipBar

    U->>Chat: submit composer
    Chat->>Adapter: run({ messages })
    Adapter->>Adapter: getPendingChips() inject into last user message
    Adapter->>Adapter: consumePendingChips()
    Adapter->>AI: streamDashboardCode(messages + chips)
    AI-->>Adapter: stream ChatContent chunks
    Adapter-->>Chat: yield content
    Adapter->>Page: onPatchApplied / onToolCall
    Page->>IFrame: updated srcDoc (new TSX source)
Loading

Comments Outside Diff (1)

  1. apps/dashboard/src/components/vibe-coding/dashboard-tool-components.tsx, line 25-27 (link)

    P2 Module-level mutable state shared across DashboardToolUI instances

    setCurrentCodeRef, currentCodeRef, and listeners are module-level singletons. If two DashboardToolUI instances coexist in the same React tree (e.g., side-by-side pane, or two chat panels rendered simultaneously), the second mount will overwrite setCurrentCodeRef and currentCodeRef, causing "Restore this version" in any tool card to operate on whichever dashboard last registered. The effect cleanup (setCurrentCodeRef = null) mitigates sequential navigation, but simultaneous instances will silently conflict.

    Consider moving these into a React context or a stable per-instance ref passed down from the parent instead of module globals.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/dashboard/src/components/vibe-coding/dashboard-tool-components.tsx
    Line: 25-27
    
    Comment:
    **Module-level mutable state shared across `DashboardToolUI` instances**
    
    `setCurrentCodeRef`, `currentCodeRef`, and `listeners` are module-level singletons. If two `DashboardToolUI` instances coexist in the same React tree (e.g., side-by-side pane, or two chat panels rendered simultaneously), the second mount will overwrite `setCurrentCodeRef` and `currentCodeRef`, causing "Restore this version" in any tool card to operate on whichever dashboard last registered. The effect cleanup (`setCurrentCodeRef = null`) mitigates sequential navigation, but simultaneous instances will silently conflict.
    
    Consider moving these into a React context or a stable per-instance ref passed down from the parent instead of module globals.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: apps/dashboard/src/components/vibe-coding/chat-adapters.ts
Line: 540

Comment:
**Chips consumed before stream completes**

`consumePendingChips?.()` is called before the `streamDashboardCode` loop runs. If the stream fails with a network error, the `catch` block fires and the user's widget/error chips are already cleared — they need to re-click the widget or manually re-trigger the error to rebuild them.

A simpler approach is to consume chips only after at least one successful streaming yield:

```ts
let chipsConsumed = false;
if (chips.length > 0) {
  // inject chipBlock …
  // don't consume yet
}

for await (const content of streamDashboardCode(…)) {
  if (!chipsConsumed) { consumePendingChips?.(); chipsConsumed = true; }
  latestContent = content;
  yield { content };
}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: apps/dashboard/src/components/vibe-coding/dashboard-tool-components.tsx
Line: 25-27

Comment:
**Module-level mutable state shared across `DashboardToolUI` instances**

`setCurrentCodeRef`, `currentCodeRef`, and `listeners` are module-level singletons. If two `DashboardToolUI` instances coexist in the same React tree (e.g., side-by-side pane, or two chat panels rendered simultaneously), the second mount will overwrite `setCurrentCodeRef` and `currentCodeRef`, causing "Restore this version" in any tool card to operate on whichever dashboard last registered. The effect cleanup (`setCurrentCodeRef = null`) mitigates sequential navigation, but simultaneous instances will silently conflict.

Consider moving these into a React context or a stable per-instance ref passed down from the parent instead of module globals.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/dashboards/[dashboardId]/page-client.tsx
Line: 195-201

Comment:
**`pendingChipsRef` can be stale after `removePendingChip`**

`removePendingChip` only calls `setPendingChips(…)`. The ref is re-synced in a `useEffect`, which runs asynchronously after paint. If the user removes a chip and then immediately submits the composer before the effect flushes (e.g., keyboard shortcut), `getPendingChips()` will still return the removed chip and it will be injected into the AI request.

Update `pendingChipsRef.current` synchronously inside the state updater:
```ts
const removePendingChip = useCallback((id: string) => {
  setPendingChips((prev) => {
    const next = prev.filter((c) => c.id !== id);
    pendingChipsRef.current = next;
    return next;
  });
}, []);
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "initial commit" | Re-trigger Greptile

Comment thread apps/dashboard/src/components/vibe-coding/chat-adapters.ts Outdated
@aadesh18 aadesh18 changed the title initial commit Custom Dashboard Improvements Apr 21, 2026
@nams1570 nams1570 merged commit d8b7499 into ai-analytics Apr 24, 2026
35 checks passed
@nams1570 nams1570 deleted the custom-dashboard-improvements branch April 24, 2026 00:34
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