mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-05 04:18:16 +00:00
Merge pull request #14999 from overleaf/mf-file-view-header-typescript
[web] Convert `file-view-header.js` to typescript GitOrigin-RevId: 1f05b086e3acb692f3745481c4022a920c4f7599
This commit is contained in:
parent
bfac201236
commit
496bb4d4e7
4 changed files with 82 additions and 38 deletions
|
@ -1,4 +1,4 @@
|
|||
import { useState, useCallback } from 'react'
|
||||
import { useState, useCallback, type ElementType } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
|
@ -11,18 +11,27 @@ import { useProjectContext } from '../../../shared/context/project-context'
|
|||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
import useAbortController from '../../../shared/hooks/use-abort-controller'
|
||||
import { LinkedFileIcon } from './file-view-icons'
|
||||
import { BinaryFile, hasProvider, LinkedFile } from '../types/binary-file'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo')
|
||||
|
||||
const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo') as {
|
||||
import: { LinkedFileInfo: ElementType }
|
||||
path: string
|
||||
}[]
|
||||
|
||||
const tprLinkedFileRefreshError = importOverleafModules(
|
||||
'tprLinkedFileRefreshError'
|
||||
)
|
||||
) as {
|
||||
import: { LinkedFileRefreshError: ElementType }
|
||||
path: string
|
||||
}[]
|
||||
|
||||
const MAX_URL_LENGTH = 60
|
||||
const FRONT_OF_URL_LENGTH = 35
|
||||
const FILLER = '...'
|
||||
const TAIL_OF_URL_LENGTH = MAX_URL_LENGTH - FRONT_OF_URL_LENGTH - FILLER.length
|
||||
|
||||
function shortenedUrl(url) {
|
||||
function shortenedUrl(url: string) {
|
||||
if (!url) {
|
||||
return
|
||||
}
|
||||
|
@ -34,7 +43,15 @@ function shortenedUrl(url) {
|
|||
return url
|
||||
}
|
||||
|
||||
export default function FileViewHeader({ file, storeReferencesKeys }) {
|
||||
type FileViewHeaderProps = {
|
||||
file: BinaryFile
|
||||
storeReferencesKeys: (keys: string[]) => void
|
||||
}
|
||||
|
||||
export default function FileViewHeader({
|
||||
file,
|
||||
storeReferencesKeys,
|
||||
}: FileViewHeaderProps) {
|
||||
const { _id: projectId } = useProjectContext({
|
||||
_id: PropTypes.string.isRequired,
|
||||
})
|
||||
|
@ -50,19 +67,19 @@ export default function FileViewHeader({ file, storeReferencesKeys }) {
|
|||
|
||||
let fileInfo
|
||||
if (file.linkedFileData) {
|
||||
if (file.linkedFileData.provider === 'url') {
|
||||
if (hasProvider(file, 'url')) {
|
||||
fileInfo = (
|
||||
<div>
|
||||
<UrlProvider file={file} />
|
||||
</div>
|
||||
)
|
||||
} else if (file.linkedFileData.provider === 'project_file') {
|
||||
} else if (hasProvider(file, 'project_file')) {
|
||||
fileInfo = (
|
||||
<div>
|
||||
<ProjectFilePathProvider file={file} />
|
||||
</div>
|
||||
)
|
||||
} else if (file.linkedFileData.provider === 'project_output_file') {
|
||||
} else if (hasProvider(file, 'project_output_file')) {
|
||||
fileInfo = (
|
||||
<div>
|
||||
<ProjectOutputFileProvider file={file} />
|
||||
|
@ -85,8 +102,8 @@ export default function FileViewHeader({ file, storeReferencesKeys }) {
|
|||
})
|
||||
.finally(() => {
|
||||
if (
|
||||
file.linkedFileData.provider === 'mendeley' ||
|
||||
file.linkedFileData.provider === 'zotero' ||
|
||||
hasProvider(file, 'mendeley') ||
|
||||
hasProvider(file, 'zotero') ||
|
||||
file.name.match(/^.*\.bib$/)
|
||||
) {
|
||||
reindexReferences()
|
||||
|
@ -151,16 +168,11 @@ export default function FileViewHeader({ file, storeReferencesKeys }) {
|
|||
)
|
||||
}
|
||||
|
||||
FileViewHeader.propTypes = {
|
||||
file: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
linkedFileData: PropTypes.object,
|
||||
}).isRequired,
|
||||
storeReferencesKeys: PropTypes.func.isRequired,
|
||||
type UrlProviderProps = {
|
||||
file: LinkedFile<'url'>
|
||||
}
|
||||
|
||||
function UrlProvider({ file }) {
|
||||
function UrlProvider({ file }: UrlProviderProps) {
|
||||
return (
|
||||
<p>
|
||||
<LinkedFileIcon />
|
||||
|
@ -181,14 +193,11 @@ function UrlProvider({ file }) {
|
|||
)
|
||||
}
|
||||
|
||||
UrlProvider.propTypes = {
|
||||
file: PropTypes.shape({
|
||||
linkedFileData: PropTypes.object,
|
||||
created: PropTypes.string,
|
||||
}).isRequired,
|
||||
type ProjectFilePathProviderProps = {
|
||||
file: LinkedFile<'project_file'>
|
||||
}
|
||||
|
||||
function ProjectFilePathProvider({ file }) {
|
||||
function ProjectFilePathProvider({ file }: ProjectFilePathProviderProps) {
|
||||
/* eslint-disable jsx-a11y/anchor-has-content, react/jsx-key */
|
||||
return (
|
||||
<p>
|
||||
|
@ -218,14 +227,11 @@ function ProjectFilePathProvider({ file }) {
|
|||
)
|
||||
}
|
||||
|
||||
ProjectFilePathProvider.propTypes = {
|
||||
file: PropTypes.shape({
|
||||
linkedFileData: PropTypes.object,
|
||||
created: PropTypes.string,
|
||||
}).isRequired,
|
||||
type ProjectOutputFileProviderProps = {
|
||||
file: LinkedFile<'project_output_file'>
|
||||
}
|
||||
|
||||
function ProjectOutputFileProvider({ file }) {
|
||||
function ProjectOutputFileProvider({ file }: ProjectOutputFileProviderProps) {
|
||||
return (
|
||||
<p>
|
||||
<LinkedFileIcon />
|
||||
|
@ -252,10 +258,3 @@ function ProjectOutputFileProvider({ file }) {
|
|||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
ProjectOutputFileProvider.propTypes = {
|
||||
file: PropTypes.shape({
|
||||
linkedFileData: PropTypes.object,
|
||||
created: PropTypes.string,
|
||||
}).isRequired,
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
type LinkedFileData = {
|
||||
url: {
|
||||
provider: 'url'
|
||||
url: string
|
||||
}
|
||||
zotero: {
|
||||
provider: 'zotero'
|
||||
importer_id: string
|
||||
}
|
||||
mendeley: {
|
||||
provider: 'mendeley'
|
||||
importer_id: string
|
||||
}
|
||||
project_file: {
|
||||
provider: 'project_file'
|
||||
v1_source_doc_id?: string
|
||||
source_project_id: string
|
||||
source_entity_path: string
|
||||
}
|
||||
project_output_file: {
|
||||
provider: 'project_output_file'
|
||||
v1_source_doc_id?: string
|
||||
source_project_id: string
|
||||
source_output_file_path: string
|
||||
}
|
||||
}
|
||||
|
||||
export type BinaryFile<T extends keyof LinkedFileData = keyof LinkedFileData> =
|
||||
{
|
||||
_id: string
|
||||
name: string
|
||||
created: Date
|
||||
id: string
|
||||
type: string
|
||||
selected: boolean
|
||||
linkedFileData?: LinkedFileData[T]
|
||||
}
|
||||
|
||||
export type LinkedFile<T extends keyof LinkedFileData> = Required<BinaryFile<T>>
|
||||
|
||||
export const hasProvider = <T extends keyof LinkedFileData>(
|
||||
file: BinaryFile,
|
||||
provider: T
|
||||
): file is LinkedFile<T> => file.linkedFileData?.provider === provider
|
|
@ -8,7 +8,7 @@ import fetchMock from 'fetch-mock'
|
|||
import sinon from 'sinon'
|
||||
|
||||
import { renderWithEditorContext } from '../../../helpers/render-with-context'
|
||||
import FileViewHeader from '../../../../../frontend/js/features/file-view/components/file-view-header.js'
|
||||
import FileViewHeader from '../../../../../frontend/js/features/file-view/components/file-view-header'
|
||||
|
||||
describe('<FileViewHeader/>', function () {
|
||||
const urlFile = {
|
||||
|
|
|
@ -39,5 +39,6 @@ declare global {
|
|||
enterprise?: boolean
|
||||
useRecaptchaNet?: boolean
|
||||
}
|
||||
expectingLinkedFileRefreshedSocketFor?: string | null
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue