Skip to content

Commit 8dac487

Browse files
authored
Merge branch 'main' into feat/view-conditions
2 parents 131bc62 + a5ec55c commit 8dac487

File tree

26 files changed

+145
-27
lines changed

26 files changed

+145
-27
lines changed

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
pnpm-version:
1111
description: Pnpm version
1212
required: true
13-
default: 9.7.1
13+
default: 10.12.1
1414
pnpm-run-install:
1515
description: Whether to run pnpm install
1616
required: false

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ concurrency:
1818

1919
env:
2020
NODE_VERSION: 23.11.0
21-
PNPM_VERSION: 9.7.1
21+
PNPM_VERSION: 10.12.1
2222
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
2323
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
2424

.github/workflows/post-release-templates.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
env:
1010
NODE_VERSION: 23.11.0
11-
PNPM_VERSION: 9.7.1
11+
PNPM_VERSION: 10.12.1
1212
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
1313
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
1414

.github/workflows/post-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313

1414
env:
1515
NODE_VERSION: 23.11.0
16-
PNPM_VERSION: 9.7.1
16+
PNPM_VERSION: 10.12.1
1717
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
1818
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
1919

.github/workflows/publish-prerelease.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
env:
1010
NODE_VERSION: 23.11.0
11-
PNPM_VERSION: 9.7.1
11+
PNPM_VERSION: 10.12.1
1212
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
1313
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
1414

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
pnpm 9.7.1
1+
pnpm 10.12.1
22
nodejs 23.11.0

