Compare commits

...

13 Commits

Author SHA1 Message Date
Jessica Chowdhury
ae0dcfd921 chore: remove outdated test 2025-09-05 12:22:48 +01:00
Jessica Chowdhury
526e1f5dc5 chore: amend e2e test 2025-09-05 12:08:26 +01:00
Jessica Chowdhury
575f0e5c5e chore: update unpublish endpoint logic 2025-09-04 16:05:23 +01:00
Jessica Chowdhury
deac5e19f9 chore: adds translations 2025-09-04 12:28:51 +01:00
Jessica Chowdhury
c576c47200 Merge branch 'main' into feat/localized-unpublish 2025-09-04 12:20:15 +01:00
Jessica Chowdhury
90d6d6101c feat: adds experimental.unpublishSpecificLocale 2025-09-04 11:40:17 +01:00
Patrik
5146fc865f fix(ui): undefined permissions passed in create-first-user view (#13671)
### What?

In the create-first-user view, fields like `richText` were being marked
as `readOnly: true` because they had no permissions entry in the
permissions map.

### Why?

The view was passing an incomplete `docPermissions` object. 

When a field had no entry in `docPermissions.fields`, `renderField`
received `permissions: undefined`, which was interpreted as denied
access.

This caused fields (notably `richText`) to default to read-only even
though the user should have full access when creating the first user.

### How?

- Updated the create-first-user view to always pass a complete
`docPermissions` object.
- Default all fields in the user collection to `{ create: true, read:
true, update: true }`.
- Ensures every field is explicitly granted full access during the
first-user flow.
- Keeps the `renderField` logic unchanged and aligned with Payload’s
permission model.

Fixes #13612 

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211211792037939
2025-09-03 14:16:49 -07:00
Jarrod Flesch
d9e183242c fix: update user session on reset (#13667)
Fixes https://github.com/payloadcms/payload/issues/13637

Adds session logic to password reset so the user is logged in after
resetting the password, similar to how it works when useSessions is
false.
2025-09-03 17:00:02 -04:00
Aapo Laakkio
7794541af3 fix(ui): don't populate on auto save (#13649)
Edited by @jacobsfletch

Autosave is run with default depth, causing form state and the document
info context to be inconsistent across the load/autosave/save lifecycle.

For example, when loading the app, the document is queried with `depth:
0` and relationships are _not_ populated. Same with save/draft/publish.
Autosave, on the other hand, populates these relationships, causing the
data to temporarily change in shape in between these events.

Here's an example:


https://github.com/user-attachments/assets/153ea112-7591-4f54-9216-575322f4edbe

Now, autosave runs with `depth: 0` as expected, consistent with the
other events of the document lifecycle.

**Plus this is a huge performance improvement.**

Fixes #13643 and #13192.

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211224908421570

---------

Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
2025-09-03 16:59:36 -04:00
German Jablonski
1a1696d9ae feat(richtext-lexical): upgrade lexical from 0.28.0 to 0.34.0 (#13622)
Fixes #13386

Below I write a clarification to copy and paste into the release note,
based on our latest upgrade of Lexical [in
v3.29.0](https://github.com/payloadcms/payload/releases/tag/v3.29.0).

## Important
This release upgrades the lexical dependency from 0.28.0 to 0.34.0.

If you installed lexical manually, update it to 0.34.0. Installing
lexical manually is not recommended, as it may break between updates,
and our re-exported versions should be used. See the [yellow banner
box](https://payloadcms.com/docs/rich-text/custom-features) for details.

If you still encounter richtext-lexical errors, do the following, in
this order:

- Delete node_modules
- Delete your lockfile (e.g. pnpm-lock.json)
- Reinstall your dependencies (e.g. pnpm install)

### Lexical Breaking Changes

The following Lexical releases describe breaking changes. We recommend
reading them if you're using Lexical APIs directly
(`@payloadcms/richtext-lexical/lexical/*`).

- [v.0.33.0](https://github.com/facebook/lexical/releases/tag/v0.33.0)
- [v.0.30.0](https://github.com/facebook/lexical/releases/tag/v0.30.0)
- [v.0.29.0](https://github.com/facebook/lexical/releases/tag/v0.29.0)

___

TODO:
- [x] https://github.com/facebook/lexical/pull/7719
- [x] https://github.com/facebook/lexical/pull/7362
- [x] https://github.com/facebook/lexical/pull/7707
- [x] https://github.com/facebook/lexical/pull/7388
- [x] https://github.com/facebook/lexical/pull/7357
- [x] https://github.com/facebook/lexical/pull/7352
- [x] https://github.com/facebook/lexical/pull/7472
- [x] https://github.com/facebook/lexical/pull/7556
- [x] https://github.com/facebook/lexical/pull/7417
- [x] https://github.com/facebook/lexical/pull/1036
- [x] https://github.com/facebook/lexical/pull/7509
- [x] https://github.com/facebook/lexical/pull/7693
- [x] https://github.com/facebook/lexical/pull/7408
- [x] https://github.com/facebook/lexical/pull/7450
- [x] https://github.com/facebook/lexical/pull/7415
- [x] https://github.com/facebook/lexical/pull/7368
- [x] https://github.com/facebook/lexical/pull/7372
- [x] https://github.com/facebook/lexical/pull/7572
- [x] https://github.com/facebook/lexical/pull/7558
- [x] https://github.com/facebook/lexical/pull/7613
- [x] https://github.com/facebook/lexical/pull/7405
- [x] https://github.com/facebook/lexical/pull/7420
- [x] https://github.com/facebook/lexical/pull/7662

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211202581885926
2025-09-03 18:49:10 +00:00
Jacob Fletcher
b8d7ccb4dc fix(ui): use consistent row ids when duplicating array and block rows (#13679)
Fixes #13653.

Duplicating array rows causes phantom rows to appear. This is because
when duplicate the row locally, we use inconsistent row IDs, e.g. the
`array.rows[0].id` does not match its `array.0.id` counterpart. This
causes form state to lose the reference to the existing row, which the
server interprets as new row as of #13551.

Before:


https://github.com/user-attachments/assets/9f7efc59-ebd9-4fbb-b643-c22d4d3140a3

After:


https://github.com/user-attachments/assets/188db823-4ee5-4757-8b89-751c8d978ad9

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211210023936585
2025-09-03 14:29:39 -04:00
Patrik
be47f65b7c fix: prevent enabling trash on folders (#13675)
### What?

This PR updates the folder configuration types to explicitly omit the
`trash` option from `CollectionConfig` when used for folders.

### Why?

Currently, only documents are designed to support trashing. Allowing
folders to be trashed introduces inconsistencies, since removing a
folder does not properly remove its references from associated
documents.

By omitting `trash` from folder configurations, we prevent accidental
use of unsupported behavior until proper design and handling for folder
trashing is implemented.

### How?

- Updated `RootFoldersConfiguration.collectionOverrides` type to use
`Omit<CollectionConfig, 'trash'>`
- Ensures `trash` cannot be enabled on folders
2025-09-03 11:04:48 -07:00
Jessica Rynkar
0f6d748365 feat: adds new experimental.localizeStatus option (#13207)
### What?
Adds a new `experimental.localizeStatus` config option, set to `false`
by default. When `true`, the admin panel will display the document
status based on the *current locale* instead of the _latest_ overall
status. Also updates the edit view to only show a `changed` status when
`autosave` is enabled.

### Why?
Showing the status for the current locale is more accurate and useful in
multi-locale setups. This update will become default behavior, able to
be opted in by setting `experimental.localizeStatus: true` in the
Payload config. This option will become depreciated in V4.

### How?
When `localizeStatus` is `true`, we store the localized status in a new
`localeStatus` field group within version data. The admin panel then
reads from this field to display the correct status for the current
locale.

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2025-09-03 10:27:08 +01:00
114 changed files with 1690 additions and 702 deletions

View File

@@ -131,6 +131,30 @@ localization: {
Since the filtering happens at the root level of the application and its result is not calculated every time you navigate to a new page, you may want to call `router.refresh` in a custom component that watches when values that affect the result change. In the example above, you would want to do this when `supportedLocales` changes on the tenant document.
## Experimental Options
Experimental options are features that may not be fully stable and may change or be removed in future releases.
These options can be enabled in your Payload Config under the `experimental` key. You can set them like this:
```ts
import { buildConfig } from 'payload'
export default buildConfig({
// ...
experimental: {
localizeStatus: true,
},
})
```
The following experimental options are available related to localization:
| Option | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`localizeStatus`** | **Boolean.** When `true`, shows document status per locale in the admin panel instead of always showing the latest overall status. Opt-in for backwards compatibility. Defaults to `false`. |
| **`unpublishSpecificLocale`** | **Boolean.** When `true`, allows unpublishing a document in a specific locale. Defaults to `false`. |
## Field Localization
Payload Localization works on a **field** level—not a document level. In addition to configuring the base Payload Config to support Localization, you need to specify each field that you would like to localize.

View File

@@ -70,6 +70,7 @@ The following options are available:
| **`admin`** | The configuration options for the Admin Panel, including Custom Components, Live Preview, etc. [More details](../admin/overview#admin-options). |
| **`bin`** | Register custom bin scripts for Payload to execute. [More Details](#custom-bin-scripts). |
| **`editor`** | The Rich Text Editor which will be used by `richText` fields. [More details](../rich-text/overview). |
| **`experimental`** | Configure experimental features for Payload. These may be unstable and may change or be removed in future releases. [More details](../experimental). |
| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). |
| **`serverURL`** | A string used to define the absolute URL of your app. This includes the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port. |
| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). |

View File

@@ -0,0 +1,67 @@
---
title: Experimental Features
label: Overview
order: 10
desc: Enable and configure experimental functionality within Payload. These featuresmay be unstable and may change or be removed without notice.
keywords: experimental, unstable, beta, preview, features, configuration, Payload, cms, headless, javascript, node, react, nextjs
---
Experimental features allow you to try out new functionality before it becomes a stable part of Payload. These features may still be in active development, may have incomplete functionality, and can change or be removed in future releases without warning.
## How It Works
Experimental features are configured via the root-level `experimental` property in your [Payload Config](../configuration/overview). This property contains individual feature flags, each flag can be configured independently, allowing you to selectively opt into specific functionality.
```ts
import { buildConfig } from 'payload'
const config = buildConfig({
// ...
experimental: {
localizeStatus: true, // highlight-line
},
})
```
## Experimental Options
The following options are available:
| Option | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`localizeStatus`** | **Boolean.** When `true`, shows document status per locale in the admin panel instead of always showing the latest overall status. Opt-in for backwards compatibility. Defaults to `false`. |
| **`unpublishSpecificLocale`** | **Boolean.** When `true`, allows unpublishing a document in a specific locale. Defaults to `false`. |
This list may change without notice.
## When to Use Experimental Features
You might enable an experimental feature when:
- You want early access to new capabilities before their stable release.
- You can accept the risks of using potentially unstable functionality.
- You are testing new features in a development or staging environment.
- You wish to provide feedback to the Payload team on new functionality.
If you are working on a production application, carefully evaluate whether the benefits outweigh the risks. For most stable applications, it is recommended to wait until the feature is officially released.
<Banner type="success">
<strong>Tip:</strong> To stay up to date on experimental features or share
your feedback, visit the{' '}
<a
href="https://github.com/payloadcms/payload/discussions"
target="_blank"
rel="noopener noreferrer"
>
Payload GitHub Discussions
</a>{' '}
or{' '}
<a
href="https://github.com/payloadcms/payload/issues"
target="_blank"
rel="noopener noreferrer"
>
open an issue
</a>
.
</Banner>

1
next-env.d.ts vendored
View File

@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -12,6 +12,7 @@ export const createGlobalVersion: CreateGlobalVersion = async function createGlo
autosave,
createdAt,
globalSlug,
localeStatus,
parent,
publishedLocale,
req,
@@ -33,6 +34,7 @@ export const createGlobalVersion: CreateGlobalVersion = async function createGlo
autosave,
createdAt,
latest: true,
localeStatus,
parent,
publishedLocale,
snapshot,

View File

@@ -12,6 +12,7 @@ export const createVersion: CreateVersion = async function createVersion(
autosave,
collectionSlug,
createdAt,
localeStatus,
parent,
publishedLocale,
req,
@@ -37,6 +38,7 @@ export const createVersion: CreateVersion = async function createVersion(
autosave,
createdAt,
latest: true,
localeStatus,
parent,
publishedLocale,
snapshot,

View File

@@ -179,6 +179,13 @@ export const queryDrafts: QueryDrafts = async function queryDrafts(
for (let i = 0; i < result.docs.length; i++) {
const id = result.docs[i].parent
const localeStatus = result.docs[i].localeStatus || {}
if (locale && localeStatus[locale]) {
result.docs[i].status = localeStatus[locale]
result.docs[i].version._status = localeStatus[locale]
}
result.docs[i] = result.docs[i].version ?? {}
result.docs[i].id = id
}

View File

@@ -15,6 +15,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
autosave,
createdAt,
globalSlug,
localeStatus,
publishedLocale,
req,
returning,
@@ -35,6 +36,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
autosave,
createdAt,
latest: true,
localeStatus,
publishedLocale,
snapshot,
updatedAt,

View File

@@ -15,6 +15,7 @@ export async function createVersion<T extends TypeWithID>(
autosave,
collectionSlug,
createdAt,
localeStatus,
parent,
publishedLocale,
req,
@@ -40,6 +41,7 @@ export async function createVersion<T extends TypeWithID>(
autosave,
createdAt,
latest: true,
localeStatus,
parent,
publishedLocale,
snapshot,

View File

@@ -36,15 +36,17 @@ export const queryDrafts: QueryDrafts = async function queryDrafts(
where: combinedWhere,
})
return {
...result,
docs: result.docs.map((doc) => {
doc = {
id: doc.parent,
...doc.version,
}
for (let i = 0; i < result.docs.length; i++) {
const id = result.docs[i].parent
const localeStatus = result.docs[i].localeStatus || {}
if (locale && localeStatus[locale]) {
result.docs[i].status = localeStatus[locale]
result.docs[i].version._status = localeStatus[locale]
}
return doc
}),
result.docs[i] = result.docs[i].version ?? {}
result.docs[i].id = id
}
return result
}

View File

@@ -1,11 +1,14 @@
import type { AdminViewServerProps } from 'payload'
import type {
AdminViewServerProps,
SanitizedDocumentPermissions,
SanitizedFieldsPermissions,
} from 'payload'
import { buildFormState } from '@payloadcms/ui/utilities/buildFormState'
import React from 'react'
import { getDocPreferences } from '../Document/getDocPreferences.js'
import { getDocumentData } from '../Document/getDocumentData.js'
import { getDocumentPermissions } from '../Document/getDocumentPermissions.js'
import { CreateFirstUserClient } from './index.client.js'
import './index.scss'
@@ -43,18 +46,27 @@ export async function CreateFirstUserView({ initPageResult }: AdminViewServerPro
user: req.user,
})
// Get permissions
const { docPermissions } = await getDocumentPermissions({
collectionConfig,
data,
req,
})
const baseFields: SanitizedFieldsPermissions = Object.fromEntries(
collectionConfig.fields
.filter((f): f is { name: string } & typeof f => 'name' in f && typeof f.name === 'string')
.map((f) => [f.name, { create: true, read: true, update: true }]),
)
// In create-first-user we should always allow all fields
const docPermissionsForForm: SanitizedDocumentPermissions = {
create: true,
delete: true,
fields: baseFields,
read: true,
readVersions: true,
update: true,
}
// Build initial form state from data
const { state: formState } = await buildFormState({
collectionSlug: collectionConfig.slug,
data,
docPermissions,
docPermissions: docPermissionsForForm,
docPreferences,
locale: locale?.code,
operation: 'create',
@@ -69,7 +81,7 @@ export async function CreateFirstUserView({ initPageResult }: AdminViewServerPro
<h1>{req.t('general:welcome')}</h1>
<p>{req.t('authentication:beginCreateFirstUser')}</p>
<CreateFirstUserClient
docPermissions={docPermissions}
docPermissions={docPermissionsForForm}
docPreferences={docPreferences}
initialState={formState}
loginWithUsername={loginWithUsername}

View File

@@ -19,6 +19,7 @@ type AutosaveCellProps = {
rowData: {
autosave?: boolean
id: number | string
localeStatus?: Record<string, 'draft' | 'published'>
publishedLocale?: string
version: {
_status: string

View File

@@ -81,22 +81,20 @@ export async function VersionsView(props: DocumentViewServerProps) {
}
const [currentlyPublishedVersion, latestDraftVersion] = await Promise.all([
hasPublishedDoc
? fetchLatestVersion({
collectionSlug,
depth: 0,
globalSlug,
overrideAccess: false,
parentID: id,
req,
select: {
id: true,
updatedAt: true,
},
status: 'published',
user,
})
: Promise.resolve(null),
fetchLatestVersion({
collectionSlug,
depth: 0,
globalSlug,
overrideAccess: false,
parentID: id,
req,
select: {
id: true,
updatedAt: true,
},
status: 'published',
user,
}),
draftsEnabled
? fetchLatestVersion({
collectionSlug,

View File

@@ -12,6 +12,7 @@ import { initTransaction } from '../../utilities/initTransaction.js'
import { killTransaction } from '../../utilities/killTransaction.js'
import { getFieldsToSign } from '../getFieldsToSign.js'
import { jwtSign } from '../jwt.js'
import { addSessionToUser } from '../sessions.js'
import { authenticateLocalStrategy } from '../strategies/local/authenticate.js'
import { generatePasswordSaltHash } from '../strategies/local/generatePasswordSaltHash.js'
@@ -143,12 +144,25 @@ export const resetPasswordOperation = async <TSlug extends CollectionSlug>(
await authenticateLocalStrategy({ doc, password: data.password })
const fieldsToSign = getFieldsToSign({
const fieldsToSignArgs: Parameters<typeof getFieldsToSign>[0] = {
collectionConfig,
email: user.email,
user,
}
const { sid } = await addSessionToUser({
collectionConfig,
payload,
req,
user,
})
if (sid) {
fieldsToSignArgs.sid = sid
}
const fieldsToSign = getFieldsToSign(fieldsToSignArgs)
const { token } = await jwtSign({
fieldsToSign,
secret,

View File

@@ -14,6 +14,7 @@ import { findVersionByIDHandler } from './findVersionByID.js'
import { findVersionsHandler } from './findVersions.js'
import { previewHandler } from './preview.js'
import { restoreVersionHandler } from './restoreVersion.js'
import { unpublishHandler } from './unpublish.js'
import { updateHandler } from './update.js'
import { updateByIDHandler } from './updateByID.js'
@@ -85,6 +86,11 @@ export const defaultCollectionEndpoints: Endpoint[] = [
method: 'post',
path: '/versions/:id',
},
{
handler: unpublishHandler,
method: 'post',
path: '/:id/unpublish',
},
{
handler: updateHandler,
method: 'patch',

View File

@@ -0,0 +1,31 @@
import { status as httpStatus } from 'http-status'
import type { PayloadHandler } from '../../config/types.js'
import { getRequestCollectionWithID } from '../../utilities/getRequestEntity.js'
import { headersWithCors } from '../../utilities/headersWithCors.js'
import { unpublishOperation } from '../operations/unpublish.js'
export const unpublishHandler: PayloadHandler = async (req) => {
const { id, collection } = getRequestCollectionWithID(req)
const result = await unpublishOperation({
id,
collection,
req,
})
return Response.json(
{
message: req.t('version:unpublishedSuccessfully'),
result,
},
{
headers: headersWithCors({
headers: new Headers(),
req,
}),
status: httpStatus.OK,
},
)
}

View File

@@ -291,6 +291,7 @@ export const createOperation = async <
autosave,
collection: collectionConfig,
docWithLocales: result,
locale,
operation: 'create',
payload,
publishSpecificLocale,

View File

@@ -0,0 +1,36 @@
import type { PayloadRequest } from '../../types/index.js'
import type { TypeWithVersion } from '../../versions/types.js'
import type { Collection } from '../config/types.js'
import { killTransaction } from '../../utilities/killTransaction.js'
import { unpublish } from '../../versions/unpublish.js'
export type Arguments = {
collection: Collection
id: number | string
req?: PayloadRequest
}
export const unpublishOperation = async <TData extends TypeWithVersion<TData>>(args: Arguments) => {
const {
id,
collection: { config: collectionConfig },
} = args
const req = args.req!
const { payload } = req
try {
const result = await unpublish({
id,
collection: collectionConfig,
payload,
req,
})
return result
} catch (error: unknown) {
await killTransaction(req)
throw error
}
}

View File

@@ -316,6 +316,7 @@ export const updateDocument = async <
collection: collectionConfig,
docWithLocales: result,
draft: shouldSaveDraft,
locale,
operation: 'update',
payload,
publishSpecificLocale,

View File

@@ -159,6 +159,21 @@ export const createClientConfig = ({
break
case 'experimental':
if (config.experimental) {
clientConfig.experimental = {}
if (config.experimental?.localizeStatus) {
clientConfig.experimental.localizeStatus = config.experimental.localizeStatus
}
if (config.experimental?.unpublishSpecificLocale) {
clientConfig.experimental.unpublishSpecificLocale =
config.experimental.unpublishSpecificLocale
}
}
break
case 'folders':
if (config.folders) {
clientConfig.folders = {

View File

@@ -47,6 +47,7 @@ export const defaults: Omit<Config, 'db' | 'editor' | 'secret'> = {
defaultDepth: 2,
defaultMaxTextLength: 40000,
endpoints: [],
experimental: {},
globals: [],
graphQL: {
disablePlaygroundInProduction: true,
@@ -121,6 +122,7 @@ export const addDefaultsToConfig = (config: Config): Config => {
config.defaultDepth = config.defaultDepth ?? 2
config.defaultMaxTextLength = config.defaultMaxTextLength ?? 40000
config.endpoints = config.endpoints ?? []
config.experimental = config.experimental ?? {}
config.globals = config.globals ?? []
config.graphQL = {
disableIntrospectionInProduction: true,

View File

@@ -721,6 +721,18 @@ export type ImportMapGenerators = Array<
}) => void
>
/**
* Experimental features.
* These may be unstable and may change or be removed in future releases.
*/
export type ExperimentalConfig = {
localizeStatus?: boolean
/**
* Enables the ability to unpublish the current locale only.
*/
unpublishSpecificLocale?: boolean
}
export type AfterErrorHook = (
args: AfterErrorHookArgs,
) => AfterErrorResult | Promise<AfterErrorResult>
@@ -1041,6 +1053,12 @@ export type Config = {
email?: EmailAdapter | Promise<EmailAdapter>
/** Custom REST endpoints */
endpoints?: Endpoint[]
/**
* Configure experimental features for Payload.
*
* These features may be unstable and may change or be removed in future releases.
*/
experimental?: ExperimentalConfig
/**
* Options for folder view within the admin panel
* @experimental this feature may change in minor versions until it is fully stable
@@ -1309,6 +1327,7 @@ export type SanitizedConfig = {
/** Default richtext editor to use for richText fields */
editor?: RichTextAdapter<any, any, any>
endpoints: Endpoint[]
experimental?: ExperimentalConfig
globals: SanitizedGlobalConfig[]
i18n: Required<I18nOptions>
jobs: SanitizedJobsConfig

View File

@@ -390,6 +390,7 @@ export type CreateVersionArgs<T = TypeWithID> = {
autosave: boolean
collectionSlug: CollectionSlug
createdAt: string
localeStatus?: Record<string, 'draft' | 'published'>
/** ID of the parent document for which the version should be created for */
parent: number | string
publishedLocale?: string
@@ -414,6 +415,7 @@ export type CreateGlobalVersionArgs<T = TypeWithID> = {
autosave: boolean
createdAt: string
globalSlug: GlobalSlug
localeStatus?: Record<string, 'draft' | 'published'>
/** ID of the parent document for which the version should be created for */
parent: number | string
publishedLocale?: string

View File

@@ -87,8 +87,8 @@ export type RootFoldersConfiguration = {
collectionOverrides?: (({
collection,
}: {
collection: CollectionConfig
}) => CollectionConfig | Promise<CollectionConfig>)[]
collection: Omit<CollectionConfig, 'trash'>
}) => Omit<CollectionConfig, 'trash'> | Promise<Omit<CollectionConfig, 'trash'>>)[]
/**
* If true, you can scope folders to specific collections.
*

View File

@@ -7,6 +7,7 @@ import { findVersionByIDHandler } from './findVersionByID.js'
import { findVersionsHandler } from './findVersions.js'
import { previewHandler } from './preview.js'
import { restoreVersionHandler } from './restoreVersion.js'
import { unpublishHandler } from './unpublish.js'
import { updateHandler } from './update.js'
export const defaultGlobalEndpoints: Endpoint[] = wrapInternalEndpoints([
@@ -40,6 +41,11 @@ export const defaultGlobalEndpoints: Endpoint[] = wrapInternalEndpoints([
method: 'post',
path: '/versions/:id',
},
{
handler: unpublishHandler,
method: 'post',
path: '/unpublish',
},
{
handler: updateHandler,
method: 'post',

View File

@@ -0,0 +1,30 @@
import { status as httpStatus } from 'http-status'
import type { PayloadHandler } from '../../config/types.js'
import { getRequestGlobal } from '../../utilities/getRequestEntity.js'
import { headersWithCors } from '../../utilities/headersWithCors.js'
import { unpublishOperation } from '../operations/unpublish.js'
export const unpublishHandler: PayloadHandler = async (req) => {
const globalConfig = getRequestGlobal(req)
const result = await unpublishOperation({
globalConfig,
req,
})
return Response.json(
{
message: req.t('version:unpublishedSuccessfully'),
result,
},
{
headers: headersWithCors({
headers: new Headers(),
req,
}),
status: httpStatus.OK,
},
)
}

View File

@@ -0,0 +1,31 @@
import type { PayloadRequest } from '../../types/index.js'
import type { TypeWithVersion } from '../../versions/types.js'
import type { SanitizedGlobalConfig } from '../config/types.js'
import { killTransaction } from '../../utilities/killTransaction.js'
import { unpublish } from '../../versions/unpublish.js'
export type Arguments = {
globalConfig: SanitizedGlobalConfig
req?: PayloadRequest
}
export const unpublishOperation = async <TData extends TypeWithVersion<TData>>(args: Arguments) => {
const { globalConfig } = args
const req = args.req!
const { payload } = req
try {
const result = await unpublish({
global: globalConfig,
payload,
req,
})
return result
} catch (error: unknown) {
await killTransaction(req)
throw error
}
}

View File

@@ -285,6 +285,7 @@ export const updateOperation = async <
docWithLocales: result,
draft: shouldSaveDraft,
global: globalConfig,
locale,
operation: 'update',
payload,
publishSpecificLocale,

View File

@@ -1,4 +1,5 @@
// @ts-strict-ignore
import type { SanitizedConfig } from '../config/types.js'
import type { CheckboxField, Field, Option } from '../fields/config/types.js'
export const statuses: Option[] = [
@@ -43,3 +44,23 @@ export const versionSnapshotField: CheckboxField = {
},
index: true,
}
export function buildLocaleStatusField(config: SanitizedConfig): Field[] {
if (!config.localization || !config.localization.locales) {
return []
}
return config.localization.locales.map((locale) => {
const code = typeof locale === 'string' ? locale : locale.code
return {
name: code,
type: 'select',
index: true,
options: [
{ label: ({ t }) => t('version:draft'), value: 'draft' },
{ label: ({ t }) => t('version:published'), value: 'published' },
],
}
})
}

View File

@@ -2,7 +2,7 @@ import type { SanitizedCollectionConfig } from '../collections/config/types.js'
import type { SanitizedConfig } from '../config/types.js'
import type { Field, FlattenedField } from '../fields/config/types.js'
import { versionSnapshotField } from './baseFields.js'
import { buildLocaleStatusField, versionSnapshotField } from './baseFields.js'
export const buildVersionCollectionFields = <T extends boolean = false>(
config: SanitizedConfig,
@@ -62,6 +62,23 @@ export const buildVersionCollectionFields = <T extends boolean = false>(
return locale.code
}),
})
if (config.experimental?.localizeStatus || config.experimental?.unpublishSpecificLocale) {
const localeStatusFields = buildLocaleStatusField(config)
fields.push({
name: 'localeStatus',
type: 'group',
admin: {
disableBulkEdit: true,
disabled: true,
},
fields: localeStatusFields,
...(flatten && {
flattenedFields: localeStatusFields as FlattenedField[],
})!,
})
}
}
fields.push({

View File

@@ -2,7 +2,7 @@ import type { SanitizedConfig } from '../config/types.js'
import type { Field, FlattenedField } from '../fields/config/types.js'
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
import { versionSnapshotField } from './baseFields.js'
import { buildLocaleStatusField, versionSnapshotField } from './baseFields.js'
export const buildVersionGlobalFields = <T extends boolean = false>(
config: SanitizedConfig,
@@ -56,6 +56,23 @@ export const buildVersionGlobalFields = <T extends boolean = false>(
return locale.code
}),
})
if (config.experimental.localizeStatus || config.experimental?.unpublishSpecificLocale) {
const localeStatusFields = buildLocaleStatusField(config)
fields.push({
name: 'localeStatus',
type: 'group',
admin: {
disableBulkEdit: true,
disabled: true,
},
fields: localeStatusFields,
...(flatten && {
flattenedFields: localeStatusFields as FlattenedField[],
})!,
})
}
}
fields.push({

View File

@@ -111,6 +111,12 @@ export const replaceWithDraftIfAvailable = async <T extends TypeWithID>({
draft.version = {} as T
}
// Lift locale status from version data if available
const localeStatus = draft.localeStatus || {}
if (locale && localeStatus[locale]) {
;(draft.version as { _status?: string })['_status'] = localeStatus[locale]
}
// Disregard all other draft content at this point,
// Only interested in the version itself.
// Operations will handle firing hooks, etc.

View File

@@ -1,3 +1,5 @@
import { version } from 'os'
// @ts-strict-ignore
import type { SanitizedCollectionConfig, TypeWithID } from '../collections/config/types.js'
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
@@ -16,6 +18,7 @@ type Args = {
draft?: boolean
global?: SanitizedGlobalConfig
id?: number | string
locale?: null | string
operation?: 'create' | 'restoreVersion' | 'update'
payload: Payload
publishSpecificLocale?: string
@@ -31,6 +34,7 @@ export const saveVersion = async ({
docWithLocales: doc,
draft,
global,
locale,
operation,
payload,
publishSpecificLocale,
@@ -42,6 +46,7 @@ export const saveVersion = async ({
let createNewVersion = true
const now = new Date().toISOString()
const versionData = deepCopyObjectSimple(doc)
if (draft) {
versionData._status = 'draft'
}
@@ -55,39 +60,39 @@ export const saveVersion = async ({
}
try {
if (autosave) {
let docs
const findVersionArgs = {
let docs
const findVersionArgs = {
limit: 1,
pagination: false,
req,
sort: '-updatedAt',
}
if (collection) {
;({ docs } = await payload.db.findVersions({
...findVersionArgs,
collection: collection.slug,
limit: 1,
pagination: false,
req,
sort: '-updatedAt',
}
if (collection) {
;({ docs } = await payload.db.findVersions({
...findVersionArgs,
collection: collection.slug,
limit: 1,
pagination: false,
req,
where: {
parent: {
equals: id,
},
where: {
parent: {
equals: id,
},
}))
} else {
;({ docs } = await payload.db.findGlobalVersions({
...findVersionArgs,
global: global!.slug,
limit: 1,
pagination: false,
req,
}))
}
const [latestVersion] = docs
},
}))
} else {
;({ docs } = await payload.db.findGlobalVersions({
...findVersionArgs,
global: global!.slug,
limit: 1,
pagination: false,
req,
}))
}
const [latestVersion] = docs
if (autosave) {
// overwrite the latest version if it's set to autosave
if (latestVersion && 'autosave' in latestVersion && latestVersion.autosave === true) {
createNewVersion = false
@@ -125,11 +130,54 @@ export const saveVersion = async ({
}
if (createNewVersion) {
let localeStatus = {}
const localizationEnabled =
payload.config.localization && payload.config.localization.locales.length > 0
if (
localizationEnabled &&
payload.config.localization !== false &&
(payload.config.experimental?.localizeStatus ||
payload.config.experimental?.unpublishSpecificLocale)
) {
const allLocales = (
(payload.config.localization && payload.config.localization?.locales) ||
[]
).map((locale) => (typeof locale === 'string' ? locale : locale.code))
// If `publish all`, set all locales to published
if (versionData._status === 'published' && !publishSpecificLocale) {
localeStatus = Object.fromEntries(allLocales.map((code) => [code, 'published']))
} else if (publishSpecificLocale || (locale && versionData._status === 'draft')) {
const status: 'draft' | 'published' = publishSpecificLocale ? 'published' : 'draft'
const incomingLocale = String(publishSpecificLocale || locale)
const existing = latestVersion?.localeStatus
// If no locale statuses are set, set it and set all others to draft
if (!existing) {
localeStatus = {
...Object.fromEntries(
allLocales.filter((code) => code !== incomingLocale).map((code) => [code, 'draft']),
),
[incomingLocale]: status,
}
} else {
// If locales already exist, update the status for the incoming locale
const { [incomingLocale]: _, ...rest } = existing
localeStatus = {
...rest,
[incomingLocale]: status,
}
}
}
}
const createVersionArgs = {
autosave: Boolean(autosave),
collectionSlug: undefined as string | undefined,
createdAt: operation === 'restoreVersion' ? versionData.createdAt : now,
globalSlug: undefined as string | undefined,
localeStatus,
parent: collection ? id : undefined,
publishedLocale: publishSpecificLocale || undefined,
req,

View File

@@ -122,6 +122,7 @@ export type SanitizedGlobalVersions = {
export type TypeWithVersion<T> = {
createdAt: string
id: string
localeStatus: Record<string, 'draft' | 'published'>
parent: number | string
publishedLocale?: string
snapshot?: boolean

View File

@@ -0,0 +1,173 @@
// @ts-strict-ignore
import type { SanitizedCollectionConfig, TypeWithID } from '../collections/config/types.js'
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
import type { Payload } from '../index.js'
import type { PayloadRequest } from '../types/index.js'
import { sanitizeInternalFields } from '../utilities/sanitizeInternalFields.js'
type Args = {
collection?: SanitizedCollectionConfig
global?: SanitizedGlobalConfig
id?: number | string
payload: Payload
req?: PayloadRequest
}
export const unpublish = async ({
id,
collection,
global,
payload,
req,
}: Args): Promise<null | TypeWithID> => {
const now = new Date().toISOString()
const findVersionArgs = {
limit: 2,
pagination: false,
req,
sort: '-updatedAt',
}
const locale = req?.query.locale as string
const unpublishSpecificLocale = req?.query.unpublishSpecificLocale ? locale : undefined
try {
let docs: any[] = []
const whereQuery =
unpublishSpecificLocale && typeof unpublishSpecificLocale === 'string'
? {
[`localeStatus.${unpublishSpecificLocale}`]: { equals: 'published' },
}
: { 'version._status': { equals: 'published' } }
if (collection) {
;({ docs } = await payload.db.findVersions({
...findVersionArgs,
collection: collection.slug,
where: {
and: [{ parent: { equals: id } }, whereQuery],
},
}))
}
if (global) {
;({ docs } = await payload.db.findGlobalVersions({
...findVersionArgs,
global: global.slug,
where: whereQuery,
}))
}
const latestVersion = docs[0]
const previousPublish = docs[1]
if (!latestVersion) {
return null
}
const data: Record<string, unknown> = {
...latestVersion,
createdAt: now,
parent: id,
updatedAt: now,
version: {
...latestVersion.version,
_status: 'draft',
updatedAt: now,
},
}
if (unpublishSpecificLocale) {
data.localeStatus = {
...latestVersion.localeStatus,
[unpublishSpecificLocale]: 'draft',
}
} else {
data.localeStatus = Object.fromEntries(
Object.keys(data.localeStatus as Record<string, unknown>).map((locale) => [
locale,
'draft',
]),
)
}
const updateVersionArgs = {
id: latestVersion.id,
req,
versionData: data as TypeWithID,
}
let result
const updateData = previousPublish ? previousPublish.version : { _status: 'draft' }
if (collection && id !== undefined) {
// update main doc to previous published if available
// otherwise set to draft
await payload.db.updateOne({
collection: collection.slug,
data: updateData,
locale: locale || undefined,
req,
where: { id: { equals: id } },
})
// update version to draft
await payload.db.updateVersion({
...updateVersionArgs,
collection: collection.slug,
})
// fetch updated main doc in requested locale
result = await payload.findByID({
id,
collection: collection.slug,
draft: true,
locale,
req,
})
}
if (global) {
// update main doc to previous published if available
// otherwise set to draft
await payload.db.updateGlobal({
slug: global.slug,
data: updateData,
req,
})
// update version to draft
await payload.db.updateGlobalVersion({
...updateVersionArgs,
global: global.slug,
})
// fetch updated main doc in requested locale
result = await payload.findGlobal({
slug: global.slug,
draft: true,
locale,
req,
})
}
return result as TypeWithID
} catch (err) {
let errorMessage: string
if (collection) {
errorMessage = `There was an error while unpublishing the ${
typeof collection.labels.singular === 'string'
? collection.labels.singular
: collection.slug
} with ID ${id}.`
} else if (global) {
errorMessage = `There was an error while unpublishing the global ${
typeof global.label === 'string' ? global.label : global.slug
}.`
} else {
errorMessage = `There was an error while unpublishing.`
}
payload.logger.error({ err, msg: errorMessage })
return null
}
}

View File

@@ -183,6 +183,11 @@
"types": "./src/lexical-proxy/@lexical-react/LexicalContextMenuPlugin.ts",
"default": "./src/lexical-proxy/@lexical-react/LexicalContextMenuPlugin.ts"
},
"./lexical/react/LexicalNodeContextMenuPlugin": {
"import": "./src/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.ts",
"types": "./src/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.ts",
"default": "./src/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.ts"
},
"./lexical/react/LexicalDecoratorBlockNode": {
"import": "./src/lexical-proxy/@lexical-react/LexicalDecoratorBlockNode.ts",
"types": "./src/lexical-proxy/@lexical-react/LexicalDecoratorBlockNode.ts",
@@ -360,16 +365,16 @@
]
},
"dependencies": {
"@lexical/headless": "0.28.0",
"@lexical/html": "0.28.0",
"@lexical/link": "0.28.0",
"@lexical/list": "0.28.0",
"@lexical/mark": "0.28.0",
"@lexical/react": "0.28.0",
"@lexical/rich-text": "0.28.0",
"@lexical/selection": "0.28.0",
"@lexical/table": "0.28.0",
"@lexical/utils": "0.28.0",
"@lexical/headless": "0.34.0",
"@lexical/html": "0.34.0",
"@lexical/link": "0.34.0",
"@lexical/list": "0.34.0",
"@lexical/mark": "0.34.0",
"@lexical/react": "0.34.0",
"@lexical/rich-text": "0.34.0",
"@lexical/selection": "0.34.0",
"@lexical/table": "0.34.0",
"@lexical/utils": "0.34.0",
"@payloadcms/translations": "workspace:*",
"@payloadcms/ui": "workspace:*",
"@types/uuid": "10.0.0",
@@ -379,7 +384,7 @@
"dequal": "2.0.3",
"escape-html": "1.0.3",
"jsox": "1.2.121",
"lexical": "0.28.0",
"lexical": "0.34.0",
"mdast-util-from-markdown": "2.0.2",
"mdast-util-mdx-jsx": "3.1.3",
"micromark-extension-mdx-jsx": "3.0.1",
@@ -394,7 +399,7 @@
"@babel/preset-env": "7.27.2",
"@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1",
"@lexical/eslint-plugin": "0.28.0",
"@lexical/eslint-plugin": "0.34.0",
"@payloadcms/eslint-config": "workspace:*",
"@types/escape-html": "1.0.4",
"@types/json-schema": "7.0.15",
@@ -581,6 +586,11 @@
"types": "./dist/lexical-proxy/@lexical-react/LexicalContextMenuPlugin.d.ts",
"default": "./dist/lexical-proxy/@lexical-react/LexicalContextMenuPlugin.js"
},
"./lexical/react/LexicalNodeContextMenuPlugin": {
"import": "./dist/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.js",
"types": "./dist/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.d.ts",
"default": "./dist/lexical-proxy/@lexical-react/LexicalNodeContextMenuPlugin.js"
},
"./lexical/react/LexicalDecoratorBlockNode": {
"import": "./dist/lexical-proxy/@lexical-react/LexicalDecoratorBlockNode.js",
"types": "./dist/lexical-proxy/@lexical-react/LexicalDecoratorBlockNode.d.ts",

View File

@@ -8,17 +8,18 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
import { useLexicalEditable } from '@lexical/react/useLexicalEditable'
import {
$computeTableMapSkipCellCheck,
$deleteTableColumn__EXPERIMENTAL,
$deleteTableRow__EXPERIMENTAL,
$deleteTableColumnAtSelection,
$deleteTableRowAtSelection,
$getNodeTriplet,
$getTableCellNodeFromLexicalNode,
$getTableColumnIndexFromTableCellNode,
$getTableNodeFromLexicalNodeOrThrow,
$getTableRowIndexFromTableCellNode,
$insertTableColumn__EXPERIMENTAL,
$insertTableRow__EXPERIMENTAL,
$insertTableColumnAtSelection,
$insertTableRowAtSelection,
$isTableCellNode,
$isTableSelection,
$mergeCells,
$unmergeCell,
getTableElement,
getTableObserverFromTableElement,
@@ -28,11 +29,8 @@ import {
import { mergeRegister } from '@lexical/utils'
import { useScrollInfo } from '@payloadcms/ui'
import {
$createParagraphNode,
$getRoot,
$getSelection,
$isElementNode,
$isParagraphNode,
$isRangeSelection,
$isTextNode,
$setSelection,
@@ -74,17 +72,6 @@ function $canUnmerge(): boolean {
return cell.__colSpan > 1 || cell.__rowSpan > 1
}
function $cellContainsEmptyParagraph(cell: TableCellNode): boolean {
if (cell.getChildrenSize() !== 1) {
return false
}
const firstChild = cell.getFirstChildOrThrow()
if (!$isParagraphNode(firstChild) || !firstChild.isEmpty()) {
return false
}
return true
}
function $selectLastDescendant(node: ElementNode): void {
const lastDescendant = node.getLastDescendant()
if ($isTextNode(lastDescendant)) {
@@ -227,105 +214,14 @@ function TableActionMenu({
const mergeTableCellsAtSelection = () => {
editor.update(() => {
const selection = $getSelection()
if ($isTableSelection(selection)) {
// Get all selected cells and compute the total area
const nodes = selection.getNodes()
const tableCells = nodes.filter($isTableCellNode)
if (tableCells.length === 0) {
return
}
// Find the table node
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCells[0] as TableCellNode)
const [gridMap] = $computeTableMapSkipCellCheck(tableNode, null, null)
// Find the boundaries of the selection including merged cells
let minRow = Infinity
let maxRow = -Infinity
let minCol = Infinity
let maxCol = -Infinity
// First pass: find the actual boundaries considering merged cells
const processedCells = new Set()
for (const row of gridMap) {
for (const mapCell of row) {
if (!mapCell || !mapCell.cell) {
continue
}
const cellKey = mapCell.cell.getKey()
if (processedCells.has(cellKey)) {
continue
}
if (tableCells.some((cell) => cell.is(mapCell.cell))) {
processedCells.add(cellKey)
// Get the actual position of this cell in the grid
const cellStartRow = mapCell.startRow
const cellStartCol = mapCell.startColumn
const cellRowSpan = mapCell.cell.__rowSpan || 1
const cellColSpan = mapCell.cell.__colSpan || 1
// Update boundaries considering the cell's actual position and span
minRow = Math.min(minRow, cellStartRow)
maxRow = Math.max(maxRow, cellStartRow + cellRowSpan - 1)
minCol = Math.min(minCol, cellStartCol)
maxCol = Math.max(maxCol, cellStartCol + cellColSpan - 1)
}
}
}
// Validate boundaries
if (minRow === Infinity || minCol === Infinity) {
return
}
// The total span of the merged cell
const totalRowSpan = maxRow - minRow + 1
const totalColSpan = maxCol - minCol + 1
// Use the top-left cell as the target cell
const targetCellMap = gridMap?.[minRow]?.[minCol]
if (!targetCellMap?.cell) {
return
}
const targetCell = targetCellMap.cell
// Set the spans for the target cell
targetCell.setColSpan(totalColSpan)
targetCell.setRowSpan(totalRowSpan)
// Move content from other cells to the target cell
const seenCells = new Set([targetCell.getKey()])
// Second pass: merge content and remove other cells
for (let row = minRow; row <= maxRow; row++) {
for (let col = minCol; col <= maxCol; col++) {
const mapCell = gridMap?.[row]?.[col]
if (!mapCell?.cell) {
continue
}
const currentCell = mapCell.cell
const key = currentCell.getKey()
if (!seenCells.has(key)) {
seenCells.add(key)
const isEmpty = $cellContainsEmptyParagraph(currentCell)
if (!isEmpty) {
targetCell.append(...currentCell.getChildren())
}
currentCell.remove()
}
}
}
// Ensure target cell has content
if (targetCell.getChildrenSize() === 0) {
targetCell.append($createParagraphNode())
}
if (!$isTableSelection(selection)) {
return
}
const nodes = selection.getNodes()
const tableCells = nodes.filter($isTableCellNode)
const targetCell = $mergeCells(tableCells)
if (targetCell) {
$selectLastDescendant(targetCell)
onClose()
}
@@ -342,7 +238,7 @@ function TableActionMenu({
(shouldInsertAfter: boolean) => {
editor.update(() => {
for (let i = 0; i < selectionCounts.rows; i++) {
$insertTableRow__EXPERIMENTAL(shouldInsertAfter)
$insertTableRowAtSelection(shouldInsertAfter)
}
onClose()
})
@@ -354,7 +250,7 @@ function TableActionMenu({
(shouldInsertAfter: boolean) => {
editor.update(() => {
for (let i = 0; i < selectionCounts.columns; i++) {
$insertTableColumn__EXPERIMENTAL(shouldInsertAfter)
$insertTableColumnAtSelection(shouldInsertAfter)
}
onClose()
})
@@ -364,7 +260,7 @@ function TableActionMenu({
const deleteTableRowAtSelection = useCallback(() => {
editor.update(() => {
$deleteTableRow__EXPERIMENTAL()
$deleteTableRowAtSelection()
onClose()
})
}, [editor, onClose])
@@ -381,7 +277,7 @@ function TableActionMenu({
const deleteTableColumnAtSelection = useCallback(() => {
editor.update(() => {
$deleteTableColumn__EXPERIMENTAL()
$deleteTableColumnAtSelection()
onClose()
})
}, [editor, onClose])

View File

@@ -17,7 +17,7 @@ import {
TableNode,
} from '@lexical/table'
import { calculateZoomLevel, mergeRegister } from '@lexical/utils'
import { $getNearestNodeFromDOMNode, isHTMLElement } from 'lexical'
import { $getNearestNodeFromDOMNode, isHTMLElement, SKIP_SCROLL_INTO_VIEW_TAG } from 'lexical'
import * as React from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
@@ -223,7 +223,7 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT)
tableRow.setHeight(newHeight)
},
{ tag: 'skip-scroll-into-view' },
{ tag: SKIP_SCROLL_INTO_VIEW_TAG },
)
},
[activeCell, editor],
@@ -281,7 +281,7 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
newColWidths[columnIndex] = newWidth
tableNode.setColWidths(newColWidths)
},
{ tag: 'skip-scroll-into-view' },
{ tag: SKIP_SCROLL_INTO_VIEW_TAG },
)
},
[activeCell, editor],

View File

@@ -9,8 +9,8 @@ import {
$getTableAndElementByKey,
$getTableColumnIndexFromTableCellNode,
$getTableRowIndexFromTableCellNode,
$insertTableColumn__EXPERIMENTAL,
$insertTableRow__EXPERIMENTAL,
$insertTableColumnAtSelection,
$insertTableRowAtSelection,
$isTableCellNode,
$isTableNode,
getTableElement,
@@ -223,10 +223,10 @@ function TableHoverActionsContainer({
const maybeTableNode = $getNearestNodeFromDOMNode(tableCellDOMNodeRef.current)
maybeTableNode?.selectEnd()
if (insertRow) {
$insertTableRow__EXPERIMENTAL()
$insertTableRowAtSelection()
setShownRow(false)
} else {
$insertTableColumn__EXPERIMENTAL()
$insertTableColumnAtSelection()
setShownColumn(false)
}
}

View File

@@ -26,7 +26,7 @@ import { richTextValidateHOC } from './validate/index.js'
let checkedDependencies = false
export const lexicalTargetVersion = '0.28.0'
export const lexicalTargetVersion = '0.34.0'
export function lexicalEditor(args?: LexicalEditorProps): LexicalRichTextAdapterProvider {
if (

View File

@@ -0,0 +1 @@
export * from '@lexical/react/LexicalNodeContextMenuPlugin'

View File

@@ -2,6 +2,7 @@
@layer payload-default {
.draggable-block-menu {
border: none;
border-radius: $style-radius-m;
padding: 0;
cursor: grab;
@@ -24,6 +25,7 @@
}
.icon {
background-color: transparent;
width: 18px;
height: 24px;
opacity: 0.3;

View File

@@ -70,7 +70,7 @@ function useDraggableBlockMenu(
): React.ReactElement {
const scrollerElem = anchorElem.parentElement
const menuRef = useRef<HTMLDivElement>(null)
const menuRef = useRef<HTMLButtonElement>(null)
const targetLineRef = useRef<HTMLDivElement>(null)
const debugHighlightRef = useRef<HTMLDivElement>(null)
const isDraggingBlockRef = useRef<boolean>(false)
@@ -396,7 +396,7 @@ function useDraggableBlockMenu(
editorConfig?.admin?.hideGutter,
])
function onDragStart(event: ReactDragEvent<HTMLDivElement>): void {
function onDragStart(event: ReactDragEvent<HTMLButtonElement>): void {
const dataTransfer = event.dataTransfer
if (!dataTransfer || !draggableBlockElem) {
return
@@ -422,15 +422,17 @@ function useDraggableBlockMenu(
return createPortal(
<React.Fragment>
<div
<button
aria-label="Drag to move"
className="icon draggable-block-menu"
draggable
onDragEnd={onDragEnd}
onDragStart={onDragStart}
ref={menuRef}
type="button"
>
<div className={isEditable ? 'icon' : ''} />
</div>
</button>
<div className="draggable-block-target-line" ref={targetLineRef} />
<div className="debug-highlight" ref={debugHighlightRef} />
</React.Fragment>,

View File

@@ -448,6 +448,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
'version:aboutToRestoreGlobal',
'version:aboutToRevertToPublished',
'version:aboutToUnpublish',
'version:aboutToUnpublishIn',
'version:aboutToUnpublishSelection',
'version:autosave',
'version:autosavedSuccessfully',
@@ -489,6 +490,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
'version:restoreThisVersion',
'version:restoring',
'version:reverting',
'version:revertUnsuccessful',
'version:revertToPublished',
'version:saveDraft',
'version:scheduledSuccessfully',
@@ -501,6 +503,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
'version:type',
'version:unpublish',
'version:unpublishing',
'version:unpublishedSuccessfully',
'version:versionID',
'version:version',
'version:versions',

View File

@@ -526,6 +526,7 @@ export const arTranslations: DefaultTranslationsObject = {
'أنت على وشك استرجاع الاعداد العامّ {{label}} إلى الحالة التي كان عليها في {{versionDate}}.',
aboutToRevertToPublished: 'أنت على وشك إعادة هذا المستند إلى حالته المنشورة. هل أنت متأكّد؟',
aboutToUnpublish: 'أنت على وشك إلغاء نشر هذا المستند. هل أنت متأكّد؟',
aboutToUnpublishIn: 'أنت على وشك إلغاء نشر هذا المستند في {{locale}}. هل أنت متأكد؟',
aboutToUnpublishSelection: 'أنت على وشك إلغاء نشر كلّ {{label}} في التّحديد. هل أنت متأكّد؟',
autosave: 'حفظ تلقائي',
autosavedSuccessfully: 'تمّ الحفظ التّلقائي بنجاح.',
@@ -570,6 +571,7 @@ export const arTranslations: DefaultTranslationsObject = {
restoring: 'تتمّ الاستعادة...',
reverting: 'يتمّ الاسترجاع...',
revertToPublished: 'الرّجوع للنسخة المنشورة',
revertUnsuccessful: 'فشل في الرجوع. لم يتم العثور على نسخة نشرت سابقا.',
saveDraft: 'حفظ المسودّة',
scheduledSuccessfully: 'تم الجدولة بنجاح.',
schedulePublish: 'جدول النشر',
@@ -580,6 +582,7 @@ export const arTranslations: DefaultTranslationsObject = {
specificVersion: 'الإصدار المحدد',
status: 'الحالة',
unpublish: 'الغاء النّشر',
unpublishedSuccessfully: 'تم الإلغاء بنجاح.',
unpublishing: 'يتمّ الغاء النّشر...',
version: 'النّسخة',
versionAgo: 'منذ {{distance}}',

View File

@@ -543,6 +543,7 @@ export const azTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Bu sənədin dəyişikliklərini dərc edilmiş vəziyyətinə qaytarmağa hazırsınız. Əminsiniz?',
aboutToUnpublish: 'Bu sənədi dərcdən çıxartmağa hazırsınız. Əminsiniz?',
aboutToUnpublishIn: 'Siz bu sənədi {{locale}} dildə nəşr etməyi dayandırmaqdasınız. Əminsiniz?',
aboutToUnpublishSelection:
'Seçimdə olan bütün {{label}}-i dərcdən çıxartmağa hazırsınız. Əminsiniz?',
autosave: 'Avtomatik yadda saxlama',
@@ -588,6 +589,8 @@ export const azTranslations: DefaultTranslationsObject = {
restoring: 'Bərpa olunur...',
reverting: 'Qayıdılır...',
revertToPublished: 'Dərc edilmişə qayıt',
revertUnsuccessful:
'Əvvəlki versiyanı geri qaytarma uğursuz oldu. Daha öncədən nəşr edilmiş versiya tapılmadı.',
saveDraft: 'Qaralamayı yadda saxla',
scheduledSuccessfully: 'Uğurla cədvələ qoyuldu.',
schedulePublish: 'Nəşr Cədvəli',
@@ -598,6 +601,7 @@ export const azTranslations: DefaultTranslationsObject = {
specificVersion: 'Xüsusi Versiya',
status: 'Status',
unpublish: 'Dərcdən çıxart',
unpublishedSuccessfully: 'Uğurla dərc olunmadı.',
unpublishing: 'Dərcdən çıxarılır...',
version: 'Versiya',
versionAgo: '{{distance}} əvvəl',

View File

@@ -540,6 +540,8 @@ export const bgTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'На път си да възстановиш промените на този документ до публикуваното му състояние. Сигурен ли си?',
aboutToUnpublish: 'На път си да скриеш този документ. Сигурен ли си?',
aboutToUnpublishIn:
'Предстои да оттеглите публикацията на този документ в {{locale}}. Сигурни ли сте?',
aboutToUnpublishSelection: 'На път си да скриеш всички избрани {{label}}. Сигурен ли си?',
autosave: 'Автоматично запазване',
autosavedSuccessfully: 'Успешно автоматично запазване.',
@@ -584,6 +586,7 @@ export const bgTranslations: DefaultTranslationsObject = {
restoring: 'Възстановяване...',
reverting: 'Връщане..',
revertToPublished: 'Върни се до публикуваното',
revertUnsuccessful: 'Връщането е неуспешно. Не е открита предишно публикувана версия.',
saveDraft: 'Запази чернова',
scheduledSuccessfully: 'Успешно насрочено.',
schedulePublish: 'Планирано публикуване',
@@ -594,6 +597,7 @@ export const bgTranslations: DefaultTranslationsObject = {
specificVersion: 'Специфична версия',
status: 'Статус',
unpublish: 'Скрий',
unpublishedSuccessfully: 'Успешно оттеглено.',
unpublishing: 'Скриване...',
version: 'Версия',
versionAgo: 'преди {{distance}}',

View File

@@ -545,6 +545,8 @@ export const bnBdTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'আপনি এই ডকুমেন্টের পরিবর্তনগুলি তার প্রকাশিত অবস্থায় ফিরিয়ে আনতে চলেছেন। আপনি কি নিশ্চিত?',
aboutToUnpublish: 'আপনি এই ডকুমেন্টটি আনপাবলিশ করতে চলেছেন। আপনি কি নিশ্চিত?',
aboutToUnpublishIn:
'আপনি সাবধানে এই দস্তাবেজ টি {{locale}} -এ অপ্রকাশিত করতে যাচ্ছেন। আপনি কি নিশ্চিত?',
aboutToUnpublishSelection:
'আপনি নির্বাচনে সমস্ত {{label}} আনপাবলিশ করতে চলেছেন। আপনি কি নিশ্চিত?',
autosave: 'স্বয়ংক্রিয় সংরক্ষণ',
@@ -590,6 +592,7 @@ export const bnBdTranslations: DefaultTranslationsObject = {
restoring: 'পুনরুদ্ধার করা হচ্ছে...',
reverting: 'পূর্বাবস্থায় ফেরানো হচ্ছে...',
revertToPublished: 'প্রকাশিত সংস্করণে ফিরে যান',
revertUnsuccessful: 'পুনরায় ব্যর্থ হয়েছে। কোনও পূর্বে প্রকাশিত সংস্করণ পাওয়া যায় নি।',
saveDraft: 'খসড়া সংরক্ষণ করুন',
scheduledSuccessfully: 'সফলভাবে নির্ধারিত হয়েছে।',
schedulePublish: 'প্রকাশের সময়সূচী নির্ধারণ করুন',
@@ -600,6 +603,7 @@ export const bnBdTranslations: DefaultTranslationsObject = {
specificVersion: 'নির্দিষ্ট সংস্করণ',
status: 'স্থিতি',
unpublish: 'প্রকাশ বাতিল করুন',
unpublishedSuccessfully: 'সফলভাবে অপ্রকাশিত হয়েছে।',
unpublishing: 'প্রকাশ বাতিল করা হচ্ছে...',
version: 'সংস্করণ',
versionAgo: '{{distance}} পূর্বে',

View File

@@ -544,6 +544,7 @@ export const bnInTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'আপনি এই ডকুমেন্টের পরিবর্তনগুলি তার প্রকাশিত অবস্থায় ফিরিয়ে আনতে চলেছেন। আপনি কি নিশ্চিত?',
aboutToUnpublish: 'আপনি এই ডকুমেন্টটি আনপাবলিশ করতে চলেছেন। আপনি কি নিশ্চিত?',
aboutToUnpublishIn: 'আপনি এই নথিটি {{locale}} এ আন-পাবলিশ করতে চলেছেন। আপনি কি নিশ্চিত?',
aboutToUnpublishSelection:
'আপনি নির্বাচনে সমস্ত {{label}} আনপাবলিশ করতে চলেছেন। আপনি কি নিশ্চিত?',
autosave: 'স্বয়ংক্রিয় সংরক্ষণ',
@@ -589,6 +590,7 @@ export const bnInTranslations: DefaultTranslationsObject = {
restoring: 'পুনরুদ্ধার করা হচ্ছে...',
reverting: 'পূর্বাবস্থায় ফেরানো হচ্ছে...',
revertToPublished: 'প্রকাশিত সংস্করণে ফিরে যান',
revertUnsuccessful: 'প্রত্যাহার অসফল। কোন পূর্বে প্রকাশিত সংস্করণ পাওয়া যায়নি।',
saveDraft: 'খসড়া সংরক্ষণ করুন',
scheduledSuccessfully: 'সফলভাবে নির্ধারিত হয়েছে।',
schedulePublish: 'প্রকাশের সময়সূচী নির্ধারণ করুন',
@@ -599,6 +601,7 @@ export const bnInTranslations: DefaultTranslationsObject = {
specificVersion: 'নির্দিষ্ট সংস্করণ',
status: 'স্থিতি',
unpublish: 'প্রকাশ বাতিল করুন',
unpublishedSuccessfully: 'সফলভাবে অপ্রকাশিত হয়েছে।',
unpublishing: 'প্রকাশ বাতিল করা হচ্ছে...',
version: 'সংস্করণ',
versionAgo: '{{distance}} পূর্বে',

View File

@@ -544,6 +544,7 @@ export const caTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
"Estàs a punt de revertir els canvis d'aquest document a l'estat publicat. Estàs segur?",
aboutToUnpublish: 'Estàs a punt de despublicar aquest document. Estàs segur?',
aboutToUnpublishIn: "Estàs a punt de despublicar aquest document en {{locale}}. N'estàs segur?",
aboutToUnpublishSelection:
'Estàs a punt de despublicar tots els {{label}} de la selecció. Estàs segur?',
autosave: 'Desa automàticament',
@@ -589,6 +590,7 @@ export const caTranslations: DefaultTranslationsObject = {
restoring: 'Restaurant...',
reverting: 'Revertint...',
revertToPublished: 'Revertir a publicat',
revertUnsuccessful: "Reversió sense èxit. No s'ha trobat cap versió publicada anteriorment.",
saveDraft: 'Desar borrador',
scheduledSuccessfully: 'Programat amb èxit.',
schedulePublish: 'Programar publicació',
@@ -599,6 +601,7 @@ export const caTranslations: DefaultTranslationsObject = {
specificVersion: 'Versió Específica',
status: 'Estat',
unpublish: 'Despublicar',
unpublishedSuccessfully: 'Publicació desfeta correctament.',
unpublishing: 'Despublicant...',
version: 'Versió',
versionAgo: 'fa {{distance}}',

View File

@@ -537,6 +537,8 @@ export const csTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Chystáte se vrátit změny tohoto dokumentu do jeho publikovaného stavu. Jste si jisti?',
aboutToUnpublish: 'Chystáte se zrušit publikování tohoto dokumentu. Jste si jisti?',
aboutToUnpublishIn:
'Chystáte se zrušit publikaci tohoto dokumentu v {{locale}}. Jste si jistý?',
aboutToUnpublishSelection:
'Chystáte se zrušit publikování všech {{label}} ve výběru. Jsi si jistá?',
autosave: 'Automatické uložení',
@@ -582,6 +584,7 @@ export const csTranslations: DefaultTranslationsObject = {
restoring: 'Obnovování...',
reverting: 'Vracení...',
revertToPublished: 'Vrátit se k publikovanému',
revertUnsuccessful: 'Vrácení neúspěšné. Nebyla nalezena žádná předchozí publikovaná verze.',
saveDraft: 'Uložit koncept',
scheduledSuccessfully: 'Úspěšně naplánováno.',
schedulePublish: 'Naplánovat publikaci',
@@ -592,6 +595,7 @@ export const csTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifická verze',
status: 'Stav',
unpublish: 'Zrušit publikování',
unpublishedSuccessfully: 'Úspěšně nezveřejněno.',
unpublishing: 'Zrušuji publikování...',
version: 'Verze',
versionAgo: 'před {{distance}}',

View File

@@ -539,6 +539,7 @@ export const daTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Du er ved at tilbagerulle dette dokuments ændringer til dets offentliggjorte tilstand. Er du sikker?',
aboutToUnpublish: 'Du er ved at afpublicere dette dokument. Er du sikker?',
aboutToUnpublishIn: 'Du er ved at afpublicere dette dokument i {{locale}}. Er du sikker?',
aboutToUnpublishSelection:
'Du er ved at afpublicere alt {{label}} i denne sektion. Er du sikker?',
autosave: 'Autosave',
@@ -584,6 +585,8 @@ export const daTranslations: DefaultTranslationsObject = {
restoring: 'Gendanner...',
reverting: 'Tilbageruller...',
revertToPublished: 'Tilbagerul til offentliggjort',
revertUnsuccessful:
'Tilbageføring mislykkedes. Ingen tidligere offentliggjorte version fundet.',
saveDraft: 'Gem kladde',
scheduledSuccessfully: 'Planlagt med succes.',
schedulePublish: 'Planlæg offentliggørelse',
@@ -594,6 +597,7 @@ export const daTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifik Version',
status: 'Status',
unpublish: 'Afpublicer',
unpublishedSuccessfully: 'Offentliggørelse annulleret med succes.',
unpublishing: 'Afpublicerer...',
version: 'Version',
versionAgo: '{{distance}} siden',

View File

@@ -551,6 +551,8 @@ export const deTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Du bist dabei, dieses Dokument auf den Stand des ersten Veröffentlichungsdatums zurückzusetzen. Bist du sicher?',
aboutToUnpublish: 'Du bist dabei dieses Dokument auf Entwurf zu setzen. Bist du dir sicher?',
aboutToUnpublishIn:
'Sie sind dabei, dieses Dokument in {{locale}} zu entöffentlichen. Sind Sie sicher?',
aboutToUnpublishSelection:
'Du bist dabei, die Veröffentlichung aller {{label}} in der Auswahl aufzuheben. Bist du dir sicher?',
autosave: 'Automatische Speicherung',
@@ -596,6 +598,8 @@ export const deTranslations: DefaultTranslationsObject = {
restoring: 'Wiederherstellen...',
reverting: 'Zurücksetzen...',
revertToPublished: 'Auf veröffentlichte Version zurücksetzen',
revertUnsuccessful:
'Rückgängigmachung fehlgeschlagen. Keine zuvor veröffentlichte Version gefunden.',
saveDraft: 'Entwurf speichern',
scheduledSuccessfully: 'Erfolgreich geplant.',
schedulePublish: 'Veröffentlichungsplan',
@@ -606,6 +610,7 @@ export const deTranslations: DefaultTranslationsObject = {
specificVersion: 'Spezifische Version',
status: 'Status',
unpublish: 'Veröffentlichung aufheben',
unpublishedSuccessfully: 'Erfolgreich unveröffentlicht.',
unpublishing: 'Veröffentlichung aufheben...',
version: 'Version',
versionAgo: 'vor {{distance}}',

View File

@@ -543,6 +543,7 @@ export const enTranslations = {
aboutToRevertToPublished:
"You are about to revert this document's changes to its published state. Are you sure?",
aboutToUnpublish: 'You are about to unpublish this document. Are you sure?',
aboutToUnpublishIn: 'You are about to unpublish this document in {{locale}}. Are you sure?',
aboutToUnpublishSelection:
'You are about to unpublish all {{label}} in the selection. Are you sure?',
autosave: 'Autosave',
@@ -588,6 +589,7 @@ export const enTranslations = {
restoring: 'Restoring...',
reverting: 'Reverting...',
revertToPublished: 'Revert to published',
revertUnsuccessful: 'Revert unsuccessful. No previously published version found.',
saveDraft: 'Save Draft',
scheduledSuccessfully: 'Scheduled successfully.',
schedulePublish: 'Schedule Publish',
@@ -598,6 +600,7 @@ export const enTranslations = {
specificVersion: 'Specific Version',
status: 'Status',
unpublish: 'Unpublish',
unpublishedSuccessfully: 'Unpublished successfully.',
unpublishing: 'Unpublishing...',
version: 'Version',
versionAgo: '{{distance}} ago',

View File

@@ -546,6 +546,7 @@ export const esTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Estás a punto de revertir los cambios de este documento a su estado publicado. ¿Estás seguro?',
aboutToUnpublish: 'Estás a punto de despublicar este documento. ¿Estás seguro?',
aboutToUnpublishIn: 'Estás a punto de despublicar este documento en {{locale}}. ¿Estás seguro?',
aboutToUnpublishSelection:
'Estás a punto de despublicar todos los {{label}} seleccionados. ¿Estás seguro?',
autosave: 'Autoguardado',
@@ -591,6 +592,7 @@ export const esTranslations: DefaultTranslationsObject = {
restoring: 'Restaurando...',
reverting: 'Revirtiendo...',
revertToPublished: 'Revertir a la versión publicada',
revertUnsuccessful: 'Reversión fallida. No se encontró una versión previamente publicada.',
saveDraft: 'Guardar borrador',
scheduledSuccessfully: 'Programado con éxito.',
schedulePublish: 'Programar publicación',
@@ -601,6 +603,7 @@ export const esTranslations: DefaultTranslationsObject = {
specificVersion: 'Versión Específica',
status: 'Estado',
unpublish: 'Despublicar',
unpublishedSuccessfully: 'Se ha despublicado con éxito.',
unpublishing: 'Despublicando...',
version: 'Versión',
versionAgo: 'hace {{distance}}',

View File

@@ -533,6 +533,7 @@ export const etTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Olete taastamas selle dokumendi muudatusi avaldatud seisundisse. Olete kindel?',
aboutToUnpublish: 'Olete tühistamas selle dokumendi avaldamist. Olete kindel?',
aboutToUnpublishIn: 'Olete just {{locale}} dokumendi avaldamise lõpetamas. Olete kindel?',
aboutToUnpublishSelection: 'Olete tühistamas kõigi valitud {{label}} avaldamist. Olete kindel?',
autosave: 'Automaatne salvestamine',
autosavedSuccessfully: 'Automaatselt salvestatud.',
@@ -577,6 +578,7 @@ export const etTranslations: DefaultTranslationsObject = {
restoring: 'Taastamine...',
reverting: 'Taastamine...',
revertToPublished: 'Taasta avaldatud seisund',
revertUnsuccessful: 'Tagasipöördumine ebaõnnestus. Eelnevalt avaldatud versiooni ei leitud.',
saveDraft: 'Salvesta mustand',
scheduledSuccessfully: 'Planeeritud edukalt.',
schedulePublish: 'Planeeri avaldamine',
@@ -587,6 +589,7 @@ export const etTranslations: DefaultTranslationsObject = {
specificVersion: 'Spetsiifiline versioon',
status: 'Olek',
unpublish: 'Tühista avaldamine',
unpublishedSuccessfully: 'Edastamata edukalt.',
unpublishing: 'Avaldamise tühistamine...',
version: 'Versioon',
versionAgo: '{{distance}} tagasi',

View File

@@ -535,6 +535,7 @@ export const faTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'شما در حال بازگردانی تغییرات این رسانه به وضعیت منتشر شده آن هستید. از این کار اطمینان دارید؟',
aboutToUnpublish: 'شما در حال لغو انتشار این سند هستید، آیا از این کار اطمینان دارید؟',
aboutToUnpublishIn: 'شما در حال غیرانتشار این سند در {{locale}} هستید. آیا مطمئن هستید؟',
aboutToUnpublishSelection: 'شما در شرف لغو انتشار {{label}} برگزیده هستید. ایا اطمینان دارید؟',
autosave: 'ذخیره خودکار',
autosavedSuccessfully: 'با موفقیت ذخیره خودکار شد.',
@@ -579,6 +580,7 @@ export const faTranslations: DefaultTranslationsObject = {
restoring: 'در حال بازیابی...',
reverting: 'در حال بازگردانی...',
revertToPublished: 'بازگردانی به انتشار یافته',
revertUnsuccessful: 'بازگشت ناموفق. نسخه قبلا منتشر شده‌ای یافت نشد.',
saveDraft: 'ذخیره پیش‌نویس',
scheduledSuccessfully: 'با موفقیت زمانبندی شد.',
schedulePublish: 'برنامه انتشار',
@@ -589,6 +591,7 @@ export const faTranslations: DefaultTranslationsObject = {
specificVersion: 'نسخه مشخص',
status: 'وضعیت',
unpublish: 'لغو انتشار',
unpublishedSuccessfully: 'با موفقیت منتشر نشد.',
unpublishing: 'در حال لغو انتشار...',
version: 'نگارش',
versionAgo: '{{distance}} پیش',

View File

@@ -555,6 +555,8 @@ export const frTranslations: DefaultTranslationsObject = {
'Vous êtes sur le point de rétablir les modifications apportées à ce document à la version publiée. Êtes-vous sûr ?',
aboutToUnpublish:
'Vous êtes sur le point dannuler la publication de ce document. Êtes-vous sûr ?',
aboutToUnpublishIn:
'Vous êtes sur le point de dépublier ce document en {{locale}}. Êtes-vous sûr ?',
aboutToUnpublishSelection:
'Vous êtes sur le point de dépublier tous les {{label}} de la sélection. Êtes-vous sûr ?',
autosave: 'Enregistrement automatique',
@@ -600,6 +602,7 @@ export const frTranslations: DefaultTranslationsObject = {
restoring: 'Restauration en cours...',
reverting: 'Republication en cours...',
revertToPublished: 'Republier',
revertUnsuccessful: 'Rétablissement échoué. Aucune version précédemment publiée trouvée.',
saveDraft: 'Enregistrer le brouillon',
scheduledSuccessfully: 'Programmé avec succès.',
schedulePublish: 'Programmer la publication',
@@ -610,6 +613,7 @@ export const frTranslations: DefaultTranslationsObject = {
specificVersion: 'Version spécifique',
status: 'Statut',
unpublish: 'Annuler la publication',
unpublishedSuccessfully: 'Non publié avec succès.',
unpublishing: 'Annulation en cours...',
version: 'Version',
versionAgo: 'il y a {{distance}}',

View File

@@ -522,6 +522,7 @@ export const heTranslations: DefaultTranslationsObject = {
'אתה עומד לשחזר את {{label}} הגלובלי למצב שהיה בו בתאריך {{versionDate}}.',
aboutToRevertToPublished: 'אתה עומד להחזיר את השינויים במסמך הזה לגרסה שפורסמה. האם אתה בטוח?',
aboutToUnpublish: 'אתה עומד לבטל את הפרסום של מסמך זה. האם אתה בטוח?',
aboutToUnpublishIn: 'אתה עומד לבטל את פרסום המסמך הזה ב-{{locale}}. האם אתה בטוח?',
aboutToUnpublishSelection: 'אתה עומד לבטל את הפרסום של כל ה{{label}} שנבחרו. האם אתה בטוח?',
autosave: 'שמירה אוטומטית',
autosavedSuccessfully: 'נשמר בהצלחה.',
@@ -566,6 +567,7 @@ export const heTranslations: DefaultTranslationsObject = {
restoring: 'משחזר...',
reverting: 'משחזר...',
revertToPublished: 'שחזר לגרסה שפורסמה',
revertUnsuccessful: 'החזרה לא הצליחה. לא נמצאה גרסה שפורסמה קודם.',
saveDraft: 'שמור טיוטה',
scheduledSuccessfully: 'תוזמן בהצלחה.',
schedulePublish: 'לוח זמנים לפרסום',
@@ -576,6 +578,7 @@ export const heTranslations: DefaultTranslationsObject = {
specificVersion: 'גרסה מסוימת',
status: 'סטטוס',
unpublish: 'בטל פרסום',
unpublishedSuccessfully: 'לא פורסם בהצלחה.',
unpublishing: 'מבטל פרסום...',
version: 'גרסה',
versionAgo: 'לפני {{distance}}',

View File

@@ -537,6 +537,7 @@ export const hrTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Vratit ćete promjene u dokumentu u objavljeno stanje. Jeste li sigurni? ',
aboutToUnpublish: 'Poništit ćete objavu ovog dokumenta. Jeste li sigurni?',
aboutToUnpublishIn: 'Na rubu ste da povučete ovaj dokument u {{locale}}. Jeste li sigurni?',
aboutToUnpublishSelection:
'Upravo ćete poništiti objavu svih {{label}} u odabiru. Jeste li sigurni?',
autosave: 'Automatsko spremanje',
@@ -582,6 +583,7 @@ export const hrTranslations: DefaultTranslationsObject = {
restoring: 'Vraćanje...',
reverting: 'Vraćanje...',
revertToPublished: 'Vrati na objavljeno',
revertUnsuccessful: 'Povratak nije uspio. Nije pronađena prethodno objavljena verzija.',
saveDraft: 'Sačuvaj nacrt',
scheduledSuccessfully: 'Uspješno zakazano.',
schedulePublish: 'Raspored objavljivanja',
@@ -592,6 +594,7 @@ export const hrTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifična verzija',
status: 'Status',
unpublish: 'Poništi objavu',
unpublishedSuccessfully: 'Uspješno nepobjavljeno.',
unpublishing: 'Poništavanje objave...',
version: 'Verzija',
versionAgo: 'prije {{distance}}',

View File

@@ -546,6 +546,8 @@ export const huTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Arra készül, hogy visszaállítsa a dokumentum módosításait a közzétett állapotába. Biztos benne?',
aboutToUnpublish: 'A dokumentum közzétételének visszavonására készül. Biztos benne?',
aboutToUnpublishIn:
'Ön arra készül, hogy visszavonja ennek a dokumentumnak a közzétételét a következően: {{locale}}. Biztos benne?',
aboutToUnpublishSelection:
'Arra készül, hogy visszavonja a kijelölésben szereplő összes {{label}} közzétételét. biztos vagy ebben?',
autosave: 'Automatikus mentés',
@@ -591,6 +593,7 @@ export const huTranslations: DefaultTranslationsObject = {
restoring: 'Visszaállítás...',
reverting: 'Visszaállítás...',
revertToPublished: 'Visszatérés a közzétetthez',
revertUnsuccessful: 'Visszaállítás sikertelen. Nem található korábban publikált változat.',
saveDraft: 'Piszkozat mentése',
scheduledSuccessfully: 'Sikeresen ütemezve.',
schedulePublish: 'Közzététel ütemezése',
@@ -601,6 +604,7 @@ export const huTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifikus verzió',
status: 'Állapot',
unpublish: 'Közzététel visszavonása',
unpublishedSuccessfully: 'Sikeresen törölve a közzétételről.',
unpublishing: 'Közzététel visszavonása...',
version: 'Verzió',
versionAgo: '{{distance}} ezelőtt',

View File

@@ -548,6 +548,8 @@ export const hyTranslations: DefaultTranslationsObject = {
'Դուք պատրաստվում եք հետ բերել այս փաստաթղթի փոփոխությունները դեպի իր հրապարակված վիճակին։ Համոզվա՞ծ եք։',
aboutToUnpublish:
'Դուք պատրաստվում եք այս փաստաթուղթը բերել չհրապարակված վիճակի։ Համոզվա՞ծ եք։',
aboutToUnpublishIn:
'Դուք պատրաստվում եք անհրատարակել այս փաստաթուղթը {{locale}} լեզվով։ Արդյոք համոզվել եք։',
aboutToUnpublishSelection:
'Դուք պատրաստվում եք ընտրության մեջ գտնվող բոլոր {{label}}-ները բերել չհրապարակված վիճակի։ Համոզվա՞ծ եք։',
autosave: 'Ինքնապահպանում',
@@ -593,6 +595,7 @@ export const hyTranslations: DefaultTranslationsObject = {
restoring: 'Վերականգնվում է...',
reverting: 'Հետ է բերվում...',
revertToPublished: 'Հետ բերել հրապարակված վիճակին',
revertUnsuccessful: 'Վերադարձը չեղարկվեց։ Առաջին առաջ հրատարակվող տարբերակը չգտնվել։',
saveDraft: 'Պահպանել սևագիրը',
scheduledSuccessfully: 'Հաջողությամբ պլանավորված։',
schedulePublish: 'Պլանավորել հրապարակումը',
@@ -603,6 +606,7 @@ export const hyTranslations: DefaultTranslationsObject = {
specificVersion: 'Մասնավոր Տարբերակ',
status: 'Կարգավիճակ',
unpublish: 'Բերել չհրապարակված վիճակի։',
unpublishedSuccessfully: 'Հրապարակումը հաջողակ չեղարկվել է:',
unpublishing: 'Բերվում է չհրապարակված վիճակի...',
version: 'Տարբերակ',
versionAgo: '{{distance}} առաջ',

View File

@@ -1,8 +1,6 @@
import { title } from 'process'
import type { DefaultTranslationsObject, Language } from '../types.js'
import type { Language } from '../types.js'
export const idTranslations = {
export const idTranslations: DefaultTranslationsObject = {
authentication: {
account: 'Akun',
accountOfCurrentUser: 'Akun pengguna saat ini',
@@ -29,11 +27,9 @@ export const idTranslations = {
forgotPassword: 'Lupa Kata Sandi',
forgotPasswordEmailInstructions:
'Silakan masukkan email Anda di bawah ini. Anda akan menerima pesan email dengan instruksi tentang cara mengatur ulang kata sandi Anda.',
forgotPasswordQuestion: 'Lupa kata sandi?',
forgotPasswordUsernameInstructions:
'Silakan masukkan nama pengguna Anda di bawah ini. Instruksi tentang cara mengatur ulang kata sandi Anda akan dikirim ke alamat email yang terkait dengan nama pengguna Anda.',
usernameNotValid: 'Nama pengguna yang diberikan tidak valid',
forgotPasswordQuestion: 'Lupa kata sandi?',
generate: 'Buat',
generateNewAPIKey: 'Buat kunci API baru',
generatingNewAPIKeyWillInvalidate:
@@ -71,6 +67,7 @@ export const idTranslations = {
tokenRefreshSuccessful: 'Penyegaran token berhasil.',
unableToVerify: 'Tidak Dapat Memverifikasi',
username: 'Nama Pengguna',
usernameNotValid: 'Nama pengguna yang diberikan tidak valid',
verified: 'Terverifikasi',
verifiedSuccessfully: 'Berhasil Diverifikasi',
verify: 'Verifikasi',
@@ -544,6 +541,8 @@ export const idTranslations = {
aboutToRevertToPublished:
'Anda akan mengembalikan perubahan dokumen ini ke keadaan yang dipublikasikan. Apakah Anda yakin?',
aboutToUnpublish: 'Anda akan membatalkan publikasi dokumen ini. Apakah Anda yakin?',
aboutToUnpublishIn:
'Anda akan membatalkan penerbitan dokumen ini dalam {{locale}}. Apakah Anda yakin?',
aboutToUnpublishSelection:
'Anda akan membatalkan publikasi semua {{label}} dalam pilihan. Apakah Anda yakin?',
autosave: 'Simpan Otomatis',
@@ -589,6 +588,8 @@ export const idTranslations = {
restoring: 'Memulihkan...',
reverting: 'Mengembalikan...',
revertToPublished: 'Kembali ke yang dipublikasikan',
revertUnsuccessful:
'Pembatalan tidak berhasil. Tidak ditemukan versi yang sebelumnya dipublikasikan.',
saveDraft: 'Simpan Draf',
scheduledSuccessfully: 'Berhasil dijadwalkan.',
schedulePublish: 'Jadwalkan Publikasi',
@@ -599,6 +600,7 @@ export const idTranslations = {
specificVersion: 'Versi Spesifik',
status: 'Status',
unpublish: 'Batalkan Publikasi',
unpublishedSuccessfully: 'Berhasil tidak dipublikasikan.',
unpublishing: 'Membatalkan publikasi...',
version: 'Versi',
versionAgo: '{{distance}} yang lalu',

View File

@@ -1,6 +1,6 @@
import type { Language } from '../types.js'
import type { DefaultTranslationsObject, Language } from '../types.js'
export const isTranslations = {
export const isTranslations: DefaultTranslationsObject = {
authentication: {
account: 'Aðgangur',
accountOfCurrentUser: 'Aðgangur núverandi notanda',
@@ -27,11 +27,9 @@ export const isTranslations = {
forgotPassword: 'Gleymdist lykilorð',
forgotPasswordEmailInstructions:
'Vinsamlegast sláðu inn netfangið þitt hér að neðan. Þú munt fá tölvupóst með leiðbeiningum um hvernig á að endurstilla lykilorðið þitt.',
forgotPasswordQuestion: 'Gleymdist lykilorðið?',
forgotPasswordUsernameInstructions:
'Vinsamlegast sláðu inn notandanafnið þitt hér að neðan. Leiðbeiningar um hvernig á að endurstilla lykilorðið þitt verða sendar á netfangið sem tengt er notandanafninu þínu.',
usernameNotValid: 'Notandanafnið sem gefið var upp er ekki gilt',
forgotPasswordQuestion: 'Gleymdist lykilorðið?',
generate: 'Búa til',
generateNewAPIKey: 'Búa til nýjan API lykil',
generatingNewAPIKeyWillInvalidate:
@@ -69,6 +67,7 @@ export const isTranslations = {
tokenRefreshSuccessful: 'Endurnýjun tokens tókst.',
unableToVerify: 'Ekki hægt að staðfesta',
username: 'Notandanafn',
usernameNotValid: 'Notandanafnið sem gefið var upp er ekki gilt',
verified: 'Staðfest',
verifiedSuccessfully: 'Staðfest',
verify: 'Staðfesta',
@@ -540,6 +539,8 @@ export const isTranslations = {
aboutToRevertToPublished:
'Þú ert að fara að snúa breytingum þessa skjals til baka í útgefna ástandið. Ertu viss?',
aboutToUnpublish: 'Þú ert að fara að fela þetta skjal. Ertu viss?',
aboutToUnpublishIn:
'Þú ert um það bil að afturkalla útgáfuna af þessum skjali í {{locale}}. Ertu viss?',
aboutToUnpublishSelection: 'Þú ert að fara að fela öll {{label}} í valinu. Ertu viss?',
autosave: 'Sjálfvirk vistun',
autosavedSuccessfully: 'Sjálfvirk vistun tókst.',
@@ -584,6 +585,7 @@ export const isTranslations = {
restoring: 'Endurheimti...',
reverting: 'Sný til baka...',
revertToPublished: 'Snúa til baka í útgefið',
revertUnsuccessful: 'Afturköllun mistókst. Engin fyrri útgáfu fundin.',
saveDraft: 'Vista drög',
scheduledSuccessfully: 'Áætlað.',
schedulePublish: 'Áætla útgáfu',
@@ -594,6 +596,7 @@ export const isTranslations = {
specificVersion: 'Tiltekin útgáfa',
status: 'Staða',
unpublish: 'Fela',
unpublishedSuccessfully: 'Óbirtist heppilega.',
unpublishing: 'Fel...',
version: 'Útgáfa',
versionAgo: '{{distance}} síðan',
@@ -601,7 +604,6 @@ export const isTranslations = {
versionCount_none: 'Engar útgáfur fundust',
versionCount_one: '{{count}} útgáfa fannst',
versionCount_other: '{{count}} útgáfur fundust',
versionCreatedOn: '{{version}} búin til þann:',
versionID: 'Útgáfuauðkenni',
versions: 'Útgáfur',
viewingVersion: 'Skoða útgáfu fyrir {{entityLabel}} {{documentTitle}}',

View File

@@ -545,6 +545,8 @@ export const itTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Stai per ripristinare le modifiche di questo documento al suo stato pubblicato. Sei sicuro?',
aboutToUnpublish: 'Stai per annullare la pubblicazione di questo documento. Sei sicuro?',
aboutToUnpublishIn:
'Stai per annullare la pubblicazione di questo documento in {{locale}}. Sei sicuro?',
aboutToUnpublishSelection:
'Stai per annullare la pubblicazione di tutte le {{label}} nella selezione. Sei sicuro?',
autosave: 'Salvataggio automatico',
@@ -590,6 +592,8 @@ export const itTranslations: DefaultTranslationsObject = {
restoring: 'Ripristino...',
reverting: 'Ritorno...',
revertToPublished: 'Ritorna alla versione pubblicata',
revertUnsuccessful:
'Annullamento non riuscito. Nessuna versione precedentemente pubblicata trovata.',
saveDraft: 'Salva Bozza',
scheduledSuccessfully: 'Programmato con successo.',
schedulePublish: 'Pubblicazione Programmata',
@@ -600,6 +604,7 @@ export const itTranslations: DefaultTranslationsObject = {
specificVersion: 'Versione Specifica',
status: 'Stato',
unpublish: 'Annulla pubblicazione',
unpublishedSuccessfully: 'Pubblicazione disattivata con successo.',
unpublishing: 'Annullamento pubblicazione...',
version: 'Versione',
versionAgo: '{{distance}} fa',

View File

@@ -540,6 +540,8 @@ export const jaTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'このデータの変更を公開時の状態に戻そうとしています。よろしいですか?',
aboutToUnpublish: 'このデータを非公開にしようとしています。よろしいですか?',
aboutToUnpublishIn:
'あなたはこのドキュメントを{{locale}}で非公開にしようとしています。よろしいですか?',
aboutToUnpublishSelection:
'選択したすべての{{label}}の公開を取り消そうとしています。よろしいですか?',
autosave: '自動保存',
@@ -585,6 +587,8 @@ export const jaTranslations: DefaultTranslationsObject = {
restoring: '復元しています...',
reverting: '内容を戻しています...',
revertToPublished: '公開時の内容に戻す',
revertUnsuccessful:
'元に戻すことができませんでした。以前に公開されたバージョンが見つかりませんでした。',
saveDraft: 'ドラフトを保存',
scheduledSuccessfully: '正常にスケジュールされました。',
schedulePublish: 'スケジュール公開',
@@ -595,6 +599,7 @@ export const jaTranslations: DefaultTranslationsObject = {
specificVersion: '特定のバージョン',
status: 'ステータス',
unpublish: '非公開',
unpublishedSuccessfully: '正常に未公開になりました。',
unpublishing: '非公開中...',
version: 'バージョン',
versionAgo: '{{distance}}前',

View File

@@ -534,6 +534,7 @@ export const koTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'이 문서의 변경 사항을 게시된 상태로 되돌리려고 합니다. 계속하시겠습니까?',
aboutToUnpublish: '이 문서를 게시 해제하려고 합니다. 계속하시겠습니까?',
aboutToUnpublishIn: '당신은 이 문서를 {{locale}}에서 공개를 취소하려고 합니다. 확실합니까?',
aboutToUnpublishSelection: '선택한 {{label}}을(를) 게시 해제하려고 합니다. 계속하시겠습니까?',
autosave: '자동 저장',
autosavedSuccessfully: '자동 저장이 완료되었습니다.',
@@ -578,6 +579,7 @@ export const koTranslations: DefaultTranslationsObject = {
restoring: '복원 중...',
reverting: '되돌리는 중...',
revertToPublished: '게시된 상태로 되돌리기',
revertUnsuccessful: '실패한 되돌리기. 이전에 게시된 버전을 찾을 수 없습니다.',
saveDraft: '초안 저장',
scheduledSuccessfully: '성공적으로 예약되었습니다.',
schedulePublish: '발행 일정',
@@ -588,6 +590,7 @@ export const koTranslations: DefaultTranslationsObject = {
specificVersion: '특정 버전',
status: '상태',
unpublish: '게시 해제',
unpublishedSuccessfully: '성공적으로 발행 취소되었습니다.',
unpublishing: '게시 해제 중...',
version: '버전',
versionAgo: '{{distance}} 전',

View File

@@ -544,6 +544,8 @@ export const ltTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Jūs ketinate atšaukti šio dokumento pakeitimus ir grįžti prie publikuotos versijos. Ar esate įsitikinęs?',
aboutToUnpublish: 'Jūs ketinate panaikinti šio dokumento publikavimą. Ar esate tikri?',
aboutToUnpublishIn:
'Jūs ketinate panaikinti šio dokumento publikaciją {{locale}}. Ar esate tikri?',
aboutToUnpublishSelection:
'Jūs ketinate atšaukti visų {{label}} pasirinkime. Ar esate įsitikinęs?',
autosave: 'Automatinis išsaugojimas',
@@ -589,6 +591,7 @@ export const ltTranslations: DefaultTranslationsObject = {
restoring: 'Atkuriamas...',
reverting: 'Grįžtama...',
revertToPublished: 'Grįžti prie publikuotojo',
revertUnsuccessful: 'Atkūrimas nepavyko. Ankstesnės publikuotos versijos nerasta.',
saveDraft: 'Išsaugoti juodraštį',
scheduledSuccessfully: 'Sėkmingai suplanuota.',
schedulePublish: 'Suplanuokite publikaciją',
@@ -599,6 +602,7 @@ export const ltTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifinė versija',
status: 'Būsena',
unpublish: 'Nebepublikuoti',
unpublishedSuccessfully: 'Sėkmingai nepublikuota.',
unpublishing: 'Nebepublikuojama...',
version: 'Versija',
versionAgo: 'prieš {{distance}}',

View File

@@ -540,6 +540,8 @@ export const lvTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Jūs grasāties atsaukt šī dokumenta izmaiņas uz publicēto versiju. Vai esat pārliecināts?',
aboutToUnpublish: 'Jūs grasāties atcelt šī dokumenta publicēšanu. Vai esat pārliecināts?',
aboutToUnpublishIn:
'Jūs gatavojaties atsaukt šī dokumenta publicēšanu {{locale}}. Vai esat pārliecināts?',
aboutToUnpublishSelection:
'Jūs grasāties atcelt publicēšanu visiem {{label}} izvēlētajā sarakstā. Vai esat pārliecināts?',
autosave: 'Automātiskā saglabāšana',
@@ -585,6 +587,7 @@ export const lvTranslations: DefaultTranslationsObject = {
restoring: 'Atjauno...',
reverting: 'Atgriež...',
revertToPublished: 'Atgriezt uz publicēto',
revertUnsuccessful: 'Atcelšana neizdevās. Iepriekš publicētā versija netika atrasta.',
saveDraft: 'Saglabāt melnrakstu',
scheduledSuccessfully: 'Veiksmīgi ieplānots.',
schedulePublish: 'Ieplānot publicēšanu',
@@ -595,6 +598,7 @@ export const lvTranslations: DefaultTranslationsObject = {
specificVersion: 'Konkrētā versija',
status: 'Statuss',
unpublish: 'Atcelt publicēšanu',
unpublishedSuccessfully: 'Veiksmīgi nepublicēts.',
unpublishing: 'Atceļ publicēšanu...',
version: 'Versija',
versionAgo: '{{distance}} pirms',

View File

@@ -549,6 +549,8 @@ export const myTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'သင်သည် အပြောင်းအလဲများကို အများဆိုင် အခြေအနေသို့ ပြန်ပြောင်းပါတော့မည်။ သေချာလား?',
aboutToUnpublish: 'အများဆိုင်မှ ပြန်ဖြုတ်တော့မည်။ သေချာလား',
aboutToUnpublishIn:
'Anda akan membatalkan penerbitan dokumen ini dalam {{locale}}. Adakah anda pasti?',
aboutToUnpublishSelection:
'သင်သည် ရွေးချယ်မှုတွင် {{label}} အားလုံးကို ထုတ်ဝေတော့မည် ဖြစ်သည်။ သေချာလား?',
autosave: 'အလိုအလျောက်သိမ်းဆည်းပါ။',
@@ -594,6 +596,7 @@ export const myTranslations: DefaultTranslationsObject = {
restoring: 'ပြန်ယူနေဆဲ...',
reverting: 'ပြန်ပြောင်းနေဆဲ...',
revertToPublished: 'အများဆိုင်သို့ ပြန်ပြောင်းပါ။',
revertUnsuccessful: 'Pulangan tidak berjaya. Tiada versi yang diterbitkan sebelumnya ditemui.',
saveDraft: 'မှုကြမ်းကို သိမ်းဆည်းမည်။',
scheduledSuccessfully: 'အောင်မြင်စွာ နေ့စွဲထားသည်။',
schedulePublish: 'ပြဌာန်းထုတ်ဝေချိန်း',
@@ -604,6 +607,7 @@ export const myTranslations: DefaultTranslationsObject = {
specificVersion: 'အထူးဗားရှင်း',
status: 'အခြေအနေ',
unpublish: 'ပြန်ဖြုတ်မည်။',
unpublishedSuccessfully: 'Berjaya tidak diterbitkan.',
unpublishing: 'ပြန်ဖြုတ်နေဆဲ ...',
version: 'ဗားရှင်း',
versionAgo: '{{distance}} ကြာပြီ',

View File

@@ -540,6 +540,8 @@ export const nbTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Du er i ferd med å tilbakestille endringene i dette dokumentet til den publiserte tilstanden. Er du sikker?',
aboutToUnpublish: 'Du er i ferd med å avpublisere dette dokumentet. Er du sikker?',
aboutToUnpublishIn:
'Du er i ferd med å avpublisere dette dokumentet i {{locale}}. Er du sikker?',
aboutToUnpublishSelection:
'Du er i ferd med å oppheve publiseringen av alle {{label}} i utvalget. Er du sikker?',
autosave: 'Lagre automatisk',
@@ -585,6 +587,7 @@ export const nbTranslations: DefaultTranslationsObject = {
restoring: 'Gjenoppretter...',
reverting: 'Tilbakestiller...',
revertToPublished: 'Tilbakestill til publisert',
revertUnsuccessful: 'Tilbakestilling mislyktes. Ingen tidligere publisert versjon funnet.',
saveDraft: 'Lagre utkast',
scheduledSuccessfully: 'Planlagt vellykket.',
schedulePublish: 'Planlegg Publisering',
@@ -595,6 +598,7 @@ export const nbTranslations: DefaultTranslationsObject = {
specificVersion: 'Spesifikk versjon',
status: 'Status',
unpublish: 'Avpubliser',
unpublishedSuccessfully: 'Avpublisert med suksess.',
unpublishing: 'Avpubliserer...',
version: 'Versjon',
versionAgo: '{{distance}} siden',

View File

@@ -549,6 +549,8 @@ export const nlTranslations: DefaultTranslationsObject = {
'U staat op het punt om de wijzigingen van dit document terug te draaien naar de gepubliceerde staat. Weet u het zeker?',
aboutToUnpublish:
'U staat op het punt om de publicatie van dit document ongedaan te maken. Weet u het zeker?',
aboutToUnpublishIn:
'U staat op het punt om dit document niet te publiceren in {{locale}}. Weet u het zeker?',
aboutToUnpublishSelection:
'You are about to unpublish all {{label}} in the selection. Are you sure?',
autosave: 'Automatisch bewaren',
@@ -594,6 +596,7 @@ export const nlTranslations: DefaultTranslationsObject = {
restoring: 'Herstellen...',
reverting: 'Terugdraaien...',
revertToPublished: 'Terugdraaien naar gepubliceerde versie',
revertUnsuccessful: 'Terugdraaien mislukt. Geen eerder gepubliceerde versie gevonden.',
saveDraft: 'Bewaar concept',
scheduledSuccessfully: 'Succesvol gepland.',
schedulePublish: 'Publicatie plannen',
@@ -604,6 +607,7 @@ export const nlTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifieke versie',
status: 'Status',
unpublish: 'Publicatie ongedaan maken',
unpublishedSuccessfully: 'Succesvol niet gepubliceerd.',
unpublishing: 'Publicatie ongedaan maken...',
version: 'Versie',
versionAgo: '{{distance}} geleden',

View File

@@ -538,6 +538,7 @@ export const plTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Zamierzasz przywrócić zmiany w tym dokumencie do stanu opublikowanego. Jesteś pewien?',
aboutToUnpublish: 'Zamierzasz cofnąć publikację tego dokumentu. Jesteś pewien?',
aboutToUnpublishIn: 'Zamierzasz opublikować ten dokument w {{locale}}. Czy jesteś pewny?',
aboutToUnpublishSelection:
'Zamierzasz cofnąć publikację wszystkich {{label}} w zaznaczeniu. Jesteś pewny?',
autosave: 'Autozapis',
@@ -583,6 +584,8 @@ export const plTranslations: DefaultTranslationsObject = {
restoring: 'Przywracanie...',
reverting: 'Cofanie...',
revertToPublished: 'Przywróć do opublikowanego',
revertUnsuccessful:
'Cofnięcie nie powiodło się. Nie znaleziono poprzednio opublikowanej wersji.',
saveDraft: 'Zapisz szkic',
scheduledSuccessfully: 'Zaplanowano pomyślnie.',
schedulePublish: 'Zaplanuj publikację',
@@ -593,6 +596,7 @@ export const plTranslations: DefaultTranslationsObject = {
specificVersion: 'Konkretna Wersja',
status: 'Status',
unpublish: 'Cofnij publikację',
unpublishedSuccessfully: 'Nieopublikowano pomyślnie.',
unpublishing: 'Cofanie publikacji...',
version: 'Wersja',
versionAgo: '{{distance}} temu',

View File

@@ -542,6 +542,7 @@ export const ptTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Você está prestes a reverter as alterações desse documento para seu estado de publicação. Tem certeza?',
aboutToUnpublish: 'Você está prestes a despublicar esse documento. Tem certeza?',
aboutToUnpublishIn: 'Está prestes a despublicar este documento em {{locale}}. Tem certeza?',
aboutToUnpublishSelection:
'Você está prestes a cancelar a publicação de todos os {{label}} na seleção. Tem certeza?',
autosave: 'Salvamento automático',
@@ -587,6 +588,7 @@ export const ptTranslations: DefaultTranslationsObject = {
restoring: 'Restaurando...',
reverting: 'Revertendo...',
revertToPublished: 'Reverter para publicado',
revertUnsuccessful: 'Reversão malsucedida. Nenhuma versão publicada anteriormente encontrada.',
saveDraft: 'Salvar rascunho',
scheduledSuccessfully: 'Agendado com sucesso.',
schedulePublish: 'Agendar Publicação',
@@ -597,6 +599,7 @@ export const ptTranslations: DefaultTranslationsObject = {
specificVersion: 'Versão Específica',
status: 'Status',
unpublish: 'Despublicar',
unpublishedSuccessfully: 'Não publicado com sucesso.',
unpublishing: 'Despublicando...',
version: 'Versão',
versionAgo: 'há {{distance}}',

View File

@@ -549,6 +549,8 @@ export const roTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Sunteți pe cale să readuceți modificările aduse acestui document la starea sa publicată. Sunteți sigur?',
aboutToUnpublish: 'Sunteți pe cale să nepublicați acest document. Sunteți sigur?',
aboutToUnpublishIn:
'Sunteți pe cale să anulați publicarea acestui document în {{locale}}. Sunteți sigur?',
aboutToUnpublishSelection:
'Sunteți pe punctul de a nepublica toate {{label}} din selecție. Sunteți sigur?',
autosave: 'Autosalvare',
@@ -594,6 +596,7 @@ export const roTranslations: DefaultTranslationsObject = {
restoring: 'Restaurare...',
reverting: 'Revenire...',
revertToPublished: 'Reveniți la publicat',
revertUnsuccessful: 'Revenire nereușită. Nicio versiune publicată anterior nu a fost găsită.',
saveDraft: 'Salvați proiectul',
scheduledSuccessfully: 'Programat cu succes.',
schedulePublish: 'Programare Publicare',
@@ -604,6 +607,7 @@ export const roTranslations: DefaultTranslationsObject = {
specificVersion: 'Versiunea specifică',
status: 'Status',
unpublish: 'Dezpublicare',
unpublishedSuccessfully: 'Nepublicat cu succes.',
unpublishing: 'Dezpublicare...',
version: 'Versiune',
versionAgo: '{{distance}} în urmă',

View File

@@ -536,6 +536,7 @@ export const rsTranslations: DefaultTranslationsObject = {
aboutToRestoreGlobal: 'Вратићете глобални {{label}} у стање у којем је био {{versionDate}}.',
aboutToRevertToPublished: 'Вратићете промене у документу у објављено стање. Да ли сте сигурни?',
aboutToUnpublish: 'Поништићете објаву овог документа. Да ли сте сигурни?',
aboutToUnpublishIn: 'Predstoje vam da povučete ovaj dokument na {{locale}}. Da li ste sigurni?',
aboutToUnpublishSelection:
'Управо ћете поништити објаву свих {{label}} у одабиру. Да ли сте сигурни?',
autosave: 'Аутоматско чување',
@@ -581,6 +582,7 @@ export const rsTranslations: DefaultTranslationsObject = {
restoring: 'Враћање...',
reverting: 'Враћање...',
revertToPublished: 'Врати на објављено',
revertUnsuccessful: 'Povratak neuspešan. Nije pronađena prethodno objavljena verzija.',
saveDraft: 'Сачувај нацрт',
scheduledSuccessfully: 'Успешно заказано.',
schedulePublish: 'Planiranje publikovanja',
@@ -591,6 +593,7 @@ export const rsTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifična verzija',
status: 'Статус',
unpublish: 'Поништи објаву',
unpublishedSuccessfully: 'Uspešno povučeno sa objave.',
unpublishing: 'Поништавање објаве...',
version: 'Верзија',
versionAgo: 'pre {{distance}}',

View File

@@ -538,6 +538,8 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Vratićete promene u dokumentu u objavljeno stanje. Da li ste sigurni?',
aboutToUnpublish: 'Poništićete objavu ovog dokumenta. Da li ste sigurni?',
aboutToUnpublishIn:
'Uskoro ćete povući objavljivanje ovog dokumenta na {{locale}}. Da li ste sigurni?',
aboutToUnpublishSelection:
'Upravo ćete poništiti objavu svih {{label}} u odabiru. Da li ste sigurni?',
autosave: 'Automatsko čuvanje',
@@ -583,6 +585,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
restoring: 'Vraćanje...',
reverting: 'Vraćanje...',
revertToPublished: 'Vrati na objavljeno',
revertUnsuccessful: 'Povratak nije uspeo. Nije pronađena prethodno objavljena verzija.',
saveDraft: 'Sačuvaj nacrt',
scheduledSuccessfully: 'Uspešno zakazano.',
schedulePublish: 'Zakaži objavljivanje',
@@ -593,6 +596,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifična verzija',
status: 'Status',
unpublish: 'Poništi objavu',
unpublishedSuccessfully: 'Uspješno nije objavljeno.',
unpublishing: 'Poništavanje objave...',
version: 'Verzija',
versionAgo: 'pre {{distance}}',

View File

@@ -542,6 +542,8 @@ export const ruTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Вы собираетесь вернуть изменения этого документа к его опубликованному состоянию. Вы уверены?',
aboutToUnpublish: 'Вы собираетесь отменить публикацию этого документа. Вы уверены?',
aboutToUnpublishIn:
'Вы собираетесь снять с публикации этот документ на {{locale}}. Вы уверены?',
aboutToUnpublishSelection:
'Вы собираетесь отменить публикацию всех выбранных {{label}}. Вы уверены?',
autosave: 'Автосохранение',
@@ -587,6 +589,7 @@ export const ruTranslations: DefaultTranslationsObject = {
restoring: 'Восстановление...',
reverting: 'Возврат...',
revertToPublished: 'Вернуться к опубликованному',
revertUnsuccessful: 'Откат не удался. Ранее опубликованная версия не найдена.',
saveDraft: 'Сохранить черновик',
scheduledSuccessfully: 'Успешно запланировано.',
schedulePublish: 'Планирование публикации',
@@ -597,6 +600,7 @@ export const ruTranslations: DefaultTranslationsObject = {
specificVersion: 'Конкретная версия',
status: 'Статус',
unpublish: 'Отменить публикацию',
unpublishedSuccessfully: 'Успешно снято с публикации.',
unpublishing: 'Отмена публикации...',
version: 'Версия',
versionAgo: '{{distance}} назад',

View File

@@ -538,6 +538,7 @@ export const skTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Chystáte sa vrátiť zmeny tohto dokumentu do jeho publikovaného stavu. Ste si istý?',
aboutToUnpublish: 'Chystáte sa zrušiť publikovanie tohto dokumentu. Ste si istý?',
aboutToUnpublishIn: 'Chystáte sa odpublikovať tento dokument v {{locale}}. Ste si istý?',
aboutToUnpublishSelection:
'Chystáte sa zrušiť publikovanie všetkých {{label}} vo výbere. Ste si istý?',
autosave: 'Automatické uloženie',
@@ -583,6 +584,7 @@ export const skTranslations: DefaultTranslationsObject = {
restoring: 'Obnovovanie...',
reverting: 'Vracanie...',
revertToPublished: 'Vrátiť sa k publikovanému',
revertUnsuccessful: 'Vrátenie neúspešné. Nebola nájdená žiadna predtým publikovaná verzia.',
saveDraft: 'Uložiť návrh',
scheduledSuccessfully: 'Úspešne naplánované.',
schedulePublish: 'Naplánovať publikovanie',
@@ -593,6 +595,7 @@ export const skTranslations: DefaultTranslationsObject = {
specificVersion: 'Špecifická verzia',
status: 'Stav',
unpublish: 'Zrušiť publikovanie',
unpublishedSuccessfully: 'Úspešne nezverejnené.',
unpublishing: 'Zrušujem publikovanie...',
version: 'Verzia',
versionAgo: 'pred {{distance}}',

View File

@@ -538,6 +538,8 @@ export const slTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Spremembe tega dokumenta boste povrnili v objavljeno stanje. Ste prepričani?',
aboutToUnpublish: 'Ta dokument boste umaknili iz objave. Ste prepričani?',
aboutToUnpublishIn:
'Ravno boste prenehali z objavo tega dokumenta v {{locale}}. Ste prepričani?',
aboutToUnpublishSelection: 'Umaknili boste iz objave vse {{label}} v izboru. Ste prepričani?',
autosave: 'Samodejno shranjevanje',
autosavedSuccessfully: 'Samodejno shranjeno uspešno.',
@@ -582,6 +584,7 @@ export const slTranslations: DefaultTranslationsObject = {
restoring: 'Obnavljanje...',
reverting: 'Razveljavljanje...',
revertToPublished: 'Vrni na objavljeno',
revertUnsuccessful: 'Povrnitev ni uspela. Ni najdena nobena prej objavljena različica.',
saveDraft: 'Shrani osnutek',
scheduledSuccessfully: 'Uspešno načrtovano.',
schedulePublish: 'Razporedi objavo',
@@ -592,6 +595,7 @@ export const slTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifična različica',
status: 'Status',
unpublish: 'Razveljavi objavo',
unpublishedSuccessfully: 'Uspešno nepobjavljeno.',
unpublishing: 'Razveljavljanje objave...',
version: 'Različica',
versionAgo: 'pred {{distance}}',

View File

@@ -540,6 +540,7 @@ export const svTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Du kommer återställa det här dokumentets ändringar till dess publicerade tillstånd. Är du säker?',
aboutToUnpublish: 'Du kommer avpublicera detta dokument. Är du säker?',
aboutToUnpublishIn: 'Du står på väg att avpublicera detta dokument i {{locale}}. Är du säker?',
aboutToUnpublishSelection:
'Du är på väg att avpublicera alla {{label}} i urvalet. Är du säker?',
autosave: 'Spara automatiskt',
@@ -585,6 +586,7 @@ export const svTranslations: DefaultTranslationsObject = {
restoring: 'Återställer...',
reverting: 'Återställer...',
revertToPublished: 'Återgå till publicerad',
revertUnsuccessful: 'Återgången misslyckades. Ingen tidigare publicerad version hittades.',
saveDraft: 'Spara Utkast',
scheduledSuccessfully: 'Schemalagd',
schedulePublish: 'Schemalägg publicering',
@@ -595,6 +597,7 @@ export const svTranslations: DefaultTranslationsObject = {
specificVersion: 'Specifik version',
status: 'Status',
unpublish: 'Avpublicera',
unpublishedSuccessfully: 'Opublicerad framgångsrikt.',
unpublishing: 'Avpublicerar...',
version: 'Version',
versionAgo: '{{distance}} sedan',

View File

@@ -528,6 +528,7 @@ export const thTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'คุณกำลังจะย้อนการเปลี่ยนแปลงของเอกสารนี้ไปยังเวอร์ชันที่เผยแพร่อยู่ คุณต้องการดำเนินการต่อหรือไม่?',
aboutToUnpublish: 'คุณกำลังจะยกเลิกเผยแพร่เอกสารนี้ คุณต้องการดำเนินการต่อหรือไม่?',
aboutToUnpublishIn: 'คุณกำลังจะยกเลิกการเผยแพร่เอกสารนี้ใน {{locale}} คุณแน่ใจไหม?',
aboutToUnpublishSelection: 'คุณกำลังจะเลิกเผยแพร่ {{label}} ทั้งหมดในส่วนที่เลือก คุณแน่ใจไหม?',
autosave: 'บันทึกอัตโนมัติ',
autosavedSuccessfully: 'บันทึกอัตโนมัติสำเร็จ',
@@ -572,6 +573,7 @@ export const thTranslations: DefaultTranslationsObject = {
restoring: 'กำลังกู้คืน...',
reverting: 'กำลังย้อน...',
revertToPublished: 'ย้อนกลับไปเวอร์ชันที่เผยแพร่อยู่',
revertUnsuccessful: 'ย้อนกลับไม่สำเร็จ ไม่พบรุ่นที่เผยแพร่ก่อนหน้านี้',
saveDraft: 'บันทึกร่าง',
scheduledSuccessfully: 'ได้ทำการจัดตารางเรียบร้อยแล้ว',
schedulePublish: 'ตั้งเวลาเผยแพร่',
@@ -582,6 +584,7 @@ export const thTranslations: DefaultTranslationsObject = {
specificVersion: 'เวอร์ชันเฉพาะ',
status: 'สถานะ',
unpublish: 'หยุดเผยแพร่',
unpublishedSuccessfully: 'ยกเลิกการเผยแพร่เรียบร้อยแล้ว',
unpublishing: 'กำลังหยุดการเผยแพร่...',
version: 'เวอร์ชัน',
versionAgo: '{{distance}} ที่แล้ว',

View File

@@ -543,6 +543,7 @@ export const trTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Bu dökümanın değişikliklerini yayınladığı haline geri getirmek üzeresiniz. Devam etmek istiyor musunuz?',
aboutToUnpublish: 'Bu dökümanı yayından kaldırmak üzeresiniz. Devam etmek istiyor musunuz?',
aboutToUnpublishIn: "{{locale}}'da bu belgeyi yayından kaldırmak üzeresiniz. Emin misiniz?",
aboutToUnpublishSelection: 'Seçimdeki tüm {{label}} yayınını kaldırmak üzeresiniz. Emin misin?',
autosave: 'Otomatik kaydet',
autosavedSuccessfully: 'Otomatik kaydetme başarılı',
@@ -587,6 +588,7 @@ export const trTranslations: DefaultTranslationsObject = {
restoring: 'Geri döndürülüyor...',
reverting: 'Değişiklikler geri alınıyor...',
revertToPublished: 'Yayınlanana geri döndür',
revertUnsuccessful: 'Geri alım başarısız. Daha önce yayımlanan bir versiyon bulunamadı.',
saveDraft: 'Taslağı kaydet',
scheduledSuccessfully: 'Başarıyla planlandı.',
schedulePublish: 'Yayını Planla',
@@ -597,6 +599,7 @@ export const trTranslations: DefaultTranslationsObject = {
specificVersion: 'Belirli Sürüm',
status: 'Durum',
unpublish: 'Yayından Kaldır',
unpublishedSuccessfully: 'Başarıyla yayınlanmadı.',
unpublishing: 'Yayından kaldırılıyor...',
version: 'Sürüm',
versionAgo: '{{distance}} önce',

View File

@@ -538,6 +538,7 @@ export const ukTranslations: DefaultTranslationsObject = {
aboutToRevertToPublished:
'Ви бажаєте повернути зміни цього документа до його опублікованого стану. Ви впевнені?',
aboutToUnpublish: 'Ви бажаєте скасувати публікацю цього документа. Ви впевнені?',
aboutToUnpublishIn: 'Ви збираєтесь зняти з публікації цей документ у {{locale}}. Ви впевнені?',
aboutToUnpublishSelection:
'Ви бажаєте скасувати публікацію всіх {{label}} у вибірці. Ви впевнені?',
autosave: 'Автозбереження',
@@ -583,6 +584,7 @@ export const ukTranslations: DefaultTranslationsObject = {
restoring: 'Відновлення...',
reverting: 'Повернення до опублікованого стану...',
revertToPublished: 'Повернутися до опублікованого стану',
revertUnsuccessful: 'Повернення невдале. Не знайдено жодної раніше опублікованої версії.',
saveDraft: 'Зберегти чернетку',
scheduledSuccessfully: 'Успішно заплановано.',
schedulePublish: 'Розклад публікації',
@@ -593,6 +595,7 @@ export const ukTranslations: DefaultTranslationsObject = {
specificVersion: 'Специфічна версія',
status: 'Статус',
unpublish: 'Скасувати публікацію',
unpublishedSuccessfully: 'Успішно відмінено публікацію.',
unpublishing: 'Скасування публікації...',
version: 'Версія',
versionAgo: '{{distance}} тому',

View File

@@ -536,6 +536,8 @@ export const viTranslations: DefaultTranslationsObject = {
'Bạn chuẩn bị khôi phục lại bản toàn thể (global) của {{label}} về phiên bản {{versionDate}}.',
aboutToRevertToPublished: 'Bạn có muốn tái xuất bản bản nháp này không?',
aboutToUnpublish: 'Bạn có muốn ngưng xuất bản?',
aboutToUnpublishIn:
'Bạn đang chuẩn bị hủy xuất bản tài liệu này trong {{locale}}. Bạn có chắc không?',
aboutToUnpublishSelection: 'Bạn có muốn ngưng xuất bản tất cả {{label}} không?',
autosave: 'Tự động lưu dữ liệu',
autosavedSuccessfully: 'Đã tự động lưu thành công.',
@@ -580,6 +582,7 @@ export const viTranslations: DefaultTranslationsObject = {
restoring: 'Đang khôi phục...',
reverting: 'Đang về trạng thái cũ...',
revertToPublished: 'Quay về trạng thái đã xuất bản',
revertUnsuccessful: 'Không thể hoàn nguyên. Không tìm thấy phiên bản được xuất bản trước đó.',
saveDraft: 'Lưu bản nháp',
scheduledSuccessfully: 'Đã lên lịch thành công.',
schedulePublish: 'Lịch xuất bản',
@@ -590,6 +593,7 @@ export const viTranslations: DefaultTranslationsObject = {
specificVersion: 'Phiên bản cụ thể',
status: 'Trạng thái',
unpublish: 'Ẩn tài liệu',
unpublishedSuccessfully: 'Đã hủy công bố thành công.',
unpublishing: 'Đang ẩn tài liệu...',
version: 'Phiên bản',
versionAgo: '{{distance}} trước',

View File

@@ -512,6 +512,7 @@ export const zhTranslations: DefaultTranslationsObject = {
aboutToRestoreGlobal: '您要将全局的{{label}}恢复到{{versionDate}}时的状态',
aboutToRevertToPublished: '您将要把这个文档的内容还原到它的发布状态。您确定吗?',
aboutToUnpublish: '您即将取消发布这个文档。您确定吗?',
aboutToUnpublishIn: '您即将取消发布此文档在{{locale}}。您确定吗?',
aboutToUnpublishSelection: '您即将取消发布所选内容中的所有 {{label}}。 您确定吗?',
autosave: '自动保存',
autosavedSuccessfully: '自动保存成功。',
@@ -556,6 +557,7 @@ export const zhTranslations: DefaultTranslationsObject = {
restoring: '恢复中...',
reverting: '还原中...',
revertToPublished: '还原到已发布的版本',
revertUnsuccessful: '撤销失败。没有找到先前发布的版本。',
saveDraft: '保存草稿',
scheduledSuccessfully: '预约发布成功。',
schedulePublish: '预约发布',
@@ -566,6 +568,7 @@ export const zhTranslations: DefaultTranslationsObject = {
specificVersion: '特定版本',
status: '状态',
unpublish: '取消发布',
unpublishedSuccessfully: '成功取消发布。',
unpublishing: '取消发布中...',
version: '版本',
versionAgo: '{{distance}}前',

View File

@@ -512,6 +512,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
aboutToRestoreGlobal: '您即將將全域 {{label}} 還原至 {{versionDate}} 的狀態。',
aboutToRevertToPublished: '您即將還原此文件至已發佈狀態。確定要繼續?',
aboutToUnpublish: '您即將取消發佈此文件。確定要繼續?',
aboutToUnpublishIn: '您即將在{{locale}}中取消發布此文件。你確定嗎?',
aboutToUnpublishSelection: '您即將取消發佈所有選取的 {{label}}。確定要繼續?',
autosave: '自動儲存',
autosavedSuccessfully: '已成功自動儲存。',
@@ -556,6 +557,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
restoring: '還原中…',
reverting: '還原中…',
revertToPublished: '還原至已發佈版本',
revertUnsuccessful: '還原失敗。找不到以前發布的版本。',
saveDraft: '儲存草稿',
scheduledSuccessfully: '排程成功。',
schedulePublish: '排程發佈',
@@ -566,6 +568,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
specificVersion: '指定版本',
status: '狀態',
unpublish: '取消發佈',
unpublishedSuccessfully: '成功取消發布。',
unpublishing: '取消發佈中…',
version: '版本',
versionAgo: '{{distance}} 前',

View File

@@ -134,13 +134,13 @@ export const Autosave: React.FC<Props> = ({ id, collection, global: globalDoc })
if (collection && id) {
entitySlug = collection.slug
url = `${serverURL}${api}/${entitySlug}/${id}?draft=true&autosave=true&locale=${localeRef.current}`
url = `${serverURL}${api}/${entitySlug}/${id}?depth=0&draft=true&autosave=true&locale=${localeRef.current}`
method = 'PATCH'
}
if (globalDoc) {
entitySlug = globalDoc.slug
url = `${serverURL}${api}/globals/${entitySlug}?draft=true&autosave=true&locale=${localeRef.current}`
url = `${serverURL}${api}/globals/${entitySlug}?depth=0&draft=true&autosave=true&locale=${localeRef.current}`
method = 'POST'
}

View File

@@ -34,27 +34,42 @@ export const Status: React.FC = () => {
const {
config: {
experimental: { unpublishSpecificLocale: enableUnpublishSpecificLocale } = {},
routes: { api },
serverURL,
},
getEntityConfig,
} = useConfig()
const { reset: resetForm } = useForm()
const { getData, reset: resetForm } = useForm()
const { code: locale } = useLocale()
const { i18n, t } = useTranslation()
const formData = getData()
const unPublishModalSlug = `confirm-un-publish-${id}`
const localeUnPublishModalSlug = `confirm-un-publish-locale-${id}`
const revertModalSlug = `confirm-revert-${id}`
let statusToRender: 'changed' | 'draft' | 'published'
const [statusToRender, setStatusToRender] = React.useState<'changed' | 'draft' | 'published'>(
'draft',
)
if (unpublishedVersionCount > 0 && hasPublishedDoc) {
statusToRender = 'changed'
} else if (!hasPublishedDoc) {
statusToRender = 'draft'
} else if (hasPublishedDoc && unpublishedVersionCount <= 0) {
statusToRender = 'published'
}
const collectionConfig = getEntityConfig({ collectionSlug })
const globalConfig = getEntityConfig({ globalSlug })
const docConfig = collectionConfig || globalConfig
const autosaveEnabled =
typeof docConfig?.versions?.drafts === 'object' ? docConfig.versions.drafts.autosave : false
React.useEffect(() => {
if (autosaveEnabled) {
if (hasPublishedDoc) {
setStatusToRender(unpublishedVersionCount > 0 ? 'changed' : 'published')
}
} else {
setStatusToRender(formData._status || 'draft')
}
}, [autosaveEnabled, hasPublishedDoc, unpublishedVersionCount, formData._status])
const displayStatusKey = isTrashed
? hasPublishedDoc
@@ -63,67 +78,64 @@ export const Status: React.FC = () => {
: statusToRender
const performAction = useCallback(
async (action: 'revert' | 'unpublish') => {
async (action: 'revert' | 'unpublish', unpublishSpecificLocale?: boolean) => {
let url
let method
let publishedDocURL
let method: 'get' | 'patch' | 'post' = 'patch'
let body
const headers = {
'Accept-Language': i18n.language,
'Content-Type': 'application/json',
}
const baseUrl = collectionSlug
? `${serverURL}${api}/${collectionSlug}/${id}`
: globalSlug
? `${serverURL}${api}/globals/${globalSlug}`
: ''
if (action === 'unpublish') {
body = {
_status: 'draft',
}
}
if (collectionSlug) {
url = `${serverURL}${api}/${collectionSlug}/${id}?locale=${locale}&fallback-locale=null&depth=0`
method = 'patch'
}
if (globalSlug) {
url = `${serverURL}${api}/globals/${globalSlug}?locale=${locale}&fallback-locale=null&depth=0`
url = `${baseUrl}/unpublish${locale ? `?locale=${locale}` : ''}${unpublishSpecificLocale ? `&unpublishSpecificLocale=true` : ''}`
method = 'post'
} else {
publishedDocURL = `${baseUrl}?locale=${locale}&fallback-locale=null&depth=0`
url = `${baseUrl}?publishSpecificLocale=${locale}`
method = collectionSlug ? 'patch' : 'post'
}
if (action === 'revert') {
const publishedDoc = await requests
.get(url, {
headers: {
'Accept-Language': i18n.language,
'Content-Type': 'application/json',
},
.get(publishedDocURL, {
headers,
})
.then((res) => res.json())
body = publishedDoc
body = publishedDoc._status === 'published' ? publishedDoc : undefined
if (!body) {
toast.error(t('version:revertUnsuccessful'))
return
}
}
const res = await requests[method](url, {
body: JSON.stringify(body),
headers: {
'Accept-Language': i18n.language,
'Content-Type': 'application/json',
},
headers,
})
if (res.status === 200) {
let data
const json = await res.json()
if (globalSlug) {
data = json.result
} else if (collectionSlug) {
data = json.doc
}
const data = action === 'revert' && !globalSlug ? json.doc : json.result
// eslint-disable-next-line @typescript-eslint/no-floating-promises
resetForm(data)
toast.success(json.message)
incrementVersionCount()
setMostRecentVersionIsAutosaved(false)
if (action === 'unpublish') {
setHasPublishedDoc(false)
setStatusToRender('draft')
} else if (action === 'revert') {
setHasPublishedDoc(true)
incrementVersionCount()
setUnpublishedVersionCount(0)
}
} else {
@@ -136,8 +148,7 @@ export const Status: React.FC = () => {
} else {
toast.error(t('error:unPublishingDocument'))
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (err) {
} catch {
toast.error(t('error:unPublishingDocument'))
}
}
@@ -147,11 +158,11 @@ export const Status: React.FC = () => {
collectionSlug,
globalSlug,
id,
i18n.language,
incrementVersionCount,
locale,
resetForm,
serverURL,
i18n.language,
resetForm,
incrementVersionCount,
setUnpublishedVersionCount,
setMostRecentVersionIsAutosaved,
t,
@@ -188,6 +199,27 @@ export const Status: React.FC = () => {
modalSlug={unPublishModalSlug}
onConfirm={() => performAction('unpublish')}
/>
{enableUnpublishSpecificLocale && (
// TODO: update when we get UI design
<>
&nbsp;&mdash;&nbsp;
<Button
buttonStyle="none"
className={`${baseClass}__action`}
id={`action-unpublish-locale`}
onClick={() => toggleModal(localeUnPublishModalSlug)}
>
{t('version:unpublish')} ({locale})
</Button>
<ConfirmationModal
body={t('version:aboutToUnpublishIn', { locale })}
confirmingLabel={t('version:unpublishing')}
heading={t('version:confirmUnpublish')}
modalSlug={localeUnPublishModalSlug}
onConfirm={() => performAction('unpublish', true)}
/>
</>
)}
</React.Fragment>
)}
{!isTrashed && canUpdate && statusToRender === 'changed' && (

View File

@@ -134,35 +134,37 @@ export function fieldReducer(state: FormState, action: FieldAction): FormState {
case 'DUPLICATE_ROW': {
const { path, rowIndex } = action
const { remainingFields, rows } = separateRows(path, state)
const rowsMetadata = [...(state[path].rows || [])]
const rowsWithDuplicate = [...(state[path].rows || [])]
const duplicateRowMetadata = deepCopyObjectSimpleWithoutReactComponents(
rowsMetadata[rowIndex],
)
const newRow = deepCopyObjectSimpleWithoutReactComponents(rowsWithDuplicate[rowIndex])
if (duplicateRowMetadata.id) {
duplicateRowMetadata.id = new ObjectId().toHexString()
const newRowID = new ObjectId().toHexString()
if (newRow.id) {
newRow.id = newRowID
}
if (rowsMetadata[rowIndex]?.customComponents?.RowLabel) {
duplicateRowMetadata.customComponents = {
RowLabel: rowsMetadata[rowIndex].customComponents.RowLabel,
if (rowsWithDuplicate[rowIndex]?.customComponents?.RowLabel) {
newRow.customComponents = {
RowLabel: rowsWithDuplicate[rowIndex].customComponents.RowLabel,
}
}
const duplicateRowState = deepCopyObjectSimpleWithoutReactComponents(rows[rowIndex])
if (duplicateRowState.id) {
duplicateRowState.id.value = new ObjectId().toHexString()
duplicateRowState.id.initialValue = new ObjectId().toHexString()
duplicateRowState.id.value = newRowID
duplicateRowState.id.initialValue = newRowID
}
for (const key of Object.keys(duplicateRowState).filter((key) => key.endsWith('.id'))) {
const idState = duplicateRowState[key]
const newNestedFieldID = new ObjectId().toHexString()
if (idState && typeof idState.value === 'string' && ObjectId.isValid(idState.value)) {
duplicateRowState[key].value = new ObjectId().toHexString()
duplicateRowState[key].initialValue = new ObjectId().toHexString()
duplicateRowState[key].value = newNestedFieldID
duplicateRowState[key].initialValue = newNestedFieldID
}
}
@@ -170,7 +172,7 @@ export function fieldReducer(state: FormState, action: FieldAction): FormState {
if (Object.keys(duplicateRowState).length > 0) {
// Add new object containing subfield names to unflattenedRows array
rows.splice(rowIndex + 1, 0, duplicateRowState)
rowsMetadata.splice(rowIndex + 1, 0, duplicateRowMetadata)
rowsWithDuplicate.splice(rowIndex + 1, 0, newRow)
}
const newState = {
@@ -179,7 +181,7 @@ export function fieldReducer(state: FormState, action: FieldAction): FormState {
[path]: {
...state[path],
disableFormData: true,
rows: rowsMetadata,
rows: rowsWithDuplicate,
value: rows.length,
},
}

395
pnpm-lock.yaml generated
View File

@@ -44,7 +44,7 @@ importers:
version: 1.54.1
'@sentry/nextjs':
specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
'@sentry/node':
specifier: ^8.33.1
version: 8.37.1
@@ -1143,7 +1143,7 @@ importers:
dependencies:
'@sentry/nextjs':
specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
'@sentry/types':
specifier: ^8.33.1
version: 8.37.1
@@ -1247,35 +1247,35 @@ importers:
specifier: 2.0.0
version: 2.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@lexical/headless':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/html':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/link':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/list':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/mark':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/react':
specifier: 0.28.0
version: 0.28.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yjs@13.6.20)
specifier: 0.34.0
version: 0.34.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yjs@13.6.20)
'@lexical/rich-text':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/selection':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/table':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@lexical/utils':
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
'@payloadcms/next':
specifier: workspace:*
version: link:../next
@@ -1307,8 +1307,8 @@ importers:
specifier: 1.2.121
version: 1.2.121
lexical:
specifier: 0.28.0
version: 0.28.0
specifier: 0.34.0
version: 0.34.0
mdast-util-from-markdown:
specifier: 2.0.2
version: 2.0.2
@@ -1353,8 +1353,8 @@ importers:
specifier: 7.27.1
version: 7.27.1(@babel/core@7.27.3)
'@lexical/eslint-plugin':
specifier: 0.28.0
version: 0.28.0(eslint@9.22.0(jiti@1.21.6))
specifier: 0.34.0
version: 0.34.0(eslint@9.22.0(jiti@1.21.6))
'@payloadcms/eslint-config':
specifier: workspace:*
version: link:../eslint-config
@@ -2045,7 +2045,7 @@ importers:
version: link:../packages/ui
'@sentry/nextjs':
specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))
'@sentry/react':
specifier: ^7.77.0
version: 7.119.2(react@19.1.0)
@@ -3934,21 +3934,42 @@ packages:
'@floating-ui/core@1.6.8':
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
'@floating-ui/core@1.7.3':
resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
'@floating-ui/dom@1.6.12':
resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==}
'@floating-ui/dom@1.7.4':
resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
'@floating-ui/react-dom@2.1.2':
resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@floating-ui/react-dom@2.1.6':
resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@floating-ui/react@0.27.16':
resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@floating-ui/react@0.27.2':
resolution: {integrity: sha512-k/yP6a9K9QwhLfIu87iUZxCH6XN5z5j/VUHHq0dEnbZYY2Y9jz68E/LXFtK8dkiaYltS2WYohnyKC0VcwVneVg==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@floating-ui/utils@0.2.10':
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
'@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
@@ -4454,82 +4475,82 @@ packages:
'@juggle/resize-observer@3.4.0':
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
'@lexical/clipboard@0.28.0':
resolution: {integrity: sha512-LYqion+kAwFQJStA37JAEMxTL/m1WlZbotDfM/2WuONmlO0yWxiyRDI18oeCwhBD6LQQd9c3Ccxp9HFwUG1AVw==}
'@lexical/clipboard@0.34.0':
resolution: {integrity: sha512-u0Jx6Lncb3AKW/BrCfI7E2mhlTT0eCp2bR1hefHnKHo2LIxil4QHg4gtj+DWTxG2vkZVQvvsrGgiC+SX8Va81A==}
'@lexical/code@0.28.0':
resolution: {integrity: sha512-9LOKSWdRhxqAKRq5yveNC21XKtW4h2rmFNTucwMWZ9vLu9xteOHEwZdO1Qv82PFUmgCpAhg6EntmnZu9xD3K7Q==}
'@lexical/code@0.34.0':
resolution: {integrity: sha512-jsr8I+DEan0FuZnjQzQmuyebH0TpSV/6ESnjpe1x4egNvaedelDAJV3/v4AZcfJuB4yM2YHFbMgb7GbUmj7usw==}
'@lexical/devtools-core@0.28.0':
resolution: {integrity: sha512-Fk4itAjZ+MqTYXN84aE5RDf+wQX67N5nyo3JVxQTFZGAghx7Ux1xLWHB25zzD0YfjMtJ0NQROAbE3xdecZzxcQ==}
'@lexical/devtools-core@0.34.0':
resolution: {integrity: sha512-m+QOdJOwK/UolrwpSDOId4665XsfMG1+MrYGm/ZGx+J7kai/j50CTTBaZ8vdslL3oPiJxGzsqm/UDubpDS6wwQ==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@lexical/dragon@0.28.0':
resolution: {integrity: sha512-T6T8YaHnhU863ruuqmRHTLUYa8sfg/ArYcrnNGZGfpvvFTfFjpWb/ELOvOWo8N6Y/4fnSLjQ20aXexVW1KcTBQ==}
'@lexical/dragon@0.34.0':
resolution: {integrity: sha512-peKKMuI9/3GQMVZ2W5aZ8vn0YErBPbfyk6F9zV2koY6frIiCzL5pBJiPpXEvmweDxnxay2TYcFTOWYNGiUWuxw==}
'@lexical/eslint-plugin@0.28.0':
resolution: {integrity: sha512-aIerq82L8A/y8be7zTPF5ZYqOtzEbCRl+kVxoc8NmwJxFPoVJkdS3rblmKu2WYlJZbR1VQbpcVhQ+K14ynMViQ==}
'@lexical/eslint-plugin@0.34.0':
resolution: {integrity: sha512-BYHvDW6SawPkrzY9QTf94qSbtvSQNFYk4vEjNPLB6bPps0SJS/UkPlK5j6XQrcpDR3Y/HmYYCLuulDtAcSXgvQ==}
peerDependencies:
eslint: '>=7.31.0 || ^8.0.0'
'@lexical/hashtag@0.28.0':
resolution: {integrity: sha512-zcqX9Qna4lj96bAUfwSQSVEhYQ0O5erSjrIhOVqEgeQ5ubz0EvqnnMbbwNHIb2n6jzSwAvpD/3UZJZtolh+zVg==}
'@lexical/hashtag@0.34.0':
resolution: {integrity: sha512-/dRzbQt+Wdt7aMAzLbnNU/M2XDhlzNGI5XpMItfiWRTYA2LT1D9hupcTHPsRRMTpidy1+JPqxPTeqGyoqHKcZQ==}
'@lexical/headless@0.28.0':
resolution: {integrity: sha512-btcaTfw9I/xQ/XYom6iKWgsPecmRawGd/5jOhP7QDtLUp7gxgM7/kiCZFYa8jDJO6j20rXuWTkc81ynVpKvjow==}
'@lexical/headless@0.34.0':
resolution: {integrity: sha512-i7Tj8G9FJcuCOIYUOMh3qEZn6VMC7RPhSN9BhRg14E+FW7uRojjWaTCl65qVJC0Rcg3pvezNKGSLdQdykXyEPw==}
'@lexical/history@0.28.0':
resolution: {integrity: sha512-CHzDxaGDn6qCFFhU0YKP1B8sgEb++0Ksqsj6BfDL/6TMxoLNQwRQhP3BUNNXl1kvUhxTQZgk3b9MjJZRaFKG9Q==}
'@lexical/history@0.34.0':
resolution: {integrity: sha512-EVLMOWTmKTyt1LOxYP0lOYNWl9lNiVZkaUgZtvncQbQaZJGgEJqc0FrZvl5K+SrRIqXiSdQi7EEfgvGwgfRqCA==}
'@lexical/html@0.28.0':
resolution: {integrity: sha512-ayb0FPxr55Ko99/d9ewbfrApul4L0z+KpU2ZG03im7EvUPVLyIGLx4S0QguMDvQh0Vu+eJ7/EESuonDs5BCe3A==}
'@lexical/html@0.34.0':
resolution: {integrity: sha512-QoFm2P9PSFadInMCFGKJBQI8M2EPUjG6fGf+mUQG9WgX7gIAvTDr21lzUM+dNGtrBwtYxUSQizmUx1NeP6ShyQ==}
'@lexical/link@0.28.0':
resolution: {integrity: sha512-T5VKxpOnML5DcXv2lW3Le0vjNlcbdohZjS9f6PAvm6eX8EzBKDpLQCopr1/0KGdlLd1QrzQsykQrdU7ieC4LRg==}
'@lexical/link@0.34.0':
resolution: {integrity: sha512-4C8BtyqqFHZR1TA5osx/W6TrgPurxwwHsJhEflkZSRkcsyzwvtgWnfkp8vD3VGRsAUApYXmbl9InbJYzrs7k9Q==}
'@lexical/list@0.28.0':
resolution: {integrity: sha512-3a8QcZ75n2TLxP+xkSPJ2V15jsysMLMe0YoObG+ew/sioVelIU8GciYsWBo5GgQmwSzJNQJeK5cJ9p1b71z2cg==}
'@lexical/list@0.34.0':
resolution: {integrity: sha512-AVhkts0WMqfUZJsJIvw7wJXKtMF0AiUT8TdEeGS6G57AvcZgH+NXiHuTiqfLLYrezZ4NWDTu70M6WJkNd7LEng==}
'@lexical/mark@0.28.0':
resolution: {integrity: sha512-v5PzmTACsJrw3GvNZy2rgPxrNn9InLvLFoKqrSlNhhyvYNIAcuC4KVy00LKLja43Gw/fuB3QwKohYfAtM3yR3g==}
'@lexical/mark@0.34.0':
resolution: {integrity: sha512-doQ/qRllCV/jgdOT46jJtEeGgIc7QV/7E2HS/4ayjHtVwQZOE8Dio7zEXqweIO83fYyt8DTb9hmWP/khrmNM1g==}
'@lexical/markdown@0.28.0':
resolution: {integrity: sha512-F3JXClqN4cjmXYLDK0IztxkbZuqkqS/AVbxnhGvnDYHQ9Gp8l7BonczhOiPwmJCDubJrAACP0L9LCqyt0jDRFw==}
'@lexical/markdown@0.34.0':
resolution: {integrity: sha512-v3vp26LslpQ3CTTIci7jC9sUryL+OYG4gu21TOxO931yOF45j/RDgDKmEuySyaq5hcB6Q+kytALKUPfZtvIP1Q==}
'@lexical/offset@0.28.0':
resolution: {integrity: sha512-/SMDQgBPeWM936t04mtH6UAn3xAjP/meu9q136bcT3S7p7V8ew9JfNp9aznTPTx+2W3brJORAvUow7Xn1fSHmw==}
'@lexical/offset@0.34.0':
resolution: {integrity: sha512-j3tdGuQuiKPdOEsIBMd8ZU4Ka22v8LFCWWOlHyU7lT4xVoC6+921QKbdI7NY9w5lX8Yd28u5HFgHE2TaTsX4AA==}
'@lexical/overflow@0.28.0':
resolution: {integrity: sha512-ppmhHXEZVicBm05w9EVflzwFavTVNAe4q0bkabWUeW0IoCT3Vg2A3JT7PC9ypmp+mboUD195foFEr1BBSv1Y8Q==}
'@lexical/overflow@0.34.0':
resolution: {integrity: sha512-9f+9E++BxR4jtmcJg4VLnAmjT19IuOS5yyqaMvwEl7612DP5ch9sYG43HusL0w5cjUFbxX6Urkqp8bMPpo0BWA==}
'@lexical/plain-text@0.28.0':
resolution: {integrity: sha512-Jj2dCMDEfRuVetfDKcUes8J5jvAfZrLnILFlHxnu7y+lC+7R/NR403DYb3NJ8H7+lNiH1K15+U2K7ewbjxS6KQ==}
'@lexical/plain-text@0.34.0':
resolution: {integrity: sha512-OmbET24smoKR1v7FKqG8ZvOns01Eaadkdg1FzcrgwnoT7lHXI3W2tO0XJ0yAQ4Z9pGX6lTNVZPf0T4ywknKYYg==}
'@lexical/react@0.28.0':
resolution: {integrity: sha512-dWPnxrKrbQFjNqExqnaAsV0UEUgw/5M1ZYRWd5FGBGjHqVTCaX2jNHlKLMA68Od0VPIoOX2Zy1TYZ8ZKtsj5Dg==}
'@lexical/react@0.34.0':
resolution: {integrity: sha512-i1GyYyJUeFXe/wwk7WI+zqnx+gB8HsSfXp5vMA7prUbpAc6RooRL6XHlY2Fc2suCAmcZmrucLZt3UFKsb+F6KQ==}
peerDependencies:
react: 19.1.0
react-dom: 19.1.0
'@lexical/rich-text@0.28.0':
resolution: {integrity: sha512-y+vUWI+9uFupIb9UvssKU/DKcT9dFUZuQBu7utFkLadxCNyXQHeRjxzjzmvFiM3DBV0guPUDGu5VS5TPnIA+OA==}
'@lexical/rich-text@0.34.0':
resolution: {integrity: sha512-fFokmx+XsnertQLlBNBLxVDqirtUztDth47/7KZRfX2M63T9nX/jx2YvuUEaHdgJMG5NhcvKuQ727fRAel6AUA==}
'@lexical/selection@0.28.0':
resolution: {integrity: sha512-AJDi67Nsexyejzp4dEQSVoPov4P+FJ0t1v6DxUU+YmcvV56QyJQi6ue0i/xd8unr75ZufzLsAC0cDJJCEI7QDA==}
'@lexical/selection@0.34.0':
resolution: {integrity: sha512-qnnNdAihfsKxPJNK6s3crsZumCyvIPclbdNzC9xMWXFjAKvt1EPMnptD7Dy//DvA5nK/e/9qKCZQ+2kgxwsZiw==}
'@lexical/table@0.28.0':
resolution: {integrity: sha512-HMPCwXdj0sRWdlDzsHcNWRgbeKbEhn3L8LPhFnTq7q61gZ4YW2umdmuvQFKnIBcKq49drTH8cUwZoIwI8+AEEw==}
'@lexical/table@0.34.0':
resolution: {integrity: sha512-MzH0OREk4zIzkDNuiSBZEDBzazEKOh9X9koQcgClySOEqL/86DEPwoDuB5h1P4oTMRlzPzyKeZhksKNoY4QoBQ==}
'@lexical/text@0.28.0':
resolution: {integrity: sha512-PT/A2RZv+ktn7SG/tJkOpGlYE6zjOND59VtRHnV/xciZ+jEJVaqAHtWjhbWibAIZQAkv/O7UouuDqzDaNTSGAA==}
'@lexical/text@0.34.0':
resolution: {integrity: sha512-8T4RwSNP/cVEzg+yf4lMlfzyelnyZjSIsUl2sTiwHHb4RD/r6Zm+VrinCUhtMNq6aasVknV7GEi8Isx60x9XSQ==}
'@lexical/utils@0.28.0':
resolution: {integrity: sha512-Qw00DjkS1nRK7DLSgqJpJ77Ti2AuiOQ6m5eM38YojoWXkVmoxqKAUMaIbVNVKqjFgrQvKFF46sXxIJPbUQkB0w==}
'@lexical/utils@0.34.0':
resolution: {integrity: sha512-rLP1WTZFk+o3d4PiKkxs76ifj7q01PjqjbZjcvUyPxjL3ca5oL1iwPU3QqXXNSNrhnJ9oQoaI7fCeA7p+9/KSw==}
'@lexical/yjs@0.28.0':
resolution: {integrity: sha512-rKHpUEd3nrvMY7ghmOC0AeGSYT7YIviba+JViaOzrCX4/Wtv5C/3Sl7Io12Z9k+s1BKmy7C28bOdQHvRWaD7vQ==}
'@lexical/yjs@0.34.0':
resolution: {integrity: sha512-nnymAhO16k82ssiP9F0ph6Yq2icDImRgWeyI76SyRsYn1HqeOwaWUZV/bx03rFgYC0DNNtBQ6TS8me4CBjcVhA==}
peerDependencies:
yjs: '>=13.5.22'
@@ -9540,8 +9561,8 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
lexical@0.28.0:
resolution: {integrity: sha512-dLE3O1PZg0TlZxRQo9YDpjCjDUj8zluGyBO9MHdjo21qZmMUNrxQPeCRt8fn2s5l4HKYFQ1YNgl7k1pOJB/vZQ==}
lexical@0.34.0:
resolution: {integrity: sha512-oqQ87i49oGRt8u9qIXow+fWeqN6luRMtYAa1GAx1l9AaR3A8Tfrgnmj2+13ej6CMPK6JunKaUXbd+7FDy+s8XQ==}
lib0@0.2.98:
resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==}
@@ -14823,17 +14844,40 @@ snapshots:
dependencies:
'@floating-ui/utils': 0.2.8
'@floating-ui/core@1.7.3':
dependencies:
'@floating-ui/utils': 0.2.10
'@floating-ui/dom@1.6.12':
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/utils': 0.2.8
'@floating-ui/dom@1.7.4':
dependencies:
'@floating-ui/core': 1.7.3
'@floating-ui/utils': 0.2.10
'@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@floating-ui/dom': 1.6.12
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
'@floating-ui/react-dom@2.1.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@floating-ui/dom': 1.7.4
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
'@floating-ui/react@0.27.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@floating-ui/react-dom': 2.1.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@floating-ui/utils': 0.2.10
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
tabbable: 6.2.0
'@floating-ui/react@0.27.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -14842,6 +14886,8 @@ snapshots:
react-dom: 19.1.0(react@19.1.0)
tabbable: 6.2.0
'@floating-ui/utils@0.2.10': {}
'@floating-ui/utils@0.2.8': {}
'@google-cloud/paginator@5.0.2':
@@ -15350,157 +15396,158 @@ snapshots:
'@juggle/resize-observer@3.4.0': {}
'@lexical/clipboard@0.28.0':
'@lexical/clipboard@0.34.0':
dependencies:
'@lexical/html': 0.28.0
'@lexical/list': 0.28.0
'@lexical/selection': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/html': 0.34.0
'@lexical/list': 0.34.0
'@lexical/selection': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/code@0.28.0':
'@lexical/code@0.34.0':
dependencies:
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
prismjs: 1.30.0
'@lexical/devtools-core@0.28.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
'@lexical/devtools-core@0.34.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@lexical/html': 0.28.0
'@lexical/link': 0.28.0
'@lexical/mark': 0.28.0
'@lexical/table': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/html': 0.34.0
'@lexical/link': 0.34.0
'@lexical/mark': 0.34.0
'@lexical/table': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
'@lexical/dragon@0.28.0':
'@lexical/dragon@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/eslint-plugin@0.28.0(eslint@9.22.0(jiti@1.21.6))':
'@lexical/eslint-plugin@0.34.0(eslint@9.22.0(jiti@1.21.6))':
dependencies:
eslint: 9.22.0(jiti@1.21.6)
'@lexical/hashtag@0.28.0':
'@lexical/hashtag@0.34.0':
dependencies:
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/headless@0.28.0':
'@lexical/headless@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/history@0.28.0':
'@lexical/history@0.34.0':
dependencies:
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/html@0.28.0':
'@lexical/html@0.34.0':
dependencies:
'@lexical/selection': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/selection': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/link@0.28.0':
'@lexical/link@0.34.0':
dependencies:
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/list@0.28.0':
'@lexical/list@0.34.0':
dependencies:
'@lexical/selection': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/selection': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/mark@0.28.0':
'@lexical/mark@0.34.0':
dependencies:
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/markdown@0.28.0':
'@lexical/markdown@0.34.0':
dependencies:
'@lexical/code': 0.28.0
'@lexical/link': 0.28.0
'@lexical/list': 0.28.0
'@lexical/rich-text': 0.28.0
'@lexical/text': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/code': 0.34.0
'@lexical/link': 0.34.0
'@lexical/list': 0.34.0
'@lexical/rich-text': 0.34.0
'@lexical/text': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/offset@0.28.0':
'@lexical/offset@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/overflow@0.28.0':
'@lexical/overflow@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/plain-text@0.28.0':
'@lexical/plain-text@0.34.0':
dependencies:
'@lexical/clipboard': 0.28.0
'@lexical/selection': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/clipboard': 0.34.0
'@lexical/selection': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/react@0.28.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yjs@13.6.20)':
'@lexical/react@0.34.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yjs@13.6.20)':
dependencies:
'@lexical/devtools-core': 0.28.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@lexical/dragon': 0.28.0
'@lexical/hashtag': 0.28.0
'@lexical/history': 0.28.0
'@lexical/link': 0.28.0
'@lexical/list': 0.28.0
'@lexical/mark': 0.28.0
'@lexical/markdown': 0.28.0
'@lexical/overflow': 0.28.0
'@lexical/plain-text': 0.28.0
'@lexical/rich-text': 0.28.0
'@lexical/table': 0.28.0
'@lexical/text': 0.28.0
'@lexical/utils': 0.28.0
'@lexical/yjs': 0.28.0(yjs@13.6.20)
lexical: 0.28.0
'@floating-ui/react': 0.27.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@lexical/devtools-core': 0.34.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@lexical/dragon': 0.34.0
'@lexical/hashtag': 0.34.0
'@lexical/history': 0.34.0
'@lexical/link': 0.34.0
'@lexical/list': 0.34.0
'@lexical/mark': 0.34.0
'@lexical/markdown': 0.34.0
'@lexical/overflow': 0.34.0
'@lexical/plain-text': 0.34.0
'@lexical/rich-text': 0.34.0
'@lexical/table': 0.34.0
'@lexical/text': 0.34.0
'@lexical/utils': 0.34.0
'@lexical/yjs': 0.34.0(yjs@13.6.20)
lexical: 0.34.0
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
react-error-boundary: 3.1.4(react@19.1.0)
transitivePeerDependencies:
- yjs
'@lexical/rich-text@0.28.0':
'@lexical/rich-text@0.34.0':
dependencies:
'@lexical/clipboard': 0.28.0
'@lexical/selection': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/clipboard': 0.34.0
'@lexical/selection': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/selection@0.28.0':
'@lexical/selection@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/table@0.28.0':
'@lexical/table@0.34.0':
dependencies:
'@lexical/clipboard': 0.28.0
'@lexical/utils': 0.28.0
lexical: 0.28.0
'@lexical/clipboard': 0.34.0
'@lexical/utils': 0.34.0
lexical: 0.34.0
'@lexical/text@0.28.0':
'@lexical/text@0.34.0':
dependencies:
lexical: 0.28.0
lexical: 0.34.0
'@lexical/utils@0.28.0':
'@lexical/utils@0.34.0':
dependencies:
'@lexical/list': 0.28.0
'@lexical/selection': 0.28.0
'@lexical/table': 0.28.0
lexical: 0.28.0
'@lexical/list': 0.34.0
'@lexical/selection': 0.34.0
'@lexical/table': 0.34.0
lexical: 0.34.0
'@lexical/yjs@0.28.0(yjs@13.6.20)':
'@lexical/yjs@0.34.0(yjs@13.6.20)':
dependencies:
'@lexical/offset': 0.28.0
'@lexical/selection': 0.28.0
lexical: 0.28.0
'@lexical/offset': 0.34.0
'@lexical/selection': 0.34.0
lexical: 0.34.0
yjs: 13.6.20
'@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)':
@@ -16559,7 +16606,7 @@ snapshots:
'@sentry/utils': 7.119.2
localforage: 1.10.0
'@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))':
'@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.77.4))(react@19.1.0)(webpack@5.96.1(@swc/core@1.11.29))':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0)
@@ -21399,7 +21446,7 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
lexical@0.28.0: {}
lexical@0.34.0: {}
lib0@0.2.98:
dependencies:

View File

@@ -1,7 +1,5 @@
import type { CollectionConfig } from 'payload'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
export const postsSlug = 'posts'
export const PostsCollection: CollectionConfig = {
@@ -15,11 +13,14 @@ export const PostsCollection: CollectionConfig = {
type: 'text',
},
{
name: 'content',
type: 'richText',
editor: lexicalEditor({
features: ({ defaultFeatures }) => [...defaultFeatures],
}),
name: 'array',
type: 'array',
fields: [
{
name: 'title',
type: 'text',
},
],
},
],
}

View File

@@ -126,21 +126,12 @@ export interface UserAuthOperations {
export interface Post {
id: string;
title?: string | null;
content?: {
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;
array?:
| {
title?: string | null;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
@@ -279,7 +270,12 @@ export interface PayloadMigration {
*/
export interface PostsSelect<T extends boolean = true> {
title?: T;
content?: T;
array?:
| T
| {
title?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
}

View File

@@ -75,6 +75,10 @@ export default buildConfigWithDefaults({
label: 'Named Save To JWT',
saveToJWT: saveToJWTKey,
},
{
name: 'richText',
type: 'richText',
},
{
name: 'group',
type: 'group',

View File

@@ -124,6 +124,33 @@ describe('Auth', () => {
.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT })
.not.toContain('create-first-user')
})
test('richText field should should not be readOnly in create first user view', async () => {
const {
admin: {
routes: { createFirstUser: createFirstUserRoute },
},
routes: { admin: adminRoute },
} = getRoutes({})
// wait for create first user route
await page.goto(serverURL + `${adminRoute}${createFirstUserRoute}`)
await expect(page.locator('.create-first-user')).toBeVisible()
await waitForVisibleAuthFields()
const richTextRoot = page
.locator('.rich-text-lexical .ContentEditable__root[data-lexical-editor="true"]')
.first()
// ensure editor is present
await expect(richTextRoot).toBeVisible()
// core read-only checks
await expect(richTextRoot).toHaveAttribute('contenteditable', 'true')
await expect(richTextRoot).not.toHaveAttribute('aria-readonly', 'true')
})
})
describe('non create first user', () => {

View File

@@ -243,6 +243,21 @@ export interface User {
adminOnlyField?: string | null;
roles: ('admin' | 'editor' | 'moderator' | 'user' | 'viewer')[];
namedSaveToJWT?: string | null;
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;
group?: {
liftedSaveToJWT?: string | null;
};
@@ -503,6 +518,7 @@ export interface UsersSelect<T extends boolean = true> {
adminOnlyField?: T;
roles?: T;
namedSaveToJWT?: T;
richText?: T;
group?:
| T
| {

View File

@@ -2,8 +2,14 @@ import type { BrowserContext, Page } from '@playwright/test'
import { expect, test } from '@playwright/test'
import { copyPasteField } from 'helpers/e2e/copyPasteField.js'
import { addArrayRowBelow, duplicateArrayRow } from 'helpers/e2e/fields/array/index.js'
import { addBlock, openBlocksDrawer, reorderBlocks } from 'helpers/e2e/fields/blocks/index.js'
import { duplicateArrayRow } from 'helpers/e2e/fields/array/index.js'
import {
addBlock,
addBlockBelow,
duplicateBlock,
openBlocksDrawer,
reorderBlocks,
} from 'helpers/e2e/fields/blocks/index.js'
import { scrollEntirePage } from 'helpers/e2e/scrollEntirePage.js'
import { toggleBlockOrArrayRow } from 'helpers/e2e/toggleCollapsible.js'
import path from 'path'
@@ -127,22 +133,13 @@ describe('Block fields', () => {
test('should open blocks drawer from block row and add below', async () => {
await page.goto(url.create)
await addArrayRowBelow(page, { fieldName: 'blocks' })
const blocksDrawer = page.locator('[id^=drawer_1_blocks-drawer-]')
await expect(blocksDrawer).toBeVisible()
// select the first block in the drawer
const firstBlockSelector = blocksDrawer
.locator('.blocks-drawer__blocks .blocks-drawer__block')
.first()
await expect(firstBlockSelector).toContainText('Content')
await firstBlockSelector.click()
await addBlockBelow(page, { fieldName: 'blocks', blockToSelect: 'Content' })
// ensure the block was inserted beneath the first in the rows
const addedRow = page.locator('#field-blocks #blocks-row-1')
await expect(addedRow).toBeVisible()
await expect(addedRow.locator('.blocks-field__block-header')).toHaveText(
'Custom Block Label: Content 02',
) // went from `Number` to `Content`
@@ -151,19 +148,17 @@ describe('Block fields', () => {
test('should duplicate block', async () => {
await page.goto(url.create)
await duplicateArrayRow(page, { fieldName: 'blocks' })
const { rowCount } = await duplicateBlock(page, { fieldName: 'blocks' })
const blocks = page.locator('#field-blocks > .blocks-field__rows > div')
expect(await blocks.count()).toEqual(5)
expect(rowCount).toEqual(5)
})
test('should save when duplicating subblocks', async () => {
await page.goto(url.create)
await duplicateArrayRow(page, { fieldName: 'blocks', rowIndex: 2 })
const { rowCount } = await duplicateBlock(page, { fieldName: 'blocks', rowIndex: 2 })
const blocks = page.locator('#field-blocks > .blocks-field__rows > div')
expect(await blocks.count()).toEqual(5)
expect(rowCount).toEqual(5)
await page.click('#action-save')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')

View File

@@ -149,7 +149,7 @@ export interface Config {
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
};
db: {
defaultIDType: number;
defaultIDType: string;
};
globals: {};
globalsSelect: {};
@@ -215,7 +215,7 @@ export interface LocalizedTextReference2 {
* via the `definition` "users".
*/
export interface User {
id: number;
id: string;
canViewConditionalField?: boolean | null;
updatedAt: string;
createdAt: string;
@@ -240,7 +240,7 @@ export interface User {
* via the `definition` "select-versions-fields".
*/
export interface SelectVersionsField {
id: number;
id: string;
hasMany?: ('a' | 'b' | 'c' | 'd')[] | null;
array?:
| {
@@ -265,7 +265,7 @@ export interface SelectVersionsField {
* via the `definition` "array-fields".
*/
export interface ArrayField {
id: number;
id: string;
title?: string | null;
items: {
text: string;
@@ -369,7 +369,7 @@ export interface ArrayField {
* via the `definition` "block-fields".
*/
export interface BlockField {
id: number;
id: string;
blocks: (ContentBlock | NoBlockname | NumberBlock | SubBlocksBlock | TabsBlock)[];
duplicate: (ContentBlock | NoBlockname | NumberBlock | SubBlocksBlock | TabsBlock)[];
collapsedByDefaultBlocks: (
@@ -500,7 +500,7 @@ export interface BlockField {
| null;
relationshipBlocks?:
| {
relationship?: (number | null) | TextField;
relationship?: (string | null) | TextField;
id?: string | null;
blockName?: string | null;
blockType: 'relationships';
@@ -697,7 +697,7 @@ export interface LocalizedTabsBlock {
* via the `definition` "text-fields".
*/
export interface TextField {
id: number;
id: string;
text: string;
hiddenTextField?: string | null;
/**
@@ -749,7 +749,7 @@ export interface TextField {
* via the `definition` "checkbox-fields".
*/
export interface CheckboxField {
id: number;
id: string;
checkbox: boolean;
checkboxNotRequired?: boolean | null;
updatedAt: string;
@@ -760,7 +760,7 @@ export interface CheckboxField {
* via the `definition` "code-fields".
*/
export interface CodeField {
id: number;
id: string;
javascript?: string | null;
typescript?: string | null;
json?: string | null;
@@ -775,7 +775,7 @@ export interface CodeField {
* via the `definition` "collapsible-fields".
*/
export interface CollapsibleField {
id: number;
id: string;
text: string;
group: {
textWithinGroup?: string | null;
@@ -808,7 +808,7 @@ export interface CollapsibleField {
* via the `definition` "conditional-logic".
*/
export interface ConditionalLogic {
id: number;
id: string;
text: string;
toggleField?: boolean | null;
fieldWithDocIDCondition?: string | null;
@@ -922,7 +922,7 @@ export interface CustomRowId {
* via the `definition` "date-fields".
*/
export interface DateField {
id: number;
id: string;
default: string;
timeOnly?: string | null;
timeOnlyWithMiliseconds?: string | null;
@@ -967,7 +967,7 @@ export interface DateField {
* via the `definition` "email-fields".
*/
export interface EmailField {
id: number;
id: string;
email: string;
localizedEmail?: string | null;
emailWithAutocomplete?: string | null;
@@ -992,7 +992,7 @@ export interface EmailField {
* via the `definition` "radio-fields".
*/
export interface RadioField {
id: number;
id: string;
radio?: ('one' | 'two' | 'three') | null;
radioWithJsxLabelOption?: ('one' | 'two' | 'three') | null;
updatedAt: string;
@@ -1003,7 +1003,7 @@ export interface RadioField {
* via the `definition` "group-fields".
*/
export interface GroupField {
id: number;
id: string;
/**
* This is a group.
*/
@@ -1085,22 +1085,22 @@ export interface GroupField {
select?: ('one' | 'two')[] | null;
};
localizedGroupRel?: {
email?: (number | null) | EmailField;
email?: (string | null) | EmailField;
};
localizedGroupManyRel?: {
email?: (number | EmailField)[] | null;
email?: (string | EmailField)[] | null;
};
localizedGroupPolyRel?: {
email?: {
relationTo: 'email-fields';
value: number | EmailField;
value: string | EmailField;
} | null;
};
localizedGroupPolyHasManyRel?: {
email?:
| {
relationTo: 'email-fields';
value: number | EmailField;
value: string | EmailField;
}[]
| null;
};
@@ -1154,30 +1154,30 @@ export interface RowField {
* via the `definition` "indexed-fields".
*/
export interface IndexedField {
id: number;
id: string;
text: string;
uniqueText?: string | null;
uniqueRelationship?: (number | null) | TextField;
uniqueHasManyRelationship?: (number | TextField)[] | null;
uniqueHasManyRelationship_2?: (number | TextField)[] | null;
uniqueRelationship?: (string | null) | TextField;
uniqueHasManyRelationship?: (string | TextField)[] | null;
uniqueHasManyRelationship_2?: (string | TextField)[] | null;
uniquePolymorphicRelationship?: {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
} | null;
uniquePolymorphicRelationship_2?: {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
} | null;
uniqueHasManyPolymorphicRelationship?:
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}[]
| null;
uniqueHasManyPolymorphicRelationship_2?:
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}[]
| null;
uniqueRequiredText: string;
@@ -1213,7 +1213,7 @@ export interface IndexedField {
* via the `definition` "json-fields".
*/
export interface JsonField {
id: number;
id: string;
json?: {
array?: {
object?: {
@@ -1254,7 +1254,7 @@ export interface JsonField {
* via the `definition` "number-fields".
*/
export interface NumberField {
id: number;
id: string;
number?: number | null;
min?: number | null;
max?: number | null;
@@ -1289,7 +1289,7 @@ export interface NumberField {
* via the `definition` "point-fields".
*/
export interface PointField {
id: number;
id: string;
/**
* @minItems 2
* @maxItems 2
@@ -1320,83 +1320,83 @@ export interface PointField {
* via the `definition` "relationship-fields".
*/
export interface RelationshipField {
id: number;
id: string;
text?: string | null;
relationship:
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}
| {
relationTo: 'array-fields';
value: number | ArrayField;
value: string | ArrayField;
};
relationHasManyPolymorphic?:
| (
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}
| {
relationTo: 'array-fields';
value: number | ArrayField;
value: string | ArrayField;
}
)[]
| null;
relationToSelf?: (number | null) | RelationshipField;
relationToSelfSelectOnly?: (number | null) | RelationshipField;
relationWithAllowCreateToFalse?: (number | null) | User;
relationWithAllowEditToFalse?: (number | null) | User;
relationWithDynamicDefault?: (number | null) | User;
relationToSelf?: (string | null) | RelationshipField;
relationToSelfSelectOnly?: (string | null) | RelationshipField;
relationWithAllowCreateToFalse?: (string | null) | User;
relationWithAllowEditToFalse?: (string | null) | User;
relationWithDynamicDefault?: (string | null) | User;
relationHasManyWithDynamicDefault?: {
relationTo: 'users';
value: number | User;
value: string | User;
} | null;
relationshipWithMin?: (number | TextField)[] | null;
relationshipWithMax?: (number | TextField)[] | null;
relationshipHasMany?: (number | TextField)[] | null;
relationshipWithMin?: (string | TextField)[] | null;
relationshipWithMax?: (string | TextField)[] | null;
relationshipHasMany?: (string | TextField)[] | null;
array?:
| {
relationship?: (number | null) | TextField;
relationship?: (string | null) | TextField;
id?: string | null;
}[]
| null;
relationshipWithMinRows?:
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}[]
| null;
relationToRow?: (string | null) | RowField;
relationToRowMany?: (string | RowField)[] | null;
relationshipDrawer?: (number | null) | TextField;
relationshipDrawerReadOnly?: (number | null) | TextField;
relationshipDrawer?: (string | null) | TextField;
relationshipDrawerReadOnly?: (string | null) | TextField;
polymorphicRelationshipDrawer?:
| ({
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
} | null)
| ({
relationTo: 'array-fields';
value: number | ArrayField;
value: string | ArrayField;
} | null);
relationshipDrawerHasMany?: (number | TextField)[] | null;
relationshipDrawerHasMany?: (string | TextField)[] | null;
relationshipDrawerHasManyPolymorphic?:
| (
| {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
}
| {
relationTo: 'array-fields';
value: number | ArrayField;
value: string | ArrayField;
}
)[]
| null;
relationshipDrawerWithAllowCreateFalse?: (number | null) | TextField;
relationshipDrawerWithAllowCreateFalse?: (string | null) | TextField;
relationshipDrawerWithFilterOptions?: {
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
} | null;
updatedAt: string;
createdAt: string;
@@ -1406,7 +1406,7 @@ export interface RelationshipField {
* via the `definition` "select-fields".
*/
export interface SelectField {
id: number;
id: string;
select?: ('one' | 'two' | 'three') | null;
selectReadOnly?: ('one' | 'two' | 'three') | null;
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null;
@@ -1436,7 +1436,7 @@ export interface SelectField {
* via the `definition` "tabs-fields-2".
*/
export interface TabsFields2 {
id: number;
id: string;
tabsInArray?:
| {
text?: string | null;
@@ -1454,7 +1454,7 @@ export interface TabsFields2 {
* via the `definition` "tabs-fields".
*/
export interface TabsField {
id: number;
id: string;
/**
* This should not collapse despite there being many tabs pushing the main fields open.
*/
@@ -1556,9 +1556,9 @@ export interface TabWithName {
* via the `definition` "uploads".
*/
export interface Upload {
id: number;
id: string;
text?: string | null;
media?: (number | null) | Upload;
media?: (string | null) | Upload;
updatedAt: string;
createdAt: string;
url?: string | null;
@@ -1576,9 +1576,9 @@ export interface Upload {
* via the `definition` "uploads2".
*/
export interface Uploads2 {
id: number;
id: string;
text?: string | null;
media?: (number | null) | Uploads2;
media?: (string | null) | Uploads2;
updatedAt: string;
createdAt: string;
url?: string | null;
@@ -1596,8 +1596,8 @@ export interface Uploads2 {
* via the `definition` "uploads3".
*/
export interface Uploads3 {
id: number;
media?: (number | null) | Uploads3;
id: string;
media?: (string | null) | Uploads3;
updatedAt: string;
createdAt: string;
url?: string | null;
@@ -1615,9 +1615,9 @@ export interface Uploads3 {
* via the `definition` "uploads-multi".
*/
export interface UploadsMulti {
id: number;
id: string;
text?: string | null;
media?: (number | Upload)[] | null;
media?: (string | Upload)[] | null;
updatedAt: string;
createdAt: string;
}
@@ -1626,16 +1626,16 @@ export interface UploadsMulti {
* via the `definition` "uploads-poly".
*/
export interface UploadsPoly {
id: number;
id: string;
text?: string | null;
media?:
| ({
relationTo: 'uploads';
value: number | Upload;
value: string | Upload;
} | null)
| ({
relationTo: 'uploads2';
value: number | Uploads2;
value: string | Uploads2;
} | null);
updatedAt: string;
createdAt: string;
@@ -1645,17 +1645,17 @@ export interface UploadsPoly {
* via the `definition` "uploads-multi-poly".
*/
export interface UploadsMultiPoly {
id: number;
id: string;
text?: string | null;
media?:
| (
| {
relationTo: 'uploads';
value: number | Upload;
value: string | Upload;
}
| {
relationTo: 'uploads2';
value: number | Uploads2;
value: string | Uploads2;
}
)[]
| null;
@@ -1667,11 +1667,11 @@ export interface UploadsMultiPoly {
* via the `definition` "uploads-restricted".
*/
export interface UploadsRestricted {
id: number;
id: string;
text?: string | null;
uploadWithoutRestriction?: (number | null) | Upload;
uploadWithAllowCreateFalse?: (number | null) | Upload;
uploadMultipleWithAllowCreateFalse?: (number | Upload)[] | null;
uploadWithoutRestriction?: (string | null) | Upload;
uploadWithAllowCreateFalse?: (string | null) | Upload;
uploadMultipleWithAllowCreateFalse?: (string | Upload)[] | null;
updatedAt: string;
createdAt: string;
}
@@ -1680,7 +1680,7 @@ export interface UploadsRestricted {
* via the `definition` "ui-fields".
*/
export interface UiField {
id: number;
id: string;
text: string;
updatedAt: string;
createdAt: string;
@@ -1690,39 +1690,39 @@ export interface UiField {
* via the `definition` "payload-locked-documents".
*/
export interface PayloadLockedDocument {
id: number;
id: string;
document?:
| ({
relationTo: 'users';
value: number | User;
value: string | User;
} | null)
| ({
relationTo: 'select-versions-fields';
value: number | SelectVersionsField;
value: string | SelectVersionsField;
} | null)
| ({
relationTo: 'array-fields';
value: number | ArrayField;
value: string | ArrayField;
} | null)
| ({
relationTo: 'block-fields';
value: number | BlockField;
value: string | BlockField;
} | null)
| ({
relationTo: 'checkbox-fields';
value: number | CheckboxField;
value: string | CheckboxField;
} | null)
| ({
relationTo: 'code-fields';
value: number | CodeField;
value: string | CodeField;
} | null)
| ({
relationTo: 'collapsible-fields';
value: number | CollapsibleField;
value: string | CollapsibleField;
} | null)
| ({
relationTo: 'conditional-logic';
value: number | ConditionalLogic;
value: string | ConditionalLogic;
} | null)
| ({
relationTo: 'custom-id';
@@ -1730,27 +1730,27 @@ export interface PayloadLockedDocument {
} | null)
| ({
relationTo: 'custom-tab-id';
value: number | CustomTabId;
value: string | CustomTabId;
} | null)
| ({
relationTo: 'custom-row-id';
value: number | CustomRowId;
value: string | CustomRowId;
} | null)
| ({
relationTo: 'date-fields';
value: number | DateField;
value: string | DateField;
} | null)
| ({
relationTo: 'email-fields';
value: number | EmailField;
value: string | EmailField;
} | null)
| ({
relationTo: 'radio-fields';
value: number | RadioField;
value: string | RadioField;
} | null)
| ({
relationTo: 'group-fields';
value: number | GroupField;
value: string | GroupField;
} | null)
| ({
relationTo: 'row-fields';
@@ -1758,76 +1758,76 @@ export interface PayloadLockedDocument {
} | null)
| ({
relationTo: 'indexed-fields';
value: number | IndexedField;
value: string | IndexedField;
} | null)
| ({
relationTo: 'json-fields';
value: number | JsonField;
value: string | JsonField;
} | null)
| ({
relationTo: 'number-fields';
value: number | NumberField;
value: string | NumberField;
} | null)
| ({
relationTo: 'point-fields';
value: number | PointField;
value: string | PointField;
} | null)
| ({
relationTo: 'relationship-fields';
value: number | RelationshipField;
value: string | RelationshipField;
} | null)
| ({
relationTo: 'select-fields';
value: number | SelectField;
value: string | SelectField;
} | null)
| ({
relationTo: 'tabs-fields-2';
value: number | TabsFields2;
value: string | TabsFields2;
} | null)
| ({
relationTo: 'tabs-fields';
value: number | TabsField;
value: string | TabsField;
} | null)
| ({
relationTo: 'text-fields';
value: number | TextField;
value: string | TextField;
} | null)
| ({
relationTo: 'uploads';
value: number | Upload;
value: string | Upload;
} | null)
| ({
relationTo: 'uploads2';
value: number | Uploads2;
value: string | Uploads2;
} | null)
| ({
relationTo: 'uploads3';
value: number | Uploads3;
value: string | Uploads3;
} | null)
| ({
relationTo: 'uploads-multi';
value: number | UploadsMulti;
value: string | UploadsMulti;
} | null)
| ({
relationTo: 'uploads-poly';
value: number | UploadsPoly;
value: string | UploadsPoly;
} | null)
| ({
relationTo: 'uploads-multi-poly';
value: number | UploadsMultiPoly;
value: string | UploadsMultiPoly;
} | null)
| ({
relationTo: 'uploads-restricted';
value: number | UploadsRestricted;
value: string | UploadsRestricted;
} | null)
| ({
relationTo: 'ui-fields';
value: number | UiField;
value: string | UiField;
} | null);
globalSlug?: string | null;
user: {
relationTo: 'users';
value: number | User;
value: string | User;
};
updatedAt: string;
createdAt: string;
@@ -1837,10 +1837,10 @@ export interface PayloadLockedDocument {
* via the `definition` "payload-preferences".
*/
export interface PayloadPreference {
id: number;
id: string;
user: {
relationTo: 'users';
value: number | User;
value: string | User;
};
key?: string | null;
value?:
@@ -1860,7 +1860,7 @@ export interface PayloadPreference {
* via the `definition` "payload-migrations".
*/
export interface PayloadMigration {
id: number;
id: string;
name?: string | null;
batch?: number | null;
updatedAt: string;

View File

@@ -1,5 +1,9 @@
import React from 'react'
export const ArrayRowLabel = () => {
return <p id="custom-array-row-label">This is a custom component</p>
export const ArrayRowLabel = (props) => {
return (
<p data-id={props.value[props?.rowNumber - 1]?.id} id="custom-array-row-label">
This is a custom component
</p>
)
}

View File

@@ -6,7 +6,12 @@ import { expect, test } from '@playwright/test'
import { assertElementStaysVisible } from 'helpers/e2e/assertElementStaysVisible.js'
import { assertNetworkRequests } from 'helpers/e2e/assertNetworkRequests.js'
import { assertRequestBody } from 'helpers/e2e/assertRequestBody.js'
import { addArrayRowAsync, removeArrayRow } from 'helpers/e2e/fields/array/index.js'
import {
addArrayRow,
addArrayRowAsync,
duplicateArrayRow,
removeArrayRow,
} from 'helpers/e2e/fields/array/index.js'
import { addBlock } from 'helpers/e2e/fields/blocks/index.js'
import { waitForAutoSaveToRunAndComplete } from 'helpers/e2e/waitForAutoSaveToRunAndComplete.js'
import * as path from 'path'
@@ -454,6 +459,34 @@ test.describe('Form State', () => {
await expect(computedTitleField).toHaveValue('Test Title 2')
})
test('array and block rows and maintain consistent row IDs across duplication', async () => {
await page.goto(postsUrl.create)
await addArrayRow(page, { fieldName: 'array' })
const row0 = page.locator('#field-array #array-row-0')
await expect(row0.locator('#custom-array-row-label')).toHaveAttribute('data-id')
await expect(row0.locator('#field-array__0__id')).toHaveValue(
(await row0.locator('#custom-array-row-label').getAttribute('data-id'))!,
)
await duplicateArrayRow(page, { fieldName: 'array' })
const row1 = page.locator('#field-array #array-row-1')
await expect(row1.locator('#custom-array-row-label')).toHaveAttribute('data-id')
await expect(row1.locator('#custom-array-row-label')).not.toHaveAttribute(
'data-id',
(await row0.locator('#custom-array-row-label').getAttribute('data-id'))!,
)
await expect(row1.locator('#field-array__1__id')).toHaveValue(
(await row1.locator('#custom-array-row-label').getAttribute('data-id'))!,
)
})
describe('Throttled tests', () => {
let cdpSession: CDPSession

Some files were not shown because too many files have changed in this diff Show More