From cfb7793cf7c0a1d09b2220262a5e861e32d92c0f Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 17 Mar 2026 09:45:06 -0700 Subject: [PATCH 1/4] fix(ui): add back file split view --- .../workspace/[workspaceId]/files/files.tsx | 61 +++++++++++++------ apps/sim/components/emcn/icons/columns2.tsx | 25 ++++++++ apps/sim/components/emcn/icons/index.ts | 1 + 3 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 apps/sim/components/emcn/icons/columns2.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/files/files.tsx b/apps/sim/app/workspace/[workspaceId]/files/files.tsx index 806d1586e71..87ea0540e1c 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/files.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/files.tsx @@ -5,6 +5,7 @@ import { createLogger } from '@sim/logger' import { useParams } from 'next/navigation' import { Button, + Columns2, Download, DropdownMenu, DropdownMenuContent, @@ -48,6 +49,7 @@ import { ResourceHeader, timeCell, } from '@/app/workspace/[workspaceId]/components' +import type { PreviewMode } from '@/app/workspace/[workspaceId]/files/components/file-viewer' import { FileViewer, isPreviewable, @@ -157,7 +159,7 @@ export function Files() { const [creatingFile, setCreatingFile] = useState(false) const [isDirty, setIsDirty] = useState(false) const [saveStatus, setSaveStatus] = useState('idle') - const [showPreview, setShowPreview] = useState(true) + const [previewMode, setPreviewMode] = useState('preview') const [showUnsavedChangesAlert, setShowUnsavedChangesAlert] = useState(false) const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) const [contextMenuFile, setContextMenuFile] = useState(null) @@ -312,7 +314,7 @@ export function Files() { if (isDirty) { setShowUnsavedChangesAlert(true) } else { - setShowPreview(false) + setPreviewMode('editor') setSelectedFileId(null) } }, [isDirty]) @@ -382,13 +384,11 @@ export function Files() { ] ) - const handleTogglePreview = useCallback(() => setShowPreview((prev) => !prev), []) - const handleDiscardChanges = useCallback(() => { setShowUnsavedChangesAlert(false) setIsDirty(false) setSaveStatus('idle') - setShowPreview(false) + setPreviewMode('editor') setSelectedFileId(null) }, []) @@ -480,7 +480,7 @@ export function Files() { if (justCreatedFileIdRef.current && !isJustCreated) { justCreatedFileIdRef.current = null } - setShowPreview(!isJustCreated) + setPreviewMode(isJustCreated ? 'editor' : 'preview') }, [selectedFileId]) useEffect(() => { @@ -504,10 +504,23 @@ export function Files() { return () => window.removeEventListener('beforeunload', handler) }, [isDirty]) + const handleCyclePreviewMode = useCallback(() => { + setPreviewMode((prev) => { + if (prev === 'editor') return 'split' + if (prev === 'split') return 'preview' + return 'editor' + }) + }, []) + + const handleTogglePreview = useCallback(() => { + setPreviewMode((prev) => (prev === 'preview' ? 'editor' : 'preview')) + }, []) + const fileActions = useMemo(() => { if (!selectedFile) return [] const canEditText = isTextEditable(selectedFile) const canPreview = isPreviewable(selectedFile) + const hasSplitView = canEditText && canPreview const saveLabel = saveStatus === 'saving' @@ -518,16 +531,10 @@ export function Files() { ? 'Save failed' : 'Save' + const nextModeLabel = previewMode === 'editor' ? 'Split' : previewMode === 'split' ? 'Preview' : 'Edit' + const nextModeIcon = previewMode === 'editor' ? Columns2 : previewMode === 'split' ? Eye : Pencil + return [ - ...(canPreview - ? [ - { - label: showPreview ? 'Edit' : 'Preview', - icon: showPreview ? Pencil : Eye, - onClick: handleTogglePreview, - }, - ] - : []), ...(canEditText ? [ { @@ -540,6 +547,23 @@ export function Files() { }, ] : []), + ...(hasSplitView + ? [ + { + label: nextModeLabel, + icon: nextModeIcon, + onClick: handleCyclePreviewMode, + }, + ] + : canPreview + ? [ + { + label: previewMode === 'preview' ? 'Edit' : 'Preview', + icon: previewMode === 'preview' ? Pencil : Eye, + onClick: handleTogglePreview, + }, + ] + : []), { label: 'Download', icon: Download, @@ -554,7 +578,8 @@ export function Files() { }, [ selectedFile, saveStatus, - showPreview, + previewMode, + handleCyclePreviewMode, handleTogglePreview, handleSave, isDirty, @@ -580,8 +605,6 @@ export function Files() { } if (selectedFile) { - const canPreview = isPreviewable(selectedFile) - return ( <>
@@ -595,7 +618,7 @@ export function Files() { file={selectedFile} workspaceId={workspaceId} canEdit={userPermissions.canEdit === true} - showPreview={showPreview && canPreview} + previewMode={previewMode} autoFocus={justCreatedFileIdRef.current === selectedFile.id} onDirtyChange={setIsDirty} onSaveStatusChange={setSaveStatus} diff --git a/apps/sim/components/emcn/icons/columns2.tsx b/apps/sim/components/emcn/icons/columns2.tsx new file mode 100644 index 00000000000..5672efeb191 --- /dev/null +++ b/apps/sim/components/emcn/icons/columns2.tsx @@ -0,0 +1,25 @@ +import type { SVGProps } from 'react' + +/** + * Columns2 icon component - displays two vertical columns in a rounded container + * @param props - SVG properties including className, fill, etc. + */ +export function Columns2(props: SVGProps) { + return ( + + + + + ) +} diff --git a/apps/sim/components/emcn/icons/index.ts b/apps/sim/components/emcn/icons/index.ts index 21c3fb3204d..f82182cff54 100644 --- a/apps/sim/components/emcn/icons/index.ts +++ b/apps/sim/components/emcn/icons/index.ts @@ -15,6 +15,7 @@ export { Card } from './card' export { Check } from './check' export { ChevronDown } from './chevron-down' export { ClipboardList } from './clipboard-list' +export { Columns2 } from './columns2' export { Columns3 } from './columns3' export { Connections } from './connections' export { Copy } from './copy' From 464c0ec36ca8864cbecc75f5c2803be99536ac79 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 17 Mar 2026 10:24:00 -0700 Subject: [PATCH 2/4] Open md in split view --- apps/sim/app/workspace/[workspaceId]/files/files.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/files.tsx b/apps/sim/app/workspace/[workspaceId]/files/files.tsx index 87ea0540e1c..a5d8263908e 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/files.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/files.tsx @@ -480,8 +480,14 @@ export function Files() { if (justCreatedFileIdRef.current && !isJustCreated) { justCreatedFileIdRef.current = null } - setPreviewMode(isJustCreated ? 'editor' : 'preview') - }, [selectedFileId]) + if (isJustCreated) { + setPreviewMode('editor') + } else { + const file = selectedFileId ? files.find((f) => f.id === selectedFileId) : null + const isMd = file ? getFileExtension(file.name) === 'md' : false + setPreviewMode(isMd ? 'split' : 'preview') + } + }, [selectedFileId, files]) useEffect(() => { if (!selectedFile) return From 0622c1f277b120fa9824861ff2a6986ca3480719 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 17 Mar 2026 10:27:50 -0700 Subject: [PATCH 3/4] Fix lint --- apps/sim/app/workspace/[workspaceId]/files/files.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/files.tsx b/apps/sim/app/workspace/[workspaceId]/files/files.tsx index a5d8263908e..cd17b5fc045 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/files.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/files.tsx @@ -537,8 +537,10 @@ export function Files() { ? 'Save failed' : 'Save' - const nextModeLabel = previewMode === 'editor' ? 'Split' : previewMode === 'split' ? 'Preview' : 'Edit' - const nextModeIcon = previewMode === 'editor' ? Columns2 : previewMode === 'split' ? Eye : Pencil + const nextModeLabel = + previewMode === 'editor' ? 'Split' : previewMode === 'split' ? 'Preview' : 'Edit' + const nextModeIcon = + previewMode === 'editor' ? Columns2 : previewMode === 'split' ? Eye : Pencil return [ ...(canEditText From f2d1a52fedb7f0cc259ea14178723c73b3840598 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 17 Mar 2026 10:42:39 -0700 Subject: [PATCH 4/4] Default to preview --- apps/sim/app/workspace/[workspaceId]/files/files.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/files.tsx b/apps/sim/app/workspace/[workspaceId]/files/files.tsx index cd17b5fc045..ac156edf562 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/files.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/files.tsx @@ -484,8 +484,8 @@ export function Files() { setPreviewMode('editor') } else { const file = selectedFileId ? files.find((f) => f.id === selectedFileId) : null - const isMd = file ? getFileExtension(file.name) === 'md' : false - setPreviewMode(isMd ? 'split' : 'preview') + const canPreview = file ? isPreviewable(file) : false + setPreviewMode(canPreview ? 'preview' : 'editor') } }, [selectedFileId, files])