fix(next): version diff view not handling all field permissions correctly (#13721)

Fixes https://github.com/payloadcms/payload/issues/13286

The version diff view did not handle all field permissions correctly,
leading to some fields disappearing if access control was set. This PR
fixes that.

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211267837905375
This commit is contained in:
Alessio Gravili
2025-09-09 08:31:15 -07:00
committed by GitHub
parent e49005fcbd
commit 911f17a887
12 changed files with 184 additions and 69 deletions

View File

@@ -91,6 +91,13 @@ export const Diff: CollectionConfig = {
name: 'textInUnnamedTab2InBlock',
type: 'text',
},
{
name: 'textInUnnamedTab2InBlockAccessFalse',
type: 'text',
access: {
read: () => false,
},
},
{
type: 'row',
fields: [
@@ -220,6 +227,13 @@ export const Diff: CollectionConfig = {
],
type: 'row',
},
{
name: 'textCannotRead',
type: 'text',
access: {
read: () => false,
},
},
{
name: 'select',
type: 'select',
@@ -244,6 +258,20 @@ export const Diff: CollectionConfig = {
name: 'textInNamedTab1',
type: 'text',
},
{
name: 'textInNamedTab1ReadFalse',
type: 'text',
access: {
read: () => false,
},
},
{
name: 'textInNamedTab1UpdateFalse',
type: 'text',
access: {
update: () => false,
},
},
],
},
{
@@ -253,6 +281,22 @@ export const Diff: CollectionConfig = {
name: 'textInUnnamedTab2',
type: 'text',
},
{
type: 'row',
fields: [
{
name: 'textInRowInUnnamedTab',
type: 'text',
},
{
name: 'textInRowInUnnamedTabUpdateFalse',
type: 'text',
access: {
update: () => false,
},
},
],
},
],
},
],

View File

@@ -1981,6 +1981,22 @@ describe('Versions', () => {
const hiddenField2 = page.locator('[data-field-path="textCannotRead"]')
await expect(hiddenField2).toBeHidden()
const hiddenField3 = page.locator('[data-field-path="namedTab1.textInNamedTab1ReadFalse"]')
await expect(hiddenField3).toBeHidden()
const visibleFieldWithUpdateFalse1 = page.locator(
'[data-field-path="namedTab1.textInNamedTab1UpdateFalse"]',
)
await expect(visibleFieldWithUpdateFalse1).toBeVisible()
const visibleField2 = page.locator('[data-field-path="textInRowInUnnamedTab"]')
await expect(visibleField2).toBeVisible()
const visibleFieldWithUpdateFalse3 = page.locator(
'[data-field-path="textInRowInUnnamedTabUpdateFalse"]',
)
await expect(visibleFieldWithUpdateFalse3).toBeVisible()
})
test('correctly renders diff for relationship fields with deleted relation', async () => {

View File

@@ -412,6 +412,7 @@ export interface Diff {
textInNamedTab1InBlock?: string | null;
};
textInUnnamedTab2InBlock?: string | null;
textInUnnamedTab2InBlockAccessFalse?: string | null;
textInRowInUnnamedTab2InBlock?: string | null;
id?: string | null;
blockName?: string | null;
@@ -509,11 +510,16 @@ export interface Diff {
[k: string]: unknown;
} | null;
textInRow?: string | null;
textCannotRead?: string | null;
select?: ('option1' | 'option2') | null;
namedTab1?: {
textInNamedTab1?: string | null;
textInNamedTab1ReadFalse?: string | null;
textInNamedTab1UpdateFalse?: string | null;
};
textInUnnamedTab2?: string | null;
textInRowInUnnamedTab?: string | null;
textInRowInUnnamedTabUpdateFalse?: string | null;
text?: string | null;
textArea?: string | null;
upload?: (string | null) | Media;
@@ -1030,6 +1036,7 @@ export interface DiffSelect<T extends boolean = true> {
textInNamedTab1InBlock?: T;
};
textInUnnamedTab2InBlock?: T;
textInUnnamedTab2InBlockAccessFalse?: T;
textInRowInUnnamedTab2InBlock?: T;
id?: T;
blockName?: T;
@@ -1057,13 +1064,18 @@ export interface DiffSelect<T extends boolean = true> {
richtext?: T;
richtextWithCustomDiff?: T;
textInRow?: T;
textCannotRead?: T;
select?: T;
namedTab1?:
| T
| {
textInNamedTab1?: T;
textInNamedTab1ReadFalse?: T;
textInNamedTab1UpdateFalse?: T;
};
textInUnnamedTab2?: T;
textInRowInUnnamedTab?: T;
textInRowInUnnamedTabUpdateFalse?: T;
text?: T;
textArea?: T;
upload?: T;

View File

@@ -248,6 +248,8 @@ export async function seed(_payload: Payload, parallel: boolean = false) {
},
namedTab1: {
textInNamedTab1: 'textInNamedTab1',
textInNamedTab1ReadFalse: 'textInNamedTab1ReadFalse',
textInNamedTab1UpdateFalse: 'textInNamedTab1UpdateFalse',
},
number: 1,
point: [1, 2],
@@ -276,6 +278,9 @@ export async function seed(_payload: Payload, parallel: boolean = false) {
textInCollapsible: 'textInCollapsible',
textInRow: 'textInRow',
textInUnnamedTab2: 'textInUnnamedTab2',
textInRowInUnnamedTab: 'textInRowInUnnamedTab',
textInRowInUnnamedTabUpdateFalse: 'textInRowInUnnamedTabUpdateFalse',
textCannotRead: 'textCannotRead',
relationshipPolymorphic: {
relationTo: 'text',
@@ -386,6 +391,8 @@ export async function seed(_payload: Payload, parallel: boolean = false) {
},
namedTab1: {
textInNamedTab1: 'textInNamedTab12',
textInNamedTab1ReadFalse: 'textInNamedTab1ReadFalse2',
textInNamedTab1UpdateFalse: 'textInNamedTab1UpdateFalse2',
},
number: 2,
json: {
@@ -439,6 +446,9 @@ export async function seed(_payload: Payload, parallel: boolean = false) {
textInRow: 'textInRow2',
textCannotRead: 'textCannotRead2',
textInUnnamedTab2: 'textInUnnamedTab22',
textInRowInUnnamedTab: 'textInRowInUnnamedTab2',
textInRowInUnnamedTabUpdateFalse: 'textInRowInUnnamedTabUpdateFalse2',
upload: uploadedImage2,
uploadHasMany: [uploadedImage, uploadedImage2],
},