Skip to content

v0.6.9: general ux improvements for tables, mothership#3747

Merged
icecrasher321 merged 11 commits intomainfrom
staging
Mar 25, 2026
Merged

v0.6.9: general ux improvements for tables, mothership#3747
icecrasher321 merged 11 commits intomainfrom
staging

Conversation

@icecrasher321
Copy link
Collaborator

fix(integrations): remove outdated trigger mode text from FAQ (#3739)
fix(home): voice input text persistence bugs (#3737)
chore: remove lodash (#3741)
feat(table): column drag-and-drop reorder (#3738)
chore: optimize imports and useShallow (#3740)
feat(tour): added product tour (#3703)
feat(home): auth-aware landing page navigation (#3743)
feat(billing): add appliesTo plan restriction for coupon codes (#3744)
improvement(mothership): show continue options on abort (#3746)

waleedlatif1 and others added 9 commits March 24, 2026 06:47
* fix(home): voice input text persistence bugs

* fix(home): gate setIsListening on startRecognition success

* fix(home): handle startRecognition failure in restartRecognition

* fix(home): reset speech prefix on submit while mic is active
* feat(table): column drag-and-drop reorder

* fix(table): remove duplicate onDragEnd call from handleDrop

* fix(table): persist columnOrder on rename/delete and defer delete to onSuccess

* fix(table): prevent stale refs during column drag operations

Fix two bugs in column drag-and-drop:
1. Stale columnWidths ref during rename - compute updated widths inline
   before passing to updateMetadata
2. Escape-cancelled drag still reorders - update dropTargetColumnNameRef
   directly in handleColumnDragLeave to prevent handleColumnDragEnd from
   reading stale ref value

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(table): insert column at correct side when anchor is unordered

When the anchor column isn't in columnOrder, add it first then insert
the new column relative to it, so 'right' insertions appear after the
anchor as expected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix conflicts

* chore: fix review changes

* chore: fix review changes

* chore: fix review changes
* feat: add product tour

* chore: updated modals

* chore: fix the tour

* chore: Tour Updates

* chore: fix review changes

* chore: fix review changes

* chore: fix review changes

* chore: fix review changes

* chore: fix review changes

* minor improvements

* chore(tour): address PR review comments

- Extract shared TourState, TourStateContext, mapPlacement, and TourTooltipAdapter
  into tour-shared.tsx, eliminating ~100 lines of duplication between product-tour.tsx
  and workflow-tour.tsx
- Fix stale closure in handleStartTour — add isOnWorkflowPage to useCallback deps
  so Take a tour dispatches the correct event after navigation

* chore(tour): address remaining PR review comments

- Remove unused logger import and instance in product-tour.tsx
- Remove unused tour-tooltip-fade animation from tailwind config
- Remove unnecessary overflow-hidden wrapper around WorkflowTour
- Add border stroke to arrow SVG in tour-tooltip for visual consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(tour): address second round of PR review comments

- Remove unnecessary 'use client' from workflow layout (children are already client components)
- Fix ref guard timing issue in TourTooltipAdapter that could prevent Joyride from tracking tooltip on subsequent steps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(tour): extract shared Joyride config, fix popover arrow overflow

- Extract duplicated Joyride floaterProps/styles into getSharedJoyrideProps()
  in tour-shared.tsx, parameterized by spotlightBorderRadius
- Fix showArrow disabling content scrolling in PopoverContent by wrapping
  children in a scrollable div when arrow is visible

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

* fix(tour): stop running tour when disabled becomes true

Prevents nav and workflow tours from overlapping. When a user navigates
to a workflow page while the nav tour is running, the disabled flag
now stops the nav tour instead of just suppressing auto-start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tour): move auto-start flag into timer, fix truncate selector conflict

- Move hasAutoStarted flag inside setTimeout callback so it's only set
  when the timer fires, allowing retry if disabled changes during delay
- Add data-popover-scroll attribute to showArrow scroll wrapper and
  exclude it from the flex-1 truncate selector to prevent overflow
  conflict

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(tour): remove duplicate overlay on center-placed tour steps

Joyride's spotlight already renders a full-screen overlay via boxShadow.
The centered TourTooltip was adding its own bg-black/55 overlay on top,
causing double-darkened backgrounds. Removed the redundant overlay div.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move docs link from settings to help dropdown

The Docs link (https://docs.sim.ai) was buried in settings navigation.
Moved it to the Help dropdown in the sidebar for better discoverability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Adithya Krishna <aadithya794@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(home): auth-aware landing page navigation

- Redirect authenticated users from / to /workspace via middleware (?home param bypasses)
- Show "Go to App" instead of "Log in / Get started" in navbar for authenticated users
- Logo links to /?home for authenticated users to stay in marketing context
- Settings "Home Page" button opens /?home
- Handle isPending session state to prevent CTA button flash

* lint

* fix(home): remove stale ?from=nav params in landing nav

* fix(home): preserve ?home param in nav links during session pending state

* lint
* feat(billing): add appliesTo plan restriction for coupon codes

* fix(billing): fail coupon creation on partial product resolution
* Show continue options on abort

* Fix lint

* Fix
@vercel
Copy link

vercel bot commented Mar 24, 2026

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Mar 25, 2026 4:11am

Request Review

@cursor
Copy link

cursor bot commented Mar 24, 2026

PR Summary

Medium Risk
Moderate risk: touches Stripe coupon creation (plan-scoped discounts) and table UI metadata persistence (column order), plus new impersonation UI that affects session state and navigation.

Overview
Adds guided product tours across workspace navigation and workflow editor using react-joyride, including new TourTooltip/Banner UI primitives and data-tour anchors plus a “Take a tour” entry in the sidebar help menu.

Improves app/landing navigation and auth UX by making navbar links and logo hrefs session-aware (using /?home deep links) and showing a Go to App CTA when authenticated; also adds an impersonation banner and admin UI actions to start/stop impersonation.

Enhances Tables UX by adding drag-and-drop column reordering persisted via new columnOrder table metadata (API schema + client handling), and fixes rename/insert/delete flows to keep widths/order metadata consistent.

Operational/perf tweaks include adding “Continue” options when chat/tool execution is aborted, fixing voice input text persistence with restartable speech recognition, switching various Zustand selectors to useShallow, replacing lodash/isEqual with es-toolkit, enabling keepPreviousData placeholders in several React Query hooks, and minor landing/blog image + copy adjustments.

Written by Cursor Bugbot for commit 59182d5. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

recognitionRef.current = null
return false
}
}, [])
Copy link

Choose a reason for hiding this comment

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

startRecognition captures stale setValue closure reference

Low Severity

The startRecognition callback has an empty dependency array [] but closes over setValue and setIsListening. Since setValue comes from a custom hook (not useState directly), it may not have a stable identity. If setValue changes identity across renders, the onresult handler inside startRecognition will call a stale setValue reference, potentially causing speech recognition results to be lost or applied incorrectly. The valueRef sync mitigates the read side, but stale setValue writes could still be a problem.

Fix in Cursor Fix in Web


if (storedBlocks.length > 0) {
storedBlocks.push({ type: 'stopped' })
storedBlocks.push({ type: 'text', content: CONTINUE_OPTIONS_CONTENT })
Copy link

Choose a reason for hiding this comment

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

Inconsistent "Stopped" vs "Stopped by user" display text

Low Severity

In persistPartialResponse, cancelled tool calls get displayTitle set to 'Stopped by user' (line 1184), but resolveInterruptedToolCalls sets it to 'Stopped' (line 1262). Since resolveInterruptedToolCalls runs after persistPartialResponse in stopGeneration, the in-memory state shows "Stopped" while the persisted server state saves "Stopped by user". On reload, users see a different label than what was shown live.

Additional Locations (1)
Fix in Cursor Fix in Web

* Allow admin users to assume user sessions

* Add explicit role check

* Fix lint

* Remove admin panel when impersonating

* Fix lint

---------

Co-authored-by: Theodore Li <theo@sim.ai>
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This release bundles several independent UX and infrastructure improvements: column drag-and-drop reorder in tables (persisted via TableMetadata.columnOrder), a new product tour powered by react-joyride, voice input text persistence fixes, auth-aware landing page navigation, "continue options" shown after a Mothership abort, appliesTo plan restriction for coupon codes, and a broad Zustand useShallow optimization pass to cut unnecessary re-renders.

Key changes:

  • table.tsx — new columnOrder state + drag handlers; displayColumns memo applies the custom order over the raw schema columns; all column mutations (insert left/right, delete, rename) keep the order in sync and persist it to the metadata API.
  • use-tour.ts / product-tour.tsx / workflow-tour.tsx — shared useTour hook handles auto-start, localStorage persistence, manual retrigger events, and smooth fade transitions between steps.
  • user-input.tsx — refactors voice recognition into startRecognition / restartRecognition; fixes prefix accumulation bugs by tracking valueRef and restarting the session on every manual input change.
  • use-chat.ts — adds resolveInterruptedToolCalls (idempotent; guards on hasAnyExecuting) called from both handleStop and finalize; injects CONTINUE_OPTIONS_CONTENT into the persisted content on abort.
  • referral-campaigns/route.tsresolveProductIds resolves broad plan categories (pro, team) or exact plan names to Stripe product IDs before creating the coupon; includes full validation and error surfacing.
  • Multiple hooks — useShallow added to multi-field Zustand selectors to prevent object identity churn.

Issues noted:

  • useSearchParams() is added to both Nav (landing) and Navbar (home) without a <Suspense> boundary in the respective parent render trees, which can opt those routes out of static generation in Next.js App Router.
  • SPEECH_RECOGNITION_LANG is hardcoded to 'en-US'; non-English users will get degraded recognition quality.
  • In handleColumnDragEnd, when the drag target isn't found in the post-filter array, Array.splice(-1, 0, dragged) inserts at the second-to-last slot instead of aborting the reorder.

Confidence Score: 4/5

  • Safe to merge — no data-loss or security issues; three non-blocking style/logic improvements remain.
  • The PR is a broad but well-scoped set of features and optimizations. The drag-and-drop column reorder is the most complex change; its core logic is correct and metadata-persisted, though the edge-case splice(-1) bug could silently misplace a column in the rare scenario where target disappears from the filtered array mid-drag. The voice recognition refactor is correct and idempotent. The auth-aware nav changes work correctly client-side; the Suspense concern is a potential static-generation regression on the public landing page but not a runtime error. All other changes (useShallow, tour, billing) look clean.
  • Pay close attention to table.tsx (column drag-end edge case) and nav.tsx / navbar.tsx (missing Suspense boundary for useSearchParams).

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table/table.tsx Adds column drag-and-drop reorder with columnOrder state, drag event handlers, and metadata persistence. One subtle logic issue: when target isn't found in the post-filter array, splice(-1, 0, dragged) inserts at the wrong position instead of aborting.
apps/sim/app/workspace/[workspaceId]/components/product-tour/use-tour.ts New shared hook managing product tour state — auto-start, localStorage persistence, manual triggers via custom events, and coordinated fade transitions. Well-structured and idempotent.
apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts Adds CONTINUE_OPTIONS_CONTENT injected on abort/stop so users can resume. The resolveInterruptedToolCalls helper is idempotent (guards on hasAnyExecuting) and is reused by both the manual stop handler and finalize. Logic looks sound.
apps/sim/app/workspace/[workspaceId]/home/components/user-input/user-input.tsx Refactors voice recognition into reusable startRecognition/restartRecognition helpers; fixes text persistence bugs by using valueRef and restarting the recognition session on each input change. Language is hardcoded to 'en-US'.
apps/sim/app/(landing)/components/nav/nav.tsx Auth-aware nav: shows "Go to App" for authenticated users; adds useSearchParams() without a Suspense boundary in the parent, which could prevent static generation of the landing page.
apps/sim/app/(home)/components/navbar/navbar.tsx Auth-aware navbar uses useSearchParams() and useSession() to determine link targets; same Suspense boundary concern as the landing Nav.
apps/sim/app/api/v1/admin/referral-campaigns/route.ts Adds appliesTo plan restriction for coupon codes; resolves plan names to Stripe product IDs via price retrieval. Error handling and validation are thorough. No issues found.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts Adds useShallow selectors to Zustand store subscriptions to reduce unnecessary re-renders. Clean optimization, no issues.
apps/sim/lib/table/types.ts Adds columnOrder?: string[] to TableMetadata to persist drag-and-drop column ordering. Minimal and correct type extension.

Sequence Diagram

sequenceDiagram
    participant User
    participant ColumnHeaderMenu
    participant Table
    participant MetadataAPI

    User->>ColumnHeaderMenu: dragstart
    ColumnHeaderMenu->>Table: onDragStart(columnName)
    Table->>Table: setDragColumnName(columnName)

    User->>ColumnHeaderMenu: dragover (target header)
    ColumnHeaderMenu->>Table: onDragOver(targetName, side)
    Table->>Table: setDropTargetColumnName / setDropSide

    User->>ColumnHeaderMenu: drop / dragend
    ColumnHeaderMenu->>Table: onDragEnd()
    Table->>Table: compute newOrder from columnOrderRef
    Table->>Table: setColumnOrder(newOrder)
    Table->>MetadataAPI: updateMetadata({ columnWidths, columnOrder })
    MetadataAPI-->>Table: 200 OK

    Note over Table: columnOrder persisted in TableMetadata.columnOrder
    Note over Table: displayColumns re-computed via useMemo on next render
Loading

Reviews (1): Last reviewed commit: "feat(admin): Add assume user capability ..." | Re-trigger Greptile

* feat(settings): add video tooltip previews for canvas settings

* fix(tooltip): add preload=none and handle query strings in video detection
@icecrasher321 icecrasher321 merged commit ed9a71f into main Mar 25, 2026
25 of 26 checks passed
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.

5 participants