docs/configuration/collections.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ The following options are available:
8585
| `defaultPopulate` | Specify which fields to select when this Collection is populated from another document. [More Details](../queries/select#defaultpopulate-collection-config-property). |
8686
| `indexes` | Define compound indexes for this collection. This can be used to either speed up querying/sorting by 2 or more fields at the same time or to ensure uniqueness between several fields. |
8787
| `forceSelect` | Specify which fields should be selected always, regardless of the `select` query which can be useful that the field exists for access control / hooks |
88+
| `disableBulkEdit` | Disable the bulk edit operation for the collection in the admin panel and the REST API |
8889

8990
_\* An asterisk denotes that a property is required._
9091

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
"drizzle-kit": "0.31.0",
155155
"drizzle-orm": "0.43.1",
156156
"escape-html": "^1.0.3",
157+
"eslint": "9.22.0",
157158
"execa": "5.1.1",
158159
"form-data": "3.0.1",
159160
"fs-extra": "10.1.0",
@@ -184,10 +185,10 @@
184185
"turbo": "^2.3.3",
185186
"typescript": "5.7.3"
186187
},
187-
"packageManager": "pnpm@9.7.1",
188+
"packageManager": "pnpm@10.12.1",
188189
"engines": {
189190
"node": "^18.20.2 || >=20.9.0",
190-
"pnpm": "^9.7.0"
191+
"pnpm": "^10.12.1"
191192
},
192193
"pnpm": {
193194
"overrides": {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ export const renderListView = async (
274274
collectionSlug,
275275
columnState,
276276
disableBulkDelete,
277-
disableBulkEdit,
277+
disableBulkEdit: collectionConfig.disableBulkEdit ?? disableBulkEdit,
278278
disableQueryPresets,
279279
enableRowSelections,
280280
hasCreatePermission,

packages/payload/src/collections/config/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,10 @@ export type CollectionConfig<TSlug extends CollectionSlug = any> = {
440440
* Default field to sort by in collection list view
441441
*/
442442
defaultSort?: Sort
443+
/**
444+
* Disable the bulk edit operation for the collection in the admin panel and the API
445+
*/
446+
disableBulkEdit?: boolean
443447
/**
444448
* When true, do not show the "Duplicate" button while editing documents within this collection and prevent `duplicate` from all APIs
445449
*/

packages/payload/src/collections/operations/update.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {
1515
import executeAccess from '../../auth/executeAccess.js'
1616
import { combineQueries } from '../../database/combineQueries.js'
1717
import { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths.js'
18-
import { APIError } from '../../errors/index.js'
18+
import { APIError, Forbidden } from '../../errors/index.js'
1919
import { type CollectionSlug, deepCopyObjectSimple } from '../../index.js'
2020
import { generateFileData } from '../../uploads/generateFileData.js'
2121
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'
@@ -63,6 +63,10 @@ export const updateOperation = async <
6363
): Promise<BulkOperationResult<TSlug, TSelect>> => {
6464
let args = incomingArgs
6565

66+
if (args.collection.config.disableBulkEdit && !args.overrideAccess) {
67+
throw new APIError(`Collection ${args.collection.config.slug} has disabled bulk edit`, 403)
68+
}
69+
6670
try {
6771
const shouldCommit = !args.disableTransaction && (await initTransaction(args.req))
6872

packages/richtext-lexical/src/features/blockquote/server/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const BlockquoteFeature = createServerFeature({
5353
})
5454
const style = [
5555
node.format ? `text-align: ${node.format};` : '',
56-
node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '',
56+
node.indent > 0 ? `padding-inline-start: ${Number(node.indent) * 2}rem;` : '',
5757
]
5858
.filter(Boolean)
5959
.join(' ')

packages/richtext-lexical/src/features/converters/lexicalToHtml/shared/findConverterForNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function findConverterForNode<
8383

8484
if (!disableIndent && (!Array.isArray(disableIndent) || !disableIndent?.includes(node.type))) {
8585
if ('indent' in node && node.indent && node.type !== 'listitem') {
86-
style['padding-inline-start'] = `${Number(node.indent) * 2}em`
86+
style['padding-inline-start'] = `${Number(node.indent) * 2}rem`
8787
}
8888
}
8989

packages/richtext-lexical/src/features/converters/lexicalToHtml_deprecated/converter/converters/paragraph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const ParagraphHTMLConverter: HTMLConverter<SerializedParagraphNode> = {
3131
})
3232
const style = [
3333
node.format ? `text-align: ${node.format};` : '',
34-
node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '',
34+
node.indent > 0 ? `padding-inline-start: ${Number(node.indent) * 2}rem;` : '',
3535
]
3636
.filter(Boolean)
3737
.join(' ')

packages/richtext-lexical/src/features/heading/server/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const HeadingFeature = createServerFeature<
7171
})
7272
const style = [
7373
node.format ? `text-align: ${node.format};` : '',
74-
node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '',
74+
node.indent > 0 ? `padding-inline-start: ${Number(node.indent) * 2}rem;` : '',
7575
]
7676
.filter(Boolean)
7777
.join(' ')

packages/ui/src/views/CollectionFolder/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ function CollectionFolderViewInContext(props: CollectionFolderViewInContextProps
264264
!smallBreak && (
265265
<ListSelection
266266
disableBulkDelete={disableBulkDelete}
267-
disableBulkEdit={disableBulkEdit}
267+
disableBulkEdit={collectionConfig.disableBulkEdit ?? disableBulkEdit}
268268
key="list-selection"
269269
/>
270270
),

pnpm-lock.yaml

Lines changed: 10 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ packages:
55
- 'test'
66
# exclude packages that are inside test directories
77
# - '!**/test/**'
8+
9+
# Allow all build scripts
10+
neverBuiltDependencies: []
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { CollectionConfig } from 'payload'
2+
3+
export const DisableBulkEdit: CollectionConfig = {
4+
slug: 'disable-bulk-edit',
5+
fields: [],
6+
disableBulkEdit: true,
7+
}

test/admin/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import { fileURLToPath } from 'node:url'
32
import path from 'path'
43

@@ -8,6 +7,7 @@ import { BaseListFilter } from './collections/BaseListFilter.js'
87
import { CustomFields } from './collections/CustomFields/index.js'
98
import { CustomViews1 } from './collections/CustomViews1.js'
109
import { CustomViews2 } from './collections/CustomViews2.js'
10+
import { DisableBulkEdit } from './collections/DisableBulkEdit.js'
1111
import { DisableCopyToLocale } from './collections/DisableCopyToLocale.js'
1212
import { DisableDuplicate } from './collections/DisableDuplicate.js'
1313
import { EditMenuItems } from './collections/editMenuItems.js'
@@ -183,6 +183,7 @@ export default buildConfigWithDefaults({
183183
Placeholder,
184184
ViewConditions,
185185
UseAsTitleGroupField,
186+
DisableBulkEdit,
186187
],
187188
globals: [
188189
GlobalHidden,

test/admin/e2e/list-view/e2e.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('List View', () => {
6666
let with300DocumentsUrl: AdminUrlUtil
6767
let withListViewUrl: AdminUrlUtil
6868
let placeholderUrl: AdminUrlUtil
69+
let disableBulkEditUrl: AdminUrlUtil
6970
let user: any
7071

7172
let serverURL: string
@@ -90,6 +91,7 @@ describe('List View', () => {
9091
customViewsUrl = new AdminUrlUtil(serverURL, customViews1CollectionSlug)
9192
withListViewUrl = new AdminUrlUtil(serverURL, listDrawerSlug)
9293
placeholderUrl = new AdminUrlUtil(serverURL, placeholderCollectionSlug)
94+
disableBulkEditUrl = new AdminUrlUtil(serverURL, 'disable-bulk-edit')
9395
const context = await browser.newContext()
9496
page = await context.newPage()
9597
initPageConsoleErrorCatch(page)
@@ -1302,6 +1304,16 @@ describe('List View', () => {
13021304
await page.locator('#confirm-delete-many-docs #confirm-action').click()
13031305
await expect(page.locator('.cell-_select')).toHaveCount(1)
13041306
})
1307+
1308+
test('should hide edit many from collection with disableBulkEdit: true', async () => {
1309+
await payload.create({ collection: 'disable-bulk-edit', data: {} })
1310+
await page.goto(disableBulkEditUrl.list)
1311+
1312+
// select one row
1313+
await page.locator('.row-1 .cell-_select input').check()
1314+
// ensure the edit many button is hidden
1315+
await expect(page.locator('.edit-many button')).toBeHidden()
1316+
})
13051317
})
13061318

13071319
describe('pagination', () => {

test/admin/payload-types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export interface Config {
9393
placeholder: Placeholder;
9494
'view-conditions': ViewCondition;
9595
'use-as-title-group-field': UseAsTitleGroupField;
96+
'disable-bulk-edit': DisableBulkEdit;
9697
'payload-locked-documents': PayloadLockedDocument;
9798
'payload-preferences': PayloadPreference;
9899
'payload-migrations': PayloadMigration;
@@ -125,6 +126,7 @@ export interface Config {
125126
placeholder: PlaceholderSelect<false> | PlaceholderSelect<true>;
126127
'view-conditions': ViewConditionsSelect<false> | ViewConditionsSelect<true>;
127128
'use-as-title-group-field': UseAsTitleGroupFieldSelect<false> | UseAsTitleGroupFieldSelect<true>;
129+
'disable-bulk-edit': DisableBulkEditSelect<false> | DisableBulkEditSelect<true>;
128130
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
129131
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
130132
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
@@ -562,6 +564,15 @@ export interface UseAsTitleGroupField {
562564
updatedAt: string;
563565
createdAt: string;
564566
}
567+
/**
568+
* This interface was referenced by `Config`'s JSON-Schema
569+
* via the `definition` "disable-bulk-edit".
570+
*/
571+
export interface DisableBulkEdit {
572+
id: string;
573+
updatedAt: string;
574+
createdAt: string;
575+
}
565576
/**
566577
* This interface was referenced by `Config`'s JSON-Schema
567578
* via the `definition` "payload-locked-documents".
@@ -672,6 +683,10 @@ export interface PayloadLockedDocument {
672683
| ({
673684
relationTo: 'use-as-title-group-field';
674685
value: string | UseAsTitleGroupField;
686+
} | null)
687+
| ({
688+
relationTo: 'disable-bulk-edit';
689+
value: string | DisableBulkEdit;
675690
} | null);
676691
globalSlug?: string | null;
677692
user: {
@@ -1066,6 +1081,14 @@ export interface UseAsTitleGroupFieldSelect<T extends boolean = true> {
10661081
updatedAt?: T;
10671082
createdAt?: T;
10681083
}
1084+
/**
1085+
* This interface was referenced by `Config`'s JSON-Schema
1086+
* via the `definition` "disable-bulk-edit_select".
1087+
*/
1088+
export interface DisableBulkEditSelect<T extends boolean = true> {
1089+
updatedAt?: T;
1090+
createdAt?: T;
1091+
}
10691092
/**
10701093
* This interface was referenced by `Config`'s JSON-Schema
10711094
* via the `definition` "payload-locked-documents_select".

test/collections-rest/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ export default buildConfigWithDefaults({
270270
path: `/${method}-test`,
271271
})),
272272
},
273+
{
274+
slug: 'disabled-bulk-edit-docs',
275+
fields: [
276+
{
277+
name: 'text',
278+
type: 'text',
279+
},
280+
],
281+
disableBulkEdit: true,
282+
},
273283
],
274284
endpoints: [
275285
{

0 commit comments

Comments
 (0)