Commit Graph

1078 Commits

Author SHA1 Message Date
Jarrod Flesch
97cffa51f8 chore: improves abort controller logic for server functions (#9131)
### What?
Removes abort controllers that were shared globally inside the server
actions provider.

### Why?
Constructing them in this way will cause different fetches using the
same function to cancel one another accidentally.

These are currently causing issues when two components call server
functions, even different functions, because the global ref inside was
being overwritten and aborting the previous one.

### How?
Standardizes how we construct and destroy abort controllers. This PR is focused around creating them to pass into the exposed serverAction provider functions. There are other places where this pattern can be applied.
2024-11-12 11:20:17 -05:00
Patrik
48d0faecae fix(next, ui): respect access of user for document locking (#9139) 2024-11-12 15:49:58 +00:00
Alessio Gravili
4f6651433c chore: ensure all packages have consistent licenses and package.json metadata (#9079) 2024-11-12 10:27:36 -05:00
Alessio Gravili
03291472d6 chore: bump all eslint dependencies, run lint and prettier (#9128)
This fixes a peer dependency error in our monorepo, as
eslint-plugin-jsx-a11y finally supports eslint v9.

Additionally, this officially adds TypeScript 5.6 support for
typescript-eslint.
2024-11-12 10:18:22 -05:00
Sasha
3298113a93 fix(ui): pass correct relationTo to locked documents creation (#9137)
### What?
Relationships within `payload-locked-documents` collection were stored
incorrectly with `relationTo` as an array:
<img width="316" alt="image"
src="https://github.com/user-attachments/assets/f84b9807-6032-4ea2-8563-5c7d13306a4a">

Example how it should be:
<img width="405" alt="image"
src="https://github.com/user-attachments/assets/80fb54fd-7c2e-4c90-bd2b-dec8e7a06040">


This additionally caused issue that `value` wasn't converted to
`ObjectID`
2024-11-12 16:14:28 +02:00
Alessio Gravili
2ad991759f fix(ui): error in filtered relationship field component while scrolling, if the select option label is a number (#9117)
1. Open fields test suite
2. Type in relationship field, that has a relation to the numbers
collection
3. Scroll

You will get an error, as the label for the entry corresponding to the
numbers collection is of type number, and it attempts to use the
.toString() method on it
2024-11-12 03:37:53 +00:00
Jacob Fletcher
c96fa613bc feat!: on demand rsc (#8364)
Currently, Payload renders all custom components on initial compile of
the admin panel. This is problematic for two key reasons:
1. Custom components do not receive contextual data, i.e. fields do not
receive their field data, edit views do not receive their document data,
etc.
2. Components are unnecessarily rendered before they are used

This was initially required to support React Server Components within
the Payload Admin Panel for two key reasons:
1. Fields can be dynamically rendered within arrays, blocks, etc.
2. Documents can be recursively rendered within a "drawer" UI, i.e.
relationship fields
3. Payload supports server/client component composition 

In order to achieve this, components need to be rendered on the server
and passed as "slots" to the client. Currently, the pattern for this is
to render custom server components in the "client config". Then when a
view or field is needed to be rendered, we first check the client config
for a "pre-rendered" component, otherwise render our client-side
fallback component.

But for the reasons listed above, this pattern doesn't exactly make
custom server components very useful within the Payload Admin Panel,
which is where this PR comes in. Now, instead of pre-rendering all
components on initial compile, we're able to render custom components
_on demand_, only as they are needed.

To achieve this, we've established [this
pattern](https://github.com/payloadcms/payload/pull/8481) of React
Server Functions in the Payload Admin Panel. With Server Functions, we
can iterate the Payload Config and return JSX through React's
`text/x-component` content-type. This means we're able to pass
contextual props to custom components, such as data for fields and
views.

## Breaking Changes

1. Add the following to your root layout file, typically located at
`(app)/(payload)/layout.tsx`:

    ```diff
    /* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
    /* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
    + import type { ServerFunctionClient } from 'payload'

    import config from '@payload-config'
    import { RootLayout } from '@payloadcms/next/layouts'
    import { handleServerFunctions } from '@payloadcms/next/utilities'
    import React from 'react'

    import { importMap } from './admin/importMap.js'
    import './custom.scss'

    type Args = {
      children: React.ReactNode
    }

+ const serverFunctions: ServerFunctionClient = async function (args) {
    +  'use server'
    +  return handleServerFunctions({
    +    ...args,
    +    config,
    +    importMap,
    +  })
    + }

    const Layout = ({ children }: Args) => (
      <RootLayout
        config={config}
        importMap={importMap}
    +  serverFunctions={serverFunctions}
      >
        {children}
      </RootLayout>
    )

    export default Layout
    ```

2. If you were previously posting to the `/api/form-state` endpoint, it
no longer exists. Instead, you'll need to invoke the `form-state` Server
Function, which can be done through the _new_ `getFormState` utility:

    ```diff
    - import { getFormState } from '@payloadcms/ui'
    - const { state } = await getFormState({
    -   apiRoute: '',
    -   body: {
    -     // ...
    -   },
    -   serverURL: ''
    - })

    + const { getFormState } = useServerFunctions()
    +
    + const { state } = await getFormState({
    +   // ...
    + })
    ```

## Breaking Changes

```diff
- useFieldProps()
- useCellProps()
```

More details coming soon.

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Co-authored-by: James <james@trbl.design>
2024-11-11 13:59:05 -05:00
Jessica Chowdhury
3e954f45c7 fix: empty publish dropdown when localization is false (#9106)
Closes https://github.com/payloadcms/payload/issues/9092
2024-11-11 12:19:29 -05:00
Elliot DeNolf
0c19afcf91 chore(release): v3.0.0-beta.127 [skip ci] 2024-11-11 09:56:14 -05:00
Jessica Chowdhury
dc111041cb fix: incorrect form changed state after doc drawer edit (#9025)
Closes #9000

When you update a relationship document via the document drawer, the
initial document is registering `modified: true`. We should only set
modified to true on the initial document if the relationship id has
changed.
2024-11-08 14:04:37 -05:00
Kendell Joseph
1f26237ba1 chore: correctly redirects after in-activity (#9070)
Issues: 
  - https://github.com/payloadcms/payload/issues/5009
  - https://github.com/payloadcms/payload/pull/8809
2024-11-08 12:20:44 -06:00
Alessio Gravili
0cd83f0591 perf: upgrade json-schema-to-typescript and various other dependencies (#9076)
This further reduces the amount of dependencies installed by payload.
Special thanks to @benmccann for this PR
(https://github.com/bcherny/json-schema-to-typescript/pull/639) !

json-schema-to-typescript before this PR (15.0.1):

![CleanShot 2024-11-07 at 15 35
53@2x](https://github.com/user-attachments/assets/83cb671c-82a8-4b59-b488-cf941d673c8e)

14mb, 37 dependencies

json-schema-to-typescript after this PR (15.0.3):

![CleanShot 2024-11-07 at 15 36
08@2x](https://github.com/user-attachments/assets/d9463275-37e5-452e-aca5-9c1bdeb2a435)

11 MB, 14 dependencies

This PR also upgrades:
- console-table-printer
- croner
- get-tsconfig
- jose
- pino-pretty
- ts-essentials
- tsx
2024-11-07 22:54:45 +00:00
Elliot DeNolf
f878e35cc7 chore(release): v3.0.0-beta.126 [skip ci] 2024-11-06 16:23:57 -05:00
Jessica Chowdhury
7dc52567f1 fix: publish locale with autosave enabled and close dropdown (#8719)
1. Fix publish specific locale option when no published versions exist
2. Close the publish locale dropdown on click
2024-11-06 14:36:28 -05:00
Sasha
f507305192 fix: handle bulk upload sequentially to prevent conflicts (#9052)
### What?
Uses sequential pattern for Bulk Upload instead of `Promise.all`.

### Why?
* Concurrent uploads led to filename conflicts for example when you have
`upload.png` and `upload(1).png` already and you try to upload
`upload.png`
* Potentially expensive for resources, especially with high amount of
files / sizes

### How?
Replaces `Promise.all` with `for` loop, adds indicator "Uploaded 2/20"
to the loading overlay.

---------

Co-authored-by: James <james@trbl.design>
2024-11-06 12:54:16 -05:00
Timothy Choi
d42529055a fix(richtext-slate, ui): use PointerEvents to show tooltips on enabled / disabled buttons (#9006)
Fixes #9005

Note: I did not replace all instances of `onMouseEnter`, just the ones
that can be disabled and have `tooltip` set.
2024-11-06 12:43:06 -05:00
Jacob Fletcher
4b4ecb386d fix(ui): dedupes custom id fields (#9050)
Setting a custom `id` field within unnamed fields causes duplicative ID
fields to be appear in the client config. When a top-level `id` field is
detected in your config, Payload uses that instead of injecting its
default field. But when nested within unnamed fields, such as an unnamed
tab, these custom `id` fields were not being found, causing the default
field to be duplicately rendered into tables columns, etc.
2024-11-06 12:19:19 -05:00
Andreas Bernhard
becf56d582 fix(ui): edit many modal draft action button order and style (#9047)
PR adjusts "draft" action button order and style on the edit-many-modal
to be consistent with default collection edit view action buttons.

This is the `v3` PR version of
https://github.com/payloadcms/payload/pull/9046 and fixes
https://github.com/payloadcms/payload/issues/9045
2024-11-06 11:19:44 -05:00
Elliot DeNolf
8a5f6f044d chore(release): v3.0.0-beta.125 [skip ci] 2024-11-06 10:24:31 -05:00
Dan Ribbens
93a55d1075 feat: add join field config where property (#8973)
### What?

Makes it possible to filter join documents using a `where` added
directly in the config.


### Why?

It makes the join field more powerful for adding contextual meaning to
the documents being returned. For example, maybe you have a
`requiresAction` field that you set and you can have a join that
automatically filters the documents to those that need attention.

### How?

In the database adapter, we merge the requested `where` to the `where`
defined on the field.
On the frontend the results are filtered using the `filterOptions`
property in the component.

Fixes
https://github.com/payloadcms/payload/discussions/8936
https://github.com/payloadcms/payload/discussions/8937

---------

Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com>
2024-11-06 10:06:25 -05:00
Paul
3ca203e08c fix(ui): json fields can now take a maxHeight in admin props and there's a mininum height of 3 lines (#9018)
JSON fields are now 3 lines minimum in height like so:

![image](https://github.com/user-attachments/assets/0b2ad47e-6929-4836-ac9d-022ffcdc6f27)


This helps fix an issue where long content is wrapped:

![image](https://github.com/user-attachments/assets/40fc2426-11d7-4ca5-a716-3347bb0d5a4b)

Previously it would show like this:

![image](https://github.com/user-attachments/assets/7f321220-ffa2-40ff-bc4b-2b26d21d4911)
2024-11-05 13:43:51 -06:00
Patrik
2175e5cdfb fix(ui): ensure upload field updates reflect in edit popup changes (#9034)
### What?

Any changes inside edit popup for the field with type `upload` and the
`relationTo` collection does nothing in context of the field, it has
affect only to collection.

I.e. when you make an edit to an uploads field in the edit drawer -
after saving and existing the drawer, your new changes are not present
until a refresh of the page.

### Why?

Previously, we were not performing a reload of the document fetch upon
saving of the doc in the edit drawer.

### How?

Now, we perform a reload (fetch) for updated docs on save within the
edit drawer.

Fixes #8837
2024-11-05 13:03:12 -05:00
Patrik
ebd3c025b7 fix(ui): updatedAt field in locked-docs collection able to be updated by non-owner (#9026)
### What?

If you have a custom field that sets the value of the field using the
`useField` hook on entry into a document - the `updatedAt` field would
be updated even when a non-owner tries to enter a locked document.

### Why?

When a field is updated in the edit view - we perform an update in
`form-state` to keep the doc in `payload-locked-documents` up to date
with the current editing status. The above scenario would hit this
update operation even on non-owner users because it was previously only
checking for `updateLastEdited` (which would get hit by the `setValue`
in the `useField` hook) so we also need to check to make sure the
current user entering a locked doc is also the owner of the document.

### How?

When performing an update to `payload-locked-documents` in
`buildFormState` - only perform the update if the current user is also
the owner of the locked document otherwise skip the `update` operation.

Fixes #8781
2024-11-05 12:39:48 -05:00
Elliot DeNolf
e390835711 chore(release): v3.0.0-beta.124 [skip ci] 2024-11-04 14:47:38 -05:00
James Mikrut
35b107a103 fix: prefetch causing stale data (#9020)
Potentially fixes #9012 by disabling prefetch for all Next.js `Link`
component usage.

With prefetch left as the default and _on_, there were cases where the
prefetch could fetch stale data for Edit routes. Then, when navigating
to the Edit route, the data could be stale.

In addition, I think there is some strangeness happening on the Next.js
side where prefetched data might still come from the router cache even
though router cache is disabled.

This fix should be done regardless, but I suspect it will solve for a
lot of stale data issues.
2024-11-04 19:24:28 +00:00
Elliot DeNolf
c33791d1f8 chore(release): v3.0.0-beta.123 [skip ci] 2024-10-31 16:10:52 -04:00
Patrik
55ce8e68fc fix: locked documents with read access for users (#8950)
### What?

When read access is restricted on the `users` collection - restricted
users would not have access to other users complete user data object
only their IDs when accessing `user.value`.

### Why?

This is problematic when determining the lock status of a document from
a restricted users perspective as `user.id` would not exist - the user
data would not be an object in this case but instead a `string` or
`number` value for user ID

### How?

This PR properly handles both cases now and checks if the incoming user
data is an object or just a `string` / `number`.
2024-10-31 09:23:18 -04:00
Sasha
c0397c35a2 fix(ui): increase z-index of ReactSelect (#8735)
Fixes https://github.com/payloadcms/payload/issues/8728

Before:
<img width="698" alt="Screenshot 2024-10-16 at 15 28 55"
src="https://github.com/user-attachments/assets/eee45448-5e97-4c2a-bbe3-727c41ed9b08">
After:
<img width="509" alt="Screenshot 2024-10-16 at 15 29 27"
src="https://github.com/user-attachments/assets/7e0a2af6-71be-41e7-ad84-4ae3bcece9b6">
2024-10-31 03:22:14 +02:00
Elliot DeNolf
d192f1414d chore(release): v3.0.0-beta.122 [skip ci] 2024-10-30 21:02:15 -04:00
Said Akhrarov
755355ea68 fix(ui): description undefined error on empty tabs array (#8830)
Fixes an error that occurs when `tabs` array is empty or active tab
config is undefined due to missing optional chaining operator.
2024-10-30 20:57:54 -04:00
Paul
57fba36257 fix(ui): overly large width on stay logged in modal content (#8952) 2024-10-31 00:01:58 +00:00
James Mikrut
03e5ae8095 fix: bulk upload mimetype wildcard file selection (#8954)
Fixes an issue where using wildcards in upload-enabled collection
mimeType restrictions would prevent files from being selected in the
bulk upload file selector.
2024-10-30 16:26:36 -06:00
Elliot DeNolf
d89db00295 chore(release): v3.0.0-beta.121 [skip ci] 2024-10-30 14:25:34 -04:00
Paul
03331de2ac fix(ui): perf improvements in bulk upload (#8944) 2024-10-30 13:44:09 -04:00
Paul
d38d7b8932 fix(ui): broken buttons in the bulk upload drawer (#8926)
Fixes the mobile bottom interface and the arrow buttons in the actions
at the top.

Before:

![image](https://github.com/user-attachments/assets/26902eb0-5d1a-480d-b6f5-c36a800a6bff)


After:

![image](https://github.com/user-attachments/assets/7837684c-37a7-4b2e-a875-47972cf1671f)
2024-10-30 11:29:58 -06:00
Dan Ribbens
6cdf141380 feat: prevent create new for joins (#8929)
### What?

Adds a way to prevent creating new documents from the admin UI in a join
field.

### Why?

There are two reasons: 
1. You want to disable this any time as a feature of your admin user
experience
2. When creating a new document it is not yet possible to create the
relationship, preventing create is necessary for the workflow to make
sense.

### How?

join field has a new admin property called `allowCreate`, can be set to
false. By default the UI will never allow create when the current
document being edited does not yet have an `id`.

Fixes #

#8892

### Before

Even though the document doesn't have an ID yet, the create buttons are
shown which doesn't actually work.

![image](https://github.com/user-attachments/assets/152abed4-a174-498b-835c-aa4779c46834)

### After

Initial document creation: 
![Screenshot 2024-10-29
125132](https://github.com/user-attachments/assets/f33b1532-5b72-4c94-967d-bda618dadd34)

Prevented using `allowCreate: false`
![Screenshot 2024-10-29
130409](https://github.com/user-attachments/assets/69c3f601-fab3-4f5a-9df5-93fd133682ca)
2024-10-29 16:49:27 -04:00
Sasha
6c341b5661 fix(ui): sanitize limit for preferences (#8913)
### What?
Fixes the issue with passing a string `limit` value from user
preferences to the mongodb `.aggregate` function.

To reproduce:

- click the list view for a collection that has a join field
- set "show per page" to 100
- reload, see this:

<img width="1001" alt="image"
src="https://github.com/user-attachments/assets/86c644d1-d183-48e6-bf34-0ccac23cb114">

### Why?
When using `.aggregate`, MongoDB doesn't cast a value for the `$limit`
stage to a number automatically as it's not handled by Mongoose. It's
also more convenient to store this value as a number.

### How?
Stores `limit` inside of preferences in number.
2024-10-29 16:03:31 -04:00
Paul
c0aa96f59a fix(ui): missing localization label on text area fields (#8927) 2024-10-29 17:19:38 +00:00
Elliot DeNolf
43fcccab93 chore(release): v3.0.0-beta.120 [skip ci] 2024-10-28 22:08:50 -04:00
Patrik
e74906f555 fix(next, ui): exclude expired locks for globals (#8914)
Continued PR off of https://github.com/payloadcms/payload/pull/8899
2024-10-28 21:49:50 -04:00
Patrik
1e002acce9 fix(next, ui): only show locked docs that are not expired (#8899)
`Issue`:

Previously, documents that were locked but expired would still show in
the list view / render the `DocumentLocked` modal upon other users
entering the document.

The expected outcome should be having expired locked documents seen as
unlocked to other users.

I.e:

- Removing the lock icon from expired locks in the list view.
- Prevent the `DocumentLocked` modal from appearing for other users -
requiring a take over.

`Fix`:

- Only query for locked documents that are not expired, aka their
`updatedAt` dates are greater than the the current time minus the lock
duration.
- Performs a `deleteMany` on expired documents when any user edits any
other document in the same collection.

Fixes #8778 

`TODO`: Add tests
2024-10-28 20:05:26 -04:00
Alessio Gravili
a8569b9e78 fix(richtext-lexical): ensure editor cursor / selection state is preserved when working with drawers (#8872)
Previously, when opening e.g. a link drawer, clicking within the drawer,
and then closing it, the cursor / selection of the lexical editor will
reset to the beginning of the editor.

Now, we have dedicated logic to storing, preserving and restoring the
lexical selection when working with drawers.

This will work with all drawers. Links, uploads, relationships etc.


https://github.com/user-attachments/assets/ab3858b1-0f52-4ee5-813f-02b848355998
2024-10-27 22:32:31 +00:00
Elliot DeNolf
6c2eecc47e chore(release): v3.0.0-beta.119 [skip ci] 2024-10-25 16:11:53 -04:00
Paul
e72e81c3da fix(ui): upload buttons being hidden at mobile screen widths (#8860) 2024-10-24 22:29:29 +00:00
Paul
085e127217 fix(ui): leave without saving when changing /account theme (#8724)
Fixes an annoying instance where on the /account page if you change your
theme then navigate away the Leaving without save popup is triggered
even though you don't need to submit a form or trigger a save in order
to change your admin theme.
2024-10-24 16:46:19 -04:00
Elliot DeNolf
b482da63c6 chore(release): v3.0.0-beta.118 [skip ci] 2024-10-23 22:07:05 -04:00
Jessica Chowdhury
03c07026c5 feat: add localized indicator to field label (#8602)
On any localized field, appends `locale` on the end of the label.
2024-10-23 15:06:30 -04:00
Elliot DeNolf
69125504af chore(release): v3.0.0-beta.117 [skip ci] 2024-10-22 09:33:50 -04:00
Elliot DeNolf
74266bdd9a feat!: bump next.js to 15.0.0 (#8825)
Bump Next.js to 15.0.0
2024-10-21 23:12:22 -04:00
Patrik
2908c9adde fix(next, ui): ensures selectAll in the list view ignores locked documents (#8813)
Fixes #8783
2024-10-21 16:18:34 -04:00