adds Translation component and removes more react-i18next
This commit is contained in:
@@ -18,6 +18,7 @@ export const Settings: React.FC<{
|
||||
return (
|
||||
<div className={[baseClass, className].filter(Boolean).join(' ')}>
|
||||
<h3>{t('general:payloadSettings')}</h3>
|
||||
|
||||
<div className={`${baseClass}__language`}>
|
||||
<Label htmlFor="language-select" label={t('general:language')} />
|
||||
<ReactSelect
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Button, Form, FormSubmit, Email, MinimalTemplate } from '@payloadcms/ui'
|
||||
import { Button, Form, FormSubmit, Email, MinimalTemplate, Translation } from '@payloadcms/ui'
|
||||
import { SanitizedConfig } from 'payload/types'
|
||||
import Link from 'next/link'
|
||||
import { initPage } from '../../utilities/initPage'
|
||||
@@ -25,7 +25,7 @@ export const generateMetadata = async ({
|
||||
export const ForgotPassword: React.FC<{
|
||||
config: Promise<SanitizedConfig>
|
||||
}> = async ({ config: configPromise }) => {
|
||||
const { config, user } = await initPage({ configPromise })
|
||||
const { config, user, i18n } = await initPage({ configPromise })
|
||||
|
||||
const {
|
||||
admin: { user: userSlug },
|
||||
@@ -47,19 +47,19 @@ export const ForgotPassword: React.FC<{
|
||||
if (user) {
|
||||
return (
|
||||
<MinimalTemplate className={baseClass}>
|
||||
<h1>
|
||||
{/* {t('alreadyLoggedIn')} */}
|
||||
Already Logged In
|
||||
</h1>
|
||||
<h1>{i18n.t('authentication:alreadyLoggedIn')}</h1>
|
||||
<p>
|
||||
{/* <Trans i18nKey="loggedInChangePassword" t={t}> */}
|
||||
<Link href={`${admin}/account`}>account</Link>
|
||||
{/* </Trans> */}
|
||||
<Translation
|
||||
t={i18n.t}
|
||||
i18nKey="authentication:loggedInChangePassword"
|
||||
elements={{
|
||||
'0': ({ children }) => <Link href={`${admin}/account`} children={children} />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<br />
|
||||
<Button buttonStyle="secondary" el="link" to={admin}>
|
||||
Back to Dashboard
|
||||
{/* {t('general:backToDashboard')} */}
|
||||
{i18n.t('general:backToDashboard')}
|
||||
</Button>
|
||||
</MinimalTemplate>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '@payloadcms/ui'
|
||||
|
||||
import type { SanitizedCollectionConfig } from '../../../../collections/config/types'
|
||||
import type { LivePreviewConfig } from '../../../../exports/config'
|
||||
@@ -31,7 +31,7 @@ const PreviewView: React.FC<
|
||||
fieldTypes: FieldTypes
|
||||
}
|
||||
> = (props) => {
|
||||
const { i18n, t } = useTranslation('general')
|
||||
const { i18n, t } = useTranslation()
|
||||
const { previewWindowType } = useLivePreviewContext()
|
||||
|
||||
const { apiURL, data, fieldTypes, permissions } = props
|
||||
@@ -69,9 +69,9 @@ const PreviewView: React.FC<
|
||||
<Fragment>
|
||||
{collection && (
|
||||
<Meta
|
||||
description={t('editing')}
|
||||
description={t('general:editing')}
|
||||
keywords={`${getTranslation(collection.labels.singular, i18n)}, Payload, CMS`}
|
||||
title={`${isEditing ? t('editing') : t('creating')} - ${getTranslation(
|
||||
title={`${isEditing ? t('general:editing') : t('general:creating')} - ${getTranslation(
|
||||
collection.labels.singular,
|
||||
i18n,
|
||||
)}`}
|
||||
@@ -92,7 +92,7 @@ const PreviewView: React.FC<
|
||||
global={global}
|
||||
id={id}
|
||||
isEditing={isEditing}
|
||||
view={t('livePreview')}
|
||||
view={t('general:livePreview')}
|
||||
/>
|
||||
<DocumentControls
|
||||
apiURL={apiURL}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
ConfirmPassword,
|
||||
HiddenInput,
|
||||
Password,
|
||||
Translation,
|
||||
} from '@payloadcms/ui'
|
||||
import './index.scss'
|
||||
import { SanitizedConfig } from 'payload/types'
|
||||
@@ -62,9 +63,13 @@ export const ResetPassword: React.FC<{
|
||||
{/* {t('alreadyLoggedIn')} */}
|
||||
</h1>
|
||||
<p>
|
||||
{/* <Trans i18nKey="loginWithAnotherUser" t={t}> */}
|
||||
<Link href={`${admin}${logoutRoute}`}>log out</Link>
|
||||
{/* </Trans> */}
|
||||
<Translation
|
||||
t={i18n.t}
|
||||
i18nKey="authentication:loggedInChangePassword"
|
||||
elements={{
|
||||
'0': ({ children }) => <Link href={`${admin}/account`} children={children} />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<br />
|
||||
<Button buttonStyle="secondary" el="link" to={admin}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import qs from 'qs'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '@payloadcms/ui'
|
||||
|
||||
import type { PaginatedDocs } from 'payload/database'
|
||||
import type { Where } from 'payload/types'
|
||||
@@ -27,7 +27,7 @@ const CompareVersion: React.FC<Props> = (props) => {
|
||||
const [options, setOptions] = useState(baseOptions)
|
||||
const [lastLoadedPage, setLastLoadedPage] = useState(1)
|
||||
const [errorLoading, setErrorLoading] = useState('')
|
||||
const { i18n, t } = useTranslation('version')
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
const getResults = useCallback(
|
||||
async ({ lastLoadedPage: lastLoadedPageArg }) => {
|
||||
@@ -99,7 +99,7 @@ const CompareVersion: React.FC<Props> = (props) => {
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
<div className={`${baseClass}__label`}>{t('compareVersion')}</div>
|
||||
<div className={`${baseClass}__label`}>{t('version:compareVersion')}</div>
|
||||
{!errorLoading && (
|
||||
<ReactSelect
|
||||
isClearable={false}
|
||||
@@ -109,7 +109,7 @@ const CompareVersion: React.FC<Props> = (props) => {
|
||||
getResults({ lastLoadedPage: lastLoadedPage + 1 })
|
||||
}}
|
||||
options={options}
|
||||
placeholder={t('selectVersionToCompare')}
|
||||
placeholder={t('version:selectVersionToCompare')}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import ReactDiffViewer from 'react-diff-viewer-continued'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '@payloadcms/ui'
|
||||
|
||||
import type { RelationshipField, SanitizedCollectionConfig } from 'payload/types'
|
||||
import type { Props } from '../types'
|
||||
@@ -74,12 +74,12 @@ const Relationship: React.FC<Props & { field: RelationshipField }> = ({
|
||||
version,
|
||||
}) => {
|
||||
const { collections } = useConfig()
|
||||
const { i18n, t } = useTranslation('general')
|
||||
const { i18n, t } = useTranslation()
|
||||
const { code: locale } = useLocale()
|
||||
|
||||
let placeholder = ''
|
||||
|
||||
if (version === comparison) placeholder = `[${t('noValue')}]`
|
||||
if (version === comparison) placeholder = `[${t('general:noValue')}]`
|
||||
|
||||
let versionToRender = version
|
||||
let comparisonToRender = comparison
|
||||
@@ -102,8 +102,7 @@ const Relationship: React.FC<Props & { field: RelationshipField }> = ({
|
||||
<div className={baseClass}>
|
||||
<Label>
|
||||
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
||||
// TODO(i18n)
|
||||
{/* {getTranslation(field.label, i18n)} */}
|
||||
{getTranslation(field.label, i18n)}
|
||||
</Label>
|
||||
<ReactDiffViewer
|
||||
hideLineNumbers
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '@payloadcms/ui'
|
||||
|
||||
import type { Props } from './types'
|
||||
|
||||
@@ -9,7 +9,7 @@ import './index.scss'
|
||||
const baseClass = 'select-version-locales'
|
||||
|
||||
const SelectLocales: React.FC<Props> = ({ onChange, options, value }) => {
|
||||
const { t } = useTranslation('version')
|
||||
const { t } = useTranslation()
|
||||
const { code } = useLocale()
|
||||
|
||||
const format = (items) => {
|
||||
@@ -26,12 +26,12 @@ const SelectLocales: React.FC<Props> = ({ onChange, options, value }) => {
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__label`}>{t('showLocales')}</div>
|
||||
<div className={`${baseClass}__label`}>{t('version:showLocales')}</div>
|
||||
<ReactSelect
|
||||
isMulti
|
||||
onChange={onChange}
|
||||
options={format(options)}
|
||||
placeholder={t('selectLocales')}
|
||||
placeholder={t('version:selectLocales')}
|
||||
value={format(value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -118,11 +118,11 @@ export const createPayloadRequest = async ({
|
||||
|
||||
// need to add:
|
||||
// ------------
|
||||
// - files
|
||||
// - transactionID
|
||||
// - findByID
|
||||
// - payloadDataLoader
|
||||
// - payloadUploadSizes
|
||||
// - files
|
||||
}
|
||||
|
||||
const req: PayloadRequest = Object.assign(request, customRequest)
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@faceless-ui/modal": "2.0.1",
|
||||
"@payloadcms/translations": "workspace:*",
|
||||
"@payloadcms/ui": "workspace:*",
|
||||
"@lexical/headless": "0.12.5",
|
||||
"@lexical/link": "0.12.5",
|
||||
"@lexical/list": "0.12.5",
|
||||
@@ -30,16 +28,16 @@
|
||||
"@lexical/rich-text": "0.12.5",
|
||||
"@lexical/selection": "0.12.5",
|
||||
"@lexical/utils": "0.12.5",
|
||||
"@payloadcms/translations": "workspace:*",
|
||||
"@payloadcms/ui": "workspace:*",
|
||||
"bson-objectid": "2.0.4",
|
||||
"classnames": "^2.3.2",
|
||||
"deep-equal": "2.2.3",
|
||||
"i18next": "22.5.1",
|
||||
"lexical": "0.12.5",
|
||||
"lodash": "4.17.21",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-error-boundary": "^4.0.11",
|
||||
"react-i18next": "11.18.6",
|
||||
"ts-essentials": "7.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -13,11 +13,11 @@ import {
|
||||
createNestedFieldPath,
|
||||
useDocumentInfo,
|
||||
useFormSubmitted,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import isDeepEqual from 'deep-equal'
|
||||
import { $getNodeByKey } from 'lexical'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { FieldProps } from '../../../../types'
|
||||
import type { BlockFields, BlockNode } from '../nodes/BlocksNode'
|
||||
@@ -181,8 +181,9 @@ export const BlockContent: React.FC<Props> = (props) => {
|
||||
className={`${baseClass}__block-pill ${baseClass}__block-pill-${formData?.blockType}`}
|
||||
pillStyle="white"
|
||||
>
|
||||
{typeof labels.singular === 'string' ? labels.singular : '[Singular Label]'}
|
||||
{/* {getTranslation(labels.singular, i18n)} */}
|
||||
{typeof labels.singular === 'string'
|
||||
? getTranslation(labels.singular, i18n)
|
||||
: '[Singular Label]'}
|
||||
</Pill>
|
||||
<SectionTitle path={`${path}blockName`} readOnly={field?.admin?.readOnly} />
|
||||
{fieldHasErrors && <ErrorPill count={errorCount} withMessage />}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
useDocumentInfo,
|
||||
useFormSubmitted,
|
||||
useLocale,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import React, { useEffect, useMemo } from 'react'
|
||||
|
||||
@@ -16,7 +17,6 @@ const baseClass = 'lexical-block'
|
||||
import type { Data } from 'payload/types'
|
||||
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { BlocksFeatureProps } from '..'
|
||||
|
||||
@@ -63,7 +63,7 @@ export const BlockComponent: React.FC<Props> = (props) => {
|
||||
const initialStateRef = React.useRef<Data>(null) // Store initial value in a ref, so it doesn't change on re-render and only gets initialized once
|
||||
|
||||
const config = useConfig()
|
||||
const { t } = useTranslation('general')
|
||||
const { t } = useTranslation()
|
||||
const { code: locale } = useLocale()
|
||||
const { getDocPreferences } = useDocumentInfo()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { BlocksDrawer, formatDrawerSlug, useEditDepth } from '@payloadcms/ui'
|
||||
import { BlocksDrawer, formatDrawerSlug, useEditDepth, useTranslation } from '@payloadcms/ui'
|
||||
import {
|
||||
$getNodeByKey,
|
||||
COMMAND_PRIORITY_EDITOR,
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
createCommand,
|
||||
} from 'lexical'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { BlocksFeatureProps } from '..'
|
||||
|
||||
@@ -60,12 +59,12 @@ export const BlocksDrawerComponent: React.FC = () => {
|
||||
|
||||
const [replaceNodeKey, setReplaceNodeKey] = useState<null | string>(null)
|
||||
const editDepth = useEditDepth()
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
const { openModal } = useModal()
|
||||
|
||||
const labels = {
|
||||
plural: t('blocks') || 'Blocks',
|
||||
singular: t('block') || 'Block',
|
||||
plural: t('fields:blocks') || 'Blocks',
|
||||
singular: t('fields:block') || 'Block',
|
||||
}
|
||||
|
||||
const addRow = useCallback(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Drawer, Form, FormSubmit, RenderFields, fieldTypes } from '@payloadcms/ui'
|
||||
import { Drawer, Form, FormSubmit, RenderFields, fieldTypes, useTranslation } from '@payloadcms/ui'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import './index.scss'
|
||||
import { type Props } from './types'
|
||||
@@ -13,10 +12,10 @@ export const LinkDrawer: React.FC<Props> = ({
|
||||
handleModalSubmit,
|
||||
initialState,
|
||||
}) => {
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Drawer className={baseClass} slug={drawerSlug} title={t('editLink') ?? ''}>
|
||||
<Drawer className={baseClass} slug={drawerSlug} title={t('fields:editLink') ?? ''}>
|
||||
<Form fields={fieldSchema} initialState={initialState} onSubmit={handleModalSubmit}>
|
||||
[RenderFields]
|
||||
{/* <RenderFields
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
useDocumentInfo,
|
||||
useEditDepth,
|
||||
useLocale,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import {
|
||||
$getSelection,
|
||||
@@ -25,7 +26,6 @@ import {
|
||||
} from 'lexical'
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { LinkFeatureProps } from '../../..'
|
||||
import type { LinkNode } from '../../../nodes/LinkNode'
|
||||
@@ -57,7 +57,7 @@ export function LinkEditor({
|
||||
|
||||
const { user } = useAuth()
|
||||
const { code: locale } = useLocale()
|
||||
const { i18n, t } = useTranslation(['fields', 'upload', 'general'])
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
const { getDocPreferences } = useDocumentInfo()
|
||||
|
||||
@@ -137,8 +137,6 @@ export function LinkEditor({
|
||||
(coll) => coll.slug === linkParent.getFields()?.doc?.relationTo,
|
||||
)
|
||||
const label = t('fields:linkedTo', {
|
||||
// TODO: fix this
|
||||
// @ts-ignore-next-line
|
||||
label: getTranslation(relatedField.labels.singular, i18n),
|
||||
}).replace(/<[^>]*>?/g, '')
|
||||
setLinkLabel(label)
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { Button, useConfig, useDocumentDrawer, usePayloadAPI } from '@payloadcms/ui'
|
||||
import { Button, useConfig, useDocumentDrawer, usePayloadAPI, useTranslation } from '@payloadcms/ui'
|
||||
import { $getNodeByKey, type ElementFormatType } from 'lexical'
|
||||
import React, { useCallback, useReducer, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { RelationshipData } from '../RelationshipNode'
|
||||
|
||||
@@ -50,7 +49,7 @@ const Component: React.FC<Props> = (props) => {
|
||||
collections.find((coll) => coll.slug === relationTo),
|
||||
)
|
||||
|
||||
const { i18n, t } = useTranslation(['fields', 'general'])
|
||||
const { i18n, t } = useTranslation()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [{ data }, { setParams }] = usePayloadAPI(
|
||||
`${serverURL}${api}/${relatedCollection.slug}/${id}`,
|
||||
@@ -88,9 +87,7 @@ const Component: React.FC<Props> = (props) => {
|
||||
>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<p className={`${baseClass}__label`}>
|
||||
{t('labelRelationship', {
|
||||
// TODO: fix this
|
||||
// @ts-ignore-next-line
|
||||
{t('fields:labelRelationship', {
|
||||
label: getTranslation(relatedCollection.labels.singular, i18n),
|
||||
})}
|
||||
</p>
|
||||
@@ -114,7 +111,7 @@ const Component: React.FC<Props> = (props) => {
|
||||
})
|
||||
}}
|
||||
round
|
||||
tooltip={t('swapRelationship')}
|
||||
tooltip={t('fields:swapRelationship')}
|
||||
/>
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
useConfig,
|
||||
useDocumentInfo,
|
||||
useLocale,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { $getNodeByKey } from 'lexical'
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import { deepCopyObject } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { ElementProps } from '..'
|
||||
import type { UploadFeatureProps } from '../..'
|
||||
@@ -122,8 +122,6 @@ export const ExtraFieldsUploadDrawer: React.FC<
|
||||
<Drawer
|
||||
slug={drawerSlug}
|
||||
title={t('general:editLabel', {
|
||||
// TODO: fix this
|
||||
// @ts-ignore-next-line
|
||||
label: getTranslation(relatedCollection.labels.singular, i18n),
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
useDrawerSlug,
|
||||
usePayloadAPI,
|
||||
useThumbnail,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { $getNodeByKey } from 'lexical'
|
||||
import React, { useCallback, useReducer, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { UploadFeatureProps } from '..'
|
||||
import type { UploadData } from '../nodes/UploadNode'
|
||||
@@ -55,7 +55,7 @@ const Component: React.FC<ElementProps> = (props) => {
|
||||
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey)
|
||||
const { editorConfig, field } = useEditorConfigContext()
|
||||
|
||||
const { i18n, t } = useTranslation('fields')
|
||||
const { i18n, t } = useTranslation()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [relatedCollection, setRelatedCollection] = useState<SanitizedCollectionConfig>(() =>
|
||||
collections.find((coll) => coll.slug === relationTo),
|
||||
@@ -147,7 +147,7 @@ const Component: React.FC<ElementProps> = (props) => {
|
||||
})
|
||||
}}
|
||||
round
|
||||
tooltip={t('swapUpload')}
|
||||
tooltip={t('fields:swapUpload')}
|
||||
/>
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
@@ -159,7 +159,7 @@ const Component: React.FC<ElementProps> = (props) => {
|
||||
removeUpload()
|
||||
}}
|
||||
round
|
||||
tooltip={t('removeUpload')}
|
||||
tooltip={t('fields:removeUpload')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { i18n } from 'i18next'
|
||||
import type { I18n } from '@payloadcms/translations'
|
||||
import type { LexicalEditor } from 'lexical'
|
||||
import type { MutableRefObject } from 'react'
|
||||
import type React from 'react'
|
||||
@@ -7,7 +7,7 @@ export class SlashMenuOption {
|
||||
// Icon for display
|
||||
Icon: () => Promise<React.FC>
|
||||
|
||||
displayName?: (({ i18n }: { i18n: i18n }) => string) | string
|
||||
displayName?: (({ i18n }: { i18n: I18n }) => string) | string
|
||||
// Used for class names and, if displayName is not provided, for display.
|
||||
key: string
|
||||
// TBD
|
||||
@@ -23,7 +23,7 @@ export class SlashMenuOption {
|
||||
key: string,
|
||||
options: {
|
||||
Icon: () => Promise<React.FC>
|
||||
displayName?: (({ i18n }: { i18n: i18n }) => string) | string
|
||||
displayName?: (({ i18n }: { i18n: I18n }) => string) | string
|
||||
keyboardShortcut?: string
|
||||
keywords?: Array<string>
|
||||
onSelect: ({ editor, queryString }: { editor: LexicalEditor; queryString: string }) => void
|
||||
@@ -47,7 +47,7 @@ export class SlashMenuOption {
|
||||
|
||||
export class SlashMenuGroup {
|
||||
// Used for class names and, if displayName is not provided, for display.
|
||||
displayName?: (({ i18n }: { i18n: i18n }) => string) | string
|
||||
displayName?: (({ i18n }: { i18n: I18n }) => string) | string
|
||||
key: string
|
||||
options: Array<SlashMenuOption>
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import type { TextNode } from 'lexical'
|
||||
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { useTranslation } from '@payloadcms/ui'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import * as React from 'react'
|
||||
import * as ReactDOM from 'react-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { SlashMenuGroup, SlashMenuOption } from './LexicalTypeaheadMenuPlugin/types'
|
||||
|
||||
@@ -28,7 +28,7 @@ function SlashMenuItem({
|
||||
onMouseEnter: () => void
|
||||
option: SlashMenuOption
|
||||
}) {
|
||||
const { i18n } = useTranslation('fields')
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
let className = `${baseClass}__item ${baseClass}__item-${option.key}`
|
||||
if (isSelected) {
|
||||
@@ -87,7 +87,7 @@ export function SlashMenuPlugin({
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const [queryString, setQueryString] = useState<null | string>(null)
|
||||
const { editorConfig } = useEditorConfigContext()
|
||||
const { i18n } = useTranslation('fields')
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const checkForTriggerMatch = useMenuTriggerMatch('/', {
|
||||
minLength: 0,
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@faceless-ui/modal": "2.0.1",
|
||||
"i18next": "22.5.1",
|
||||
"@payloadcms/translations": "workspace:^",
|
||||
"@payloadcms/ui": "workspace:^",
|
||||
"is-hotkey": "0.2.0",
|
||||
"react": "18.2.0",
|
||||
"react-i18next": "11.18.6",
|
||||
"slate": "0.91.4",
|
||||
"slate-history": "0.86.0",
|
||||
"slate-hyperscript": "0.81.3",
|
||||
|
||||
@@ -4,12 +4,17 @@ import type { BaseEditor, BaseOperation } from 'slate'
|
||||
import type { HistoryEditor } from 'slate-history'
|
||||
import type { ReactEditor } from 'slate-react'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import {
|
||||
Error,
|
||||
FieldDescription,
|
||||
Label,
|
||||
useEditDepth,
|
||||
useField,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import isHotkey from 'is-hotkey'
|
||||
import { Error, FieldDescription, Label, useField, withCondition } from 'payload/components/forms'
|
||||
import { useEditDepth } from 'payload/components/utilities'
|
||||
import { getTranslation } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Node, Element as SlateElement, Text, Transforms, createEditor } from 'slate'
|
||||
import { withHistory } from 'slate-history'
|
||||
import { Editable, Slate, withReact } from 'slate-react'
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
'use client'
|
||||
|
||||
import type { Fields } from 'payload/types'
|
||||
import type { Fields } from '@payloadcms/ui'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { useDrawerSlug } from 'payload/components/elements'
|
||||
import { reduceFieldsToValues } from 'payload/components/forms'
|
||||
import {
|
||||
buildStateFromSchema,
|
||||
reduceFieldsToValues,
|
||||
useAuth,
|
||||
useConfig,
|
||||
useDocumentInfo,
|
||||
useDrawerSlug,
|
||||
useLocale,
|
||||
} from 'payload/components/utilities'
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import React, { Fragment, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Editor, Range, Transforms } from 'slate'
|
||||
import { ReactEditor, useSlate } from 'slate-react'
|
||||
|
||||
@@ -73,7 +73,7 @@ export const LinkButton: React.FC<{
|
||||
const { code: locale } = useLocale()
|
||||
const [initialState, setInitialState] = useState<Fields>({})
|
||||
|
||||
const { i18n, t } = useTranslation(['upload', 'general'])
|
||||
const { i18n, t } = useTranslation()
|
||||
const editor = useSlate()
|
||||
const config = useConfig()
|
||||
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
'use client'
|
||||
|
||||
import type { Fields } from 'payload/types'
|
||||
import type { Fields } from '@payloadcms/ui'
|
||||
import type { HTMLAttributes } from 'react'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { Button, Popup } from 'payload/components'
|
||||
import { useDrawerSlug } from 'payload/components/elements'
|
||||
import { reduceFieldsToValues } from 'payload/components/forms'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import {
|
||||
Button,
|
||||
Popup,
|
||||
Translation,
|
||||
buildStateFromSchema,
|
||||
reduceFieldsToValues,
|
||||
useAuth,
|
||||
useConfig,
|
||||
useDocumentInfo,
|
||||
useDrawerSlug,
|
||||
useLocale,
|
||||
} from 'payload/components/utilities'
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import { deepCopyObject, getTranslation } from 'payload/utilities'
|
||||
import { deepCopyObject } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { Editor, Node, Transforms } from 'slate'
|
||||
import { ReactEditor, useSlate } from 'slate-react'
|
||||
|
||||
@@ -73,7 +76,7 @@ export const LinkElement: React.FC<{
|
||||
const config = useConfig()
|
||||
const { user } = useAuth()
|
||||
const { code: locale } = useLocale()
|
||||
const { i18n, t } = useTranslation('fields')
|
||||
const { i18n, t } = useTranslation()
|
||||
const { closeModal, openModal, toggleModal } = useModal()
|
||||
const [renderModal, setRenderModal] = useState(false)
|
||||
const [renderPopup, setRenderPopup] = useState(false)
|
||||
@@ -155,16 +158,9 @@ export const LinkElement: React.FC<{
|
||||
render={() => (
|
||||
<div className={`${baseClass}__popup`}>
|
||||
{element.linkType === 'internal' && element.doc?.relationTo && element.doc?.value && (
|
||||
<Trans
|
||||
i18nKey="fields:linkedTo"
|
||||
values={{
|
||||
label: getTranslation(
|
||||
config.collections.find(({ slug }) => slug === element.doc.relationTo)?.labels
|
||||
?.singular,
|
||||
i18n,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Translation
|
||||
elements={{
|
||||
'0': ({ children }) => (
|
||||
<a
|
||||
className={`${baseClass}__link-label`}
|
||||
href={`${config.routes.admin}/collections/${element.doc.relationTo}/${element.doc.value}`}
|
||||
@@ -172,9 +168,20 @@ export const LinkElement: React.FC<{
|
||||
target="_blank"
|
||||
title={`${config.routes.admin}/collections/${element.doc.relationTo}/${element.doc.value}`}
|
||||
>
|
||||
label
|
||||
{children}
|
||||
</a>
|
||||
</Trans>
|
||||
),
|
||||
}}
|
||||
i18nKey="fields:linkedTo"
|
||||
t={t}
|
||||
variables={{
|
||||
label: getTranslation(
|
||||
config.collections.find(({ slug }) => slug === element.doc.relationTo)?.labels
|
||||
?.singular,
|
||||
i18n,
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{(element.linkType === 'custom' || !element.linkType) && (
|
||||
<a
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
'use client'
|
||||
|
||||
import { Drawer } from 'payload/components/elements'
|
||||
import { Form, FormSubmit, RenderFields } from 'payload/components/forms'
|
||||
import { fieldTypes } from 'payload/components/forms'
|
||||
import {
|
||||
Drawer,
|
||||
Form,
|
||||
FormSubmit,
|
||||
RenderFields,
|
||||
fieldTypes,
|
||||
useEditDepth,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { useHotkey } from 'payload/components/hooks'
|
||||
import { useEditDepth } from 'payload/components/utilities'
|
||||
import React, { useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import type { Props } from './types'
|
||||
|
||||
@@ -20,10 +24,10 @@ export const LinkDrawer: React.FC<Props> = ({
|
||||
handleModalSubmit,
|
||||
initialState,
|
||||
}) => {
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Drawer className={baseClass} slug={drawerSlug} title={t('editLink')}>
|
||||
<Drawer className={baseClass} slug={drawerSlug} title={t('fields:editLink')}>
|
||||
<Form fields={fieldSchema} initialState={initialState} onSubmit={handleModalSubmit}>
|
||||
<RenderFields
|
||||
fieldSchema={fieldSchema}
|
||||
@@ -38,7 +42,7 @@ export const LinkDrawer: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
const LinkSubmit: React.FC = () => {
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
const ref = useRef<HTMLButtonElement>(null)
|
||||
const editDepth = useEditDepth()
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { RelationshipComponent } from 'payload/components/fields/Relationship'
|
||||
import { SelectComponent } from 'payload/components/fields/Select'
|
||||
import { useFormFields } from 'payload/components/forms'
|
||||
import { useAuth, useConfig } from 'payload/components/utilities'
|
||||
import {
|
||||
RelationshipComponent,
|
||||
SelectComponent,
|
||||
useAuth,
|
||||
useConfig,
|
||||
useFormFields,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import React, { Fragment, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const createOptions = (collections, permissions) =>
|
||||
collections.reduce((options, collection) => {
|
||||
@@ -28,7 +31,7 @@ const createOptions = (collections, permissions) =>
|
||||
const RelationshipFields = () => {
|
||||
const { collections } = useConfig()
|
||||
const { permissions } = useAuth()
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [options, setOptions] = useState(() => createOptions(collections, permissions))
|
||||
const relationTo = useFormFields<string>(([fields]) => fields.relationTo?.value as string)
|
||||
@@ -39,10 +42,15 @@ const RelationshipFields = () => {
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<SelectComponent label={t('relationTo')} name="relationTo" options={options} required />
|
||||
<SelectComponent
|
||||
label={t('fields:relationTo')}
|
||||
name="relationTo"
|
||||
options={options}
|
||||
required
|
||||
/>
|
||||
{relationTo && (
|
||||
<RelationshipComponent
|
||||
label={t('relatedDocument')}
|
||||
label={t('fields:relatedDocument')}
|
||||
name="value"
|
||||
relationTo={relationTo}
|
||||
required
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useListDrawer } from 'payload/components/elements'
|
||||
import { useListDrawer, useTranslation } from '@payloadcms/ui'
|
||||
import React, { Fragment, useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ReactEditor, useSlate } from 'slate-react'
|
||||
|
||||
import RelationshipIcon from '../../../icons/Relationship'
|
||||
@@ -33,7 +32,7 @@ type Props = {
|
||||
path: string
|
||||
}
|
||||
const RelationshipButton: React.FC<Props> = ({ enabledCollectionSlugs }) => {
|
||||
const { t } = useTranslation('fields')
|
||||
const { t } = useTranslation()
|
||||
const editor = useSlate()
|
||||
const [selectedCollectionSlug, setSelectedCollectionSlug] = useState(
|
||||
() => enabledCollectionSlugs[0],
|
||||
@@ -72,7 +71,7 @@ const RelationshipButton: React.FC<Props> = ({ enabledCollectionSlugs }) => {
|
||||
onClick={() => {
|
||||
// do nothing
|
||||
}}
|
||||
tooltip={t('addRelationship')}
|
||||
tooltip={t('fields:addRelationship')}
|
||||
>
|
||||
<RelationshipIcon />
|
||||
</ElementButton>
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
import type { HTMLAttributes } from 'react'
|
||||
|
||||
import { Button } from 'payload/components'
|
||||
import { useDocumentDrawer, useListDrawer } from 'payload/components/elements'
|
||||
import { usePayloadAPI } from 'payload/components/hooks'
|
||||
import { useConfig } from 'payload/components/utilities'
|
||||
import { getTranslation } from 'payload/utilities'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import {
|
||||
Button,
|
||||
useConfig,
|
||||
useDocumentDrawer,
|
||||
useListDrawer,
|
||||
usePayloadAPI,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import React, { useCallback, useReducer, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Transforms } from 'slate'
|
||||
import { ReactEditor, useFocused, useSelected, useSlateStatic } from 'slate-react'
|
||||
|
||||
@@ -53,7 +56,7 @@ const Element: React.FC<Props> = (props) => {
|
||||
)
|
||||
const selected = useSelected()
|
||||
const focused = useFocused()
|
||||
const { i18n, t } = useTranslation(['fields', 'general'])
|
||||
const { i18n, t } = useTranslation()
|
||||
const editor = useSlateStatic()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [{ data }, { setParams }] = usePayloadAPI(
|
||||
@@ -141,7 +144,7 @@ const Element: React.FC<Props> = (props) => {
|
||||
>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<p className={`${baseClass}__label`}>
|
||||
{t('labelRelationship', {
|
||||
{t('fields:labelRelationship', {
|
||||
label: getTranslation(relatedCollection.labels.singular, i18n),
|
||||
})}
|
||||
</p>
|
||||
@@ -165,7 +168,7 @@ const Element: React.FC<Props> = (props) => {
|
||||
// do nothing
|
||||
}}
|
||||
round
|
||||
tooltip={t('swapRelationship')}
|
||||
tooltip={t('fields:swapRelationship')}
|
||||
/>
|
||||
</ListDrawerToggler>
|
||||
<Button
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useListDrawer } from 'payload/components/elements'
|
||||
import { useListDrawer, useTranslation } from '@payloadcms/ui'
|
||||
import React, { Fragment, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ReactEditor, useSlate } from 'slate-react'
|
||||
|
||||
import UploadIcon from '../../../icons/Upload'
|
||||
@@ -34,7 +33,7 @@ type ButtonProps = {
|
||||
}
|
||||
|
||||
const UploadButton: React.FC<ButtonProps> = ({ enabledCollectionSlugs }) => {
|
||||
const { t } = useTranslation(['upload', 'general'])
|
||||
const { t } = useTranslation()
|
||||
const editor = useSlate()
|
||||
|
||||
const [ListDrawer, ListDrawerToggler, { closeDrawer }] = useListDrawer({
|
||||
|
||||
@@ -3,19 +3,23 @@
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { Drawer } from 'payload/components/elements'
|
||||
import { Form, FormSubmit, RenderFields, fieldTypes } from 'payload/components/forms'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import {
|
||||
Drawer,
|
||||
Form,
|
||||
FormSubmit,
|
||||
RenderFields,
|
||||
buildStateFromSchema,
|
||||
fieldTypes,
|
||||
useAuth,
|
||||
useConfig,
|
||||
useDocumentInfo,
|
||||
useLocale,
|
||||
} from 'payload/components/utilities'
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { sanitizeFields } from 'payload/config'
|
||||
import { deepCopyObject, getTranslation } from 'payload/utilities'
|
||||
import { deepCopyObject } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Transforms } from 'slate'
|
||||
import { ReactEditor, useSlateStatic } from 'slate-react'
|
||||
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
import type { HTMLAttributes } from 'react'
|
||||
|
||||
import { Button } from 'payload/components'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import {
|
||||
Button,
|
||||
DrawerToggler,
|
||||
FileGraphic,
|
||||
useConfig,
|
||||
useDocumentDrawer,
|
||||
useDrawerSlug,
|
||||
useListDrawer,
|
||||
} from 'payload/components/elements'
|
||||
import { FileGraphic } from 'payload/components/graphics'
|
||||
import { usePayloadAPI, useThumbnail } from 'payload/components/hooks'
|
||||
import { useConfig } from 'payload/components/utilities'
|
||||
import { getTranslation } from 'payload/utilities'
|
||||
usePayloadAPI,
|
||||
useThumbnail,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import React, { useCallback, useReducer, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Transforms } from 'slate'
|
||||
import { ReactEditor, useFocused, useSelected, useSlateStatic } from 'slate-react'
|
||||
|
||||
@@ -54,7 +55,7 @@ const Element: React.FC<ElementProps> = (props) => {
|
||||
routes: { api },
|
||||
serverURL,
|
||||
} = useConfig()
|
||||
const { i18n, t } = useTranslation('fields')
|
||||
const { i18n, t } = useTranslation()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [relatedCollection, setRelatedCollection] = useState<SanitizedCollectionConfig>(() =>
|
||||
collections.find((coll) => coll.slug === relationTo),
|
||||
@@ -187,7 +188,7 @@ const Element: React.FC<ElementProps> = (props) => {
|
||||
// do nothing
|
||||
}}
|
||||
round
|
||||
tooltip={t('swapUpload')}
|
||||
tooltip={t('fields:swapUpload')}
|
||||
/>
|
||||
</ListDrawerToggler>
|
||||
<Button
|
||||
@@ -200,7 +201,7 @@ const Element: React.FC<ElementProps> = (props) => {
|
||||
removeUpload()
|
||||
}}
|
||||
round
|
||||
tooltip={t('removeUpload')}
|
||||
tooltip={t('fields:removeUpload')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,6 +135,7 @@ const clientTranslationKeys = [
|
||||
'fields:searchForBlock',
|
||||
'fields:selectFieldsToEdit',
|
||||
'fields:showAll',
|
||||
'fields:swapRelationship',
|
||||
'fields:uploadNewLabel',
|
||||
|
||||
'general:aboutToDeleteCount',
|
||||
|
||||
@@ -50,7 +50,11 @@ export const getTranslationString = ({
|
||||
return undefined
|
||||
}, translations)
|
||||
|
||||
return translation
|
||||
if (!translation) {
|
||||
console.log('key not found: ', key)
|
||||
}
|
||||
|
||||
return translation || key
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,14 +69,22 @@ const replaceVars = ({
|
||||
vars,
|
||||
}: {
|
||||
translationString: string
|
||||
vars: Record<string, string>
|
||||
}) => {
|
||||
return Object.keys(vars).reduce((acc, varKey) => {
|
||||
if (acc) {
|
||||
return acc.replace(`{{${varKey}}}`, vars[varKey])
|
||||
vars: {
|
||||
[key: string]: any
|
||||
}
|
||||
return acc
|
||||
}, translationString)
|
||||
}) => {
|
||||
const parts = translationString.split(/({{.*?}})/)
|
||||
|
||||
return parts
|
||||
.map((part) => {
|
||||
if (part.startsWith('{{') && part.endsWith('}}')) {
|
||||
const placeholder = part.substring(2, part.length - 2).trim()
|
||||
return vars[placeholder] || part
|
||||
} else {
|
||||
return part
|
||||
}
|
||||
})
|
||||
.join('')
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@ import { Button } from '../Button'
|
||||
import * as PopupList from '../Popup/PopupButtonList'
|
||||
import './index.scss'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Translation } from '../Translation'
|
||||
|
||||
const baseClass = 'delete-document'
|
||||
|
||||
@@ -112,18 +113,17 @@ const DeleteDocument: React.FC<Props> = (props) => {
|
||||
<MinimalTemplate className={`${baseClass}__template`}>
|
||||
<h1>{t('general:confirmDeletion')}</h1>
|
||||
<p>
|
||||
{t('general:aboutToDelete', {
|
||||
<Translation
|
||||
t={t}
|
||||
i18nKey="general:aboutToDelete"
|
||||
variables={{
|
||||
label: getTranslation(singularLabel, i18n),
|
||||
title: titleToRender,
|
||||
})}
|
||||
{/* <Trans
|
||||
i18nKey="aboutToDelete"
|
||||
t={t}
|
||||
values={{ label: getTranslation(singularLabel, i18n), title: titleToRender }}
|
||||
>
|
||||
aboutToDelete
|
||||
<strong>{titleToRender}</strong>
|
||||
</Trans> */}
|
||||
}}
|
||||
elements={{
|
||||
'1': ({ children }) => <strong children={children} />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<div className={`${baseClass}__actions`}>
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '../../providers/Translation'
|
||||
import { Button } from '../Button'
|
||||
|
||||
import './index.scss'
|
||||
@@ -22,7 +22,7 @@ export const Dropzone: React.FC<Props> = ({ onChange, className, mimeTypes }) =>
|
||||
const [dragging, setDragging] = React.useState(false)
|
||||
const inputRef = React.useRef(null)
|
||||
|
||||
const { t } = useTranslation(['upload', 'general'])
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handlePaste = React.useCallback(
|
||||
(e: ClipboardEvent) => {
|
||||
@@ -107,7 +107,7 @@ export const Dropzone: React.FC<Props> = ({ onChange, className, mimeTypes }) =>
|
||||
}}
|
||||
className={`${baseClass}__file-button`}
|
||||
>
|
||||
{t('selectFile')}
|
||||
{t('upload:selectFile')}
|
||||
</Button>
|
||||
|
||||
<input
|
||||
@@ -119,7 +119,7 @@ export const Dropzone: React.FC<Props> = ({ onChange, className, mimeTypes }) =>
|
||||
/>
|
||||
|
||||
<p className={`${baseClass}__label`}>
|
||||
{t('general:or')} {t('dragAndDrop')}
|
||||
{t('general:or')} {t('upload:dragAndDrop')}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '../../providers/Translation'
|
||||
import ReactCrop, { type Crop as CropType } from 'react-image-crop'
|
||||
import 'react-image-crop/dist/ReactCrop.css'
|
||||
|
||||
@@ -34,7 +34,7 @@ export const EditUpload: React.FC<{
|
||||
showFocalPoint?: boolean
|
||||
}> = ({ fileName, fileSrc, imageCacheTag, showCrop, showFocalPoint }) => {
|
||||
const { closeModal } = useModal()
|
||||
const { t } = useTranslation(['general', 'upload'])
|
||||
const { t } = useTranslation()
|
||||
const { formQueryParams, setFormQueryParams } = useFormQueryParams()
|
||||
const { uploadEdits } = formQueryParams || {}
|
||||
const [crop, setCrop] = useState<CropType>({
|
||||
@@ -117,7 +117,7 @@ export const EditUpload: React.FC<{
|
||||
</h2>
|
||||
<div className={`${baseClass}__actions`}>
|
||||
<Button
|
||||
aria-label={t('cancel')}
|
||||
aria-label={t('general:cancel')}
|
||||
buttonStyle="secondary"
|
||||
className={`${baseClass}__cancel`}
|
||||
onClick={() => closeModal(editDrawerSlug)}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { MinimalTemplate } from '../../templates/Minimal'
|
||||
import { useDocumentInfo } from '../../providers/DocumentInfo'
|
||||
import { Button } from '../Button'
|
||||
import './index.scss'
|
||||
import { Translation } from '../Translation'
|
||||
|
||||
const baseClass = 'generate-confirmation'
|
||||
|
||||
@@ -43,11 +44,13 @@ const GenerateConfirmation: React.FC<Props> = (props) => {
|
||||
<MinimalTemplate className={`${baseClass}__template`}>
|
||||
<h1>{t('authentication:confirmGeneration')}</h1>
|
||||
<p>
|
||||
<strong>{t('authentication:generatingNewAPIKeyWillInvalidate')}</strong>
|
||||
{/* <Trans i18nKey="generatingNewAPIKeyWillInvalidate" t={t}>
|
||||
generatingNewAPIKeyWillInvalidate
|
||||
<strong>invalidate</strong>
|
||||
</Trans> */}
|
||||
<Translation
|
||||
t={t}
|
||||
i18nKey="authentication:generatingNewAPIKeyWillInvalidate"
|
||||
elements={{
|
||||
1: ({ children }) => <strong children={children} />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Modal, useModal } from '@faceless-ui/modal'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '../../providers/Translation'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
import type { Props } from './types'
|
||||
@@ -22,14 +22,14 @@ const StayLoggedInModal: React.FC<Props> = (props) => {
|
||||
routes: { admin },
|
||||
} = config
|
||||
const { toggleModal } = useModal()
|
||||
const { t } = useTranslation('authentication')
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Modal className={baseClass} slug="stay-logged-in">
|
||||
<div className={`${baseClass}__wrapper`}>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<h1>{t('stayLoggedIn')}</h1>
|
||||
<p>{t('youAreInactive')}</p>
|
||||
<h1>{t('authentication:stayLoggedIn')}</h1>
|
||||
<p>{t('authentication:youAreInactive')}</p>
|
||||
</div>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<Button
|
||||
@@ -39,7 +39,7 @@ const StayLoggedInModal: React.FC<Props> = (props) => {
|
||||
history.push(`${admin}${logoutRoute}`)
|
||||
}}
|
||||
>
|
||||
{t('logOut')}
|
||||
{t('authentication:logOut')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
@@ -47,7 +47,7 @@ const StayLoggedInModal: React.FC<Props> = (props) => {
|
||||
toggleModal(modalSlug)
|
||||
}}
|
||||
>
|
||||
{t('stayLoggedIn')}
|
||||
{t('authentication:stayLoggedIn')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
44
packages/ui/src/elements/Translation/index.tsx
Normal file
44
packages/ui/src/elements/Translation/index.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import * as React from 'react'
|
||||
import { TFunction } from '@payloadcms/translations'
|
||||
|
||||
const RecursiveTranslation: React.FC<{
|
||||
translationString: string
|
||||
elements?: Record<string, React.FC<{ children: React.ReactNode }>>
|
||||
}> = ({ translationString, elements }) => {
|
||||
const regex = /(<[^>]+>.*?<\/[^>]+>)/g
|
||||
const sections = translationString.split(regex)
|
||||
|
||||
return (
|
||||
<span>
|
||||
{sections.map((section, index) => {
|
||||
const Element = elements?.[index.toString()]
|
||||
if (Element) {
|
||||
const regex = new RegExp(`<${index}>(.*?)<\/${index}>`, 'g')
|
||||
const children = section.replace(regex, (_, group) => group)
|
||||
return (
|
||||
<Element>
|
||||
<RecursiveTranslation translationString={children} />
|
||||
</Element>
|
||||
)
|
||||
}
|
||||
return section
|
||||
})}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
type TranslationProps = {
|
||||
i18nKey: string
|
||||
variables?: Record<string, unknown>
|
||||
elements?: Record<string, React.FC<{ children: React.ReactNode }>>
|
||||
t: TFunction
|
||||
}
|
||||
export const Translation: React.FC<TranslationProps> = ({ elements, variables, i18nKey, t }) => {
|
||||
let stringWithVariables = t(i18nKey, variables || {})
|
||||
|
||||
if (!elements) {
|
||||
return stringWithVariables
|
||||
}
|
||||
|
||||
return <RecursiveTranslation translationString={stringWithVariables} elements={elements} />
|
||||
}
|
||||
@@ -32,4 +32,6 @@ export { useListDrawer } from '../elements/ListDrawer'
|
||||
export { useDocumentDrawer } from '../elements/DocumentDrawer'
|
||||
export { ShimmerEffect } from '../elements/ShimmerEffect'
|
||||
export { useDrawerSlug } from '../elements/Drawer/useDrawerSlug'
|
||||
export { default as Popup } from '../elements/Popup'
|
||||
// export { useThumbnail } from '../elements/Upload'
|
||||
export { Translation } from '../elements/Translation'
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { SanitizedCollectionConfig, SanitizedGlobalConfig } from 'payload/t
|
||||
|
||||
import { useFormFields } from '../forms/Form/context'
|
||||
import { formatDocTitle } from '../utilities/formatDocTitle'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '../providers/Translation'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
|
||||
const useTitle = (args: {
|
||||
|
||||
@@ -11,15 +11,15 @@ export type LanguageOptions = {
|
||||
}[]
|
||||
|
||||
const Context = createContext<{
|
||||
t: (key: string, vars?: Record<string, string | number>) => string
|
||||
t: (key: string, vars?: Record<string, any>) => string
|
||||
i18n: I18n
|
||||
languageOptions: LanguageOptions
|
||||
}>({
|
||||
t: () => '',
|
||||
t: (key) => key,
|
||||
i18n: {
|
||||
language: 'en',
|
||||
fallbackLanguage: 'en',
|
||||
t: () => '',
|
||||
t: (key) => key,
|
||||
},
|
||||
languageOptions: undefined,
|
||||
})
|
||||
@@ -36,7 +36,7 @@ export const TranslationProvider: React.FC<{
|
||||
fallbackLang: ClientConfig['i18n']['fallbackLanguage']
|
||||
languageOptions: LanguageOptions
|
||||
}> = ({ children, translations, lang, fallbackLang, languageOptions }) => {
|
||||
const nextT = (key: string, vars?: Record<string, string | number>): string =>
|
||||
const nextT = (key: string, vars?: Record<string, any>): string =>
|
||||
t({
|
||||
key,
|
||||
vars,
|
||||
|
||||
@@ -13,7 +13,7 @@ jest.mock('../../../../utilities/Config', () => ({
|
||||
useConfig: () => ({ admin: { dateFormat: 'MMMM do yyyy, h:mm a' } }),
|
||||
}))
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
jest.mock('../../../../providers/Translation', () => ({
|
||||
useTranslation: () => ({ t: (string) => string }),
|
||||
}))
|
||||
|
||||
|
||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -1245,9 +1245,6 @@ importers:
|
||||
deep-equal:
|
||||
specifier: 2.2.3
|
||||
version: 2.2.3
|
||||
i18next:
|
||||
specifier: 22.5.1
|
||||
version: 22.5.1
|
||||
lexical:
|
||||
specifier: 0.12.5
|
||||
version: 0.12.5
|
||||
@@ -1263,9 +1260,6 @@ importers:
|
||||
react-error-boundary:
|
||||
specifier: ^4.0.11
|
||||
version: 4.0.11(react@18.2.0)
|
||||
react-i18next:
|
||||
specifier: 11.18.6
|
||||
version: 11.18.6(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
ts-essentials:
|
||||
specifier: 7.0.3
|
||||
version: 7.0.3(typescript@5.2.2)
|
||||
@@ -1288,18 +1282,18 @@ importers:
|
||||
'@faceless-ui/modal':
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1(react-dom@18.2.0)(react@18.2.0)
|
||||
i18next:
|
||||
specifier: 22.5.1
|
||||
version: 22.5.1
|
||||
'@payloadcms/translations':
|
||||
specifier: workspace:^
|
||||
version: link:../translations
|
||||
'@payloadcms/ui':
|
||||
specifier: workspace:^
|
||||
version: link:../ui
|
||||
is-hotkey:
|
||||
specifier: 0.2.0
|
||||
version: 0.2.0
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
react-i18next:
|
||||
specifier: 11.18.6
|
||||
version: 11.18.6(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
slate:
|
||||
specifier: 0.91.4
|
||||
version: 0.91.4
|
||||
|
||||
Reference in New Issue
Block a user