fix(ui): should not show publish specific locale button when no localized fields exist (#13459)
### What? Hides the `Publish in [specific locale]` button on collections and globals when no localized fields are present. ### Why? Currently, the `Publish in [specific locale]` shows on every collection/global as long as `localization` is enabled in the Payload config, however this is not necessary when the collection/global has no localized fields. ### How? Checks that localized fields exist prior to rendering the `Publish in [specific locale]` button. Fixes #13447 --------- Co-authored-by: German Jablonski <43938777+GermanJablo@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import type { PublishButtonClientProps } from 'payload'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import * as qs from 'qs-esm'
|
||||
import React, { useCallback } from 'react'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { useForm, useFormModified } from '../../forms/Form/context.js'
|
||||
import { FormSubmit } from '../../forms/Submit/index.js'
|
||||
@@ -15,6 +15,7 @@ import { useEditDepth } from '../../providers/EditDepth/index.js'
|
||||
import { useLocale } from '../../providers/Locale/index.js'
|
||||
import { useOperation } from '../../providers/Operation/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { traverseForLocalizedFields } from '../../utilities/traverseForLocalizedFields.js'
|
||||
import { PopupList } from '../Popup/index.js'
|
||||
import { ScheduleDrawer } from './ScheduleDrawer/index.js'
|
||||
|
||||
@@ -86,6 +87,15 @@ export function PublishButton({ label: labelProp }: PublishButtonClientProps) {
|
||||
(hasAutosave || !modified),
|
||||
)
|
||||
|
||||
const [hasLocalizedFields, setHasLocalizedFields] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const hasLocalizedField = traverseForLocalizedFields(entityConfig?.fields)
|
||||
setHasLocalizedFields(hasLocalizedField)
|
||||
}, [entityConfig?.fields])
|
||||
|
||||
const canPublishSpecificLocale = localization && hasLocalizedFields && hasPublishPermission
|
||||
|
||||
const operation = useOperation()
|
||||
|
||||
const disabled = operation === 'update' && !modified
|
||||
@@ -213,7 +223,7 @@ export function PublishButton({ label: labelProp }: PublishButtonClientProps) {
|
||||
onClick={defaultPublish}
|
||||
size="medium"
|
||||
SubMenuPopupContent={
|
||||
localization || canSchedulePublish
|
||||
canPublishSpecificLocale || canSchedulePublish
|
||||
? ({ close }) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -227,7 +237,7 @@ export function PublishButton({ label: labelProp }: PublishButtonClientProps) {
|
||||
</PopupList.Button>
|
||||
</PopupList.ButtonGroup>
|
||||
)}
|
||||
{localization && canPublish && (
|
||||
{canPublishSpecificLocale && (
|
||||
<PopupList.ButtonGroup>
|
||||
<PopupList.Button id="publish-locale" onClick={secondaryPublish}>
|
||||
{secondaryLabel}
|
||||
|
||||
45
packages/ui/src/utilities/traverseForLocalizedFields.ts
Normal file
45
packages/ui/src/utilities/traverseForLocalizedFields.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { ClientField } from 'payload'
|
||||
|
||||
export const traverseForLocalizedFields = (fields: ClientField[]): boolean => {
|
||||
for (const field of fields) {
|
||||
if ('localized' in field && field.localized) {
|
||||
return true
|
||||
}
|
||||
|
||||
switch (field.type) {
|
||||
case 'array':
|
||||
case 'collapsible':
|
||||
case 'group':
|
||||
case 'row':
|
||||
if (field.fields && traverseForLocalizedFields(field.fields)) {
|
||||
return true
|
||||
}
|
||||
break
|
||||
|
||||
case 'blocks':
|
||||
if (field.blocks) {
|
||||
for (const block of field.blocks) {
|
||||
if (block.fields && traverseForLocalizedFields(block.fields)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case 'tabs':
|
||||
if (field.tabs) {
|
||||
for (const tab of field.tabs) {
|
||||
if ('localized' in tab && tab.localized) {
|
||||
return true
|
||||
}
|
||||
if ('fields' in tab && tab.fields && traverseForLocalizedFields(tab.fields)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -4,6 +4,9 @@ export const noLocalizedFieldsCollectionSlug = 'no-localized-fields'
|
||||
|
||||
export const NoLocalizedFieldsCollection: CollectionConfig = {
|
||||
slug: noLocalizedFieldsCollectionSlug,
|
||||
versions: {
|
||||
drafts: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
|
||||
@@ -29,6 +29,7 @@ import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { arrayCollectionSlug } from './collections/Array/index.js'
|
||||
import { nestedToArrayAndBlockCollectionSlug } from './collections/NestedToArrayAndBlock/index.js'
|
||||
import { noLocalizedFieldsCollectionSlug } from './collections/NoLocalizedFields/index.js'
|
||||
import { richTextSlug } from './collections/RichText/index.js'
|
||||
import {
|
||||
arrayWithFallbackCollectionSlug,
|
||||
@@ -61,6 +62,7 @@ let urlCannotCreateDefaultLocale: AdminUrlUtil
|
||||
let urlPostsWithDrafts: AdminUrlUtil
|
||||
let urlArray: AdminUrlUtil
|
||||
let arrayWithFallbackURL: AdminUrlUtil
|
||||
let noLocalizedFieldsURL: AdminUrlUtil
|
||||
|
||||
const title = 'english title'
|
||||
const spanishTitle = 'spanish title'
|
||||
@@ -87,6 +89,7 @@ describe('Localization', () => {
|
||||
urlPostsWithDrafts = new AdminUrlUtil(serverURL, localizedDraftsSlug)
|
||||
urlArray = new AdminUrlUtil(serverURL, arrayCollectionSlug)
|
||||
arrayWithFallbackURL = new AdminUrlUtil(serverURL, arrayWithFallbackCollectionSlug)
|
||||
noLocalizedFieldsURL = new AdminUrlUtil(serverURL, noLocalizedFieldsCollectionSlug)
|
||||
|
||||
context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
@@ -671,6 +674,13 @@ describe('Localization', () => {
|
||||
await expect(page.locator('#field-title')).toBeEmpty()
|
||||
})
|
||||
})
|
||||
|
||||
test('should not show publish specific locale button when no localized fields exist', async () => {
|
||||
await page.goto(urlPostsWithDrafts.create)
|
||||
await expect(page.locator('#publish-locale')).toHaveCount(1)
|
||||
await page.goto(noLocalizedFieldsURL.create)
|
||||
await expect(page.locator('#publish-locale')).toHaveCount(0)
|
||||
})
|
||||
})
|
||||
|
||||
async function createLocalizedArrayItem(page: Page, url: AdminUrlUtil) {
|
||||
|
||||
Reference in New Issue
Block a user