diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js
index e27b029895..f16b204bbb 100644
--- a/services/web/config/settings.defaults.js
+++ b/services/web/config/settings.defaults.js
@@ -827,8 +827,10 @@ module.exports = {
createFileModes: [],
gitBridge: [],
publishModal: [],
- tprLinkedFileInfo: [],
- tprLinkedFileRefreshError: [],
+ tprFileViewInfo: [],
+ tprFileViewRefreshError: [],
+ tprFileViewRefreshButton: [],
+ tprFileViewNotOriginalImporter: [],
contactUsModal: [],
editorToolbarButtons: [],
sourceEditorExtensions: [],
diff --git a/services/web/frontend/js/features/file-view/components/file-view-header.tsx b/services/web/frontend/js/features/file-view/components/file-view-header.tsx
index 5de43e79bd..aa2e0b2030 100644
--- a/services/web/frontend/js/features/file-view/components/file-view-header.tsx
+++ b/services/web/frontend/js/features/file-view/components/file-view-header.tsx
@@ -12,11 +12,17 @@ import importOverleafModules from '../../../../macros/import-overleaf-module.mac
import { LinkedFileIcon } from './file-view-icons'
import { BinaryFile, hasProvider, LinkedFile } from '../types/binary-file'
import FileViewRefreshButton from './file-view-refresh-button'
-import FileViewNotOriginalImporter from './file-view-not-original-importer'
import FileViewRefreshError from './file-view-refresh-error'
-const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo') as {
- import: { LinkedFileInfo: ElementType }
+const tprFileViewInfo = importOverleafModules('tprFileViewInfo') as {
+ import: { TPRFileViewInfo: ElementType }
+ path: string
+}[]
+
+const tprFileViewNotOriginalImporter = importOverleafModules(
+ 'tprFileViewNotOriginalImporter'
+) as {
+ import: { TPRFileViewNotOriginalImporter: ElementType }
path: string
}[]
@@ -79,8 +85,8 @@ export default function FileViewHeader({ file }: FileViewHeaderProps) {
{file.linkedFileData && fileInfo}
{file.linkedFileData &&
- tprLinkedFileInfo.map(({ import: { LinkedFileInfo }, path }) => (
-
+ tprFileViewInfo.map(({ import: { TPRFileViewInfo }, path }) => (
+
))}
{file.linkedFileData && permissionsLevel !== 'readOnly' && (
@@ -95,7 +101,12 @@ export default function FileViewHeader({ file }: FileViewHeaderProps) {
{t('download')}
- {file.linkedFileData &&
}
+ {file.linkedFileData &&
+ tprFileViewNotOriginalImporter.map(
+ ({ import: { TPRFileViewNotOriginalImporter }, path }) => (
+
+ )
+ )[0]}
{refreshError && (
)}
diff --git a/services/web/frontend/js/features/file-view/components/file-view-not-original-importer.tsx b/services/web/frontend/js/features/file-view/components/file-view-not-original-importer.tsx
deleted file mode 100644
index a18b1c3a5d..0000000000
--- a/services/web/frontend/js/features/file-view/components/file-view-not-original-importer.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { useTranslation } from 'react-i18next'
-import { capitalize } from 'lodash'
-import { useUserContext } from '@/shared/context/user-context'
-import { BinaryFile, hasProvider } from '../types/binary-file'
-
-type FileViewNotOriginalImporterProps = {
- file: BinaryFile
-}
-
-export default function FileViewNotOriginalImporter({
- file,
-}: FileViewNotOriginalImporterProps) {
- const { t } = useTranslation()
- const { id: userId } = useUserContext()
-
- const isMendeleyOrZotero =
- hasProvider(file, 'mendeley') || hasProvider(file, 'zotero')
-
- if (!isMendeleyOrZotero) {
- return null
- }
-
- const isImporter = file.linkedFileData.importer_id === userId
-
- if (isImporter) {
- return null
- }
-
- return (
-
-
- {t('only_importer_can_refresh', {
- provider: capitalize(file.linkedFileData.provider),
- })}
-
-
- )
-}
diff --git a/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx b/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx
index b3e4eee1e7..be6e68ccc0 100644
--- a/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx
+++ b/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx
@@ -1,73 +1,99 @@
import {
type Dispatch,
type SetStateAction,
+ type ElementType,
useCallback,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
-import classNames from 'classnames'
import Icon from '@/shared/components/icon'
import { postJSON } from '@/infrastructure/fetch-json'
import { useProjectContext } from '@/shared/context/project-context'
import useAbortController from '@/shared/hooks/use-abort-controller'
-import { useUserContext } from '@/shared/context/user-context'
-import { hasProvider, type BinaryFile } from '../types/binary-file'
+import type { BinaryFile } from '../types/binary-file'
import { Nullable } from '../../../../../types/utils'
+import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
type FileViewRefreshButtonProps = {
setRefreshError: Dispatch
>>
file: BinaryFile
}
+const tprFileViewRefreshButton = importOverleafModules(
+ 'tprFileViewRefreshButton'
+) as {
+ import: { TPRFileViewRefreshButton: ElementType }
+ path: string
+}[]
+
export default function FileViewRefreshButton({
setRefreshError,
file,
}: FileViewRefreshButtonProps) {
- const { signal } = useAbortController()
- const { t } = useTranslation()
- const [refreshing, setRefreshing] = useState(false)
const { _id: projectId } = useProjectContext()
- const { id: userId } = useUserContext()
+ const { signal } = useAbortController()
+ const [refreshing, setRefreshing] = useState(false)
- const isMendeleyOrZotero =
- hasProvider(file, 'mendeley') || hasProvider(file, 'zotero')
+ const refreshFile = useCallback(
+ (isTPR: Nullable) => {
+ setRefreshing(true)
+ // Replacement of the file handled by the file tree
+ window.expectingLinkedFileRefreshedSocketFor = file.name
+ const body = {
+ shouldReindexReferences: isTPR || /\.bib$/.test(file.name),
+ }
+ postJSON(`/project/${projectId}/linked_file/${file.id}/refresh`, {
+ signal,
+ body,
+ })
+ .then(() => {
+ setRefreshing(false)
+ })
+ .catch(err => {
+ setRefreshing(false)
+ setRefreshError(err.data?.message || err.message)
+ })
+ },
+ [file, projectId, signal, setRefreshError]
+ )
- let isImporter
-
- if (isMendeleyOrZotero) {
- isImporter = file.linkedFileData.importer_id === userId
+ if (tprFileViewRefreshButton.length > 0) {
+ return tprFileViewRefreshButton.map(
+ ({ import: { TPRFileViewRefreshButton }, path }) => (
+
+ )
+ )[0]
+ } else {
+ return (
+
+ )
}
+}
- const buttonClickable = isMendeleyOrZotero ? isImporter : true
+type FileViewRefreshButtonDefaultProps = {
+ refreshFile: (isTPR: Nullable) => void
+ refreshing: boolean
+}
- const refreshFile = useCallback(() => {
- setRefreshing(true)
- // Replacement of the file handled by the file tree
- window.expectingLinkedFileRefreshedSocketFor = file.name
- const body = {
- shouldReindexReferences: isMendeleyOrZotero || /\.bib$/.test(file.name),
- }
- postJSON(`/project/${projectId}/linked_file/${file.id}/refresh`, {
- signal,
- body,
- })
- .then(() => {
- setRefreshing(false)
- })
- .catch(err => {
- setRefreshing(false)
- setRefreshError(err.data?.message || err.message)
- })
- }, [file, projectId, signal, setRefreshError, isMendeleyOrZotero])
+function FileViewRefreshButtonDefault({
+ refreshFile,
+ refreshing,
+}: FileViewRefreshButtonDefaultProps) {
+ const { t } = useTranslation()
return (