Skip to content

Commit b8c83e8

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
refactor(ui): share static API and MCP parameter cards
1 parent ffd56d1 commit b8c83e8

21 files changed

Lines changed: 308 additions & 295 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers.tsx‎

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
ChipSelect,
1919
Code,
2020
type ComboboxOption,
21+
FieldCard,
2122
Label,
2223
useCopyToClipboard,
2324
} from '@sim/emcn'
@@ -713,36 +714,29 @@ function ServerDetailView({
713714
return hasParams ? (
714715
<div className='flex flex-col gap-2'>
715716
{Object.entries(properties).map(([name, prop]) => (
716-
<div
717+
<FieldCard
717718
key={name}
718-
className='overflow-hidden rounded-sm border border-[var(--border-1)]'
719+
title={name}
720+
badge={
721+
<Badge variant='type' size='sm'>
722+
{prop.type || 'any'}
723+
</Badge>
724+
}
719725
>
720-
<div className='flex items-center justify-between bg-[var(--surface-4)] px-2.5 py-[5px]'>
721-
<div className='flex min-w-0 flex-1 items-center gap-2'>
722-
<span className='block truncate text-[var(--text-tertiary)] text-base'>
723-
{name}
724-
</span>
725-
<Badge variant='type' size='sm'>
726-
{prop.type || 'any'}
727-
</Badge>
728-
</div>
729-
</div>
730-
<div className='rounded-b-[4px] border-[var(--border-1)] border-t bg-[var(--surface-2)] px-2.5 pt-1.5 pb-2.5'>
731-
<div className='flex flex-col gap-1.5'>
732-
<Label>Description</Label>
733-
<ChipInput
734-
value={editingParameterDescriptions[name] || ''}
735-
onChange={(e) =>
736-
setEditingParameterDescriptions((prev) => ({
737-
...prev,
738-
[name]: e.target.value,
739-
}))
740-
}
741-
placeholder={`Enter description for ${name}`}
742-
/>
743-
</div>
726+
<div className='flex flex-col gap-1.5'>
727+
<Label>Description</Label>
728+
<ChipInput
729+
value={editingParameterDescriptions[name] || ''}
730+
onChange={(e) =>
731+
setEditingParameterDescriptions((prev) => ({
732+
...prev,
733+
[name]: e.target.value,
734+
}))
735+
}
736+
placeholder={`Enter description for ${name}`}
737+
/>
744738
</div>
745-
</div>
739+
</FieldCard>
746740
))}
747741
</div>
748742
) : (

‎apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/data-row.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,11 @@ export const DataRow = React.memo(function DataRow({
287287
{hasWorkflowColumns && (
288288
<Button
289289
type='button'
290-
variant='ghost'
291-
size='sm'
290+
variant='quiet'
291+
size='icon'
292292
aria-label={runningCount > 0 ? `Stop ${runningCount} running` : 'Run row'}
293293
title={runningCount > 0 ? `Stop ${runningCount} running` : 'Run row'}
294-
className='size-[20px] shrink-0 p-0 text-[var(--text-primary)] hover-hover:bg-[var(--surface-2)]'
294+
className='shrink-0'
295295
onClick={() => {
296296
if (runningCount > 0) {
297297
onStopRow(row.id)

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

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ChipModalField,
1414
ChipModalFooter,
1515
ChipModalHeader,
16+
FieldCard,
1617
Label,
1718
} from '@sim/emcn'
1819
import { getErrorMessage } from '@sim/utils/errors'
@@ -237,31 +238,24 @@ export function ApiInfoModal({ open, onOpenChange, workflowId }: ApiInfoModalPro
237238
<ChipModalField type='custom' title={`Parameters (${inputFormat.length})`}>
238239
<div className='flex flex-col gap-2'>
239240
{inputFormat.map((field) => (
240-
<div
241+
<FieldCard
241242
key={field.name}
242-
className='overflow-hidden rounded-sm border border-[var(--border-1)]'
243+
title={field.name}
244+
badge={
245+
<Badge variant='type' size='sm'>
246+
{field.type || 'string'}
247+
</Badge>
248+
}
243249
>
244-
<div className='flex items-center justify-between bg-[var(--surface-4)] px-2.5 py-[5px]'>
245-
<div className='flex min-w-0 flex-1 items-center gap-2'>
246-
<span className='block truncate text-[var(--text-tertiary)] text-sm'>
247-
{field.name}
248-
</span>
249-
<Badge variant='type' size='sm'>
250-
{field.type || 'string'}
251-
</Badge>
252-
</div>
250+
<div className='flex flex-col gap-1.5'>
251+
<Label className='text-small'>Description</Label>
252+
<ChipInput
253+
value={paramDescriptions[field.name] || ''}
254+
onChange={(e) => handleParamDescriptionChange(field.name, e.target.value)}
255+
placeholder={`Enter description for ${field.name}`}
256+
/>
253257
</div>
254-
<div className='rounded-b-[4px] border-[var(--border-1)] border-t bg-[var(--surface-2)] px-2.5 pt-1.5 pb-2.5'>
255-
<div className='flex flex-col gap-1.5'>
256-
<Label className='text-small'>Description</Label>
257-
<ChipInput
258-
value={paramDescriptions[field.name] || ''}
259-
onChange={(e) => handleParamDescriptionChange(field.name, e.target.value)}
260-
placeholder={`Enter description for ${field.name}`}
261-
/>
262-
</div>
263-
</div>
264-
</div>
258+
</FieldCard>
265259
))}
266260
</div>
267261
</ChipModalField>

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

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
ChipInput,
99
ChipModalField,
1010
type ComboboxOption,
11+
FieldCard,
1112
Skeleton,
1213
} from '@sim/emcn'
1314
import { createLogger } from '@sim/logger'
@@ -578,38 +579,31 @@ export function McpDeploy({
578579
</p>
579580
<div className='flex flex-col gap-2'>
580581
{inputFormat.map((field) => (
581-
<div
582+
<FieldCard
582583
key={field.name}
583-
className='overflow-hidden rounded-sm border border-[var(--border-1)]'
584+
title={field.name}
585+
badge={
586+
<Badge variant='type' size='sm'>
587+
{field.type}
588+
</Badge>
589+
}
584590
>
585-
<div className='flex items-center justify-between bg-[var(--surface-4)] px-2.5 py-[5px]'>
586-
<div className='flex min-w-0 flex-1 items-center gap-2'>
587-
<span className='block truncate text-[var(--text-tertiary)] text-sm'>
588-
{field.name}
589-
</span>
590-
<Badge variant='type' size='sm'>
591-
{field.type}
592-
</Badge>
593-
</div>
594-
</div>
595-
<div className='rounded-b-[4px] border-[var(--border-1)] border-t bg-[var(--surface-2)] px-2.5 pt-1.5 pb-2.5'>
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-
/>
611-
</div>
612-
</div>
591+
<ChipModalField
592+
type='input'
593+
title='Description'
594+
flush
595+
value={
596+
parameterDescriptions[field.name] ?? startBlockDescriptions[field.name] ?? ''
597+
}
598+
onChange={(value) =>
599+
setParameterDescriptions((prev) => ({
600+
...prev,
601+
[field.name]: value,
602+
}))
603+
}
604+
placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`}
605+
/>
606+
</FieldCard>
613607
))}
614608
</div>
615609
</ChipModalField>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/condition-input/condition-input.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ export function ConditionInput({
966966
disabled ||
967967
(!isRouterMode && isElseConditionTitle(block.title))
968968
}
969-
className='h-auto p-0'
969+
size='icon'
970970
>
971971
<Plus className='size-[14px]' />
972972
<span className='sr-only'>Add Block</span>
@@ -986,7 +986,7 @@ export function ConditionInput({
986986
disabled ||
987987
(!isRouterMode && isElseConditionTitle(block.title))
988988
}
989-
className='h-auto p-0'
989+
size='icon'
990990
>
991991
<ChevronUp className='size-[14px]' />
992992
<span className='sr-only'>Move Up</span>
@@ -1008,7 +1008,7 @@ export function ConditionInput({
10081008
isElseConditionTitle(conditionalBlocks[index + 1]?.title)) ||
10091009
(!isRouterMode && isElseConditionTitle(block.title))
10101010
}
1011-
className='h-auto p-0'
1011+
size='icon'
10121012
>
10131013
<ChevronDown className='size-[14px]' />
10141014
<span className='sr-only'>Move Down</span>
@@ -1025,7 +1025,7 @@ export function ConditionInput({
10251025
disabled={
10261026
isPreview || disabled || conditionalBlocks.length <= (isRouterMode ? 1 : 2)
10271027
}
1028-
className='h-auto p-0'
1028+
size='icon'
10291029
>
10301030
<Trash className='size-[14px]' />
10311031
<span className='sr-only'>Delete Block</span>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/document-tag-entry/document-tag-entry.tsx‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,15 @@ export function DocumentTagEntry({
257257

258258
const renderActions = (tag: DocumentTag) => (
259259
<>
260-
<Button
261-
variant='ghost'
262-
onClick={addTag}
263-
disabled={isReadOnly || !canAddMoreTags}
264-
className='h-auto p-0'
265-
>
260+
<Button variant='ghost' onClick={addTag} disabled={isReadOnly || !canAddMoreTags} size='icon'>
266261
<Plus className='size-[14px]' />
267262
<span className='sr-only'>Add Tag</span>
268263
</Button>
269264
<Button
270265
variant='ghost-destructive'
271266
onClick={() => removeTag(tag.id)}
272267
disabled={isReadOnly}
273-
className='h-auto p-0'
268+
size='icon'
274269
>
275270
<Trash className='size-[14px]' />
276271
<span className='sr-only'>Delete Tag</span>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function EvalInput({
147147
variant='ghost'
148148
onClick={addMetric}
149149
disabled={isPreview || disabled}
150-
className='h-auto p-0'
150+
size='icon'
151151
>
152152
<Plus className='size-[14px]' />
153153
<span className='sr-only'>Add Metric</span>
@@ -162,7 +162,7 @@ export function EvalInput({
162162
variant='ghost-destructive'
163163
onClick={() => removeMetric(metric.id)}
164164
disabled={isPreview || disabled || metrics.length === 1}
165-
className='h-auto p-0'
165+
size='icon'
166166
>
167167
<Trash className='size-[14px]' />
168168
<span className='sr-only'>Delete Metric</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { ButtonHTMLAttributes } from 'react'
2+
import { cn, Tooltip } from '@sim/emcn'
3+
import { ArrowLeftRight } from '@sim/emcn/icons'
4+
5+
interface FieldModeToggleProps {
6+
label: string
7+
active: boolean
8+
disabled?: boolean
9+
onClick: ButtonHTMLAttributes<HTMLButtonElement>['onClick']
10+
}
11+
12+
/** Shared field-mode affordance; the caller owns the mode and its stored values. */
13+
export function FieldModeToggle({ label, active, disabled, onClick }: FieldModeToggleProps) {
14+
return (
15+
<Tooltip.Root>
16+
<Tooltip.Trigger asChild>
17+
<button
18+
type='button'
19+
className='flex size-[12px] shrink-0 items-center justify-center bg-transparent p-0 focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--text-muted)_30%,transparent)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--surface-2)] disabled:cursor-not-allowed disabled:opacity-50'
20+
onClick={onClick}
21+
disabled={disabled}
22+
aria-label={label}
23+
>
24+
<ArrowLeftRight
25+
className={cn(
26+
'size-[12px]! transition-colors',
27+
active ? 'text-[var(--text-primary)]' : 'text-[var(--text-secondary)]'
28+
)}
29+
/>
30+
</button>
31+
</Tooltip.Trigger>
32+
<Tooltip.Content side='top'>
33+
<p>{label}</p>
34+
</Tooltip.Content>
35+
</Tooltip.Root>
36+
)
37+
}

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/components/filter-rule-row.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ export function FilterRuleRow({
129129

130130
const renderActions = () => (
131131
<>
132-
<Button variant='ghost' onClick={onAdd} disabled={isReadOnly} className='h-auto p-0'>
132+
<Button variant='ghost' onClick={onAdd} disabled={isReadOnly} size='icon'>
133133
<Plus className='size-[14px]' />
134134
<span className='sr-only'>Add Condition</span>
135135
</Button>
136136
<Button
137137
variant='ghost-destructive'
138138
onClick={() => onRemove(rule.id)}
139139
disabled={isReadOnly}
140-
className='h-auto p-0'
140+
size='icon'
141141
>
142142
<Trash className='size-[14px]' />
143143
<span className='sr-only'>Delete Condition</span>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/knowledge-tag-filters/knowledge-tag-filters.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ export function KnowledgeTagFilters({
257257
addFilter()
258258
}}
259259
disabled={isReadOnly}
260-
className='h-auto p-0'
260+
size='icon'
261261
>
262262
<Plus className='size-[14px]' />
263263
<span className='sr-only'>Add Filter</span>
@@ -269,7 +269,7 @@ export function KnowledgeTagFilters({
269269
removeFilter(filter.id)
270270
}}
271271
disabled={isReadOnly}
272-
className='h-auto p-0'
272+
size='icon'
273273
>
274274
<Trash className='size-[14px]' />
275275
<span className='sr-only'>Delete Filter</span>

0 commit comments

Comments
 (0)