feat: UI improvements and automation enhancements#279
Conversation
… 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)
📝 WalkthroughWalkthroughThis 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
Comment |
There was a problem hiding this comment.
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) anddisplayMessagesuseMemo (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).
Summary
This PR includes several improvements to UI components and automation features:
UI Components
Chat
Automations
Backend (Convex)
promptMessageIdparameter to prevent duplicate message savingUtils & i18n
[IMAGES],[ATTACHMENTS]) from user messagesSummary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.