Commit Graph

301 Commits

Author SHA1 Message Date
Germán Jabloñski
efce1549d0 chore(plugin-search): enable TypeScript strict mode (#11508) 2025-03-03 18:31:26 +00:00
Elliot DeNolf
bdf0113b2f chore(release): v3.25.0 [skip ci] 2025-02-27 12:06:03 -05:00
Alessio Gravili
2a3682ff68 fix(deps): ensure Next.js 15.2.0 compatibility, upgrade nextjs and @types/react versions in monorepo (#11419)
This bumps next.js to 15.2.0 in our monorepo, as well as all @types/react and @types/react-dom versions. Additionally, it removes the obsolete `peerDependencies` property from our root package.json.

This PR also fixes 2 bugs introduced by Next.js 15.2.0. This highlights why running our test suite against the latest Next.js, to make sure Payload is compatible, version is important.

## 1. handleWhereChange running endlessly

Upgrading to Next.js 15.2.0 caused `handleWhereChange` to be continuously called by a `useEffect` when the list view filters were opened, leading to a React error - I did not investigate why upgrading the Next.js version caused that, but this PR fixes it by making use of the more predictable `useEffectEvent`.

## 2. Custom Block and Array label React key errors

Upgrading to Next.js 15.2.0 caused react key errors when rendering custom block and array row labels on the server. This has been fixed by rendering those with a key

## 3. Table React key errors

When rendering a `Table`, a React key error is thrown since Next.js 15.2.0
2025-02-27 05:56:09 +00:00
Alessio Gravili
0058f82d87 perf: add limit: 1 and pagination: false to various payload queries (#11319)
`payload.find` queries can be made faster by specifying `limit: 1` and `pagination: false` when only the first document is needed. This PR applies those options to various queries to improve performance.
2025-02-21 11:09:40 -07:00
Elliot DeNolf
f3161f9405 chore(release): v3.24.0 [skip ci] 2025-02-19 13:37:26 -05:00
Jacob Fletcher
af5554981c refactor(ui): simplifies confirmation modal callback (#11278)
Removes unnecessary callback args from the `onConfirm` callback in the
new `ConfirmationModal` component. Now, the component will close and
reset `isConfirming` state for itself.
2025-02-19 09:18:37 -05:00
Jacob Fletcher
bd8ced1b60 feat(ui): confirmation modal (#11271)
There are nearly a dozen independent implementations of the same modal
spread throughout the admin panel and various plugins. These modals are
used to confirm or cancel an action, such as deleting a document, bulk
publishing, etc. Each of these instances is nearly identical, leading to
unnecessary development efforts when creating them, inconsistent UI, and
duplicative stylesheets.

Everything is now standardized behind a new `ConfirmationModal`
component. This modal comes with a standard API that is flexible enough
to replace nearly every instance. This component has also been exported
for reuse.

Here is a basic example of how to use it:

```tsx
'use client'
import { ConfirmationModal, useModal } from '@payloadcms/ui'
import React, { Fragment } from 'react'

const modalSlug = 'my-confirmation-modal'

export function MyComponent() {
  const { openModal } = useModal()

  return (
    <Fragment>
      <button
        onClick={() => {
          openModal(modalSlug)
        }}
        type="button"
      >
        Do something
      </button>
      <ConfirmationModal
        heading="Are you sure?"
        body="Confirm or cancel before proceeding."
        modalSlug={modalSlug}
        onConfirm={({ closeConfirmationModal, setConfirming }) => {
          // do something
          setConfirming(false)
          closeConfirmationModal()
        }}
      />
    </Fragment>
  )
}
```
2025-02-19 02:27:03 -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
Elliot DeNolf
480c6e7c09 chore(release): v3.23.0 [skip ci] 2025-02-11 12:53:51 -05:00
Elliot DeNolf
a80c6b5212 chore(release): v3.22.0 [skip ci] 2025-02-07 09:22:48 -05:00
Elliot DeNolf
834fdde088 chore(release): v3.21.0 [skip ci] 2025-02-05 14:15:51 -05:00
Paul
42da87b6e9 fix(plugin-search): deleting docs even when there's a published version (#10993)
Fixes https://github.com/payloadcms/payload/issues/9770

If you had a published document but then created a new draft it would
delete the search doc, this PR adds an additional find to check if an
existing published doc exists before deleting the search doc.

Also adds a few jsdocs to plugin config
2025-02-05 10:14:17 -05:00
Jessica Chowdhury
0f85a6e0cc fix(plugin-search): generates full docURL with basePath from next config (#10910)
Fixes #10878. The Search Plugin displays a link within the search
results collection that points to the underlying document that is
related to that result. The href used, however, was not accounting for
any `basePath` provided to the `next.config.js`, leading to a 404 if
using a custom base path. The fix is to use the `Link` component from
`next/link` instead of an anchor tag directly. This will automatically
inject the the base path into the href before rendering it.

This PR also brings back the `CopyToClipboard` component. This makes it
easy for the user to copy the href instead of navigating to it.

---------

Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
2025-02-03 15:17:07 -05:00
Jacob Fletcher
177127141e chore(plugin-search): improves types (#10955)
There were a number of areas within the Search Plugin where typings
could have been improved, namely:
- The `customProps` sent to the `ReindexButton`. This now uses the
`satisfies` keyword to ensure type strictness.
- The `collectionLabels` prop sent to the `ReindexButtonClient`
component. This is now standardized behind a new
`ResolvedCollectionLabels` type to closely reflect `CollectionLabels`.
This was also converted from unnecessarily invoking a function to being
a basic object.
- The `locale` type sent through `SyncDocArgs`. This now uses
`Locale['code']` from Payload.
2025-02-03 19:53:04 +00:00
Jacob Fletcher
4a4e90a170 chore(plugin-search): deprecates apiBasePath from config (#10953)
Continuation of #10632. The `apiBasePath` property in the Search Plugin
config is unnecessary. This plugin reads directly from the Payload
config for this property. Exposing it to the plugin's config was likely
a mistake during sanitization before passing it through to the remaining
files. This property was added to resolve the types, but as result,
exposed it to the config unnecessarily. This PR marks this property with
the deprecated flag to prevent breaking changes.
2025-02-03 19:06:05 +00:00
Suphon T.
6353cf8bbe fix(plugin-search): gets api route from useConfig (#10632)
This fixes #10631.

Originally the api basepath for the reindex button is resolved during
plugin initialization. Looks like this happens before payload overrides
the config with the `basePath `from the next config.
I've changed it so that it uses the `useConfig` hook, and manually
tested that it works.

![CleanShot 2568-01-17 at 16 03
16@2x](https://github.com/user-attachments/assets/c931577b-2717-4635-b5c6-17aa1b4eb734)
2025-02-03 18:14:21 +00:00
Elliot DeNolf
5bd17cc111 chore(release): v3.20.0 [skip ci] 2025-01-29 10:41:55 -05:00
Alessio Gravili
b9d3250117 chore: migrate outdated @payloadcms/next/utilities imports (#10777) 2025-01-24 01:58:45 +00:00
Elliot DeNolf
b2ebf85082 chore(release): v3.19.0 [skip ci] 2025-01-23 13:38:39 -05:00
Alessio Gravili
0c5321e6f8 chore: temporarily revert 10597 (#10718)
Temporarily reverts 10597 to fix plugin-oauth
2025-01-22 16:36:54 -05:00
Sasha
be98edaa6c fix: apply CORS response headers without headersWithCors (#10597)
Fixes https://github.com/payloadcms/payload/issues/10332

Previously, the `cors` configuration wasn't respected for:
- Custom endpoints without using `headersWithCors` which as described in
https://github.com/payloadcms/payload/issues/10332 is not documented.
- Some of our endpoints like `/payload-jobs/run` or from plugins due to
missing `headersWithCors` -
592f02b3bf/packages/payload/src/queues/restEndpointRun.ts (L82-L88)

In 2.0, you didn't need `headersWithCors` and I think it's expected to
handle this logic by default.
This completely removes `headersWithCors` boilerplate from the all
endpoints and instead, handles this logic at the end of
`handleEndpoints` directly -
https://github.com/payloadcms/payload/compare/fix/default-cors?expand=1#diff-82e97630068f9fc40256f3f46e06226215ab150d16012281810586b51b0cfd51

Also deprecates public export of `headersWithCors`
2025-01-21 03:29:07 +02:00
Elliot DeNolf
26aeebcce0 chore(release): v3.18.0 [skip ci] 2025-01-20 17:02:02 -05:00
Germán Jabloñski
d4039f2f9e chore: enable noUncheckedIndexedAccess in all packages except richtext-lexical (#10592)
richtext-lexical throws a lot of errors so it will need a separate PR
2025-01-15 16:09:10 +00:00
Germán Jabloñski
d55b6a3db9 chore: enable noImplicitOverride in all packages (#10588) 2025-01-15 10:06:40 +00:00
Germán Jabloñski
085c1d0cac chore: make TypeScript strict by default in packages and 7 packages stricter (#10579)
This PR modifies `tsconfig.base.json` by setting the following
strictness properties to true: `strict`, `noUncheckedIndexedAccess` and
`noImplicitOverride`.

In packages where compilation errors were observed, these settings were
opted out, and TODO comments were added to make it easier to track the
roadmap for converting everything to strict mode.

The following packages now have increased strictness, which prevents new
errors from being accidentally introduced:

- storage-vercel-blob
- storage-s3*
- storage-gcs
- plugin-sentry
- payload-cloud*
- email-resend*
- email-nodemailer*

*These packages already had `strict: true`, but now have
`noUncheckedIndexedAccess` and `noImplicitOverride`.

Note that this only affects the `/packages` folder, but not
`/templates`, `/test` or `/examples` which have a different `tsconfig`.
2025-01-14 21:39:40 +00:00
Elliot DeNolf
a865a902d5 chore(release): v3.17.1 [skip ci] 2025-01-13 19:57:13 -05:00
Elliot DeNolf
3c29015887 chore(release): v3.17.0 [skip ci] 2025-01-13 16:24:41 -05:00
Elliot DeNolf
d265c26049 chore(release): v3.16.0 [skip ci] 2025-01-10 14:12:06 -05:00
Sasha
e46ad67c3b chore: update year in licenses (#10463)
Happy New Year!
2025-01-10 14:05:37 -05:00
Elliot DeNolf
81188fc8bb chore(release): v3.15.1 [skip ci] 2025-01-07 21:49:22 -05:00
Elliot DeNolf
a5443a1c6c chore(release): v3.15.0 [skip ci] 2025-01-07 12:46:11 -05:00
Elliot DeNolf
766b67f0be chore(release): v3.14.0 [skip ci] 2025-01-03 08:34:41 -05:00
Elliot DeNolf
b0ebd92a1e chore(release): v3.13.0 [skip ci] 2025-01-01 23:15:48 -05:00
Said Akhrarov
cdaebcc79c fix(plugin-search): respect custom api route in reindexButton (#10258)
<!--

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 fixes an issue with `plugin-search` where the ReindexButton was
not directing the reindex call to the correct endpoint location if the
user defined a custom config api route.

### Why?
To allow collection reindexing even when the default base api path gets
overriden with a user-provided one.

### How?
By threading the custom route to the ReindexButton component that calls
the reindex endpoint.

Fixes #10245

Notes:
- I think the `basePath` check/manipulation might be better in the RSC
instead of the client

Edit: @JessChowdhury Didn't see you were assigned until after! Felt bad
about this since it's my bad, wanted to take some ownership over the bug
here, my mistake!
2024-12-31 00:08:58 +00:00
Elliot DeNolf
fabe5411f4 chore(release): v3.12.0 [skip ci] 2024-12-28 12:02:39 -05:00
Dan Ribbens
326b72072c chore: update rimraf and fix windows compatible clean script (#10152)
Previously we had been downgrading rimraf to v3 simply to handle clean
with glob patterns across platforms. In v4 and newer of rimraf you can
add `-g` to use glob patterns.

This change updates rimraf and adds the flag to handle globs in our
package scripts to be windows compatible.
2024-12-27 09:16:17 -05:00
Elliot DeNolf
e9a330d4b9 chore(release): v3.11.0 [skip ci] 2024-12-21 07:56:14 -05:00
Elliot DeNolf
4d50046104 chore(release): v3.10.0 [skip ci] 2024-12-20 14:42:13 -05:00
Elliot DeNolf
d0d7b51ed5 chore(release): v3.9.0 [skip ci] 2024-12-18 15:58:11 -05:00
Jacob Fletcher
b8de401195 chore: fixes package license file casing (#10021)
Fixes file casing for all package licenses where applicable, i.e.
`license.md` → `LICENSE.md` to comply with standards outlined
[here](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository).
2024-12-18 10:36:42 -05:00
Alessio Gravili
f5c13deb24 build: fix tsconfig monorepo setup (#10028)
Should fix messed up import suggestions and simplifies all tsconfigs
through inheritance.

One main issue was that packages were inheriting `baseURL: "."` from the
root tsconfig. This caused incorrect import suggestions that start with
"packages/...".

This PR ensures that packages do not inherit this baseURL: "." property,
while ensuring the root, non-inherited tsconfig still keeps it to get
tests to work (the importMap needs it)
2024-12-17 14:49:29 -05:00
Said Akhrarov
29ad1fcb77 fix(plugin-search): prevent error on undefined value in linkToDoc component (#9932)
<!--

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 fixes a runtime error encountered when navigating into a search
doc that had its' related collection doc deleted, but it itself remained
(if for example `deleteFromSearch` deletion failed for some reason).

### Why?
To prevent runtime errors for end-users using `plugin-search`.

### How?
By returning earlier if the field value is undefined or missing required
values in `LinkToDoc`.

Fixes #9443 (partially, see also: #9623)
2024-12-17 04:39:15 +00:00
Elliot DeNolf
3f35d36934 chore(release): v3.8.0 [skip ci] 2024-12-16 21:12:02 -05:00
Elliot DeNolf
4c3e41beb1 chore(release): v3.7.0 [skip ci] 2024-12-13 12:06:46 -05:00
Elliot DeNolf
45d20643df chore(release): v3.6.0 [skip ci] 2024-12-11 13:05:47 -05:00
Elliot DeNolf
ff62017cf2 chore(release): v3.5.0 [skip ci] 2024-12-06 14:58:41 -05:00
Alessio Gravili
8f3f44922e feat: upgrade to React 19 stable and Next.js 15.0.4 (#9801)
No need for those ugly @types/react overrides anymore!
2024-12-06 14:53:36 -05:00
Elliot DeNolf
0ca473e6ca chore(release): v3.4.0 [skip ci] 2024-12-04 10:32:41 -05:00
Elliot DeNolf
a6ba9e3a41 chore(release): v3.3.0 [skip ci] 2024-12-03 12:53:42 -05:00
Sasha
b8965077b8 fix(plugin-search): delete proper search document when doc has the same value but different relationTo (#9616)
Fixes https://github.com/payloadcms/payload/issues/9612

Previously, the plugin search with different collections but the same
IDs could delete a wrong search document on synchronization, because we
queried the search document only by `doc.value`. Instead, we should also
query by `doc.relationTo`.
2024-11-29 21:25:26 +02:00