Skip to content

Commit cfa8a5c

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
refactor(ui): use EMCN fields in deployment and setup modals
1 parent 7eb9cc4 commit cfa8a5c

5 files changed

Lines changed: 184 additions & 163 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx‎

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
ChipConfirmModal,
88
ChipEmailsInput,
99
ChipInput,
10-
ChipTextarea,
10+
ChipModalField,
1111
cn,
1212
Input,
1313
Label,
@@ -335,12 +335,7 @@ export function ChatDeploy({
335335

336336
return (
337337
<>
338-
<form
339-
id='chat-deploy-form'
340-
ref={formRef}
341-
onSubmit={handleSubmit}
342-
className='-mx-1 space-y-4 px-1'
343-
>
338+
<form id='chat-deploy-form' ref={formRef} onSubmit={handleSubmit} className='space-y-4'>
344339
{errors.general && (
345340
<div className='flex items-center gap-2 rounded-md border border-[color-mix(in_srgb,var(--text-error)_20%,transparent)] bg-[color-mix(in_srgb,var(--text-error)_10%,transparent)] px-3 py-2 text-[var(--text-error)] text-small'>
346341
<TriangleAlert className='size-4 shrink-0' />
@@ -358,27 +353,21 @@ export function ChatDeploy({
358353
isEditingExisting={!!existingChat}
359354
/>
360355

361-
<div>
362-
<Label
363-
htmlFor='title'
364-
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
365-
>
366-
Title
367-
</Label>
368-
<ChipInput
369-
id='title'
370-
placeholder='Customer Support Assistant'
371-
value={formData.title}
372-
onChange={(e) => updateField('title', e.target.value)}
373-
required
374-
disabled={chatSubmitting}
375-
/>
376-
{errors.title && (
377-
<p className='mt-[6.5px] text-[var(--text-error)] text-caption'>{errors.title}</p>
356+
<ChipModalField type='custom' title='Title' htmlFor='title' error={errors.title}>
357+
{(aria) => (
358+
<ChipInput
359+
id='title'
360+
placeholder='Customer Support Assistant'
361+
value={formData.title}
362+
onChange={(e) => updateField('title', e.target.value)}
363+
required
364+
disabled={chatSubmitting}
365+
{...aria}
366+
/>
378367
)}
379-
</div>
368+
</ChipModalField>
380369

381-
<div>
370+
<div className='px-2'>
382371
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
383372
Output
384373
</Label>
@@ -400,7 +389,7 @@ export function ChatDeploy({
400389
)}
401390
</div>
402391

403-
<div className='flex items-center justify-between gap-3'>
392+
<div className='flex items-center justify-between gap-3 px-2'>
404393
<div className='min-w-0'>
405394
<Label className='block pl-0.5 text-[var(--text-primary)] text-small'>
406395
Include thinking
@@ -414,7 +403,7 @@ export function ChatDeploy({
414403
/>
415404
</div>
416405

417-
<div className='flex items-center justify-between gap-3'>
406+
<div className='flex items-center justify-between gap-3 px-2'>
418407
<div className='min-w-0'>
419408
<Label className='block pl-0.5 text-[var(--text-primary)] text-small'>
420409
Include tool calls
@@ -443,26 +432,17 @@ export function ChatDeploy({
443432
hasExistingPassword={existingPassword}
444433
error={errors.password || errors.emails}
445434
/>
446-
<div>
447-
<Label
448-
htmlFor='welcomeMessage'
449-
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
450-
>
451-
Welcome message
452-
</Label>
453-
<ChipTextarea
454-
id='welcomeMessage'
455-
placeholder='Enter a welcome message for your chat'
456-
value={formData.welcomeMessage}
457-
onChange={(e) => updateField('welcomeMessage', e.target.value)}
458-
rows={3}
459-
disabled={chatSubmitting}
460-
className='min-h-[80px]'
461-
/>
462-
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
463-
This message will be displayed when users first open the chat
464-
</p>
465-
</div>
435+
<ChipModalField
436+
type='textarea'
437+
title='Welcome message'
438+
placeholder='Enter a welcome message for your chat'
439+
value={formData.welcomeMessage}
440+
onChange={(value) => updateField('welcomeMessage', value)}
441+
rows={3}
442+
disabled={chatSubmitting}
443+
minHeight={80}
444+
hint='This message will be displayed when users first open the chat'
445+
/>
466446

467447
<button
468448
type='button'
@@ -516,7 +496,7 @@ export function ChatDeploy({
516496

517497
function LoadingSkeleton() {
518498
return (
519-
<div className='-mx-1 space-y-4 px-1'>
499+
<div className='space-y-4 px-2'>
520500
<div className='space-y-3'>
521501
<div>
522502
<Skeleton className='mb-[6.5px] h-[16px] w-[26px]' />
@@ -586,7 +566,7 @@ function IdentifierInput({
586566
const displayUrl = fullUrl.replace(/^https?:\/\//, '')
587567

588568
return (
589-
<div>
569+
<div className='px-2'>
590570
<Label
591571
htmlFor='chat-url'
592572
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
@@ -729,7 +709,7 @@ function AuthSelector({
729709
}, [authOptions, authType, onAuthTypeChange])
730710

731711
return (
732-
<div className='space-y-4'>
712+
<div className='space-y-4 px-2'>
733713
<div>
734714
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
735715
Access control

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx‎

Lines changed: 85 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
'use client'
22

3-
import { useCallback, useEffect, useMemo, useState } from 'react'
3+
import { useCallback, useEffect, useId, useMemo, useState } from 'react'
44
import {
55
Badge,
66
Chip,
77
ChipCombobox,
88
ChipInput,
9-
ChipTextarea,
9+
ChipModalField,
1010
type ComboboxOption,
11-
cn,
12-
Label,
1311
Skeleton,
1412
} from '@sim/emcn'
1513
import { createLogger } from '@sim/logger'
@@ -133,6 +131,7 @@ export function McpDeploy({
133131
onActiveServerChange,
134132
}: McpDeployProps) {
135133
const params = useParams()
134+
const toolNameId = useId()
136135
const workspaceId = params.workspaceId as string
137136
const [showCreateModal, setShowCreateModal] = useState(false)
138137

@@ -480,7 +479,7 @@ export function McpDeploy({
480479

481480
if (isLoadingServers || (isLoadingDeployedState && !deployedState)) {
482481
return (
483-
<div className='-mx-1 space-y-4 px-1'>
482+
<div className='space-y-4 px-2'>
484483
<div className='space-y-3'>
485484
<div>
486485
<Skeleton className='mb-[6.5px] h-[16px] w-[70px]' />
@@ -522,7 +521,7 @@ export function McpDeploy({
522521
return (
523522
<form
524523
id='mcp-deploy-form'
525-
className='-mx-1 space-y-3 px-1'
524+
className='space-y-3'
526525
onSubmit={(e) => {
527526
e.preventDefault()
528527
handleSave()
@@ -540,49 +539,41 @@ export function McpDeploy({
540539
/>
541540
))}
542541

543-
<div>
544-
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
545-
Tool name
546-
</Label>
547-
<ChipInput
548-
value={toolName}
549-
onChange={(e) => setToolName(e.target.value)}
550-
placeholder='e.g., book_flight'
551-
aria-invalid={!!toolNameError}
552-
error={Boolean(toolNameError)}
553-
/>
554-
<p
555-
className={cn(
556-
'mt-[6.5px] text-xs',
557-
toolNameError ? 'text-[var(--text-error)]' : 'text-[var(--text-secondary)]'
558-
)}
559-
>
560-
{toolNameError ?? 'Use lowercase letters, numbers, and underscores only'}
561-
</p>
562-
</div>
563-
564-
<div>
565-
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
566-
Description
567-
</Label>
568-
<ChipTextarea
569-
placeholder={
570-
workflowDescriptionFallback
571-
? `Defaults to the workflow description: ${workflowDescriptionFallback}`
572-
: 'Describe what this tool does...'
573-
}
574-
className='min-h-[100px]'
575-
value={toolDescription}
576-
onChange={(e) => setToolDescription(e.target.value)}
577-
/>
578-
</div>
542+
<ChipModalField
543+
type='custom'
544+
title='Tool name'
545+
htmlFor={toolNameId}
546+
error={toolNameError}
547+
hint='Use lowercase letters, numbers, and underscores only'
548+
>
549+
{(aria) => (
550+
<ChipInput
551+
id={toolNameId}
552+
value={toolName}
553+
onChange={(e) => setToolName(e.target.value)}
554+
placeholder='e.g., book_flight'
555+
error={Boolean(toolNameError)}
556+
{...aria}
557+
/>
558+
)}
559+
</ChipModalField>
560+
561+
<ChipModalField
562+
type='textarea'
563+
title='Description'
564+
placeholder={
565+
workflowDescriptionFallback
566+
? `Defaults to the workflow description: ${workflowDescriptionFallback}`
567+
: 'Describe what this tool does...'
568+
}
569+
minHeight={100}
570+
value={toolDescription}
571+
onChange={setToolDescription}
572+
/>
579573

580574
{inputFormat.length > 0 && (
581-
<div>
582-
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
583-
Parameters ({inputFormat.length})
584-
</Label>
585-
<p className='mb-[6.5px] pl-0.5 text-[var(--text-secondary)] text-xs'>
575+
<ChipModalField type='custom' title={`Parameters (${inputFormat.length})`}>
576+
<p className='pl-0.5 text-[var(--text-secondary)] text-xs'>
586577
Descriptions default to your Start block inputs; edit to override for this tool.
587578
</p>
588579
<div className='flex flex-col gap-2'>
@@ -602,60 +593,61 @@ export function McpDeploy({
602593
</div>
603594
</div>
604595
<div className='rounded-b-[4px] border-[var(--border-1)] border-t bg-[var(--surface-2)] px-2.5 pt-1.5 pb-2.5'>
605-
<div className='flex flex-col gap-1.5'>
606-
<Label className='text-small'>Description</Label>
607-
<ChipInput
608-
value={
609-
parameterDescriptions[field.name] ??
610-
startBlockDescriptions[field.name] ??
611-
''
612-
}
613-
onChange={(e) =>
614-
setParameterDescriptions((prev) => ({
615-
...prev,
616-
[field.name]: e.target.value,
617-
}))
618-
}
619-
placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`}
620-
/>
621-
</div>
596+
<ChipModalField
597+
type='input'
598+
title='Description'
599+
flush
600+
value={
601+
parameterDescriptions[field.name] ?? startBlockDescriptions[field.name] ?? ''
602+
}
603+
onChange={(value) =>
604+
setParameterDescriptions((prev) => ({
605+
...prev,
606+
[field.name]: value,
607+
}))
608+
}
609+
placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`}
610+
/>
622611
</div>
623612
</div>
624613
))}
625614
</div>
626-
</div>
615+
</ChipModalField>
627616
)}
628617

629-
<div>
630-
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
631-
Servers
632-
</Label>
633-
<ChipCombobox
634-
options={serverOptions}
635-
multiSelect
636-
multiSelectValues={selectedServerIdsForForm}
637-
onMultiSelectChange={handleServerSelectionChange}
638-
placeholder='Select servers...'
639-
searchable
640-
searchPlaceholder='Search servers...'
641-
disabled={!toolName.trim() || !!toolNameError || isPending}
642-
overlayContent={
643-
<span className='truncate text-[var(--text-primary)]'>{selectedServersLabel}</span>
644-
}
645-
/>
646-
{!toolName.trim() ? (
647-
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
648-
Enter a tool name to select servers
649-
</p>
650-
) : toolNameError ? (
651-
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
652-
Fix the tool name to select servers
653-
</p>
654-
) : null}
655-
</div>
618+
<ChipModalField
619+
type='custom'
620+
title='Servers'
621+
submitOnEnter={false}
622+
hint={
623+
!toolName.trim()
624+
? 'Enter a tool name to select servers'
625+
: toolNameError
626+
? 'Fix the tool name to select servers'
627+
: undefined
628+
}
629+
>
630+
{(aria) => (
631+
<ChipCombobox
632+
aria-label='Servers'
633+
{...aria}
634+
options={serverOptions}
635+
multiSelect
636+
multiSelectValues={selectedServerIdsForForm}
637+
onMultiSelectChange={handleServerSelectionChange}
638+
placeholder='Select servers...'
639+
searchable
640+
searchPlaceholder='Search servers...'
641+
disabled={!toolName.trim() || !!toolNameError || isPending}
642+
overlayContent={
643+
<span className='truncate text-[var(--text-primary)]'>{selectedServersLabel}</span>
644+
}
645+
/>
646+
)}
647+
</ChipModalField>
656648

657649
{saveErrors.length > 0 && (
658-
<div className='mt-[6.5px] flex flex-col gap-0.5'>
650+
<div className='mt-[6.5px] flex flex-col gap-0.5 px-2'>
659651
{saveErrors.map((error) => (
660652
<p key={error} className='text-[var(--text-error)] text-caption'>
661653
{error}

0 commit comments

Comments
 (0)