Skip to content

fix(chat-deploy): added new image upload component, fixed some state issues with success view#842

Merged
waleedlatif1 merged 2 commits intostagingfrom
cherry-pick-9006c72
Aug 1, 2025
Merged

fix(chat-deploy): added new image upload component, fixed some state issues with success view#842
waleedlatif1 merged 2 commits intostagingfrom
cherry-pick-9006c72

Conversation

@waleedlatif1
Copy link
Collaborator

Description

added new image upload component, fixed some state issues with success view

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Tested manually

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • All tests pass locally and in CI (bun run test)
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • I have updated version numbers as needed (if needed)
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Security Considerations:

  • My changes do not introduce any new security vulnerabilities
  • I have considered the security implications of my changes

@waleedlatif1 waleedlatif1 merged commit 9a565f4 into staging Aug 1, 2025
3 of 4 checks passed
@vercel
Copy link

vercel bot commented Aug 1, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sim 🔄 Building (Inspect) Visit Preview 💬 Add feedback Aug 1, 2025 7:43pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
docs ⬜️ Skipped (Inspect) Aug 1, 2025 7:43pm

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR adds image upload functionality to chat deployments and fixes state management issues in the success view. The changes introduce a new ImageUpload component that provides drag-and-drop file handling, validation, and cloud storage integration through both presigned URLs and fallback server uploads. The component supports Azure Blob Storage and AWS S3 with proper security configuration via Next.js remotePatterns.

The chat deployment flow has been enhanced with image customization capabilities, allowing users to upload logos for their deployed chat interfaces. The deployment schema and API integration now support an optional imageUrl parameter. State management improvements include better handling of existing chat edits through an isEditingExisting flag that optimizes subdomain validation, and enhanced success view interactions with hidden trigger buttons that enable proper communication between modal footer buttons and form components.

Additional changes include removal of verbose logging statements from Ollama provider utilities and store methods, and proper export organization for the new hooks and components. The implementation follows established patterns in the codebase while adding comprehensive error handling and loading states for the new image upload workflow.

Confidence score: 3/5

  • This PR introduces significant new functionality with potential architectural concerns around component coupling
  • Score reflects complex state management changes and a problematic deeply nested import path that violates established patterns
  • Pay close attention to the ImageUpload component's import path and the DOM querying pattern in deploy-modal.tsx

Context used:

Context - Use established path alias patterns instead of deeply nested relative import paths. (link)

13 files reviewed, 7 comments

Edit Code Review Bot Settings | Greptile

