Commit Graph

12874 Commits

Author SHA1 Message Date
Alessio Gravili
4c8cafd6a6 perf: deduplicate blocks used in multiple places using new config.blocks property (#10905)
If you have multiple blocks that are used in multiple places, this can quickly blow up the size of your Payload Config. This will incur a performance hit, as more data is
1.  sent to the client (=> bloated `ClientConfig` and large initial html) and
2. processed on the server (permissions are calculated every single time you navigate to a page - this iterates through all blocks you have defined, even if they're duplicative)

This can be optimized by defining your block **once** in your Payload Config, and just referencing the block slug whenever it's used, instead of passing the entire block config. To do this, the block can be defined in the `blocks` array of the Payload Config. The slug can then be passed to the `blockReferences` array in the Blocks Field - the `blocks` array has to be empty for compatibility reasons.

```ts
import { buildConfig } from 'payload'
import { lexicalEditor, BlocksFeature } from '@payloadcms/richtext-lexical'

// Payload Config
const config = buildConfig({
  // Define the block once
  blocks: [
    {
      slug: 'TextBlock',
      fields: [
        {
          name: 'text',
          type: 'text',
        },
      ],
    },
  ],
  collections: [
    {
      slug: 'collection1',
      fields: [
        {
          name: 'content',
          type: 'blocks',
          // Reference the block by slug
          blockReferences: ['TextBlock'],
          blocks: [], // Required to be empty, for compatibility reasons
        },
      ],
    },
     {
      slug: 'collection2',
      fields: [
        {
          name: 'editor',
          type: 'richText',
          editor: lexicalEditor({
            BlocksFeature({
              // Same reference can be reused anywhere, even in the lexical editor, without incurred performance hit
              blocks: ['TextBlock'],
            })
          })
        },
      ],
    },
  ],
})
```

## v4.0 Plans

In 4.0, we will remove the `blockReferences` property, and allow string block references to be passed directly to the blocks `property`. Essentially, we'd remove the `blocks` property and rename `blockReferences` to `blocks`.

The reason we opted to a new property in this PR is to avoid breaking changes. Allowing strings to be passed to the `blocks` property will prevent plugins that iterate through fields / blocks from compiling.

## PR Changes

- Testing: This PR introduces a plugin that automatically converts blocks to block references. This is done in the fields__blocks test suite, to run our existing test suite using block references.

- Block References support: Most changes are similar. Everywhere we iterate through blocks, we have to now do the following:
1. Check if `field.blockReferences` is provided. If so, only iterate through that.
2. Check if the block is an object (= actual block), or string
3. If it's a string, pull the actual block from the Payload Config or from `payload.blocks`.

The exception is config sanitization and block type generations. This PR optimizes them so that each block is only handled once, instead of every time the block is referenced.

## Benchmarks

60 Block fields, each block field having the same 600 Blocks.

### Before:
**Initial HTML:** 195 kB
**Generated types:** takes 11 minutes, 461,209 lines

https://github.com/user-attachments/assets/11d49a4e-5414-4579-8050-e6346e552f56

### After:
**Initial HTML:** 73.6 kB
**Generated types:** takes 2 seconds, 35,810 lines

https://github.com/user-attachments/assets/3eab1a99-6c29-489d-add5-698df67780a3

### After Permissions Optimization (follow-up PR)
Initial HTML: 73.6 kB

https://github.com/user-attachments/assets/a909202e-45a8-4bf6-9a38-8c85813f1312


## Future Plans

1. This PR does not yet deduplicate block references during permissions calculation. We'll optimize that in a separate PR, as this one is already large enough
2. The same optimization can be done to deduplicate fields. One common use-case would be link field groups that may be referenced in multiple entities, outside of blocks. We might explore adding a new `fieldReferences` property, that allows you to reference those same `config.blocks`.
2025-02-14 00:08:20 +00:00
Alessio Gravili
152a9b6adf docs: fix invalid link (#11174)
Links have to be defined in markdown - html a tags won't automatically be converted to links anymore.
2025-02-13 16:46:20 -07:00
lucasbajoua
d47c980509 fix(ui): url encode imageCacheTag for media on dashboard (#11164)
### What?
URL encodes the imageCacheTag query param used to render Media on the
Admin Dashboard

### Why?
The format of the timestamp used as the `imageCacheTag` is causing an
`InvalidQueryStringException` when hosting with Cloudfront + Lambda
(SST/OpenNext)
[See issue](https://github.com/payloadcms/payload/issues/11163)

### How?
Uses `encodeURIComponent` on instances where the `imageCacheTag` is
being formatted for the request URL. (In EditUpload, Thumbnail, and
PreviewSizes)

Fixes #11163

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2025-02-13 21:42:52 +00:00
Kendell Joseph
7f124cfe93 fix(ui): json schema (#11123)
Fixes https://github.com/payloadcms/payload/issues/10166

[fix: json schema #11123 - Watch
Video](https://www.loom.com/share/0f5199234ad1486f910a39165de837e5)

- Using the same `URI` with the same `schema` will throw an error.
- Using the same `URI` with a different `schema` will throw a warning
(but still work).

If you want to use the same schema on a different field, you need to
define a different URI.
2025-02-13 16:26:57 -05:00
Said Akhrarov
6901b2639d fix(ui): prevent omitting fileSize from non-images (#11146)
### What?
This PR displays file size in upload cards for all upload mimetypes. The
current behavior hides this metric from the user if the file mimetype
does not start with `image`.

### Why?
Showing end-users and editors a file size is universally useful - not
only for images, but for all types of files that can be uploaded via the
upload field.

### How?
By making the predicate that adds this metric less restrictive. Instead
of checking if the mimetype is image-like, it checks if the file size is
truthy.

Before:

![image](https://github.com/user-attachments/assets/949e3be9-6dca-43c3-b2f8-a7e91307e48e)

After:

![image](https://github.com/user-attachments/assets/cb500390-dc64-48e3-a87c-e4ec4d19d019)
2025-02-13 16:05:12 -05:00
Jacob Fletcher
16d75a7c7b feat(ui): refines progress bar animation curve (#11167)
Refines the animation curve used in the new progress bar for route
transitions. Uses an exponential acceleration and decay so that the
indicator progresses quickly at the onset, then gradually decelerates at
it approaches completion. Also caps the progress at ~90%.

Introduced in #9275.
2025-02-13 20:37:30 +00:00
Jacob Fletcher
de68ef4548 fix(ui): adds delay to progress bar for fast networks (#11157)
On fast networks where page transitions are quick, such as local dev in
most cases, the progress bar should not render. This leads to a constant
flashing of the progress bar at the top of the screen and does not
provide any value.

The fix is to add a delay to the initial rendering of the progress bar,
and only show if the transition takes longer than _n_ milliseconds. This
value can be adjusted as needed, but right now is set to 150ms.

Introduced in #9275.
2025-02-13 12:35:41 -05:00
Jacob Fletcher
f4639c418f chore(deps): bumps @monaco-editor/react to v4.7.0 to suppress react 19 warnings (#11161)
The `@monaco-editor/react` package now includes React 19 in its peer
dependencies thanks to
https://github.com/suren-atoyan/monaco-react/pull/651. This package was
also incorrectly listed in `payload` as a regular dependency, but since
it's only used for type imports, it should be listed a dev dependency
instead.
2025-02-13 12:24:53 -05:00
Adit
24da30ab74 docs: add inlineBlock converter example to the converters configuration in Converters.mdx (#11158)
### What?
Added a quick example to showcase how to add a converter for inlineBlocks.

### Why?
This is not easy to figure out in the current version. As per [Discord discussion](https://discord.com/channels/967097582721572934/1338624577990823997)

### How?
Added a very basic 3 lines example to keep the file simple.
2025-02-13 17:01:23 +00:00
Sasha
4be410cc4f test: add types testing for select and joins (#11138)
Adds additional type testing for `select` and `joins` Local API
properties to ensure we don't break those between changes
2025-02-13 18:11:31 +02:00
Jacob Fletcher
cd1117515b refactor(ui): deprecates Link props (#11155)
Deprecates all cases where `Link` could be sent as a prop. This was a
relic from the past, where we attempted to make our UI library
router-agnostic. This was a pipe dream and created more problems than it
solved, for example the logout button was missing this prop, causing it
to render an anchor tag and perform a hard navigation (caught in #9275).

Does so in a non-breaking way, where these props are now optional and
simply unused, as opposed to removing them outright.
2025-02-13 11:10:57 -05:00
Jacob Fletcher
3f550bc0ec feat: route transitions (#9275)
Due to nature of server-side rendering, navigation within the admin
panel can lead to slow page response times. This can lead to the feeling
of an unresponsive app after clicking a link, for example, where the
page remains in a stale state while the server is processing. This is
especially noticeable on slow networks when navigating to data heavy or
process intensive pages.

To alleviate the bad UX that this causes, the user needs immediate
visual indication that _something_ is taking place. This PR renders a
progress bar in the admin panel which is immediately displayed when a
user clicks a link, and incrementally grows in size until the new route
has loaded in.

Inspired by https://github.com/vercel/react-transition-progress.

Old:

https://github.com/user-attachments/assets/1820dad1-3aea-417f-a61d-52244b12dc8d

New:

https://github.com/user-attachments/assets/99f4bb82-61d9-4a4c-9bdf-9e379bbafd31

To tie into the progress bar, you'll need to use Payload's new `Link`
component instead of the one provided by Next.js:

```diff
- import { Link } from 'next/link'
+ import { Link } from '@payloadcms/ui'
```

Here's an example:

```tsx
import { Link } from '@payloadcms/ui'

const MyComponent = () => {
  return (
    <Link href="/somewhere">
      Go Somewhere
    </Link>
  )
}
```

In order to trigger route transitions for a direct router event such as
`router.push`, you'll need to wrap your function calls with the
`startRouteTransition` method provided by the `useRouteTransition` hook.

```ts
'use client'
import React, { useCallback } from 'react'
import { useTransition } from '@payloadcms/ui'
import { useRouter } from 'next/navigation'

const MyComponent: React.FC = () => {
  const router = useRouter()
  const { startRouteTransition } = useRouteTransition()
 
  const redirectSomewhere = useCallback(() => {
    startRouteTransition(() => router.push('/somewhere'))
  }, [startRouteTransition, router])
 
  // ...
}
```

In the future [Next.js might provide native support for
this](https://github.com/vercel/next.js/discussions/41934#discussioncomment-12077414),
and if it does, this implementation can likely be simplified.

Of course there are other ways of achieving this, such as with
[Suspense](https://react.dev/reference/react/Suspense), but they all
come with a different set of caveats. For example with Suspense, you
must provide a fallback component. This means that the user might be
able to immediately navigate to the new page, which is good, but they'd
be presented with a skeleton UI while the other parts of the page stream
in. Not necessarily an improvement to UX as there would be multiple
loading states with this approach.

There are other problems with using Suspense as well. Our default
template, for example, contains the app header and sidebar which are not
rendered within the root layout. This means that they need to stream in
every single time. On fast networks, this would also lead to a
noticeable "blink" unless there is some mechanism by which we can detect
and defer the fallback from ever rendering in such cases. Might still be
worth exploring in the future though.
2025-02-13 09:48:13 -05:00
Germán Jabloñski
706410e693 chore: update codeowners (#11151)
I only remove myself from this file.

I'm getting a lot of notifications that don't significantly change those
directories. I'll keep an eye out, but feel free to assign me as a
reviewer wherever you see fit!
2025-02-13 13:51:28 +00:00
Dan Ribbens
3131dba039 docs: filterAvailableLocales (#11031)
Adding documentation and tests missing in PR #11007

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Co-authored-by: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
2025-02-12 14:48:12 -05:00
Jessica Chowdhury
6bfa66c9ff chore: typo in migrate:fresh command (#11140)
### What?
The migration CLI help says `migration:fresh` is available to use - this
doesn't exist, the command should be `migrate:fresh`.

Closes #10965 & #10967
2025-02-12 16:23:11 +00:00
Germán Jabloñski
6eee787493 chore: add typescript-strict-plugin to the payload package for incremental file-by-file migration [skip lint] (#11133)
### What?

Implement the
[typescript-strict-plugin](https://github.com/allegro/typescript-strict-plugin)
plugin in the payload (core) package.

### Why?

1. One strategy for incremental migration is to enable strictness rules
in tsconfig, fix some errors, and push them without committing the
changes to tsconfig.json. However, this is not feasible for a package as
large as Payload that has over 1000 typescript errors. Until the work is
done, new contributions would undo the work being done.
2. Even if no migration work is done after this PR, this change already
improves the strictness of the package. 89 of the 311 files within the
package already satisfy strict mode. This PR only adds a comment
`@ts-strict-ignore` to files that had at least one compilation error.
This way, the propagation of errors in those files is stopped.
3. New files created in the package are strict by default (this was the
main improvement in version 2 of `typescript-strict-plugin`).

I recommend starting the migration with this package because it is the
one that almost all the others depend on. Once we finish this package,
we can repeat the same strategy on another one, or use the strategy I
mentioned in point 1 if the package is small.

### Note

If you don't see errors in the IDE when you uncomment `//
@ts-strict-ignore`, try restarting the typescript server or VSCode


### How to contribute to the migration ❤️

1. Remove `// @ts-strict-ignore` comments from 1 or more files
2. Fix the pending errors (they should appear in your IDE's intellisense
or when running `cd packages/payload` + `pnpm build:types`
3. Submit your PR!

Important: You don't need to fix everything at once! Furthermore, I
recommend breaking this down into very small PRs to trace potential
issues later if there are any. So if you have 5 minutes, tackle a small
file—every bit counts! 🤗
2025-02-12 11:06:03 -05:00
Hulpoi George-Valentin
30c77d8137 fix(ui): safe call within useEffect teardown (#11135)
`NavProvider` useEffects teardown is trying to set `style` on an element
that may not exist. The original code produces the following error:


![image](https://github.com/user-attachments/assets/11a83fbe-67eb-42a9-bd78-749ea98b67c5)

![image](https://github.com/user-attachments/assets/28ed2534-2387-416b-8191-d68b478161aa)

Therefore, a condition has been added to check if `navRef.current` is
truthy.
2025-02-12 15:30:31 +00:00
Paul
707e85ebcf templates: add new readme for quick start on vercel platform (#11131) 2025-02-12 15:28:59 +00:00
Germán Jabloñski
09ada20ce8 chore(richtext-lexical): fix unchecked indexed access, make richtext-lexical full ts strict (part 5/5) (#11132)
This PR concludes the series to make `richtext-lexical` full strict in
TypeScript 🥳
2025-02-12 12:28:28 +00:00
David Hu
9068bdacae fix(richtext-lexical): add container div to table element to allow horizontal scroll in HTML and JSX converters (#11119)
### What?
Add a `div` wrapper to `table` tag in `TableFeature`

### Why?
This allows for adding horizontal scrolling to the table. We use table
in our blog, however, on mobile, the content is wider than the screen
width, and causes a horizontal scroll of all the content. I attached a
video to show. You can see it by visiting the page on mobile
https://magichour.ai/blog/10-best-ai-video-generators


https://github.com/user-attachments/assets/55778765-697e-426d-ac8a-1b0913adac13


Adding this container div allow me to target the div with a style
```css
.lexical-table-container {
  overflow-x: scroll;
}
```

### How?
![Screenshot 2025-02-11 at 11 26
18 AM](https://github.com/user-attachments/assets/873050b3-79b9-49ec-85ed-297286813577)

I tested this change by manually editing the HTML in our blog to include
the `div` with the overflow style, and it fixes the issue.

Also, verified just adding the `div` did not change anything related to
the rendered output.
2025-02-12 09:10:49 -03:00
Alessio Gravili
155f9f80fe feat: add siblingFields arg to field hooks (#11117)
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.
2025-02-11 14:22:31 -07:00
Alessio Gravili
2056e9b740 fix(richtext-lexical): reliably install exact lexical version by removing it from peerDeps (#11122)
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.
2025-02-11 21:01:33 +00:00
Paul
44be433d44 templates: add packageManager to website template instead of engines.pnpm (#11121)
Should fix breaking changes issues with pnpm 10
2025-02-11 19:50:40 +00:00
Germán Jabloñski
002e921ede chore(richtext-lexical): improve types of UploadData (#10982)
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.
2025-02-11 14:24:05 -05:00
Alejandro Martinez
3098f35537 docs: explains i18n language changing (#10964)
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>
2025-02-11 14:14:49 -05:00
Alejandro Martinez
d7dee225fc docs: explains i18n installation (#10963)
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>
2025-02-11 13:53:55 -05:00
Cody Stallings
c31bff7e57 docs: fixes misc grammar and spelling errors (#10996)
Fixed various spelling/grammatical errors found when reading the docs.
2025-02-11 18:37:23 +00:00
Elliot DeNolf
5d199587a3 templates: bump for v3.23.0 (#11115)
🤖 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>
2025-02-11 13:25:25 -05:00
Sasha
ececa65c78 fix(next): pre-flight OPTIONS request errors from the graphql endpoint (#11103)
Fixes https://github.com/payloadcms/payload/issues/11101
2025-02-11 13:22:16 -05:00
Germán Jabloñski
7a400a7a79 fix(richtext-lexical): unindent button in toolbar is never active (#11089)
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.
2025-02-11 13:21:58 -05:00
Jacob Fletcher
2a0094def7 fix(ui): relationship filterOptions not applied within the list view (#11008)
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.
2025-02-11 13:20:55 -05:00
Elliot DeNolf
48471b7210 chore: tsconfig.base.json reset 2025-02-11 13:02:24 -05:00
Elliot DeNolf
480c6e7c09 chore(release): v3.23.0 [skip ci] 2025-02-11 12:53:51 -05:00
Elliot DeNolf
da77f99df4 fix(payload-cloud): handle socket closures (#11113)
- Port #11015 to handle sockets
- Fix `AccessDenied` errors to properly return 404 in specific scenarios
- Add optional `debug` flag
2025-02-11 12:50:46 -05:00
Paul
ae4a78b298 templates: bump engines pnpm version to support 10 (#11112)
Bumps to support v10 of pnpm in our website templates so installation
doesn't fail on Vercel
2025-02-11 14:46:41 +00:00
Jacob Fletcher
da6511eba9 fix(ui): relationship filter renders stale values when changing fields (#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.
2025-02-11 09:45:41 -05:00
Sasha
1f3ccb82d9 docs: update custom endpoints docs, handler does not accept array of functions anymore (#11110)
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.
2025-02-11 13:56:34 +02:00
Said Akhrarov
d6a03eeaba docs: adds options table to payload-wide upload options (#10904)
<!--

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`.
2025-02-11 01:19:58 +00:00
Jonathan Bredo
3f80c5993c docs: fixing 3 dead internal links (#11100)
### What?
Dead links located in docs, replaced with functioning links.

### Why?
It broke my [Cursor AI](https://github.com/getcursor/cursor) from
crawling and indexing the docs :(

### How?
Identified broken links by a free online service,
https://www.deadlinkchecker.com/, and fixed all links prefixed with
`https://payloadcms.com/docs`

[Referenced in
Discord.](https://discord.com/channels/967097582721572934/967097582721572937/1338664792717525032)
2025-02-11 01:09:11 +00:00
Paul
c18c58e1fb feat(ui): add timezone support to scheduled publish (#11090)
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.


![image](https://github.com/user-attachments/assets/0cc6522b-1b2f-4608-a592-67e3cdcdb566)

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
2025-02-10 19:48:52 -05:00
Paul
36168184b5 fix(ui): incorrectly incrementing version counts if maxPerDoc is set to 0 (#11097)
Fixes https://github.com/payloadcms/payload/issues/9891

We were incorrectly setting max version count to 0 if it was configured
as maxPerDoc `0` due to `Math.min`
2025-02-10 23:28:40 +00:00
Sasha
98fec35368 fix(db-postgres): incorrect pagination results when querying hasMany relationships multiple times (#11096)
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,
        },
      },
    ],
  },
})
```
2025-02-11 01:16:18 +02:00
Jarrod Flesch
fde526e07f fix: set initialValues alongside values during onSuccess (#10825)
### 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>
2025-02-10 16:49:06 -05:00
James Mikrut
5dadccea39 feat: adds new jobs.shouldAutoRun property (#11092)
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.
2025-02-10 21:43:20 +00:00
Jarrod Flesch
d2fe9b0807 fix(db-mongodb): ensures same level operators are respected (#11087)
### 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
2025-02-10 16:29:08 -05:00
Markus
95ec57575d fix(storage-s3): sockets not closing (#11015)
### 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
2025-02-10 15:17:30 -05:00
Paul
430ebd42ff feat: add timezone support on date fields (#10896)
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

![image](https://github.com/user-attachments/assets/fcebdb7f-be01-4382-a1ce-3369f72b4309)

Light mode

![image](https://github.com/user-attachments/assets/dee2f1c6-4d0c-49e9-b6c8-a51a83a5e864)
2025-02-10 15:02:53 -05:00
Jacob Fletcher
3415ba81ac chore: updates CODEOWNERS (#11088) 2025-02-10 14:51:07 -05:00
Germán Jabloñski
fa18923317 fix(richtext-lexical): improve keyboard navigation on DecoratorNodes (#11022)
Fixes #8506



https://github.com/user-attachments/assets/a5e26f18-2557-4f19-bd89-73f246200fa5
2025-02-10 19:22:25 +00:00
James Mikrut
91a0f90649 fix(next): allows relative live preview urls (#11083)
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
2025-02-10 18:20:34 +00:00