mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-13 21:53:43 +01:00
Merge pull request #15474 from overleaf/td-ide-page-file-and-multiple-view
React IDE page: implement file views and file delete handling GitOrigin-RevId: 491cad7b147e55bc4a250da387916c7e2dff14ae
This commit is contained in:
@@ -1,35 +1,26 @@
|
||||
import { Panel, PanelGroup } from 'react-resizable-panels'
|
||||
import { VerticalResizeHandle } from '@/features/ide-react/components/resize/vertical-resize-handle'
|
||||
import React, { ElementType, useEffect } from 'react'
|
||||
import React, { ElementType } from 'react'
|
||||
import useScopeValue from '@/shared/hooks/use-scope-value'
|
||||
import SourceEditor from '@/features/source-editor/components/source-editor'
|
||||
import {
|
||||
EditorScopeValue,
|
||||
useEditorManagerContext,
|
||||
} from '@/features/ide-react/context/editor-manager-context'
|
||||
import { EditorScopeValue } from '@/features/ide-react/context/editor-manager-context'
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
import { EditorProps } from '@/features/ide-react/components/editor/editor'
|
||||
import classNames from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const symbolPaletteComponents = importOverleafModules(
|
||||
'sourceEditorSymbolPalette'
|
||||
) as { import: { default: ElementType }; path: string }[]
|
||||
|
||||
export function EditorPane({
|
||||
shouldPersistLayout,
|
||||
openDocId,
|
||||
fileTreeReady,
|
||||
}: EditorProps) {
|
||||
const { openDocId: openDocWithId } = useEditorManagerContext()
|
||||
export type EditorPaneProps = {
|
||||
shouldPersistLayout?: boolean
|
||||
show: boolean
|
||||
}
|
||||
|
||||
export function EditorPane({ shouldPersistLayout, show }: EditorPaneProps) {
|
||||
const { t } = useTranslation()
|
||||
const [editor] = useScopeValue<EditorScopeValue>('editor')
|
||||
|
||||
useEffect(() => {
|
||||
if (!fileTreeReady || !openDocId) {
|
||||
return
|
||||
}
|
||||
openDocWithId(openDocId)
|
||||
}, [fileTreeReady, openDocId, openDocWithId])
|
||||
|
||||
return (
|
||||
<PanelGroup
|
||||
autoSaveId={
|
||||
@@ -39,21 +30,27 @@ export function EditorPane({
|
||||
}
|
||||
direction="vertical"
|
||||
units="pixels"
|
||||
className={classNames({ hidden: !show })}
|
||||
>
|
||||
<Panel
|
||||
id="editor"
|
||||
id="sourceEditor"
|
||||
order={1}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{!!editor.sharejs_doc &&
|
||||
!editor.opening &&
|
||||
editor.multiSelectedCount === 0 &&
|
||||
!editor.error_state ? (
|
||||
<SourceEditor />
|
||||
{(!editor.sharejs_doc || editor.opening) &&
|
||||
!editor.error_state &&
|
||||
!!editor.open_doc_id ? (
|
||||
<div className="loading-panel">
|
||||
<span>
|
||||
<i className="fa fa-spin fa-refresh" />
|
||||
{t('loading')}…
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
<SourceEditor />
|
||||
</Panel>
|
||||
{editor.showSymbolPalette ? (
|
||||
<>
|
||||
@@ -65,7 +62,7 @@ export function EditorPane({
|
||||
minSize={250}
|
||||
maxSize={336}
|
||||
>
|
||||
<div className="ide-react-placeholder-symbol-palette">
|
||||
<div className="ide-react-symbol-palette">
|
||||
{symbolPaletteComponents.map(
|
||||
({ import: { default: Component }, path }) => (
|
||||
<Component key={path} />
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import { useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
ImperativePanelHandle,
|
||||
Panel,
|
||||
PanelGroup,
|
||||
} from 'react-resizable-panels'
|
||||
import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/horizontal-resize-handle'
|
||||
import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler'
|
||||
import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel'
|
||||
import { useLayoutContext } from '@/shared/context/layout-context'
|
||||
import { EditorPane } from '@/features/ide-react/components/editor/editor-pane'
|
||||
import PlaceholderFile from '@/features/ide-react/components/layout/placeholder/placeholder-file'
|
||||
import PlaceholderPdf from '@/features/ide-react/components/layout/placeholder/placeholder-pdf'
|
||||
import classnames from 'classnames'
|
||||
|
||||
export type EditorProps = {
|
||||
shouldPersistLayout?: boolean
|
||||
openDocId: string | null
|
||||
fileTreeReady: boolean
|
||||
}
|
||||
|
||||
export default function Editor({
|
||||
shouldPersistLayout = false,
|
||||
openDocId,
|
||||
fileTreeReady,
|
||||
}: EditorProps) {
|
||||
const { t } = useTranslation()
|
||||
const { view, pdfLayout, changeLayout } = useLayoutContext()
|
||||
|
||||
const pdfPanelRef = useRef<ImperativePanelHandle>(null)
|
||||
const isDualPane = pdfLayout === 'sideBySide'
|
||||
const editorIsVisible = isDualPane || view === 'editor'
|
||||
const pdfIsOpen = isDualPane || view === 'pdf'
|
||||
|
||||
useCollapsiblePanel(pdfIsOpen, pdfPanelRef)
|
||||
|
||||
if (view === 'file') {
|
||||
return <PlaceholderFile />
|
||||
}
|
||||
|
||||
const historyIsOpen = view === 'history'
|
||||
|
||||
function setPdfIsOpen(isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
changeLayout('sideBySide')
|
||||
} else {
|
||||
changeLayout('flat', 'editor')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<PanelGroup
|
||||
autoSaveId={
|
||||
shouldPersistLayout ? 'ide-react-editor-and-pdf-layout' : undefined
|
||||
}
|
||||
direction="horizontal"
|
||||
className={classnames({ hide: historyIsOpen })}
|
||||
>
|
||||
{editorIsVisible ? (
|
||||
<Panel id="editor" order={1} defaultSize={50}>
|
||||
<EditorPane
|
||||
shouldPersistLayout={shouldPersistLayout}
|
||||
openDocId={openDocId}
|
||||
fileTreeReady={fileTreeReady}
|
||||
/>
|
||||
</Panel>
|
||||
) : null}
|
||||
{isDualPane ? (
|
||||
<HorizontalResizeHandle>
|
||||
<HorizontalToggler
|
||||
id="editor-pdf"
|
||||
togglerType="east"
|
||||
isOpen={pdfIsOpen}
|
||||
setIsOpen={isOpen => setPdfIsOpen(isOpen)}
|
||||
tooltipWhenOpen={t('tooltip_hide_pdf')}
|
||||
tooltipWhenClosed={t('tooltip_show_pdf')}
|
||||
/>
|
||||
</HorizontalResizeHandle>
|
||||
) : null}
|
||||
{pdfIsOpen ? (
|
||||
<Panel
|
||||
ref={pdfPanelRef}
|
||||
id="pdf"
|
||||
order={2}
|
||||
defaultSize={50}
|
||||
minSize={5}
|
||||
collapsible
|
||||
onCollapse={collapsed => setPdfIsOpen(!collapsed)}
|
||||
>
|
||||
<PlaceholderPdf />
|
||||
</Panel>
|
||||
) : null}
|
||||
</PanelGroup>
|
||||
)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function MultipleSelectionPane({
|
||||
selectedEntityCount,
|
||||
}: {
|
||||
selectedEntityCount: number
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="multi-selection-ongoing">
|
||||
<div className="multi-selection-message">
|
||||
<h4>{`${selectedEntityCount} ${t('files_selected')}`}</h4>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function NoOpenDocPane() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="loading-panel">
|
||||
<span>
|
||||
<i className="fa fa-arrow-left" />
|
||||
{t('open_a_file_on_the_left')}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function NoSelectionPane() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="no-file-selection">
|
||||
<div className="no-file-selection-message">
|
||||
<h3>{t('no_selection_select_file')}</h3>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user