Skip to content

feat: UI improvements and automation enhancements#279

Merged
Israeltheminer merged 5 commits into
mainfrom
update-ui
Jan 23, 2026
Merged

feat: UI improvements and automation enhancements#279
Israeltheminer merged 5 commits into
mainfrom
update-ui

Conversation

@Israeltheminer

@Israeltheminer Israeltheminer commented Jan 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR includes several improvements to UI components and automation features:

UI Components

  • Dialog: Improved formatting and removed unused 'full' size variant
  • DataTable Filters: Added unique IDs and htmlFor attributes for accessibility

Chat

  • ImagePreviewDialog: New reusable component with zoom in/out/reset controls and mouse wheel zoom support

Automations

  • Assistant: Added module-level duplicate message prevention, client message IDs, and image preview
  • Sidepanel: Added desktop clear chat button
  • Version Navigation: Fixed routing for nested execution routes

Backend (Convex)

  • Added promptMessageId parameter to prevent duplicate message saving
  • Code formatting improvements in generate_response

Utils & i18n

  • Added internal marker stripping ([IMAGES], [ATTACHMENTS]) from user messages
  • Added image viewer translations

Summary by CodeRabbit

  • New Features

    • Interactive image previews with zoom controls (zoom in/out and reset) for messages.
    • File attachment support in automation chat interface.
    • Desktop clear chat button for automation panel.
  • Improvements

    • Enhanced accessibility with proper label associations for form controls.
    • Search inputs now display localized placeholder text.

✏️ Tip: You can customize this high-level summary in your review settings.

… filters

- Remove 'full' size variant from dialog (unused)
- Improve attribute formatting in DialogContent
- Add unique IDs and htmlFor to filter checkboxes for accessibility
- Add ImagePreviewDialog component with zoom in/out/reset controls
- Support mouse wheel zoom (scroll to zoom)
- Add zoom level display (percentage)
- Refactor MarkdownImage to use the new dialog component
- Add chat.imageViewer i18n keys
…age preview

- Add module-level duplicate message prevention (survives remounts)
- Add isSendingRef to prevent concurrent sends
- Add client message ID for deduplication
- Improve message matching with timestamp/content tolerance
- Add image preview functionality to assistant chat
- Add desktop clear chat button in sidepanel header
- Fix version navigation for nested routes (executions/*)
…port

- Add promptMessageId parameter to prevent duplicate message saving
- Clean up code formatting in generate_response.ts
- Improve type annotations in extractToolCallsFromSteps
- Update afterBeforeHookInput signature for new parameters
- Add stripInternalMarkers to remove [IMAGES] and [ATTACHMENTS] markers
- Integrate marker stripping into stripWorkflowContext
- Add chat.imageViewer translations (zoomIn, zoomOut, resetZoom)
@coderabbitai

coderabbitai Bot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces enhancements across multiple components and utilities in the platform services. Changes include accessibility improvements to data-table filters with i18n and proper label associations; removal of the "full" size variant from the dialog component; substantial updates to the automation assistant with duplicate-send prevention, optimistic messaging with clientMessageId tracking, and image preview functionality; a new ImagePreviewDialog component with zoom controls; enhanced attachment handling in workflow agent actions; improved message generation with promptMessageId support; internal marker stripping for message content processing; and new translation strings for image viewer controls. The changes span UI components, React hooks, backend agent actions, utilities, and configuration files.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • tale-project/tale#22: Adds image preview dialog/modal with zoom functionality for Markdown images in message-bubble component, directly paralleling the ImagePreviewDialog changes in this PR.
  • tale-project/tale#19: Implements multi-modal attachments and image preview flow across automation assistant and agent codepaths, covering file registration, content building, and UI preview handling similarly addressed here.
  • tale-project/tale#212: Modifies optimistic messaging and message deduplication behavior in automation assistant, directly related to the clientMessageId and duplicate-send guard logic introduced in this PR.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
services/platform/app/features/automations/components/automation-assistant.tsx (1)

376-426: Consider extracting duplicated message matching logic.

The matching logic (timestamp tolerance + normalized content comparison) is duplicated between the useEffect (lines 386-391) and displayMessages useMemo (lines 416-421). Consider extracting this into a helper function to improve maintainability.

♻️ Suggested refactor
// Add helper function above the component
function isMatchingUserMessage(
  serverMsg: Message,
  pendingMsg: Message,
  toleranceMs = 60000,
): boolean {
  if (serverMsg.role !== 'user') return false;
  const timeDiff = Math.abs(
    serverMsg.timestamp.getTime() - pendingMsg.timestamp.getTime(),
  );
  const contentMatch =
    serverMsg.content.trim().toLowerCase() ===
    pendingMsg.content.trim().toLowerCase();
  return timeDiff < toleranceMs || contentMatch;
}

Then use it in both places:

const hasMatchingServerMessage = transformedMessages.some((m) =>
  isMatchingUserMessage(m, pendingUserMessage),
);
🤖 Fix all issues with AI agents
In `@services/platform/app/components/ui/data-table/data-table-filters.tsx`:
- Around line 220-246: The generated checkbox id (`checkboxId` in the
filter.options.map block that composes `filter-${filter.key}-${option.value}`)
can become invalid if `option.value` or `filter.key` contain spaces or special
characters; sanitize/slugify both `filter.key` and `option.value` before
building the id so htmlFor/label association remains valid. Add or reuse a small
helper (e.g., slugify or sanitizeId) and call it when composing `checkboxId` and
when passing the id to the Checkbox component, ensuring handleFilterChange still
receives the original `option.value` (not the slug) for logic purposes. Ensure
the same sanitized id is used for both the label's htmlFor and Checkbox id to
preserve accessibility.

In
`@services/platform/app/features/automations/components/automation-sidepanel.tsx`:
- Around line 217-230: The clear-chat buttons use a generic aria-label
tCommon('actions.delete'); update both desktop and mobile buttons (the ones
gated by showAIChat/canClearChat and the mobile button near handleClearChat) to
use a context-specific translation like t('sidePanel.clearChat') instead of
tCommon, and add the corresponding sidePanel.clearChat key to the automations
i18n file; ensure the component imports/uses the local translator (t) that
contains automations translations so handleClearChat buttons use the new,
descriptive aria-label.

In `@services/platform/convex/agents/workflow/actions.ts`:
- Around line 96-101: The code is unsafely casting serialized IDs to the domain
Id type—update the types to avoid the cast: change the FileAttachment model (or
add a new FileAttachmentInput/SerializedFileAttachment type) so its fileId is
typed as string for serialized data, then use that serialized type for
attachments and in registerFilesWithAgent instead of casting (remove the "as
FileAttachment['fileId']" in the fileAttachments mapping and update any call
sites like registerFilesWithAgent to accept the serialized input type). This
aligns runtime serialized IDs with type definitions and eliminates the unsafe
cast.
- Around line 95-106: The code registers client-supplied FileAttachment fileIds
without verifying they belong to the request's organization; before calling
registerFilesWithAgent, fetch/validate each fileId's owner organizationId
against the action context organizationId (e.g., via an existing DB/query helper
like getFileById or a new verifyFileBelongsToOrganization(fileId,
organizationId) used from the same module), throw an authorization error if any
file's organizationId does not match, and only pass the verified
FileAttachment[] into registerFilesWithAgent (references: FileAttachment type,
registerFilesWithAgent, and the action context variable that holds
organizationId).

Comment thread services/platform/convex/agents/workflow/actions.ts
Comment thread services/platform/convex/agents/workflow/actions.ts
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.

1 participant