Skip to content

Commit d113175

Browse files
committed
Merge branch 'feat/canonical-subblock' of github.com:simstudioai/sim into feat/canonical-subblock
2 parents d43247c + 931a061 commit d113175

File tree

2 files changed

+96
-35
lines changed
  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor

2 files changed

+96
-35
lines changed

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,8 @@ const renderLabel = (
203203
const canonicalToggleDisabled = wandState?.disabled || canonicalToggle?.disabled
204204

205205
return (
206-
<Label
207-
className='flex items-center justify-between gap-[6px] pl-[2px]'
208-
onClick={(e) => e.preventDefault()}
209-
>
210-
<div className='flex items-center gap-[6px] whitespace-nowrap'>
206+
<div className='flex items-center justify-between gap-[6px] pl-[2px]'>
207+
<Label className='flex items-center gap-[6px] whitespace-nowrap'>
211208
{config.title}
212209
{required && <span className='ml-0.5'>*</span>}
213210
{config.type === 'code' && config.language === 'json' && (
@@ -225,7 +222,7 @@ const renderLabel = (
225222
</Tooltip.Content>
226223
</Tooltip.Root>
227224
)}
228-
</div>
225+
</Label>
229226
<div className='flex items-center gap-[6px]'>
230227
{showWand && (
231228
<>
@@ -260,7 +257,7 @@ const renderLabel = (
260257
'h-5 max-w-[200px] flex-1 text-[11px]',
261258
wandState.isStreaming && 'text-muted-foreground'
262259
)}
263-
placeholder='Generate...'
260+
placeholder='Generate with AI...'
264261
/>
265262
<Button
266263
variant='tertiary'
@@ -284,7 +281,7 @@ const renderLabel = (
284281
{showCanonicalToggle && (
285282
<button
286283
type='button'
287-
className='flex h-[12px] w-[12px] flex-shrink-0 items-center justify-center bg-transparent p-0 disabled:opacity-50'
284+
className='flex h-[12px] w-[12px] flex-shrink-0 items-center justify-center bg-transparent p-0 disabled:cursor-not-allowed disabled:opacity-50'
288285
onClick={canonicalToggle?.onToggle}
289286
disabled={canonicalToggleDisabled}
290287
aria-label={canonicalToggle?.mode === 'advanced' ? 'Use selector' : 'Enter manual ID'}
@@ -300,7 +297,7 @@ const renderLabel = (
300297
</button>
301298
)}
302299
</div>
303-
</Label>
300+
</div>
304301
)
305302
}
306303

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,28 @@ export function Editor() {
124124
currentWorkflow.isSnapshotView
125125
)
126126

127+
/**
128+
* Partitions subBlocks into regular fields and standalone advanced-only fields.
129+
* Standalone advanced fields have mode 'advanced' and are not part of a canonical swap pair.
130+
*/
131+
const { regularSubBlocks, advancedOnlySubBlocks } = useMemo(() => {
132+
const regular: typeof subBlocks = []
133+
const advancedOnly: typeof subBlocks = []
134+
135+
for (const subBlock of subBlocks) {
136+
const isStandaloneAdvanced =
137+
subBlock.mode === 'advanced' && !canonicalIndex.canonicalIdBySubBlockId[subBlock.id]
138+
139+
if (isStandaloneAdvanced) {
140+
advancedOnly.push(subBlock)
141+
} else {
142+
regular.push(subBlock)
143+
}
144+
}
145+
146+
return { regularSubBlocks: regular, advancedOnlySubBlocks: advancedOnly }
147+
}, [subBlocks, canonicalIndex.canonicalIdBySubBlockId])
148+
127149
// Get block connections
128150
const { incomingConnections, hasIncomingConnections } = useBlockConnections(currentBlockId || '')
129151

@@ -346,14 +368,14 @@ export function Editor() {
346368
ref={subBlocksRef}
347369
className='subblocks-section flex flex-1 flex-col overflow-hidden'
348370
>
349-
<div className='flex-1 overflow-y-auto overflow-x-hidden px-[8px] pt-[12px] pb-[8px]'>
371+
<div className='flex-1 overflow-y-auto overflow-x-hidden px-[8px] pt-[12px] pb-[8px] [overflow-anchor:none]'>
350372
{subBlocks.length === 0 ? (
351373
<div className='flex h-full items-center justify-center text-center text-[#8D8D8D] text-[13px]'>
352374
This block has no subblocks
353375
</div>
354376
) : (
355377
<div className='flex flex-col'>
356-
{subBlocks.map((subBlock, index) => {
378+
{regularSubBlocks.map((subBlock, index) => {
357379
const stableKey = getSubBlockStableKey(
358380
currentBlockId || '',
359381
subBlock,
@@ -373,6 +395,10 @@ export function Editor() {
373395
)
374396
: undefined
375397

398+
const showDivider =
399+
index < regularSubBlocks.length - 1 ||
400+
(!hasAdvancedOnlyFields && index < subBlocks.length - 1)
401+
376402
return (
377403
<div key={stableKey} className='subblock-row'>
378404
<SubBlock
@@ -402,7 +428,7 @@ export function Editor() {
402428
: undefined
403429
}
404430
/>
405-
{index < subBlocks.length - 1 && (
431+
{showDivider && (
406432
<div className='subblock-divider px-[2px] pt-[16px] pb-[13px]'>
407433
<div
408434
className='h-[1.25px]'
@@ -416,30 +442,68 @@ export function Editor() {
416442
</div>
417443
)
418444
})}
419-
</div>
420-
)}
421445

422-
{/* Advanced Mode Toggle - Only show when block has standalone advanced-only fields */}
423-
{hasAdvancedOnlyFields && userPermissions.canEdit && (
424-
<div className='flex items-center justify-center pt-[8px] pb-[4px]'>
425-
<Button
426-
variant='ghost'
427-
size='sm'
428-
onClick={handleToggleAdvancedMode}
429-
className='h-[28px] gap-[6px] px-[10px] text-[12px] text-[var(--text-secondary)] hover:text-[var(--text-primary)]'
430-
>
431-
{displayAdvancedOptions ? (
432-
<>
433-
<ChevronUp className='h-[14px] w-[14px]' />
434-
Hide advanced fields
435-
</>
436-
) : (
437-
<>
438-
<ChevronDown className='h-[14px] w-[14px]' />
439-
Show advanced fields
440-
</>
441-
)}
442-
</Button>
446+
{hasAdvancedOnlyFields && userPermissions.canEdit && (
447+
<div className='flex items-center gap-[10px] px-[2px] pt-[14px] pb-[12px]'>
448+
<div
449+
className='h-[1.25px] flex-1'
450+
style={{
451+
backgroundImage:
452+
'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)',
453+
}}
454+
/>
455+
<button
456+
type='button'
457+
onClick={handleToggleAdvancedMode}
458+
className='flex items-center gap-[6px] whitespace-nowrap font-medium text-[13px] text-[var(--text-secondary)] hover:text-[var(--text-primary)]'
459+
>
460+
{displayAdvancedOptions ? 'Hide advanced fields' : 'Show advanced fields'}
461+
<ChevronDown
462+
className={`h-[14px] w-[14px] transition-transform duration-200 ${displayAdvancedOptions ? 'rotate-180' : ''}`}
463+
/>
464+
</button>
465+
<div
466+
className='h-[1.25px] flex-1'
467+
style={{
468+
backgroundImage:
469+
'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)',
470+
}}
471+
/>
472+
</div>
473+
)}
474+
475+
{advancedOnlySubBlocks.map((subBlock, index) => {
476+
const stableKey = getSubBlockStableKey(
477+
currentBlockId || '',
478+
subBlock,
479+
subBlockState
480+
)
481+
482+
return (
483+
<div key={stableKey} className='subblock-row'>
484+
<SubBlock
485+
blockId={currentBlockId}
486+
config={subBlock}
487+
isPreview={false}
488+
subBlockValues={subBlockState}
489+
disabled={!userPermissions.canEdit}
490+
fieldDiffStatus={undefined}
491+
allowExpandInPreview={false}
492+
/>
493+
{index < advancedOnlySubBlocks.length - 1 && (
494+
<div className='subblock-divider px-[2px] pt-[16px] pb-[13px]'>
495+
<div
496+
className='h-[1.25px]'
497+
style={{
498+
backgroundImage:
499+
'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)',
500+
}}
501+
/>
502+
</div>
503+
)}
504+
</div>
505+
)
506+
})}
443507
</div>
444508
)}
445509
</div>

0 commit comments

Comments
 (0)