Skip to content

Commit 4c4f708

Browse files
committed
updated setup instructions links, destructure trigger outputs, fix text subblock styling
1 parent 845d0f0 commit 4c4f708

File tree

26 files changed

+947
-407
lines changed

26 files changed

+947
-407
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface TextProps {
1717
*
1818
* @remarks
1919
* - Automatically detects and renders HTML content safely
20-
* - Applies prose styling for HTML content (links, code, lists, etc.)
20+
* - Applies consistent styling for HTML content (links, code, lists, etc.)
2121
* - Falls back to plain text rendering for non-HTML content
2222
*
2323
* Note: This component renders trusted, internally-defined content only
@@ -33,7 +33,7 @@ export function Text({ blockId, subBlockId, content, className }: TextProps) {
3333
className={`rounded-md border bg-[var(--surface-2)] p-4 shadow-sm ${className || ''}`}
3434
>
3535
<div
36-
className='prose prose-sm dark:prose-invert max-w-none break-words text-sm [&_a]:text-blue-600 [&_a]:underline [&_a]:hover:text-blue-700 [&_a]:dark:text-blue-400 [&_a]:dark:hover:text-blue-300 [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:text-xs [&_strong]:font-semibold [&_ul]:ml-5 [&_ul]:list-disc'
36+
className='max-w-none break-words text-[var(--text-secondary)] text-sm [&_a]:text-[var(--brand-secondary)] [&_a]:underline [&_a]:underline-offset-2 [&_a]:hover:brightness-110 [&_code]:rounded [&_code]:bg-[var(--surface-5)] [&_code]:px-1 [&_code]:py-0.5 [&_code]:text-[var(--text-tertiary)] [&_code]:text-xs [&_strong]:font-medium [&_strong]:text-[var(--text-primary)] [&_ul]:ml-5 [&_ul]:list-disc [&_ul]:marker:text-[var(--text-muted)]'
3737
dangerouslySetInnerHTML={{ __html: content }}
3838
/>
3939
</div>
@@ -43,7 +43,7 @@ export function Text({ blockId, subBlockId, content, className }: TextProps) {
4343
return (
4444
<div
4545
id={`${blockId}-${subBlockId}`}
46-
className={`whitespace-pre-wrap break-words rounded-md border bg-[var(--surface-2)] p-4 text-muted-foreground text-sm shadow-sm ${className || ''}`}
46+
className={`whitespace-pre-wrap break-words rounded-md border bg-[var(--surface-2)] p-4 text-[var(--text-secondary)] text-sm shadow-sm ${className || ''}`}
4747
>
4848
{content}
4949
</div>

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/folder-item/folder-item.tsx

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
useDeleteFolder,
2323
useDeleteSelection,
2424
useDuplicateFolder,
25+
useDuplicateSelection,
2526
useExportFolder,
2627
useExportSelection,
2728
} from '@/app/workspace/[workspaceId]/w/hooks'
@@ -99,11 +100,17 @@ export function FolderItem({
99100

100101
const isDeleting = isDeletingThisFolder || isDeletingSelection
101102

102-
const { handleDuplicateFolder } = useDuplicateFolder({
103+
const { handleDuplicateFolder: handleDuplicateThisFolder } = useDuplicateFolder({
103104
workspaceId,
104105
folderIds: folder.id,
105106
})
106107

108+
const { isDuplicating: isDuplicatingSelection, handleDuplicateSelection } = useDuplicateSelection(
109+
{
110+
workspaceId,
111+
}
112+
)
113+
107114
const {
108115
isExporting: isExportingThisFolder,
109116
hasWorkflows,
@@ -317,6 +324,7 @@ export function FolderItem({
317324
return
318325
}
319326

327+
useFolderStore.getState().clearFolderSelection()
320328
handleToggleExpanded()
321329
},
322330
[handleToggleExpanded, shouldPreventClickRef, isEditing, onFolderClick, folder.id]
@@ -404,6 +412,18 @@ export function FolderItem({
404412
}
405413
}, [handleExportSelection, handleExportThisFolder])
406414

415+
const handleDuplicate = useCallback(async () => {
416+
if (!capturedSelectionRef.current) return
417+
418+
const { isMixed, workflowIds, folderIds } = capturedSelectionRef.current
419+
420+
if (isMixed || folderIds.length > 1) {
421+
await handleDuplicateSelection(workflowIds, folderIds)
422+
} else {
423+
await handleDuplicateThisFolder()
424+
}
425+
}, [handleDuplicateSelection, handleDuplicateThisFolder])
426+
407427
const isMixedSelection = useMemo(() => {
408428
return capturedSelectionRef.current?.isMixed ?? false
409429
}, [isContextMenuOpen])
@@ -517,18 +537,20 @@ export function FolderItem({
517537
onRename={handleStartEdit}
518538
onCreate={handleCreateWorkflowInFolder}
519539
onCreateFolder={handleCreateFolderInFolder}
520-
onDuplicate={handleDuplicateFolder}
540+
onDuplicate={handleDuplicate}
521541
onExport={handleExport}
522542
onDelete={handleOpenDeleteModal}
523543
showCreate={!isMixedSelection}
524544
showCreateFolder={!isMixedSelection}
525545
showRename={!isMixedSelection && selectedFolders.size <= 1}
526-
showDuplicate={!isMixedSelection}
546+
showDuplicate={true}
527547
showExport={true}
528548
disableRename={!userPermissions.canEdit}
529549
disableCreate={!userPermissions.canEdit || createWorkflowMutation.isPending}
530550
disableCreateFolder={!userPermissions.canEdit || createFolderMutation.isPending}
531-
disableDuplicate={!userPermissions.canEdit || !hasWorkflows}
551+
disableDuplicate={
552+
!userPermissions.canEdit || isDuplicatingSelection || !hasExportableContent
553+
}
532554
disableExport={!userPermissions.canEdit || isExporting || !hasExportableContent}
533555
disableDelete={!userPermissions.canEdit || !canDeleteSelection}
534556
/>

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/workflow-item/avatars/avatars.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function UserAvatar({ user, index }: UserAvatarProps) {
5151
)}
5252
<AvatarFallback
5353
style={{ background: color }}
54-
className='border-0 font-semibold text-[7px] text-white'
54+
className='border-0 font-semibold text-[7px] text-white leading-none'
5555
>
5656
{initials}
5757
</AvatarFallback>
@@ -132,7 +132,7 @@ export function Avatars({ workflowId }: AvatarsProps) {
132132
<Tooltip.Root>
133133
<Tooltip.Trigger asChild>
134134
<Avatar size='xs' style={{ zIndex: 0 } as CSSProperties}>
135-
<AvatarFallback className='border-0 bg-[#404040] font-semibold text-[7px] text-white'>
135+
<AvatarFallback className='border-0 bg-[#404040] font-semibold text-[7px] text-white leading-none'>
136136
+{overflowCount}
137137
</AvatarFallback>
138138
</Avatar>

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/workflow-item/workflow-item.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
useCanDelete,
2020
useDeleteSelection,
2121
useDeleteWorkflow,
22+
useDuplicateSelection,
2223
useDuplicateWorkflow,
2324
useExportSelection,
2425
useExportWorkflow,
@@ -123,16 +124,26 @@ export function WorkflowItem({
123124
}
124125
}, [handleDeleteSelection, handleDeleteWorkflows])
125126

126-
const { handleDuplicateWorkflow: duplicateWorkflow } = useDuplicateWorkflow({ workspaceId })
127+
const { handleDuplicateWorkflow: duplicateWorkflows } = useDuplicateWorkflow({ workspaceId })
128+
const { isDuplicating: isDuplicatingSelection, handleDuplicateSelection } = useDuplicateSelection(
129+
{ workspaceId }
130+
)
127131

128132
const { handleExportWorkflow: handleExportWorkflows } = useExportWorkflow()
129133
const { handleExportSelection } = useExportSelection()
130134

131-
const handleDuplicateWorkflow = useCallback(() => {
132-
const workflowIds = capturedSelectionRef.current?.workflowIds || []
133-
if (workflowIds.length === 0) return
134-
duplicateWorkflow(workflowIds)
135-
}, [duplicateWorkflow])
135+
const handleDuplicate = useCallback(() => {
136+
if (!capturedSelectionRef.current) return
137+
138+
const { isMixed, workflowIds, folderIds } = capturedSelectionRef.current
139+
140+
if (isMixed) {
141+
handleDuplicateSelection(workflowIds, folderIds)
142+
} else {
143+
if (workflowIds.length === 0) return
144+
duplicateWorkflows(workflowIds)
145+
}
146+
}, [duplicateWorkflows, handleDuplicateSelection])
136147

137148
const handleExport = useCallback(() => {
138149
if (!capturedSelectionRef.current) return
@@ -432,18 +443,18 @@ export function WorkflowItem({
432443
onClose={closeMenu}
433444
onOpenInNewTab={handleOpenInNewTab}
434445
onRename={handleStartEdit}
435-
onDuplicate={handleDuplicateWorkflow}
446+
onDuplicate={handleDuplicate}
436447
onExport={handleExport}
437448
onDelete={handleOpenDeleteModal}
438449
onColorChange={handleColorChange}
439450
currentColor={workflow.color}
440451
showOpenInNewTab={!isMixedSelection && selectedWorkflows.size <= 1}
441452
showRename={!isMixedSelection && selectedWorkflows.size <= 1}
442-
showDuplicate={!isMixedSelection}
453+
showDuplicate={true}
443454
showExport={true}
444455
showColorChange={!isMixedSelection && selectedWorkflows.size <= 1}
445456
disableRename={!userPermissions.canEdit}
446-
disableDuplicate={!userPermissions.canEdit}
457+
disableDuplicate={!userPermissions.canEdit || isDuplicatingSelection}
447458
disableExport={!userPermissions.canEdit}
448459
disableColorChange={!userPermissions.canEdit}
449460
disableDelete={!userPermissions.canEdit || !canDeleteSelection}

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/workflow-list.tsx

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,22 @@ interface WorkflowListProps {
4949
const DropIndicatorLine = memo(function DropIndicatorLine({
5050
show,
5151
level = 0,
52+
position = 'before',
5253
}: {
5354
show: boolean
5455
level?: number
56+
position?: 'before' | 'after'
5557
}) {
5658
if (!show) return null
59+
60+
const positionStyle = position === 'before' ? { top: '-2px' } : { bottom: '-2px' }
61+
5762
return (
5863
<div
59-
className='pointer-events-none absolute right-0 left-0 z-20 flex items-center'
60-
style={{ paddingLeft: `${level * TREE_SPACING.INDENT_PER_LEVEL}px` }}
64+
className='pointer-events-none absolute right-0 left-0 z-20'
65+
style={{ ...positionStyle, paddingLeft: `${level * TREE_SPACING.INDENT_PER_LEVEL}px` }}
6166
>
62-
<div className='h-[2px] flex-1 rounded-full bg-[#33b4ff]/70' />
67+
<div className='h-[2px] rounded-full bg-[#33b4ff]/70' />
6368
</div>
6469
)
6570
})
@@ -101,11 +106,11 @@ export function WorkflowList({
101106
createEmptyFolderDropZone,
102107
createFolderContentDropZone,
103108
createRootDropZone,
109+
createEdgeDropZone,
104110
handleDragStart,
105111
handleDragEnd,
106112
} = useDragDrop({ disabled: !canReorder })
107113

108-
// Create context value with drag state for visual styling
109114
const dragContextValue = useSidebarDragContextValue(isDragging)
110115

111116
useEffect(() => {
@@ -217,7 +222,7 @@ export function WorkflowList({
217222

218223
return (
219224
<div key={workflow.id} className='relative'>
220-
<DropIndicatorLine show={showBefore} level={level} />
225+
<DropIndicatorLine show={showBefore} level={level} position='before' />
221226
<div
222227
style={{ paddingLeft: `${level * TREE_SPACING.INDENT_PER_LEVEL}px` }}
223228
{...createWorkflowDragHandlers(workflow.id, folderId)}
@@ -228,11 +233,11 @@ export function WorkflowList({
228233
level={level}
229234
dragDisabled={dragDisabled}
230235
onWorkflowClick={handleWorkflowClick}
231-
onDragStart={() => handleDragStart('workflow', folderId)}
236+
onDragStart={() => handleDragStart(folderId)}
232237
onDragEnd={handleDragEnd}
233238
/>
234239
</div>
235-
<DropIndicatorLine show={showAfter} level={level} />
240+
<DropIndicatorLine show={showAfter} level={level} position='after' />
236241
</div>
237242
)
238243
},
@@ -292,12 +297,11 @@ export function WorkflowList({
292297

293298
return (
294299
<div key={folder.id} className='relative'>
295-
<DropIndicatorLine show={showBefore} level={level} />
296-
{/* Drop target highlight overlay - covers entire folder section */}
300+
<DropIndicatorLine show={showBefore} level={level} position='before' />
297301
<div
298302
className={clsx(
299-
'pointer-events-none absolute inset-0 z-10 rounded-[4px] transition-opacity duration-75',
300-
showInside && isDragging ? 'bg-[#33b4ff1a] opacity-100' : 'opacity-0'
303+
'pointer-events-none absolute inset-0 z-10 rounded-[4px]',
304+
showInside && isDragging ? 'bg-[#33b4ff1a]' : 'hidden'
301305
)}
302306
/>
303307
<div
@@ -309,11 +313,11 @@ export function WorkflowList({
309313
level={level}
310314
dragDisabled={dragDisabled}
311315
onFolderClick={handleFolderClick}
312-
onDragStart={() => handleDragStart('folder', parentFolderId)}
316+
onDragStart={() => handleDragStart(parentFolderId)}
313317
onDragEnd={handleDragEnd}
314318
/>
315319
</div>
316-
<DropIndicatorLine show={showAfter} level={level} />
320+
<DropIndicatorLine show={showAfter} level={level} position='after' />
317321

318322
{isExpanded && (hasChildren || isDragging) && (
319323
<div className='relative' {...createFolderContentDropZone(folder.id)}>
@@ -385,7 +389,13 @@ export function WorkflowList({
385389
}, [folderTree, rootWorkflows])
386390

387391
const hasRootItems = rootItems.length > 0
392+
const firstItemId = rootItems[0]?.id ?? null
393+
const lastItemId = rootItems[rootItems.length - 1]?.id ?? null
388394
const showRootInside = dropIndicator?.targetId === 'root' && dropIndicator?.position === 'inside'
395+
const showTopIndicator =
396+
firstItemId && dropIndicator?.targetId === firstItemId && dropIndicator?.position === 'before'
397+
const showBottomIndicator =
398+
lastItemId && dropIndicator?.targetId === lastItemId && dropIndicator?.position === 'after'
389399

390400
const handleContainerClick = useCallback(
391401
(e: React.MouseEvent<HTMLDivElement>) => {
@@ -424,20 +434,41 @@ export function WorkflowList({
424434
{...rootDropZoneHandlers}
425435
data-empty-area
426436
>
427-
{/* Root drop target highlight overlay */}
428437
<div
429438
className={clsx(
430-
'pointer-events-none absolute inset-0 z-10 rounded-[4px] transition-opacity duration-75',
431-
showRootInside && isDragging ? 'bg-[#33b4ff1a] opacity-100' : 'opacity-0'
439+
'pointer-events-none absolute inset-0 z-10 rounded-[4px]',
440+
showRootInside && isDragging ? 'bg-[#33b4ff1a]' : 'hidden'
432441
)}
433442
/>
443+
{isDragging && hasRootItems && (
444+
<div
445+
className='absolute top-0 right-0 left-0 z-30 h-[12px]'
446+
{...createEdgeDropZone(firstItemId, 'before')}
447+
/>
448+
)}
449+
{showTopIndicator && (
450+
<div className='pointer-events-none absolute top-0 right-0 left-0 z-20'>
451+
<div className='h-[2px] rounded-full bg-[#33b4ff]/70' />
452+
</div>
453+
)}
434454
<div className='space-y-[2px]' data-empty-area>
435455
{rootItems.map((item) =>
436456
item.type === 'folder'
437457
? renderFolderSection(item.data as FolderTreeNode, 0, null)
438458
: renderWorkflowItem(item.data as WorkflowMetadata, 0, null)
439459
)}
440460
</div>
461+
{isDragging && hasRootItems && (
462+
<div
463+
className='absolute right-0 bottom-0 left-0 z-30 h-[12px]'
464+
{...createEdgeDropZone(lastItemId, 'after')}
465+
/>
466+
)}
467+
{showBottomIndicator && (
468+
<div className='pointer-events-none absolute right-0 bottom-0 left-0 z-20'>
469+
<div className='h-[2px] rounded-full bg-[#33b4ff]/70' />
470+
</div>
471+
)}
441472
</div>
442473

443474
<input

0 commit comments

Comments
 (0)