Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
ChipConfirmModal,
ChipEmailsInput,
ChipInput,
ChipTextarea,
ChipModalField,
cn,
Input,
Label,
Expand Down Expand Up @@ -335,12 +335,7 @@ export function ChatDeploy({

return (
<>
<form
id='chat-deploy-form'
ref={formRef}
onSubmit={handleSubmit}
className='-mx-1 space-y-4 px-1'
>
<form id='chat-deploy-form' ref={formRef} onSubmit={handleSubmit} className='space-y-4'>
{errors.general && (
<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'>
<TriangleAlert className='size-4 shrink-0' />
Expand All @@ -358,27 +353,21 @@ export function ChatDeploy({
isEditingExisting={!!existingChat}
/>

<div>
<Label
htmlFor='title'
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
>
Title
</Label>
<ChipInput
id='title'
placeholder='Customer Support Assistant'
value={formData.title}
onChange={(e) => updateField('title', e.target.value)}
required
disabled={chatSubmitting}
/>
{errors.title && (
<p className='mt-[6.5px] text-[var(--text-error)] text-caption'>{errors.title}</p>
<ChipModalField type='custom' title='Title' htmlFor='title' error={errors.title}>
{(aria) => (
<ChipInput
id='title'
placeholder='Customer Support Assistant'
value={formData.title}
onChange={(e) => updateField('title', e.target.value)}
required
disabled={chatSubmitting}
{...aria}
/>
)}
</div>
</ChipModalField>

<div>
<div className='px-2'>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Output
</Label>
Expand All @@ -400,7 +389,7 @@ export function ChatDeploy({
)}
</div>

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

<div className='flex items-center justify-between gap-3'>
<div className='flex items-center justify-between gap-3 px-2'>
<div className='min-w-0'>
<Label className='block pl-0.5 text-[var(--text-primary)] text-small'>
Include tool calls
Expand Down Expand Up @@ -443,26 +432,17 @@ export function ChatDeploy({
hasExistingPassword={existingPassword}
error={errors.password || errors.emails}
/>
<div>
<Label
htmlFor='welcomeMessage'
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
>
Welcome message
</Label>
<ChipTextarea
id='welcomeMessage'
placeholder='Enter a welcome message for your chat'
value={formData.welcomeMessage}
onChange={(e) => updateField('welcomeMessage', e.target.value)}
rows={3}
disabled={chatSubmitting}
className='min-h-[80px]'
/>
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
This message will be displayed when users first open the chat
</p>
</div>
<ChipModalField
type='textarea'
title='Welcome message'
placeholder='Enter a welcome message for your chat'
value={formData.welcomeMessage}
onChange={(value) => updateField('welcomeMessage', value)}
rows={3}
disabled={chatSubmitting}
minHeight={80}
hint='This message will be displayed when users first open the chat'
/>

<button
type='button'
Expand Down Expand Up @@ -516,7 +496,7 @@ export function ChatDeploy({

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

return (
<div>
<div className='px-2'>
<Label
htmlFor='chat-url'
className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'
Expand Down Expand Up @@ -729,7 +709,7 @@ function AuthSelector({
}, [authOptions, authType, onAuthTypeChange])

return (
<div className='space-y-4'>
<div className='space-y-4 px-2'>
<div>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Access control
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
'use client'

import { useCallback, useEffect, useMemo, useState } from 'react'
import { useCallback, useEffect, useId, useMemo, useState } from 'react'
import {
Badge,
Chip,
ChipCombobox,
ChipInput,
ChipTextarea,
ChipModalField,
type ComboboxOption,
cn,
Label,
Skeleton,
} from '@sim/emcn'
import { createLogger } from '@sim/logger'
Expand Down Expand Up @@ -133,6 +131,7 @@ export function McpDeploy({
onActiveServerChange,
}: McpDeployProps) {
const params = useParams()
const toolNameId = useId()
const workspaceId = params.workspaceId as string
const [showCreateModal, setShowCreateModal] = useState(false)

Expand Down Expand Up @@ -480,7 +479,7 @@ export function McpDeploy({

if (isLoadingServers || (isLoadingDeployedState && !deployedState)) {
return (
<div className='-mx-1 space-y-4 px-1'>
<div className='space-y-4 px-2'>
<div className='space-y-3'>
<div>
<Skeleton className='mb-[6.5px] h-[16px] w-[70px]' />
Expand Down Expand Up @@ -522,7 +521,7 @@ export function McpDeploy({
return (
<form
id='mcp-deploy-form'
className='-mx-1 space-y-3 px-1'
className='space-y-3'
onSubmit={(e) => {
e.preventDefault()
handleSave()
Expand All @@ -540,49 +539,41 @@ export function McpDeploy({
/>
))}

<div>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Tool name
</Label>
<ChipInput
value={toolName}
onChange={(e) => setToolName(e.target.value)}
placeholder='e.g., book_flight'
aria-invalid={!!toolNameError}
error={Boolean(toolNameError)}
/>
<p
className={cn(
'mt-[6.5px] text-xs',
toolNameError ? 'text-[var(--text-error)]' : 'text-[var(--text-secondary)]'
)}
>
{toolNameError ?? 'Use lowercase letters, numbers, and underscores only'}
</p>
</div>

<div>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Description
</Label>
<ChipTextarea
placeholder={
workflowDescriptionFallback
? `Defaults to the workflow description: ${workflowDescriptionFallback}`
: 'Describe what this tool does...'
}
className='min-h-[100px]'
value={toolDescription}
onChange={(e) => setToolDescription(e.target.value)}
/>
</div>
<ChipModalField
type='custom'
title='Tool name'
htmlFor={toolNameId}
error={toolNameError}
hint='Use lowercase letters, numbers, and underscores only'
>
{(aria) => (
<ChipInput
id={toolNameId}
value={toolName}
onChange={(e) => setToolName(e.target.value)}
placeholder='e.g., book_flight'
error={Boolean(toolNameError)}
{...aria}
/>
)}
</ChipModalField>

<ChipModalField
type='textarea'
title='Description'
placeholder={
workflowDescriptionFallback
? `Defaults to the workflow description: ${workflowDescriptionFallback}`
: 'Describe what this tool does...'
}
minHeight={100}
value={toolDescription}
onChange={setToolDescription}
/>

{inputFormat.length > 0 && (
<div>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Parameters ({inputFormat.length})
</Label>
<p className='mb-[6.5px] pl-0.5 text-[var(--text-secondary)] text-xs'>
<ChipModalField type='custom' title={`Parameters (${inputFormat.length})`}>
<p className='pl-0.5 text-[var(--text-secondary)] text-xs'>
Descriptions default to your Start block inputs; edit to override for this tool.
</p>
<div className='flex flex-col gap-2'>
Expand All @@ -602,60 +593,61 @@ export function McpDeploy({
</div>
</div>
<div className='rounded-b-[4px] border-[var(--border-1)] border-t bg-[var(--surface-2)] px-2.5 pt-1.5 pb-2.5'>
<div className='flex flex-col gap-1.5'>
<Label className='text-small'>Description</Label>
<ChipInput
value={
parameterDescriptions[field.name] ??
startBlockDescriptions[field.name] ??
''
}
onChange={(e) =>
setParameterDescriptions((prev) => ({
...prev,
[field.name]: e.target.value,
}))
}
placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`}
/>
</div>
<ChipModalField
type='input'
title='Description'
flush
value={
parameterDescriptions[field.name] ?? startBlockDescriptions[field.name] ?? ''
}
onChange={(value) =>
setParameterDescriptions((prev) => ({
...prev,
[field.name]: value,
}))
}
placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`}
/>
</div>
</div>
))}
</div>
</div>
</ChipModalField>
)}

<div>
<Label className='mb-[6.5px] block pl-0.5 text-[var(--text-primary)] text-small'>
Servers
</Label>
<ChipCombobox
options={serverOptions}
multiSelect
multiSelectValues={selectedServerIdsForForm}
onMultiSelectChange={handleServerSelectionChange}
placeholder='Select servers...'
searchable
searchPlaceholder='Search servers...'
disabled={!toolName.trim() || !!toolNameError || isPending}
overlayContent={
<span className='truncate text-[var(--text-primary)]'>{selectedServersLabel}</span>
}
/>
{!toolName.trim() ? (
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
Enter a tool name to select servers
</p>
) : toolNameError ? (
<p className='mt-[6.5px] text-[var(--text-secondary)] text-xs'>
Fix the tool name to select servers
</p>
) : null}
</div>
<ChipModalField
type='custom'
title='Servers'
submitOnEnter={false}
hint={
!toolName.trim()
? 'Enter a tool name to select servers'
: toolNameError
? 'Fix the tool name to select servers'
: undefined
}
>
{(aria) => (
<ChipCombobox
aria-label='Servers'
{...aria}
options={serverOptions}
multiSelect
multiSelectValues={selectedServerIdsForForm}
onMultiSelectChange={handleServerSelectionChange}
placeholder='Select servers...'
searchable
searchPlaceholder='Search servers...'
disabled={!toolName.trim() || !!toolNameError || isPending}
overlayContent={
<span className='truncate text-[var(--text-primary)]'>{selectedServersLabel}</span>
}
/>
)}
</ChipModalField>

{saveErrors.length > 0 && (
<div className='mt-[6.5px] flex flex-col gap-0.5'>
<div className='mt-[6.5px] flex flex-col gap-0.5 px-2'>
{saveErrors.map((error) => (
<p key={error} className='text-[var(--text-error)] text-caption'>
{error}
Expand Down
Loading
Loading