Comment on lines +38 to 41
if (isEditingExisting && !originalSubdomain) {
setIsValid(true)
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: This optimistic validation could lead to a race condition. If originalSubdomain loads after the user has already changed the subdomain, this early return might prevent proper validation of the new value.

Comment on lines +3 to +7
export function useSubdomainValidation(
subdomain: string,
originalSubdomain?: string,
isEditingExisting?: boolean
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider grouping the optional parameters into an options object for better maintainability as the function signature grows.

Context Used: Context - Group optional parameters into an options object for better maintainability when defining functions or methods. (link)

import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { cn } from '@/lib/utils'
import { useImageUpload } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/hooks/use-image-upload'
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider using path alias instead of deeply nested relative import

Context Used: Context - Use established path alias patterns instead of deeply nested relative import paths. (link)

Comment on lines +92 to +96
const fakeEvent = {
target: {
files: [file],
},
} as unknown as React.ChangeEvent<HTMLInputElement>
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Type assertion to unknown bypasses TypeScript safety. Consider defining proper event type

Context Used: Context - Avoid using type assertions to 'any' in TypeScript. Instead, ensure proper type definitions are used to maintain type safety. (link)

</p>
</div>
</div>
) : displayUrl ? (
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Redundant condition - displayUrl is already falsy-checked on line 128

Suggested change
) : displayUrl ? (
) : (

Comment on lines +54 to +93
if (presignedResponse.ok) {
// Use direct upload with presigned URL
const presignedData = await presignedResponse.json()

// Log the presigned URL response for debugging
logger.info('Presigned URL response:', presignedData)

// Upload directly to storage provider
const uploadHeaders: Record<string, string> = {
'Content-Type': file.type,
}

// Add any additional headers from the presigned response (for Azure Blob)
if (presignedData.uploadHeaders) {
Object.assign(uploadHeaders, presignedData.uploadHeaders)
}

const uploadResponse = await fetch(presignedData.uploadUrl, {
method: 'PUT',
body: file,
headers: uploadHeaders,
})

logger.info(`Upload response status: ${uploadResponse.status}`)
logger.info(
'Upload response headers:',
Object.fromEntries(uploadResponse.headers.entries())
)

if (!uploadResponse.ok) {
const responseText = await uploadResponse.text()
logger.error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
throw new Error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
}

// Use the file info returned from the presigned URL endpoint
const publicUrl = presignedData.fileInfo.path
logger.info(`Image uploaded successfully via direct upload: ${publicUrl}`)
return publicUrl
}
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: No error handling if presignedData.uploadUrl or presignedData.fileInfo.path are missing from response

Suggested change
if (presignedResponse.ok) {
// Use direct upload with presigned URL
const presignedData = await presignedResponse.json()
// Log the presigned URL response for debugging
logger.info('Presigned URL response:', presignedData)
// Upload directly to storage provider
const uploadHeaders: Record<string, string> = {
'Content-Type': file.type,
}
// Add any additional headers from the presigned response (for Azure Blob)
if (presignedData.uploadHeaders) {
Object.assign(uploadHeaders, presignedData.uploadHeaders)
}
const uploadResponse = await fetch(presignedData.uploadUrl, {
method: 'PUT',
body: file,
headers: uploadHeaders,
})
logger.info(`Upload response status: ${uploadResponse.status}`)
logger.info(
'Upload response headers:',
Object.fromEntries(uploadResponse.headers.entries())
)
if (!uploadResponse.ok) {
const responseText = await uploadResponse.text()
logger.error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
throw new Error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
}
// Use the file info returned from the presigned URL endpoint
const publicUrl = presignedData.fileInfo.path
logger.info(`Image uploaded successfully via direct upload: ${publicUrl}`)
return publicUrl
}
if (presignedResponse.ok) {
// Use direct upload with presigned URL
const presignedData = await presignedResponse.json()
// Validate required fields in presigned response
if (!presignedData.uploadUrl || !presignedData.fileInfo?.path) {
throw new Error('Invalid presigned response: missing uploadUrl or fileInfo.path')
}
// Log the presigned URL response for debugging
logger.info('Presigned URL response:', presignedData)
// Upload directly to storage provider
const uploadHeaders: Record<string, string> = {
'Content-Type': file.type,
}
// Add any additional headers from the presigned response (for Azure Blob)
if (presignedData.uploadHeaders) {
Object.assign(uploadHeaders, presignedData.uploadHeaders)
}
const uploadResponse = await fetch(presignedData.uploadUrl, {
method: 'PUT',
body: file,
headers: uploadHeaders,
})
logger.info(`Upload response status: ${uploadResponse.status}`)
logger.info(
'Upload response headers:',
Object.fromEntries(uploadResponse.headers.entries())
)
if (!uploadResponse.ok) {
const responseText = await uploadResponse.text()
logger.error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
throw new Error(`Direct upload failed: ${uploadResponse.status} - ${responseText}`)
}
// Use the file info returned from the presigned URL endpoint
const publicUrl = presignedData.fileInfo.path
logger.info(`Image uploaded successfully via direct upload: ${publicUrl}`)
return publicUrl
}

Comment on lines +131 to +133
const previewUrl = URL.createObjectURL(file)
setPreviewUrl(previewUrl)
previewRef.current = previewUrl
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Creates object URL but doesn't immediately clean up previous one when file changes

Suggested change
const previewUrl = URL.createObjectURL(file)
setPreviewUrl(previewUrl)
previewRef.current = previewUrl
// Clean up previous preview URL to prevent memory leaks
if (previewRef.current) {
URL.revokeObjectURL(previewRef.current)
}
const previewUrl = URL.createObjectURL(file)
setPreviewUrl(previewUrl)
previewRef.current = previewUrl

icecrasher321 added a commit that referenced this pull request Aug 1, 2025
…n, deployed chat improvements (#843)

* fix(domain): fix telemetry endpoint, only add redirects for hosted version (#822)

* fix(otel): change back telemetry endpoint

* only add redirects for hosted version

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* fix(search-modal): fixed search modal keyboard nav (#823)

* fixed search modal keyboard nav

* break down file

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* improvement(docs): add base exec charge info to docs (#826)

* improvement(doc-tags-subblock): use table for doc tags subblock in create_document tool for KB (#827)

* improvement(doc-tags-subblock): use table for doc tags create doc tool in KB block

* enforce max tags

* remove red warning text

* fix(bugs): fixed rb2b csp, fixed overly-verbose logs, fixed x URLs (#828)

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* feat(wand): subblock level wand configuration + migrate old wand usage to this (#829)

* feat(wand): subblock level wand configuration + migrate old wand usage to this

* fix build issue

* Update apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/wand-prompt-bar/wand-prompt-bar.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* remove optional param

* remove unused test file

* address greptile comments

* change to enum for gen type

* fix caching issue

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* feat(tools): added hunter.io tools/block, added default values of first option in dropdowns to avoid operation selector issue, added descriptions & param validation & updated docs (#825)

* feat(tools): added hunter.io tools/block, added default values of first option in dropdowns to avoid operation selector issue

* fix

* added description for all outputs, fixed param validation for tools

* cleanup

* add dual validation, once during serialization and once during execution

* improvement(docs): add base exec charge info to docs (#826)

* improvement(doc-tags-subblock): use table for doc tags subblock in create_document tool for KB (#827)

* improvement(doc-tags-subblock): use table for doc tags create doc tool in KB block

* enforce max tags

* remove red warning text

* fix(bugs): fixed rb2b csp, fixed overly-verbose logs, fixed x URLs (#828)

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* fixed serialization errors to appear like execution errors, also fixed contrast on cmdk modal

* fixed required for tools, added tag dropdown for kb tags

* fix remaining tools with required fields

* update utils

* update docs

* fix kb tags

* fix types for exa

* lint

* updated contributing guide + pr template

* Test pre-commit hook with linting

* Test pre-commit hook again

* remove test files

* fixed wealthbox tool

* update telemetry endpoints

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>

* fix(deployed-chat): trigger blocks should not interfere with deployed chat exec (#832)

* fix(deployed-chat): allow non-streaming responses in deployed chat, allow partial failure responses in deployed chat (#833)

* fix(deployed-chat): allow non-streaming responses in deployed chat, allow partial failure responses in deployed chat

* fix(csp): runtime variable resolution for CSP

* cleanup

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* fix(sockets): duplicate block op should go through debounced path (#834)

* improvement(sockets): add batch subblock updates for duplicate to clear queue faster (#835)

* improvement(sockets): duplicate op should let addBlock take subblock values instead of separate looped op (#836)

* improvement(sockets): addBlock can accept subblock values

* cleanup unused code

* fix(deploy-modal): break down deploy modal into separate components (#837)

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* fix(kb-tags): docs page kb tags ui (#838)

* fix(kb-tags): docs page kb tags ui

* remove console logs

* remove console error

* fix(chat-deploy): fixed form submission access patterns, fixed kb block filters (#839)

* fix(chat-deploy): fixed form submission access patterns

* fix(kb-block): fix tag filters component, removed unused component

* fixed kb block subcomponents

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* fix(kb-tags): ui fixes, delete persistence for doc page header (#841)

* fix deletion of tags + refactor next slot calc

* fix kb tag filters count ui

* fix(chat-deploy): added new image upload component, fixed some state issues with success view (#842)

* fix(chat-deploy): added new image upload component, fixed some state issues with success view

* cleanup

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

* feat(deploy-chat): added a logo upload for the chat, incr font size

* fix(deploy-modal): break down deploy modal into separate components (#837)

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@waleedlatif1 waleedlatif1 deleted the cherry-pick-9006c72 branch August 2, 2025 22:17
waleedlatif1 added a commit that referenced this pull request Aug 5, 2025
…issues with success view (#842)

* fix(chat-deploy): added new image upload component, fixed some state issues with success view

* cleanup

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>
arenadeveloper02 pushed a commit to arenadeveloper02/p2-sim that referenced this pull request Sep 19, 2025
…issues with success view (simstudioai#842)

* fix(chat-deploy): added new image upload component, fixed some state issues with success view

* cleanup

---------

Co-authored-by: waleedlatif <waleedlatif@waleedlatifs-MacBook-Pro.local>
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