-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix(ui): add back file split view #3632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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<SaveStatus>('idle') | ||||||
| const [showPreview, setShowPreview] = useState(true) | ||||||
| const [previewMode, setPreviewMode] = useState<PreviewMode>('preview') | ||||||
| const [showUnsavedChangesAlert, setShowUnsavedChangesAlert] = useState(false) | ||||||
| const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) | ||||||
| const [contextMenuFile, setContextMenuFile] = useState<WorkspaceFileRecord | null>(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,8 +480,14 @@ export function Files() { | |||||
| if (justCreatedFileIdRef.current && !isJustCreated) { | ||||||
| justCreatedFileIdRef.current = null | ||||||
| } | ||||||
| setShowPreview(!isJustCreated) | ||||||
| }, [selectedFileId]) | ||||||
| if (isJustCreated) { | ||||||
| setPreviewMode('editor') | ||||||
| } else { | ||||||
| const file = selectedFileId ? files.find((f) => f.id === selectedFileId) : null | ||||||
| const canPreview = file ? isPreviewable(file) : false | ||||||
| setPreviewMode(canPreview ? 'preview' : 'editor') | ||||||
| } | ||||||
| }, [selectedFileId, files]) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Adding The original code only had The simplest fix is to exclude
Suggested change
If the lint warning is a concern, you can capture const filesRef = useRef(files)
useEffect(() => { filesRef.current = files }, [files])
useEffect(() => {
// ...
const file = selectedFileId ? filesRef.current.find((f) => f.id === selectedFileId) : null
// ...
}, [selectedFileId]) |
||||||
|
|
||||||
| useEffect(() => { | ||||||
| if (!selectedFile) return | ||||||
|
|
@@ -504,10 +510,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<HeaderAction[]>(() => { | ||||||
| if (!selectedFile) return [] | ||||||
| const canEditText = isTextEditable(selectedFile) | ||||||
| const canPreview = isPreviewable(selectedFile) | ||||||
| const hasSplitView = canEditText && canPreview | ||||||
|
|
||||||
| const saveLabel = | ||||||
| saveStatus === 'saving' | ||||||
|
|
@@ -518,16 +537,12 @@ 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 +555,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 +586,8 @@ export function Files() { | |||||
| }, [ | ||||||
| selectedFile, | ||||||
| saveStatus, | ||||||
| showPreview, | ||||||
| previewMode, | ||||||
| handleCyclePreviewMode, | ||||||
| handleTogglePreview, | ||||||
| handleSave, | ||||||
| isDirty, | ||||||
|
|
@@ -580,8 +613,6 @@ export function Files() { | |||||
| } | ||||||
|
|
||||||
| if (selectedFile) { | ||||||
| const canPreview = isPreviewable(selectedFile) | ||||||
|
|
||||||
| return ( | ||||||
| <> | ||||||
| <div className='flex h-full flex-1 flex-col overflow-hidden bg-[var(--bg)]'> | ||||||
|
|
@@ -595,7 +626,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} | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<SVGSVGElement>) { | ||
| return ( | ||
| <svg | ||
| width='24' | ||
| height='24' | ||
| viewBox='-1 -2 24 24' | ||
| fill='none' | ||
| stroke='currentColor' | ||
| strokeWidth='1.75' | ||
| strokeLinecap='round' | ||
| strokeLinejoin='round' | ||
| xmlns='http://www.w3.org/2000/svg' | ||
| {...props} | ||
| > | ||
| <path d='M0.75 3.25C0.75 1.86929 1.86929 0.75 3.25 0.75H17.25C18.6307 0.75 19.75 1.86929 19.75 3.25V16.25C19.75 17.6307 18.6307 18.75 17.25 18.75H3.25C1.86929 18.75 0.75 17.6307 0.75 16.25V3.25Z' /> | ||
| <path d='M10.25 0.75V18.75' /> | ||
| </svg> | ||
| ) | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.