8a7124a15e0d96ecf35be2462c388cb15578b5c2
14072 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8a7124a15e |
fix(next): resolve filterOptions by path (#13779)
Follow up to #11375. When setting `filterOptions` on relationship or upload fields _that are nested within a named field_, those options won't be applied to the `Filter` component in the list view. This is because of how we key the results when resolving `filterOptions` on the server. Instead of using the field path as expected, we were using the field name, causing a failed lookup on the front-end. This also solves an issue where two fields with the same name would override each other's `filterOptions`, since field names alone are not unique. Unrelated: this PR also does some general housekeeping to e2e test helpers. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211332845301583 |
||
|
|
82820312e8 |
feat: expose multipart/form-data parsing options (#13766)
When sending REST API requests with multipart/form-data, e.g. PATCH or POST within the admin panel, a request body larger than 1MB throws the following error: ``` Unterminated string in JSON at position... ``` This is because there are sensible defaults imposed by the HTML form data parser (currently using [busboy](https://github.com/fastify/busboy)). If your documents exceed this limit, you may run into this error when editing them within the admin panel. To support large documents over 1MB, use the new `bodyParser` property on the root config: ```ts import { buildConfig } from 'payload' const config = buildConfig({ // ... bodyParser: { limits: { fieldSize: 2 * 1024 * 1024, // This will allow requests containing up to 2MB of multipart/form-data } } } ``` --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211317005907885 |
||
|
|
3af546eeee |
feat: global beforeOperation hook (#13768)
Adds support for the `beforeOperation` hook on globals. Runs before all
other hooks to either modify the arguments that operations receive, or
perform side-effects before an operation begins.
```ts
import type { GlobalConfig } from 'payload'
const MyGlobal: GlobalConfig = {
// ...
hooks: {
beforeOperation: []
}
}
```
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211317005907890
|
||
|
|
4482eaf9ad |
fix(ui): safely access preferences when loading list view (#13771)
Fixes an issue when user has no collection preferences saved. When no collection level preferences are saved, the result is `undefined`. This change ensures there is a result before accessing `res.value`. |
||
|
|
58953de241 | chore(release): v3.55.1 [skip ci] | ||
|
|
285fc8cf7e |
fix: presentational-field types incorrectly exposing hooks (#11514)
### What? Presentational Fields such as [Row](https://payloadcms.com/docs/fields/row) are described as only effecting the admin panel. If they do not impact data, their types should not include hooks in the fields config. ### Why? Developers can currently assign hooks to these fields, expecting them to work, when in reality they are not called. ### How? Omit `hooks` from `FieldBase` Fixes #11507 --------- Co-authored-by: German Jablonski <43938777+GermanJablo@users.noreply.github.com> |
||
|
|
e40c82161e |
fix(next): error after logging in and navigating to different page in production (#13758)
Since https://github.com/payloadcms/payload/pull/13714, if you open payload, log in, then client-side navigate to any page (e.g. clicking on any collection), the following error will appear and crash the page: <img width="2046" height="460" alt="Screenshot 2025-09-09 at 18 35 46@2x" src="https://github.com/user-attachments/assets/26762b4c-55de-4e8c-b09c-ef7e9a16b9c2" /> This only happens in production. It does not happen during development, because the `SyncClientConfig` `useEffect` runs twice due to react strict mode. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211306293437542 |
||
|
|
ffed5407cd |
fix(ui): listSearchableFields can resolve to multiple fields with the same name when using tabs (#13668)
Fixes #13665 This PR fixes the issue by searching only for the first field with the given name. I used a Set to iterate over the array of fields only once. The question remains: What happens if someone wants to search for a nested field that has the same name as a top-level field? I think this is a much less likely scenario than the one that happened to OP in #13665, and in that case the user would probably want to change the name of the nested field. If we see this as a problem in the future, we can consider something like using paths (`tabName.fieldName`). For review, the example snippet that appears in the issue can be used. |
||
|
|
15e462be04 |
templates: ensure blank template installs matching react-dom version (#13757)
Currently, in fresh installations, pnpm may install react-dom version 19.1.1, which will throw an error as it does not match the react version it installs (19.1.0) --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211306293437538 |
||
|
|
e52b7572c5 |
fix(graphql): pass collectionSlug to nested join fields in tabs, collapsible and group resolvers (#13752)
## Problem GraphQL join fields nested inside tabs and collapsibles return empty results due to missing `collectionSlug` parameter propagation in the tabs and collapsible resolver. ## Root Cause The `tabs` resolver in `fieldToSchemaMap.ts` doesn't pass `collectionSlug` to nested field resolvers, causing polymorphic relationship queries to fail when constructing MongoDB filters. ## Solution - Added `collectionSlug` parameter to tabs resolver function signature - Pass `collectionSlug` to `buildObjectType` for named tabs - Pass `collectionSlug` to `addSubField` for unnamed tabs ## Testing - [x] Verified join fields work correctly in tab-nested scenarios - [x] Tested with multiple collection types - [x] Confirmed no breaking changes to existing functionality Fixes #13345 We have got this running successfully in production and are looking forward for this to get merged so we do not have to patch the core anymore :) --------- Co-authored-by: Alessio Gravili <alessio@gravili.de> |
||
|
|
dbd91bf354 |
templates: bump for v3.55.0 (#13754)
🤖 Automated bump of templates for v3.55.0
Triggered by user: @denolfe
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
|
||
|
|
f531576da6 | chore(release): v3.55.0 [skip ci] | ||
|
|
e1ea07441e |
feat: adds disableListColumn and disableListFilter to imageSize admin props (#13699)
### What? Added support for `disableListColumn` and `disableListFilter` admin properties on imageSize configurations that automatically apply to all fields within the corresponding size group. ### Why? Upload collections with multiple image sizes can clutter the admin list view with many size-specific columns and filters. This feature allows developers to selectively hide size fields from list views while keeping them accessible in the document edit view. ### How? Modified `getBaseFields.ts` to inherit admin properties from imageSize configuration and apply them to all nested fields (url, width, height, mimeType, filesize, filename) within each size group. The implementation uses conditional spread operators to only apply these properties when explicitly set to `true`, maintaining backward compatibility. |
||
|
|
6a0637ecb2 |
feat(ui): save collection folder tab preferences (#13702)
Saves folder preferences when navigating from list to folder view. This is a UX improvement so users don't need to click by-folder every time they go back to the list view. |
||
|
|
1293019825 |
fix(plugin-search): update with db adapter on create (#13670)
Fixes https://github.com/payloadcms/payload/issues/13106 The search plugin could accidentally create duplicate entries when a document is created and within that same lifecycle a payload.update is called. The nested docs plugin does this which causes 2 entries for the same document to be inserted. |
||
|
|
911f17a887 |
fix(next): version diff view not handling all field permissions correctly (#13721)
Fixes https://github.com/payloadcms/payload/issues/13286 The version diff view did not handle all field permissions correctly, leading to some fields disappearing if access control was set. This PR fixes that. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211267837905375 |
||
|
|
e49005fcbd |
feat: unauthenticated client config (#13714)
Secures the client config behind authentication to prevent exposing underlying schemas to unauthenticated users. Serves an "unauthenticated" version of the client config in its place, containing only minimally required properties to enable the login flow. For example, when downloading the page source for the login view, the entire client config is embedded in the page response, including all collection slugs, field names, etc. This is not inherently insecure. Hooks and core business logic have already been stripped out, and data is not exposed, but this pattern could shine light into a project's general structure which could be considered IP. This could also be considered a small performance benefit to the login page, which is now smaller in size relative to the config and can potentially download faster. Note: the create first user flow is an acception to the rule. It requires the full config in order to render fields, including joins, relationships, etc. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211258607273690 |
||
|
|
b2f9d4e9a4 |
fix(storage-vercel-blob): filename is incorrectly stored encoded when addRandomSuffix is true (#13746)
Previously, if `addRandomSuffix` is set to true, the filename would be stored URL-encoded in the database: <img width="2212" height="140" alt="Screenshot 2025-09-08 at 18 47 50@2x" src="https://github.com/user-attachments/assets/1b001e30-0154-4764-a2e9-b7d8bf729581" /> If in addition to that, if you set `disablePayloadAccessControl: true`, Payload will url-encode the already url-encoded filename on read, leading to an error. This PR fixes this issue by always decoding the filename before storing it in the database, so that they're always stored unencoded, no matter if `addRandomSuffix` is set or not: <img width="1730" height="184" alt="Screenshot 2025-09-08 at 18 49 29@2x" src="https://github.com/user-attachments/assets/44328bfa-e489-4247-9e9b-7ddc6e271afb" /> --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211177878397844 |
||
|
|
d2d2df4408 |
perf(ui): opt-in to the select api in the list view (#13697)
Adds a new property to the config that enables the Select API in the
list view. This is a performance opt-in, where only the active columns
(and those specified in `forceSelect`) are queried. This can greatly
improve performance, especially for collections with large documents or
many fields.
To enable this, use the `admin.enableListViewSelectAPI` in your
Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
admin: {
enableListViewSelectAPI: true // This will select only the active columns (and any `forceSelect` fields)
}
}
```
Note: The `enableListViewSelectAPI` property is currently labeled as
experimental, as it will likely become the default behavior in v4 and be
deprecated. The reason it cannot be the default now is because cells or
other components may be relying on fully populated data, which will no
longer be the case when using `select`.
For example, if your component relies on a "title" field, this field
will _**not**_ exist if the column is **_inactive_**:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
fields: [
// ...
{
name: 'myField',
type: 'text',
hooks: {
afterRead: [
({ doc }) => doc.title // `title` will only be populated if the column is active
]
}
}
]
}
```
There are other cases that might be affected by this change as well, for
example any components relying on the `data` object returned by the
`useListQuery()` hook:
```ts
'use client'
export const MyComponent = () => {
const { data } = useListQuery() // `data.docs` will only contain fields that are selected
// ...
}
```
To ensure title is always present, you will need to add that field to
the `forceSelect` property in your Collection Config:
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
// ...
forceSelect: {
title: true
}
}
```
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211248751470559
|
||
|
|
a0112d70a9 |
fix(plugin-multi-tenant): hide watchTenant column field (#13740)
Fixes https://github.com/payloadcms/payload/issues/13731 The watch tenant field is just a ui field used to sync updates to the selector, should not appear in the columns selector on the list view. |
||
|
|
a528a55639 |
test: increase timeout in uploads cors test (#13743)
Deflakes the uploads e2e suite. The CORS test was not waiting not long enough for the response and ultimately fails. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211295974585601 |
||
|
|
27cfe775dd |
docs: missing comma in custom-strategies example (#13701)
Fix missing comma at custom-strategies example |
||
|
|
24e436bfa8 |
fix(richtext-lexical): fix picture closing tag in html converter (#13100)
# Fixing invalid html from convertLexicalToHTML with UploadConverter ## What? When using the [convertLexicalToHTML function](https://github.com/payloadcms/payload/blob/main/packages/richtext-lexical/src/features/converters/lexicalToHtml/sync/index.ts#L33C17-L33C37) to convert richtext into html, the resulting html is incorrect when an upload is present. ## Why? The error is within the UploadHTMLConverter, as you can see in my commits. The picture closing tag has a Dollar sign in it `</picture$>`, which is invalid html. This results in the picture not closing at the right place. The picture element is not only wrapping the img tag, but also all following content of that richtext field. > I suppose that dollar sign ended up there due to auto rename tags from IDE. ```ts import { convertLexicalToHTML } from "@payloadcms/richtext-lexical/html"; const html = convertLexicalToHTML({ data: content }); ``` **Example before fix** ```html <div class="payload-richtext"> <h2>Title</h2> <p>description</p> <picture> <img alt="media.png" height="400" src="https://some.url/storage/v1/object/public/media/media.png" width="684"> <p>Some more text</p> </picture> </div> ``` **Example after fix** ```html <div class="payload-richtext"> <h2>Title</h2> <p>description</p> <picture> <img alt="media.png" height="400" src="https://some.url/storage/v1/object/public/media/media.png" width="684"> </picture> <p>Some more text</p> </div> ``` |
||
|
|
bbcdea5450 |
fix(next): display deleted relations and uploads in version diff views (#12955)
This PR fixes an issue where `relationship` and `upload` fields that had their document-counterpart deleted would cause a runtime error. This happens because the version diff components expected a populated document instead of an id. Two e2e tests were also added to the existing suite to test that the diff view is reachable even after deletions. ### Why? To prevent a runtime error when viewing diffs for documents that have relationships to deleted documents. ### How? Adjusting the diff view to accommodate deleted document relations. Fixes #12915 Before: [version-diff-collections-before.mp4](https://private-user-images.githubusercontent.com/20878653/458373129-745a5313-b85a-4ef0-a0d4-a13b52994f6f.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTA5Njc3NDEsIm5iZiI6MTc1MDk2NzQ0MSwicGF0aCI6Ii8yMDg3ODY1My80NTgzNzMxMjktNzQ1YTUzMTMtYjg1YS00ZWYwLWEwZDQtYTEzYjUyOTk0ZjZmLm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA2MjYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwNjI2VDE5NTA0MVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTUwOTUzMmJmYWI4YmM4ODZjYjhiNWVkOWE0NDgwODRiYjUxNjVkZmNiOWE2NWM3ODVhMTJiY2ViMGQ4MDE4NjYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.Of4Os9WCeOo_aN2kHNMShEgOc4-mYAwc41_E3YsX1tw) After: [versions-collections-after-Posts---Payload.webm](https://github.com/user-attachments/assets/ce4031da-b703-4944-857d-9ff627c58fdd) Notes: - I renamed `PopulatedRelationshipValue` to `RelationshipValue` as we don't actually know if the value is populated. Such as in the case of when the doc was deleted. |
||
|
|
794bf8299c |
fix(next): version diff view shows correct document title in step nav (#13713)
This PR fixes two bugs in the version diff view SetStepNav component ### Bug 1: Document title isn't shown correctly in the step navigation if the field of `useAsTitle` is nested inside a presentational field. The StepNav shows the title of the document consistently throughout every view except the version diff view. In the version diff view, the document title is always `[Untitled]` if the field of `useAsTitle` is nested inside presentational fields. Below is a video demo of the bug: https://github.com/user-attachments/assets/23cb140a-b6d3-4d39-babf-5e4878651869 This happens because the fields of the collection/global aren't flattened inside SetStepNav and thus the component is not accessing the field data correctly. This results in the title being `null` causing the fallback title to be shown. ### Bug 2: Step navigation shows the title of the version viewed, not the current version The StepNav component takes the title of the current version viewed. This causes the second part of the navigation path to change between versions which is inconsistent between other views and doesn't seem intentional, although it could be. Below is a video of the bug with the first bug fixed by flattening the fields: https://github.com/user-attachments/assets/e5beb9b3-8e2e-4232-b1e5-5cce720e46b9 This happens due to the fact that the title is taken from the `useAsTitle` field of the **viewed** version rather than the **current** version. This bug is fixed by using the `useDocumentTitle` hook from the ui package instead of passing the version's `useAsTitle` data down the component tree. The final state of the step navigation is shown in the following video: https://github.com/user-attachments/assets/a69d5088-e7ee-43be-8f47-d9775d43dde9 I also added a test to test that the title part in the step navigation stays consistent between versions and implicitly also tests that the document title is shown correctly in the step nav if the field of `useAsTitle` is a nested inside a presentational field. |
||
|
|
9f0573d714 |
chore(ui): prevent loading orphaned documents when viewing root collection folders (#13684)
Root level collection folders should not display items, only folders. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210821658736793 |
||
|
|
f288cf6a8f |
feat(ui): adds admin.autoRefresh root config property (#13682)
Adds the `admin.autoRefresh` property to the root config. This allows users to stay logged and have their token always refresh in the background without being prompted with the "Stay Logged In?" modal. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211114366468735 |
||
|
|
03f7102433 |
fix: ensure client-side live preview correctly updates for globals (#13718)
Previously, we were sending incorrect API requests for globals. Additionally, the global findOne endpoint did not respect the data attribute. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211249618316704 |
||
|
|
09e3174834 |
fix(ui): consistent searchbar across folders and lists (#13712)
Search bar styling was inconsistent across folder and list views. This re-uses the SearchBar component in the ListHeader component. |
||
|
|
a4a0298435 |
fix: set X-Payload-HTTP-Method-Override as allowed cross origin header (#13717)
### What? Set X-Payload-HTTP-Method-Override as allowed cross origin header ### Why? As of #13619 the live preview uses POST method to retrieve updated data. When running cms and website on different origins, the cross origin requires X-Payload-HTTP-Method-Override header to be allowed ### How? Adding X-Payload-HTTP-Method-Override as a default allowed header |
||
|
|
7a8bcdf7ba |
feat(richtext-lexical): upgrade lexical from 0.34.0 to 0.35.0 (#13715)
This release upgrades the lexical dependency from 0.34.0 to 0.35.0. If you installed lexical manually, update it to 0.35.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.35.0](https://github.com/facebook/lexical/releases/tag/v0.35.0) |
||
|
|
6e203db33c |
feat(live-preview): client-side live preview: simplify population, support hooks and lexical block population (#13619)
Alternative solution to https://github.com/payloadcms/payload/pull/11104. Big thanks to @andershermansen and @GermanJablo for kickstarting work on a solution and bringing this to our attention. This PR copies over the live-preview test suite example from his PR. Fixes https://github.com/payloadcms/payload/issues/5285, https://github.com/payloadcms/payload/issues/6071 and https://github.com/payloadcms/payload/issues/8277. Potentially fixes #11801 This PR completely gets rid of our client-side live preview field traversal + population and all logic related to it, and instead lets the findByID endpoint handle it. The data sent through the live preview message event is now passed to findByID via the newly added `data` attribute. The findByID endpoint will then use this data and run hooks on it (which run population), instead of fetching the data from the database. This new API basically behaves like a `/api/populate?data=` endpoint, with the benefit that it runs all the hooks. Another use-case for it will be rendering lexical data. Sometimes you may only have unpopulated data available. This functionality allows you to then populate the lexical portion of it on-the-fly, so that you can properly render it to JSX while displaying images. ## Benefits - a lot less code to maintain. No duplicative population logic - much faster - one single API request instead of one request per relationship to populate - all payload features are now correctly supported (population and hooks) - since hooks are now running for client-side live preview, this means the `lexicalHTML` field is now supported! This was a long-running issue - this fixes a lot of population inconsistencies that we previously did not know of. For example, it previously populated lexical and slate relationships even if the data was saved in an incorrect format ## [Method Override (POST)](https://payloadcms.com/docs/rest-api/overview#using-method-override-post) change The population request to the findByID endpoint is sent as a post request, so that we can pass through the `data` without having to squeeze it into the url params. To do that, it uses the `X-Payload-HTTP-Method-Override` header. Previously, this functionality still expected the data to be sent through as URL search params - just passed to the body instead of the URL. In this PR, I made it possible to pass it as JSON instead. This means: - the receiving endpoint will receive the data under `req.data` and is not able to read it from the search params - this means existing endpoints won't support this functionality unless they also attempt to read from req.data. - for the purpose of this PR, the findByID endpoint was modified to support this behavior. This functionality is documented as it can be useful for user-defined endpoints as well. Passing data as json has the following benefits: - it's more performant - no need to serialize and deserialize data to search params via `qs-esm`. This is especially important here, as we are passing large amounts of json data - the current implementation was serializing the data incorrectly, leading to incorrect data within nested lexical nodes **Note for people passing their own live preview `requestHandler`:** instead of sending a GET request to populate documents, you will now need to send a POST request to the findByID endpoint and pass additional headers. Additionally, you will need to send through the arguments as JSON instead of search params and include `data` as an argument. Here is the updated defaultRequestHandler for reference: ```ts const defaultRequestHandler: CollectionPopulationRequestHandler = ({ apiPath, data, endpoint, serverURL, }) => { const url = `${serverURL}${apiPath}/${endpoint}` return fetch(url, { body: JSON.stringify(data), credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-Payload-HTTP-Method-Override': 'GET', }, method: 'POST', }) } ``` --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211124793355068 - https://app.asana.com/0/0/1211124793355066 |
||
|
|
0c44c3bdd9 |
fix(richtext-lexical): add internationalization support for default style label in textStateFeature (#13662)
Fixes #13470 Output: <img width="344" height="176" alt="image" src="https://github.com/user-attachments/assets/6a966e19-0a03-4252-9afa-b8149a95565b" /> |
||
|
|
008a52d8ec |
fix(templates): URI encode the cacheTag in getMediaUrl utility - Website template (#13558)
### What? Encode the cacheTag in the ImageMedia component ### Why? In the website template, media is render using the updatedAt field as a cacheTag, this value causes an InvalidQueryStringException when deploying to Cloudfront ### How? Uses encodeURIComponent on encode the date value of updatedAt Fixes https://github.com/payloadcms/payload/issues/13557 |
||
|
|
7e98fbf78e |
fix(ui): cannot filter by virtual relationship fields in WhereBuilder (#13686)
### What? - Fixed an issue where virtual relationship fields (`virtual: string`, e.g. `post.title`) could not be used in the WhereBuilder filter dropdown. - Ensured regular virtual fields (`virtual: true`) are still excluded since they are not backed by database fields. ### Why? Previously, attempting to filter by a virtual relationship caused runtime errors because the field was treated as a plain text field. At the same time, non-queryable virtuals needed to remain excluded to avoid invalid queries. ### How? - Updated `reduceFieldsToOptions` to recognize `virtual: string` fields and map them to their underlying path while keeping their declared type and operators. - Continued to filter out `virtual: true` fields in the same guard used for hidden/disabled fields. |
||
|
|
d109b44856 |
chore: add AGENTS.md (#13688)
Adds an [`AGENTS.md`](https://agents.md) file. |
||
|
|
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
|
||
|
|
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. |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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> |
||
|
|
a11586811e |
fix(ui): field.admin.condition data attribute missing document ID when document is being edited (#13676)
Fixes https://github.com/payloadcms/payload/issues/10379 During form state requests, the passed `data` did not have access to the document ID. This was because the data we use came from the client, passed as an argument. The client did not pass data that included the document ID. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211203844178567 |
||
|
|
9b109339ee |
fix(ui): await for publish success to update the UI (#13673)
Fixes #13664 Before: https://github.com/user-attachments/assets/083577f5-9006-4b35-9799-3df704ed84a8 After: https://github.com/user-attachments/assets/70a89a5b-bed4-447c-94f6-57bf3dbd2a70 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211210023936582 |
||
|
|
4e972c3fe2 |
docs(plugin-form-builder): add RadioField documentation (#13529)
### What? Adds comprehensive documentation for the RadioField component in the form builder plugin documentation. ### Why? Addresses review feedback from #11908 noting that the RadioField was not documented after being exported for end-user use. ### How? - Added RadioField section with complete property documentation - Added detailed Radio Options sub-section explaining option structure - Updated Select field documentation for consistency (added missing placeholder property and detailed options structure) - Added radio field to configuration example to show all available fields Fixes the documentation gap identified in #11908 review comments. |
||
|
|
cfb70f06bb |
ci(deps): bump the github_actions group across 3 directories with 4 updates (#13654)
Bumps the github_actions group with 4 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action), [SethCohen/github-releases-to-discord](https://github.com/sethcohen/github-releases-to-discord) and [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request). Bumps the github_actions group with 1 update in the /.github/actions/triage directory: [actions/checkout](https://github.com/actions/checkout). Bumps the github_actions group with 4 updates in the /.github/workflows directory: [actions/checkout](https://github.com/actions/checkout), [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action), [SethCohen/github-releases-to-discord](https://github.com/sethcohen/github-releases-to-discord) and [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request). Updates `actions/checkout` from 4 to 5 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v5.0.0</h2> <h2>What's Changed</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> <li>Prepare v5.0.0 release by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li> </ul> <h2>⚠️ Minimum Compatible Runner Version</h2> <p><strong>v2.327.1</strong><br /> <a href="https://github.com/actions/runner/releases/tag/v2.327.1">Release Notes</a></p> <p>Make sure your runner is updated to this version or newer to use this release.</p> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p> <h2>v4.3.0</h2> <h2>What's Changed</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> <li>Prepare release v4.3.0 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/motss"><code>@motss</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li><a href="https://github.com/mouismail"><code>@mouismail</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li><a href="https://github.com/benwells"><code>@benwells</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li><a href="https://github.com/nebuk89"><code>@nebuk89</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li><a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p> <h2>v4.2.2</h2> <h2>What's Changed</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4.2.1...v4.2.2">https://github.com/actions/checkout/compare/v4.2.1...v4.2.2</a></p> <h2>v4.2.1</h2> <h2>What's Changed</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/Jcambass"><code>@Jcambass</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1919">actions/checkout#1919</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4.2.0...v4.2.1">https://github.com/actions/checkout/compare/v4.2.0...v4.2.1</a></p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>V5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>V4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <h2>v4.2.0</h2> <ul> <li>Add Ref and Commit outputs by <a href="https://github.com/lucacome"><code>@lucacome</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li> <li>Dependency updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>- <a href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>, <a href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li> </ul> <h2>v4.1.7</h2> <ul> <li>Bump the minor-npm-dependencies group across 1 directory with 4 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li> <li>Bump actions/checkout from 3 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li> <li>Check out other refs/* by commit by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li> <li>Pin actions/checkout's own workflows to a known, good, stable version. by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li> </ul> <h2>v4.1.6</h2> <ul> <li>Check platform to set archive extension appropriately by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li> </ul> <h2>v4.1.5</h2> <ul> <li>Update NPM dependencies by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li> <li>Bump github/codeql-action from 2 to 3 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li> <li>Bump actions/setup-node from 1 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li> <li>Bump actions/upload-artifact from 2 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li> <li>README: Suggest <code>user.email</code> to be <code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li> </ul> <h2>v4.1.4</h2> <ul> <li>Disable <code>extensions.worktreeConfig</code> when disabling <code>sparse-checkout</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li> <li>Add dependabot config by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li> <li>Bump the minor-actions-dependencies group with 2 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li> <li>Bump word-wrap from 1.2.3 to 1.2.5 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li> </ul> <h2>v4.1.3</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
1c68ed5251 |
fix(ui): sidebar missing sticky top offset (#13652)
Regression from https://github.com/payloadcms/payload/pull/13340. Incorrect fallback value for the `--sidebar-wrap-top` css variable was used. ### Before <img width="2896" height="1200" alt="CleanShot 2025-09-01 at 10 03 39@2x" src="https://github.com/user-attachments/assets/caf054d2-ac61-4a96-b6a1-3981ce9f528f" /> ### After <img width="2894" height="1194" alt="CleanShot 2025-09-01 at 10 02 59@2x" src="https://github.com/user-attachments/assets/1e13e084-6f62-47bb-88b3-921ba5f3ff10" /> |
||
|
|
65b3845d92 |
fix(plugin-multi-tenant): skip baseFilter if user has access to all tenants (#13633)
Fixes https://github.com/payloadcms/payload/issues/13589#issuecomment-3234832478 ### Problem The baseFilter is being applied when a user has no tenant selected, is assigned to tenants BUT also passes the `userHasAccessToAllTenants` check. ### Fix Do not apply the baseFilter when no tenant is selected and the user passes the `userHasAccessToAllTenants` check. |
||
|
|
917c66fe44 |
fix(db-sqlite): convert Date to ISO 8601 string in queries (#11694)
### What? Restores the ability to query by `Date(...)` when using the `sqlite` adapter. ### Why? Queries involving JavaScript `Date`s return incorrect results because they are not converted to ISO 8601 strings by the `sqlite` adapter. ### How? Wraps comparison operators to convert `Date` parameters to ISO 8601 strings. Fixes #11692 --------- Co-authored-by: German Jablonski <43938777+GermanJablo@users.noreply.github.com> |