chore: thread missing Link components to Button

This commit is contained in:
Jarrod Flesch
2024-03-05 15:17:27 -05:00
parent c2509b462c
commit 0d0e9bc953
19 changed files with 104 additions and 120 deletions

View File

@@ -1,5 +1,4 @@
export { AdminLayout } from './layouts/Admin'
export { DocumentLayout } from './layouts/Document'
export { RootLayout } from './layouts/Root'
export { Dashboard as DashboardPage } from './views/Dashboard'
export { Login } from './views/Login'

View File

@@ -1,42 +0,0 @@
import type { SanitizedConfig } from 'payload/types'
import { DocumentHeader } from '@payloadcms/ui'
import '@payloadcms/ui/scss/app.scss'
import React, { Fragment } from 'react'
import { initPage } from '../../utilities/initPage'
export const metadata = {
description: 'Generated by Next.js',
title: 'Next.js',
}
export const DocumentLayout = async ({
children,
collectionSlug,
config: configPromise,
globalSlug,
}: {
children: React.ReactNode
collectionSlug?: string
config: Promise<SanitizedConfig>
globalSlug?: string
}) => {
const { collectionConfig, globalConfig, req } = await initPage({
collectionSlug,
config: configPromise,
globalSlug,
})
return (
<Fragment>
<DocumentHeader
collectionConfig={collectionConfig}
config={req.payload.config}
globalConfig={globalConfig}
i18n={req.i18n}
/>
{children}
</Fragment>
)
}

View File

