Skip to content

Commit aae4542

Browse files
waleedlatif1waleedlatif
authored andcommitted
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>
1 parent 7179584 commit aae4542

File tree

9 files changed

+550
-348
lines changed

9 files changed

+550
-348
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/components/auth-selector.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export function AuthSelector({
139139
disabled={disabled}
140140
className='pr-28'
141141
required={!isExistingChat}
142+
autoComplete='new-password'
142143
/>
143144
<div className='absolute top-0 right-0 flex h-full'>
144145
<Button
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Label } from '@/components/ui'
2+
import { getBaseDomain, getEmailDomain } from '@/lib/urls/utils'
3+
4+
interface ExistingChat {
5+
id: string
6+
subdomain: string
7+
title: string
8+
description: string
9+
authType: 'public' | 'password' | 'email'
10+
allowedEmails: string[]
11+
outputConfigs: Array<{ blockId: string; path: string }>
12+
customizations?: {
13+
welcomeMessage?: string
14+
}
15+
isActive: boolean
16+
}
17+
18+
interface SuccessViewProps {
19+
deployedUrl: string
20+
existingChat: ExistingChat | null
21+
}
22+
23+
export function SuccessView({ deployedUrl, existingChat }: SuccessViewProps) {
24+
const url = new URL(deployedUrl)
25+
const hostname = url.hostname
26+
const isDevelopmentUrl = hostname.includes('localhost')
27+
28+
let domainSuffix
29+
if (isDevelopmentUrl) {
30+
const baseDomain = getBaseDomain()
31+
const baseHost = baseDomain.split(':')[0]
32+
const port = url.port || (baseDomain.includes(':') ? baseDomain.split(':')[1] : '3000')
33+
domainSuffix = `.${baseHost}:${port}`
34+
} else {
35+
domainSuffix = `.${getEmailDomain()}`
36+
}
37+
38+
const baseDomainForSplit = getEmailDomain()
39+
const subdomainPart = isDevelopmentUrl
40+
? hostname.split('.')[0]
41+
: hostname.split(`.${baseDomainForSplit}`)[0]
42+
43+
return (
44+
<div className='space-y-4'>
45+
<div className='space-y-2'>
46+
<Label className='font-medium text-sm'>
47+
Chat {existingChat ? 'Update' : 'Deployment'} Successful
48+
</Label>
49+
<div className='relative flex items-center rounded-md ring-offset-background'>
50+
<a
51+
href={deployedUrl}
52+
target='_blank'
53+
rel='noopener noreferrer'
54+
className='flex h-10 flex-1 items-center break-all rounded-l-md border border-r-0 p-2 font-medium text-primary text-sm'
55+
>
56+
{subdomainPart}
57+
</a>
58+
<div className='flex h-10 items-center whitespace-nowrap rounded-r-md border border-l-0 bg-muted px-3 font-medium text-muted-foreground text-sm'>
59+
{domainSuffix}
60+
</div>
61+
</div>
62+
<p className='text-muted-foreground text-xs'>
63+
Your chat is now live at{' '}
64+
<a
65+
href={deployedUrl}
66+
target='_blank'
67+
rel='noopener noreferrer'
68+
className='text-primary hover:underline'
69+
>
70+
this URL
71+
</a>
72+
</p>
73+
</div>
74+
</div>
75+
)
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useChatDeployment } from './use-chat-deployment'
2+
import { useChatForm } from './use-chat-form'
3+
4+
export { useChatDeployment, useChatForm }
5+
6+
export type { ChatFormData, ChatFormErrors } from './use-chat-form'

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx

Lines changed: 34 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,11 @@ export function DeployModal({
6464
isLoadingDeployedState,
6565
refetchDeployedState,
6666
}: DeployModalProps) {
67-
// Use registry store for deployment-related functions
6867
const deploymentStatus = useWorkflowRegistry((state) =>
6968
state.getWorkflowDeploymentStatus(workflowId)
7069
)
7170
const isDeployed = deploymentStatus?.isDeployed || false
7271
const setDeploymentStatus = useWorkflowRegistry((state) => state.setDeploymentStatus)
73-
74-
// Local state
7572
const [isSubmitting, setIsSubmitting] = useState(false)
7673
const [isUndeploying, setIsUndeploying] = useState(false)
7774
const [deploymentInfo, setDeploymentInfo] = useState<WorkflowDeploymentInfo | null>(null)
@@ -84,7 +81,6 @@ export function DeployModal({
8481
const [chatExists, setChatExists] = useState(false)
8582
const [isChatFormValid, setIsChatFormValid] = useState(false)
8683

87-
// Generate an example input format for the API request
8884
const getInputFormatExample = () => {
8985
let inputFormatExample = ''
9086
try {
@@ -128,7 +124,6 @@ export function DeployModal({
128124
return inputFormatExample
129125
}
130126

131-
// Fetch API keys when modal opens
132127
const fetchApiKeys = async () => {
133128
if (!open) return
134129

@@ -147,7 +142,6 @@ export function DeployModal({
147142
}
148143
}
149144

150-
// Fetch chat deployment info when modal opens
151145
const fetchChatDeploymentInfo = async () => {
152146
if (!open || !workflowId) return
153147

@@ -173,23 +167,19 @@ export function DeployModal({
173167
}
174168
}
175169

176-
// Call fetchApiKeys when the modal opens
177170
useEffect(() => {
178171
if (open) {
179-
// Set loading state immediately when modal opens
180172
setIsLoading(true)
181173
fetchApiKeys()
182174
fetchChatDeploymentInfo()
183175
setActiveTab('api')
184176
}
185177
}, [open, workflowId])
186178

187-
// Fetch deployment info when the modal opens and the workflow is deployed
188179
useEffect(() => {
189180
async function fetchDeploymentInfo() {
190181
if (!open || !workflowId || !isDeployed) {
191182
setDeploymentInfo(null)
192-
// Only reset loading if modal is closed
193183
if (!open) {
194184
setIsLoading(false)
195185
}
@@ -199,7 +189,6 @@ export function DeployModal({
199189
try {
200190
setIsLoading(true)
201191

202-
// Get deployment info
203192
const response = await fetch(`/api/workflows/${workflowId}/deploy`)
204193

205194
if (!response.ok) {
@@ -228,23 +217,20 @@ export function DeployModal({
228217
fetchDeploymentInfo()
229218
}, [open, workflowId, isDeployed, needsRedeployment])
230219

231-
// Handle form submission for deployment
232220
const onDeploy = async (data: DeployFormValues) => {
233-
// Reset any previous errors
234221
setApiDeployError(null)
235222

236223
try {
237224
setIsSubmitting(true)
238225

239-
// Deploy the workflow with the selected API key
240226
const response = await fetch(`/api/workflows/${workflowId}/deploy`, {
241227
method: 'POST',
242228
headers: {
243229
'Content-Type': 'application/json',
244230
},
245231
body: JSON.stringify({
246232
apiKey: data.apiKey,
247-
deployChatEnabled: false, // Separate chat deployment
233+
deployChatEnabled: false,
248234
}),
249235
})
250236

@@ -255,21 +241,17 @@ export function DeployModal({
255241

256242
const { isDeployed: newDeployStatus, deployedAt } = await response.json()
257243

258-
// Update the store with the deployment status
259244
setDeploymentStatus(
260245
workflowId,
261246
newDeployStatus,
262247
deployedAt ? new Date(deployedAt) : undefined,
263248
data.apiKey
264249
)
265250

266-
// Reset the needs redeployment flag
267251
setNeedsRedeployment(false)
268252
if (workflowId) {
269253
useWorkflowRegistry.getState().setWorkflowNeedsRedeployment(workflowId, false)
270254
}
271-
272-
// Update the local deployment info
273255
const endpoint = `${getEnv('NEXT_PUBLIC_APP_URL')}/api/workflows/${workflowId}/execute`
274256
const inputFormatExample = getInputFormatExample()
275257

@@ -284,18 +266,14 @@ export function DeployModal({
284266

285267
setDeploymentInfo(newDeploymentInfo)
286268

287-
// Fetch the updated deployed state after deployment
288269
await refetchDeployedState()
289-
290-
// No notification on successful deploy
291270
} catch (error: any) {
292271
logger.error('Error deploying workflow:', { error })
293272
} finally {
294273
setIsSubmitting(false)
295274
}
296275
}
297276

298-
// Handle workflow undeployment
299277
const handleUndeploy = async () => {
300278
try {
301279
setIsUndeploying(true)
@@ -309,13 +287,8 @@ export function DeployModal({
309287
throw new Error(errorData.error || 'Failed to undeploy workflow')
310288
}
311289

312-
// Update deployment status in the store
313290
setDeploymentStatus(workflowId, false)
314-
315-
// Reset chat deployment info
316291
setChatExists(false)
317-
318-
// Close the modal
319292
onOpenChange(false)
320293
} catch (error: any) {
321294
logger.error('Error undeploying workflow:', { error })
@@ -324,7 +297,6 @@ export function DeployModal({
324297
}
325298
}
326299

327-
// Handle redeployment of workflow
328300
const handleRedeploy = async () => {
329301
try {
330302
setIsSubmitting(true)
@@ -335,7 +307,7 @@ export function DeployModal({
335307
'Content-Type': 'application/json',
336308
},
337309
body: JSON.stringify({
338-
deployChatEnabled: false, // Separate chat deployment
310+
deployChatEnabled: false,
339311
}),
340312
})
341313

@@ -346,21 +318,18 @@ export function DeployModal({
346318

347319
const { isDeployed: newDeployStatus, deployedAt, apiKey } = await response.json()
348320

349-
// Update deployment status in the store
350321
setDeploymentStatus(
351322
workflowId,
352323
newDeployStatus,
353324
deployedAt ? new Date(deployedAt) : undefined,
354325
apiKey
355326
)
356327

357-
// Reset the needs redeployment flag
358328
setNeedsRedeployment(false)
359329
if (workflowId) {
360330
useWorkflowRegistry.getState().setWorkflowNeedsRedeployment(workflowId, false)
361331
}
362332

363-
// Fetch the updated deployed state after redeployment
364333
await refetchDeployedState()
365334
} catch (error: any) {
366335
logger.error('Error redeploying workflow:', { error })
@@ -369,56 +338,47 @@ export function DeployModal({
369338
}
370339
}
371340

372-
// Custom close handler to ensure we clean up loading states
373341
const handleCloseModal = () => {
374342
setIsSubmitting(false)
375343
setChatSubmitting(false)
376344
onOpenChange(false)
377345
}
378346

379-
// Handle chat form submission
380-
const handleChatSubmit = async () => {
381-
setChatSubmitting(true)
347+
const handleWorkflowPreDeploy = async () => {
348+
if (!isDeployed) {
349+
const response = await fetch(`/api/workflows/${workflowId}/deploy`, {
350+
method: 'POST',
351+
headers: {
352+
'Content-Type': 'application/json',
353+
},
354+
body: JSON.stringify({
355+
deployApiEnabled: true,
356+
deployChatEnabled: false,
357+
}),
358+
})
382359

383-
try {
384-
// Check if workflow is deployed first
385-
if (!isDeployed) {
386-
// Deploy workflow first
387-
const response = await fetch(`/api/workflows/${workflowId}/deploy`, {
388-
method: 'POST',
389-
headers: {
390-
'Content-Type': 'application/json',
391-
},
392-
body: JSON.stringify({
393-
deployApiEnabled: true,
394-
deployChatEnabled: false,
395-
}),
396-
})
360+
if (!response.ok) {
361+
const errorData = await response.json()
362+
throw new Error(errorData.error || 'Failed to deploy workflow')
363+
}
397364

398-
if (!response.ok) {
399-
const errorData = await response.json()
400-
throw new Error(errorData.error || 'Failed to deploy workflow')
401-
}
365+
const { isDeployed: newDeployStatus, deployedAt, apiKey } = await response.json()
402366

403-
const { isDeployed: newDeployStatus, deployedAt, apiKey } = await response.json()
367+
setDeploymentStatus(
368+
workflowId,
369+
newDeployStatus,
370+
deployedAt ? new Date(deployedAt) : undefined,
371+
apiKey
372+
)
404373

405-
// Update the store with the deployment status
406-
setDeploymentStatus(
407-
workflowId,
408-
newDeployStatus,
409-
deployedAt ? new Date(deployedAt) : undefined,
410-
apiKey
411-
)
412-
}
374+
setDeploymentInfo((prev) => (prev ? { ...prev, apiKey } : null))
375+
}
376+
}
413377

414-
// Trigger form submission in the ChatDeploy component
415-
const form = document.querySelector('.chat-deploy-form') as HTMLFormElement
416-
if (form) {
417-
form.requestSubmit()
418-
}
419-
} catch (error: any) {
420-
logger.error('Error auto-deploying workflow for chat:', { error })
421-
setChatSubmitting(false)
378+
const handleChatFormSubmit = () => {
379+
const form = document.getElementById('chat-deploy-form') as HTMLFormElement
380+
if (form) {
381+
form.requestSubmit()
422382
}
423383
}
424384

@@ -513,13 +473,13 @@ export function DeployModal({
513473
chatSubmitting={chatSubmitting}
514474
setChatSubmitting={setChatSubmitting}
515475
onValidationChange={setIsChatFormValid}
476+
onPreDeployWorkflow={handleWorkflowPreDeploy}
516477
/>
517478
)}
518479
</div>
519480
</div>
520481
</div>
521482

522-
{/* Footer buttons */}
523483
{activeTab === 'api' && !isDeployed && (
524484
<div className='flex flex-shrink-0 justify-between border-t px-6 py-4'>
525485
<Button variant='outline' onClick={handleCloseModal}>
@@ -558,7 +518,7 @@ export function DeployModal({
558518

559519
<Button
560520
type='button'
561-
onClick={handleChatSubmit}
521+
onClick={handleChatFormSubmit}
562522
disabled={chatSubmitting || !isChatFormValid}
563523
className={cn(
564524
'gap-2 font-medium',

0 commit comments

Comments
 (0)