Skip to content

Commit

Permalink
fix(ui): lexical was incorrectly set to readonly in blocks (#9237)
Browse files Browse the repository at this point in the history
Fixes a bug introduced in `beta-131` that rendered Lexical fields as
read-only if they were within a block.
  • Loading branch information
jmikrut authored Nov 15, 2024
1 parent 30d66bf commit 131d1be
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
const disabledFromAdmin = field?.admin && 'disabled' in field.admin && field.admin.disabled

if (fieldAffectsData(field) && !(isHiddenField || disabledFromAdmin)) {
const fieldPermissions = permissions[field.name]
const fieldPermissions = permissions === true ? permissions : permissions?.[field.name]

let hasPermission: boolean = fieldPermissions === true || fieldPermissions?.read

Expand Down Expand Up @@ -382,7 +382,10 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
parentPassesCondition: passesCondition,
parentPath,
parentSchemaPath: rowSchemaPath,
permissions: permissions?.[field.name]?.blocks?.[block.slug]?.fields || {},
permissions:
fieldPermissions === true
? fieldPermissions
: permissions?.[field.name]?.blocks?.[block.slug]?.fields || {},
preferences,
previousFormState,
renderAllFields: requiresRender,
Expand Down Expand Up @@ -467,7 +470,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
parentPassesCondition: passesCondition,
parentPath: path,
parentSchemaPath: schemaPath,
permissions: permissions?.[field.name]?.fields || {},
permissions: fieldPermissions ?? permissions?.[field.name]?.fields ?? {},
preferences,
previousFormState,
renderAllFields,
Expand Down Expand Up @@ -658,7 +661,11 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
parentPassesCondition: passesCondition,
parentPath: tabHasName(tab) ? tabPath : parentPath,
parentSchemaPath: tabHasName(tab) ? tabSchemaPath : parentSchemaPath,
permissions: tabHasName(tab) ? permissions?.[tab.name]?.fields || {} : permissions,
permissions: tabHasName(tab)
? typeof permissions === 'boolean'
? permissions
: permissions?.[tab.name] || {}
: permissions,
preferences,
previousFormState,
renderAllFields,
Expand Down
22 changes: 22 additions & 0 deletions test/access-control/collections/RichText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { CollectionConfig } from 'payload'

export const RichText: CollectionConfig = {
slug: 'rich-text',
fields: [
{
name: 'blocks',
type: 'blocks',
blocks: [
{
slug: 'richText',
fields: [
{
name: 'richText',
type: 'richText',
},
],
},
],
},
],
}
2 changes: 2 additions & 0 deletions test/access-control/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Config, User } from './payload-types.js'
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
import { devUser } from '../credentials.js'
import { Disabled } from './collections/Disabled/index.js'
import { RichText } from './collections/RichText/index.js'
import {
createNotUpdateCollectionSlug,
docLevelAccessSlug,
Expand Down Expand Up @@ -506,6 +507,7 @@ export default buildConfigWithDefaults({
],
},
Disabled,
RichText,
],
globals: [
{
Expand Down
24 changes: 24 additions & 0 deletions test/access-control/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ describe('access control', () => {
let restrictedUrl: AdminUrlUtil
let unrestrictedURL: AdminUrlUtil
let readOnlyCollectionUrl: AdminUrlUtil
let richTextUrl: AdminUrlUtil
let readOnlyGlobalUrl: AdminUrlUtil
let restrictedVersionsUrl: AdminUrlUtil
let userRestrictedCollectionURL: AdminUrlUtil
Expand All @@ -80,6 +81,7 @@ describe('access control', () => {

url = new AdminUrlUtil(serverURL, slug)
restrictedUrl = new AdminUrlUtil(serverURL, fullyRestrictedSlug)
richTextUrl = new AdminUrlUtil(serverURL, 'rich-text')
unrestrictedURL = new AdminUrlUtil(serverURL, unrestrictedSlug)
readOnlyCollectionUrl = new AdminUrlUtil(serverURL, readOnlySlug)
readOnlyGlobalUrl = new AdminUrlUtil(serverURL, readOnlySlug)
Expand Down Expand Up @@ -147,6 +149,28 @@ describe('access control', () => {
})
})

describe('rich text', () => {
test('rich text within block should render as editable', async () => {
await page.goto(richTextUrl.create)

await page.locator('.blocks-field__drawer-toggler').click()
await page.locator('.thumbnail-card').click()
const richTextField = page.locator('.rich-text-lexical')
const contentEditable = richTextField.locator('.ContentEditable__root').first()
await expect(contentEditable).toBeVisible()
await contentEditable.click()

const typedText = 'Hello, this field is editable!'
await page.keyboard.type(typedText)

await expect(
page.locator('[data-lexical-text="true"]', {
hasText: exactText(typedText),
}),
).toHaveCount(1)
})
})

describe('collection — fully restricted', () => {
let existingDoc: ReadOnlyCollection

Expand Down
56 changes: 56 additions & 0 deletions test/access-control/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface Config {
'hidden-access': HiddenAccess;
'hidden-access-count': HiddenAccessCount;
disabled: Disabled;
'rich-text': RichText;
'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
Expand All @@ -52,6 +53,7 @@ export interface Config {
'hidden-access': HiddenAccessSelect<false> | HiddenAccessSelect<true>;
'hidden-access-count': HiddenAccessCountSelect<false> | HiddenAccessCountSelect<true>;
disabled: DisabledSelect<false> | DisabledSelect<true>;
'rich-text': RichTextSelect<false> | RichTextSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
Expand Down Expand Up @@ -350,6 +352,37 @@ export interface Disabled {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "rich-text".
*/
export interface RichText {
id: string;
blocks?:
| {
richText?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
id?: string | null;
blockName?: string | null;
blockType: 'richText';
}[]
| null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-locked-documents".
Expand Down Expand Up @@ -424,6 +457,10 @@ export interface PayloadLockedDocument {
| ({
relationTo: 'disabled';
value: string | Disabled;
} | null)
| ({
relationTo: 'rich-text';
value: string | RichText;
} | null);
globalSlug?: string | null;
user:
Expand Down Expand Up @@ -694,6 +731,25 @@ export interface DisabledSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "rich-text_select".
*/
export interface RichTextSelect<T extends boolean = true> {
blocks?:
| T
| {
richText?:
| T
| {
richText?: T;
id?: T;
blockName?: T;
};
};
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-locked-documents_select".
Expand Down

0 comments on commit 131d1be

Please sign in to comment.