Zotero: fix for 6.3.0

This commit is contained in:
yu-i-i
2026-09-27 18:11:27 +02:00
parent ccc1c57ccd
commit dc36597117
9 changed files with 47 additions and 45 deletions
@@ -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(),
}),
@@ -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
}
}
@@ -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'
}
}
@@ -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<string>('')
const [selectedGroupId, setSelectedGroupId] = useState<string>("")
const [selectedFormat, setSelectedFormat] = useState<string>('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,
}
})
}
@@ -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 (
<p>
<LinkedFileIcon />
&nbsp;
{(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,
})
)}
</p>
@@ -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 (
<div className="file-view-error">
<OLNotification type="error" content={message} />
<Notification type="error" content={message} />
</div>
)
}
@@ -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 (
<OLNotification
<Notification
type="error"
content={t('zotero_groups_loading_error', {
provider: t('zotero'),
@@ -11,7 +11,7 @@ import {
OLModalFooter,
} from '@/shared/components/ol/ol-modal'
import OLButton from '@/shared/components/ol/ol-button'
import OLNotification from '@/shared/components/ol/ol-notification'
import Notification from '@/shared/components/notification'
import { ProjectSyncState, GitSyncModalStatus } from '../../types/git-sync-types'
@@ -51,19 +51,19 @@ const ZoteroLinkInfoModal = ({ show, isError, handleHide }: ZoteroLinkInfoModalP
<OLModalBody>
{showUnlinkInfo ? (
<OLNotification
<Notification
type="warning"
content={t('unlink_warning_reference', { provider: t('zotero') })}
/>
) : isError ? (
<OLNotification
<Notification
type="error"
content={t('problem_checking_connection_with_provider', {
provider: t('zotero'),
})}
/>
) : (
<OLNotification
<Notification
type="info"
content={
<Trans
@@ -12,7 +12,7 @@ import {
OLModalHeader,
OLModalTitle,
} from '@/shared/components/ol/ol-modal'
import OLNotification from '@/shared/components/ol/ol-notification'
import Notification from '@/shared/components/notification'
import ZoteroLogo from '@/shared/svgs/zotero-logo'
/**
@@ -97,14 +97,14 @@ export const ZoteroWidget = function ZoteroWidget() {
</p>
{isErrorConnCheck && (
<OLNotification
<Notification
type="error"
content={t('problem_checking_connection_with_provider', { provider: t('zotero') })}
/>
)}
{isErrorUnlink && (
<OLNotification
<Notification
type="error"
content={t('generic_something_went_wrong')}
/>