-
Notifications
You must be signed in to change notification settings - Fork 3.2k
feat: add Esperanto translation #5705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
behilam
wants to merge
5,792
commits into
payloadcms:2.x
Choose a base branch
from
behilam:main
base: 2.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Contributor
Author
|
Edit: The tests are passing now in local with the new changes added to main. |
Contributor
Author
|
Hi! I updated this PR with the latest changes from main. Is there something else needed? |
Supports grouping documents by specific fields within the list view. For example, imagine having a "posts" collection with a "categories" field. To report on each specific category, you'd traditionally filter for each category, one at a time. This can be quite inefficient, especially with large datasets. Now, you can interact with all categories simultaneously, grouped by distinct values. Here is a simple demonstration: https://github.com/user-attachments/assets/0dcd19d2-e983-47e6-9ea2-cfdd2424d8b5 Enable on any collection by setting the `admin.groupBy` property: ```ts import type { CollectionConfig } from 'payload' const MyCollection: CollectionConfig = { // ... admin: { groupBy: true } } ``` This is currently marked as beta to gather feedback while we reach full stability, and to leave room for API changes and other modifications. Use at your own risk. Note: when using `groupBy`, bulk editing is done group-by-group. In the future we may support cross-group bulk editing. Dependent on payloadcms#13102 (merged). --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210774523852467 --------- Co-authored-by: Paul Popus <paul@payloadcms.com>
Blocks container labels should match the Array and Tab labels. Uses same styling approach as Array labels. ### Before <img width="229" height="260" alt="CleanShot 2025-07-24 at 12 26 38" src="https://github.com/user-attachments/assets/9c4eb7c5-3638-4b47-805b-1206f195f5eb" /> ### After <img width="245" height="259" alt="CleanShot 2025-07-24 at 12 27 00" src="https://github.com/user-attachments/assets/c04933b4-226f-403b-9913-24ba00857aab" />
…payloadcms#13216) ## Problem: In PR payloadcms#11887, a bug fix for `copyToLocale` was introduced to address issues with copying content between locales in Postgres. However, an incorrect algorithm was used, which removed all "id" properties from documents being copied. This led to bug payloadcms#12536, where `copyToLocale` would mistakenly delete the document in the source language, affecting not only Postgres but any database. ## Cause and Solution: When copying documents with localized arrays or blocks, Postgres throws errors if there are two blocks with the same ID. This is why PR payloadcms#11887 removed all IDs from the document to avoid conflicts. However, this removal was too broad and caused issues in cases where it was unnecessary. The correct solution should remove the IDs only in nested fields whose ancestors are localized. The reasoning is as follows: - When an array/block is **not localized** (`localized: false`), if it contains localized fields, these fields share the same ID across different locales. - When an array/block **is localized** (`localized: true`), its descendant fields cannot share the same ID across different locales if Postgres is being used. This wouldn't be an issue if the table containing localized blocks had a composite primary key of `locale + id`. However, since the primary key is just `id`, we need to assign a new ID for these fields. This PR properly removes IDs **only for nested fields** whose ancestors are localized. Fixes payloadcms#12536 ## Example: ### Before Fix: ```js // Original document (en) array: [{ id: "123", text: { en: "English text" } }] // After copying to 'es' locale, a new ID was created instead of updating the existing item array: [{ id: "456", // 🐛 New ID created! text: { es: "Spanish text" } // 🐛 'en' locale is missing }] ``` ### After fix: ```js // After fix array: [{ id: "123", // ✅ Same ID maintained text: { en: "English text", es: "Spanish text" // ✅ Properly merged with existing item } }] ``` ## Additional fixes: ### TraverseFields In the process of designing an appropriate solution, I detected a couple of bugs in traverseFields that are also addressed in this PR. ### Fixed MongoDB Empty Array Handling During testing, I discovered that MongoDB and PostgreSQL behave differently when querying documents that don't exist in a specific locale: - PostgreSQL: Returns the document with data from the fallback locale - MongoDB: Returns the document with empty arrays for localized fields This difference caused `copyToLocale` to fail in MongoDB because the merge algorithm only checked for `null` or `undefined` values, but not empty arrays. When MongoDB returned `content: []` for a non-existent locale, the algorithm would attempt to iterate over the empty array instead of using the source locale's data. ### Move test e2e to int The test introduced in payloadcms#11887 didn't catch the bug because our e2e suite doesn't run on Postgres. I migrated the test to an integration test that does run on Postgres and MongoDB.
### What?
This PR introduces complete trash (soft-delete) support. When a
collection is configured with `trash: true`, documents can now be
soft-deleted and restored via both the API and the admin panel.
```
import type { CollectionConfig } from 'payload'
const Posts: CollectionConfig = {
slug: 'posts',
trash: true, // <-- New collection config prop @default false
fields: [
{
name: 'title',
type: 'text',
},
// other fields...
],
}
```
### Why
Soft deletes allow developers and admins to safely remove documents
without losing data immediately. This enables workflows like reversible
deletions, trash views, and auditing—while preserving compatibility with
drafts, autosave, and version history.
### How?
#### Backend
- Adds new `trash: true` config option to collections.
- When enabled:
- A `deletedAt` timestamp is conditionally injected into the schema.
- Soft deletion is performed by setting `deletedAt` instead of removing
the document from the database.
- Extends all relevant API operations (`find`, `findByID`, `update`,
`delete`, `versions`, etc.) to support a new `trash` param:
- `trash: false` → excludes trashed documents (default)
- `trash: true` → includes both trashed and non-trashed documents
- To query **only trashed** documents: use `trash: true` with a `where`
clause like `{ deletedAt: { exists: true } }`
- Enforces delete access control before allowing a soft delete via
update or updateByID.
- Disables version restoring on trashed documents (must be restored
first).
#### Admin Panel
- Adds a dedicated **Trash view**: `/collections/:collectionSlug/trash`
- Default delete action now soft-deletes documents when `trash: true` is
set.
- **Delete confirmation modal** includes a checkbox to permanently
delete instead.
- Trashed documents:
- Displays UI banner for better clarity of trashed document edit view vs
non-trashed document edit view
- Render in a read-only edit view
- Still allow access to **Preview**, **API**, and **Versions** tabs
- Updated Status component:
- Displays “Previously published” or “Previously a draft” for trashed
documents.
- Disables status-changing actions when documents are in trash.
- Adds new **Restore** bulk action to clear the `deletedAt` timestamp.
- New `Restore` and `Permanently Delete` buttons for
single-trashed-document restore and permanent deletion.
- **Restore confirmation modal** includes a checkbox to restore as
`published`, defaults to `draft`.
- Adds **Empty Trash** and **Delete permanently** bulk actions.
#### Notes
- This feature is completely opt-in. Collections without trash: true
behave exactly as before.
https://github.com/user-attachments/assets/00b83f8a-0442-441e-a89e-d5dc1f49dd37
…oadcms#13265) Previously, filtering by a polymorphic relationship inside an array / group (unless the `name` is `version`) / tab caused `QueryError: The following path cannot be queried:`.
…tion (payloadcms#13213) When populating the selector it should populate it with assigned tenants before fetching all tenants that a user has access to. You may have "public" tenants and while a user may have _access_ to the tenant, the selector should show the ones they are assigned to. Users with full access are the ones that should be able to see the public ones for editing.
🤖 Automated bump of templates for v3.49.0 Triggered by user: @denolfe Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Adds logic for svg+xml file type detection. --------- Co-authored-by: Philipp Schneider <47689073+philipp-tailor@users.noreply.github.com>
Based from payloadcms#13276 Fixes payloadcms#7624 If an uploaded image has `.svg` ext, and the mimeType is read as `application/xml` adjust the mimeType to `image/svg+xml`. --------- Co-authored-by: Philipp Schneider <47689073+philipp-tailor@users.noreply.github.com>
…make paragraphs and lists match without CSS (payloadcms#13274) Previously, the Lexical editor was using px, and the JSX converter was using rem. payloadcms#12848 fixed the inconsistency by changing the editor to rem, but it should have been the other way around, changing the JSX converter to px. You can see the latest explanation about why it should be 40px [here](payloadcms#13130 (comment)). In short, that's the default indentation all browsers use for lists. This time I'm making sure to leave clear comments everywhere and a test to avoid another regression. Here is an image of what the e2e test looks like: <img width="321" height="678" alt="image" src="https://github.com/user-attachments/assets/8880c7cb-a954-4487-8377-aee17c06754c" /> The first part is the Lexical editor, the second is the JSX converter. As you can see, the checkbox in JSX looks a little odd because it uses an input checkbox (as opposed to a pseudo-element in the Lexical editor). I thought about adding an inline style to move it slightly to the left, but I found that browsers don't have a standard size for the checkbox; it varies by browser and device. That requires a little more thought; I'll address that in a future PR. Fixes payloadcms#13130
Previously, `db.deleteMany` on postgres resulted in 2 roundtrips to the
database (find + delete with ids). This PR passes the where query
directly to the `deleteWhere` function, resulting in only one roundtrip
to the database (delete with where).
If the where query queries other tables (=> joins required), this falls
back to find + delete with ids. However, this is also more optimized
than before, as we now pass `select: { id: true }` to the findMany
query.
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1210871676349299
Respects join.type instead of hardcoding leftJoin
That property does not exist and was used in a previous, outdated implementation of auto scheduling
Fixes payloadcms#13191 - Render a single html element for single error messages - Preserve ul structure for multiple errors - Updates tests to check for both cases
Looks like a merge resolution kept unused code. The same condition is added a couple lines below this removal.
- bumps next.js from 15.3.2 to 15.4.4 in monorepo and templates. It's important to run our tests against the latest Next.js version to guarantee full compatibility. - bumps playwright because of peer dependency conflict with next 15.4.4 - bumps react types because why not https://nextjs.org/blog/next-15-4 As part of this upgrade, the functionality added by payloadcms#11658 broke. This PR fixes it by creating a wrapper around `React.isValidElemen`t that works for Next.js 15.4. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210803039809808
…ayloadcms#13300) ### What? - Fixed an issue where group-by enabled collections with `trash: true` were not showing trashed documents in the collection’s trash view. - Ensured that the `trash` query argument is properly passed to the `findDistinct` call within `handleGroupBy`, allowing trashed documents to be included in grouped list views. ### Why? Previously, when viewing the trash view of a collection with both **group-by** and **trash** enabled, trashed documents would not appear. This was caused by the `trash` argument not being forwarded to `findDistinct` in `handleGroupBy`, which resulted in empty or incorrect group-by results. ### How? - Passed the `trash` flag through all relevant `findDistinct` and `find` calls in `handleGroupBy`.
…#13204) --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210561338171141
Ensures the browser uses fresh data after seeding by refreshing the route and navigating when done.
Fixes typo in variable name within the relationship field component. `disableFormModication` → `disableFormModification`
… components (payloadcms#13302) Custom document tab components (server components) do not receive the `user` prop, as the types suggest. This makes it difficult to wire up conditional rendering based on the user. This is because tab conditions don't receive a user argument either, forcing you to render the default tab component yourself—but a custom component should not be needed for this in the first place. Now they both receive `req` alongside `user`, which is more closely aligned with custom field components. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210906078627357
## Problem When logging in with a `?redirect=`, the target page may crash. This happens because the update from `SyncClientConfig` is applied in a `useEffect`, which runs **_after_** the target page's client components render. As a result, those components read the unauthenticated client config on first render - even though they expect the authenticated one. ## Steps To Reproduce 1. logout 2. login with ?redirect= 3. document client component incorrectly still receives unauthenticated client config on render 4. THEN the SyncClientConfig useEffect runs. Too late 5. Potential error (depending on the page, e.g. document view) - document client component expects sth to be there, but it is not ## Solution This PR replaces `SyncClientConfig` with a `RootPageConfigProvider`. This new provider shadows the root layout’s `ConfigProvider` and ensures the correct client config is available **_immediately_**. It still updates the config using `useEffect` (the same way`SyncClientConfig` did), but with one key difference: - During the brief window between the redirect and the effect running, it overrides the root layout’s config and provides the fresh, authenticated config from the root page via the `RootConfigContext`. This guarantees that client components on the target page receive the correct config on first render, preventing errors caused by reading the outdated unauthenticated config. ## Additional change - get rid of `UnsanitizedClientConfig` and `sanitizeClientConfig` Those functions added unnecessary complexity, just to build the blocksMap. I removed those and perform the building of the `blocksMap` server-side - directly in `createClientConfig`. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211334752795621
The information about the block field and the blocks themselves wasn't separated in the documentation, and in fact, there were times when they were confused and incorrectly mixed. This caused confusion among our users. This PR closes an issue, a discussion, and another PR that arose because it wasn't clear that the `blockName` could be programmatically modified with the block's content. This is possible through `admin.components.Label`, which isn't the best name, as it changes the `label` and the `name` of the block, two different concepts. I've added a section to the documentation that I think will make all of this much clearer. Before: <img width="266" height="362" alt="image" src="https://github.com/user-attachments/assets/3b5c95f0-2cdb-4995-a25d-9984f9ab54cb" /> After: <img width="266" height="383" alt="image" src="https://github.com/user-attachments/assets/99936f64-326f-4d69-a464-626d7f53fa08" /> Replaces payloadcms#12135 Fixes payloadcms#12112 & addresses payloadcms#4648 --------- Co-authored-by: Said Akhrarov <36972061+akhrarovsaid@users.noreply.github.com>
…3789) ### What? Opening a document with an expired lock and richtext caused the richtext to be read-only. ### Why? The changes in payloadcms#13579 made the richtext read only if isLocked is set. But the server side implementation of isLocked did not consider expired locks. ### How? Update the server-side getIsLocked to also consider expired locks by not loading them.
Redirecting from login to any non-auth collection crashes the page with the following error: ``` Cannot read properties of null (reading 'fields') ``` TL;DR: the page-level config context was threading stale methods from the root config provider. #### Background The client config is now gated behind authentication as of payloadcms#13714, so it changes based on authentication status. If the root layout is mounted before authentication, it puts the unauthenticated client config into state for the entire app to consume. On login, the root layout does not re-render, so the page itself needs to generate a fresh client config and sync it up. This leads to race conditions, however, where if the login page included a `?redirect=` param, the redirect would take place _before_ the page-level client config could sync to the layout, and ultimately crash the page. This was addressed in payloadcms#13786. While this fixed redirects to the "users" collection, this collection is _already_ included in the client config (soon to be omitted by payloadcms#13785). So if you redirect to any other collection, the above error occurs. #### Problem The page-level config context is only overriding the `config` property, keeping stale methods from the root config provider. This means calling `getEntityConfig` during this moment in the time would reference the stale config, although `config` itself would be fresh. #### Solution Wrap the page with an entirely new context provider. Do not thread inherited methods from the root provider, this way all new methods get instantiated using the fresh config. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211332845301596
…eview messages (payloadcms#13793) ### What? Fix two live preview issues affecting client-side navigation: 1. Stale preview data leaking between pages using `useLivePreview`. 2. Erroneous fetches to `/api/undefined` and incorrect content rendering when preview events lack slugs. ### Why? The live-preview module cached merged preview data globally, which persisted across route changes, causing a new page to render with the previous page’s data. The client attempted to merge when preview events didn’t specify collectionSlug or globalSlug, producing an endpoint of undefined and triggering requests to /api/undefined, sometimes overwriting state with mismatched content. ### How? Clear the internal cache at the time of `subscribe()` so each page using `useLivePreview` starts from a clean slate. In `handleMessage`, only call `mergeData` when `collectionSlug` or `globalSlug` is present; otherwise return `initialData` and perform no request. Fixes payloadcms#13792
Follow-up to payloadcms#13714. Fully sanitizes the unauthenticated client config to exclude much of the users collection, including fields, etc. These are not required of the login flow and are now completely omitted along with other unnecessary properties. This is closely aligned with the goals of the original PR, and as an added bonus, makes the config _even smaller_ than it already was for unauthenticated users. Needs payloadcms#13790. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211332845301588
payloadcms#13796) Similar spirit as payloadcms#13714. Permissions are embedded into the page response, exposing some field names to unauthenticated users. For example, when setting `read: () => false` on a field, that field's name is now included in the response due to its presence in the permissions object. We now search the HTML source directly in the test, similar to "view source" in the browser, which will be much effective at preventing regression going forward. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211347942663256
…yloadcms#13728) ### What? Fixes a typo in the description of query presets. ### Why? Grammar
…ayloadcms#13748) ### What? Updated a few words to better represent what they mean in Dutch. ### Why? The words that are used now are synonyms but have the wrong meaning in the context of the UI. ### How? Clear - Duidelijk - This means like "This explanation was very clear" Changed it to "Wissen", which is to clear filters. Close - Dichtbij - This means close by, like "This drive is just around to corner, it is close by" Changed it to "Sluiten", which is to close for example a dialog
… "Cannot read properties of undefined" (payloadcms#13800) Fixes payloadcms#12924 ### What? If an access check request resulted in no access to a doc, then the sanitizer will remove even the `collections` field from the sanitized permissions. This throws a server error when the `collections` field is attempted to be accessed with some collection slug. The error is "Cannot read properties of undefined". ### Why? An example of how this might come about: I am using multi-tenancy. I have some conditions about which users can see other user's information (do they share any tenants). One workflow is such that a "super admin" (user A) of a tenant removes an "admin" (user B) inside their tenant. This is done by removing the tenant from the user's list. After user A's update succeeds, payload defaults to trying to reload user B's page. However, the two no longer share a tenant. The access controls correctly evaluate that user A should no longer be able to see/update/etc user B, but there is a bug in how the objects are handled (see below). The sanitizer removes the .collections field from the sanitizedPermissions, so we get a server error about the key missing "Cannot read properties of undefined (reading 'users')" in my case. ### How? Instead of immediately keying into the sanitizedPermissions, we see if the collections exist. If not, we make sure to return a well-defined object with no permissions. Before: ```ts return sanitizedPermissions.collections![config.slug]! ``` After: ```ts const collectionPermissions = sanitizedPermissions?.collections?.[config.slug] return collectionPermissions ?? { fields: {} } ``` --------- Co-authored-by: Alessio Gravili <alessio@gravili.de>
…agination (payloadcms#13805) When searching and the data is still being fetched, users see "no options" until the data is populated, this is very confusing especially if the loading time could take more seconds, user would start clearing input and type again. This PR shows the loading indicator during search and pagination by setting `isLoading` to true immediately when search begins and setting it to false when data fetching completes **Before** https://github.com/user-attachments/assets/86367207-31f6-40f0-bd98-c9e885ecd0dd **After** https://github.com/user-attachments/assets/202d2c05-61a6-4e3a-9973-65b302b4495a
…zed fields (payloadcms#13794) Fixes payloadcms#13756 The findByID endpoint, by default, expects the data for localized fields to be an object, values mapped to the locale. This is not the case for client-side live preview, as we send already-flattened data to the findByID endpoint. For localized fields where the value is an object (richText/json/group), the afterRead hook handler would attempt to flatten the field value, even though it was already flattened. ## Solution The solution is to expose a `flattenLocales` arg to the findByID endpoint (default: true) and pass `flattenLocales: false` from the client-side live preview request handler. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211334752795627
…re reliable job system crons (payloadcms#13564) ## New jobs:handle-schedules bin script Similarly to `payload jobs:run`, this PR adds a new `jobs:handle-schedules` bin script which only handles scheduling. ## Allows jobs:run bin script to handle scheduling Similarly to how [payload autoRun](https://payloadcms.com/docs/jobs-queue/queues#cron-jobs) handles both running and scheduling jobs by default, you can now set the `payload jobs:run` bin script to also handle scheduling. This is opt-in: ```sh pnpm payload jobs:run --cron "*/5 * * * *" --queue myQueue --handle-schedules # This will both schedule jobs according to the configuration and run them ``` ## Cron schedules for all bin scripts Previously, only the `payload jobs:run` bin script accepted a cron flag. The `payload jobs:handle-schedules` would have required the same logic to also handle a cron flag. Instead of opting for this duplicative logic, I'm now handling cron logic before we determine which script to run. This means: it's simpler and requires less duplicative code. **This allows all other bin scripts (including custom ones) to use the `--cron` flag**, enabling cool use-cases like scheduling your own custom scripts - no additional config required! Example: ```sh pnpm payload run ./myScript.ts --cron "0 * * * *" ``` Video Example: https://github.com/user-attachments/assets/4ded738d-2ef9-43ea-8136-f47f913a7ba8 ## More reliable job system crons When using autorun or `--cron`, if one cron run takes longer than the cron interval, the second cron would run before the first one finishes. This can be especially dangerous when running jobs using a bin script, potentially causing race conditions, as the first cron run will take longer due to payload initialization overhead (only for first cron run, consecutive ones use cached payload). Now, consecutive cron runs will wait for the first one to finish by using the `{ protect: true }` property of Croner. This change will affect both autorun and bin scripts. ## Cleanup - Centralized payload instance cleanup (payload.destroy()) for all bin scripts - The `getPayload` function arguments were not properly typed. Arguments like `disableOnInit: true` are already supported, but the type did not reflect that. This simplifies the type and makes it more accurate. ## Fixes - `allQueues` argument for `payload jobs:run` was not respected --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211124797199077
…ter (payloadcms#13809) ### What? Remove `select` parameter from database operations in update operation during version creation to fix malformed version data. ### Why? The `select` parameter was being passed to `saveVersion()` in update operations, causing versions to only contain selected fields ### How? - Removed `select` parameter from `payload.db.updateOne()` calls in update operations - Removed `select` parameter from `saveVersion()` call in update operation --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211334352350013
…#12918) Follow-up to payloadcms#12893. ### What? Removes cases where submitting a document as a draft in a collection with versioning enabled would cause publishing validation errors to be displayed on further document form changes. An example case is when saving the draft failed due to a `beforeChange` hook throwing an `APIError`. ### How The behavior change is that the form state is marked as un-submitted post a submit failure as a draft. The form not being considered as submitted results in `packages/ui/src/views/Edit/index.tsx` to use `skipValidation: true`. --------- Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Fixes payloadcms#12286. Supersedes payloadcms#12290. As of [v3.35.0](https://github.com/payloadcms/payload/releases/tag/v3.35.0), you are no longer able to directly pass a `path` prop to a custom field component. For example: ```tsx 'use client' import React from 'react' import { TextField } from '@payloadcms/ui' import type { TextFieldClientComponent } from 'payload' export const MyCustomField: TextFieldClientComponent = (props) => { return ( <TextField {...props} path="path.to.some.other.field" // This will not be respected, because this field's context takes precedence /> ) } ``` This was introduced in payloadcms#11973 where we began passing a new `potentiallyStalePath` arg to the `useField` hook that takes the path from context as priority. This change was necessary in order to fix stale paths during row manipulation while the server is processing. To ensure field components respect your custom path, you need to wrap your components with their own `FieldPathContext`: ```tsx 'use client' import React from 'react' import { TextField, FieldPathContext } from '@payloadcms/ui' import type { TextFieldClientComponent } from 'payload' export const MyCustomField: TextFieldClientComponent = (props) => { return ( <FieldPathContext path="path.to.some.other.field"> <TextField {...props} /> </FieldPathContext> ) } ``` It's possible we can remove this in the future. I explored this in payloadcms#12290, but it may require some more substantial changes in architecture. These exports are labeled experimental to allow for any potential changes in behavior that we may need to make in the future. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210533177582945
…s#13269) ### What? Passes the same args provided to a task's `shouldRestore` function to both the `onSuccess` & `onFail` callbacks ### Why? Currently `onSuccess` and `onFail` are quite useless without any context, this will allow for a wider range of functionality: - Checking if it's the last failure - Access to the task `input` - Access to `req` to allow logging, email notifications, etc. ### How? 1. Created a new `TaskCallbackArgs` type, which replicates the args of the `ShouldRestoreFn` type. 2. Add a `TaskCallbackFn` type 3. Update the function calls of both `onSuccess` and `onFail`. ### Questions - I wasn't sure about the typing of `input` – I can see `input: input!` being used elsewhere for task errors so I replicated that. - Same for `taskStatus`, I added a type check but I'm not sure if this is the right approach (what would scenario would result in a `null` value?). Should `TaskCallbackArgs['taskStatus']` be typed to allow for `null` values? --------- Co-authored-by: Alessio Gravili <alessio@gravili.de>
…ds (payloadcms#13807) ### What? Skip field validation when trashing documents with empty required fields. ### Why? When trashing a document that was saved as a draft with empty required fields, Payload would run full validation and fail with "The following fields are invalid" errors. This happened because trash operations were treated as regular updates that require full field validation, even though trashing is just a metadata change (setting `deletedAt`) and shouldn't be blocked by content validation issues. ### How? - Modified `skipValidation` logic in `updateDocument()` to skip validation when `deletedAt` is being set in the update data Fixes payloadcms#13706
… types (payloadcms#13820) ### What? Fixes crash when virtual fields use field types not supported by the WhereBuilder (e.g. 'group' fields). <img width="1336" height="459" alt="Screenshot 2025-09-16 at 11 00 30 AM" src="https://github.com/user-attachments/assets/3adbb507-3033-4f52-b7cc-3c5bad74900b" /> ### Why? Users reported a crash with error "Cannot read properties of undefined (reading 'operators')" when entering collection list views with virtual fields that have `type: 'group'`. The issue occurred because: - Virtual fields can use any field type including 'group' - The `fieldTypes` object in WhereBuilder only supports specific field types (text, number, select, etc.) - Code tried to access `fieldTypes[field.type].operators` when `field.type` was 'group', causing undefined access ### How? - Refactored virtual field handling to use a unified processing flow instead of separate early returns - Virtual fields now set the `pathPrefix` to their virtual path and continue through normal field validation --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211315667956059 --------- Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
…#13819) Previously, sorting like: `sort: 'relationship.anotherRelationship.title'` (and more nested) didn't work with the MongoDB adapter, this PR fixes this.
…or (payloadcms#13825) When using server-side live preview across domains, the initial `postMessage` to the iframe throws the following error: ```txt Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://your-frontend.com') does not match the recipient window's origin ('https://your-backend.com'). ``` This error is misleading, however, as it's thrown even when the iframe's source exactly matches the post message's `targetOrigin`. For example: ```ts recipient.postMessage(message, targetOrigin) ``` The problem is that the initial message is sent before the iframe is ready to receive it, resulting in the parent window posting to itself. This is not a problem when the front-end is running on the same server, but if the recipient changes while initializing, the target origin will be mismatched. Worth noting that this is not an issue with client-side live preview. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211376499297320
…alVersions` and handle it properly (payloadcms#13763) * The `pagination` property was missing in `findVersions` and `findGlobalVersions` Local API operations, although the actual functions did have it - https://github.com/payloadcms/payload/blob/1b93c4becc9f85684bc2d79795615aee101988fd/packages/payload/src/collections/operations/findVersions.ts#L25 * The handling of the `pagination` property in those functions was broken, this PR fixes it.
…ms#13827) Fixes an issue with the new experimental `enableListViewSelectAPI` config option. Group fields were not populating properly in the list view ### Before (incorrect) ```ts { group.field: true } ``` ### After (correct) ```ts { group: { field: true } } ```
payloadcms#13828) When using `pnpm next build --experimental-build-mode compile` in our website template, Next.js outputs the following code: <img width="2322" height="1262" alt="Screenshot 2025-09-16 at 14 39 31@2x" src="https://github.com/user-attachments/assets/bb7dc5c1-ffe7-4ee7-8864-19cb2147c07d" /> If you then run `pnpm next build --experimental-build-mode generate` or `pnpm next build --experimental-build-mode generate-env` which inlines the env variable, it becomes the following code: <img width="2276" height="1340" alt="Screenshot 2025-09-16 at 14 40 14@2x" src="https://github.com/user-attachments/assets/6fc8cbd4-4df8-4d9b-a3e5-fc299e147537" /> Suddenly, it no longer assigns to a variable but to a string, which is invalid JavaScript syntax, throwing the following error: <img width="2314" height="320" alt="Screenshot 2025-09-16 at 14 40 53@2x" src="https://github.com/user-attachments/assets/2c3487be-82e3-4043-aa04-0d98f0a05b4b" /> This PR works around this issue changing up the source code in `getServerSideURL`. I have reported this issue to Next.js: vercel/next.js#83863 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211375615406662
…ayloadcms#13815) Wrap `EmailField` and `TextField` with `FieldPathContext` to ensure the inputs bind to their own paths (`"email"`, `"username"`) instead of inheriting the relationship field name (e.g., `"author"`). This restores correct `name` / `schemaPath` binding and fixes form submission. Regression introduced in payloadcms#11973. Fixes payloadcms#13764. This approach is consistent with the discussion in [payloadcms#13806](payloadcms#13806), where it was suggested that enforcing field paths explicitly is the right direction. **What?** Fixes regression where inline create drawer fields (`EmailField`, `TextField`) incorrectly inherited the parent relationship field name, breaking form submission. **Why?** Without this fix, the email input in inline create forms was bound to the relationship field name (e.g., `"author"`) instead of `"email"`, causing authentication-enabled collections to fail when creating users inline. **How?** * Wrap `EmailField` with `FieldPathContext value="email"` * Wrap `TextField` with `FieldPathContext value="username"` * Ensures inputs register under the correct paths in form state. Fixes payloadcms#13764.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Adds a new translation: Esperanto
Type of change
Checklist: