forked from payloadcms/payload
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui): allows customizing version diff components, render versions…
… ui on the server (payloadcms#10815) This PR moves the logic for rendering diff field components in the version comparison view from the client to the server. This allows us to expose more customization options to the server-side Payload Config. For example, users can now pass their own diff components for fields - even including RSCs. This PR also cleans up the version view types Implements the following from payloadcms#4197: - allow for customization of diff components - more control over versions screens in general TODO: - [x] Bring getFieldPaths fixes into core - [x] Cleanup and test with scrutiny. Ensure all field types display their diffs correctly - [x] Review public API for overriding field types, add docs - [x] Add e2e test for new public API
- Loading branch information
Showing
70 changed files
with
11,005 additions
and
3,701 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
13 changes: 13 additions & 0 deletions
13
packages/next/src/views/Version/Default/SelectedLocalesContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
'use client' | ||
|
||
import React, { createContext } from 'react' | ||
|
||
type SelectedLocalesContextType = { | ||
selectedLocales: string[] | ||
} | ||
|
||
export const SelectedLocalesContext = createContext<SelectedLocalesContextType>({ | ||
selectedLocales: [], | ||
}) | ||
|
||
export const useSelectedLocales = () => React.useContext(SelectedLocalesContext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
packages/next/src/views/Version/RenderFieldsToDiff/RenderVersionFieldsToDiff.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
'use client' | ||
const baseClass = 'render-field-diffs' | ||
import type { VersionField } from 'payload' | ||
|
||
import './index.scss' | ||
|
||
import { ShimmerEffect } from '@payloadcms/ui' | ||
import React, { Fragment, useEffect } from 'react' | ||
|
||
export const RenderVersionFieldsToDiff = ({ | ||
versionFields, | ||
}: { | ||
versionFields: VersionField[] | ||
}): React.ReactNode => { | ||
const [hasMounted, setHasMounted] = React.useState(false) | ||
|
||
// defer rendering until after the first mount as the CSS is loaded with Emotion | ||
// this will ensure that the CSS is loaded before rendering the diffs and prevent CLS | ||
useEffect(() => { | ||
setHasMounted(true) | ||
}, []) | ||
|
||
return ( | ||
<div className={baseClass}> | ||
{!hasMounted ? ( | ||
<Fragment> | ||
<ShimmerEffect height="8rem" width="100%" /> | ||
</Fragment> | ||
) : ( | ||
versionFields?.map((field, fieldIndex) => { | ||
if (field.fieldByLocale) { | ||
const LocaleComponents: React.ReactNode[] = [] | ||
for (const [locale, baseField] of Object.entries(field.fieldByLocale)) { | ||
LocaleComponents.push( | ||
<div className={`${baseClass}__locale`} key={[locale, fieldIndex].join('-')}> | ||
<div className={`${baseClass}__locale-value`}>{baseField.CustomComponent}</div> | ||
</div>, | ||
) | ||
} | ||
return ( | ||
<div className={`${baseClass}__field`} key={fieldIndex}> | ||
{LocaleComponents} | ||
</div> | ||
) | ||
} else if (field.field) { | ||
return ( | ||
<div | ||
className={`${baseClass}__field field__${field.field.type}`} | ||
data-field-path={field.field.path} | ||
key={fieldIndex} | ||
> | ||
{field.field.CustomComponent} | ||
</div> | ||
) | ||
} | ||
|
||
return null | ||
}) | ||
)} | ||
</div> | ||
) | ||
} |
Oops, something went wrong.