Commit Graph

13067 Commits

Author SHA1 Message Date
Jarrod Flesch
56dec13820 fix: format admin url inside forgot pw email (#11509)
### What?
Supersedes https://github.com/payloadcms/payload/pull/11490.

Refactors imports of `formatAdminURL` to import from `payload/shared`
instead of `@payloadcms/ui/shared`. The ui package now imports and
re-exports the function to prevent this from being a breaking change.

### Why?
This makes it easier for other packages/plugins to consume the
`formatAdminURL` function instead of needing to implement their own or
rely on the ui package for the utility.
2025-03-04 11:55:36 -05:00
Elliot DeNolf
1d168318d0 chore(release): v3.26.0 [skip ci] 2025-03-04 10:01:54 -05:00
Sasha
f143d25728 fix(storage-uploadthing): files are duplicated to the storage via client uploads (#11518)
When uploading file via client side upload we invalidate it then on the
server side with re-uploading. This works fine with most adapters since
they just replace the old file under the same key. UploadThing works
differently and generates a new key every time.

Example of the issue:
<img width="611" alt="image"
src="https://github.com/user-attachments/assets/9c01b52a-d159-4f32-9f66-3b5fbadab7b4"
/>

Now, we clear the old file before doing re-upload.
2025-03-04 14:57:30 +00:00
Patrik
7d2480aef9 fix(next): incorrect active state for partial matches of collection names in sidebar (#11511)
Previously, collections with similar names (e.g., `uploads` and
`uploads-poly`) both appeared active when viewing either collection.

This was due to `pathname.startsWith(href)`, which caused partial
matches.

This update refines the `isActive` logic to prevent partial matches.
2025-03-03 16:46:47 -05:00
Patrik
c417e3a627 fix: avif images not converting to upload.formatOptions set file types (#11505)
Previously, AVIF images were not converted to other file types as
expected, despite `upload.formatOptions` specifying a different file
type.

The issue was due to `canResizeImage` not recognizing `'image/avif',`
causing `fileSupportsResize` to return `false` and preventing the image
from undergoing format conversion.

This fix updates `canResizeImage` to include `'image/avif'`, ensuring
that AVIF images are processed correctly and converted to a different
file type when specified in `formatOptions`.

Fixes #10694 
Fixes #9985
2025-03-03 14:58:39 -05:00
Germán Jabloñski
efce1549d0 chore(plugin-search): enable TypeScript strict mode (#11508) 2025-03-03 18:31:26 +00:00
Ondřej Nývlt
d57a78616a docs: clarify that image resizing/cropping require sharp to be specified in payload config (#11470)
### What

Clarifies that `sharp` must be specified in payload config for image
resizing & cropping to work. Also adds link to the configuration page
for further information.

### Why

It is not immediately clear from this single documentation page alone.
While it says that the feature relies on sharp, it does not say that it
must be added to config. Most people won't probably run into this since
they're probably going to use `create-payload-app`, which configures
sharp by default. But those who use custom config (like me) may be left
wondering why this feature does not work.

See [Crop images and preview sizes not
working](https://payloadcms.com/community-help/discord/crop-images-and-preview-sizes-not-working)
in community help.
2025-03-03 13:24:05 -05:00
Germán Jabloñski
a3fe60778c chore(translations): enable TypeScript strict mode (#11494) 2025-03-03 13:01:14 -03:00
Jarrod Flesch
4ddf96502c fix(examples): ensure working multi-tenant example with pg (#11501)
### What?
There were a couple issues with the implementation within the example
when using postgres.
- `ensureUniqueUsername` tenant was being extracted incorrectly, should
not constrain query unless it was present
- `ensureUniqueSlug` was querying by NaN when tenant was not present on
data or originalDoc
- `users` read access was not correctly extracting the tenant id in the
correct type depending on DB

Fixes https://github.com/payloadcms/payload/issues/11484
2025-03-03 10:21:55 -05:00
Paul
562acb7492 templates: fix vercel website template importmap error caused by missing import (#11500)
The new client side handler was missing in the importmap on the template
for the vercel blob storage adapter
2025-03-03 15:15:44 +00:00
Jacob Fletcher
bf4fa59026 chore(deps): bumps payload-admin-bar to v1.0.7 to suppress react 19 warnings (#11499)
The `payload-admin-bar` now supports React 19 as a result of
https://github.com/payloadcms/payload-admin-bar/pull/13. This will
suppress the React 19 warnings on install within the website templates
and various examples that rely on this package.
2025-03-03 10:13:24 -05:00
Elliot DeNolf
fd1a4f689e ci: change custom github actions target back to es5 2025-03-03 10:08:13 -05:00
Patrik
a15c38f665 ci: clarify version reporting in issue templates (#11498)
This update improves the `Environment Info` section in the issue
template by asking users to provide exact version numbers instead of
"latest."

This ensures that bug reports remain accurate and useful over time.
2025-03-03 09:46:15 -05:00
Paul
fa8a2f8d8d chore: add docker volume directories to gitignore (#10902)
Added these directories to gitignore so they don't conflict with
stashing, which throws an error due to host user not having write
permissions
2025-03-03 11:32:40 +00:00
Vincent Vu
b9108b4306 docs: fix documentation "CheckListFeature" (#11480)
### What?
CheckListFeature is noted in the documentation. However, the package
uses ChecklistFeature

Rather than changing the package, this would be better.
2025-03-03 07:47:23 -03:00
Alessio Gravili
6a3d58bb32 feat(db-*): support limit in db.updateMany (#11488)
This PR adds a new `limit` property to `payload.db.updateMany`. This functionality is required for [migrating our job system to use faster, direct db adapter calls](https://github.com/payloadcms/payload/pull/11489)
2025-03-03 05:32:57 +00:00
Alessio Gravili
192964417d chore: temporarily disables flaky "should execute a custom script" test (#11487)
The newly added "should execute a custom script" int test is very flaky on mongodb - it was failing most of the time. This PR skips this test until it's fixed

Example failures:
- https://github.com/payloadcms/payload/actions/runs/13618762213/job/38065304540
- https://github.com/payloadcms/payload/actions/runs/13611742446/job/38049886588
- https://github.com/payloadcms/payload/actions/runs/13608918590/job/38043761182
- https://github.com/payloadcms/payload/actions/runs/13599001510/job/38021936623
2025-03-02 21:05:25 -07:00
Alessio Gravili
f03d450d8e templates: bump payload versions, upgrade next.js to 15.2.0, fix eslint errors (#11486)
- Ensures website templates build without eslint errors
- Upgrades all templates from Next.js 15.1.5 to 15.2.0
- Bumps all payload versions, updates all lockfiles to reference latest payload versions. The blank template was still installing 3.17.1 and the website template was installing 3.18.0
- Simplifies defaultLexical.ts
2025-03-03 02:01:53 +00:00
Alessio Gravili
398d48ab16 templates: improve naming of richtext component import, add 'payload-richtext' classname (#11485)
Our previous `RichTextWithoutBlocks` import alias was confusing - this PR changes it to `ConvertRichText`. This should make it clear that that's the imported RichText component that performs the editor state => JSX conversion
2025-03-02 18:34:34 -07:00
Alessio Gravili
377454416a chore(eslint): speed up no-imports-from-self rule by ensuring cache is used (#11483)
Our `no-imports-from-self` eslint rule was supposed to cache the package.json name to ensure it doesn't try to find and read the package.json for every single import statement.

Turns out that cache was never used. Credits to @etrepum for [finding this issue](https://github.com/facebook/lexical/pull/7272#discussion_r1976666227)
2025-03-02 19:51:49 +00:00
Alessio Gravili
cd29978faf feat(richtext-lexical): add htmlToLexical helper (#11479)
This adds a new `convertHTMLToLexical` helper that makes converting HTML to Lexical easy
2025-03-02 03:42:10 +00:00
Alessio Gravili
e1b30842fb feat(richtext-lexical): add editorConfigFactory helper to streamline getting the editor config (#11467)
This PR exports a new `editorConfigFactory` that provides multiple standardized ways to retrieve the editor configuration needed for the Lexical editor.

## Why this is needed

Getting the editor config is required for converting the lexical editor state into/from different formats, as it's needed to create a headless editor. While we're moving away from requiring headless editor instantiation for common format conversions, some conversion types and other use cases still require it.

Currently, retrieving the editor config is cumbersome - you either need an existing field to extract it from or the payload config to create it from scratch, with multiple approaches for each method.

## What this PR does

The `editorConfigFactory` consolidates all possible ways to retrieve the editor config into a single factory with clear methods:

```ts
editorConfigFactory.default()
editorConfigFactory.fromField()
editorConfigFactory.fromUnsanitizedField()
editorConfigFactory.fromFeatures()
editorConfigFactory.fromEditor()
```

This results in less code, simpler implementation, and improved developer experience. The PR also adds documentation for all retrieval methods.
2025-03-01 23:44:25 +00:00
Jacob Fletcher
927078c4db fix(ui): uses query provider as single source of truth for where builder (#11476)
The "where" builder maintains its own duplicative state for conditions.
This is problematic when an outside force needs to control the
conditions in some way, but the "where" builder will not receive those
updates.

While it is a requirement of the "where" builder to transform the
"where" query into "and" / "or" format for rendering, it does so in a
way that causes it to become out of sync with the query provider. This
is because we first initialize state from context, then for every change
to conditions, report those updates to contexts—but not the other way
around.

To fix this, we need to completely remove state from the "where" builder
and solely rely on the query context as a single source of truth. This
will allow it to receive automatic updates from query provider without
needing to sync both local state and context simultaneously. Now, we
only ever need to send updates to the query provider and let the
top-down rendering cycle propagate those changes everywhere.
2025-03-01 16:20:00 -05:00
Alessio Gravili
dda17f0c32 chore(richtext-lexical): export LexicalFieldAdminProps (#11464) 2025-03-01 03:32:02 +00:00
Alessio Gravili
6d8aca5ab3 fix(richtext-lexical): ensure nested forms do not use form element (#11462)
Previously, lexical blocks initialized a new `Form` component that rendered as `<form>` in the DOM. This may lead to React errors, as forms nested within forms is not valid HTML.

This PR changes them to render as `<div>` in the DOM instead.
2025-02-28 19:29:07 -07:00
Dmitrii Kuzmin
c828e336ee fix: excludes index files from migration files filtering (#10722) 2025-02-28 19:39:44 -05:00
Sasha
90d3c65008 perf: automatically add index on a relationship field when used as target for a join field (#11463)
When the join field is used, Payload now automatically adds an index on
the target relationship field.

For example:
```
{
  name: 'relatedPosts',
  type: 'join',
  collection: "posts",
  on: 'category',
},

{
  name: 'category',
  type: 'relationship',
  relationTo: "categories",
},
```

Here, `index: true` implicitly added to the `category` relationship
field during sanitization to improve querying performance.
2025-03-01 02:37:19 +02:00
Said Akhrarov
e75d38ca82 fix(ui): remove stale thumbnails in bulkUpload after partial success (#10651) 2025-02-28 22:18:18 +00:00
Sasha
79a7b4ad02 chore(db-mongodb): tsconfig uses strict: true and noUncheckedIndexedAccess: true (#11444)
Migrates the `db-mongodb` package to use `strict: true` and
`noUncheckedIndexedAccess: true` TSConfig properties.
This greatly improves code quality and prevents some runtime errors or
gives better error messages.
2025-03-01 00:17:24 +02:00
Vincent Vu
f7f5651004 fix(templates): handle enableLink condition safely (#10728) 2025-02-28 22:03:42 +00:00
Michael Bykovski
45a7c8b764 fix: response headers from authstrategies are now merged together, even if no user was returned (#10883)
### What?
Merges response headers returned from auth strategies

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2025-02-28 16:38:32 -05:00
Sasha
25e8799a09 docs: add few notes about DocumentDB and Azure Cosmos DB (#11336)
Adds few notes about limitations when using Azure Cosmos DB and
DocumentDB

Discussion: https://github.com/payloadcms/payload/discussions/11333
2025-02-28 21:14:51 +00:00
Jacob Fletcher
6cbda9e231 fix(ui): bulk editing users throws client-side exception (#11461)
When bulk editing an auth-enabled collection such as users, a
client-side exception is thrown. This is because we're trying to access
the `disableBulkEdit` property on `undefined`. This is due to hidden,
auth-specific fields like `salt` and `hash` lacking an admin config.

No test is explicitly needed for this as `"strictNullChecks": true` will
throw an error at compile time, once enabled.
2025-02-28 21:06:40 +00:00
Sasha
fc42c40883 fix(storage-s3, storage-azure, storage-gcs): client uploads when a collection has prefix configured (#11436)
### What?
Fixes client uploads when storage collection config has the `prefix`
property configured. Previously, it failed with "Object key was not
found".

### Why?
This is expected to work.

### How?
The client upload handler now receives to its props `prefix`. Then it
threads it to the server-side `staticHandler` through
`clientUploadContext` and then to `getFilePrefix`, which checks for
`clientUploadContext.prefix` and returns if there is.

Previously, `staticHandler` tried to load the file without including
prefix consideration.

This changes only these adapters:
* S3
* Azure
* GCS

With the Vercel Blob adapter, `prefix` works correctly.
2025-02-28 15:50:23 -05:00
Patrik
83b4548fc1 fix(next): active nav item not clickable in edit view (#11457)
This fixes an issue where the active collection nav item was
non-clickable inside documents. Now, it remains clickable when viewing a
document, allowing users to return to the list view from the nav items
in the sidebar.

The active state indicator still appears in both cases.
2025-02-28 15:14:21 -05:00
Jarrod Flesch
81e8a9d50d chore(examples): update multi-tenant example (#11459)
Bumps deps inside examples repo lockfile. Fixes import map, supersedes
https://github.com/payloadcms/payload/pull/10804
2025-02-28 14:57:58 -05:00
Mike Newberry
9bb89b7b52 feat(ui): close the nav when the user navigates away on small screens (#10932) 2025-02-28 19:31:57 +00:00
Sasha
d4d2bf4617 perf(db-mongodb): faster join field aggregation by replacing mongoose-aggregate-paginate-v2 with a custom implementation (#10936)
Fixes
https://github.com/payloadcms/payload/discussions/10165#discussioncomment-12034047

As described in the discussion, we have an incorrect order of
aggregation pipeline when using aggregations with the join field. We
must use `$sort`, `$skip`, `$limit` before the `$lookup` or otherwise
mongodb scans all the docs, applies `$lookup` for them and only after
applies `$limit`, `$skip`.
Replaces `mongoose-aggregate-paginate-v2` with a custom
`aggregatePaginate` because we need a custom solution here. This was
considered in https://github.com/payloadcms/payload/pull/9594 but it was
reverted as for now.

Fixes https://github.com/payloadcms/payload/issues/11187
2025-02-28 21:30:00 +02:00
nomad-dev
8b5bc3de33 docs: fix method useAllFormFields on admin/hooks.mdx (#10935) 2025-02-28 19:27:27 +00:00
Liège Arthur
19b4ec2562 docs: use local API to upload a local file (#10839) 2025-02-28 19:18:54 +00:00
Said Akhrarov
bef98c8d6e fix(ui): scope rah-static and progress-bar styles to payload-default layer (#11442) 2025-02-28 14:05:39 -05:00
Said Akhrarov
77395b6483 docs: adds info and example for headersWithCors (#11141) 2025-02-28 13:43:00 -05:00
Violet Rosenzweig
fcaf59176d docs: custom auth strategy requires the collection slug in return value (#11327) 2025-02-28 13:30:29 -05:00
Adrian Maj
206b4b9d88 docs: broken &apos; char entity instead of ' in plugins/build-your-own (#11363) 2025-02-28 13:27:40 -05:00
Jacob Fletcher
67c4a20237 fix(next): properly instantiates req.url on localhost (#11455)
The `req.url` property at the page level was not reflective of the
actual URL on localhost. This was because we were passing an
incompatible `url` override into `createLocalReq` (lacking protocol).
This would silently fail to construct the URL object, ultimately losing
the top-level domain on `req.url` as well as the port on `req.origin`
(see #11454).

Closes #11448.
2025-02-28 13:04:26 -05:00
Alessio Gravili
38131ed2c3 feat: ability to cancel jobs (#11409)
This adds new `payload.jobs.cancel` and `payload.jobs.cancelByID` methods that allow you to cancel already-running jobs, or prevent queued jobs from running.

While it's not possible to cancel a function mid-execution, this will stop job execution the next time the job makes a request to the db, which happens after every task.
2025-02-28 17:58:43 +00:00
Patrik
96d1d90e78 fix(ui): use full image url for upload previews instead of thumbnail url (#11435) 2025-02-28 12:47:02 -05:00
Jessica Chowdhury
9e97319c6f fix(ui): locale selector in versions view should remove filtered locales (#11447)
### What?
The `locale selector` in the version comparison view shows all locales
on first load. It does not accomodate the `filterAvailableLocales`
option and shows locales which should be filtered.

### How?
Pass the initial locales through the `filterAvailableLocales` function.

Closes #11408

#### Testing
Use test suite `localization` and the `localized-drafts` collection.
Test added to `test/localization/e2e`.
2025-02-28 17:37:07 +00:00
Jacob Fletcher
a65289c211 fix: ensures req.origin includes port on localhost (#11454)
The `req.origin` property on the `PayloadRequest` object does not
include the port when running on localhost, a requirement of the [HTML
Living Standard](https://html.spec.whatwg.org/#origin). This was because
we were initializing the url with a fallback of `http://localhost` (no
port). When constructed via `new URL()`, the port is unable to be
extracted. This is fixed by using the `host` property off the headers
object, if it exists, which includes the port.

Partial fix for #11448.
2025-02-28 12:26:38 -05:00
Alessio Gravili
4a1b74952f chore(richtext-lexical): improve UploadData jsdocs (#11292) 2025-02-28 12:18:09 -05:00