Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(next): autosave document rendering #9364

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 27 additions & 19 deletions packages/next/src/views/Document/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const renderDocument = async ({
}> => {
const {
collectionConfig,
docID: id,
docID: idFromArgs,
globalConfig,
locale,
permissions,
Expand All @@ -72,7 +72,7 @@ export const renderDocument = async ({
const segments = Array.isArray(params?.segments) ? params.segments : []
const collectionSlug = collectionConfig?.slug || undefined
const globalSlug = globalConfig?.slug || undefined
const isEditing = getIsEditing({ id, collectionSlug, globalSlug })
let isEditing = getIsEditing({ id: idFromArgs, collectionSlug, globalSlug })

let RootViewOverride: PayloadComponent
let CustomView: ViewFromConfig<ServerSideEditViewProps>
Expand All @@ -82,10 +82,10 @@ export const renderDocument = async ({
let apiURL: string

// Fetch the doc required for the view
const doc =
let doc =
initialData ||
(await getDocumentData({
id,
id: idFromArgs,
collectionSlug,
globalSlug,
locale,
Expand All @@ -104,7 +104,7 @@ export const renderDocument = async ({
] = await Promise.all([
// Get document preferences
getDocPreferences({
id,
id: idFromArgs,
collectionSlug,
globalSlug,
payload,
Expand All @@ -113,7 +113,7 @@ export const renderDocument = async ({

// Get permissions
getDocumentPermissions({
id,
id: idFromArgs,
collectionConfig,
data: doc,
globalConfig,
Expand All @@ -122,7 +122,7 @@ export const renderDocument = async ({

// Fetch document lock state
getIsLocked({
id,
id: idFromArgs,
collectionConfig,
globalConfig,
isEditing,
Expand All @@ -135,7 +135,7 @@ export const renderDocument = async ({
{ state: formState },
] = await Promise.all([
getVersions({
id,
id: idFromArgs,
collectionConfig,
docPermissions,
globalConfig,
Expand All @@ -144,15 +144,15 @@ export const renderDocument = async ({
user,
}),
buildFormState({
id,
id: idFromArgs,
collectionSlug,
data: doc,
docPermissions,
docPreferences,
fallbackLocale: false,
globalSlug,
locale: locale?.code,
operation: (collectionSlug && id) || globalSlug ? 'update' : 'create',
operation: (collectionSlug && idFromArgs) || globalSlug ? 'update' : 'create',
renderAllFields: true,
req,
schemaPath: collectionSlug || globalSlug,
Expand Down Expand Up @@ -187,7 +187,7 @@ export const renderDocument = async ({

const apiQueryParams = `?${params.toString()}`

apiURL = `${serverURL}${apiRoute}/${collectionSlug}/${id}${apiQueryParams}`
apiURL = `${serverURL}${apiRoute}/${collectionSlug}/${idFromArgs}${apiQueryParams}`

RootViewOverride =
collectionConfig?.admin?.components?.views?.edit?.root &&
Expand Down Expand Up @@ -274,8 +274,10 @@ export const renderDocument = async ({
const validateDraftData =
collectionConfig?.versions?.drafts && collectionConfig?.versions?.drafts?.validate

if (shouldAutosave && !validateDraftData && !id && collectionSlug) {
const doc = await payload.create({
let id = idFromArgs

if (shouldAutosave && !validateDraftData && !idFromArgs && collectionSlug) {
doc = await payload.create({
collection: collectionSlug,
data: initialData || {},
depth: 0,
Expand All @@ -287,12 +289,18 @@ export const renderDocument = async ({
})

if (doc?.id) {
const redirectURL = formatAdminURL({
adminRoute,
path: `/collections/${collectionSlug}/${doc.id}`,
serverURL,
})
redirect(redirectURL)
id = doc.id
isEditing = getIsEditing({ id: doc.id, collectionSlug, globalSlug })

if (!drawerSlug) {
const redirectURL = formatAdminURL({
adminRoute,
path: `/collections/${collectionSlug}/${doc.id}`,
serverURL,
})

redirect(redirectURL)
}
} else {
throw new Error('not-found')
}
Expand Down
6 changes: 4 additions & 2 deletions packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { useModal } from '@faceless-ui/modal'
import React, { useCallback, useEffect, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'

import type { DocumentDrawerProps } from './types.js'
Expand Down Expand Up @@ -45,6 +45,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({

const [DocumentView, setDocumentView] = useState<React.ReactNode>(undefined)
const [isLoading, setIsLoading] = useState(true)
const hasRenderedDocument = useRef(false)

const getDocumentView = useCallback(
(docID?: number | string) => {
Expand Down Expand Up @@ -142,8 +143,9 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
}, [getDocumentView])

useEffect(() => {
if (!DocumentView) {
if (!DocumentView && !hasRenderedDocument.current) {
getDocumentView(existingDocID)
hasRenderedDocument.current = true
}
}, [DocumentView, getDocumentView, existingDocID])

Expand Down
16 changes: 6 additions & 10 deletions packages/ui/src/providers/ServerFunctions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type RenderDocument = (args: {
redirectAfterDelete?: boolean
redirectAfterDuplicate?: boolean
signal?: AbortSignal
}) => Promise<{ docID: string; Document: React.ReactNode }>
}) => Promise<{ data: Data; Document: React.ReactNode }>

type GetDocumentSlots = (args: {
collectionSlug: string
Expand Down Expand Up @@ -129,16 +129,12 @@ export const ServerFunctionsProvider: React.FC<{
const { signal: remoteSignal, ...rest } = args || {}

try {
if (!remoteSignal?.aborted) {
const result = (await serverFunction({
name: 'render-document',
args: { fallbackLocale: false, ...rest },
})) as { docID: string; Document: React.ReactNode }
const result = (await serverFunction({
name: 'render-document',
args: { fallbackLocale: false, ...rest },
})) as { data: Data; Document: React.ReactNode }

if (!remoteSignal?.aborted) {
return result
}
}
return result
} catch (_err) {
console.error(_err) // eslint-disable-line no-console
}
Expand Down
7 changes: 3 additions & 4 deletions test/fields-relationship/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,9 @@ describe('fields - relationship', () => {
await expect(options).toHaveCount(2) // two docs
await options.nth(0).click()
await expect(field).toContainText(relationOneDoc.id)
await saveDocAndAssert(page)
await wait(200)
await trackNetworkRequests(page, `/api/${relationOneSlug}`, {
beforePoll: async () => await page.reload(),
await trackNetworkRequests(page, `/api/${relationOneSlug}`, async () => {
await saveDocAndAssert(page)
await wait(200)
})
})

Expand Down
3 changes: 3 additions & 0 deletions test/helpers/e2e/trackNetworkRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { expect } from '@playwright/test'
export const trackNetworkRequests = async (
page: Page,
url: string,
action: () => Promise<any>,
options?: {
allowedNumberOfRequests?: number
beforePoll?: () => Promise<any> | void
Expand All @@ -26,6 +27,8 @@ export const trackNetworkRequests = async (
}
})

await action()

if (typeof beforePoll === 'function') {
await beforePoll()
}
Expand Down
38 changes: 38 additions & 0 deletions test/versions/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import type { BrowserContext, Page } from '@playwright/test'

import { expect, test } from '@playwright/test'
import { navigateToDoc } from 'helpers/e2e/navigateToDoc.js'
import path from 'path'
import { wait } from 'payload/shared'
import { fileURLToPath } from 'url'
Expand All @@ -43,6 +44,7 @@ import {
throttleTest,
} from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { trackNetworkRequests } from '../helpers/e2e/trackNetworkRequests.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
import { reInitializeDB } from '../helpers/reInitializeDB.js'
import { waitForAutoSaveToRunAndComplete } from '../helpers/waitForAutoSaveToRunAndComplete.js'
Expand Down Expand Up @@ -394,6 +396,42 @@ describe('versions', () => {
expect(page.url()).toMatch(/\/versions$/)
})

test('collection - should autosave', async () => {
await page.goto(autosaveURL.create)
await page.locator('#field-title').fill('autosave title')
await waitForAutoSaveToRunAndComplete(page)
await expect(page.locator('#field-title')).toHaveValue('autosave title')

const { id: postID } = await payload.create({
collection: postCollectionSlug,
data: {
title: 'post title',
description: 'post description',
},
})

await page.goto(postURL.edit(postID))

await trackNetworkRequests(
page,
`${serverURL}/admin/collections/${postCollectionSlug}/${postID}`,
async () => {
await page
.locator(
'#field-relationToAutosaves.field-type.relationship .relationship-add-new__add-button.doc-drawer__toggler',
)
.click()
},
{
allowedNumberOfRequests: 1,
},
)

const drawer = page.locator('[id^=doc-drawer_autosave-posts_1_]')
await expect(drawer).toBeVisible()
await expect(drawer.locator('.id-label')).toBeVisible()
})

test('global - should autosave', async () => {
const url = new AdminUrlUtil(serverURL, autoSaveGlobalSlug)
await page.goto(url.global(autoSaveGlobalSlug))
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
],
"paths": {
"@payload-config": [
"./test/_community/config.ts"
"./test/versions/config.ts"
],
"@payloadcms/live-preview": [
"./packages/live-preview/src"
Expand Down