Commit Graph

36 Commits

Author SHA1 Message Date
Paul
c43891b2ba fix(db-mongodb): localized dates being returned as date objects instead of strings (#12354)
Fixes https://github.com/payloadcms/payload/issues/12334

We weren't passing locale through to the Date transformer function so
localized dates were being read as objects instead of strings.
2025-05-10 17:15:15 -07:00
Germán Jabloñski
97e2e77ff4 chore: run dev:generate-types (#11994) 2025-04-08 17:25:29 -03: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
3709950d50 feat: maintains column state in url (#11387)
Maintains column state in the URL. This makes it possible to share
direct links to the list view in a specific column order or active
column state, similar to the behavior of filters. This also makes it
possible to change both the filters and columns in the same rendering
cycle, a requirement of the "list presets" feature being worked on here:
#11330.

For example:

```
?columns=%5B"title"%2C"content"%2C"-updatedAt"%2C"createdAt"%2C"id"%5D
```

The `-` prefix denotes that the column is inactive.

This strategy performs a single round trip to the server, ultimately
simplifying the table columns provider as it no longer needs to request
a newly rendered table for itself. Without this change, column state
would need to be replaced first, followed by a change to the filters.
This would make an unnecessary number of requests to the server and
briefly render the UI in a stale state.

This all happens behind an optimistic update, where the state of the
columns is immediately reflected in the UI while the request takes place
in the background.

Technically speaking, an additional database query in performed compared
to the old strategy, whereas before we'd send the data through the
request to avoid this. But this is a necessary tradeoff and doesn't have
huge performance implications. One could argue that this is actually a
good thing, as the data might have changed in the background which would
not have been reflected in the result otherwise.
2025-02-27 20:00:40 -05:00
Patrik
f1b005c4f5 fix(ui): object type field labels not displaying in search filter (#11366)
This PR ensures that when `titleField.label` is provided as an object,
it is correctly translated and displayed in the search filter's
placeholder.

Previously, the implementation only supported string values, which could
lead to issues with object type labels. With these changes, object type
labels will now properly show as intended in the search filter.

Fixes #11348
2025-02-24 13:38:21 -05:00
Sasha
117949b8d9 test: regenerate payload-types.ts for all test suites (#11238)
Regenerates `payload-types.ts` for all test suites.
2025-02-18 00:45:59 +02: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
Jacob Fletcher
afcc970e36 fix(next): ensures req.locale is populated before running access control (#10533)
Fixes #10529. The `req.locale` property within collection and global
access control functions does not reflect the current locale. This was
because we were attaching the locale to the req only _after_ running
`payload.auth`, which attempts to get access control without a
fully-formed req. The fix is to first authenticate the user using the
`executeAuthStrategies` operation directly, then determine the request
locale with that user, and finally get access results with the proper
locale.
2025-01-13 10:33:27 -05:00
Sasha
1af7d8745c fix: localized tabs with empty data and an array field inside lead to crash in afterChange (#10410)
Previously, this config:
```ts
import type { CollectionConfig } from 'payload'

export const tabSlug = 'tabs'

export const Tab: CollectionConfig = {
  slug: tabSlug,
  fields: [
    {
      type: 'tabs',
      tabs: [
        {
          name: 'tabLocalized',
          localized: true,
          fields: [
            {
              name: 'title',
              type: 'text',
            },
            {
              name: 'array',
              type: 'array',
              fields: [
                {
                  name: 'title',
                  type: 'text',
                },
              ],
            },
          ],
        },
      ],
    },
  ],
}

```
This call
```ts
const result = await payload.create({
  collection: tabSlug,
  locale: englishLocale,
  data: {
    tabLocalized: {},
  },
})
```

Led to the following crash with the MongoDB adapter
<img width="741" alt="image"
src="https://github.com/user-attachments/assets/8d1d37de-a685-4a30-bd37-58af164108a2"
/>

This is due to how Mongoose, apparently just ignores the `minimize:
false` configuration
a83a430a3a/packages/db-mongodb/src/models/buildSchema.ts (L571)
and we, instead of `tabLocalized: { en: { } }` receive just
`tabLocalized: {}`.

This isn't an issue with group fields because we have fallback for them

a83a430a3a/packages/payload/src/fields/hooks/afterChange/promise.ts (L203)

This PR adds the same for tabs.
2025-01-11 00:37:23 +02:00
Sasha
c7b3204439 fix: copy to locale with localized arrays and blocks generate new IDs to prevent errors in postgres (#10292)
Fixes https://github.com/payloadcms/payload/issues/10093
2025-01-03 14:23:16 -05:00
Alessio Gravili
c7138b9aab chore: update generated types for all test suites (#9577) 2024-11-27 20:36:37 +00:00
Jessica Chowdhury
601759d967 feat: adds ability to copy data from across locales (#8203)
### What?

Adds ability to copy data from one locale to another at a document
level.

### How?

For any localized collection, you will find a new option in the document
controls called `Copy to Locale`.

This option will open a drawer, from here you can select your origin and
destination locales.

If data already exists in the destination locale, you can choose to: 
1. Overwrite this data (this will copy any empty fields in your origin
locale)
2. Not overwrite existing data (this will only copy data into empty
fields in the destination locale)

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2024-11-26 17:06:30 -05: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
Sasha
414030e1f1 fix(drizzle): row / collapsible inside of localized fields (#8539)
Fixes https://github.com/payloadcms/payload/issues/8405
2024-10-04 11:48:54 -04:00
Sasha
613d3b090e fix(drizzle): hasMany / poly relationships nested to localized fields / nested blocks to localized fields (#8456)
fixes https://github.com/payloadcms/payload/issues/8455 and
https://github.com/payloadcms/payload/issues/8462

- Builds the `_locale` column for the `_rels` when it's inside of a
localized group / tab
- Properly builds `sanitizedPath` for blocks in the transform-read
function when it's inside of a localized field. This fixes with fields
inside that have its own table (like `_rels`, select `hasMany: true`
etc)

Adds _more_ tests!
2024-09-28 17:33:50 +03:00
Sasha
b7db53cef4 fix(drizzle)!: localized fields uniqueness per locale (#8230)
Previously, this worked with MongoDB but failed with Postgres / SQLite
when the `slug` field has both `localized: true` and `unique: true`.

```ts
await payload.create({
  collection: "posts",
  locale: "en",
  data: {
    slug: "my-post"
  }
})

await payload.create({
  collection: "posts",
  locale: "de",
  data: {
    slug: "my-post"
  }
})
```

Now, we build unique constraints and indexes in combination with the
_locale column. This should also improve query performance for fields
with both index: true and localized: true.

### Migration steps (Postgres/SQLite only)
This change updates the database schema and requires a migration (if you
have any localized fields). To apply it, run the following commands:

```sh
pnpm payload migration:create locale_unique_indexes
pnpm payload migrate
```

Note that if you use `db.push: true` which is a default, you don't have
to run `pnpm payload migrate` in the development mode, only in the
production, as Payload automatically pushes the schema to your DB with
it.
2024-09-16 14:47:13 -04:00
James Mikrut
c460868e52 fix: duplication with localized arrays in unnamed tabs (#8236)
Fixes a case where in relational DBs, you can't duplicate documents if
you have localized arrays within unnamed tabs.

The `beforeDuplicate` hooks were not being run for fields within unnamed
tabs.
2024-09-16 11:43:36 -04:00
Alessio Gravili
dc12047723 feat: reduce package size and amount of dependencies by upgrading json-schema-to-typescript (#7938)
Closes https://github.com/payloadcms/payload/issues/7934
2024-08-28 21:59:32 +00:00
James Mikrut
18b0806b5b fix(db-postgres, db-sqlite): hasMany text, number, poly relationship, blocks, arrays within localized fields (#7900)
## Description

In Postgres, localized blocks or arrays that contain other array / block
/ relationship fields were not properly storing locales in the database.

Now they are! Need to check a few things yet:

- Ensure test coverage is sufficient
- Test localized array, with non-localized array inside of it
- Test localized block with relationship field within it
- Ensure `_rels` table gets the `locale` column added if a single
non-localized relationship exists within a localized array / block

Fixes step 6 as identified in #7805
2024-08-28 17:43:12 +00:00
Patrik
b3e8ddf302 fix(db-mongodb): removes precedence of regular chars over international chars in sort (#7294)
## Description

V2 PR [here](https://github.com/payloadcms/payload/pull/6923)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-07-23 09:03:00 -04:00
Alessio Gravili
e5d5126d14 chore: regenerate all types in test dir, and add to eslint & prettier ignores 2024-07-11 15:59:38 -04:00
Jacob Fletcher
9e76c8f4e3 feat!: prebundle payload, ui, richtext-lexical (#6579)
# Breaking Changes

### New file import locations

Exports from the `payload` package have been _significantly_ cleaned up.
Now, just about everything is able to be imported from `payload`
directly, rather than an assortment of subpath exports. This means that
things like `import { buildConfig } from 'payload/config'` are now just
imported via `import { buildConfig } from 'payload'`. The mental model
is significantly simpler for developers, but you might need to update
some of your imports.

Payload now exposes only three exports:

1. `payload` - all types and server-only Payload code
2. `payload/shared` - utilities that can be used in either the browser
or in Node environments
3. `payload/node` - heavy utilities that should only be imported in Node
scripts and never be imported into bundled code like Next.js

### UI library pre-bundling

With this release, we've dramatically sped up the compile time for
Payload by pre-bundling our entire UI package for use inside of the
Payload admin itself. There are new exports that should be used within
Payload custom components:

1. `@payloadcms/ui/client` - all client components 
2. `@payloadcms/ui/server` - all server components

For all of your custom Payload admin UI components, you should be
importing from one of these two pre-compiled barrel files rather than
importing from the more deeply nested exports directly. That will keep
compile times nice and speedy, and will also make sure that the bundled
JS for your admin UI is kept small.

For example, whereas before, if you imported the Payload `Button`, you
would have imported it like this:

```ts
import { Button } from '@payloadcms/ui/elements/Button'
```

Now, you would import it like this:

```ts
import { Button } from '@payloadcms/ui/client'
```

This is a significant DX / performance optimization that we're pretty
pumped about.

However, if you are importing or re-using Payload UI components
_outside_ of the Payload admin UI, for example in your own frontend
apps, you can import from the individual component exports which will
make sure that the bundled JS is kept to a minimum in your frontend
apps. So in your own frontend, you can continue to import directly to
the components that you want to consume rather than importing from the
pre-compiled barrel files.

Individual component exports will now come with their corresponding CSS
and everything will work perfectly as-expected.

### Specific exports have changed

- `'@payloadcms/ui/templates/Default'` and
`'@payloadcms/ui/templates/Minimal`' are now exported from
`'@payloadcms/next/templates'`
- Old: `import { LogOut } from '@payloadcms/ui/icons/LogOut'` new:
`import { LogOutIcon } from '@payloadcms/ui/icons/LogOut'`

## Background info

In effort to make local dev as fast as possible, we need to import as
few files as possible so that the compiler has less to process. One way
we've achieved this in the Admin Panel was to _remove_ all .scss imports
from all components in the `@payloadcms/ui` module using a build
process. This stripped all `import './index.scss'` statements out of
each component before injecting them into `dist`. Instead, it bundles
all of the CSS into a single `main.css` file, and we import _that_ at
the root of the app.

While this concept is _still_ the right solution to the problem, this
particular approach is not viable when using these components outside
the Admin Panel, where not only does this root stylesheet not exist, but
where it would also bloat your app with unused styles. Instead, we need
to _keep_ these .scss imports in place so they are imported directly
alongside your components, as expected. Then, we need create a _new_
build step that _separately_ compiles the components _without_ their
stylesheets—this way your app can consume either as needed from the new
`client` and `server` barrel files within `@payloadcms/ui`, i.e. from
within `@payloadcms/next` and all other admin-specific packages and
plugins.

This way, all other applications will simply import using the direct
file paths, just as they did before. Except now they come with
stylesheets.

And we've gotten a pretty awesome initial compilation performance boost.

---------

Co-authored-by: James <james@trbl.design>
Co-authored-by: Alessio Gravili <alessio@gravili.de>
2024-06-17 14:25:36 -04:00
Elliot DeNolf
354ad7092c chore: type gen formatting (#6309) 2024-05-09 23:55:55 -04:00
Alessio Gravili
f7a2cf96b9 chore: properly working generated types within tests (#6288) 2024-05-09 17:12:51 -04:00
Elliot DeNolf
14eb66c87d test: refactor int tests to use initPayloadInt which reduces boilerplate 2024-03-16 10:11:00 -04:00
Jarrod Flesch
46fc41cbd9 fix: incorrect duplication of data in admin ui (#3907) 2023-10-27 22:41:33 -04:00
James
0f3b364e46 chore: hoists tests out of payload package 2023-09-01 14:45:41 -04:00
Alessio Gravili
a67278b29f chore: move to monorepo structure 2023-08-23 12:20:30 +02:00
Dan Ribbens
682f8ecae4 wip merge master 2023-06-29 13:27:33 -04:00
Alessio Gravili
15442a9cc7 fix: use correct locale when querying relationships for list view (#2438)
* chore: use correct locale when querying relationship for list view

* chore: make sure the relationships are re-queried when the locale changes

* chore: cleans up localization test ts-types

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2023-04-17 12:43:33 -04:00
James
ee54c1481c fix: #1808, arrays and blocks now save localized nested field data upon reordering rows 2023-01-09 12:58:13 -05:00
Dan Ribbens
04c689c5b0 fix: handle multiple locales in relationship population (#1452) 2022-11-28 14:24:01 -05:00
Dan Ribbens
145e1db05d fix: dev:generate-types on all test configs (#919) 2022-08-13 13:04:24 -04:00
James
39d075b999 fix: ensures passing partial data to update works when fields are localized 2022-07-17 15:00:38 -07:00
Elliot DeNolf
b5ce54c7ae test: localization relationship tests 2022-07-16 18:01:13 -07:00
Elliot DeNolf
ba79b4446c test: refactor all test directories into one 2022-07-15 12:51:43 -07:00