fix(ui): autosave in document drawer overwrites local changes (#13587)
Fixes #13574. When editing an autosave-enabled document within a document drawer, any changes made will while the autosave is processing are ultimately discarded from local form state. This makes is difficult or even impossible to edit fields. This is because we server-render, then replace, the entire document on every save. This includes form state, which is stale because it was rendered while new changes were still being made. We don't need to re-render the entire view on every save, though, only on create. We don't do this on the top-level edit view, for example. Instead, we only need to replace form state. This change is also a performance improvement because we are no longer rendering all components unnecessarily, especially on every autosave interval. Before: https://github.com/user-attachments/assets/e9c221bf-4800-4153-af55-8b82e93b3c26 After: https://github.com/user-attachments/assets/d77ef2f3-b98b-41d6-ba6c-b502b9bb99cc Note: ignore the flashing autosave status and doc controls. This is horrible and we're actively fixing it, but is outside the scope of this PR. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211139422639700
This commit is contained in:
@@ -70,17 +70,6 @@ export const AddNewRelation: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
if (isNewValue) {
|
||||
// dispatchOptions({
|
||||
// collection: collectionConfig,
|
||||
// // TODO: fix this
|
||||
// // @ts-expect-error-next-line
|
||||
// type: 'ADD',
|
||||
// config,
|
||||
// docs: [doc],
|
||||
// i18n,
|
||||
// sort: true,
|
||||
// })
|
||||
|
||||
if (hasMany === true) {
|
||||
onChange([
|
||||
...(Array.isArray(value) ? value : []),
|
||||
@@ -148,86 +137,89 @@ export const AddNewRelation: React.FC<Props> = ({
|
||||
label: getTranslation(relatedCollections[0]?.labels.singular, i18n),
|
||||
})
|
||||
|
||||
if (show) {
|
||||
return (
|
||||
<div className={baseClass} id={`${path}-add-new`}>
|
||||
{relatedCollections.length === 1 && (
|
||||
<Fragment>
|
||||
<DocumentDrawerToggler
|
||||
className={[
|
||||
`${baseClass}__add-button`,
|
||||
unstyled && `${baseClass}__add-button--unstyled`,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
onClick={() => setShowTooltip(false)}
|
||||
onMouseEnter={() => setShowTooltip(true)}
|
||||
onMouseLeave={() => setShowTooltip(false)}
|
||||
>
|
||||
{ButtonFromProps ? (
|
||||
if (!show) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={baseClass} id={`${path}-add-new`}>
|
||||
{relatedCollections.length === 1 && (
|
||||
<Fragment>
|
||||
<DocumentDrawerToggler
|
||||
className={[
|
||||
`${baseClass}__add-button`,
|
||||
unstyled && `${baseClass}__add-button--unstyled`,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
onClick={() => {
|
||||
setShowTooltip(false)
|
||||
}}
|
||||
onMouseEnter={() => setShowTooltip(true)}
|
||||
onMouseLeave={() => setShowTooltip(false)}
|
||||
>
|
||||
{ButtonFromProps ? (
|
||||
ButtonFromProps
|
||||
) : (
|
||||
<Fragment>
|
||||
<Tooltip className={`${baseClass}__tooltip`} show={showTooltip}>
|
||||
{label}
|
||||
</Tooltip>
|
||||
<PlusIcon />
|
||||
</Fragment>
|
||||
)}
|
||||
</DocumentDrawerToggler>
|
||||
<DocumentDrawer onSave={onSave} />
|
||||
</Fragment>
|
||||
)}
|
||||
{relatedCollections.length > 1 && (
|
||||
<Fragment>
|
||||
<Popup
|
||||
button={
|
||||
ButtonFromProps ? (
|
||||
ButtonFromProps
|
||||
) : (
|
||||
<Fragment>
|
||||
<Tooltip className={`${baseClass}__tooltip`} show={showTooltip}>
|
||||
{label}
|
||||
</Tooltip>
|
||||
<Button
|
||||
buttonStyle="none"
|
||||
className={`${baseClass}__add-button`}
|
||||
tooltip={popupOpen ? undefined : t('fields:addNew')}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Fragment>
|
||||
)}
|
||||
</DocumentDrawerToggler>
|
||||
<DocumentDrawer onSave={onSave} />
|
||||
</Fragment>
|
||||
)}
|
||||
{relatedCollections.length > 1 && (
|
||||
<Fragment>
|
||||
<Popup
|
||||
button={
|
||||
ButtonFromProps ? (
|
||||
ButtonFromProps
|
||||
) : (
|
||||
<Button
|
||||
buttonStyle="none"
|
||||
className={`${baseClass}__add-button`}
|
||||
tooltip={popupOpen ? undefined : t('fields:addNew')}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
buttonType="custom"
|
||||
horizontalAlign="center"
|
||||
onToggleOpen={onPopupToggle}
|
||||
render={({ close: closePopup }) => (
|
||||
<PopupList.ButtonGroup>
|
||||
{relatedCollections.map((relatedCollection) => {
|
||||
if (permissions.collections[relatedCollection?.slug].create) {
|
||||
return (
|
||||
<PopupList.Button
|
||||
className={`${baseClass}__relation-button--${relatedCollection?.slug}`}
|
||||
key={relatedCollection?.slug}
|
||||
onClick={() => {
|
||||
closePopup()
|
||||
setSelectedCollection(relatedCollection?.slug)
|
||||
}}
|
||||
>
|
||||
{getTranslation(relatedCollection?.labels?.singular, i18n)}
|
||||
</PopupList.Button>
|
||||
)
|
||||
}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
buttonType="custom"
|
||||
horizontalAlign="center"
|
||||
onToggleOpen={onPopupToggle}
|
||||
render={({ close: closePopup }) => (
|
||||
<PopupList.ButtonGroup>
|
||||
{relatedCollections.map((relatedCollection) => {
|
||||
if (permissions.collections[relatedCollection?.slug].create) {
|
||||
return (
|
||||
<PopupList.Button
|
||||
className={`${baseClass}__relation-button--${relatedCollection?.slug}`}
|
||||
key={relatedCollection?.slug}
|
||||
onClick={() => {
|
||||
closePopup()
|
||||
setSelectedCollection(relatedCollection?.slug)
|
||||
}}
|
||||
>
|
||||
{getTranslation(relatedCollection?.labels?.singular, i18n)}
|
||||
</PopupList.Button>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
})}
|
||||
</PopupList.ButtonGroup>
|
||||
)}
|
||||
size="medium"
|
||||
/>
|
||||
{collectionConfig && permissions.collections[collectionConfig?.slug]?.create && (
|
||||
<DocumentDrawer onSave={onSave} />
|
||||
return null
|
||||
})}
|
||||
</PopupList.ButtonGroup>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
size="medium"
|
||||
/>
|
||||
{collectionConfig && permissions.collections[collectionConfig?.slug]?.create && (
|
||||
<DocumentDrawer onSave={onSave} />
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { abortAndIgnore, handleAbortRef } from '../../utilities/abortAndIgnore.j
|
||||
import { DocumentDrawerContextProvider } from './Provider.js'
|
||||
|
||||
export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
id: existingDocID,
|
||||
id: docID,
|
||||
collectionSlug,
|
||||
disableActions,
|
||||
drawerSlug,
|
||||
@@ -43,10 +43,11 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
|
||||
const [DocumentView, setDocumentView] = useState<React.ReactNode>(undefined)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const hasInitialized = useRef(false)
|
||||
|
||||
const getDocumentView = useCallback(
|
||||
(docID?: number | string, showLoadingIndicator: boolean = false) => {
|
||||
(docID?: DocumentDrawerProps['id'], showLoadingIndicator: boolean = false) => {
|
||||
const controller = handleAbortRef(abortGetDocumentViewRef)
|
||||
|
||||
const fetchDocumentView = async () => {
|
||||
@@ -78,7 +79,6 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
} catch (error) {
|
||||
toast.error(error?.message || t('error:unspecific'))
|
||||
closeModal(drawerSlug)
|
||||
// toast.error(data?.errors?.[0].message || t('error:unspecific'))
|
||||
}
|
||||
|
||||
abortGetDocumentViewRef.current = null
|
||||
@@ -105,7 +105,9 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
|
||||
const onSave = useCallback<DocumentDrawerProps['onSave']>(
|
||||
(args) => {
|
||||
getDocumentView(args.doc.id)
|
||||
if (args.operation === 'create') {
|
||||
getDocumentView(args.doc.id)
|
||||
}
|
||||
|
||||
if (typeof onSaveFromProps === 'function') {
|
||||
void onSaveFromProps({
|
||||
@@ -151,10 +153,10 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (!DocumentView && !hasInitialized.current) {
|
||||
getDocumentView(existingDocID, true)
|
||||
getDocumentView(docID, true)
|
||||
hasInitialized.current = true
|
||||
}
|
||||
}, [DocumentView, getDocumentView, existingDocID])
|
||||
}, [DocumentView, getDocumentView, docID])
|
||||
|
||||
// Cleanup any pending requests when the component unmounts
|
||||
useEffect(() => {
|
||||
|
||||
@@ -26,8 +26,8 @@ const formatDocumentDrawerSlug = ({
|
||||
}: {
|
||||
collectionSlug: string
|
||||
depth: number
|
||||
id: number | string
|
||||
uuid: string // supply when creating a new document and no id is available
|
||||
id?: number | string
|
||||
uuid: string
|
||||
}) => `doc-drawer_${collectionSlug}_${depth}${id ? `_${id}` : ''}_${uuid}`
|
||||
|
||||
export const DocumentDrawerToggler: React.FC<DocumentTogglerProps> = ({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Data, FormState, Operation } from 'payload'
|
||||
import type { Data, DefaultDocumentIDType, FormState, Operation } from 'payload'
|
||||
import type React from 'react'
|
||||
import type { HTMLAttributes } from 'react'
|
||||
|
||||
@@ -7,10 +7,18 @@ import type { DocumentDrawerContextProps } from './Provider.js'
|
||||
|
||||
export type DocumentDrawerProps = {
|
||||
readonly AfterFields?: React.ReactNode
|
||||
/**
|
||||
* The slug of the collection to which the document belongs.
|
||||
*/
|
||||
readonly collectionSlug: string
|
||||
readonly disableActions?: boolean
|
||||
readonly drawerSlug?: string
|
||||
readonly id?: null | number | string
|
||||
/**
|
||||
* The ID of the document to be edited.
|
||||
* When provided, will be fetched and displayed in the drawer.
|
||||
* If omitted, will render the "create new" view for the given collection.
|
||||
*/
|
||||
readonly id?: DefaultDocumentIDType | null
|
||||
readonly initialData?: Data
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -43,19 +51,9 @@ export type UseDocumentDrawerContext = {
|
||||
toggleDrawer: () => void
|
||||
}
|
||||
|
||||
export type UseDocumentDrawer = (args: {
|
||||
/**
|
||||
* The slug of the collection to which the document belongs.
|
||||
*/
|
||||
collectionSlug: string
|
||||
/**
|
||||
* The ID of the document to be edited.
|
||||
* When provided, will be fetched and displayed in the drawer.
|
||||
* If omitted, will render the "create new" view for the given collection.
|
||||
*/
|
||||
id?: number | string
|
||||
overrideEntityVisibility?: boolean
|
||||
}) => [
|
||||
export type UseDocumentDrawer = (
|
||||
args: Pick<DocumentDrawerProps, 'collectionSlug' | 'id' | 'overrideEntityVisibility'>,
|
||||
) => [
|
||||
// drawer
|
||||
React.FC<
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable react-compiler/react-compiler -- TODO: fix */
|
||||
'use client'
|
||||
|
||||
import type { ClientUser, DocumentViewClientProps, FormState } from 'payload'
|
||||
import type { ClientUser, DocumentViewClientProps } from 'payload'
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation.js'
|
||||
import { formatAdminURL } from 'payload/shared'
|
||||
|
||||
@@ -568,7 +568,9 @@ describe('Relationship Field', () => {
|
||||
).toHaveCount(1)
|
||||
await drawerField.fill('Updated document')
|
||||
await saveButton.click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('Updated successfully')
|
||||
await expect(page.locator('.payload-toast-container').first()).toContainText(
|
||||
'Updated successfully',
|
||||
)
|
||||
await page.locator('.doc-drawer__header-close').click()
|
||||
await expect(
|
||||
page.locator('#field-relationshipHasMany .value-container .rs__multi-value'),
|
||||
|
||||
@@ -387,6 +387,13 @@ export interface User {
|
||||
hash?: string | null;
|
||||
loginAttempts?: number | null;
|
||||
lockUntil?: string | null;
|
||||
sessions?:
|
||||
| {
|
||||
id: string;
|
||||
createdAt?: string | null;
|
||||
expiresAt: string;
|
||||
}[]
|
||||
| null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
@@ -661,6 +668,13 @@ export interface UsersSelect<T extends boolean = true> {
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
sessions?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
createdAt?: T;
|
||||
expiresAt?: T;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import type { BrowserContext, Dialog, Page } from '@playwright/test'
|
||||
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { postsCollectionSlug } from 'admin/slugs.js'
|
||||
import path from 'path'
|
||||
import { wait } from 'payload/shared'
|
||||
import { fileURLToPath } from 'url'
|
||||
@@ -37,6 +38,7 @@ import {
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
initPageConsoleErrorCatch,
|
||||
openDocDrawer,
|
||||
saveDocAndAssert,
|
||||
// throttleTest,
|
||||
} from '../helpers.js'
|
||||
@@ -1315,6 +1317,42 @@ describe('Versions', () => {
|
||||
await expect(computedTitleField).toHaveValue('Initial')
|
||||
})
|
||||
|
||||
test('- with autosave - does not override local changes to form state after autosave runs within document drawer', async () => {
|
||||
await payload.create({
|
||||
collection: autosaveCollectionSlug,
|
||||
data: {
|
||||
title: 'This is a test',
|
||||
description: 'some description',
|
||||
},
|
||||
})
|
||||
|
||||
const url = new AdminUrlUtil(serverURL, postsCollectionSlug)
|
||||
await page.goto(url.create)
|
||||
|
||||
await page.locator('#field-relationToAutosaves .rs__control').click()
|
||||
await page.locator('.rs__option:has-text("This is a test")').click()
|
||||
|
||||
await openDocDrawer(
|
||||
page,
|
||||
'#field-relationToAutosaves .relationship--single-value__drawer-toggler',
|
||||
)
|
||||
|
||||
const titleField = page.locator('#field-title')
|
||||
|
||||
await titleField.fill('')
|
||||
|
||||
// press slower than the autosave interval, but not faster than the response and processing
|
||||
await titleField.pressSequentially('Initial', {
|
||||
delay: 150,
|
||||
})
|
||||
|
||||
const drawer = page.locator('[id^=doc-drawer_autosave-posts_1_]')
|
||||
|
||||
await waitForAutoSaveToRunAndComplete(drawer)
|
||||
|
||||
await expect(titleField).toHaveValue('Initial')
|
||||
})
|
||||
|
||||
test('- with autosave - does not display success toast after autosave complete', async () => {
|
||||
const url = new AdminUrlUtil(serverURL, autosaveCollectionSlug)
|
||||
await page.goto(url.create)
|
||||
|
||||
@@ -71,8 +71,8 @@ export interface Config {
|
||||
posts: Post;
|
||||
'autosave-posts': AutosavePost;
|
||||
'autosave-with-draft-button-posts': AutosaveWithDraftButtonPost;
|
||||
'autosave-with-validate-posts': AutosaveWithValidatePost;
|
||||
'autosave-multi-select-posts': AutosaveMultiSelectPost;
|
||||
'autosave-with-validate-posts': AutosaveWithValidatePost;
|
||||
'draft-posts': DraftPost;
|
||||
'draft-with-max-posts': DraftWithMaxPost;
|
||||
'draft-with-validate-posts': DraftWithValidatePost;
|
||||
@@ -96,8 +96,8 @@ export interface Config {
|
||||
posts: PostsSelect<false> | PostsSelect<true>;
|
||||
'autosave-posts': AutosavePostsSelect<false> | AutosavePostsSelect<true>;
|
||||
'autosave-with-draft-button-posts': AutosaveWithDraftButtonPostsSelect<false> | AutosaveWithDraftButtonPostsSelect<true>;
|
||||
'autosave-with-validate-posts': AutosaveWithValidatePostsSelect<false> | AutosaveWithValidatePostsSelect<true>;
|
||||
'autosave-multi-select-posts': AutosaveMultiSelectPostsSelect<false> | AutosaveMultiSelectPostsSelect<true>;
|
||||
'autosave-with-validate-posts': AutosaveWithValidatePostsSelect<false> | AutosaveWithValidatePostsSelect<true>;
|
||||
'draft-posts': DraftPostsSelect<false> | DraftPostsSelect<true>;
|
||||
'draft-with-max-posts': DraftWithMaxPostsSelect<false> | DraftWithMaxPostsSelect<true>;
|
||||
'draft-with-validate-posts': DraftWithValidatePostsSelect<false> | DraftWithValidatePostsSelect<true>;
|
||||
@@ -282,17 +282,6 @@ export interface AutosaveWithDraftButtonPost {
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-with-validate-posts".
|
||||
*/
|
||||
export interface AutosaveWithValidatePost {
|
||||
id: string;
|
||||
title: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-multi-select-posts".
|
||||
@@ -305,6 +294,17 @@ export interface AutosaveMultiSelectPost {
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-with-validate-posts".
|
||||
*/
|
||||
export interface AutosaveWithValidatePost {
|
||||
id: string;
|
||||
title: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "draft-with-max-posts".
|
||||
@@ -411,6 +411,7 @@ export interface Diff {
|
||||
textInNamedTab1InBlock?: string | null;
|
||||
};
|
||||
textInUnnamedTab2InBlock?: string | null;
|
||||
textInRowInUnnamedTab2InBlock?: string | null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'TabsBlock';
|
||||
@@ -705,14 +706,14 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'autosave-with-draft-button-posts';
|
||||
value: string | AutosaveWithDraftButtonPost;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'autosave-with-validate-posts';
|
||||
value: string | AutosaveWithValidatePost;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'autosave-multi-select-posts';
|
||||
value: string | AutosaveMultiSelectPost;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'autosave-with-validate-posts';
|
||||
value: string | AutosaveWithValidatePost;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'draft-posts';
|
||||
value: string | DraftPost;
|
||||
@@ -860,21 +861,21 @@ export interface AutosaveWithDraftButtonPostsSelect<T extends boolean = true> {
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-with-validate-posts_select".
|
||||
* via the `definition` "autosave-multi-select-posts_select".
|
||||
*/
|
||||
export interface AutosaveWithValidatePostsSelect<T extends boolean = true> {
|
||||
export interface AutosaveMultiSelectPostsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
tag?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
_status?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-multi-select-posts_select".
|
||||
* via the `definition` "autosave-with-validate-posts_select".
|
||||
*/
|
||||
export interface AutosaveMultiSelectPostsSelect<T extends boolean = true> {
|
||||
export interface AutosaveWithValidatePostsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
tag?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
_status?: T;
|
||||
@@ -1027,6 +1028,7 @@ export interface DiffSelect<T extends boolean = true> {
|
||||
textInNamedTab1InBlock?: T;
|
||||
};
|
||||
textInUnnamedTab2InBlock?: T;
|
||||
textInRowInUnnamedTab2InBlock?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
@@ -1384,6 +1386,6 @@ export interface Auth {
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
}
|
||||
@@ -21,15 +21,8 @@
|
||||
"skipLibCheck": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"sourceMap": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"ES2022"
|
||||
],
|
||||
"types": [
|
||||
"node",
|
||||
"jest"
|
||||
],
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
||||
"types": ["node", "jest"],
|
||||
"incremental": true,
|
||||
"isolatedModules": true,
|
||||
"plugins": [
|
||||
@@ -38,72 +31,36 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@payload-config": [
|
||||
"./test/form-state/config.ts"
|
||||
],
|
||||
"@payloadcms/admin-bar": [
|
||||
"./packages/admin-bar/src"
|
||||
],
|
||||
"@payloadcms/live-preview": [
|
||||
"./packages/live-preview/src"
|
||||
],
|
||||
"@payloadcms/live-preview-react": [
|
||||
"./packages/live-preview-react/src/index.ts"
|
||||
],
|
||||
"@payloadcms/live-preview-vue": [
|
||||
"./packages/live-preview-vue/src/index.ts"
|
||||
],
|
||||
"@payloadcms/ui": [
|
||||
"./packages/ui/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/shared": [
|
||||
"./packages/ui/src/exports/shared/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/rsc": [
|
||||
"./packages/ui/src/exports/rsc/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/scss": [
|
||||
"./packages/ui/src/scss.scss"
|
||||
],
|
||||
"@payloadcms/ui/scss/app.scss": [
|
||||
"./packages/ui/src/scss/app.scss"
|
||||
],
|
||||
"@payloadcms/next/*": [
|
||||
"./packages/next/src/exports/*.ts"
|
||||
],
|
||||
"@payload-config": ["./test/_community/config.ts"],
|
||||
"@payloadcms/admin-bar": ["./packages/admin-bar/src"],
|
||||
"@payloadcms/live-preview": ["./packages/live-preview/src"],
|
||||
"@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],
|
||||
"@payloadcms/live-preview-vue": ["./packages/live-preview-vue/src/index.ts"],
|
||||
"@payloadcms/ui": ["./packages/ui/src/exports/client/index.ts"],
|
||||
"@payloadcms/ui/shared": ["./packages/ui/src/exports/shared/index.ts"],
|
||||
"@payloadcms/ui/rsc": ["./packages/ui/src/exports/rsc/index.ts"],
|
||||
"@payloadcms/ui/scss": ["./packages/ui/src/scss.scss"],
|
||||
"@payloadcms/ui/scss/app.scss": ["./packages/ui/src/scss/app.scss"],
|
||||
"@payloadcms/next/*": ["./packages/next/src/exports/*.ts"],
|
||||
"@payloadcms/richtext-lexical/client": [
|
||||
"./packages/richtext-lexical/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/richtext-lexical/rsc": [
|
||||
"./packages/richtext-lexical/src/exports/server/rsc.ts"
|
||||
],
|
||||
"@payloadcms/richtext-slate/rsc": [
|
||||
"./packages/richtext-slate/src/exports/server/rsc.ts"
|
||||
],
|
||||
"@payloadcms/richtext-lexical/rsc": ["./packages/richtext-lexical/src/exports/server/rsc.ts"],
|
||||
"@payloadcms/richtext-slate/rsc": ["./packages/richtext-slate/src/exports/server/rsc.ts"],
|
||||
"@payloadcms/richtext-slate/client": [
|
||||
"./packages/richtext-slate/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-seo/client": [
|
||||
"./packages/plugin-seo/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-sentry/client": [
|
||||
"./packages/plugin-sentry/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-stripe/client": [
|
||||
"./packages/plugin-stripe/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-search/client": [
|
||||
"./packages/plugin-search/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-seo/client": ["./packages/plugin-seo/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-sentry/client": ["./packages/plugin-sentry/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-stripe/client": ["./packages/plugin-stripe/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-search/client": ["./packages/plugin-search/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-form-builder/client": [
|
||||
"./packages/plugin-form-builder/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-import-export/rsc": [
|
||||
"./packages/plugin-import-export/src/exports/rsc.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/rsc": [
|
||||
"./packages/plugin-multi-tenant/src/exports/rsc.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/rsc": ["./packages/plugin-multi-tenant/src/exports/rsc.ts"],
|
||||
"@payloadcms/plugin-multi-tenant/utilities": [
|
||||
"./packages/plugin-multi-tenant/src/exports/utilities.ts"
|
||||
],
|
||||
@@ -113,42 +70,25 @@
|
||||
"@payloadcms/plugin-multi-tenant/client": [
|
||||
"./packages/plugin-multi-tenant/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant": [
|
||||
"./packages/plugin-multi-tenant/src/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant": ["./packages/plugin-multi-tenant/src/index.ts"],
|
||||
"@payloadcms/plugin-multi-tenant/translations/languages/all": [
|
||||
"./packages/plugin-multi-tenant/src/translations/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/translations/languages/*": [
|
||||
"./packages/plugin-multi-tenant/src/translations/languages/*.ts"
|
||||
],
|
||||
"@payloadcms/next": [
|
||||
"./packages/next/src/exports/*"
|
||||
],
|
||||
"@payloadcms/storage-azure/client": [
|
||||
"./packages/storage-azure/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-s3/client": [
|
||||
"./packages/storage-s3/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/next": ["./packages/next/src/exports/*"],
|
||||
"@payloadcms/storage-azure/client": ["./packages/storage-azure/src/exports/client.ts"],
|
||||
"@payloadcms/storage-s3/client": ["./packages/storage-s3/src/exports/client.ts"],
|
||||
"@payloadcms/storage-vercel-blob/client": [
|
||||
"./packages/storage-vercel-blob/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-gcs/client": [
|
||||
"./packages/storage-gcs/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-gcs/client": ["./packages/storage-gcs/src/exports/client.ts"],
|
||||
"@payloadcms/storage-uploadthing/client": [
|
||||
"./packages/storage-uploadthing/src/exports/client.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"${configDir}/src"
|
||||
],
|
||||
"exclude": [
|
||||
"${configDir}/dist",
|
||||
"${configDir}/build",
|
||||
"${configDir}/temp",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
"include": ["${configDir}/src"],
|
||||
"exclude": ["${configDir}/dist", "${configDir}/build", "${configDir}/temp", "**/*.spec.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user