@@ -9,7 +9,6 @@ import type { CollectionRouteHandler } from '../types'
export const find: CollectionRouteHandler = async ({ collection, req }) => {
const { searchParams } = req
// parse using `qs` to handle `where` queries
const { depth, draft, limit, page, sort, where } = qs.parse(searchParams.toString()) as {
depth?: string

View File

@@ -19,10 +19,7 @@ import { auth } from './auth'
import { getRequestLanguage } from './getRequestLanguage'
type Args = {
collectionSlug?: string
config: Promise<SanitizedConfig> | SanitizedConfig
globalSlug?: string
localeParam?: string
redirectUnauthenticatedUser?: boolean
route?: string
searchParams?: { [key: string]: string | string[] | undefined }
@@ -30,13 +27,12 @@ type Args = {
export const initPage = async ({
config: configPromise,
localeParam,
redirectUnauthenticatedUser = false,
route,
searchParams,
}: Args): Promise<InitPageResult> => {
const headers = getHeaders()
const localeParam = searchParams?.locale as string
const { cookies, permissions, user } = await auth({
config: configPromise,
headers,

View File

@@ -14,9 +14,9 @@ const chars = {
const baseClass = 'query-inspector'
const Bracket = ({
type,
comma = false,
position,
type,
}: {
comma?: boolean
position: 'end' | 'start'
@@ -49,7 +49,7 @@ export const RenderJSON = ({
parentType = 'object',
trailingComma = false,
}: Args) => {
const objectKeys = Object.keys(object)
const objectKeys = object ? Object.keys(object) : []
const objectLength = objectKeys.length
const [isOpen, setIsOpen] = React.useState<boolean>(true)

View File

@@ -24,8 +24,9 @@ import queryString from 'qs'
import React, { Fragment } from 'react'
import type { AdminViewProps } from '../Root'
import type { GenerateEditViewMetadata } from './getMetaBySegment'
import { GenerateEditViewMetadata, getMetaBySegment } from './getMetaBySegment'
import { getMetaBySegment } from './getMetaBySegment'
import { getViewsFromConfig } from './getViewsFromConfig'
export const generateMetadata: GenerateEditViewMetadata = async (args) => getMetaBySegment(args)
@@ -178,6 +179,7 @@ export const Document: React.FC<AdminViewProps> = async ({
locale: locale.code,
uploadEdits: undefined,
}
console.log('server code', `${action}?${queryString.stringify(formQueryParams)}`)
const componentProps: ServerSideEditViewProps = {
id,
@@ -208,7 +210,7 @@ export const Document: React.FC<AdminViewProps> = async ({
/>
<HydrateClientUser permissions={permissions} user={user} />
<SetDocumentInfo
action={action}
action={`${action}?${queryString.stringify(formQueryParams)}`}
apiURL={apiURL}
collectionSlug={collectionConfig?.slug}
disableActions={false}

View File

@@ -48,7 +48,7 @@ export const ForgotPassword: React.FC<AdminViewProps> = ({ initPageResult }) =>
/>
</p>
<br />
<Button buttonStyle="secondary" el="link" to={admin}>
<Button Link={Link} buttonStyle="secondary" el="link" to={admin}>
{i18n.t('general:backToDashboard')}
</Button>
</Fragment>

View File

@@ -25,6 +25,7 @@ import {
SetViewActions,
UnpublishMany,
} from '@payloadcms/ui/elements'
import Link from 'next/link'
import { formatFilesize } from 'payload/utilities'
import React, { Fragment, useEffect } from 'react'
@@ -156,7 +157,7 @@ export const DefaultListView: React.FC = () => {
<div className={`${baseClass}__no-results`}>
<p>{i18n.t('general:noResults', { label: getTranslation(labels?.plural, i18n) })}</p>
{hasCreatePermission && newDocumentURL && (
<Button el="link" to={newDocumentURL}>
<Button Link={Link} el="link" to={newDocumentURL}>
{i18n.t('general:createNewLabel', {
label: getTranslation(labels?.singular, i18n),
})}

View File

@@ -1,5 +1,6 @@
'use client'
import { Button, Gutter, useConfig, useStepNav, useTranslation } from '@payloadcms/ui'
import Link from 'next/link'
import React from 'react'
// import Meta from '../../utilities/Meta'
@@ -41,7 +42,7 @@ const NotFound: React.FC<{
<Gutter className={`${baseClass}__wrap`}>
<h1>{t('general:nothingFound')}</h1>
<p>{t('general:sorryNotFound')}</p>
<Button className={`${baseClass}__button`} el="link" to={`${admin}`}>
<Button Link={Link} className={`${baseClass}__button`} el="link" to={`${admin}`}>
{t('general:backToDashboard')}
</Button>
</Gutter>

View File

@@ -61,7 +61,7 @@ export const ResetPassword: React.FC<AdminViewProps> = ({ initPageResult, params
/>
</p>
<br />
<Button buttonStyle="secondary" el="link" to={admin}>
<Button Link={Link} buttonStyle="secondary" el="link" to={admin}>
{i18n.t('general:backToDashboard')}
</Button>
</div>

View File

@@ -1,5 +1,6 @@
'use client'
import { Button, useTranslation } from '@payloadcms/ui'
import Link from 'next/link'
import React from 'react'
export const UnauthorizedClient: React.FC<{ logoutRoute: string }> = ({ logoutRoute }) => {
@@ -10,7 +11,7 @@ export const UnauthorizedClient: React.FC<{ logoutRoute: string }> = ({ logoutRo
<h2>{t('error:unauthorized')}</h2>
<p>{t('error:notAllowedToAccessPage')}</p>
<br />
<Button el="link" to={logoutRoute}>
<Button Link={Link} el="link" to={logoutRoute}>
{t('authentication:logOut')}
</Button>
</React.Fragment>

View File

@@ -49,6 +49,7 @@ export const ButtonContents = ({ children, icon, showTooltip, tooltip }) => {
export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((props, ref) => {
const {
id,
type = 'button',
Link,
'aria-label': ariaLabel,
buttonStyle = 'primary',
@@ -65,7 +66,6 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
size = 'medium',
to,
tooltip,
type = 'button',
url,
} = props
@@ -95,6 +95,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
const buttonProps = {
id,
type,
'aria-disabled': disabled,
'aria-label': ariaLabel,
className: classes,
@@ -104,13 +105,12 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
onMouseLeave: tooltip ? () => setShowTooltip(false) : undefined,
rel: newTab ? 'noopener noreferrer' : undefined,
target: newTab ? '_blank' : undefined,
type,
}
switch (el) {
case 'link':
if (!Link) {
console.error('Link is required when using el="link"')
console.error('Link is required when using el="link"', children)
return null
}

View File

@@ -1,5 +1,5 @@
import { getTranslation } from '@payloadcms/translations'
import qs from 'qs'
import { useRouter } from 'next/navigation'
import React from 'react'
import { useConfig } from '../../providers/Config'
@@ -23,9 +23,7 @@ const Localizer: React.FC<{
const { i18n } = useTranslation()
const locale = useLocale()
const { searchParams } = useSearchParams()
const localeLabel = getTranslation(locale.label, i18n)
const router = useRouter()
if (localization) {
const { locales } = localization
@@ -36,42 +34,28 @@ const Localizer: React.FC<{
horizontalAlign="right"
render={({ close }) => (
<PopupList.ButtonGroup>
<React.Fragment>
{locale ? (
<PopupList.Button
active
href={{
search: qs.stringify({
...searchParams,
locale: locale.code,
}),
}}
key={locale.code}
onClick={close}
>
{localeLabel}
{localeLabel !== locale.code && ` (${locale.code})`}
</PopupList.Button>
) : null}
{locales.map((localeOption) => {
if (locale.code === localeOption.code) return null
const newParams = {
...searchParams,
locale: localeOption.code,
}
const search = qs.stringify(newParams)
const localeOptionLabel = getTranslation(localeOption.label, i18n)
return (
<PopupList.Button href={{ search }} key={localeOption.code} onClick={close}>
<PopupList.Button
active={locale.code === localeOption.code}
href={{ query: newParams }}
key={localeOption.code}
onClick={() => {
close()
router.refresh()
}}
>
{localeOptionLabel}
{localeOptionLabel !== localeOption.code && ` (${localeOption.code})`}
</PopupList.Button>
)
})}
</React.Fragment>
</PopupList.ButtonGroup>
)}
showScrollbar

View File

@@ -19,6 +19,7 @@ export { EditDepthContext, EditDepthProvider } from '../providers/EditDepth'
export { useEditDepth } from '../providers/EditDepth'
export { FormQueryParams, FormQueryParamsProvider } from '../providers/FormQueryParams'
export type { QueryParamTypes } from '../providers/FormQueryParams'
export { useFormQueryParams } from '../providers/FormQueryParams'
export { useListInfo } from '../providers/ListInfo'
export { ListInfoProvider } from '../providers/ListInfo'
export type { ColumnPreferences } from '../providers/ListInfo/types'

View File

@@ -11,7 +11,7 @@ export const mergeServerFormState = (
let changed = false
Object.entries(newState).forEach(([path, newFieldState]) => {
newFieldState.initialValue = oldState[path].initialValue
newFieldState.initialValue = oldState[path]?.initialValue
newFieldState.value = oldState[path].value
const oldErrorPaths: string[] = []

View File

@@ -26,7 +26,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const [tokenInMemory, setTokenInMemory] = useState<string>()
const [tokenExpiration, setTokenExpiration] = useState<number>()
const pathname = usePathname()
const { push } = useRouter()
const router = useRouter()
// const { code } = useLocale()
const code = 'en' // TODO: re-enable i18n asap
@@ -52,12 +52,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const redirectParam = `?redirect=${encodeURIComponent(
window.location.pathname.replace(admin, ''),
)}`
push(`${admin}${logoutInactivityRoute}${redirectParam}`)
router.replace(`${admin}${logoutInactivityRoute}${redirectParam}`)
} else {
push(`${admin}${logoutInactivityRoute}`)
router.replace(`${admin}${logoutInactivityRoute}`)
}
closeAllModals()
}, [push, admin, logoutInactivityRoute, closeAllModals])
}, [router, admin, logoutInactivityRoute, closeAllModals])
const revokeTokenAndExpire = useCallback(() => {
setTokenInMemory(undefined)
@@ -212,7 +212,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
if (autoLoginJson?.token) {
setTokenAndExpiration(autoLoginJson)
}
push(typeof searchParams['redirect'] === 'string' ? searchParams['redirect'] : admin)
router.push(
typeof searchParams['redirect'] === 'string' ? searchParams['redirect'] : admin,
)
} else {
setUser(null)
revokeTokenAndExpire()
@@ -232,7 +234,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
i18n.language,
autoLogin,
setTokenAndExpiration,
push,
router,
searchParams,
admin,
revokeTokenAndExpire,

View File

@@ -2,6 +2,8 @@
import type { Locale } from 'payload/config'
// TODO: abstract the `next/navigation` dependency out from this component
import { useRouter } from 'next/navigation'
import React, { createContext, useContext, useEffect, useState } from 'react'
import { findLocaleFromCode } from '../../utilities/findLocaleFromCode'
@@ -20,7 +22,8 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
const defaultLocale =
localization && localization.defaultLocale ? localization.defaultLocale : 'en'
const { searchParams } = useSearchParams()
const { dispatchSearchParams, searchParams } = useSearchParams()
const router = useRouter()
const [localeCode, setLocaleCode] = useState<string>(
(searchParams?.locale as string) || defaultLocale,
@@ -35,6 +38,7 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
const localeFromParams = searchParams.locale
useEffect(() => {
async function localeChangeHandler() {
if (!localization) {
return
}
@@ -43,12 +47,11 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
if (localeFromParams && localization.localeCodes.indexOf(localeFromParams as string) > -1) {
setLocaleCode(localeFromParams as string)
setLocale(findLocaleFromCode(localization, localeFromParams as string))
if (user) setPreference('locale', localeFromParams)
if (user) await setPreference('locale', localeFromParams)
return
}
// set locale from preferences or default
;(async () => {
let preferenceLocale: string
let isPreferenceInConfig: boolean
if (user) {
@@ -60,12 +63,25 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
setLocale(findLocaleFromCode(localization, preferenceLocale))
return
}
setPreference('locale', defaultLocale)
await setPreference('locale', defaultLocale)
}
setLocaleCode(defaultLocale)
setLocale(findLocaleFromCode(localization, defaultLocale))
})()
}, [defaultLocale, getPreference, localeFromParams, setPreference, user, localization])
}
void localeChangeHandler()
}, [defaultLocale, getPreference, localeFromParams, setPreference, user, localization, router])
useEffect(() => {
if (searchParams?.locale) {
dispatchSearchParams({
type: 'set',
params: {
locale: searchParams.locale,
},
})
}
}, [searchParams.locale, dispatchSearchParams])
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
}

View File

@@ -24,6 +24,7 @@ export const SearchParamsProvider: React.FC<{ children?: React.ReactNode }> = ({
const [searchParams, dispatchSearchParams] = React.useReducer((state: State, action: Action) => {
const stackAction = action.browserHistory || 'push'
let paramsToSet
switch (action.type) {
case 'set':
paramsToSet = {

View File

@@ -13,7 +13,30 @@ export default buildConfigWithDefaults({
PostsCollection,
MediaCollection,
// ...add more collections here
{
slug: 'localized',
fields: [
{
name: 'text',
type: 'text',
localized: true,
},
],
},
],
localization: {
defaultLocale: 'en',
locales: [
{
code: 'en',
label: 'English',
},
{
code: 'es',
label: 'Spanish',
},
],
},
globals: [
MenuGlobal,
// ...add more globals here