This PR adds a new `siblingFields` argument to field hooks. This allows
us to dramatically simplify the `lexicalHTML` field, which previously
had to use a complex `findFieldPathAndSiblingFields` function that
deeply traverses the entire `CollectionConfig` just to find the sibling
fields.
This will hopefully allow pnpm to reliably install the correct lexical version, as lexical is now solely part of our `dependencies`. Currently, pnpm completely disregards lexical version bumps until the user deletes both the lockfile and their `node_modules` folder.
The downside of this is that pnpm will no longer throw a warning if payload is installed in a project with a mismatching lexical version. However, noone read that warning anyways, and our runtime dependency checker is more reliable.
One step closer to being able to remove `noUncheckedIndexedAccess` in
`packages/richtext-lexical/tsconfig.json`.
I'm introducing UploadData_P4 which is a more precise version of
UploadData. I'm doing it as a different type because there's a chance
it'll be a breaking change for some users.
UploadData is used in many places, but I'm currently replacing it only
in
`packages/richtext-lexical/src/exports/react/components/RichText/converter/converters/upload.tsx`,
because in the other files it's too rooted to other types like
UploadNode.
Elaborate how one is supposed to change the admin panel's language
because it is not initially clear or trivial to someone new and going
through the docs from the start.
---------
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Make it clearer that you need to install `@payloadcms/translations`. I
think it would help for new people, especially new programmers.
---------
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
🤖 Automated bump of templates for v3.23.0
Triggered by user: @denolfe
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Fixes#11082
In addition to fixing the bug described in that issue, I'm fixing the
problem where when outdenting, indent 0 blocks stay the same. The new
logic verifies that all selected blocks can be outdented.
It remains to be done the same with the tab and shift + tab commands.
Fixes#10440. When `filterOptions` are set on a relationship field,
those same filters are not applied to the `Filter` component within the
list view. This is because `filterOptions` is not being thread into the
`RelationshipFilter` component responsible for populating the available
options.
To do this, we first need to be resolve the filter options on the server
as they accept functions. Once resolved, they can be prop-drilled into
the proper component and appended onto the client-side "where" query.
Reliant on #11080.
Fixes#9873. The relationship filter in the "where" builder renders
stale values when switching between fields or adding additional "and"
conditions. This was because the `RelationshipFilter` component was not
responding to changes in the `relationTo` prop and failing to reset
internal state when these events took place.
While it sounds like a simple fix, it was actually quite extensive. The
`RelationshipFilter` component was previously relying on a `useEffect`
that had a callback in its dependencies. This was causing the effect to
run uncontrollably using old references. To avoid this, we use the new
`useEffectEvent` approach which allows the underlying effect to run much
more precisely. Same with the `Condition` component that wraps it. We
now run callbacks directly within event handlers as much as possible,
and rely on `useEffectEvent` _only_ for debounced value changes.
This component was also unnecessarily complex...and still is to some
degree. Previously, it was maintaining two separate refs, one to track
the relationships that have yet to fully load, and another to track the
next pages of each relationship that need to load on the next run. These
have been combined into a single ref that tracks both simultaneously, as
this data is interrelated.
This change also does some much needed housekeeping to the
`WhereBuilder` by improving types, defaulting the operator field, etc.
Related: #11023 and #11032
Unrelated: finds a few more instances where the new `addListFilter`
helper from #11026 could be used. Also removes a few duplicative tests.
Fixes https://github.com/payloadcms/payload/issues/11109
Rewrites the description for the `handler` property of the `Endpoint`
type. This function:
* does not have `res` and `next` anymore
* the `handler` property does not accept an array of functions anymore.
Additionally, adds a more meaningful description for the `req` argument.
<!--
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 #
-->
### What?
This PR adds a table to the [Payload-wide Upload
Options](https://payloadcms.com/docs/upload/overview#payload-wide-upload-options)
section of the docs.
### Why?
To give users more insight into the customization options provided
out-of-the-box with uploads. Previously, these options were not visible
on the docs, forcing users to inspect source code to see how they can
customize their global upload settings. It wasn't clear, for example,
that a `fileSize` limit would not produce a 413 in a response by
default, but would truncate the file contents instead.
### How?
Changes to `docs/upload/overview.mdx`.
This PR extends timezone support to scheduled publish UI and collection,
the timezone will be stored on the `input` JSON instead of the
`waitUntil` date field so that we avoid needing a schema migration for
SQL databases.

If a timezone is selected then the displayed date in the table will be
formatted for that timezone.
Timezones remain optional here as they can be deselected in which case
the date will behave as normal, rendering and formatting to the user's
local timezone.
For the backend logic that can be left untouched since the underlying
date values are stored in UTC the job runners will always handle this
relative time by default.
Todo:
- [x] add e2e to this drawer too to ensure that dates are rendered as
expected
Fixes https://github.com/payloadcms/payload/issues/10810
This was caused by using `COUNT(*)` aggregation instead of
`COUNT(DISTINCT table.id)`. However, we want to use `COUNT(*)` because
`COUNT(DISTINCT table.id)` is slow on large tables. Now we fallback to
`COUNT(DISTINCT table.id)` only when `COUNT(*)` cannot work properly.
Example of a query that leads to incorrect `totalDocs`:
```ts
const res = await payload.find({
collection: 'directors',
limit: 10,
where: {
or: [
{
movies: {
equals: movie2.id,
},
},
{
movies: {
equals: movie1.id,
},
},
{
movies: {
equals: movie1.id,
},
},
],
},
})
```
### What?
Initial values should be set from the server when `acceptValues` is
true.
### Why?
This is needed since we take the values from the server after a
successful form submission.
### How?
Add `initialValue` into `serverPropsToAccept` when `acceptValues` is
true.
Fixes https://github.com/payloadcms/payload/issues/10820
---------
Co-authored-by: Alessio Gravili <alessio@gravili.de>
Adds a `shouldAutoRun` property to the `jobs` config to be able to have
fine-grained control over if jobs should be run. This is helpful in
cases where you may have many horizontally scaled compute instances, and
only one instance should be responsible for running jobs.
### What?
If you had multiple operator constraints on a single field, the last one
defined would be the only one used.
Example:
```ts
where: {
id: {
in: [doc2.id],
not_in: [], // <-- only respected this operator constraint
},
}
```
and
```ts
where: {
id: {
not_in: [],
in: [doc2.id], // <-- only respected this operator constraint
},
}
```
They would yield different results.
### Why?
The results were not merged into an `$and` query inside parseParams.
### How?
Merges the results within an `$and` constraint.
Fixes https://github.com/payloadcms/payload/issues/10944
Supersedes https://github.com/payloadcms/payload/pull/11011
### What?
Within collections using the `storage-s3` plugins, we eventually start
receiving the following warnings:
`@smithy/node-http-handler:WARN socket usage at capacity=50 and 156
additional requests are enqueued. See
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html
or increase socketAcquisitionWarningTimeout=(millis) in the
NodeHttpHandler config.`
Also referenced in this issue: #6382
The
[solution](https://github.com/payloadcms/payload/issues/6382#issuecomment-2325468104)
provided by @denolfe in that issue only delayed the reappearance of the
problem somewhat, but did not resolve it.
### Why?
As far as I understand, in the `staticHandler` of the plugin, when
getting items from storage, and they are currently cached, the cached
results are immediately returned without handling the stream. As per
[this](https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/CLIENTS.md#nodejs-requesthandler)
entry in the aws-sdk docs, if the streaming response is not read, or
manually destroyed, a socket might not properly close.
### How?
Before returning the cached items, manually destroy the streaming
response to make certain the socket is being properly closed.
Additionally, add an error check to also consume/destroy the streaming
response in case an error occurs, to not leave orphaned sockets.
Fixes#6382
Adds support for timezone selection on date fields.
### Summary
New `admin.timezones` config:
```ts
{
// ...
admin: {
// ...
timezones: {
supportedTimezones: ({ defaultTimezones }) => [
...defaultTimezones,
{ label: '(GMT-6) Monterrey, Nuevo Leon', value: 'America/Monterrey' },
],
defaultTimezone: 'America/Monterrey',
},
}
}
```
New `timezone` property on date fields:
```ts
{
type: 'date',
name: 'date',
timezone: true,
}
```
### Configuration
All date fields now accept `timezone: true` to enable this feature,
which will inject a new field into the configuration using the date
field's name to construct the name for the timezone column. So
`publishingDate` will have `publishingDate_tz` as an accompanying
column. This new field is inserted during config sanitisation.
Dates continue to be stored in UTC, this will help maintain dates
without needing a migration and it makes it easier for data to be
manipulated as needed. Mongodb also has a restriction around storing
dates only as UTC.
All timezones are stored by their IANA names so it's compatible with
browser APIs. There is a newly generated type for `SupportedTimezones`
which is reused across fields.
We handle timezone calculations via a new package `@date-fns/tz` which
we will be using in the future for handling timezone aware scheduled
publishing/unpublishing and more.
### UI
Dark mode

Light mode

We now properly allow relative live preview URLs which is handy if
you're deploying on a platform like Vercel and do not know what the
preview domain is going to end up being at build time.
This PR also removes some problematic code in the website template which
hard-codes the protocol to `https://` in production even if you're
running locally.
Fixes#11070
Adds documentation for the `usePayloadAPI` hook to the React Hooks
documentation.
The new section provides details on how the hook works, its parameters,
return values, and example usage.
**Changes:**
- Added `usePayloadAPI` documentation to the React Hooks page.
- Explained its purpose, arguments, and return values.
- Included an example demonstrating how to fetch data and update request
parameters dynamically.
Fixes: #10969
### What
Before, richText docs were showing a feature name spelt as
`BlockQuoteFeature`.
### How?
However, the accurate spelling of the feature is `BlockquoteFeature`.
If an error is thrown during the payload init process, it gets ignored and an unhelpful, meaningless
` ⨯ OverwriteModelError: Cannot overwrite ___ model once compiled.`
error is thrown instead. The actual error that caused this will never be logged. This PR fixes this and ensures the actual error is logged.
## Why did this happen?
If an error is thrown during the init process, it is caught and handled by the `src/utilities/routeError.ts` - this helper properly logs the error using pino.
The problem is that pino did not exist, as payload did not finish initializing - it errored during it. So, it tries to initialize payload again before logging the error... which will fail again. If payload failed initializing the first time, it will fail the second time. => No error is logged.
This PR ensures the error is logged using `console.error()` if the originating error was thrown during the payload init process, instead of attempting to initialize it again and again
Fixes https://github.com/payloadcms/payload/issues/11055
Functions passed to array field, block field or block `labels` were not properly handled in the client config, causing those functions to be sent to the client. This leads to a "Functions cannot be passed directly to Client Component" error
This PR exposes the `ClientConfig` as an argument to the lexical `ClientFeature`. This is a requirement for https://github.com/payloadcms/payload/pull/10905, as we need to get the ClientBlocks from the `clientConfig.blocksMap` if they are strings.
## Example
```tsx
export const BlocksFeatureClient = createClientFeature(
({ config, featureClientSchemaMap, props, schemaPath }) => { // <= config is the new argument
// Return ClientFeature
})
```
When filtering the list view, removing the final condition from the
query closes the "where" builder entirely. This forces the user to
re-open the filter controls and begin adding conditions from the start.
This PR fixes 2 eslint config issues that prevented it from running in our test dir
- spec files were ignored by the root eslint config. This should have only ignored spec files within our packages, as they are ignored by the respective package tsconfigs
- defining the payload plugin crashed eslint in our test dir, as it was already defined in the root eslint config it was inheriting
The "select decoratorNodes" test was flaky, as it often selected the relationship block node with a relationship to "payload.jpg", instead of the upload node for "payload.jpg", depending on which node loaded first.
This PR ensures it waits for all blocks to be loaded, and updates the selector to specifically target the upload node
Previously, data created by other tests was also leaking into unrelated tests, causing them to fail. The new reset-db-between-tests logic added by this PR fixes this.
Additionally, this increases playwright timeouts for CI, and adds a specific timeout override for opening a drawer, as it was incredibly slow in CI