mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Fix "Edit file" link in visual editor tooltip (#19532)
GitOrigin-RevId: 1f196c3d195b69eae8169c9ffc0629f1cdf6d97b
This commit is contained in:
parent
2f80e74d8a
commit
30074fbe4e
3 changed files with 55 additions and 64 deletions
|
@ -1,18 +1,12 @@
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useCodeMirrorStateContext } from '../codemirror-editor'
|
|
||||||
import { Button } from 'react-bootstrap'
|
import { Button } from 'react-bootstrap'
|
||||||
import { resolveCommandNode } from '../../extensions/command-tooltip'
|
import Icon from '@/shared/components/icon'
|
||||||
import {
|
import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
|
||||||
FilePathArgument,
|
|
||||||
LiteralArgContent,
|
|
||||||
} from '../../lezer-latex/latex.terms.mjs'
|
|
||||||
import Icon from '../../../../shared/components/icon'
|
|
||||||
import { EditorState } from '@codemirror/state'
|
|
||||||
|
|
||||||
export const IncludeTooltipContent: FC = () => {
|
export const IncludeTooltipContent: FC = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const state = useCodeMirrorStateContext()
|
const { openIncludedFile } = useIncludedFile('IncludeArgument')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ol-cm-command-tooltip-content">
|
<div className="ol-cm-command-tooltip-content">
|
||||||
|
@ -20,17 +14,7 @@ export const IncludeTooltipContent: FC = () => {
|
||||||
type="button"
|
type="button"
|
||||||
bsStyle="link"
|
bsStyle="link"
|
||||||
className="ol-cm-command-tooltip-link"
|
className="ol-cm-command-tooltip-link"
|
||||||
onClick={() => {
|
onClick={openIncludedFile}
|
||||||
const name = readFileName(state)
|
|
||||||
if (name) {
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent('editor:open-file', {
|
|
||||||
detail: { name },
|
|
||||||
})
|
|
||||||
)
|
|
||||||
// TODO: handle file not found
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Icon type="edit" fw />
|
<Icon type="edit" fw />
|
||||||
{t('open_file')}
|
{t('open_file')}
|
||||||
|
@ -38,15 +22,3 @@ export const IncludeTooltipContent: FC = () => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const readFileName = (state: EditorState) => {
|
|
||||||
const commandNode = resolveCommandNode(state)
|
|
||||||
const argumentNode = commandNode
|
|
||||||
?.getChild('IncludeArgument')
|
|
||||||
?.getChild(FilePathArgument)
|
|
||||||
?.getChild(LiteralArgContent)
|
|
||||||
|
|
||||||
if (argumentNode) {
|
|
||||||
return state.sliceDoc(argumentNode.from, argumentNode.to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useCodeMirrorStateContext } from '../codemirror-editor'
|
|
||||||
import { Button } from 'react-bootstrap'
|
import { Button } from 'react-bootstrap'
|
||||||
import { resolveCommandNode } from '../../extensions/command-tooltip'
|
import Icon from '@/shared/components/icon'
|
||||||
import {
|
import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
|
||||||
FilePathArgument,
|
|
||||||
LiteralArgContent,
|
|
||||||
} from '../../lezer-latex/latex.terms.mjs'
|
|
||||||
import Icon from '../../../../shared/components/icon'
|
|
||||||
import { EditorState } from '@codemirror/state'
|
|
||||||
|
|
||||||
export const InputTooltipContent: FC = () => {
|
export const InputTooltipContent: FC = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const state = useCodeMirrorStateContext()
|
const { openIncludedFile } = useIncludedFile('InputArgument')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ol-cm-command-tooltip-content">
|
<div className="ol-cm-command-tooltip-content">
|
||||||
|
@ -20,17 +14,7 @@ export const InputTooltipContent: FC = () => {
|
||||||
type="button"
|
type="button"
|
||||||
bsStyle="link"
|
bsStyle="link"
|
||||||
className="ol-cm-command-tooltip-link"
|
className="ol-cm-command-tooltip-link"
|
||||||
onClick={() => {
|
onClick={openIncludedFile}
|
||||||
const name = readFileName(state)
|
|
||||||
if (name) {
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent('editor:open-file', {
|
|
||||||
detail: { name },
|
|
||||||
})
|
|
||||||
)
|
|
||||||
// TODO: handle file not found
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Icon type="edit" fw />
|
<Icon type="edit" fw />
|
||||||
{t('open_file')}
|
{t('open_file')}
|
||||||
|
@ -38,15 +22,3 @@ export const InputTooltipContent: FC = () => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const readFileName = (state: EditorState) => {
|
|
||||||
const commandNode = resolveCommandNode(state)
|
|
||||||
const argumentNode = commandNode
|
|
||||||
?.getChild('InputArgument')
|
|
||||||
?.getChild(FilePathArgument)
|
|
||||||
?.getChild(LiteralArgContent)
|
|
||||||
|
|
||||||
if (argumentNode) {
|
|
||||||
return state.sliceDoc(argumentNode.from, argumentNode.to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { useCodeMirrorStateContext } from '@/features/source-editor/components/codemirror-editor'
|
||||||
|
import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
|
||||||
|
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
import { EditorState } from '@codemirror/state'
|
||||||
|
import { resolveCommandNode } from '@/features/source-editor/extensions/command-tooltip'
|
||||||
|
import {
|
||||||
|
FilePathArgument,
|
||||||
|
LiteralArgContent,
|
||||||
|
} from '@/features/source-editor/lezer-latex/latex.terms.mjs'
|
||||||
|
|
||||||
|
export const useIncludedFile = (argumentType: string) => {
|
||||||
|
const state = useCodeMirrorStateContext()
|
||||||
|
const { findEntityByPath } = useFileTreePathContext()
|
||||||
|
const { openDocId } = useEditorManagerContext()
|
||||||
|
|
||||||
|
const openIncludedFile = useCallback(() => {
|
||||||
|
const name = readIncludedPath(state, argumentType)
|
||||||
|
if (name) {
|
||||||
|
// TODO: find in relative path or root folder
|
||||||
|
for (const extension of ['.tex', '']) {
|
||||||
|
const result = findEntityByPath(`${name}${extension}`)
|
||||||
|
if (result) {
|
||||||
|
return openDocId(result.entity._id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: handle file not found
|
||||||
|
}
|
||||||
|
}, [argumentType, findEntityByPath, openDocId, state])
|
||||||
|
|
||||||
|
return { openIncludedFile }
|
||||||
|
}
|
||||||
|
|
||||||
|
const readIncludedPath = (
|
||||||
|
state: EditorState,
|
||||||
|
argumentType: string | number
|
||||||
|
) => {
|
||||||
|
const commandNode = resolveCommandNode(state)
|
||||||
|
const argumentNode = commandNode
|
||||||
|
?.getChild(argumentType)
|
||||||
|
?.getChild(FilePathArgument)
|
||||||
|
?.getChild(LiteralArgContent)
|
||||||
|
|
||||||
|
if (argumentNode) {
|
||||||
|
return state.sliceDoc(argumentNode.from, argumentNode.to)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue