Filtering by `null` `number` field values or normal values with the
`exists` operator was not working in `postgres` & `sqlite`.
Was previously fixed for `mongodb`
[here](https://github.com/payloadcms/payload/pull/8416)
Now fixed for `postgres` & `sqlite` adapters as well.
In some instances, form states incorrectly setting valid to true even
when they should not be, just because no validate function is present.
This was apparent when using bulk upload drawers inside the multi-tenant
example which inserts a custom field for the TenantSelector on
documents.
Reported internally
https://payloadcms.slack.com/archives/C079W6WT0R1/p1726670927732309
<!--
For external contributors, please include:
- A summary of the pull request and any related issues it fixes.
- Reasoning for the changes made or any additional context that may be
useful.
Ensure you have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
-->
fixes#8672
This PR makes a more clear gap between `version_createdAt` /
`version_updatedAt` and `createdAt` / `updatedAt` columns / fields in
mongodb.
- `createdAt` - This should be a new value in a new version. Before this
change it was the same all the time. Should remain the same on autosave.
- The same for `updatedAt`, but it should be updated on every change
(including autosave)
- `version_createdAt` - Should remain equal to `createdAt` from the
parent collection / table
- `version_updatedAt` - On a latest version it makes sense this be the
same as `updatedAt` from the parent collection / table, as all the
`version_*` fields should be just synced with it
### Improvements
- Uses overlay modal for "logging out..." display on logout view
- If user manually logs out it takes them directly to the login page
after logout, if caused by inactivity then they will see the logout page
that explains that they were logged out due to inactivity
- Fixes issue with cookie refresh triggering even after the user logs
out
- Cleans up auth provider timeouts for refresh and force logout
- `setUser` now expects the result similar to the response from the
`/me` endpoint, which includes the token, exp, and user
### BREAKING CHANGE
If you are using the `setUser` function exposed from the `useAuth()`
provider, then you will need to make some adjustments.
`setUser` now expects the response data from auth enabled endpoints, ie
the `/me` route. This is so the cookie and expiration can be properly
set in sync when a new user is set on the provider.
```ts
// before
setUser({
id: 670524817048be0fa222fc01,
email: dev@payloadcms.com,
// ... other user properties
})
// new
setUser({
user: {
id: 670524817048be0fa222fc01,
email: dev@payloadcms.com,
// ... other user properties
},
exp: 1728398351,
token: "....eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC...."
})
```
Fixes https://github.com/payloadcms/payload/issues/8470
Cleans up the way we redirect and where it happens.
## Improvements
- When you verify, the admin panel will display a toast when it
redirects you to the login route. This is contextually helpful as to
what is happening.
- Removes dead code path, as we always set the _verifiedToken to null
after it is used.
## `handleAdminPage` renamed to `getRouteInfo`
This function no longer handles routing. It kicks that responsibility
back up to the initPage function.
## `isAdminAuthRoute` renamed to `isPublicAdminRoute`
This was inversely named as it determines if a given route is public.
Also simplifies deterministic logic here.
## `redirectUnauthenticatedUser` argument
This is no longer used or needed. We can determine these things by using
the `isPublicAdminRoute` function.
## View Style fixes
- Reset Password
- Forgot Password
- Unauthorized
All payload css is now encapsulated inside CSS layers under `@layer
payload-default`
Any custom css will now have the highest possible specificity.
We have also provided a new layer `@layer payload` if you want to use
layers and ensure that your styles are applied after payload.
To override existing styles in a way that the existing rules of
specificity would be respected you can use the default layer like so
```css
@layer payload-default {
// my styles within the payload specificity
}
```
Fixes https://github.com/payloadcms/payload/issues/8534
UI fields are now excluded by default from the bulk edit view fields
options.
If you need to have the UI field there, you can provide:
```ts
admin: {
disableBulkEdit: false
}
```
This PR
- Introduces multiline markdown transformers / mdx support
- Introduce `shouldMergeAdjacentLines` option in
`$convertFromMarkdownString`. If true, merges adjacent lines as per
commonmark spec. This would allow to close:
https://github.com/payloadcms/payload/issues/8049
- Many new features and bug fixes!
- Ports over changes from the lexical playground. Most notably:
- add support for enabling table row stripping
- make table resizing & table cell selection more reliable
**BREAKING**: This upgrades lexical from 0.17.0 to 0.18.0. If you have
any lexical packages installed in your project, please update them
accordingly. Additionally, if you depend on the lexical APIs, please
consult their changelog, as lexical may introduce breaking changes:
https://github.com/facebook/lexical/releases/tag/v0.18.0
---------
Co-authored-by: Alessio Gravili <alessio@gravili.de>
Removes the setModified call from Autosave logic and updates the
`preventLeaveWithoutSaving` logic in Document info to actually disable
if autosave is enabled (previously it always resolved to true)
Fixes https://github.com/payloadcms/payload/issues/8072
Fixes#7780
Fixes a bug where the number field won't save data if it's being removed
entirely (should be null) instead of changed to another value.
---------
Co-authored-by: PatrikKozak <patrik@payloadcms.com>
This PR implements the ability to attempt to force the use of light/dark
theme in the admin panel. While I am a big advocate for the benefits
that dark mode can bring to UX, it does not always suit a clients
branding needs.
Open to discussion on whether we consider this a suitable feature for
the platform. Please feel free to add to this PR as needed.
TODO:
- [x] Implement tests (I'm open to guidance on this from the Payload
team as currently it doesn't look like it's possible to adjust the
payload config file on the fly - meaning it can't be easily placed in
the admin folder tests).
---------
Co-authored-by: Germán Jabloñski <43938777+GermanJablo@users.noreply.github.com>
Updates:
- Exports `handleGoBack`, `handleBackToDashboard`, & `handleTakeOver`
functions to consolidate logic in default edit view & live-preview edit
view.
- Only unlock document on navigation away from edit view entirely (aka
do not unlock document if switching between tabs like `edit` -->
`live-preview` --> `versions` --> `api`
Fixes the issue where the published or changed document is always shown
as "Changed" instead of "Published" or "Draft"

Statuses:
- Published - when the current version is also the published version
- Changed - when the current version is a draft version but a published
version exists
- Draft - when the current version is a draft and no published versions
exist
---------
Co-authored-by: Jessica Chowdhury <jessica@trbl.design>
This PR addresses around 500 TypeScript errors by enabling
strictNullChecks in the richtext-lexical package. In the process,
several bugs were identified and fixed.
In some cases, I applied non-null assertions where necessary, although
there may be room for further type refinement in the future. The focus
of this PR is to resolve the immediate issues without introducing
additional technical debt, rather than aiming for perfect type
definitions at this stage.
---------
Co-authored-by: Alessio Gravili <alessio@gravili.de>
Fixes https://github.com/payloadcms/payload/issues/8013
**BREAKING:**
- Upgrades minimum supported @types/react version from
npm:types-react@19.0.0-rc.0 to npm:types-react@19.0.0-rc.1
- Upgrades minimum supported @types/react-dom version from
npm:types-react-dom@19.0.0-rc.0 to npm:types-react-dom@19.0.0-rc.1
- Upgrades minimum supported react and react-dom version from
19.0.0-rc-06d0b89e-20240801 to 19.0.0-rc-5dcb0097-20240918
- Upgrades minimum supported Next.js version from 15.0.0-canary.104 to
15.0.0-canary.160
---------
Co-authored-by: PatrikKozak <patrik@payloadcms.com>
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
## Description
- Adds a new "join" field type to Payload and is supported by all database adapters
- The UI uses a table view for the new field
- `db-mongodb` changes relationships to be stored as ObjectIDs instead of strings (for now querying works using both types internally to the DB so no data migration should be necessary unless you're querying directly, see breaking changes for details
- Adds a reusable traverseFields utility to Payload to make it easier to work with nested fields, used internally and for plugin maintainers
```ts
export const Categories: CollectionConfig = {
slug: 'categories',
fields: [
{
name: 'relatedPosts',
type: 'join',
collection: 'posts',
on: 'category',
}
]
}
```
BREAKING CHANGES:
All mongodb relationship and upload values will be stored as MongoDB ObjectIDs instead of strings going forward. If you have existing data and you are querying data directly, outside of Payload's APIs, you get different results. For example, a `contains` query will no longer works given a partial ID of a relationship since the ObjectID requires the whole identifier to work.
---------
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: James <james@trbl.design>
This speeds up all page loads and reduces the amount of requests
## Example
### Clientside transition from dashboard => ui-fields list view
#### Router cache disabled
GET /admin/collections/ui-fields 200 in 33ms
POST /api/form-state 200 in 9ms
POST /api/form-state 200 in 10ms
GET /api/payload-preferences/ui-fields-list 200 in 11ms
GET /admin/collections/ui-fields?limit=10&sort=id 200 in 42ms
#### Router cache enabled
GET /admin/collections/ui-fields 200 in 33ms
POST /api/form-state 200 in 11ms
POST /api/form-state 200 in 12ms
GET /api/payload-preferences/ui-fields-list 200 in 15ms
GET /admin/collections/ui-fields?limit=10&sort=id 200 in 42ms
**GET /admin/collections/ui-fields?limit=10&sort=id 200 in 82ms** <==
this is gone