Skip to content

Commit f49eeb1

Browse files
authored
fix(next): respect collection-level live preview config (#13036)
Fixes #13035. We broke collection-level live preview configs in #12860.
1 parent 1d9ad6f commit f49eeb1

File tree

10 files changed

+126
-14
lines changed

10 files changed

+126
-14
lines changed

packages/next/src/views/Document/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
DocumentViewServerProps,
77
DocumentViewServerPropsOnly,
88
EditViewComponent,
9+
LivePreviewConfig,
910
PayloadComponent,
1011
RenderDocumentVersionsProperties,
1112
} from 'payload'
@@ -91,7 +92,6 @@ export const renderDocument = async ({
9192
payload: {
9293
config,
9394
config: {
94-
admin: { livePreview: livePreviewConfig },
9595
routes: { admin: adminRoute, api: apiRoute },
9696
serverURL,
9797
},
@@ -329,6 +329,12 @@ export const renderDocument = async ({
329329
viewType,
330330
}
331331

332+
const livePreviewConfig: LivePreviewConfig = {
333+
...(config.admin.livePreview || {}),
334+
...(collectionConfig?.admin?.livePreview || {}),
335+
...(globalConfig?.admin?.livePreview || {}),
336+
}
337+
332338
const livePreviewURL =
333339
typeof livePreviewConfig?.url === 'function'
334340
? await livePreviewConfig.url({

packages/ui/src/providers/LivePreview/index.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ export const LivePreviewProvider: React.FC<LivePreviewProviderProps> = ({
226226
)
227227
}, [isLivePreviewing, setPreference, collectionSlug, globalSlug])
228228

229+
const isLivePreviewEnabled = Boolean(
230+
operation !== 'create' &&
231+
((collectionSlug && config?.admin?.livePreview?.collections?.includes(collectionSlug)) ||
232+
(globalSlug && config.admin?.livePreview?.globals?.includes(globalSlug)) ||
233+
entityConfig?.admin?.livePreview),
234+
)
235+
229236
return (
230237
<LivePreviewContext
231238
value={{
@@ -235,13 +242,7 @@ export const LivePreviewProvider: React.FC<LivePreviewProviderProps> = ({
235242
fieldSchemaJSON,
236243
iframeHasLoaded,
237244
iframeRef,
238-
isLivePreviewEnabled: Boolean(
239-
(operation !== 'create' &&
240-
collectionSlug &&
241-
config?.admin?.livePreview?.collections?.includes(collectionSlug)) ||
242-
(globalSlug && config.admin?.livePreview?.globals?.includes(globalSlug)) ||
243-
entityConfig?.admin?.livePreview,
244-
),
245+
isLivePreviewEnabled,
245246
isLivePreviewing,
246247
isPopupOpen,
247248
listeningForMessages,

test/_community/payload-types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,13 @@ export interface User {
203203
hash?: string | null;
204204
loginAttempts?: number | null;
205205
lockUntil?: string | null;
206+
sessions?:
207+
| {
208+
id: string;
209+
createdAt?: string | null;
210+
expiresAt: string;
211+
}[]
212+
| null;
206213
password?: string | null;
207214
}
208215
/**
@@ -341,6 +348,13 @@ export interface UsersSelect<T extends boolean = true> {
341348
hash?: T;
342349
loginAttempts?: T;
343350
lockUntil?: T;
351+
sessions?:
352+
| T
353+
| {
354+
id?: T;
355+
createdAt?: T;
356+
expiresAt?: T;
357+
};
344358
}
345359
/**
346360
* This interface was referenced by `Config`'s JSON-Schema

test/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ export async function saveDocHotkeyAndAssert(page: Page): Promise<void> {
248248

249249
export async function saveDocAndAssert(
250250
page: Page,
251-
selector: '#access-save' | '#action-publish' | '#action-save-draft' | string = '#action-save',
251+
selector: '#action-publish' | '#action-save' | '#action-save-draft' | string = '#action-save',
252252
expectation: 'error' | 'success' = 'success',
253253
): Promise<void> {
254254
await wait(500) // TODO: Fix this

test/live-preview/collections/Categories.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { CollectionConfig } from 'payload'
22

33
import { categoriesSlug } from '../shared.js'
44

5-
const Categories: CollectionConfig = {
5+
export const Categories: CollectionConfig = {
66
slug: categoriesSlug,
77
admin: {
88
useAsTitle: 'title',
@@ -17,5 +17,3 @@ const Categories: CollectionConfig = {
1717
},
1818
],
1919
}
20-
21-
export default Categories
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { CollectionConfig } from 'payload'
2+
3+
import { collectionLevelConfigSlug } from '../shared.js'
4+
5+
export const CollectionLevelConfig: CollectionConfig = {
6+
slug: collectionLevelConfigSlug,
7+
admin: {
8+
description: "Live Preview is enabled on this collection's own config, not the root config.",
9+
useAsTitle: 'title',
10+
livePreview: {
11+
url: 'http://localhost:3000/live-preview',
12+
},
13+
},
14+
access: {
15+
read: () => true,
16+
},
17+
fields: [
18+
{
19+
name: 'title',
20+
type: 'text',
21+
},
22+
],
23+
}

test/live-preview/config.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import path from 'path'
33
const filename = fileURLToPath(import.meta.url)
44
const dirname = path.dirname(filename)
55
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
6-
import Categories from './collections/Categories.js'
6+
import { Categories } from './collections/Categories.js'
7+
import { CollectionLevelConfig } from './collections/CollectionLevelConfig.js'
78
import { Media } from './collections/Media.js'
89
import { Pages } from './collections/Pages.js'
910
import { Posts } from './collections/Posts.js'
@@ -44,7 +45,17 @@ export default buildConfigWithDefaults({
4445
},
4546
cors: ['http://localhost:3000', 'http://localhost:3001'],
4647
csrf: ['http://localhost:3000', 'http://localhost:3001'],
47-
collections: [Users, Pages, Posts, SSR, SSRAutosave, Tenants, Categories, Media],
48+
collections: [
49+
Users,
50+
Pages,
51+
Posts,
52+
SSR,
53+
SSRAutosave,
54+
Tenants,
55+
Categories,
56+
Media,
57+
CollectionLevelConfig,
58+
],
4859
globals: [Header, Footer],
4960
onInit: seed,
5061
typescript: {

test/live-preview/e2e.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
toggleLivePreview,
2828
} from './helpers.js'
2929
import {
30+
collectionLevelConfigSlug,
3031
desktopBreakpoint,
3132
mobileBreakpoint,
3233
pagesSlug,
@@ -101,6 +102,22 @@ describe('Live Preview', () => {
101102
await expect(page.locator('iframe.live-preview-iframe')).toBeHidden()
102103
})
103104

105+
test('collection - does not enable live preview is collections that are not configured', async () => {
106+
const usersURL = new AdminUrlUtil(serverURL, 'users')
107+
await navigateToDoc(page, usersURL)
108+
const toggler = page.locator('#live-preview-toggler')
109+
await expect(toggler).toBeHidden()
110+
})
111+
112+
test('collection - respect collection-level live preview config', async () => {
113+
const collURL = new AdminUrlUtil(serverURL, collectionLevelConfigSlug)
114+
await page.goto(collURL.create)
115+
await page.locator('#field-title').fill('Collection Level Config')
116+
await saveDocAndAssert(page)
117+
await toggleLivePreview(page)
118+
await expect(page.locator('iframe.live-preview-iframe')).toBeVisible()
119+
})
120+
104121
test('saves live preview state to preferences and loads it on next visit', async () => {
105122
await deletePreferences({
106123
payload,

test/live-preview/payload-types.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export interface Config {
7575
tenants: Tenant;
7676
categories: Category;
7777
media: Media;
78+
'collection-level-config': CollectionLevelConfig;
7879
'payload-locked-documents': PayloadLockedDocument;
7980
'payload-preferences': PayloadPreference;
8081
'payload-migrations': PayloadMigration;
@@ -89,6 +90,7 @@ export interface Config {
8990
tenants: TenantsSelect<false> | TenantsSelect<true>;
9091
categories: CategoriesSelect<false> | CategoriesSelect<true>;
9192
media: MediaSelect<false> | MediaSelect<true>;
93+
'collection-level-config': CollectionLevelConfigSelect<false> | CollectionLevelConfigSelect<true>;
9294
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
9395
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
9496
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
@@ -146,6 +148,13 @@ export interface User {
146148
hash?: string | null;
147149
loginAttempts?: number | null;
148150
lockUntil?: string | null;
151+
sessions?:
152+
| {
153+
id: string;
154+
createdAt?: string | null;
155+
expiresAt: string;
156+
}[]
157+
| null;
149158
password?: string | null;
150159
}
151160
/**
@@ -834,6 +843,18 @@ export interface SsrAutosave {
834843
createdAt: string;
835844
_status?: ('draft' | 'published') | null;
836845
}
846+
/**
847+
* Live Preview is enabled on this collection's own config, not the root config.
848+
*
849+
* This interface was referenced by `Config`'s JSON-Schema
850+
* via the `definition` "collection-level-config".
851+
*/
852+
export interface CollectionLevelConfig {
853+
id: string;
854+
title?: string | null;
855+
updatedAt: string;
856+
createdAt: string;
857+
}
837858
/**
838859
* This interface was referenced by `Config`'s JSON-Schema
839860
* via the `definition` "payload-locked-documents".
@@ -872,6 +893,10 @@ export interface PayloadLockedDocument {
872893
| ({
873894
relationTo: 'media';
874895
value: string | Media;
896+
} | null)
897+
| ({
898+
relationTo: 'collection-level-config';
899+
value: string | CollectionLevelConfig;
875900
} | null);
876901
globalSlug?: string | null;
877902
user: {
@@ -929,6 +954,13 @@ export interface UsersSelect<T extends boolean = true> {
929954
hash?: T;
930955
loginAttempts?: T;
931956
lockUntil?: T;
957+
sessions?:
958+
| T
959+
| {
960+
id?: T;
961+
createdAt?: T;
962+
expiresAt?: T;
963+
};
932964
}
933965
/**
934966
* This interface was referenced by `Config`'s JSON-Schema
@@ -1395,6 +1427,15 @@ export interface MediaSelect<T extends boolean = true> {
13951427
focalX?: T;
13961428
focalY?: T;
13971429
}
1430+
/**
1431+
* This interface was referenced by `Config`'s JSON-Schema
1432+
* via the `definition` "collection-level-config_select".
1433+
*/
1434+
export interface CollectionLevelConfigSelect<T extends boolean = true> {
1435+
title?: T;
1436+
updatedAt?: T;
1437+
createdAt?: T;
1438+
}
13981439
/**
13991440
* This interface was referenced by `Config`'s JSON-Schema
14001441
* via the `definition` "payload-locked-documents_select".

test/live-preview/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const ssrAutosavePagesSlug = 'ssr-autosave'
55
export const postsSlug = 'posts'
66
export const mediaSlug = 'media'
77
export const categoriesSlug = 'categories'
8+
export const collectionLevelConfigSlug = 'collection-level-config'
89
export const usersSlug = 'users'
910

1011
export const mobileBreakpoint = {

0 commit comments

Comments
 (0)