diff --git a/services/web/frontend/js/features/file-view/components/file-view-header.js b/services/web/frontend/js/features/file-view/components/file-view-header.tsx
similarity index 83%
rename from services/web/frontend/js/features/file-view/components/file-view-header.js
rename to services/web/frontend/js/features/file-view/components/file-view-header.tsx
index 5a7d8bb3d3..55667909d1 100644
--- a/services/web/frontend/js/features/file-view/components/file-view-header.js
+++ b/services/web/frontend/js/features/file-view/components/file-view-header.tsx
@@ -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 = (
@@ -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 (
@@ -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 (
@@ -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 (
@@ -252,10 +258,3 @@ function ProjectOutputFileProvider({ file }) {
)
}
-
-ProjectOutputFileProvider.propTypes = {
- file: PropTypes.shape({
- linkedFileData: PropTypes.object,
- created: PropTypes.string,
- }).isRequired,
-}
diff --git a/services/web/frontend/js/features/file-view/types/binary-file.ts b/services/web/frontend/js/features/file-view/types/binary-file.ts
new file mode 100644
index 0000000000..efed8be1d1
--- /dev/null
+++ b/services/web/frontend/js/features/file-view/types/binary-file.ts
@@ -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
=
+ {
+ _id: string
+ name: string
+ created: Date
+ id: string
+ type: string
+ selected: boolean
+ linkedFileData?: LinkedFileData[T]
+ }
+
+export type LinkedFile = Required>
+
+export const hasProvider = (
+ file: BinaryFile,
+ provider: T
+): file is LinkedFile => file.linkedFileData?.provider === provider
diff --git a/services/web/test/frontend/features/file-view/components/file-view-header.test.js b/services/web/test/frontend/features/file-view/components/file-view-header.test.js
index 6789462a3d..8fbc005028 100644
--- a/services/web/test/frontend/features/file-view/components/file-view-header.test.js
+++ b/services/web/test/frontend/features/file-view/components/file-view-header.test.js
@@ -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('', function () {
const urlFile = {
diff --git a/services/web/types/window.ts b/services/web/types/window.ts
index 68290269ae..ee97878621 100644
--- a/services/web/types/window.ts
+++ b/services/web/types/window.ts
@@ -39,5 +39,6 @@ declare global {
enterprise?: boolean
useRecaptchaNet?: boolean
}
+ expectingLinkedFileRefreshedSocketFor?: string | null
}
}