062c1d7e896d4e05f271dede6ed8002ae66c545c
14142 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
ac691b675b |
fix(ui): should not show publish specific locale button when no localized fields exist (#13459)
### What? Hides the `Publish in [specific locale]` button on collections and globals when no localized fields are present. ### Why? Currently, the `Publish in [specific locale]` shows on every collection/global as long as `localization` is enabled in the Payload config, however this is not necessary when the collection/global has no localized fields. ### How? Checks that localized fields exist prior to rendering the `Publish in [specific locale]` button. Fixes #13447 --------- Co-authored-by: German Jablonski <43938777+GermanJablo@users.noreply.github.com> |
||
|
|
fdab2712c0 |
feat(richtext-lexical): add options to hide block handles (#13647)
### What? Currently the `DraggableBlockPlugin` and `AddBlockHandlePlugin` components are automatically applied to every editor. For flexibility purposes, we want to allow these to be optionally removed when needed. ### Why? There are scenarios where you may want to enforce certain limitations on an editor, such as only allowing a single line of text. The draggable block element and add block button wouldn't play nicely with this scenario. Previously in order to do this, you needed to use custom css to hide the elements, which still technically allows them to be accessible to the end-user if they removed the CSS. This implementation ensures the handlers are properly removed when not wanted. ### How? Add `hideDraggableBlockElement` and `hideAddBlockButton` options to the lexical `admin` property. When these are set to `true`, the `DraggableBlockPlugin` and `AddBlockHandlePlugin` are not rendered to the DOM. Addresses #13636 |
||
|
|
a231a05b7c |
fix(plugin-nested-docs): prevent phantom breadcrumb row (#13628)
When saving a doc and regenerating the breadcrumbs array, a phantom row will append itself to the end of the array on save. This is because of fixes made in #13551 changed the way we merge array and block rows from the server. To fix this we need to ensure that row IDs are consistent across form state invocations, i.e. the hooks that mutate the array rows _cannot_ discard the row IDs. Before: https://github.com/user-attachments/assets/db715801-b4fd-4114-b39b-8d9b37fad979 After: https://github.com/user-attachments/assets/6da63a31-cd5d-43c1-a15e-caddbc540d56 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211175452200168 |
||
|
|
b99c324f1e |
perf(plugin-search): reindex collections in parallel, up to 80% faster (#13608)
Reindexing all collections in the search plugin was previously done in sequence which is slow and risks timing out under certain network conditions. By running these requests in parallel we are able to save **on average ~80%** in compute time. This test includes reindexing 2000 documents in total across 2 collections, 3 times over. The indexes themselves are relatively simple, containing only a couple simple fields each, so the savings would only increase with more complexity and/or more documents. Before: Attempt 1: 38434.87ms Attempt 2: 47852.61ms Attempt 3: 28407.79ms Avg: 38231.75ms After: Attempt 1: 7834.29ms Attempt 2: 7744.40ms Attempt 3: 7918.58ms Avg: 7832.42ms Total savings: ~79.51% --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211162504205343 |
||
|
|
426f99ca99 |
fix(ui): json field type ignoring editorOptions (#13630)
### What? Fix `JSON` field so that it respects `admin.editorOptions` (e.g. `tabSize`, `insertSpaces`, etc.), matching the behavior of the `code` field. Also refactor `CodeEditor` to set indentation and whitespace options per-model instead of globally. ### Why? - Previously, the JSON field ignored `editorOptions` and always serialized with spaces (`tabSize: 2`). This caused inconsistencies when comparing JSON and code fields configured with the same options. - Monaco’s global defaults were being overridden in a way that leaked settings between editors, making per-field customization unreliable. ### How? - Updated `JSON` field to extract `tabSize` from `editorOptions` and pass it through consistently when serializing and mounting the editor. - Refactored CodeEditor to: - Disable `detectIndentation` globally. - Apply `insertSpaces`, `tabSize`, and `trimAutoWhitespace` on a per-model basis inside onMount. - Preserve all other `editorOptions` as before. Fixes #13583 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211177100283503 --------- Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com> |
||
|
|
4600c94cac |
fix(plugin-nested-docs): crumbs not syncing on non-versioned collections (#13629)
Fixes https://github.com/payloadcms/payload/issues/13563 When using the nested docs plugin with collections that do not have drafts enabled. It was not syncing breadcrumbs from parent changes. The root cause was returning early on any document that did not meet `doc._status !== 'published'` check, which was **_always_** the case for non-draft collections. ### Before ```ts if (doc._status !== 'published') { return } ``` ### After ```ts if (collection.versions.drafts && doc._status !== 'published') { return } ``` |
||
|
|
c1b4960795 | chore(release): v3.54.0 [skip ci] | ||
|
|
97c41ce0c5 |
refactor: deprecate job queue runHooks property (#13617)
Setting `runHooks: true` is already discouraged and will make the job queue system a lot slower and less reliable. We have no test coverage for this and it's additional code we need to maintain. To further discourage using this property, this PR marks it as deprecated and for removal in 4.0. |
||
|
|
e0ffada80b |
feat: support parallel job queue tasks, speed up task running (#13614)
Currently, attempting to run tasks in parallel will result in DB errors. ## Solution The problem was caused due to inefficient db update calls. After each task completes, we need to update the log array in the payload-jobs collection. On postgres, that's a different table. Currently, the update works the following way: 1. Nuke the table 2. Re-insert every single row, including the new one This will throw db errors if multiple processes start doing that. Additionally, due to conflicts, new log rows may be lost. This PR makes use of the the [new db $push operation ](https://github.com/payloadcms/payload/pull/13453) we recently added to atomically push a new log row to the database in a single round-trip. This not only reduces the amount of db round trips (=> faster job queue system) but allows multiple tasks to perform this db operation in parallel, without conflicts. ## Problem **Example:** ```ts export const fastParallelTaskWorkflow: WorkflowConfig<'fastParallelTask'> = { slug: 'fastParallelTask', handler: async ({nlineTask }) => { const taskFunctions = [] for (let i = 0; i < 20; i++) { const idx = i + 1 taskFunctions.push(async () => { return await inlineTask(`parallel task ${idx}`, { input: { test: idx, }, task: () => { return { output: { taskID: idx.toString(), }, } }, }) }) } await Promise.all(taskFunctions.map((f) => f())) }, } ``` On SQLite, this would throw the following error: ```bash Caught error Error: UNIQUE constraint failed: payload_jobs_log.id at Object.next (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/libsql@0.4.7/node_modules/libsql/index.js:335:20) at Statement.all (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/libsql@0.4.7/node_modules/libsql/index.js:360:16) at executeStmt (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5/node_modules/@libsql/client/lib-cjs/sqlite3.js:285:34) at Sqlite3Client.execute (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5/node_modules/@libsql/client/lib-cjs/sqlite3.js:101:16) at /Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/libsql/session.ts:288:58 at LibSQLPreparedQuery.queryWithCache (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/sqlite-core/session.ts:79:18) at LibSQLPreparedQuery.values (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/libsql/session.ts:286:21) at LibSQLPreparedQuery.all (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/libsql/session.ts:214:27) at QueryPromise.all (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/sqlite-core/query-builders/insert.ts:402:26) at QueryPromise.execute (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/sqlite-core/query-builders/insert.ts:414:40) at QueryPromise.then (/Users/alessio/Documents/GitHub/payload/node_modules/.pnpm/drizzle-orm@0.44.2_@libsql+client@0.14.0_bufferutil@4.0.8_utf-8-validate@6.0.5__@opentelemetr_asjmtflojkxlnxrshoh4fj5f6u/node_modules/src/query-promise.ts:31:15) { rawCode: 1555, code: 'SQLITE_CONSTRAINT_PRIMARYKEY', libsqlError: true } ``` --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211001438499053 |
||
|
|
303381e049 |
fix(ui): prevent infinite redirect if no user (#13615)
Conditionally send the user to the inactivity route if there was a user but refresh failed. You can get into an infinite loop if you call this function externally and a redirect is being used in the url. |
||
|
|
0a18306599 |
feat: configurable toast notifications (#13609)
Follow up to #12119. You can now configure the toast notifications used in the admin panel through the Payload config: ```ts import { buildConfig } from 'payload' export default buildConfig({ // ... admin: { // ... toast: { duration: 8000, limit: 1, // ... } } }) ``` _Note: the toast config is temporarily labeled as experimental to allow for changes to the API, if necessary._ --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211139422639711 |
||
|
|
5ded64eaaf |
feat(db-*): support atomic array $push db updates (#13453)
This PR adds **atomic** `$push` **support for array fields**. It makes it possible to safely append new items to arrays, which is especially useful when running tasks in parallel (like job queues) where multiple processes might update the same record at the same time. By handling pushes atomically, we avoid race conditions and keep data consistent - especially on postgres, where the current implementation would nuke the entire array table before re-inserting every single array item. The feature works for both localized and unlocalized arrays, and supports pushing either single or multiple items at once. This PR is a requirement for reliably running parallel tasks in the job queue - see https://github.com/payloadcms/payload/pull/13452. Alongside documenting `$push`, this PR also adds documentation for `$inc`. ## Changes to updatedAt behavior https://github.com/payloadcms/payload/pull/13335 allows us to override the updatedAt property instead of the db always setting it to the current date. However, we are not able to skip updating the updatedAt property completely. This means, usage of $push results in 2 postgres db calls: 1. set updatedAt in main row 2. append array row in arrays table This PR changes the behavior to only automatically set updatedAt if it's undefined. If you explicitly set it to `null`, this now allows you to skip the db adapter automatically setting updatedAt. => This allows us to use $push in just one single db call ## Usage Examples ### Pushing a single item to an array ```ts const post = (await payload.db.updateOne({ data: { array: { $push: { text: 'some text 2', id: new mongoose.Types.ObjectId().toHexString(), }, }, }, collection: 'posts', id: post.id, })) ``` ### Pushing a single item to a localized array ```ts const post = (await payload.db.updateOne({ data: { arrayLocalized: { $push: { en: { text: 'some text 2', id: new mongoose.Types.ObjectId().toHexString(), }, es: { text: 'some text 2 es', id: new mongoose.Types.ObjectId().toHexString(), }, }, }, }, collection: 'posts', id: post.id, })) ``` ### Pushing multiple items to an array ```ts const post = (await payload.db.updateOne({ data: { array: { $push: [ { text: 'some text 2', id: new mongoose.Types.ObjectId().toHexString(), }, { text: 'some text 3', id: new mongoose.Types.ObjectId().toHexString(), }, ], }, }, collection: 'posts', id: post.id, })) ``` ### Pushing multiple items to a localized array ```ts const post = (await payload.db.updateOne({ data: { arrayLocalized: { $push: { en: { text: 'some text 2', id: new mongoose.Types.ObjectId().toHexString(), }, es: [ { text: 'some text 2 es', id: new mongoose.Types.ObjectId().toHexString(), }, { text: 'some text 3 es', id: new mongoose.Types.ObjectId().toHexString(), }, ], }, }, }, collection: 'posts', id: post.id, })) ``` --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211110462564647 |
||
|
|
a67043854e |
fix: restore as draft function was passing a published status (#13599)
### What When using the `Restore as draft` action from the version view, the restored document incorrectly appears as `published` in the API. This issue was reported by a client. ### Why In the `restoreVersion` operation, the document is updated via `db.updateOne` (line 265). The update passes along the status stored in the version being restored but does not respect the `draft` query parameter. ### How Ensures that the result status is explicitly set to `draft` when the `draft` argument is `true`. |
||
|
|
ded8ec4117 |
docs: adds default populate video (#13586)
Uses the VideoDrawer block to link relevant YouTube video at the bottom of defaultPopulate section |
||
|
|
5c41966a32 |
ci: remove run-e2e-turbo flow (#13611)
Removing `run-e2e-turbo` flow as it was unused. Can re-introduce or make this the default in future if needed. |
||
|
|
6db07f0c03 | feat(plugin-multi-tenant): allow custom tenant field per collection (#13553) | ||
|
|
13c24afa63 |
feat: allow multiple, different payload instances using getPayload in same process (#13603)
Fixes https://github.com/payloadcms/payload/issues/13433. Testing release: `3.54.0-internal.90cf7d5` Previously, when calling `getPayload`, you would always use the same, cached payload instance within a single process, regardless of the arguments passed to the `getPayload` function. This resulted in the following issues - both are fixed by this PR: - If, in your frontend you're calling `getPayload` without `cron: true`, and you're hosting the Payload Admin Panel in the same process, crons will not be enabled even if you visit the admin panel which calls `getPayload` with `cron: true`. This will break jobs autorun depending on which page you visit first - admin panel or frontend - Within the same process, you are unable to use `getPayload` twice for different instances of payload with different Payload Configs. On postgres, you can get around this by manually calling new `BasePayload()` which skips the cache. This did not work on mongoose though, as mongoose was caching the models on a global singleton (this PR addresses this). In order to bust the cache for different Payload Config, this PR introduces a new, optional `key` property to `getPayload`. ## Mongoose - disable using global singleton This PR refactors the Payload Mongoose adapter to stop relying on the global mongoose singleton. Instead, each adapter instance now creates and manages its own scoped Connection object. ### Motivation Previously, calling `getPayload()` more than once in the same process would throw `Cannot overwrite model` errors because models were compiled into the global singleton. This prevented running multiple Payload instances side-by-side, even when pointing at different databases. ### Changes - Replace usage of `mongoose.connect()` / `mongoose.model()` with instance-scoped `createConnection()` and `connection.model()`. - Ensure models, globals, and versions are compiled per connection, not globally. - Added proper `close()` handling on `this.connection` instead of `mongoose.disconnect()`. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211114366468745 |
||
|
|
03a00ca37d |
fix(plugin-multi-tenant): prevent duplicate filters on referenced blocks (#13607)
Fixes https://github.com/payloadcms/payload/issues/13601 When using block references, tenant filter options were being applied n+1 every time a block reference was used. |
||
|
|
138938ec55 |
fix(ui): bulk edit overwriting fields within named tabs (#13600)
Fixes https://github.com/payloadcms/payload/issues/13429 Having a config like the following would remove data from the nested tabs array field when bulk editing. ```ts { type: 'tabs', tabs: [ { label: 'Tabs Tabs Array', fields: [ { type: 'tabs', tabs: [ { name: 'tabTab', fields: [ { name: 'tabTabArray', type: 'array', fields: [ { name: 'tabTabArrayText', type: 'text', } ] } ] } ] } ] } ] } ``` |
||
|
|
1dc346af04 |
fix(graphql): invalid enum names when values include brackets (#13597)
### What? Brackets (`[ ]`) in option values end up in GraphQL enum names via `formatName`, causing schema generation to fail. This PR adds a single rule to `formatName`: - replace `[` and `]` with `_` ### Why? Using `_` (instead of removing the brackets) is safer and more consistent: - Avoid collisions: removal can merge distinct strings (`"A[B]"` → `"AB"`). `_` keeps them distinct (`"A_B"`). - **Consistency**: `formatName` already maps punctuation to `_` (`. - / + , ( ) '`). Brackets follow the same rule. Readability: `mb-[150px]` → `mb__150px_` is clearer than `mb150px`. Digits/units safety: removal can jam characters (`w-[2/3]` → `w23`); `_` avoids that (`w_2_3_`). ### How? Update formatName to include a bracket replacement step: ``` .replace(/\[|\]/g, '_') ``` No other call sites or value semantics change; only names containing brackets are affected. Fixes #13466 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211141396953194 |
||
|
|
bd81936ad4 |
fix(ui): autosave in document drawer overwrites local changes (#13587)
Fixes #13574. When editing an autosave-enabled document within a document drawer, any changes made will while the autosave is processing are ultimately discarded from local form state. This makes is difficult or even impossible to edit fields. This is because we server-render, then replace, the entire document on every save. This includes form state, which is stale because it was rendered while new changes were still being made. We don't need to re-render the entire view on every save, though, only on create. We don't do this on the top-level edit view, for example. Instead, we only need to replace form state. This change is also a performance improvement because we are no longer rendering all components unnecessarily, especially on every autosave interval. Before: https://github.com/user-attachments/assets/e9c221bf-4800-4153-af55-8b82e93b3c26 After: https://github.com/user-attachments/assets/d77ef2f3-b98b-41d6-ba6c-b502b9bb99cc Note: ignore the flashing autosave status and doc controls. This is horrible and we're actively fixing it, but is outside the scope of this PR. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211139422639700 |
||
|
|
cf37433667 |
fix(ui): multiple logout requests being made in parallel (#13595)
Fixes https://github.com/payloadcms/payload/issues/13565 The logout operation was running twice and causing a race condition on user updates. This change ensures the logout operation only runs 1 time. Really this view should have 1 purpose and that is to show the inactivity view. Currently it has 2 purposes which is why it needs the useEffect — the root of this issue. Instead we should just call the `logOut` function from the logout button instead of it linking to a logout page. |
||
|
|
344ad69572 |
fix(next): richtext fields not read-only for locked documents (#13579)
### What?
Ensure the Rich Text field is read-only when viewing a locked document.
### Why?
When opening a locked doc in read-only mode, the Rich Text field could
still appear editable. This is inconsistent with other fields and allows
users to try typing into a locked document.
### How?
- Pass `readOnly={isTrashedDoc || isLocked}` into `buildFormState` in
the edit view renderer.
|
||
|
|
f260d0ab49 |
feat(plugin-multi-tenant): re-enable global selector on all views (#13575)
Fixes #13559 Re-enable the global tenant selector on all views. In the last release the global tenant filter was only enabled on tenant enabled collection list views. This change allows the global tenant filter to be selected on all non-document views. This is useful on custom views or custom components on views that may not be tenant-enabled. |
||
|
|
45c3be25b4 |
docs: blank-template-url-fix (#13580)
- encodes URL in Installation section so link renders properly - Fixes #13403 |
||
|
|
a92c251620 |
fix: hide jobs stats global by default (#13566)
The jobs stats global is used internally to get the scheduling system to work. Currently, if scheduling is enabled, the "Payload Jobs Stats" global is visible in the Payload Admin Panel: <img width="524" height="252" alt="Screenshot 2025-08-23 at 00 10 13@2x" src="https://github.com/user-attachments/assets/91702c93-4b58-4990-922b-8241ea9aa00e" /> Similarly to how we do it in the Payload Jobs collection, this PR hides the payload jobs stats global from the admin panel by default --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211124797199081 |
||
|
|
810184269d |
fix(ui): auth-fields container renders despite no visible auth/API key/verify content (#13554)
### What? Prevents the Auth component from rendering an empty `.auth-fields` wrapper. ### Why? When `disableLocalStrategy` is true and `enableFields` is false, but `useAPIKey` is true while read access to API key fields is denied, the component still rendered the parent wrapper with a background—showing a blank box. ### How? Introduce `hasVisibleContent`: - `showAuthBlock = enableFields` - `showAPIKeyBlock = useAPIKey && canReadApiKey` - `showVerifyBlock = verify && isEditing` If none are true, return `null`. (`disableLocalStrategy` is already accounted for via `enableFields`.) Fixes #12089 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211117270523574 |
||
|
|
1e13474068 |
fix: deeply merge array and block rows from server form state (#13551)
Continuation of https://github.com/payloadcms/payload/pull/13501. When merging server form state with `acceptValues: true`, like on submit (not autosave), rows are not deeply merged causing custom row components, like row labels, to disappear. This is because we never attach components to the form state response unless it has re-rendered server-side, so unless we merge these rows with the current state, we lose them. Instead of allowing `acceptValues` to override all local changes to rows, we need to flag any newly added rows with `addedByServer` so they can bypass the merge strategy. Existing rows would continue to be merged as expected, and new rows are simply appended to the end. Discovered here: https://discord.com/channels/967097582721572934/967097582721572937/1408367321797365840 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211115023863814 |
||
|
|
598ff4cf7b | fix(ui): correctly pass query params to locked document requests (#10802) | ||
|
|
409dd56f90 |
fix(plugin-multi-tenant): autosave global documents not rendering (#13552)
Fixes https://github.com/payloadcms/payload/issues/13507 When enabling autosave on global multi-tenant documents, the page would not always render - more noticeably with smaller autosave intervals. |