Fixes#10284. The `admin.disable` property is no longer supported as of
v3. Instead, to opt-out of serving the Admin Panel, REST API, or GraphQL
API, you must delete their corresponding directories within your Next.js
app. For example, to opt-out of everything, delete the `/app/(payload)`
directory entirely. Or to remove specifically the Admin Panel or API
routes, delete the `/app/(payload)/admin` or `/app/(payload)/api`
directories, respectively. Note: if you've modified the default paths
for these routes via `admin.routes`, delete those directories instead.
Makes the wrapper container `<div class='payload-richtext'>` optional.
This is useful when importing and re-using the `<RichText/>` component
as part of another custom component already providing a container.
If the following markdown:
```md
**`text`**
```
was imported and then re-exported, the result was
```md
`**text**`
```
Which would have been rendered as
```html
<code>**text**</code>
```
Instead of
```html
<strong><code>text</code></strong>
```
The localization e2e test is notorious for flaking, consuming a lot of
time and resources continually retrying. This was because the test was
attempting to click DOM elements using selectors that never resolve, or
attempting to click inaccessible DOM nodes such as those behind a modal.
The fix is to ensure that the dot nav, for example, is disabled while
form state loads, and that modals are properly closed prior to executing
subsequent tests, etc. Tests also needed to explicitly check for
_enabled_ states before performing click actions, rather than simply
awaiting their visibility.
Fixes#10018. When toggling columns, then sorting them, the table is
reset to the collection's default columns instead of the user's
preferred columns. This is because when sorting columns, a stale
client-side cache of the user's preferences is used to update their sort
preference. This is because when column state is constructed
server-side, it completely bypasses the client-side cache. To fix this,
sort preferences are now also set on the server right alongside column
preferences, which performs an upsert-like operation to ensure that no
existing preferences are lost.
### What?
If you query with all locales using the `'all'` value for locales, the
`req.locale` value is `'all'` but the type definition only contains the
available locales.
### Why?
The `CustomPayloadRequestProperties.locale` property was only being
typed as `TypedLocale` and was not extending `'all'.`
### How?
Extends type all to the locale type definition in req
Fixes#10244
If `@payload-config` is not set in tsconfig, findConfig could fail when
performing a `path.extname` on an undefined value.
Example error in this scenario:
```
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined.
```
Reproduction steps:
1. Set `strict: true` in `templates/website/tsconfig.json`
2. You will find a ts error in
`templates/website/src/components/RichText/index.tsx`.
This is because the blockType property of blocks is generated by Payload
as a literal (e.g. "mediaBlock") and cannot be assigned to a string.
To test this PR, you can make the change to `JSXConvertersFunction` in
node_modules of the website template
A large number of users have been confused why their upload collection
doesn't work as expected when deploying to Vercel. This is because by
default, Payload uses local disk storage for file uploads - which will
not function properly in that environment.
This adds a warning if a user is deploying on Vercel, and they have any
upload collection missing an adapter - aka, writing to disk.
<!--
Thank you for the PR! Please go through the checklist below and make
sure you've completed all the steps.
Please review the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository if you haven't already.
The following items will ensure that your PR is handled as smoothly as
possible:
- PR Title must follow conventional commits format. For example, `feat:
my new feature`, `fix(plugin-seo): my fix`.
- Minimal description explained as if explained to someone not
immediately familiar with the code.
- Provide before/after screenshots or code diffs if applicable.
- Link any related issues/discussions from GitHub or Discord.
- Add review comments if necessary to explain to the reviewer the logic
behind a change
-->
### What?
This patch implements the functionality in `imageResizer` to omit the
generation of the image when either width or height is undefined and
`withoutEnlargement` is set to `undefined`
### Why?
#9986: `withoutEnlargement` doesn't work when `height` is undefined in
`upload.imageSizes`
### How?
This code checks if `withoutEnlargement` is undefined and either
`targetWidth` or `targetHeight` is missing. If so, it further checks
whether the target dimensions (if provided) are larger than the original
image dimensions. If the target would enlarge the image, it returns
'omit', skipping the resizing to prevent enlargement
Fixes#9986
---------
Co-authored-by: Patrik Kozak <patrik@payloadcms.com>
Say you opened
`http://localhost:3000/admin/collections/posts/67786e917283ec71ce4ab058?branch=main`,
the `branch=main` query param would not be passed to the find operation.
This means that reading `req.query` in, say, an `afterRead` hook, you
would get an empty object back.
This PR threads through `query`, `search` and `searchParams` with the
main goal of making them accessible in hooks.
## Use-case
Custom branch selector component in a collection's edit view.
Select branch => `branch` query param is added to the URL.
Collection `afterRead` hook then fetches the respective content from
that branch (which it gets from `req.query`) and returns its data
To reproduce the bug:
1. Within a Lexical editor, insert a relationship field.
2. In the drawer, change the selected collection.
3. The table below changes correctly, but the title and the "create new"
button quickly revert to the original option.
https://github.com/user-attachments/assets/e4b7c615-4b98-4c11-a4b9-a828606edb6f
<!--
Thank you for the PR! Please go through the checklist below and make
sure you've completed all the steps.
Please review the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository if you haven't already.
The following items will ensure that your PR is handled as smoothly as
possible:
- PR Title must follow conventional commits format. For example, `feat:
my new feature`, `fix(plugin-seo): my fix`.
- Minimal description explained as if explained to someone not
immediately familiar with the code.
- Provide before/after screenshots or code diffs if applicable.
- Link any related issues/discussions from GitHub or Discord.
- Add review comments if necessary to explain to the reviewer the logic
behind a change
### What?
### Why?
### How?
Fixes #
-->
Fixes#9882 and #9691
In 2.0, we would accept data coming back from an update operation and
then reflect those changes in UI.
However, in 3.0, we did not do that anymore - meaning you could change a
document with hooks in `beforeChange` or `afterChange`, but then not see
the changes made on the server.
This PR updates the way that `mergeServerFormState` works, and adds a
property to optionally allow values from server form state - which can
then be used in the `onSuccess` form handler which may need to define
new field values.
Allows to set `maxDepth: 0` for join fields and improves JSDoc about
`maxDepth`, adds tests to confirm that
https://github.com/payloadcms/payload/issues/10243 is not an issue, but
just happens because the default `maxDepth` is `1`.
### What
The vercel storage adapter returns a 500 internal server error when a
file is not found.
It's expected that it will return 404 when a file is not found.
### Why
The `head` function from vercel blob sdk does not return undefined when
a blob is not found, but throws an error as documented here:
https://vercel.com/docs/storage/vercel-blob/using-blob-sdk#head
### How
Check if exception thrown is of type BlobNotFoundError and return a 404
in that case.
### Testing
***Note***: I have not been able to test this inside payload itself as
I'm unable to build a package to test with. I have tested the
implementation outside. Is it possible to get a canary build so proper
testing with package can be done?
Fixes#10326
Similar to #10331. Since React 19, refs can now be passed directly
through props without the need for `React.forwardRef`. This greatly
simplifies components types and overall syntax.
This PR adds a button to the `/account` view which allows users to reset
their preferences on-demand. This is to that editors can quickly reset their
preferences via the admin ui without the need of accessing the db directly,
which was simply not possible before. To do this, we add a new button at
the bottom of the account view which performs a standard `DELETE`
request using the REST API to the `'payload-preferences'` collection.
Related: #9949
Demo: [Posts-reset-prefs--Payload.webm](https://github.com/user-attachments/assets/560cbbe3-06ef-4b7c-b3c2-9702883b1fc6)
Since the `@payloadcms/live-preview-react` package could be installed
within headless front-ends, it does not necessarily need to be
restricted to only React 19. This package does not use any newer React
features since hooks were introduced in v16.8.0. For this reason, the
peer deps have been loosened to allow this and all other major versions
up to React 19. This change was first introduced in #6387.
### What?
`path` was missing in server component prop types.
### How?
Adds a BaseFieldServerProps for each field type that accepts takes
`path` as a prop.
### What?
Previously, `.env` & `.env.example` modifications during `cpa` occurred
after a project was initialized.
### Why?
As a result, these modifications would be seen as uncommitted
modifications in the project repo.
### How?
Now, we make these modifications in the `createProject` script before
the project is initialized.
Also, updates the **template** `.env.example` files to use the generic
db name `your-database-name` for better alignment & clarity.
Fixes#10232
When updating password within the account view, the server console
throws an error because it is unable to find the remaining user fields
when building form state. This was because the field schema map sets
these fields within its own `_users.auth` key, separate from the other
fields. When the form submits, it uses this key as the schema path,
which may not contain all user fields, even though it sends full
document data through the request.
Fixes#10296. When an async `useEffect` runs twice or more before
resolving, we use the Abort Controller API to cancel previous events.
This works by instantiating a new ref on each run, and if a previous ref
was detected, it will be aborted and a new instance will be set up for
the next run. However, while the logic was aborting previous instances
as expected, it was failing to instantiate a new one.
Whenever form state fails, like when field conditions, validations, or
default value functions throw errors, blocks and array rows are stuck
within an infinite loading state. Examples of this might be when
accessing properties of undefined within these functions, etc. Although
these errors are logged to the server console, the UI is be misleading,
where the user often waits for the request to resolve rather than
understanding that an underlying API error has occurred. Now, we safely
execute these functions within a `try...catch` block and handle their
failures accordingly. On the client, form state will resolve as expected
using the default return values for these functions.
### What?
This PR aims to prevent a runtime error by allowing deletions in media
collections and preventing them from impacting workflows while using
`hasMany` upload fields.
### Why?
To prevent runtime issues during common tasks.
### How?
By treating deleted media documents as empty placeholders instead of
undefined objects.
Fixes#9328
Before:
[Dashboard-before--Payload.webm](https://github.com/user-attachments/assets/32cbfe1d-2569-43bc-be05-abd2d9913b9b)
After:
[Dashboard-after--Payload.webm](https://github.com/user-attachments/assets/b5cb67b8-21de-403c-879c-680e49fd380c)
Notes:
- There is room for improvement here: allow selection of existing media
in upload collection instead of forcing user to upload new. Workaround
is to remove the row and choose existing as usual.
- New uploads chosen will always replace the first instance of undefined
placeholder due to the simple check. If you have 3 deleted entries and
open the drawer on the second one, then it will populate the first one
anyway. This can be improved but will require more laborious code
changes.
- Noticed an issue where deleted non-hasMany upload fields do not
re-render after a file is uploaded. It only shows the previous deleted
doc, ie id: "untitled - ID: ...". Re-renders correctly when choosing
from existing. This is unrelated to this PR. I will investigate further.
- I'm realizing this actually diverges from what `db-postgres` does, as
deleted entries in a `hasMany` upload gets removed from the field in the
initial deletion probably due to cascading the deletion...
When hitting the delete or updates routes and no docs were effected, the
API returns success messages with improper verb tenses, i.e. `Deleted 0
Post successfully`.
### What?
Previously, while uploading a file - if the uploading process took a bit
of time, users could still save the document prior to the upload fully
completing.
### Why?
During the uploading process - the save button should be disabled until
the upload is complete to prevent premature saving of an upload
document.
### How?
Now, we keep track of the state of the upload in a provider and disable
the save button until the file is fully uploaded.