feat: adds experimental.allLocaleStatus flag to add new group status field
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
import { authCollectionEndpoints } from '../../auth/endpoints/index.js'
|
||||
import { getBaseAuthFields } from '../../auth/getAuthFields.js'
|
||||
import { TimestampsRequired } from '../../errors/TimestampsRequired.js'
|
||||
import { baseAllLocaleStatusField } from '../../fields/baseFields/baseAllLocaleStatusField.js'
|
||||
import { sanitizeFields } from '../../fields/config/sanitize.js'
|
||||
import { fieldAffectsData } from '../../fields/config/types.js'
|
||||
import { mergeBaseFields } from '../../fields/mergeBaseFields.js'
|
||||
@@ -256,6 +257,10 @@ export const sanitizeCollection = async (
|
||||
sanitized.fields = mergeBaseFields(sanitized.fields, getBaseAuthFields(sanitized.auth))
|
||||
}
|
||||
|
||||
if (config.experimental?.allLocaleStatus) {
|
||||
sanitized.fields = mergeBaseFields(sanitized.fields, baseAllLocaleStatusField)
|
||||
}
|
||||
|
||||
if (collection?.admin?.pagination?.limits?.length) {
|
||||
sanitized.admin!.pagination!.limits = collection.admin.pagination.limits
|
||||
}
|
||||
|
||||
@@ -158,6 +158,21 @@ export const createClientConfig = ({
|
||||
|
||||
break
|
||||
|
||||
case 'experiental':
|
||||
if (config.experimental) {
|
||||
if (!clientConfig.experimental) {
|
||||
clientConfig.experimental = {}
|
||||
}
|
||||
if (config.experimental?.localizeStatus) {
|
||||
clientConfig.experimental.localizeStatus = config.experimental.localizeStatus
|
||||
}
|
||||
if (config.experimental?.allLocaleStatus) {
|
||||
clientConfig.experimental.allLocaleStatus = config.experimental.allLocaleStatus
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
case 'folders':
|
||||
if (config.folders) {
|
||||
clientConfig.folders = {
|
||||
@@ -193,13 +208,6 @@ export const createClientConfig = ({
|
||||
config.localization.defaultLocalePublishOption
|
||||
}
|
||||
|
||||
if (config.experimental?.localizeStatus) {
|
||||
if (!clientConfig.experimental) {
|
||||
clientConfig.experimental = {}
|
||||
}
|
||||
clientConfig.experimental.localizeStatus = config.experimental.localizeStatus
|
||||
}
|
||||
|
||||
if (config.localization.fallback) {
|
||||
clientConfig.localization.fallback = config.localization.fallback
|
||||
}
|
||||
|
||||
@@ -725,6 +725,15 @@ export type ImportMapGenerators = Array<
|
||||
* These may be unstable and may change or be removed in future releases.
|
||||
*/
|
||||
export type ExperimentalConfig = {
|
||||
/**
|
||||
* Adds `_allLocaleStatus` group field which maintains the statuses of all locales.
|
||||
* @default false
|
||||
*/
|
||||
allLocaleStatus?: boolean
|
||||
/**
|
||||
* Returns status of the current locale instead of overall document.
|
||||
* @default false
|
||||
*/
|
||||
localizeStatus?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Field } from '../config/types.js'
|
||||
|
||||
export const baseAllLocaleStatusField: Field[] = [
|
||||
{
|
||||
name: '_allLocaleStatus',
|
||||
type: 'json',
|
||||
admin: {
|
||||
components: {
|
||||
Cell: '@payloadcms/ui/rsc#AllLocaleStatusCell',
|
||||
},
|
||||
hidden: true,
|
||||
},
|
||||
hooks: {
|
||||
afterRead: [
|
||||
async (args) => {
|
||||
const { collection, data, req } = args
|
||||
const id = data?.id
|
||||
if (id && collection && collection.versions) {
|
||||
const version = await req.payload.findVersions({
|
||||
collection: collection.slug,
|
||||
limit: 1,
|
||||
where: {
|
||||
parent: {
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (version.docs && version.docs[0]?.localeStatus) {
|
||||
return version.docs[0].localeStatus
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
label: 'Status - All Locales',
|
||||
},
|
||||
]
|
||||
@@ -63,7 +63,7 @@ export const buildVersionCollectionFields = <T extends boolean = false>(
|
||||
}),
|
||||
})
|
||||
|
||||
if (config.experimental?.localizeStatus) {
|
||||
if (config.experimental?.localizeStatus || config.experimental?.allLocaleStatus) {
|
||||
const localeStatusFields = buildLocaleStatusField(config)
|
||||
|
||||
fields.push({
|
||||
|
||||
@@ -57,7 +57,7 @@ export const buildVersionGlobalFields = <T extends boolean = false>(
|
||||
}),
|
||||
})
|
||||
|
||||
if (config.experimental.localizeStatus) {
|
||||
if (config.experimental.localizeStatus || config.experimental?.allLocaleStatus) {
|
||||
const localeStatusFields = buildLocaleStatusField(config)
|
||||
|
||||
fields.push({
|
||||
|
||||
@@ -137,7 +137,8 @@ export const saveVersion = async ({
|
||||
if (
|
||||
localizationEnabled &&
|
||||
payload.config.localization !== false &&
|
||||
payload.config.experimental?.localizeStatus
|
||||
(payload.config.experimental?.localizeStatus ||
|
||||
payload.config.experimental?.allLocaleStatus)
|
||||
) {
|
||||
const allLocales = (
|
||||
(payload.config.localization && payload.config.localization?.locales) ||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
'use client'
|
||||
|
||||
import type { Data } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
import { Pill } from '../../Pill/index.js'
|
||||
import './index.scss'
|
||||
|
||||
type Props = {
|
||||
readonly availableLocales: string[]
|
||||
readonly data: Data
|
||||
}
|
||||
|
||||
const baseClass = 'locale-status-cell'
|
||||
|
||||
export const AllLocaleStatusCellClient = ({ availableLocales, data }: Props) => {
|
||||
const localesToRender = Object.fromEntries(
|
||||
Object.entries(data).filter(([key]) => availableLocales.includes(key))
|
||||
)
|
||||
|
||||
if (Object.keys(localesToRender).length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
{Object.entries(localesToRender).map(([locale, status]) => (
|
||||
<Pill key={locale} pillStyle={status === 'published' ? 'success' : 'light-gray'} size="small">
|
||||
{locale}
|
||||
</Pill>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
@layer payload-default {
|
||||
.locale-status-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: calc(var(--base) / 2);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createLocalReq, type DefaultServerCellComponentProps } from 'payload'
|
||||
import React from 'react'
|
||||
|
||||
import { AllLocaleStatusCellClient } from './index.client.js'
|
||||
|
||||
export const AllLocaleStatusCell = async ({ cellData, payload }: DefaultServerCellComponentProps) => {
|
||||
const { localization } = payload.config
|
||||
const req = await createLocalReq({}, payload)
|
||||
|
||||
let availableLocales: string[] = []
|
||||
|
||||
|
||||
if (localization) {
|
||||
const filtered =
|
||||
(await localization.filterAvailableLocales?.({
|
||||
locales: localization.locales,
|
||||
req,
|
||||
})) ?? localization.locales
|
||||
|
||||
availableLocales = filtered.map((locale) => locale.code)
|
||||
}
|
||||
|
||||
return (
|
||||
<AllLocaleStatusCellClient
|
||||
availableLocales={availableLocales}
|
||||
data={cellData}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ export { FieldDiffLabel } from '../../elements/FieldDiffLabel/index.js'
|
||||
export { FolderTableCell } from '../../elements/FolderView/Cell/index.server.js'
|
||||
export { FolderField } from '../../elements/FolderView/FolderField/index.server.js'
|
||||
export { getHTMLDiffComponents } from '../../elements/HTMLDiff/index.js'
|
||||
export { AllLocaleStatusCell } from '../../elements/Status/AllLocaleStatusCell/index.server.js'
|
||||
export { File } from '../../graphics/File/index.js'
|
||||
export { CheckIcon } from '../../icons/Check/index.js'
|
||||
export { copyDataFromLocaleHandler } from '../../utilities/copyDataFromLocale.js'
|
||||
|
||||
@@ -430,6 +430,7 @@ export default buildConfigWithDefaults({
|
||||
],
|
||||
experimental: {
|
||||
localizeStatus: true,
|
||||
allLocaleStatus: true,
|
||||
},
|
||||
localization: {
|
||||
filterAvailableLocales: ({ locales }) => {
|
||||
|
||||
Reference in New Issue
Block a user