Files
payload/packages/next/src/views/Version/SelectComparison/index.tsx
Alessio Gravili bc98567f41 feat!: rename @payloadcms/ui/client to @payloadcms/ui, and other auto-suggestion & exports improvements (#6848)
**BREAKING:** All `@payloadcms/ui/client` exports have been renamed to
`@payloadcms/ui`. A simple find & replace across your entire project
will be enough to migrate. This change greatly improves import
auto-completions in IDEs which lack proper support for package.json
exports, like Webstorm.
2024-06-19 16:36:00 +00:00

140 lines
3.6 KiB
TypeScript

'use client'
import type { PaginatedDocs, Where } from 'payload'
import {
ReactSelect,
fieldBaseClass,
useConfig,
useDocumentInfo,
useTranslation,
} from '@payloadcms/ui'
import { formatDate } from '@payloadcms/ui/shared'
import qs from 'qs'
import React, { useCallback, useEffect, useState } from 'react'
import type { Props } from './types.js'
import { mostRecentVersionOption, publishedVersionOption } from '../shared.js'
import './index.scss'
const baseClass = 'compare-version'
const maxResultsPerRequest = 10
const baseOptions = [mostRecentVersionOption]
export const SelectComparison: React.FC<Props> = (props) => {
const { baseURL, onChange, parentID, publishedDoc, value, versionID } = props
const {
admin: { dateFormat },
} = useConfig()
const { docConfig } = useDocumentInfo()
const [options, setOptions] = useState(baseOptions)
const [lastLoadedPage, setLastLoadedPage] = useState(1)
const [errorLoading, setErrorLoading] = useState('')
const { i18n, t } = useTranslation()
const loadedAllOptionsRef = React.useRef(false)
const getResults = useCallback(
async ({ lastLoadedPage: lastLoadedPageArg }) => {
if (loadedAllOptionsRef.current) return
const query: {
[key: string]: unknown
where: Where
} = {
depth: 0,
limit: maxResultsPerRequest,
page: lastLoadedPageArg,
where: {
and: [
{
id: {
not_equals: versionID,
},
},
],
},
}
if (docConfig.versions?.drafts) {
query.where.and.push({
latest: {
not_equals: true,
},
})
}
if (parentID) {
query.where.and.push({
parent: {
equals: parentID,
},
})
}
const search = qs.stringify(query)
const response = await fetch(`${baseURL}?${search}`, {
credentials: 'include',
headers: {
'Accept-Language': i18n.language,
},
})
if (response.ok) {
const data: PaginatedDocs = await response.json()
if (data.docs.length > 0) {
setOptions((existingOptions) => [
...existingOptions,
...data.docs.map((doc) => ({
label: formatDate({ date: doc.updatedAt, i18n, pattern: dateFormat }),
value: doc.id,
})),
])
if (!data.hasNextPage) {
loadedAllOptionsRef.current = true
}
setLastLoadedPage(data.page)
}
} else {
setErrorLoading(t('error:unspecific'))
}
},
[dateFormat, baseURL, parentID, versionID, t, i18n, docConfig.versions?.drafts],
)
useEffect(() => {
void getResults({ lastLoadedPage: 1 })
}, [getResults])
return (
<div
className={[fieldBaseClass, baseClass, errorLoading && 'error-loading']
.filter(Boolean)
.join(' ')}
>
<div className={`${baseClass}__label`}>{t('version:compareVersion')}</div>
{!errorLoading && (
<ReactSelect
isClearable={false}
isSearchable={false}
onChange={onChange}
onMenuScrollToBottom={() => {
void getResults({ lastLoadedPage: lastLoadedPage + 1 })
}}
options={[
...(publishedDoc?._status === 'published' ? [publishedVersionOption] : []),
...options,
]}
placeholder={t('version:selectVersionToCompare')}
value={value}
/>
)}
{errorLoading && <div className={`${baseClass}__error-loading`}>{errorLoading}</div>}
</div>
)
}