diff --git a/libraries/overleaf-editor-core/lib/schemas.js b/libraries/overleaf-editor-core/lib/schemas.js index af78c0148f..f613e638de 100644 --- a/libraries/overleaf-editor-core/lib/schemas.js +++ b/libraries/overleaf-editor-core/lib/schemas.js @@ -140,6 +140,7 @@ const rawLinkedFileData = z.discriminatedUnion('provider', [ format: z.enum(['bibtex', 'biblatex']).optional(), group_id: zz.routeSegment().nullish(), importer_id: z.string().optional(), + importer_name: z.string().optional(), v1_importer_id: z.number().optional(), importedAt: z.iso.datetime().optional(), }), 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 index d49bce2e62..40a27d8e57 100644 --- a/services/web/frontend/js/features/file-view/types/binary-file.ts +++ b/services/web/frontend/js/features/file-view/types/binary-file.ts @@ -17,11 +17,11 @@ export type LinkedFileData = { } zotero: { provider: 'zotero' - zoteroGroupId?: string + group_id: string | null + format: 'bibtex' | 'biblatex' importedAt: Date | string - importedByUserId: string - importedByName: string - bibFormat: 'bibtex' | 'biblatex' + importer_id: string + importer_name: string } } diff --git a/services/web/modules/zotero/app/src/ZoteroLinkedFileAgent.mjs b/services/web/modules/zotero/app/src/ZoteroLinkedFileAgent.mjs index 8fc3929be5..6c595a669e 100644 --- a/services/web/modules/zotero/app/src/ZoteroLinkedFileAgent.mjs +++ b/services/web/modules/zotero/app/src/ZoteroLinkedFileAgent.mjs @@ -19,14 +19,14 @@ import ZoteroApiClient from './ZoteroApiClient.mjs' * linkedFileData shape: * { * provider: 'zotero' - * zoteroGroupId?: string + * group_id: string | null * importedAt: Date | string - * importedByUserId: string - * importedByName: string - * bibFormat: 'bibtex' || 'biblatex' + * importer_id: string + * importer_name: string + * format: 'bibtex' || 'biblatex' * } * - * - If zoteroGroupId is present, export that group's library. + * - If group_id is present, export that group's library. * - Otherwise, export the user's personal library ("My Library"). */ async function createLinkedFile( @@ -37,8 +37,8 @@ async function createLinkedFile( userId ) { - linkedFileData.importedByUserId = userId - linkedFileData.importedByName = await _getUserName(userId) || 'Unknown' + linkedFileData.importer_id = userId + linkedFileData.importer_name = await _getUserName(userId) || 'Unknown' logger.debug( { projectId, userId, linkedFileData }, @@ -76,16 +76,16 @@ async function refreshLinkedFile( // refresh importer's displayed name // if the importer is the owner, name is not displayed, refresh is not needed // if the importer is not available, the old name is preserved - const userName = await _getUserName(linkedFileData.importedByUserId) - if (userName && linkedFileData.importedByUserId != userId) { - linkedFileData.importedByName = userName + const userName = await _getUserName(linkedFileData.importer_id) + if (userName && linkedFileData.importer_id != userId) { + linkedFileData.importer_name = userName const { element, path } = await ProjectLocator.promises.findElement({ project_id: projectId, element_id: parentFolderId, type: 'folders' }) const fileIndex = element.fileRefs.findIndex(file => file.name === name) - const updatePath = `${path.mongo}.fileRefs.${fileIndex}.linkedFileData.importedByName` + const updatePath = `${path.mongo}.fileRefs.${fileIndex}.linkedFileData.importer_name` await Project.updateOne({ _id: projectId }, { $set: { [updatePath]: userName } }) } @@ -103,12 +103,12 @@ async function refreshLinkedFile( } async function _getBibtex(linkedFileData) { - const userId = linkedFileData.importedByUserId + const userId = linkedFileData.importer_id try { return await ZoteroApiClient.getLibraryBibtex( userId, - linkedFileData.zoteroGroupId, // == null for main library - linkedFileData.bibFormat || 'bibtex' + linkedFileData.group_id, // == null for main library + linkedFileData.format || 'bibtex' ) } catch (err) { @@ -117,11 +117,11 @@ async function _getBibtex(linkedFileData) { throw new LinkedFilesErrors.AccessDeniedError('Zotero access denied').withCause(err) } if (err instanceof ServiceNotConfiguredError) { - logger.debug({ userId: linkedFileData.importedByUserId, err }, 'Zotero account not linked') + logger.debug({ userId: linkedFileData.importer_id, err }, 'Zotero account not linked') throw new LinkedFilesErrors.AccessDeniedError('Zotero account not linked').withCause(err) } if (err instanceof NotFoundError) { - logger.debug({ group: linkedFileData.zoteroGroupId, err }, 'Zotero group is not found') + logger.debug({ group: linkedFileData.group_id, err }, 'Zotero group is not found') throw new LinkedFilesErrors.SourceFileNotFoundError('Zotero group is not found').withCause(err) } logger.error({ linkedFileData, err }, 'failed to retrieve bib file from Zotero') @@ -132,15 +132,13 @@ async function _getBibtex(linkedFileData) { function _sanitizeData(data) { return { provider: 'zotero', - ...(data.zoteroGroupId && { - zoteroGroupId: data.zoteroGroupId, - }), + group_id: data.group_id ?? null, importedAt: data.importedAt, - ...(data.importedByUserId && { - importedByUserId: data.importedByUserId, + ...(data.importer_id && { + importer_id: data.importer_id, }), - importedByName: data.importedByName || 'Unknown', - bibFormat: (data.bibFormat === 'biblatex') ? 'biblatex' : 'bibtex' + importer_name: data.importer_name || 'Unknown', + format: (data.format === 'biblatex') ? 'biblatex' : 'bibtex' } } diff --git a/services/web/modules/zotero/frontend/js/components/file-tree-import-from-zotero.tsx b/services/web/modules/zotero/frontend/js/components/file-tree-import-from-zotero.tsx index 37ce78f8d2..4aca5a4cde 100644 --- a/services/web/modules/zotero/frontend/js/components/file-tree-import-from-zotero.tsx +++ b/services/web/modules/zotero/frontend/js/components/file-tree-import-from-zotero.tsx @@ -9,7 +9,7 @@ import ErrorMessage from '@/features/file-tree/components/file-tree-create/error import OLFormGroup from '@/shared/components/ol/ol-form-group' import OLFormLabel from '@/shared/components/ol/ol-form-label' import OLFormSelect from '@/shared/components/ol/ol-form-select' -import OLNotification from '@/shared/components/ol/ol-notification' +import Notification from '@/shared/components/notification' type ZoteroGroup = { id: string @@ -23,7 +23,7 @@ export default function FileTreeImportFromZotero({ groups }: FileTreeImportFromZ const { name, setName } = useFileTreeCreateName() const { setValid } = useFileTreeCreateForm() const { finishCreatingLinkedFile, error, inFlight } = useFileTreeActionable() - const [selectedGroupId, setSelectedGroupId] = useState('') + const [selectedGroupId, setSelectedGroupId] = useState("") const [selectedFormat, setSelectedFormat] = useState('bibtex') useEffect(() => { @@ -40,7 +40,10 @@ export default function FileTreeImportFromZotero({ groups }: FileTreeImportFromZ finishCreatingLinkedFile({ name, provider: 'zotero', - data: { zoteroGroupId: selectedGroupId, bibFormat: selectedFormat } + data: { + group_id: selectedGroupId || undefined, + format: selectedFormat, + } }) } diff --git a/services/web/modules/zotero/frontend/js/components/tpr-file-view-info.tsx b/services/web/modules/zotero/frontend/js/components/tpr-file-view-info.tsx index 5865546bf7..0c1e85511e 100644 --- a/services/web/modules/zotero/frontend/js/components/tpr-file-view-info.tsx +++ b/services/web/modules/zotero/frontend/js/components/tpr-file-view-info.tsx @@ -25,14 +25,14 @@ export function TPRFileViewInfo({ file }: TPRFileViewInfoProps) { const formattedDate = formatTime(importedAt) const relative = relativeDate(importedAt) - const importedByUserId = (file.linkedFileData as any)?.importedByUserId - const importedByName = (file.linkedFileData as any)?.importedByName || 'Unknown' + const importer_id = (file.linkedFileData as any)?.importer_id + const importer_name = (file.linkedFileData as any)?.importer_name || 'Unknown' return (

  - {(importedByUserId === getMeta('ol-user_id')) ? ( + {(importer_id === getMeta('ol-user_id')) ? ( t('imported_from_zotero_at_date', { formattedDate, relativeDate: relative, @@ -41,7 +41,7 @@ export function TPRFileViewInfo({ file }: TPRFileViewInfoProps) { t('imported_from_zotero_at_date_by', { formattedDate, relativeDate: relative, - importedByName, + importer_name, }) )}

diff --git a/services/web/modules/zotero/frontend/js/components/tpr-file-view-refresh-error.tsx b/services/web/modules/zotero/frontend/js/components/tpr-file-view-refresh-error.tsx index 8df80ce1ce..0dc6d744cd 100644 --- a/services/web/modules/zotero/frontend/js/components/tpr-file-view-refresh-error.tsx +++ b/services/web/modules/zotero/frontend/js/components/tpr-file-view-refresh-error.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import OLNotification from '@/shared/components/ol/ol-notification' +import Notification from '@/shared/components/notification' import type { LinkedFile, LinkedFileData } from '@/features/file-view/types/binary-file' import { hasProvider } from '@/features/file-view/types/binary-file' @@ -35,7 +35,7 @@ export function TPRFileViewRefreshError({ return (
- +
) } diff --git a/services/web/modules/zotero/frontend/js/components/zotero-create-file.tsx b/services/web/modules/zotero/frontend/js/components/zotero-create-file.tsx index 602b0af7ac..8936cd6641 100644 --- a/services/web/modules/zotero/frontend/js/components/zotero-create-file.tsx +++ b/services/web/modules/zotero/frontend/js/components/zotero-create-file.tsx @@ -4,7 +4,7 @@ import useAsync from '@/shared/hooks/use-async' import { getJSON } from '@/infrastructure/fetch-json' import { debugConsole } from '@/utils/debugging' import OLButton from '@/shared/components/ol/ol-button' -import OLNotification from '@/shared/components/ol/ol-notification' +import Notification from '@/shared/components/notification' import { useFileTreeActionable } from '@/features/file-tree/contexts/file-tree-actionable' import FileTreeModalCreateFileMode from '@/features/file-tree/components/file-tree-create/file-tree-modal-create-file-mode' import FileTreeCreateNameProvider from '@/features/file-tree/contexts/file-tree-create-name' @@ -108,7 +108,7 @@ export function CreateFilePane() { } } else if (isGroupsError) { return ( - {showUnlinkInfo ? ( - ) : isError ? ( - ) : ( - {isErrorConnCheck && ( - )} {isErrorUnlink && ( -