Skip to content

Commit

Permalink
chore: supports live preview url as function (#3455)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobsfletch committed Oct 6, 2023
1 parent 03538c0 commit 5bc8103
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import type { Dispatch } from 'react'

import { createContext, useContext } from 'react'

import type { LivePreview } from '../../../../../exports/config'
import type { LivePreviewConfig } from '../../../../../exports/config'
import type { SizeReducerAction } from './sizeReducer'

export interface LivePreviewContextType {
breakpoint: LivePreview['breakpoints'][number]['name']
breakpoints: LivePreview['breakpoints']
breakpoint: LivePreviewConfig['breakpoints'][number]['name']
breakpoints: LivePreviewConfig['breakpoints']
deviceFrameRef: React.RefObject<HTMLDivElement>
iframeHasLoaded: boolean
iframeRef: React.RefObject<HTMLIFrameElement>
measuredDeviceSize: {
height: number
width: number
}
setBreakpoint: (breakpoint: LivePreview['breakpoints'][number]['name']) => void
setBreakpoint: (breakpoint: LivePreviewConfig['breakpoints'][number]['name']) => void
setHeight: (height: number) => void
setIframeHasLoaded: (loaded: boolean) => void
setSize: Dispatch<SizeReducerAction>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DndContext } from '@dnd-kit/core'
import React, { useCallback, useEffect } from 'react'

import type { LivePreview } from '../../../../../exports/config'
import type { LivePreviewConfig } from '../../../../../exports/config'
import type { EditViewProps } from '../../types'
import type { usePopupWindow } from '../usePopupWindow'

Expand All @@ -11,7 +11,7 @@ import { LivePreviewContext } from './context'
import { sizeReducer } from './sizeReducer'

export type ToolbarProviderProps = EditViewProps & {
breakpoints?: LivePreview['breakpoints']
breakpoints?: LivePreviewConfig['breakpoints']
children: React.ReactNode
deviceSize?: {
height: number
Expand All @@ -37,7 +37,7 @@ export const LivePreviewProvider: React.FC<ToolbarProviderProps> = (props) => {
const [size, setSize] = React.useReducer(sizeReducer, { height: 0, width: 0 })

const [breakpoint, setBreakpoint] =
React.useState<LivePreview['breakpoints'][0]['name']>('responsive')
React.useState<LivePreviewConfig['breakpoints'][0]['name']>('responsive')

// The toolbar needs to freely drag and drop around the page
const handleDragEnd = (ev) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'

import type { LivePreview as LivePreviewType } from '../../../../../exports/config'
import type { LivePreviewConfig } from '../../../../../exports/config'
import type { Field } from '../../../../../fields/config/types'
import type { EditViewProps } from '../../types'
import type { usePopupWindow } from '../usePopupWindow'
Expand Down Expand Up @@ -121,7 +121,7 @@ export const LivePreview: React.FC<
> = (props) => {
let url

let breakpoints: LivePreviewType['breakpoints'] = [
let breakpoints: LivePreviewConfig['breakpoints'] = [
{
name: 'responsive',
height: '100%',
Expand Down
20 changes: 17 additions & 3 deletions packages/payload/src/admin/components/views/LivePreview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Fragment } from 'react'
import { useTranslation } from 'react-i18next'

import type { LivePreviewConfig } from '../../../../exports/config'
import type { SanitizedCollectionConfig, SanitizedGlobalConfig } from '../../../../exports/types'
import type { EditViewProps } from '../types'

Expand All @@ -11,6 +12,8 @@ import RenderFields from '../../forms/RenderFields'
import { filterFields } from '../../forms/RenderFields/filterFields'
import { fieldTypes } from '../../forms/field-types'
import { LeaveWithoutSaving } from '../../modals/LeaveWithoutSaving'
import { useDocumentInfo } from '../../utilities/DocumentInfo'
import { useLocale } from '../../utilities/Locale'
import Meta from '../../utilities/Meta'
import { SetStepNav } from '../collections/Edit/SetStepNav'
import { LivePreview } from './Preview'
Expand All @@ -21,17 +24,28 @@ const baseClass = 'live-preview'

export const LivePreviewView: React.FC<EditViewProps> = (props) => {
const { i18n, t } = useTranslation('general')
const documentInfo = useDocumentInfo()
const locale = useLocale()

let url
let urlFromConfig: LivePreviewConfig['url']

if ('collection' in props) {
url = props?.collection.admin.livePreview.url
urlFromConfig = props?.collection.admin.livePreview.url
}

if ('global' in props) {
url = props?.global.admin.livePreview.url
urlFromConfig = props?.global.admin.livePreview.url
}

const url =
typeof urlFromConfig === 'function'
? urlFromConfig({
data: props?.data,
documentInfo,
locale,
})
: urlFromConfig

const popupState = usePopupWindow({
eventType: 'livePreview',
href: url,
Expand Down
2 changes: 1 addition & 1 deletion packages/payload/src/collections/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const collectionSchema = joi.object().keys({
width: joi.alternatives().try(joi.number(), joi.string()),
}),
),
url: joi.string(),
url: joi.alternatives().try(joi.string(), joi.func()),
}),
pagination: joi.object({
defaultLimit: joi.number(),
Expand Down
4 changes: 2 additions & 2 deletions packages/payload/src/collections/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type {
Endpoint,
EntityDescription,
GeneratePreviewURL,
LivePreview,
LivePreviewConfig,
} from '../../config/types'
import type { PayloadRequest, RequestContext } from '../../express/types'
import type { Field } from '../../fields/config/types'
Expand Down Expand Up @@ -273,7 +273,7 @@ export type CollectionAdminOptions = {
/**
* Live preview options
*/
livePreview?: LivePreview
livePreview?: LivePreviewConfig
pagination?: {
defaultLimit?: number
limits?: number[]
Expand Down
7 changes: 5 additions & 2 deletions packages/payload/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { Configuration } from 'webpack'

import type { DocumentTab } from '../admin/components/elements/DocumentHeader/Tabs/types'
import type { RichTextAdapter } from '../admin/components/forms/field-types/RichText/types'
import type { ContextType } from '../admin/components/utilities/DocumentInfo/types'
import type { CollectionEditViewProps, GlobalEditViewProps } from '../admin/components/views/types'
import type { User } from '../auth/types'
import type { PayloadBundler } from '../bundlers/types'
Expand Down Expand Up @@ -40,7 +41,7 @@ type Email = {
// eslint-disable-next-line no-use-before-define
export type Plugin = (config: Config) => Config | Promise<Config>

export type LivePreview = {
export type LivePreviewConfig = {
/**
Device breakpoints to use for the `iframe` of the Live Preview window.
Options are displayed in the Live Preview toolbar.
Expand All @@ -58,7 +59,9 @@ export type LivePreview = {
The frontend application is responsible for receiving the message and updating the UI accordingly.
Use the `useLivePreview` hook to get started in React applications.
*/
url?: string
url?:
| ((args: { data: Record<string, any>; documentInfo: ContextType; locale: Locale }) => string)
| string
}

type GeneratePreviewURLOptions = {
Expand Down
2 changes: 1 addition & 1 deletion packages/payload/src/globals/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const globalSchema = joi
width: joi.alternatives().try(joi.number(), joi.string()),
}),
),
url: joi.string(),
url: joi.alternatives().try(joi.string(), joi.func()),
}),
preview: joi.func(),
}),
Expand Down
7 changes: 3 additions & 4 deletions packages/payload/src/globals/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ import type {
Endpoint,
EntityDescription,
GeneratePreviewURL,
LivePreview,
LivePreviewConfig,
} from '../../config/types'
import type { PayloadRequest } from '../../express/types'
import type { Field } from '../../fields/config/types'
import type { Where } from '../../types'

import type { IncomingGlobalVersions, SanitizedGlobalVersions } from '../../versions/types'

export type TypeWithID = {
Expand Down Expand Up @@ -80,6 +79,7 @@ export type GlobalAdminOptions = {
*/
Edit?:
| {
[name: string]: EditView
/**
* Replace or modify individual nested routes, or add new ones:
* + `Default` - `/admin/globals/:slug`
Expand All @@ -93,7 +93,6 @@ export type GlobalAdminOptions = {
*/
Default?: EditView
Versions?: EditView
[name: string]: EditView
// TODO: uncomment these as they are built
// API?: EditView
// LivePreview?: EditView
Expand Down Expand Up @@ -123,7 +122,7 @@ export type GlobalAdminOptions = {
/**
* Live preview options
*/
livePreview?: LivePreview
livePreview?: LivePreviewConfig
/**
* Function to generate custom preview URL
*/
Expand Down
2 changes: 1 addition & 1 deletion test/live-preview/collections/Pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const Pages: CollectionConfig = {
},
admin: {
livePreview: {
url: 'http://localhost:3001',
url: ({ data }) => `http://localhost:3001/${data?.slug}`,
breakpoints: [
{
label: 'Mobile',
Expand Down
8 changes: 1 addition & 7 deletions test/live-preview/collections/Posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,14 @@ export const Posts: CollectionConfig = {
},
admin: {
livePreview: {
url: 'http://localhost:3001',
url: ({ data, documentInfo }) => `http://localhost:3001/${documentInfo.slug}/${data?.slug}`,
breakpoints: [
{
label: 'Mobile',
name: 'mobile',
width: 375,
height: 667,
},
// {
// label: 'Desktop',
// name: 'desktop',
// width: 1440,
// height: 900,
// },
],
},
useAsTitle: 'title',
Expand Down

0 comments on commit 5bc8103

Please sign in to comment.