From 075e2361e313c2021fe4a0c07175d24a361ac1a6 Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos Date: Sat, 19 Sep 2026 12:47:05 -0700 Subject: [PATCH 1/3] refactor(ui): share static API and MCP parameter cards --- .../workflow-mcp-servers.tsx | 48 ++++---- .../general/components/api-info-modal.tsx | 38 +++---- .../deploy-modal/components/mcp/mcp.tsx | 54 ++++----- .../collapsible-card.test.tsx | 18 ++- .../collapsible-card/collapsible-card.tsx | 104 ++++++++---------- .../src/components/field-card/field-card.tsx | 74 +++++++++++++ packages/emcn/src/components/index.ts | 1 + 7 files changed, 200 insertions(+), 137 deletions(-) create mode 100644 packages/emcn/src/components/field-card/field-card.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers.tsx index 8e60c534209..15811dc6306 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers.tsx @@ -18,6 +18,7 @@ import { ChipSelect, Code, type ComboboxOption, + FieldCard, Label, useCopyToClipboard, } from '@sim/emcn' @@ -713,36 +714,29 @@ function ServerDetailView({ return hasParams ? (
{Object.entries(properties).map(([name, prop]) => ( -
+ {prop.type || 'any'} + + } > -
-
- - {name} - - - {prop.type || 'any'} - -
-
-
-
- - - setEditingParameterDescriptions((prev) => ({ - ...prev, - [name]: e.target.value, - })) - } - placeholder={`Enter description for ${name}`} - /> -
+
+ + + setEditingParameterDescriptions((prev) => ({ + ...prev, + [name]: e.target.value, + })) + } + placeholder={`Enter description for ${name}`} + />
-
+ ))}
) : ( diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/general/components/api-info-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/general/components/api-info-modal.tsx index 7a21bfd9882..255f810eb13 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/general/components/api-info-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/general/components/api-info-modal.tsx @@ -13,6 +13,7 @@ import { ChipModalField, ChipModalFooter, ChipModalHeader, + FieldCard, Label, } from '@sim/emcn' import { getErrorMessage } from '@sim/utils/errors' @@ -237,31 +238,24 @@ export function ApiInfoModal({ open, onOpenChange, workflowId }: ApiInfoModalPro
{inputFormat.map((field) => ( -
+ {field.type || 'string'} + + } > -
-
- - {field.name} - - - {field.type || 'string'} - -
+
+ + handleParamDescriptionChange(field.name, e.target.value)} + placeholder={`Enter description for ${field.name}`} + />
-
-
- - handleParamDescriptionChange(field.name, e.target.value)} - placeholder={`Enter description for ${field.name}`} - /> -
-
-
+ ))}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx index b02d1cc1606..353ed8aad66 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx @@ -8,6 +8,7 @@ import { ChipInput, ChipModalField, type ComboboxOption, + FieldCard, Skeleton, } from '@sim/emcn' import { createLogger } from '@sim/logger' @@ -578,38 +579,31 @@ export function McpDeploy({

{inputFormat.map((field) => ( -
+ {field.type} + + } > -
-
- - {field.name} - - - {field.type} - -
-
-
- - setParameterDescriptions((prev) => ({ - ...prev, - [field.name]: value, - })) - } - placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`} - /> -
-
+ + setParameterDescriptions((prev) => ({ + ...prev, + [field.name]: value, + })) + } + placeholder={startBlockDescriptions[field.name] || `Describe ${field.name}`} + /> + ))}
diff --git a/packages/emcn/src/components/collapsible-card/collapsible-card.test.tsx b/packages/emcn/src/components/collapsible-card/collapsible-card.test.tsx index 2a46d78eaef..a61dba4b2eb 100644 --- a/packages/emcn/src/components/collapsible-card/collapsible-card.test.tsx +++ b/packages/emcn/src/components/collapsible-card/collapsible-card.test.tsx @@ -1,6 +1,6 @@ /** @vitest-environment jsdom */ import { act, type ReactNode, useState } from 'react' -import { CollapsibleCard } from '@sim/emcn' +import { CollapsibleCard, FieldCard } from '@sim/emcn' import { createRoot, type Root } from 'react-dom/client' import { afterEach, describe, expect, it, vi } from 'vitest' @@ -103,3 +103,19 @@ describe('CollapsibleCard', () => { expect(parentClick).not.toHaveBeenCalled() }) }) + +it('keeps static FieldCard content visible without a collapse target', () => { + mount( + string} data-field='query'> + + + ) + const card = container!.querySelector('[data-field="query"]')! + const input = card.querySelector('input')! + expect(card.textContent).toContain('query') + expect(card.textContent).toContain('string') + expect(card.querySelector('[role="button"], button, [aria-expanded]')).toBeNull() + act(() => card.querySelector('[data-overflow-text]')!.click()) + expect(card.querySelector('input')).toBe(input) + expect(input.value).toBe('Search terms') +}) diff --git a/packages/emcn/src/components/collapsible-card/collapsible-card.tsx b/packages/emcn/src/components/collapsible-card/collapsible-card.tsx index a2e9a640c68..9104661a7ea 100644 --- a/packages/emcn/src/components/collapsible-card/collapsible-card.tsx +++ b/packages/emcn/src/components/collapsible-card/collapsible-card.tsx @@ -4,6 +4,7 @@ import type * as React from 'react' import { cn } from '../../lib/cn' import { handleKeyboardActivation } from '../../lib/keyboard' import { Expandable, ExpandableContent } from '../expandable/expandable' +import { FieldCardContent, FieldCardFrame } from '../field-card/field-card' import { OverflowText, overflowTextClipClass } from '../overflow-text/overflow-text' export interface CollapsibleCardProps @@ -28,6 +29,7 @@ export interface CollapsibleCardProps * A collapsible field card: a `--surface-4` header (click / keyboard to toggle) * with a fade-clipped title + optional badge, over a `--surface-2` body. Shared by * the workflow input-mapping rows and the enrichment output-column config. + * Its frame and body are also used by the always-open FieldCard. * * @example * - {children} -
- ) + const content = {children} return ( -
-
-
{ - if (event.target !== event.currentTarget) return - handleKeyboardActivation(event, onToggleCollapse) - }} - > - {typeof title === 'string' || typeof title === 'number' ? ( - - ) : ( - - {title} - - )} - {badge} -
- {actions && ( + className={cn(collapsed ? 'overflow-hidden' : 'overflow-visible', className)} + header={ + <>
event.stopPropagation()} + role='button' + tabIndex={0} + aria-expanded={!collapsed} + aria-controls={contentProps?.id} + className={cn( + 'flex min-w-0 flex-1 cursor-pointer items-center gap-2 px-2.5 py-[5px]', + actions && 'pr-2' + )} + onClick={onToggleCollapse} + onKeyDown={(event) => { + if (event.target !== event.currentTarget) return + handleKeyboardActivation(event, onToggleCollapse) + }} > - {actions} + {typeof title === 'string' || typeof title === 'number' ? ( + + ) : ( + + {title} + + )} + {badge}
- )} -
+ {actions && ( +
event.stopPropagation()} + > + {actions} +
+ )} + + } + > {animated ? ( {content} @@ -115,6 +105,6 @@ export function CollapsibleCard({ ) : ( !collapsed && content )} -
+ ) } diff --git a/packages/emcn/src/components/field-card/field-card.tsx b/packages/emcn/src/components/field-card/field-card.tsx new file mode 100644 index 00000000000..c5f05745635 --- /dev/null +++ b/packages/emcn/src/components/field-card/field-card.tsx @@ -0,0 +1,74 @@ +import type * as React from 'react' +import { cn } from '../../lib/cn' +import { OverflowText, overflowTextClipClass } from '../overflow-text/overflow-text' + +export interface FieldCardProps + extends Omit, 'title' | 'children'> { + /** Field name; plain text uses the standard fade and full-value tooltip. */ + title: React.ReactNode + /** Optional content adjacent to the field name, such as a type badge. */ + badge?: React.ReactNode + /** Always-visible field controls or description. */ + children: React.ReactNode +} + +interface FieldCardFrameProps extends React.HTMLAttributes { + header: React.ReactNode +} + +/** Internal frame shared by static and collapsible field cards. */ +export function FieldCardFrame({ header, children, className, ...props }: FieldCardFrameProps) { + return ( +
+
+ {header} +
+ {children} +
+ ) +} + +/** Internal body shared by static and collapsible field cards. */ +export function FieldCardContent({ className, ...props }: React.HTMLAttributes) { + return ( +
+ ) +} + +/** + * An always-open field card with the same frame and body as CollapsibleCard. + * The header is a label, not a button; controls retain their own behavior. + * + * @example + * string}> + * {descriptionField} + * + */ +export function FieldCard({ title, badge, children, className, ...props }: FieldCardProps) { + return ( + + {typeof title === 'string' || typeof title === 'number' ? ( + + ) : ( + + {title} + + )} + {badge} +
+ } + > + {children} + + ) +} diff --git a/packages/emcn/src/components/index.ts b/packages/emcn/src/components/index.ts index 84ffa9b00a3..0d397af9b98 100644 --- a/packages/emcn/src/components/index.ts +++ b/packages/emcn/src/components/index.ts @@ -148,6 +148,7 @@ export { dropdownMenuRowClass, } from './dropdown-menu/dropdown-menu' export { Expandable, ExpandableContent } from './expandable/expandable' +export { FieldCard, type FieldCardProps } from './field-card/field-card' export { DashedDividerLine, FieldDivider } from './field-divider/field-divider' export { Info } from './info/info' export { From 85d3acddc7fed76f7f0a22734fa62b3455093a86 Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos <157128530+BillLeoutsakosvl346@users.noreply.github.com> Date: Sat, 19 Sep 2026 13:58:29 -0700 Subject: [PATCH 2/3] improvement(ui): standardize card header icon actions (#8033) Co-authored-by: Bill Leoutsakos --- .../components/condition-input/condition-input.tsx | 8 ++++---- .../document-tag-entry/document-tag-entry.tsx | 9 ++------- .../sub-block/components/eval-input/eval-input.tsx | 4 ++-- .../filter-builder/components/filter-rule-row.tsx | 4 ++-- .../knowledge-tag-filters/knowledge-tag-filters.tsx | 4 ++-- .../components/selector-combobox/selector-combobox.tsx | 3 ++- .../sort-builder/components/sort-rule-row.tsx | 4 ++-- .../sub-block/components/starter/input-format.tsx | 10 +++------- .../components/variables-input/variables-input.tsx | 4 ++-- .../w/[workflowId]/components/variables/variables.tsx | 2 +- 10 files changed, 22 insertions(+), 30 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/condition-input/condition-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/condition-input/condition-input.tsx index 41fccf4943f..dede5811704 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/condition-input/condition-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/condition-input/condition-input.tsx @@ -969,7 +969,7 @@ export function ConditionInput({ disabled || (!isRouterMode && isElseConditionTitle(block.title)) } - className='h-auto p-0' + size='icon' > Add Block @@ -989,7 +989,7 @@ export function ConditionInput({ disabled || (!isRouterMode && isElseConditionTitle(block.title)) } - className='h-auto p-0' + size='icon' > Move Up @@ -1011,7 +1011,7 @@ export function ConditionInput({ isElseConditionTitle(conditionalBlocks[index + 1]?.title)) || (!isRouterMode && isElseConditionTitle(block.title)) } - className='h-auto p-0' + size='icon' > Move Down @@ -1028,7 +1028,7 @@ export function ConditionInput({ disabled={ isPreview || disabled || conditionalBlocks.length <= (isRouterMode ? 1 : 2) } - className='h-auto p-0' + size='icon' > Delete Block diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/document-tag-entry/document-tag-entry.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/document-tag-entry/document-tag-entry.tsx index 7023aa4f226..9decc0cce59 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/document-tag-entry/document-tag-entry.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/document-tag-entry/document-tag-entry.tsx @@ -257,12 +257,7 @@ export function DocumentTagEntry({ const renderActions = (tag: DocumentTag) => ( <> - @@ -270,7 +265,7 @@ export function DocumentTagEntry({ variant='ghost-destructive' onClick={() => removeTag(tag.id)} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Delete Tag diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx index 652f79b6e3a..a8c87277a31 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx @@ -147,7 +147,7 @@ export function EvalInput({ variant='ghost' onClick={addMetric} disabled={isPreview || disabled} - className='h-auto p-0' + size='icon' > Add Metric @@ -162,7 +162,7 @@ export function EvalInput({ variant='ghost-destructive' onClick={() => removeMetric(metric.id)} disabled={isPreview || disabled || metrics.length === 1} - className='h-auto p-0' + size='icon' > Delete Metric diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/components/filter-rule-row.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/components/filter-rule-row.tsx index 7e0e4375b3b..33a1fc95fc7 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/components/filter-rule-row.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/components/filter-rule-row.tsx @@ -129,7 +129,7 @@ export function FilterRuleRow({ const renderActions = () => ( <> - @@ -137,7 +137,7 @@ export function FilterRuleRow({ variant='ghost-destructive' onClick={() => onRemove(rule.id)} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Delete Condition diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/knowledge-tag-filters/knowledge-tag-filters.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/knowledge-tag-filters/knowledge-tag-filters.tsx index dc4e6b62c34..0621ae5171b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/knowledge-tag-filters/knowledge-tag-filters.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/knowledge-tag-filters/knowledge-tag-filters.tsx @@ -257,7 +257,7 @@ export function KnowledgeTagFilters({ addFilter() }} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Add Filter @@ -269,7 +269,7 @@ export function KnowledgeTagFilters({ removeFilter(filter.id) }} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Delete Filter diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox.tsx index 3130bf0f9ca..c94d01c12d9 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox.tsx @@ -263,7 +263,8 @@ export function SelectorCombobox({ @@ -96,7 +96,7 @@ export function SortRuleRow({ variant='ghost-destructive' onClick={() => onRemove(rule.id)} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Delete Sort diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx index c23c18ba66c..4626149cba9 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx @@ -647,12 +647,7 @@ export function FieldFormat({ animated actions={ <> - @@ -660,7 +655,8 @@ export function FieldFormat({ variant='ghost-destructive' onClick={() => removeField(field.id)} disabled={isReadOnly} - className='h-auto p-0 hover-hover:opacity-90' + size='icon' + className='hover-hover:opacity-90' > Delete Field diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx index aa6d7cc9328..46f41a74b3e 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx @@ -428,7 +428,7 @@ export function VariablesInput({ addAssignment() }} disabled={isReadOnly || allVariablesAssigned} - className='h-auto p-0' + size='icon' > Add Variable @@ -440,7 +440,7 @@ export function VariablesInput({ removeAssignment(assignment.id) }} disabled={isReadOnly} - className='h-auto p-0' + size='icon' > Delete Variable diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables.tsx index 61ca1967060..a836389a65b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables.tsx @@ -457,7 +457,7 @@ export function Variables({ readOnly = false }: VariablesProps) { e.stopPropagation() handleRemoveVariable(variable.id) }} - className='h-auto p-0' + size='icon' disabled={readOnly} aria-label={`Delete ${variable.name || `variable ${index + 1}`}`} > From c1c0a5efeb8e1fb113713f7db7f011d838327b3c Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos <157128530+BillLeoutsakosvl346@users.noreply.github.com> Date: Sat, 19 Sep 2026 17:55:52 -0700 Subject: [PATCH 3/3] improvement(ui): share field mode toggles (#8046) * improvement(ui): share field mode toggles * fix(ui): transition field mode icon colors --------- Co-authored-by: Bill Leoutsakos --- .../field-mode-toggle/field-mode-toggle.tsx | 37 ++++++++++++++ .../components/starter/input-format.tsx | 41 +++++----------- .../components/tools/usage-control.tsx | 33 +++---------- .../variables-input/variables-input.tsx | 45 +++++------------ .../editor/components/sub-block/sub-block.tsx | 49 ++++--------------- 5 files changed, 81 insertions(+), 124 deletions(-) create mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle.tsx new file mode 100644 index 00000000000..e7916f529d2 --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle.tsx @@ -0,0 +1,37 @@ +import type { ButtonHTMLAttributes } from 'react' +import { cn, Tooltip } from '@sim/emcn' +import { ArrowLeftRight } from '@sim/emcn/icons' + +interface FieldModeToggleProps { + label: string + active: boolean + disabled?: boolean + onClick: ButtonHTMLAttributes['onClick'] +} + +/** Shared field-mode affordance; the caller owns the mode and its stored values. */ +export function FieldModeToggle({ label, active, disabled, onClick }: FieldModeToggleProps) { + return ( + + + + + +

{label}

+
+
+ ) +} diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx index 4626149cba9..a949d97a61b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx @@ -14,15 +14,15 @@ import { Label, languages, OverflowText, - Tooltip, } from '@sim/emcn' -import { ArrowLeftRight, Plus, Trash } from '@sim/emcn/icons' +import { Plus, Trash } from '@sim/emcn/icons' import Editor from 'react-simple-code-editor' import { createDefaultInputFormatField, isFileFieldType, parseInputFormatFiles, } from '@/lib/workflows/input-format' +import { FieldModeToggle } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle' import { FileUpload } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/file-upload/file-upload' import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text' import { @@ -166,32 +166,17 @@ export function FieldFormat({ if (!canUseUploader) return null const label = mode === 'upload' ? 'Switch to JSON' : 'Switch to file uploader' return ( - - - - - -

{label}

-
-
+ + setFileFieldModes((prev) => ({ + ...prev, + [field.id]: mode === 'upload' ? 'json' : 'upload', + })) + } + /> ) } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/usage-control.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/usage-control.tsx index e79ab62abcd..684602b559c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/usage-control.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/usage-control.tsx @@ -1,7 +1,7 @@ -import { Combobox, cn, Label, Tooltip } from '@sim/emcn' -import { ArrowLeftRight } from '@sim/emcn/icons' +import { Combobox, Label } from '@sim/emcn' import type { CanonicalMode } from '@/lib/workflows/subblocks/visibility' import type { StoredTool } from '@/lib/workflows/tool-input/types' +import { FieldModeToggle } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle' import { ShortInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/short-input' import type { SubBlockConfig } from '@/blocks/types' @@ -63,29 +63,12 @@ export function ToolUsageControl({
- - - - - -

{toggleLabel}

-
-
+
{mode === 'advanced' ? ( diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx index 46f41a74b3e..0d129662c0e 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx @@ -10,11 +10,11 @@ import { Label, OverflowText, Textarea, - Tooltip, } from '@sim/emcn' -import { ArrowLeftRight, Plus, Trash } from '@sim/emcn/icons' +import { Plus, Trash } from '@sim/emcn/icons' import { generateId } from '@sim/utils/id' import { useParams } from 'next/navigation' +import { FieldModeToggle } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle' import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text' import { checkTagTrigger, @@ -472,36 +472,17 @@ export function VariablesInput({
{assignment.type === 'boolean' && ( - - - - - -

{isManualBoolean ? 'Switch to selector' : 'Switch to manual value'}

-
-
+ + setManualBooleanModes((prev) => ({ + ...prev, + [assignment.id]: !isManualBoolean, + })) + } + /> )}
{assignment.type === 'boolean' && !isManualBoolean ? ( diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx index 4795928d1c6..88bb88e2ace 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx @@ -1,13 +1,6 @@ import { type JSX, type MouseEvent, memo, useCallback, useMemo, useRef, useState } from 'react' import { Button, cn, Input, Label, Tooltip } from '@sim/emcn' -import { - ArrowLeftRight, - ArrowUp, - Check, - Clipboard, - SquareArrowUpRight, - TriangleAlert, -} from '@sim/emcn/icons' +import { ArrowUp, Check, Clipboard, SquareArrowUpRight, TriangleAlert } from '@sim/emcn/icons' import { isEqual } from 'es-toolkit' import { useParams } from 'next/navigation' import type { FilterRule, SortRule } from '@/lib/table/query-builder/constants' @@ -54,6 +47,7 @@ import { WorkflowSelectorInput, WorkspaceFolderSelector, } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components' +import { FieldModeToggle } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/field-mode-toggle/field-mode-toggle' import { MODAL_REGISTRY } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/modal-registry' import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate' import type { SubBlockConfig } from '@/blocks/types' @@ -377,37 +371,14 @@ const renderLabel = ( )} {showCanonicalToggle && ( - - - - - -

- {canonicalToggle?.mode === 'advanced' - ? 'Switch to selector' - : 'Switch to manual ID'} -

-
-
+ )}