Skip to content

Commit 657ad20

Browse files
authored
feat(ui): adds disable copy to locale option to collection config (#11546)
### What? Adds new option to disable the `copy to locale` button, adds description to docs and adds e2e test. ### Why? Client request. ### How? The option can be used like this: ```ts // in collection config admin: { disableCopyToLocale: true, }, ```
1 parent 30af889 commit 657ad20

File tree

8 files changed

+65
-1
lines changed

8 files changed

+65
-1
lines changed

docs/configuration/collections.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ The following options are available:
121121
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin Panel. If no field is defined, the ID of the document is used as the title. A field with `virtual: true` cannot be used as the title. |
122122
| `description` | Text to display below the Collection label in the List View to give editors more information. Alternatively, you can use the `admin.components.Description` to render a React component. [More details](#custom-components). |
123123
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this Collection's List View. |
124+
| `disableCopyToLocale` | Disables the "Copy to Locale" button while editing documents within this Collection. Only applicable when localization is enabled. |
124125
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this Collection. |
125126
| `enableRichTextLink` | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
126127
| `enableRichTextRelationship` | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,11 @@ export type CollectionAdminOptions = {
327327
* Custom description for collection. This will also be used as JSDoc for the generated types
328328
*/
329329
description?: EntityDescription
330+
/**
331+
* Disable the Copy To Locale button in the edit document view
332+
* @default false
333+
*/
334+
disableCopyToLocale?: boolean
330335
enableRichTextLink?: boolean
331336
enableRichTextRelationship?: boolean
332337
/**

packages/ui/src/elements/DocumentControls/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ export const DocumentControls: React.FC<{
137137
(collectionConfig?.versions?.drafts && collectionConfig?.versions?.drafts?.autosave) ||
138138
(globalConfig?.versions?.drafts && globalConfig?.versions?.drafts?.autosave)
139139

140+
const disableCopyToLocale = localization && collectionConfig?.admin?.disableCopyToLocale
141+
140142
return (
141143
<Gutter className={baseClass}>
142144
<div className={`${baseClass}__wrapper`}>
@@ -263,7 +265,7 @@ export const DocumentControls: React.FC<{
263265
verticalAlign="bottom"
264266
>
265267
<PopupList.ButtonGroup>
266-
{localization && <CopyLocaleData />}
268+
{!disableCopyToLocale && <CopyLocaleData />}
267269
{hasCreatePermission && (
268270
<React.Fragment>
269271
{!disableCreate && (
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { CollectionConfig } from 'payload'
2+
3+
import { disableCopyToLocale } from '../slugs.js'
4+
5+
export const DisableCopyToLocale: CollectionConfig = {
6+
slug: disableCopyToLocale,
7+
admin: {
8+
disableCopyToLocale: true,
9+
},
10+
fields: [
11+
{
12+
name: 'title',
13+
type: 'text',
14+
},
15+
],
16+
}

test/admin/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { BaseListFilter } from './collections/BaseListFilter.js'
77
import { CustomFields } from './collections/CustomFields/index.js'
88
import { CustomViews1 } from './collections/CustomViews1.js'
99
import { CustomViews2 } from './collections/CustomViews2.js'
10+
import { DisableCopyToLocale } from './collections/DisableCopyToLocale.js'
1011
import { DisableDuplicate } from './collections/DisableDuplicate.js'
1112
import { Geo } from './collections/Geo.js'
1213
import { CollectionGroup1A } from './collections/Group1A.js'
@@ -158,6 +159,7 @@ export default buildConfigWithDefaults({
158159
CollectionGroup2B,
159160
Geo,
160161
DisableDuplicate,
162+
DisableCopyToLocale,
161163
BaseListFilter,
162164
with300Documents,
163165
ListDrawer,

test/admin/e2e/general/e2e.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
} from '../../shared.js'
3434
import {
3535
customViews2CollectionSlug,
36+
disableCopyToLocale as disableCopyToLocaleSlug,
3637
disableDuplicateSlug,
3738
geoCollectionSlug,
3839
globalSlug,
@@ -71,6 +72,7 @@ describe('General', () => {
7172
let notInViewUrl: AdminUrlUtil
7273
let globalURL: AdminUrlUtil
7374
let customViewsURL: AdminUrlUtil
75+
let disableCopyToLocale: AdminUrlUtil
7476
let disableDuplicateURL: AdminUrlUtil
7577
let serverURL: string
7678
let adminRoutes: ReturnType<typeof getRoutes>
@@ -91,6 +93,7 @@ describe('General', () => {
9193
notInViewUrl = new AdminUrlUtil(serverURL, notInViewCollectionSlug)
9294
globalURL = new AdminUrlUtil(serverURL, globalSlug)
9395
customViewsURL = new AdminUrlUtil(serverURL, customViews2CollectionSlug)
96+
disableCopyToLocale = new AdminUrlUtil(serverURL, disableCopyToLocaleSlug)
9497
disableDuplicateURL = new AdminUrlUtil(serverURL, disableDuplicateSlug)
9598
uploadsTwo = new AdminUrlUtil(serverURL, uploadTwoCollectionSlug)
9699

@@ -515,6 +518,14 @@ describe('General', () => {
515518
await page.goto(notInViewUrl.global('not-in-view-global'))
516519
await expect(page.locator('.render-title')).toContainText('Not In View Global')
517520
})
521+
522+
test('should hide Copy To Locale button when disableCopyToLocale: true', async () => {
523+
await page.goto(disableCopyToLocale.create)
524+
await page.locator('#field-title').fill(title)
525+
await saveDocAndAssert(page)
526+
await page.locator('.doc-controls__popup >> .popup-button').click()
527+
await expect(page.locator('#copy-locale-data__button')).toBeHidden()
528+
})
518529
})
519530

520531
describe('custom CSS', () => {

test/admin/payload-types.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export interface Config {
6464
auth: {
6565
users: UserAuthOperations;
6666
};
67+
blocks: {};
6768
collections: {
6869
uploads: Upload;
6970
'uploads-two': UploadsTwo;
@@ -81,6 +82,7 @@ export interface Config {
8182
'group-two-collection-twos': GroupTwoCollectionTwo;
8283
geo: Geo;
8384
'disable-duplicate': DisableDuplicate;
85+
'disable-copy-to-locale': DisableCopyToLocale;
8486
'base-list-filters': BaseListFilter;
8587
with300documents: With300Document;
8688
'with-list-drawer': WithListDrawer;
@@ -106,6 +108,7 @@ export interface Config {
106108
'group-two-collection-twos': GroupTwoCollectionTwosSelect<false> | GroupTwoCollectionTwosSelect<true>;
107109
geo: GeoSelect<false> | GeoSelect<true>;
108110
'disable-duplicate': DisableDuplicateSelect<false> | DisableDuplicateSelect<true>;
111+
'disable-copy-to-locale': DisableCopyToLocaleSelect<false> | DisableCopyToLocaleSelect<true>;
109112
'base-list-filters': BaseListFiltersSelect<false> | BaseListFiltersSelect<true>;
110113
with300documents: With300DocumentsSelect<false> | With300DocumentsSelect<true>;
111114
'with-list-drawer': WithListDrawerSelect<false> | WithListDrawerSelect<true>;
@@ -446,6 +449,16 @@ export interface DisableDuplicate {
446449
updatedAt: string;
447450
createdAt: string;
448451
}
452+
/**
453+
* This interface was referenced by `Config`'s JSON-Schema
454+
* via the `definition` "disable-copy-to-locale".
455+
*/
456+
export interface DisableCopyToLocale {
457+
id: string;
458+
title?: string | null;
459+
updatedAt: string;
460+
createdAt: string;
461+
}
449462
/**
450463
* This interface was referenced by `Config`'s JSON-Schema
451464
* via the `definition` "base-list-filters".
@@ -550,6 +563,10 @@ export interface PayloadLockedDocument {
550563
relationTo: 'disable-duplicate';
551564
value: string | DisableDuplicate;
552565
} | null)
566+
| ({
567+
relationTo: 'disable-copy-to-locale';
568+
value: string | DisableCopyToLocale;
569+
} | null)
553570
| ({
554571
relationTo: 'base-list-filters';
555572
value: string | BaseListFilter;
@@ -863,6 +880,15 @@ export interface DisableDuplicateSelect<T extends boolean = true> {
863880
updatedAt?: T;
864881
createdAt?: T;
865882
}
883+
/**
884+
* This interface was referenced by `Config`'s JSON-Schema
885+
* via the `definition` "disable-copy-to-locale_select".
886+
*/
887+
export interface DisableCopyToLocaleSelect<T extends boolean = true> {
888+
title?: T;
889+
updatedAt?: T;
890+
createdAt?: T;
891+
}
866892
/**
867893
* This interface was referenced by `Config`'s JSON-Schema
868894
* via the `definition` "base-list-filters_select".

test/admin/slugs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const hiddenCollectionSlug = 'hidden-collection'
1111
export const notInViewCollectionSlug = 'not-in-view-collection'
1212
export const noApiViewCollectionSlug = 'collection-no-api-view'
1313
export const disableDuplicateSlug = 'disable-duplicate'
14+
export const disableCopyToLocale = 'disable-copy-to-locale'
1415
export const uploadCollectionSlug = 'uploads'
1516

1617
export const uploadTwoCollectionSlug = 'uploads-two'

0 commit comments

Comments
 (0)