Compare commits

..

42 Commits

Author SHA1 Message Date
Elliot DeNolf
f8ec6a7490 chore(release): payload/2.32.3 [skip ci] 2025-05-08 11:17:10 -07:00
Kapil Barad
5ecee3f6f6 fix(upload): ensure only image files are read for preview (#9562)
### What?
Ensure only image files are read for preview.

### Why?
Upon uploading larger files, it crashes the browser as it's reading the
whole file for preview.

Fixes #9559

Co-authored-by: Kapil Barad <>
2025-05-08 13:26:07 +01:00
Patrik
a09fefaed7 fix: filter state resetting when removing previous condition in WhereBuilder (#12262)
### What?

This PR fixes an issue in the `WhereBuilder` component where removing a
previous filter condition would cause remaining conditions to reset
their `operator` and `value`.

The problem was that the `Condition` components were keyed only by their
index, causing React to incorrectly reuse component instances when the
condition list changed. This led to stale or mismatched internal state
after a filter was removed.

The fix updates the key for each `Condition` to be based on a
combination of field `name`, `operator`, and `indexes`. This ensures the
components are correctly recreated when necessary and that the selected
`field`, `operator`, and `value` persist properly across updates.
2025-05-01 10:37:51 -04:00
Elliot DeNolf
e97606a91b chore: update changelog 2025-03-14 14:21:31 -04:00
Elliot DeNolf
fde64094ac chore(release): plugin-stripe/0.0.19 [skip ci] 2025-03-14 14:02:07 -04:00
Elliot DeNolf
1b1d690874 chore(release): plugin-sentry/0.0.8 [skip ci] 2025-03-14 14:01:55 -04:00
Elliot DeNolf
09d715ff38 chore(release): plugin-relationship-object-ids/0.0.6 [skip ci] 2025-03-14 14:01:46 -04:00
Elliot DeNolf
db51b4c5ab chore(release): plugin-cloud-storage/1.2.2 [skip ci] 2025-03-14 14:01:37 -04:00
Elliot DeNolf
0ec5e096f3 chore(release): plugin-cloud/3.0.4 [skip ci] 2025-03-14 14:01:23 -04:00
Elliot DeNolf
c3f80aaa4b chore(release): db-mongodb/1.7.5 [skip ci] 2025-03-14 14:01:10 -04:00
Elliot DeNolf
2ba5cae83e chore(release): bundler-webpack/1.0.9 [skip ci] 2025-03-14 14:01:00 -04:00
Elliot DeNolf
c2120c06bb chore(release): bundler-vite/0.1.9 [skip ci] 2025-03-14 14:00:36 -04:00
Elliot DeNolf
9c6ab39bf4 chore(release): payload/2.32.2 [skip ci] 2025-03-14 13:58:58 -04:00
Elliot DeNolf
965d3d8d47 chore: run audit fix on high severity (#11705)
`pnpm audit --audit-level high --fix`
2025-03-14 13:56:03 -04:00
Elliot DeNolf
34ce21c1f8 chore(release): plugin-stripe/0.0.18 [skip ci] 2025-03-14 13:53:06 -04:00
Elliot DeNolf
ca6725b4ec chore(release): plugin-sentry/0.0.7 [skip ci] 2025-03-14 13:52:48 -04:00
Elliot DeNolf
a54fc12189 chore(release): plugin-relationship-object-ids/0.0.5 [skip ci] 2025-03-14 13:52:31 -04:00
Elliot DeNolf
cfe0fdf3f6 chore(release): plugin-cloud-storage/1.2.1 [skip ci] 2025-03-14 13:52:18 -04:00
Elliot DeNolf
2e2013602d chore(release): plugin-cloud/3.0.3 [skip ci] 2025-03-14 13:51:53 -04:00
Elliot DeNolf
9f17391475 chore(release): db-mongodb/1.7.4 [skip ci] 2025-03-14 13:51:39 -04:00
Elliot DeNolf
cd12963296 chore(release): bundler-webpack/1.0.8 [skip ci] 2025-03-14 13:51:26 -04:00
Elliot DeNolf
165442028c chore(release): bundler-vite/0.1.8 [skip ci] 2025-03-14 13:50:58 -04:00
Elliot DeNolf
3c4c32fecd chore(release): payload/2.32.1 [skip ci] 2025-03-14 13:48:46 -04:00
Elliot DeNolf
7648b32669 chore: bump dependencies (#11702)
Bump misc dependencies for security vulnerabilities.
2025-03-14 12:53:24 -04:00
Elliot DeNolf
c835a21707 chore: simplify query parsing (#11613)
Simplifies query parsing logic.
2025-03-14 11:18:26 -04:00
Will Robson
a5e6ea5737 fix: remove collapsible label prefix from the FieldSelect dropdown component (#10760)
### What?

Removes Collapsible label from child field label in the `FieldSelect`
component (for example Bulk Edit field select dropdown)

### Why?

Including the Collapsible field label in the option label of the
FieldSelect component could potentially be confusing to a user as it
eludes to the field being nested in the Data schema.

### How?

In the reduceFields function of the FieldsLabel component, if
`field.type === 'collpasible'` the collapsible field's label will not be
combined with the child fields labels.

Fixes #10757

---------

Co-authored-by: Patrik Kozak <patrik@payloadcms.com>
2025-02-17 15:44:13 -05:00
Patrik
106d7dde23 ci: updates actions/upload-artifact to v4 & explicitly use ubuntu-24.04 instead of latest (#10898)
### What

- Updates actions/upload-artifact from `v3` to `v4` in github actions
workflow.
- Install playwright in pipeline instead of npm script

---------

Co-authored-by: Elliot DeNolf <denolfe@gmail.com>
2025-02-17 15:14:51 -05:00
Patrik
276a6dde06 chore: adds tests for forceRenderAllFields admin prop (#10479)
### What?

Adds `e2e` tests for previously new collection / global config admin
prop: `forceRenderAllFields`
2025-01-10 13:30:07 -05:00
Elliot DeNolf
f12cb6298a chore(release): payload/2.32.0 [skip ci] 2025-01-10 11:10:55 -05:00
Alessio Gravili
2e352552d1 chore: export CheckboxInput (#10489) 2025-01-10 01:31:17 -07:00
Elliot DeNolf
aae52181b0 chore(release): payload/2.31.0 [skip ci] 2025-01-09 10:39:31 -05:00
Patrik
07ff181ccf feat: adds forceRenderAllFields admin prop to force all fields in edit view to render immediately (#10464)
### What?

Adds new `forceRenderAllFields` `admin` prop to `collection` & `global`
configs.

This new prop forces all fields in the `Edit` view to render
immediately, regardless of scroll position. By default, this is set to
`false` to improve performance, as fields are progressively rendered to
balance load times. Enabling this option can make it easier to locate
fields using browser search (e.g., CMD+F).

```
admin: {
  forceRenderAllFields: true,
},
```

### Why?

Previously, fields were only rendered to a certain viewport pixel height
for performance purposes. As a result, this disallowed using the browser
search on all fields in the edit view if they were not completely loaded
in i.e in the proper viewport.
2025-01-09 09:06:06 -05:00
Jessica Chowdhury
f430db8bc5 feat(v2): allows filtering on group field types from list view (#10421)
### What?
**V2 Update** – Adds support for using group fields when filtering the
list view.

### Why?
This feature was originally introduced in V3. Due to popular demand from
V2 users, we are backporting it into V2.

### How?
Updates the `WhereBuilder` to map over fields within a group and prefix
them with the parent field name. Similar to V3 PR
[here](https://github.com/payloadcms/payload/pull/6647).

#### Review & Testing
Use the `admin` test suite and the `posts` collection to see this
change.
2025-01-08 18:36:40 +00:00
Alessio Gravili
a2e54db469 docs: fix backtick escaping in TableWithDrawers blocks (#10221) 2024-12-27 23:40:47 -07:00
Alessio Gravili
73bd4370b8 docs: fix typo (#10219) 2024-12-27 22:33:02 -07:00
Alessio Gravili
95a4443ea1 docs: migrate to new mdx rendering (#10218) 2024-12-27 22:29:02 -07:00
Dan Ribbens
59ee821cec Revert "fix(plugin-form-builder): use escapeHTML on submission data in serializeLexical" (#9805)
Reverts payloadcms/payload#8110
2024-12-06 15:58:35 -05:00
Naoto Ikeno
4892d96515 fix(graphql): 500 error when querying hasMany field data that is filtered by access-control (#6519)
This PR closes #6518.
Just filtering null item from the `results` array makes thing work well.

## Description

<!-- Please include a summary of the pull request and any related issues
it fixes. Please also include relevant motivation and context. -->

- [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

<!-- Please delete options that are not relevant. -->

- [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-12-06 10:25:09 -05:00
NorthBlue333
b0de37ba95 fix(plugin-form-builder): use escapeHTML on submission data in serializeLexical (#8110)
## Description

Fixes #8109 
Note this should also be merge in payload/beta!

- [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:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes

Signed-off-by: NorthBlue333 <north333@free.fr>
2024-12-06 10:01:32 -05:00
アルパカ
0cf96785bc fix: when publishing from a draft, only 10 were published. (#7906)
## Description
this PR close : https://github.com/payloadcms/payload/issues/7905

delete limit when updated
- 
<!-- Please include a summary of the pull request and any related issues
it fixes. Please also include relevant motivation and context. -->

- [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

<!-- Please delete options that are not relevant. -->

- [ ] Chore (non-breaking change which does not add functionality)
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-12-06 09:55:56 -05:00
Rajiv Seelam
e7ae5f0a97 Fix typo in concepts (#6864)
## Description

In example demonstrating depth, it's for posts, but it mentions "user"
as an example

- [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

<!-- Please delete options that are not relevant. -->

- [x] This change requires a documentation update
2024-12-06 09:35:13 -05:00
Vid Čufar
7039b1f82e feat(i18n): add Slovenian (sl) translation (#8709)
This PR introduces Slovenian (sl) language translation.
2024-12-06 09:06:54 -05:00
105 changed files with 6454 additions and 3437 deletions

View File

@@ -13,7 +13,7 @@ on:
jobs:
on-labeled-ensure-one-status:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
issues: write
# Only run on issue labeled and if label starts with 'status:'
@@ -49,7 +49,7 @@ jobs:
}
on-issue-close:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
issues: write
if: github.event.action == 'closed'
@@ -82,7 +82,7 @@ jobs:
}
on-issue-reopen:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
issues: write
if: github.event.action == 'reopened'
@@ -93,7 +93,7 @@ jobs:
labels: 'status: needs-triage'
on-issue-assigned:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
issues: write
if: >
@@ -106,11 +106,11 @@ jobs:
labels: 'status: needs-triage'
# on-pr-merge:
# runs-on: ubuntu-latest
# runs-on: ubuntu-24.04
# if: github.event.pull_request.merged == true
# steps:
# on-pr-close:
# runs-on: ubuntu-latest
# runs-on: ubuntu-24.04
# if: github.event_name == 'pull_request_target' && github.event.pull_request.merged == false
# steps:

View File

@@ -11,7 +11,7 @@ permissions:
jobs:
lock_issues:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Lock issues
uses: dessant/lock-threads@v5

View File

@@ -2,13 +2,13 @@ name: build
on:
pull_request:
types: [ opened, reopened, synchronize ]
types: [opened, reopened, synchronize]
push:
branches: [ 'main' ]
branches: ['main']
jobs:
changes:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
pull-requests: read
outputs:
@@ -42,7 +42,7 @@ jobs:
core-build:
needs: changes
if: ${{ needs.changes.outputs.needs_build == 'true' }}
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
@@ -53,10 +53,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -88,7 +88,7 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
tests:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: core-build
strategy:
fail-fast: false
@@ -108,10 +108,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -131,7 +131,7 @@ jobs:
- name: Start PostgreSQL
uses: CasperWA/postgresql-action@v1.2
with:
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
postgresql db: ${{ env.POSTGRES_DB }}
postgresql user: ${{ env.POSTGRES_USER }}
postgresql password: ${{ env.POSTGRES_PASSWORD }}
@@ -181,22 +181,22 @@ jobs:
POSTGRES_URL: ${{ env.POSTGRES_URL }}
tests-e2e:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: core-build
strategy:
fail-fast: false
matrix:
part: [ 1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8 ]
part: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8]
steps:
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -210,6 +210,28 @@ jobs:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Store Playwright's Version
run: |
# Extract the version number using a more targeted regex pattern with awk
PLAYWRIGHT_VERSION=$(pnpm ls @playwright/test --depth=0 | awk '/@playwright\/test/ {print $2}')
echo "Playwright's Version: $PLAYWRIGHT_VERSION"
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
- name: Cache Playwright Browsers for Playwright's Version
id: cache-playwright-browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
- name: Setup Playwright - Browsers and Dependencies
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Setup Playwright - Dependencies-only
if: steps.cache-playwright-browsers.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromium
- name: E2E Tests
uses: nick-fields/retry@v2
with:
@@ -218,7 +240,7 @@ jobs:
timeout_minutes: 15
command: pnpm test:e2e --part ${{ matrix.part }} --bail
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
@@ -226,7 +248,7 @@ jobs:
retention-days: 1
tests-type-generation:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: core-build
steps:
@@ -234,10 +256,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -258,7 +280,7 @@ jobs:
run: pnpm dev:generate-graphql-schema graphql-schema-gen
build-packages:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: core-build
strategy:
fail-fast: false
@@ -278,10 +300,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -299,7 +321,7 @@ jobs:
run: pnpm turbo run build --filter=${{ matrix.pkg }}
plugins:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: core-build
strategy:
fail-fast: false
@@ -319,10 +341,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Install pnpm
uses: pnpm/action-setup@v3
@@ -346,11 +368,11 @@ jobs:
templates:
needs: changes
if: ${{ needs.changes.outputs.templates == 'true' }}
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
template: [ blank, website, ecommerce ]
template: [blank, website, ecommerce]
steps:
- uses: actions/checkout@v4
@@ -361,10 +383,10 @@ jobs:
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
- name: Use Node.js 22.6.0
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22.6.0
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0

View File

@@ -8,7 +8,7 @@ on:
jobs:
post_release:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:

View File

@@ -5,7 +5,7 @@ on:
jobs:
test:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Echo
run: echo "Register release-canary workflow"

View File

@@ -5,7 +5,7 @@ on:
jobs:
stale:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
issues: write
pull-requests: write

View File

@@ -18,7 +18,7 @@ permissions:
jobs:
debug-context:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: View context attributes
uses: actions/github-script@v7
@@ -27,7 +27,7 @@ jobs:
label-created-by:
name: label-on-open
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Tag with 'created-by'
uses: actions/github-script@v7
@@ -89,7 +89,7 @@ jobs:
triage:
name: initial-triage
if: github.event_name == 'issues'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:

View File

@@ -1,3 +1,45 @@
## [2.32.3](https://github.com/payloadcms/payload/compare/v2.32.2...v2.32.3) (2025-05-08)
### Bug Fixes
* filter state resetting when removing previous condition in WhereBuilder ([#12262](https://github.com/payloadcms/payload/issues/12262)) ([a09fefa](https://github.com/payloadcms/payload/commit/a09fefaed746ff945d16f41647f1fdb32200e35e))
* **upload:** ensure only image files are read for preview ([#9562](https://github.com/payloadcms/payload/issues/9562)) ([5ecee3f](https://github.com/payloadcms/payload/commit/5ecee3f6f6cbaec06a0b48ca251a25c2993e8451)), closes [#9559](https://github.com/payloadcms/payload/issues/9559)
## [2.32.2](https://github.com/payloadcms/payload/compare/v2.32.1...v2.32.2) (2025-03-14)
- Bumps dependencies ([#11702](https://github.com/payloadcms/payload/pull/11702)) ([#11705](https://github.com/payloadcms/payload/pull/11705))
### Bug Fixes
* remove collapsible label prefix from the FieldSelect dropdown component ([#10760](https://github.com/payloadcms/payload/issues/10760)) ([a5e6ea5](https://github.com/payloadcms/payload/commit/a5e6ea57373591ec90f452ad61b376f72f9ce304)), closes [#10757](https://github.com/payloadcms/payload/issues/10757)
### Bug Fixes
* remove collapsible label prefix from the FieldSelect dropdown component ([#10760](https://github.com/payloadcms/payload/issues/10760)) ([a5e6ea5](https://github.com/payloadcms/payload/commit/a5e6ea57373591ec90f452ad61b376f72f9ce304)), closes [#10757](https://github.com/payloadcms/payload/issues/10757)
## [2.32.0](https://github.com/payloadcms/payload/compare/v2.31.0...v2.32.0) (2025-01-10)
### Features
* export CheckboxInput ([#10489](https://github.com/payloadcms/payload/issues/10489)) ([2e35255](https://github.com/payloadcms/payload/commit/2e352552d1905217acdc52f5c4a6255eb24b247c))
## [2.31.0](https://github.com/payloadcms/payload/compare/v2.30.4...v2.31.0) (2025-01-09)
### Features
* adds `forceRenderAllFields` admin prop to force all fields in edit view to render immediately ([#10464](https://github.com/payloadcms/payload/issues/10464)) ([07ff181](https://github.com/payloadcms/payload/commit/07ff181ccf5e455c97a4afa6d72bcbc173b1a76d))
* **i18n:** add Slovenian (sl) translation ([#8709](https://github.com/payloadcms/payload/issues/8709)) ([7039b1f](https://github.com/payloadcms/payload/commit/7039b1f82e323358a605f9b2165328403f8da74c))
* **v2:** allows filtering on group field types from list view ([#10421](https://github.com/payloadcms/payload/issues/10421)) ([f430db8](https://github.com/payloadcms/payload/commit/f430db8bc5853f5a444d8c2ec6626df0af2e41a4))
### Bug Fixes
* **graphql:** 500 error when querying hasMany field data that is filtered by access-control ([#6519](https://github.com/payloadcms/payload/issues/6519)) ([4892d96](https://github.com/payloadcms/payload/commit/4892d965157285964fb024516ddcdf56a74cc68e)), closes [#6518](https://github.com/payloadcms/payload/issues/6518)
* when publishing from a draft, only 10 were published. ([#7906](https://github.com/payloadcms/payload/issues/7906)) ([0cf9678](https://github.com/payloadcms/payload/commit/0cf96785bc47e2d2ef107a139d03058e99c8bb79))
## [2.30.4](https://github.com/payloadcms/payload/compare/v2.30.3...v2.30.4) (2024-11-11)

View File

@@ -34,16 +34,14 @@ const defaultPayloadAccess = ({ req: { user } }) => {
```
<Banner type="success">
<strong>Note:</strong>
<br />
**Note:**
In the Local API, all Access Control functions are skipped by default, allowing your server to do
whatever it needs. But, you can opt back in by setting the option
{' '}
<strong>
overrideAccess
</strong>
{' '}
to <strong>false</strong>.
**overrideAccess**
to **false**.
</Banner>
### Access Control Types
@@ -57,8 +55,8 @@ You can manage access within Payload on three different levels:
### When Access Control is Executed
<Banner type="success">
<strong>Note:</strong>
<br />
**Note:**
Access control functions are utilized in two places. It's important to understand how and when
your access control is executed.
</Banner>
@@ -76,10 +74,10 @@ To accomplish this, Payload ships with an `Access` operation, which is executed
### Argument Availability
<Banner type="warning">
<strong>Important:</strong>
<br />
When your access control functions are executed via the <strong>access</strong> operation, the{' '}
<strong>id</strong> and <strong>data</strong> arguments will be <strong>undefined</strong>,
**Important:**
When your access control functions are executed via the **access** operation, the{' '}
**id** and **data** arguments will be **undefined**,
because Payload is executing your functions without referencing a specific document.
</Banner>

View File

@@ -46,8 +46,8 @@ At their core, a bundler's main goal is to take a bunch of files and turn them i
Since the bundled file is sent to the browser, it can't include any server-only code. You will need to remove any server-only code from your admin UI before bundling it. You can learn more about [excluding server code](/docs/admin/excluding-server-code) section.
<Banner type="warning">
<strong>Using environment variables in the admin UI</strong>
<br />
**Using environment variables in the admin UI**
Bundles should not contain sensitive information. By default, Payload
excludes env variables from the bundle. If you need to use env variables in your payload config,
you need to prefix them with `PAYLOAD_PUBLIC_` to make them available to the client-side code.

View File

@@ -11,8 +11,8 @@ While designing the Payload Admin panel, we determined it should be as minimal a
To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
Custom components will automatically be provided with all props that the default component normally
accepts.
</Banner>
@@ -133,8 +133,8 @@ To add a _new_ view to the Admin Panel, simply add another key to the `views` ob
```
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
Routes are cascading. This means that unless explicitly given the `exact` property, they will match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all routes in your application. Alternatively, you could define your nested route _before_ your parent route.
</Banner>
@@ -451,8 +451,8 @@ Your custom view components will be given all the props that a React Router `<Ro
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the admin panel or not. |
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
It's up to you to secure your custom views. If your view requires a user to be logged in or to
have certain access rights, you should handle that within your view component yourself.
</Banner>
@@ -471,8 +471,8 @@ To see how to pass in your custom views to create custom views of your own, take
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
Don't see a built-in field type that you need? Build it! Using a combination of custom validation
and custom components, you can override the entirety of how a component functions within the admin
panel and effectively create your own field type.
@@ -546,7 +546,7 @@ const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
<Banner type="success">
For more information regarding the hooks that are available to you while you build custom
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
components, including the **useField** hook, [click here](/docs/admin/hooks).
</Banner>
## Label Component
@@ -651,7 +651,7 @@ export default titleField;
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to add your own context to any Payload app for use in other custom components within the admin panel. Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. Read the [React context](https://reactjs.org/docs/context.html) docs to learn more.
<Banner type="warning">
<strong>Reminder:</strong> Don't forget to pass the **children** prop through the provider
**Reminder:** Don't forget to pass the **children** prop through the provider
component for the admin UI to show
</Banner>

View File

@@ -8,8 +8,8 @@ desc: NEEDS TO BE WRITTEN
## Admin environment vars
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
Be careful about what variables you provide to your client-side code. Analyze every single one to
make sure that you're not accidentally leaking anything that an attacker could exploit. Only keys
that are safe for anyone to read in plain text should be provided to your Admin panel.

View File

@@ -69,8 +69,8 @@ export const createStripeSubscription = async ({ data, operation }) => {
```
<Banner type="error">
<strong>Warning:</strong>
<br />
**Warning:**
The above code is NOT production-ready and should not be referenced to create Stripe
subscriptions. Although creating a beforeChange hook is a completely valid spot to do things like
create subscriptions, the code above is incomplete and insecure, meant for explanation purposes

View File

@@ -57,7 +57,7 @@ const {
There are times when a custom field component needs to have access to data from other fields, and you have a few options to do so. The `useFormFields` hook is a powerful and highly performant way to retrieve a form's field state, as well as to retrieve the `dispatchFields` method, which can be helpful for setting other fields' form states from anywhere within a form.
<Banner type="success">
<strong>This hook is great for retrieving only certain fields from form state</strong> because it
**This hook is great for retrieving only certain fields from form state** because it
ensures that it will only cause a rerender when the items that you ask for change.
</Banner>
@@ -133,8 +133,8 @@ To see types for each action supported within the `dispatchFields` hook, check o
The `useForm` hook can be used to interact with the form itself, and sends back many methods that can be used to reactively fetch form state without causing rerenders within your components each time a field is changed. This is useful if you have action-based callbacks that your components fire, and need to interact with form state _based on a user action_.
<Banner type="warning">
<strong>Warning:</strong>
<br />
**Warning:**
This hook is optimized to avoid causing rerenders when fields change, and as such, its `fields`
property will be out of date. You should only leverage this hook if you need to perform actions
against the form in response to your users' actions. Do not rely on its returned "fields" as being
@@ -152,7 +152,7 @@ The `useForm` hook returns an object with the following properties: |
rows={[
[
{
value: <strong><code>fields</code></strong>,
value: "**`fields`**",
},
{
value: "Deprecated. This property cannot be relied on as up-to-date.",
@@ -163,7 +163,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>submit</code></strong>,
value: "**`submit`**",
},
{
value: "Method to trigger the form to submit",
@@ -174,7 +174,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>dispatchFields</code></strong>,
value: "**`dispatchFields`**",
},
{
value: "Dispatch actions to the form field state",
@@ -185,7 +185,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>validateForm</code></strong>,
value: "**`validateForm`**",
},
{
value: "Trigger a validation of the form state",
@@ -196,10 +196,10 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>createFormData</code></strong>,
value: "**`createFormData`**",
},
{
value: <>Create a <code>multipart/form-data</code> object from the current form's state</>,
value: "Create a `multipart/form-data` object from the current form's state",
},
{
value: ''
@@ -207,7 +207,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>disabled</code></strong>,
value: "**`disabled`**",
},
{
value: "Boolean denoting whether or not the form is disabled",
@@ -218,7 +218,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>getFields</code></strong>,
value: "**`getFields`**",
},
{
value: 'Gets all fields from state',
@@ -229,7 +229,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>getField</code></strong>,
value: "**`getField`**",
},
{
value: 'Gets a single field from state by path',
@@ -240,7 +240,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>getData</code></strong>,
value: "**`getData`**",
},
{
value: 'Returns the data stored in the form',
@@ -251,7 +251,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>getSiblingData</code></strong>,
value: "**`getSiblingData`**",
},
{
value: 'Returns form sibling data for the given field path',
@@ -262,10 +262,10 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>setModified</code></strong>,
value: "**`setModified`**",
},
{
value: <>Set the form\'s <code>modified</code> state</>,
value: "Set the form\'s `modified` state",
},
{
value: '',
@@ -273,10 +273,10 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>setProcessing</code></strong>,
value: "**`setProcessing`**",
},
{
value: <>Set the form\'s <code>processing</code> state</>,
value: "Set the form\'s `processing` state",
},
{
value: '',
@@ -284,10 +284,10 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>setSubmitted</code></strong>,
value: "**`setSubmitted`**",
},
{
value: <>Set the form\'s <code>submitted</code> state</>,
value: "Set the form\'s `submitted` state",
},
{
value: '',
@@ -295,7 +295,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>formRef</code></strong>,
value: "**`formRef`**",
},
{
value: 'The ref from the form HTML element',
@@ -306,7 +306,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>reset</code></strong>,
value: "**`reset`**",
},
{
value: 'Method to reset the form to its initial state',
@@ -317,7 +317,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>addFieldRow</code></strong>,
value: "**`addFieldRow`**",
},
{
value: "Method to add a row on an array or block field",
@@ -326,8 +326,7 @@ The `useForm` hook returns an object with the following properties: |
drawerTitle: 'addFieldRow',
drawerDescription: 'A useful method to programmatically add a row to an array or block field.',
drawerSlug: 'addFieldRow',
drawerContent: (
<>
drawerContent: `
<TableWithDrawers
columns={[
'Prop',
@@ -336,7 +335,7 @@ The `useForm` hook returns an object with the following properties: |
rows={[
[
{
value: <strong><code>path</code></strong>,
value: "**\\\`path\\\`**",
},
{
value: "The path to the array or block field",
@@ -344,7 +343,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>rowIndex</code></strong>,
value: "**\\\`rowIndex\\\`**",
},
{
value: "The index of the row to add. If omitted, the row will be added to the end of the array.",
@@ -352,7 +351,7 @@ The `useForm` hook returns an object with the following properties: |
],
[
{
value: <strong><code>data</code></strong>,
value: "**\\\`data\\\`**",
},
{
value: "The data to add to the row",
@@ -361,14 +360,9 @@ The `useForm` hook returns an object with the following properties: |
]}
/>
{' '}
<br />
{' '}
<pre>
{`import { useForm } from "payload/components/forms";
\`\`\`tsx
import { useForm } from "payload/components/forms";
export const CustomArrayManager = () => {
const { addFieldRow } = useForm()
@@ -391,12 +385,13 @@ export const CustomArrayManager = () => {
Add Row
</button>
)
}`}
</pre>
}
\`\`\`
<p>An example config to go along with the custom component</p>
<pre>
{`const ExampleCollection = {
An example config to go along with the Custom Component
\`\`\`tsx
const ExampleCollection = {
slug: "example-collection",
fields: [
{
@@ -414,20 +409,19 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
],
}`}
</pre>
</>
)
}
\`\`\`
`
}
],
[
{
value: <strong><code>removeFieldRow</code></strong>,
value: "**`removeFieldRow`**",
},
{
value: "Method to remove a row from an array or block field",
@@ -436,8 +430,7 @@ export const CustomArrayManager = () => {
drawerTitle: 'removeFieldRow',
drawerDescription: 'A useful method to programmatically remove a row from an array or block field.',
drawerSlug: 'removeFieldRow',
drawerContent: (
<>
drawerContent: `
<TableWithDrawers
columns={[
'Prop',
@@ -446,7 +439,7 @@ export const CustomArrayManager = () => {
rows={[
[
{
value: <strong><code>path</code></strong>,
value: "**\\\`path\\\`**",
},
{
value: "The path to the array or block field",
@@ -454,7 +447,7 @@ export const CustomArrayManager = () => {
],
[
{
value: <strong><code>rowIndex</code></strong>,
value: "**\\\`rowIndex\\\`**",
},
{
value: "The index of the row to remove",
@@ -463,14 +456,10 @@ export const CustomArrayManager = () => {
]}
/>
{' '}
<br />
{' '}
<pre>
{`import { useForm } from "payload/components/forms";
\`\`\`tsx
import { useForm } from "payload/components/forms";
export const CustomArrayManager = () => {
const { removeFieldRow } = useForm()
@@ -488,12 +477,13 @@ export const CustomArrayManager = () => {
Remove Row
</button>
)
}`}
</pre>
}
\`\`\`
<p>An example config to go along with the custom component</p>
<pre>
{`const ExampleCollection = {
An example config to go along with the Custom Component
\`\`\`tsx
const ExampleCollection = {
slug: "example-collection",
fields: [
{
@@ -511,20 +501,19 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
],
}`}
</pre>
</>
)
}
\`\`\`
`
}
],
[
{
value: <strong><code>replaceFieldRow</code></strong>,
value: "**`replaceFieldRow`**",
},
{
value: "Method to replace a row from an array or block field",
@@ -533,8 +522,7 @@ export const CustomArrayManager = () => {
drawerTitle: 'replaceFieldRow',
drawerDescription: 'A useful method to programmatically replace a row from an array or block field.',
drawerSlug: 'replaceFieldRow',
drawerContent: (
<>
drawerContent: `
<TableWithDrawers
columns={[
'Prop',
@@ -543,7 +531,7 @@ export const CustomArrayManager = () => {
rows={[
[
{
value: <strong><code>path</code></strong>,
value: "**\\\`path\\\`**",
},
{
value: "The path to the array or block field",
@@ -551,7 +539,7 @@ export const CustomArrayManager = () => {
],
[
{
value: <strong><code>rowIndex</code></strong>,
value: "**\\\`rowIndex\\\`**",
},
{
value: "The index of the row to replace",
@@ -559,7 +547,7 @@ export const CustomArrayManager = () => {
],
[
{
value: <strong><code>data</code></strong>,
value: "**\\\`data\\\`**",
},
{
value: "The data to replace within the row",
@@ -568,14 +556,11 @@ export const CustomArrayManager = () => {
]}
/>
{' '}
<br />
{' '}
<pre>
{`import { useForm } from "payload/components/forms";
\`\`\`tsx
import { useForm } from "payload/components/forms";
export const CustomArrayManager = () => {
const { replaceFieldRow } = useForm()
@@ -598,12 +583,13 @@ export const CustomArrayManager = () => {
Replace Row
</button>
)
}`}
</pre>
}
\`\`\`
<p>An example config to go along with the custom component</p>
<pre>
{`const ExampleCollection = {
An example config to go along with the Custom Component
\`\`\`tsx
const ExampleCollection = {
slug: "example-collection",
fields: [
{
@@ -621,15 +607,14 @@ export const CustomArrayManager = () => {
name: "customArrayManager",
admin: {
components: {
Field: CustomArrayManager,
Field: '/path/to/CustomArrayManagerField',
},
},
},
],
}`}
</pre>
</>
)
}
\`\`\`
`
}
],
]}

View File

@@ -51,8 +51,8 @@ All options for the Admin panel are defined in your base Payload config file.
### The Admin User Collection
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
The Payload Admin panel can only be used by one Collection that supports
[Authentication](/docs/authentication/overview).
</Banner>

View File

@@ -15,8 +15,8 @@ Out of the box, Payload handles the persistence of your users' preferences in a
1. The "collapsed" state of blocks, on a document level, as users edit or interact with documents
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
All preferences are stored on an individual user basis. Payload automatically recognizes the user
that is reading or setting a preference via all provided authentication methods.
</Banner>

View File

@@ -45,7 +45,7 @@ Here are the main differences between how Vite aliases work and how Webpack alia
**Vite aliases do not work with absolute paths.**
In Vite, alias keys must <strong>exactly match</strong> a import paths. If you have 2 files that import the same server-only module, but have different import paths, you would need to add 2 aliases to support both import paths.
In Vite, alias keys must **exactly match** a import paths. If you have 2 files that import the same server-only module, but have different import paths, you would need to add 2 aliases to support both import paths.
```ts
// File A

View File

@@ -59,8 +59,8 @@ export default buildConfig({
```
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
If changes to your Webpack aliases are not surfacing, they might be
[cached](https://webpack.js.org/configuration/cache/) in `node_modules/.cache/webpack`. Try
deleting that folder and restarting your server.

View File

@@ -46,9 +46,9 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
</Banner>
<Banner type="warning">
<strong>Important:</strong>
**Important:**
If you change your `PAYLOAD_SECRET`, you will need to regenerate your API keys.
<br />
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will no longer be valid.
</Banner>
@@ -95,8 +95,8 @@ You can customize how the Forgot Password workflow operates with the following o
Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
HTML templating can be used to create custom email templates, inline CSS automatically, and more.
You can make a reusable function that standardizes all email sent from Payload, which makes
sending custom emails more DRY. Payload doesn't ship with an HTML templating engine, so you are
@@ -138,8 +138,8 @@ export const Customers: CollectionConfig = {
```
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
If you specify a different URL to send your users to for resetting their password, such as a page
on the frontend of your app or similar, you need to handle making the call to the Payload REST or
GraphQL reset-password operation yourself on your frontend, using the token that was provided for
@@ -198,8 +198,8 @@ export const Customers: CollectionConfig = {
```
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
If you specify a different URL to send your users to for email verification, such as a page on the
frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL
verification operation yourself on your frontend, using the token that was provided for you.

View File

@@ -351,8 +351,8 @@ const token = await payload.forgotPassword({
```
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
You can stop the reset-password email from being sent via using the local API. This is helpful if
you need to create user accounts programmatically, but not set their password for them. This
effectively generates a reset password token which you can then use to send to a page you create,

View File

@@ -87,10 +87,10 @@ Successfully logging in returns a `JWT` (JSON web token) which is how a user wil
You can specify what data gets encoded to the JWT token by setting `saveToJWT` to true in your auth collection fields. If you wish to use a different key other than the field `name`, you can provide it to `saveToJWT` as a string. It is also possible to use `saveToJWT` on fields that are nested in inside groups and tabs. If a group has a `saveToJWT` set it will include the object with all sub-fields in the token. You can set `saveToJWT: false` for any fields you wish to omit. If a field inside a group has `saveToJWT` set, but the group does not, the field will be included at the top level of the token.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
You can access the logged-in user from access control functions and hooks via the Express{' '}
<strong>req</strong>. The logged-in user is automatically added as the <strong>user</strong>{' '}
**req**. The logged-in user is automatically added as the **user**
property.
</Banner>
@@ -119,8 +119,8 @@ const pages = await response.json()
For more about how to automatically include cookies in requests from your app to your Payload API, [click here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Sending_a_request_with_credentials_included).
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
To make sure you have a Payload cookie set properly in your browser after logging in, you can use
Chrome's Developer Tools - Application - Cookies - [your-domain-here]. The Chrome Developer tools
will still show HTTP-only cookies, even when JavaScript running on the page can't.
@@ -135,10 +135,10 @@ For example, let's say you have a very popular app running at coolsite.com. This
So, if a user of coolsite.com is logged in and just browsing around on the internet, they might stumble onto a page with bad intentions. That bad page might automatically make requests to all sorts of sites to see if they can find one that they can log into - and coolsite.com might be on their list. If your user was logged in while they visited that evil site, the attacker could do whatever they wanted as if they were your coolsite.com user by just sending requests to the coolsite API (which would automatically include the auth cookie). They could send themselves a bunch of money from your user's account, change the user's password, etc. This is what a CSRF attack is.
<Banner type="warning">
<strong>
**
To protect against CSRF attacks, Payload only accepts cookie-based authentication from domains
that you explicitly whitelist.
</strong>
**
</Banner>
To define domains that should allow users to identify themselves via the Payload HTTP-only cookie, use the `csrf` option on the base Payload config to whitelist domains that you trust.

View File

@@ -54,7 +54,7 @@ Any of the features in Payload Cloud that require environment variables will aut
Payment methods can be set per project and can be updated any time. You can use teams default payment method, or add a new one. Modify your payment methods in your Project settings / Team settings.
<Banner type="success">
<strong>Note:</strong> All Payload Cloud teams that deploy a project require a card on file. This
**Note:** All Payload Cloud teams that deploy a project require a card on file. This
helps us prevent fraud and abuse on our platform. If you select a plan with a free trial, you will
not be charged until your trial period is over. Well remind you 7 days before your trial ends and
you can cancel anytime.

View File

@@ -31,7 +31,7 @@ Next, select your `GitHub Scope`. If you belong to multiple organizations, they
After selecting your scope, create a unique `repository name` and select whether you want your repository to be public or private on GitHub.
<Banner type="warning">
<strong>Note:</strong> Public repositories can be accessed by anyone online, while private
**Note:** Public repositories can be accessed by anyone online, while private
repositories grant access only to you and anyone you explicitly authorize.
</Banner>
@@ -45,7 +45,7 @@ Payload Cloud works for any Node.js + MongoDB app. From the New Project page, se
_Creating a new project from an existing repository._
<Banner type="warning">
<strong>Note:</strong> In order to make use of the features of Payload Cloud in your own codebase,
**Note:** In order to make use of the features of Payload Cloud in your own codebase,
you will need to add the [Cloud Plugin](https://github.com/payloadcms/plugin-cloud) to your
Payload app.
</Banner>

View File

@@ -14,7 +14,7 @@ It's often best practice to write your Collections in separate files and then im
## Options
| Option | Description |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
@@ -70,23 +70,24 @@ Demo source code on GitHub.
You can customize the way that the Admin panel behaves on a collection-by-collection basis by defining the `admin`
property on a collection's config.
| Option | Description |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
| `description` | Text or React component to display below the Collection label in the List view to give editors more information. |
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| `enableRichTextLink` | The [Rich Text](/docs/fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](#preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) |
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More](#list-searchable-fields) |
| **`pagination`** | Set pagination-specific options for this collection. [More](#pagination) |
| Option | Description |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
| `description` | Text or React component to display below the Collection label in the List view to give editors more information. |
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
| `forceRenderAllFields ` | Forces all fields in the Edit view to render immediately, regardless of scroll position. By default, this is set to `false` to improve performance, as fields are progressively rendered to balance load times. Enabling this option can make it easier to locate fields using browser search (e.g., `CMD+F`). |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| `enableRichTextLink` | The [Rich Text](/docs/fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](#preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) |
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More](#list-searchable-fields) |
| **`pagination`** | Set pagination-specific options for this collection. [More](#pagination) |
### Preview
@@ -132,7 +133,7 @@ export const Posts: CollectionConfig = {
Here are a few options that you can specify options for pagination on a collection-by-collection basis:
| Option | Description |
|----------------|-----------------------------------------------------------------------------------------------------|
| -------------- | --------------------------------------------------------------------------------------------------- |
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List view. |
@@ -164,10 +165,11 @@ add `admin.listSearchableFields: ['title', 'metaDescription', 'tags']` - and the
those three fields plus the ID field.
<Banner type="warning">
<strong>Note:</strong>
<br />
If you are adding <strong>listSearchableFields</strong>, make sure you index each of these fields
so your admin queries can remain performant.
**Note:**
If you are adding **listSearchableFields**, make sure you index each of these fields
so your admin queries can remain performant.
</Banner>
### Admin Hooks

View File

@@ -17,7 +17,7 @@ the main Payload config.
## Options
| Option | Description |
|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Global. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Global. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`label`** | Text for the name in the Admin panel or an object with keys for each language. Auto-generated from slug if not defined. |
@@ -30,7 +30,7 @@ the main Payload config.
| **`graphQL.name`** | Text used in schema generation. Auto-generated from slug if not defined. |
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`dbName`** | Custom table or collection name for this global depending on the database adapter. Auto-generated from slug if not defined.
| **`dbName`** | Custom table or collection name for this global depending on the database adapter. Auto-generated from slug if not defined. |
_\* An asterisk denotes that a property is required._
@@ -72,14 +72,15 @@ in the Public Demo source code on GitHub.
You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a
Global's config.
| Option | Description |
|---------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| Option | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| `forceRenderAllFields ` | Forces all fields in the Edit view to render immediately, regardless of scroll position. By default, this is set to `false` to improve performance, as fields are progressively rendered to balance load times. Enabling this option can make it easier to locate fields using browser search (e.g., `CMD+F`). |
### Preview

View File

@@ -62,8 +62,8 @@ The Payload admin panel reads the language settings of a user's browser and disp
After a user logs in, they can change their language selection in the `/account` view.
<Banner>
<strong>Note:</strong>
<br />
**Note:**
If there is a language that Payload does not yet support, we accept code
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
</Banner>

View File

@@ -149,8 +149,8 @@ All field types with a `name` property support the `localized` property—even t
and `block`s.
<Banner>
<strong>Note:</strong>
<br />
**Note:**
Enabling localization for field types that support nested fields will automatically create
localized "sets" of all fields contained within the field. For example, if you have a page layout
using a blocks field type, you have the choice of either localizing the full layout, by enabling
@@ -158,8 +158,8 @@ and `block`s.
</Banner>
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
When converting an existing field to or from `localized: true` the data structure in the document
will change for this field and so existing data for this field will be lost. Before changing the
localization setting on fields with existing data, you may need to consider a field migration
@@ -235,9 +235,9 @@ const posts = await payload.find({
```
<Banner type="alert">
<strong>Tip:</strong>
<br />
**Tip:**
The REST and Local APIs can return all localization data in one request by passing 'all' or '*' as
the <strong>locale</strong> parameter. The response will be structured so that field values come
the **locale** parameter. The response will be structured so that field values come
back as the full objects keyed for each locale instead of the single, translated value.
</Banner>

View File

@@ -11,8 +11,8 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
**Also, because the Payload source code is fully written in TypeScript, its configs are strongly typed—meaning that even if you aren't using TypeScript, your IDE (such as VSCode) may still provide helpful information like type-ahead suggestions while you write your config.**
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
This file is included in the Payload admin bundle, so make sure you do not embed any sensitive
information.
</Banner>
@@ -135,8 +135,8 @@ project-name
```
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
If you use an environment variable to configure any properties that are required for the Admin
panel to function (ex. serverURL or any routes), you need to make sure that your Admin panel code
can access it. [Click here](/docs/admin/webpack#admin-environment-vars) for more info.

View File

@@ -11,8 +11,8 @@ Database transactions allow your application to make a series of database change
By default, Payload will use transactions for all operations, as long as it is supported by the configured database. Database changes are contained within all Payload operations and any errors thrown will result in all changes being rolled back without being committed. When transactions are not supported by the database, Payload will continue to operate as expected without them.
<Banner type="info">
<strong>Note:</strong>
<br />
**Note:**
MongoDB requires a connection to a replicaset in order to make use of transactions.
</Banner>

View File

@@ -7,8 +7,8 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
---
<Banner>
The Blocks field type is <strong>incredibly powerful</strong> and can be used as a{' '}
<em>layout builder</em> as well as to define any other flexible content model you can think of. It
The Blocks field type is **incredibly powerful** and can be used as a
*layout builder* as well as to define any other flexible content model you can think of. It
stores an array of objects, where each object must match the shape of one of your provided block
configs.
</Banner>
@@ -65,8 +65,8 @@ properties:
Blocks are defined as separate configs of their own.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
Best practice is to define each block config in its own file, and then import them into your
Blocks field as necessary. This way each block config can be easily shared between fields. For
instance, using the "layout builder" example, you might want to feature a few of the same blocks

View File

@@ -13,7 +13,7 @@ keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configurati
</Banner>
<Banner type="warning">
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
**Note:** The Point field type is currently only supported in MongoDB.
</Banner>
<LightDarkImage
@@ -47,7 +47,7 @@ The data structure in the database matches the GeoJSON structure to represent po
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
**Note:** The Point field type is currently only supported in MongoDB.
</Banner>
### Example

View File

@@ -41,8 +41,8 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
Option values should be strings that do not contain hyphens or special characters due to GraphQL
enumeration naming constraints. Underscores are allowed. If you determine you need your option
values to be non-strings or contain special characters, they will be formatted accordingly before

View File

@@ -52,8 +52,8 @@ caption="Admin panel screenshot of a Relationship field"
_\* An asterisk denotes that a property is required._
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
The [Depth](/docs/getting-started/concepts#depth) parameter can be used to automatically populate
related documents that are returned by the API.
</Banner>
@@ -173,12 +173,12 @@ export const ExampleCollection: CollectionConfig = {
You can learn more about writing queries [here](/docs/queries/overview).
<Banner type="warning">
<strong>Note:</strong>
<br />
When a relationship field has both <strong>filterOptions</strong> and a custom{' '}
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
**Note:**
When a relationship field has both **filterOptions** and a custom{' '}
**validate** function, the api will not validate **filterOptions**{' '}
unless you call the default relationship field validation function imported from{' '}
<strong>payload/fields/validations</strong> in your validate function.
**payload/fields/validations** in your validate function.
</Banner>
### How the data is saved
@@ -360,7 +360,7 @@ However, you **cannot** query on any field values within the related document.
Since we are referencing multiple collections, the field you are querying on may not exist and break the query.
<Banner type="warning">
<strong>Note:</strong>
<br />
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a non-polymorphic relationship.
**Note:**
You **cannot** query on a field within a polymorphic relationship as you would with a non-polymorphic relationship.
</Banner>

View File

@@ -18,7 +18,7 @@ keywords: rich text, fields, config, configuration, documentation, Content Manag
caption="Admin panel screenshot of a Rich Text field"
/>
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
Right now, Payload is officially supporting two rich text editors:
@@ -26,7 +26,7 @@ Right now, Payload is officially supporting two rich text editors:
2. [Lexical](/docs/rich-text/lexical) - beta, where things will be moving
<Banner type="success">
<strong>Consistent with Payload's goal of making you learn as little of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em> rich text editor.</strong> Instead, you can invest your time and effort into learning the underlying open-source tools that will allow you to apply your learnings elsewhere as well.
**Consistent with Payload's goal of making you learn as little of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a __Payload__ rich text editor.** Instead, you can invest your time and effort into learning the underlying open-source tools that will allow you to apply your learnings elsewhere as well.
</Banner>
### Config
@@ -67,4 +67,4 @@ Override the default text direction of the Admin panel for this field. Set to `t
### Editor-specific options
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.

View File

@@ -44,8 +44,8 @@ caption="Admin panel screenshot of a Select field"
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
Option values should be strings that do not contain hyphens or special characters due to GraphQL
enumeration naming constraints. Underscores are allowed. If you determine you need your option
values to be non-strings or contain special characters, they will be formatted accordingly before

View File

@@ -12,8 +12,8 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
</Banner>
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
To use this field, you need to have a Collection configured to allow Uploads. For more
information, [click here](/docs/upload/overview) to read about how to enable Uploads on a
collection by collection basis.
@@ -37,7 +37,7 @@ caption="Admin panel screenshot of an Upload field"
| Option | Description |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. **Note: the related collection must be configured to support Uploads.** |
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
@@ -110,10 +110,10 @@ const uploadField = {
You can learn more about writing queries [here](/docs/queries/overview).
<Banner type="warning">
<strong>Note:</strong>
<br />
When an upload field has both <strong>filterOptions</strong> and a custom{' '}
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
**Note:**
When an upload field has both **filterOptions** and a custom{' '}
**validate** function, the api will not validate **filterOptions**{' '}
unless you call the default upload field validation function imported from{' '}
<strong>payload/fields/validations</strong> in your validate function.
**payload/fields/validations** in your validate function.
</Banner>

View File

@@ -135,9 +135,9 @@ If you were to query the Posts endpoint at, say, `http://localhost:3000/api/post
}
```
Notice how the `user.author` is fully populated, but `user.author.department` is left as a document ID? That's because the User collection counted as the first level of `depth` and got populated—but then prevented any further populations from taking place.
Notice how the `post.author` is fully populated, but `post.author.department` is left as a document ID? That's because the User collection counted as the first level of `depth` and got populated—but then prevented any further populations from taking place.
To populate `user.author.department` in it's entirety you could specify `?depth=2` or _higher_.
To populate `post.author.department` in it's entirety you could specify `?depth=2` or _higher_.
```
// ?depth=2
@@ -157,8 +157,8 @@ To populate `user.author.department` in it's entirety you could specify `?depth=
```
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
When access control on collections prevents relationship fields from populating, the API response
will contain the relationship id instead of the full document.
</Banner>

View File

@@ -15,8 +15,8 @@ Payload is a headless CMS and application framework. It's meant to provide a mas
development process, but importantly, stay out of your way as your apps get more complex.
<Banner type="success">
<strong>Payload 2.0 has been released!</strong>
<br />
**Payload 2.0 has been released!**
Includes Postgres support, Live Preview, Lexical Editor, and more. <a href="/blog/payload-2-0">Read the announcement</a>.
</Banner>

View File

@@ -72,8 +72,8 @@ The above example outputs all your definitions to a file relative from your payl
#### Adding an NPM script
<Banner type="warning">
<strong>Important</strong>
<br />
**Important**
Payload needs to be able to find your config to generate your GraphQL schema.
</Banner>

View File

@@ -116,8 +116,8 @@ GraphQL Playground is enabled by default for development purposes, but disabled
You can even log in using the `login[collection-singular-label-here]` mutation to use the Playground as an authenticated user.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
To see more regarding how the above queries and mutations are used, visit your GraphQL playground
(by default at
[http://localhost:3000/api/graphql-playground](http://localhost:3000/api/graphql-playground))

View File

@@ -51,12 +51,12 @@ All field-level hooks are formatted to accept the same arguments, although some
which field hook you are utilizing.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
It's a good idea to conditionally scope your logic based on which operation is executing. For
example, if you are writing a <strong>beforeChange</strong> hook, you may want to perform
different logic based on if the current <strong>operation</strong> is <strong>create</strong> or{' '}
<strong>update</strong>.
example, if you are writing a **beforeChange** hook, you may want to perform
different logic based on if the current **operation** is **create** or
**update**.
</Banner>
#### Arguments
@@ -86,8 +86,8 @@ All field hooks can optionally modify the return value of the field before the o
optionally return the value that should be used within the field.
<Banner type="warning">
<strong>Important</strong>
<br />
**Important**
Due to GraphQL's typed nature, you should never change the type of data that you return from a
field, otherwise GraphQL will produce errors. If you need to change the shape or type of data,
reconsider Field Hooks and instead evaluate if Collection / Global hooks might suit you better.

View File

@@ -11,8 +11,8 @@ within Node, directly on your server. Here, you don't need to deal with server l
can interact directly with your database.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
The Local API is incredibly powerful when used with server-side rendering app frameworks like
NextJS. With other headless CMS, you need to request your data from third-party servers which can
add significant loading time to your server-rendered pages. With Payload, you don't have to leave
@@ -85,8 +85,8 @@ executed in.
_There are more options available on an operation by operation basis outlined below._
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
By default, all access control checks are disabled in the Local API, but you can re-enable them if
you'd like, as well as pass a specific user to run the operation with.
</Banner>

View File

@@ -191,7 +191,7 @@ formBuilder({
Each field represents a form input. To override default settings pass either a boolean value or a partial [Payload Block](https://payloadcms.com/docs/fields/blocks) _keyed to the block's slug_. See [Field Overrides](#field-overrides) for more details on how to do this.
<Banner type="info">
<strong>Note:</strong>
**Note:**
"Fields" here is in reference to the _fields to build forms with_, not to be confused with the _fields of a collection_ which are set via `formOverrides.fields`.
</Banner>
@@ -388,13 +388,13 @@ Below are some common troubleshooting tips. To help other developers, please con
## Screenshots
![screenshot 1](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-1.jpg?raw=true)
<br />
![screenshot 2](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-2.jpg?raw=true)
<br />
![screenshot 3](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-3.jpg?raw=true)
<br />
![screenshot 4](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-4.jpg?raw=true)
<br />
![screenshot 5](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-5.jpg?raw=true)
<br />
![screenshot 6](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-6.jpg?raw=true)

View File

@@ -159,8 +159,8 @@ When defined, the `breadcrumbs` field will not be provided for you, and instead,
own `breadcrumbs` field to each collection manually. Set this property to the `name` of your custom field.
<Banner type="info">
<strong>Note:</strong>
<br />
**Note:**
If you opt out of automatically being provided a `parent` or `breadcrumbs` field, you need to make sure that both fields are placed at the top-level of your document. They cannot exist within any nested data structures like a `group`, `array`, or `blocks`.
</Banner>
@@ -209,8 +209,8 @@ const examplePageConfig: CollectionConfig = {
```
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
If overriding the `name` of either `breadcrumbs` or `parent` fields, you must specify the `breadcrumbsFieldSlug` or `parentFieldSlug` respectively.
</Banner>

View File

@@ -102,8 +102,8 @@ const res = await fetch(`/api/stripe/rest`, {
```
<Banner type="info">
<strong>Note:</strong>
<br />
**Note:**
The `/api` part of these routes may be different based on the settings defined in your Payload config.
</Banner>
@@ -218,8 +218,8 @@ export const MyFunction = async () => {
This option will setup a basic sync between Payload collections and Stripe resources for you automatically. It will create all the necessary hooks and webhooks handlers, so the only thing you have to do is map your Payload fields to their corresponding Stripe properties. As documents are created, updated, and deleted from either Stripe or Payload, the changes are reflected on either side.
<Banner type="info">
<strong>Note:</strong>
<br />
**Note:**
If you wish to enable a _two-way_ sync, be sure to setup [`webhooks`](#webhooks) and pass the `stripeWebhooksEndpointSecret` through your config.
</Banner>
@@ -253,8 +253,8 @@ export default config
```
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
Due to limitations in the Stripe API, this currently only works with top-level fields. This is because every Stripe object is a separate entity, making it difficult to abstract into a simple reusable library. In the future, we may find a pattern around this. But for now, cases like that will need to be hard-coded.
</Banner>

View File

@@ -8,7 +8,7 @@ keywords: deployment, production, config, configuration, documentation, Content
<Banner type="success">
So you've developed a Payload app, it's fully tested, and running great locally. Now it's time to
launch. <strong>Awesome! Great work!</strong> Now, what's next?
launch. **Awesome! Great work!** Now, what's next?
</Banner>
There are many ways to deploy Payload to a production environment. When evaluating how you will deploy Payload, you need
@@ -44,9 +44,9 @@ Because _**you**_ are in complete control of who can do what with your data, you
wield that power responsibly before deploying to Production.
<Banner type="error">
<strong>By default, all Access Control functions require that a user is successfully logged in to Payload to create, read, update, or delete data.</strong>{' '}
**By default, all Access Control functions require that a user is successfully logged in to Payload to create, read, update, or delete data.**{' '}
But, if you allow public user registration, for example, you will want to make sure that your
access control functions are more strict - permitting <strong>only appropriate users</strong> to
access control functions are more strict - permitting **only appropriate users** to
perform appropriate actions.
</Banner>
@@ -110,8 +110,8 @@ or a similar cloud provider, you can trust them to take care of your database's
backups.
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
If versions are enabled and a collection has many documents you may need a minimum of an m10
mongoDB atlas cluster if you reach a sorting `exceeded memory limit` error to view a collection
list in the admin UI. The limitations of the m2 and m5 tier clusters are here: [Atlas M0 (Free
@@ -160,9 +160,9 @@ perpetually.
- Many other more traditional web hosts
<Banner type="error">
<strong>Warning:</strong>
<br />
If you rely on Payload's <strong>Upload</strong> functionality, make sure you either use a host
**Warning:**
If you rely on Payload's **Upload** functionality, make sure you either use a host
with a persistent filesystem or have an integration with a third-party file host like Amazon S3.
</Banner>

View File

@@ -26,13 +26,13 @@ To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate lim
| **`trustProxy`** | True or false, to enable to allow requests to pass through a proxy such as a load balancer or an `nginx` reverse proxy. |
<Banner type="warning">
<strong>Warning:</strong>
<br />
**Warning:**
Very commonly, NodeJS apps are served behind `nginx` reverse proxies and similar. If you use
rate-limiting while you're behind a proxy, <strong>all</strong> IP addresses from everyone that
rate-limiting while you're behind a proxy, **all** IP addresses from everyone that
uses your API will appear as if they are from a local origin (127.0.0.1), and your users will get
rate-limited very quickly without cause. If you plan to host your app behind a proxy, make sure
you set <strong>trustProxy</strong> to <strong>true</strong>.
you set **trustProxy** to **true**.
</Banner>
### Max Depth

View File

@@ -9,7 +9,7 @@ keywords: query, documents, overview, documentation, Content Management System,
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
<Banner>
<strong>Here, "querying" relates to filtering or searching through documents within a Collection.</strong>{' '}
**Here, "querying" relates to filtering or searching through documents within a Collection.**
You can build queries to pass to Find operations as well as to [restrict which documents certain
users can access](/docs/access-control/overview) via access control functions.
</Banner>
@@ -69,10 +69,9 @@ The above example demonstrates a simple query but you can get much more complex.
| `near` | For distance related to a [point field](/docs/fields/point) comma separated as `<longitude>, <latitude>, <maxDistance in meters (nullable)>, <minDistance in meters (nullable)>`. |
<Banner type="success">
<strong>Tip</strong>:<br />
If you know your users will be querying on certain fields a lot, you can add <strong>
index: true
</strong> to a field's config which will speed up searches using that field immensely.
**Tip**:
If you know your users will be querying on certain fields a lot, you can add **index: true**
to a field's config which will speed up searches using that field immensely.
</Banner>
### And / Or Logic

View File

@@ -47,29 +47,16 @@ Note: Collection slugs must be formatted in kebab-case
updatedAt: "2023-04-27T11:27:32.419Z",
},
},
drawerContent: (
<>
<h6>Additional <code>find</code> query parameters</h6>
The <code>find</code> endpoint supports the following additional query parameters:
<ul>
<li>
<a href="/docs/queries/overview#sort">sort</a> - sort by field
</li>
<li>
<a href="/docs/queries/overview">where</a> - pass a where query to constrain returned
documents
</li>
<li>
<a href="/docs/queries/pagination#pagination-controls">limit</a> - limit the returned
documents to a certain number
</li>
<li>
<a href="/docs/queries/pagination#pagination-controls">page</a> - get a specific page of
documents
</li>
</ul>
</>
),
drawerContent: `
#### Additional \`find\` query parameters
The \`find\` endpoint supports the following additional query parameters:
- [sort](/docs/queries/overview#sort) - sort by field
- [where](/docs/queries/overview) - pass a where query to constrain returned documents
- [limit](/docs/queries/pagination#pagination-controls) - limit the returned documents to a certain number
- [page](/docs/queries/pagination#pagination-controls) - get a specific page of documents
`
},
},
{
@@ -613,8 +600,8 @@ export const Orders: CollectionConfig = {
```
<Banner>
<strong>Note:</strong>
<br />
**Note:**
**req** will have the **payload** object and can be used inside your endpoint handlers for making
calls like req.payload.find() that will make use of access control and hooks.
</Banner>

View File

@@ -374,8 +374,8 @@ Functions prefixed with a `$` can only be run inside of an `editor.update()` or
This has been taken from the [lexical serialization & deserialization docs](https://lexical.dev/docs/concepts/serialization#html---lexical).
<Banner type="success">
<strong>Note:</strong>
<br />
**Note:**
Using the <code>discrete: true</code> flag ensures instant updates to the editor state. If immediate reading of the updated state isn't necessary, you can omit the flag.
</Banner>

View File

@@ -124,12 +124,12 @@ The built-in `relationship` element is a powerful way to reference other Documen
Similar to the `relationship` element, the `upload` element is a user-friendly way to reference [Upload-enabled collections](/docs/upload/overview) with a UI specifically designed for media / image-based uploads.
<Banner type="success">
<strong>Tip:</strong>
<br />
**Tip:**
Collections are automatically allowed to be selected within the Rich Text relationship and upload
elements by default. If you want to disable a collection from being able to be referenced in Rich
Text fields, set the collection admin options of <strong>enableRichTextLink</strong> and{' '}
<strong>enableRichTextRelationship</strong> to false.
Text fields, set the collection admin options of **enableRichTextLink** and
**enableRichTextRelationship** to false.
</Banner>
Relationship and Upload elements are populated dynamically into your Rich Text field' content. Within the REST and Local APIs, any present RichText `relationship` or `upload` elements will respect the `depth` option that you pass, and will be populated accordingly. In GraphQL, each `richText` field accepts an argument of `depth` for you to utilize.
@@ -271,7 +271,7 @@ const serialize = (children) =>
}
if (node.text === '') {
text = <br />;
text = ;
}
// Handle other leaf types here...
@@ -311,8 +311,8 @@ const serialize = (children) =>
```
<Banner>
<strong>Note:</strong>
<br />
**Note:**
The above example is for how to render to JSX, although for plain HTML the pattern is similar.
Just remove the JSX and return HTML strings instead!
</Banner>

View File

@@ -162,8 +162,8 @@ export interface Collection1 {
```
<Banner type="warning">
<strong>Naming Collisions</strong>
<br />
**Naming Collisions**
Since these types are hoisted to the top level, you need to be aware that naming collisions can
occur. For example, if you have a collection with the name of `Meta` and you also create a
interface with the name `Meta` they will collide. It is recommended to scope your interfaces by
@@ -177,8 +177,8 @@ Now that your types have been generated, payloads local API will now be typed. I
#### Adding an NPM script
<Banner type="warning">
<strong>Important</strong>
<br />
**Important**
Payload needs to be able to find your config to generate your types.
</Banner>

View File

@@ -32,10 +32,10 @@ _Admin panel screenshot depicting a Media Collection with Upload enabled_
Every Payload Collection can opt-in to supporting Uploads by specifying the `upload` property on the Collection's config to either `true` or to an object containing `upload` options.
<Banner type="success">
<strong>Tip:</strong>
<br />A common pattern is to create a <strong>Media</strong> collection and enable <strong>
upload
</strong> on that collection.
**Tip:**
A common pattern is to create a **Media** collection and enable
**upload**
on that collection.
</Banner>
### Collection Upload Options
@@ -162,8 +162,8 @@ When an uploaded image is smaller than the defined image size, we have 3 options
3. `true`: if the image is smaller than the image size, return the original image
<Banner type="error">
<strong>Note:</strong>
<br />
**Note:**
By default, the image size will return NULL when the uploaded image is smaller than the defined image size.
Use the `withoutEnlargement` prop to change this.
</Banner>
@@ -199,12 +199,12 @@ If no resizing options are specified (`imageSizes` or `resizeOptions`), the foca
If you are using a plugin to send your files off to a third-party file storage host or CDN, like Amazon S3 or similar, you may not want to store your files locally at all. You can prevent Payload from writing files to disk by specifying `disableLocalStorage: true` on your collection's upload config.
<Banner type="warning">
<strong>Note:</strong>
<br />
**Note:**
This is a fairly advanced feature. If you do disable local file storage, by default, your admin
panel's thumbnails will be broken as you will not have stored a file. It will be totally up to you
to use either a plugin or your own hooks to store your files in a permanent manner, as well as
provide your own admin thumbnail using <strong>upload.adminThumbnail</strong>.
provide your own admin thumbnail using **upload.adminThumbnail**.
</Banner>
### Admin Thumbnails
@@ -236,8 +236,8 @@ export const Media: CollectionConfig = {
```
<Banner>
<strong>Note:</strong>
<br />
**Note:**
This function runs in the browser. If your function returns `null` or `false` Payload will show
the default generic file thumbnail instead.
</Banner>
@@ -266,8 +266,8 @@ export const Media: CollectionConfig = {
### Uploading Files
<Banner type="warning">
<strong>Important:</strong>
<br />
**Important:**
Uploading files is currently only possible through the REST and Local APIs due to how GraphQL
works. It's difficult and fairly nonsensical to support uploading files through GraphQL.
</Banner>

View File

@@ -70,6 +70,6 @@ If we created a new version for each autosave, you'd quickly find a ton of autos
<Banner type="success">
Instead of creating a new version each time a document is autosaved, Payload smartly only creates{' '}
<strong>one</strong> autosave version, and then updates that specific version with each autosave
**one** autosave version, and then updates that specific version with each autosave
performed. This makes sure that your versions remain nice and tidy.
</Banner>

View File

@@ -26,16 +26,16 @@ Collections and Globals both support the same options for configuring drafts. Yo
### Database changes
By enabling drafts on a collection or a global, Payload will <strong>automatically inject a new field into your schema</strong> called `_status`. The `_status` field is used internally by Payload to store if a document is set to `draft` or `published`.
By enabling drafts on a collection or a global, Payload will **automatically inject a new field into your schema** called `_status`. The `_status` field is used internally by Payload to store if a document is set to `draft` or `published`.
**Admin UI status indication**
Within the Admin UI, if drafts are enabled, a document can be shown with one of three "statuses":
1. <strong>Draft</strong> - if a document has never been published, and only draft versions of the document
1. **Draft** - if a document has never been published, and only draft versions of the document
are present
1. <strong>Published</strong> - if a document is published and there are no newer drafts available
1. <strong>Changed</strong> - if a document has been published, but there are newer drafts available
1. **Published** - if a document is published and there are no newer drafts available
1. **Changed** - if a document has been published, but there are newer drafts available
and not yet published
### Draft API
@@ -48,7 +48,7 @@ Within the Admin UI, if drafts are enabled, a document can be shown with one of
##### Updating or creating drafts
If you enable drafts on a collection or global, the `create` and `update` operations for REST, GraphQL, and Local APIs expose a new option called `draft` which allows you to specify if you are creating or updating a <strong>draft</strong>, or if you're just sending your changes straight to the published document. For example, if you pass the query parameter `?draft=true` to a REST `create` or `update` operation, your action will be treated as if you are creating a `draft` and not a published document. By default, the `draft` argument is set to `false`.
If you enable drafts on a collection or global, the `create` and `update` operations for REST, GraphQL, and Local APIs expose a new option called `draft` which allows you to specify if you are creating or updating a **draft**, or if you're just sending your changes straight to the published document. For example, if you pass the query parameter `?draft=true` to a REST `create` or `update` operation, your action will be treated as if you are creating a `draft` and not a published document. By default, the `draft` argument is set to `false`.
**Required fields**
@@ -58,9 +58,9 @@ If `draft` is enabled while creating or updating a document, all fields are cons
In addition to the `draft` argument within `create` and `update` operations, a `draft` argument is also exposed for `find` and `findByID` operations.
If `draft` is set to `true` while reading a document, <strong>Payload will automatically replace returned document(s) with their newest drafts</strong> if any newer drafts are available.
If `draft` is set to `true` while reading a document, **Payload will automatically replace returned document(s) with their newest drafts** if any newer drafts are available.
<strong>For example, let's take the following scenario:</strong>
**For example, let's take the following scenario:**
1. You create a new collection document and publish it right away
1. You then make some updates, and save the updates as a draft
@@ -75,7 +75,7 @@ But, if you specify `draft` as `true`, Payload will automatically replace your p
### Controlling who can see Collection drafts
<Banner type="warning">
If you're using the <strong>drafts</strong> feature, it's important for you to consider who can
If you're using the **drafts** feature, it's important for you to consider who can
view your drafts, and who can view only published documents. Luckily, Payload makes this extremely
simple and puts the power completely in your hands.
</Banner>
@@ -115,15 +115,15 @@ export const Pages: CollectionConfig = {
```
<Banner type="warning">
<strong>Note regarding adding versions to an existing collection</strong>
<br />
**Note regarding adding versions to an existing collection**
If you already have a collection with documents, and you <em>opt in</em> to draft functionality
after you have already created existing documents, all of your old documents{' '}
<em>will not have a _status field</em> until you resave them. For this reason, if you are{' '}
<em>adding</em> versions into an existing collection, you might want to write your access control
function to allow for users to read both documents where{' '}
<strong>_status is equal to "published"</strong> as well as where{' '}
<strong>_status does not exist</strong>.
**_status is equal to "published"** as well as where{' '}
**_status does not exist**.
</Banner>
Here is an example for how to write an access control function that grants access to both documents where `_status` is equal to "published" and where `_status` does not exist:

View File

@@ -28,7 +28,7 @@
"script:release": "tsx ./scripts/release.ts",
"test": "pnpm test:int && pnpm test:components && pnpm test:e2e",
"test:components": "cross-env jest --config=jest.components.config.js",
"test:e2e": "npx playwright install --with-deps chromium && ts-node -T ./test/runE2E.ts",
"test:e2e": "ts-node -T ./test/runE2E.ts",
"test:e2e:debug": "cross-env PWDEBUG=1 DISABLE_LOGGING=true playwright test",
"test:e2e:headed": "cross-env DISABLE_LOGGING=true playwright test --headed",
"test:int:postgres": "cross-env PAYLOAD_DATABASE=postgres DISABLE_LOGGING=true jest --forceExit --detectOpenHandles",
@@ -38,7 +38,7 @@
"devDependencies": {
"@aws-sdk/client-s3": "^3.142.0",
"@payloadcms/eslint-config": "workspace:*",
"@playwright/test": "1.40.1",
"@playwright/test": "1.50.0",
"@swc/cli": "0.1.65",
"@swc/jest": "0.2.29",
"@swc/register": "0.1.10",
@@ -69,7 +69,7 @@
"cross-env": "7.0.3",
"dotenv": "8.6.0",
"drizzle-orm": "0.32.1",
"express": "4.18.2",
"express": "4.21.2",
"form-data": "3.0.1",
"fs-extra": "10.1.0",
"get-port": "5.1.1",
@@ -87,6 +87,7 @@
"mongodb-memory-server": "^9",
"node-fetch": "2.6.12",
"nodemon": "3.0.3",
"playwright": "1.50.0",
"prettier": "^3.0.3",
"prompts": "2.4.2",
"qs": "6.11.2",
@@ -115,7 +116,26 @@
"dotenv": "$dotenv",
"drizzle-orm": "$drizzle-orm",
"ts-node": "$ts-node",
"typescript": "$typescript"
"typescript": "$typescript",
"braces@<3.0.3": "^3.0.3",
"ws@>=8.0.0 <8.17.1": "^8.17.1",
"ws@>=7.0.0 <7.5.10": "^7.5.10",
"micromatch@<4.0.8": "^4.0.8",
"vite@>=4.0.0 <4.5.4": "^4.5.4",
"vite@>=4.0.0 <=4.5.3": "^4.5.4",
"rollup@>=3.0.0 <3.29.5": "^3.29.5",
"@sentry/browser@<7.119.1": "^7.119.1",
"send@<0.19.0": "^0.19.0",
"serve-static@<1.16.0": "^1.16.0",
"cross-spawn@<6.0.6": "^6.0.6",
"cross-spawn@>=7.0.0 <7.0.5": "^7.0.5",
"nanoid@<3.3.8": "^3.3.8",
"path-to-regexp@>=0.2.0 <1.9.0": "^1.9.0",
"esbuild@<=0.24.2": "^0.25.0",
"vite@<=4.5.5": "^4.5.6",
"prismjs@<1.30.0": "^1.30.0",
"@babel/runtime@<7.26.10": "^7.26.10",
"@babel/helpers@<7.26.10": "^7.26.10"
}
},
"engines": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/bundler-vite",
"version": "0.1.7",
"version": "0.1.9",
"description": "The officially supported Vite bundler adapter for Payload",
"repository": {
"type": "git",
@@ -26,7 +26,7 @@
"prepublishOnly": "pnpm clean && pnpm build"
},
"dependencies": {
"@rollup/plugin-image": "^3.0.2",
"@rollup/plugin-image": "^3.0.3",
"@vitejs/plugin-react": "^4.0.4",
"compression": "1.7.4",
"connect-history-api-fallback": "1.6.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/bundler-webpack",
"version": "1.0.7",
"version": "1.0.9",
"description": "The officially supported Webpack bundler adapter for Payload",
"repository": {
"type": "git",
@@ -43,7 +43,7 @@
"swc-minify-webpack-plugin": "^2.1.3",
"terser-webpack-plugin": "^5.3.10",
"url-loader": "4.1.1",
"webpack": "^5.78.0",
"webpack": "5.91.0",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^4.10.0",
"webpack-dev-middleware": "6.1.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-mongodb",
"version": "1.7.3",
"version": "1.7.5",
"description": "The officially supported MongoDB database adapter for Payload",
"repository": {
"type": "git",
@@ -28,7 +28,7 @@
"deepmerge": "4.3.1",
"get-port": "5.1.1",
"http-status": "1.6.2",
"mongoose": "6.12.3",
"mongoose": "6.13.8",
"mongoose-aggregate-paginate-v2": "1.0.6",
"mongoose-paginate-v2": "1.7.22",
"prompts": "2.4.2",
@@ -37,7 +37,7 @@
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
"@types/mongoose-aggregate-paginate-v2": "1.0.9",
"mongodb": "4.17.1",
"mongodb": "4.17.2",
"mongodb-memory-server": "^9",
"payload": "workspace:*"
},

View File

@@ -19,19 +19,19 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@types/eslint": "8.44.2",
"@typescript-eslint/eslint-plugin": "6.6.0",
"@typescript-eslint/parser": "6.6.0",
"eslint": "8.48.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-jest": "27.2.3",
"eslint-plugin-jest-dom": "5.1.0",
"eslint-plugin-jsx-a11y": "6.7.1",
"@types/eslint": "8.56.12",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"eslint": "8.57.1",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-jest-dom": "5.5.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-perfectionist": "2.0.0",
"eslint-plugin-playwright": "0.16.0",
"eslint-plugin-react": "7.33.2",
"eslint-plugin-perfectionist": "2.11.0",
"eslint-plugin-playwright": "0.22.2",
"eslint-plugin-react": "7.37.4",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-regexp": "1.15.0"
},

View File

@@ -1,6 +1,6 @@
{
"name": "payload",
"version": "2.30.4",
"version": "2.32.3",
"description": "Node, React and MongoDB Headless CMS and Application Framework",
"license": "MIT",
"main": "./dist/index.js",
@@ -45,10 +45,6 @@
"lint": "eslint \"src/**/*.ts\"",
"prepublishOnly": "pnpm clean && pnpm build",
"pretest": "pnpm build",
"release:beta": "release-it pre --preReleaseId=beta --npm.tag=beta --config .release-it.pre.js",
"release:major": "release-it major",
"release:minor": "release-it minor",
"release:patch": "release-it patch",
"translateNewKeys": "ts-node -T ./scripts/translateNewKeys.ts"
},
"dependencies": {
@@ -73,7 +69,7 @@
"deep-equal": "2.2.3",
"deepmerge": "4.3.1",
"dotenv": "8.6.0",
"express": "4.21.0",
"express": "4.21.2",
"express-fileupload": "1.4.0",
"express-rate-limit": "5.5.1",
"file-type": "16.5.4",
@@ -117,7 +113,6 @@
"probe-image-size": "6.0.0",
"process": "0.11.10",
"qs": "6.11.2",
"qs-middleware": "1.0.3",
"react": "^18.0.0",
"react-animate-height": "2.1.2",
"react-datepicker": "4.16.0",
@@ -143,7 +138,6 @@
},
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
"@release-it/conventional-changelog": "7.0.0",
"@types/asap": "2.0.0",
"@types/body-parser": "1.19.5",
"@types/body-scroll-lock": "^3.1.0",
@@ -198,7 +192,6 @@
"passport-strategy": "1.0.0",
"postcss-loader": "6.2.1",
"postcss-preset-env": "9.0.0",
"release-it": "16.1.3",
"rimraf": "4.4.1",
"sass-loader": "12.6.0",
"serve-static": "1.15.0",
@@ -207,7 +200,7 @@
"terser-webpack-plugin": "^5.3.10",
"url-loader": "4.1.1",
"vite": "^4.4.9",
"webpack": "^5.78.0"
"webpack": "5.91.0"
},
"resolutions": {
"ajv": "8.14.0",

View File

@@ -7,10 +7,10 @@ import type { FieldTypes } from '../../forms/field-types'
import RenderFields from '../../forms/RenderFields'
import { filterFields } from '../../forms/RenderFields/filterFields'
import { useOperation } from '../../utilities/OperationProvider'
import { Gutter } from '../Gutter'
import ViewDescription from '../ViewDescription'
import './index.scss'
import { useOperation } from '../../utilities/OperationProvider'
const baseClass = 'document-fields'
@@ -20,6 +20,7 @@ export const DocumentFields: React.FC<{
description?: Description
fieldTypes: FieldTypes
fields: FieldWithPath[]
forceRenderAllFields?: boolean
forceSidebarWrap?: boolean
hasSavePermission: boolean
permissions: CollectionPermission | GlobalPermission
@@ -30,6 +31,7 @@ export const DocumentFields: React.FC<{
description,
fieldTypes,
fields,
forceRenderAllFields,
forceSidebarWrap,
hasSavePermission,
permissions,
@@ -41,9 +43,9 @@ export const DocumentFields: React.FC<{
fieldSchema: fields,
fieldTypes,
filter: (field) => field?.admin?.position === 'sidebar',
operation,
permissions: permissions.fields,
readOnly: !hasSavePermission,
operation,
})
const hasSidebarFields = sidebarFields && sidebarFields.length > 0
@@ -77,6 +79,7 @@ export const DocumentFields: React.FC<{
!field.admin.position ||
(field.admin.position && field.admin.position !== 'sidebar')
}
forceRenderAllFields={forceRenderAllFields}
permissions={permissions.fields}
readOnly={!hasSavePermission}
/>
@@ -90,6 +93,7 @@ export const DocumentFields: React.FC<{
<RenderFields
fieldTypes={fieldTypes}
fields={sidebarFields}
forceRenderAllFields={forceRenderAllFields}
permissions={permissions.fields}
readOnly={!hasSavePermission}
/>

View File

@@ -18,7 +18,7 @@ type Props = {
setSelected: (fields: FieldWithPath[]) => void
}
const combineLabel = (prefix, field, i18n): string =>
export const combineLabel = (prefix, field, i18n): string =>
`${prefix === '' ? '' : `${prefix} > `}${getTranslation(field.label || field.name, i18n) || ''}`
const reduceFields = (
fields: Field[],
@@ -38,6 +38,9 @@ const reduceFields = (
) {
return fieldsToUse
}
if (field.type === 'collapsible') {
return [...fieldsToUse, ...reduceFields(field.fields, i18n, path, labelPrefix)]
}
if (!(field.type === 'array' || field.type === 'blocks') && fieldHasSubFields(field)) {
return [
...fieldsToUse,

View File

@@ -122,7 +122,7 @@ const Condition: React.FC<Props> = (props) => {
onChange: setInternalValue,
operator: operatorValue,
options: valueOptions,
value: internalValue,
value: internalValue ?? '',
}}
/>
</div>

View File

@@ -3,27 +3,101 @@ import React, { useReducer, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useHistory } from 'react-router-dom'
import type { Field } from '../../../../exports/types'
import type { Where } from '../../../../types'
import type { Props } from './types'
import { tabHasName } from '../../../../exports/types'
import flattenTopLevelFields from '../../../../utilities/flattenTopLevelFields'
import { getTranslation } from '../../../../utilities/getTranslation'
import useThrottledEffect from '../../../hooks/useThrottledEffect'
import { createNestedFieldPath } from '../../forms/Form/createNestedFieldPath'
import { useSearchParams } from '../../utilities/SearchParams'
import Button from '../Button'
import { combineLabel } from '../FieldSelect'
import Condition from './Condition'
import fieldTypes from './field-types'
import './index.scss'
import reducer from './reducer'
import { transformWhereQuery } from './transformWhereQuery'
import validateWhereQuery from './validateWhereQuery'
const baseClass = 'where-builder'
const reduceFields = (fields, i18n) =>
export type ReduceClientFieldsArgs = {
fields: Field[]
i18n: any
labelPrefix?: string
pathPrefix?: string
}
const reduceFields = (fields, i18n, labelPrefix, pathPrefix) =>
flattenTopLevelFields(fields).reduce((reduced, field) => {
let operators = []
if (field.admin && 'disableListFilter' in field.admin && field.admin?.disableListFilter)
return reduced
if (field.type === 'group' && 'fields' in field) {
const translatedLabel = getTranslation(field.label || '', i18n)
const labelWithPrefix = labelPrefix
? translatedLabel
? labelPrefix + ' > ' + translatedLabel
: labelPrefix
: translatedLabel
const pathWithPrefix = field.name
? pathPrefix
? pathPrefix + '.' + field.name
: field.name
: pathPrefix
reduced.push(...reduceFields(field.fields, i18n, labelWithPrefix, pathWithPrefix))
return reduced
}
if (field.type === 'tab' && 'tabs' in field) {
const tabs = field.tabs as Array<any>
tabs.forEach((tab) => {
if (typeof tab.label !== 'boolean') {
const localizedTabLabel = getTranslation(tab.label, i18n)
const labelWithPrefix = labelPrefix
? labelPrefix + ' > ' + localizedTabLabel
: localizedTabLabel
const tabPathPrefix =
tabHasName(tab) && tab.name
? pathPrefix
? pathPrefix + '.' + tab.name
: tab.name
: pathPrefix
if (typeof localizedTabLabel === 'string') {
reduced.push(...reduceFields(tab.fields, i18n, labelWithPrefix, tabPathPrefix))
}
}
})
return reduced
}
if ((field.type as string) === 'row' && 'fields' in field) {
reduced.push(...reduceFields(field.fields, i18n, labelPrefix, pathPrefix))
return reduced
}
if ((field.type as string) === 'collapsible' && 'fields' in field) {
const localizedTabLabel = getTranslation(field.label || '', i18n)
const labelWithPrefix = labelPrefix
? labelPrefix + ' > ' + localizedTabLabel
: localizedTabLabel
reduced.push(...reduceFields(field.fields, i18n, labelWithPrefix, pathPrefix))
return reduced
}
if (typeof fieldTypes[field.type] === 'object') {
if (typeof fieldTypes[field.type].operators === 'function') {
operators = fieldTypes[field.type].operators(
@@ -48,9 +122,17 @@ const reduceFields = (fields, i18n) =>
return acc
}, [])
const localizedLabel = getTranslation(field.label || field.name, i18n)
const formattedLabel = labelPrefix ? combineLabel(labelPrefix, field, i18n) : localizedLabel
const formattedValue = pathPrefix
? createNestedFieldPath(pathPrefix, field as Field)
: field.name
const formattedField = {
label: getTranslation(field.label || field.name, i18n),
value: field.name,
label: formattedLabel,
value: formattedValue,
...fieldTypes[field.type],
operators: reducedOperators,
props: {
@@ -58,10 +140,8 @@ const reduceFields = (fields, i18n) =>
},
}
if (field.admin && 'disableListFilter' in field.admin && field.admin?.disableListFilter)
return reduced
return [...reduced, formattedField]
reduced.push(formattedField)
return reduced
}
return reduced
@@ -104,7 +184,7 @@ const WhereBuilder: React.FC<Props> = (props) => {
return []
})
const [reducedFields] = useState(() => reduceFields(collection.fields, i18n))
const [reducedFields] = useState(() => reduceFields(collection.fields, i18n, null, null))
// This handles updating the search query (URL) when the where conditions change
useThrottledEffect(
@@ -193,19 +273,26 @@ const WhereBuilder: React.FC<Props> = (props) => {
{orIndex !== 0 && <div className={`${baseClass}__label`}>{t('or')}</div>}
<ul className={`${baseClass}__and-filters`}>
{Array.isArray(or?.and) &&
or.and.map((_, andIndex) => (
<li key={andIndex}>
{andIndex !== 0 && <div className={`${baseClass}__label`}>{t('and')}</div>}
<Condition
andIndex={andIndex}
dispatch={dispatchConditions}
fields={reducedFields}
key={andIndex}
orIndex={orIndex}
value={conditions[orIndex].and[andIndex]}
/>
</li>
))}
or.and.map((_, andIndex) => {
const condition = conditions[orIndex].and[andIndex]
const fieldName = Object.keys(condition)[0]
const operator = Object.keys(condition?.[fieldName] || {})?.[0]
return (
<li key={andIndex}>
{andIndex !== 0 && (
<div className={`${baseClass}__label`}>{t('and')}</div>
)}
<Condition
andIndex={andIndex}
dispatch={dispatchConditions}
fields={reducedFields}
key={`${fieldName}-${operator}-${andIndex}-${orIndex}`}
orIndex={orIndex}
value={condition}
/>
</li>
)
})}
</ul>
</li>
))}

View File

@@ -33,15 +33,21 @@ const intersectionObserverOptions = {
* All this component does is render the field's Field Components, and pass them the props they need to function.
**/
const RenderFields: React.FC<Props> = (props) => {
const { className, fieldTypes, forceRender, margins } = props
const {
className,
fieldTypes,
forceRender: forceRenderFromProps,
forceRenderAllFields,
margins,
} = props
const { i18n, t } = useTranslation('general')
const [hasRendered, setHasRendered] = useState(Boolean(forceRender))
const [intersectionRef, entry] = useIntersect(intersectionObserverOptions, forceRender)
const [hasRendered, setHasRendered] = useState(Boolean(forceRenderFromProps))
const [intersectionRef, entry] = useIntersect(intersectionObserverOptions, forceRenderFromProps)
const isIntersecting = Boolean(entry?.isIntersecting)
const isAboveViewport = entry?.boundingClientRect?.top < 0
const shouldRender = forceRender || isIntersecting || isAboveViewport
const shouldRender = forceRenderFromProps || isIntersecting || isAboveViewport
const operation = useOperation()
useEffect(() => {
@@ -105,7 +111,7 @@ const RenderFields: React.FC<Props> = (props) => {
readOnly,
},
fieldTypes,
forceRender,
forceRender: forceRenderAllFields || forceRenderFromProps,
indexPath:
'indexPath' in props ? `${props?.indexPath}.${fieldIndex}` : `${fieldIndex}`,
path: field.path || (isFieldAffectingData && 'name' in field ? field.name : ''),

View File

@@ -7,6 +7,7 @@ export type Props = {
className?: string
fieldTypes: FieldTypes
forceRender?: boolean
forceRenderAllFields?: boolean
margins?: 'small' | false
permissions?:
| {

View File

@@ -42,7 +42,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
duplicateRow,
fieldTypes,
fields,
forceRender = false,
forceRender,
hasMaxRows,
indexPath,
isSortable,

View File

@@ -118,7 +118,7 @@ const BlocksField: React.FC<Props> = (props) => {
const duplicateRow = useCallback(
(rowIndex: number) => {
dispatchFields({ path, rowIndex, type: 'DUPLICATE_ROW' })
dispatchFields({ type: 'DUPLICATE_ROW', path, rowIndex })
setModified(true)
setTimeout(() => {
@@ -138,7 +138,7 @@ const BlocksField: React.FC<Props> = (props) => {
const moveRow = useCallback(
(moveFromIndex: number, moveToIndex: number) => {
dispatchFields({ moveFromIndex, moveToIndex, path, type: 'MOVE_ROW' })
dispatchFields({ type: 'MOVE_ROW', moveFromIndex, moveToIndex, path })
setModified(true)
},
[dispatchFields, path, setModified],
@@ -146,14 +146,14 @@ const BlocksField: React.FC<Props> = (props) => {
const toggleCollapseAll = useCallback(
(collapsed: boolean) => {
dispatchFields({ collapsed, path, setDocFieldPreferences, type: 'SET_ALL_ROWS_COLLAPSED' })
dispatchFields({ type: 'SET_ALL_ROWS_COLLAPSED', collapsed, path, setDocFieldPreferences })
},
[dispatchFields, path, setDocFieldPreferences],
)
const setCollapse = useCallback(
(rowID: string, collapsed: boolean) => {
dispatchFields({ collapsed, path, rowID, setDocFieldPreferences, type: 'SET_ROW_COLLAPSED' })
dispatchFields({ type: 'SET_ROW_COLLAPSED', collapsed, path, rowID, setDocFieldPreferences })
},
[dispatchFields, path, setDocFieldPreferences],
)

View File

@@ -24,6 +24,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
admin: { className, description, initCollapsed, readOnly },
fieldTypes,
fields,
forceRender = false,
indexPath,
label,
path,
@@ -125,7 +126,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
path: createNestedFieldPath(path, field),
}))}
fieldTypes={fieldTypes}
forceRender
forceRender={forceRender}
indexPath={indexPath}
margins="small"
permissions={permissions}

View File

@@ -4,6 +4,7 @@ import type { CollapsibleField } from '../../../../../fields/config/types'
export type Props = Omit<CollapsibleField, 'type'> & {
fieldTypes: FieldTypes
forceRender?: boolean
indexPath: string
path?: string
permissions: FieldPermissions

View File

@@ -19,7 +19,7 @@ export const ConfigProvider: React.FC<{ children: React.ReactNode; config: Sanit
const resolvedConfig = await incomingConfig
setConfig(resolvedConfig)
}
awaitConfig()
void awaitConfig()
}
}, [incomingConfig])

View File

@@ -19,7 +19,7 @@ export const DefaultGlobalEdit: React.FC<
const { apiURL, data, fieldTypes, global, permissions } = props
const { i18n } = useTranslation()
const { admin: { description } = {}, fields, label } = global
const { admin: { description, forceRenderAllFields } = {}, fields, label } = global
const hasSavePermission = permissions?.update?.permission
@@ -44,6 +44,7 @@ export const DefaultGlobalEdit: React.FC<
description={description}
fieldTypes={fieldTypes}
fields={fields}
forceRenderAllFields={forceRenderAllFields}
hasSavePermission={hasSavePermission}
permissions={permissions}
/>

View File

@@ -122,6 +122,11 @@ const PreviewView: React.FC<
description={description}
fieldTypes={fieldTypes}
fields={fields}
forceRenderAllFields={
collection?.admin?.forceRenderAllFields ??
global?.admin?.forceRenderAllFields ??
false
}
forceSidebarWrap
hasSavePermission={hasSavePermission}
permissions={permissions}

View File

@@ -39,7 +39,7 @@ export const DefaultCollectionEdit: React.FC<
permissions,
} = props
const { auth, upload } = collection
const { admin: { forceRenderAllFields } = {}, auth, upload } = collection
const [fields] = useState(() => formatFields(collection, isEditing))
@@ -92,6 +92,7 @@ export const DefaultCollectionEdit: React.FC<
}
fieldTypes={fieldTypes}
fields={fields}
forceRenderAllFields={forceRenderAllFields}
hasSavePermission={hasSavePermission}
permissions={permissions}
/>

View File

@@ -74,7 +74,7 @@ export const Upload: React.FC<Props> = (props) => {
const handleFileChange = useCallback(
(newFile: File) => {
if (newFile instanceof File) {
if (newFile instanceof File && isImage(newFile.type)) {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const imgSrc = e.target?.result

View File

@@ -62,6 +62,7 @@ const collectionSchema = joi.object().keys({
disableDuplicate: joi.bool(),
enableRichTextLink: joi.boolean(),
enableRichTextRelationship: joi.boolean(),
forceRenderAllFields: joi.boolean(),
group: joi.alternatives().try(joi.string(), joi.object().pattern(joi.string(), [joi.string()])),
hidden: joi.alternatives().try(joi.boolean(), joi.func()),
hideAPIURL: joi.bool(),

View File

@@ -317,6 +317,11 @@ export type CollectionAdminOptions = {
disableDuplicate?: boolean
enableRichTextLink?: boolean
enableRichTextRelationship?: boolean
/**
* Forces all fields in the Edit view to render immediately, regardless of scroll position
* @default false
*/
forceRenderAllFields?: boolean
/**
* Place collections into a navigational group
* */

View File

@@ -130,6 +130,7 @@ async function update<TSlug extends keyof GeneratedTypes['collections']>(
const query = await payload.db.queryDrafts<GeneratedTypes['collections'][TSlug]>({
collection: collectionConfig.slug,
limit: 0,
locale,
req,
where: versionsWhere,

View File

@@ -31,6 +31,7 @@ export { default as Submit } from '../../admin/components/forms/Submit'
export { default as FormSubmit } from '../../admin/components/forms/Submit'
export { fieldTypes } from '../../admin/components/forms/field-types'
export { default as Checkbox } from '../../admin/components/forms/field-types/Checkbox'
export { CheckboxInput } from '../../admin/components/forms/field-types/Checkbox/Input'
export { default as Collapsible } from '../../admin/components/forms/field-types/Collapsible'
export { default as Date } from '../../admin/components/forms/field-types/DateTime'

View File

@@ -0,0 +1,16 @@
import type { RequestHandler } from 'express'
import type { IParseOptions } from 'qs'
import { parse as parseQueryString } from 'qs'
import { parse as parseUrl } from 'url'
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
type QueryStringOptions = IParseOptions & { decoder?: never | undefined }
export function addParsedQuery(options?: QueryStringOptions): RequestHandler {
return (req, res, next) => {
const url = parseUrl(req.url)
req.query = parseQueryString(url.query, options)
next()
}
}

View File

@@ -5,12 +5,12 @@ import fileUpload from 'express-fileupload'
import rateLimit from 'express-rate-limit'
import methodOverride from 'method-override'
import passport from 'passport'
import qsMiddleware from 'qs-middleware'
import type { Payload } from '../../payload'
import type { PayloadRequest } from '../types'
import localizationMiddleware from '../../localization/middleware'
import { addParsedQuery } from './addParsedQuery'
import authenticate from './authenticate'
import convertPayload from './convertPayload'
import corsHeaders from './corsHeaders'
@@ -45,7 +45,7 @@ const middleware = (payload: Payload): any => {
i18nMiddleware(payload.config.i18n),
identifyAPI('REST'),
methodOverride('X-HTTP-Method-Override'),
qsMiddleware({ arrayLimit: 1000, depth: 10, strictNullHandling: true }),
addParsedQuery({ arrayLimit: 1000, depth: 10, strictNullHandling: true }),
bodyParser.urlencoded({ extended: true }),
compression(payload.config.express.compression),
localizationMiddleware,

View File

@@ -40,6 +40,7 @@ const globalSchema = joi
}),
}),
description: joi.alternatives().try(joi.string(), componentSchema),
forceRenderAllFields: joi.boolean(),
group: joi
.alternatives()
.try(joi.string(), joi.object().pattern(joi.string(), [joi.string()])),

View File

@@ -138,6 +138,11 @@ export type GlobalAdminOptions = {
* Custom description for collection
*/
description?: EntityDescription
/**
* Forces all fields in the Edit view to render immediately, regardless of scroll position
* @default false
*/
forceRenderAllFields?: boolean
/**
* Place globals into a navigational group
* */

View File

@@ -405,7 +405,7 @@ function buildObjectType({
}
await Promise.all(resultPromises)
return results
return results.filter((doc) => doc != null)
}
let id = value

View File

@@ -21,6 +21,7 @@ import ro from './ro.json'
import rs from './rs.json'
import rsLatin from './rs-latin.json'
import ru from './ru.json'
import sl from './sl.json'
import sv from './sv.json'
import th from './th.json'
import tr from './tr.json'
@@ -53,6 +54,7 @@ export default {
rs,
rsLatin,
ru,
sl,
sv,
th,
tr,

View File

@@ -0,0 +1,386 @@
{
"$schema": "./translation-schema.json",
"authentication": {
"account": "Račun",
"accountOfCurrentUser": "Račun trenutnega uporabnika",
"alreadyActivated": "Že aktivirano",
"alreadyLoggedIn": "Že prijavljen",
"apiKey": "API ključ",
"authenticated": "Avtenticiran",
"backToLogin": "Nazaj na prijavo",
"beginCreateFirstUser": "Za začetek ustvarite prvega uporabnika.",
"changePassword": "Spremeni geslo",
"checkYourEmailForPasswordReset": "Preverite svoj e-poštni predal za povezavo, ki vam bo omogočila varno ponastavitev gesla.",
"confirmGeneration": "Potrdi generiranje",
"confirmPassword": "Potrdi geslo",
"createFirstUser": "Ustvari prvega uporabnika",
"emailNotValid": "Vneseni e-poštni naslov ni veljaven",
"emailSent": "E-pošta poslana",
"enableAPIKey": "Omogoči API ključ",
"failedToUnlock": "Odklepanje ni uspelo",
"forceUnlock": "Prisilno odkleni",
"forgotPassword": "Pozabljeno geslo",
"forgotPasswordEmailInstructions": "Prosimo, vnesite svoj e-poštni naslov. Prejeli boste e-poštno sporočilo z navodili za ponastavitev gesla.",
"forgotPasswordQuestion": "Pozabljeno geslo?",
"generate": "Generiraj",
"generateNewAPIKey": "Generiraj nov API ključ",
"generatingNewAPIKeyWillInvalidate": "Generiranje novega API ključa bo <1>razveljavilo</1> prejšnji ključ. Ali ste prepričani, da želite nadaljevati?",
"lockUntil": "Zakleni do",
"logBackIn": "Ponovna prijava",
"logOut": "Odjava",
"loggedIn": "Za prijavo z drugim uporabnikom se morate najprej <0>odjaviti</0>.",
"loggedInChangePassword": "Za spremembo gesla pojdite na svoj <0>račun</0> in tam uredite svoje geslo.",
"loggedOutInactivity": "Odjavljeni ste bili zaradi neaktivnosti.",
"loggedOutSuccessfully": "Uspešno ste se odjavili.",
"login": "Prijava",
"loginAttempts": "Poskusi prijave",
"loginUser": "Prijavi uporabnika",
"loginWithAnotherUser": "Za prijavo z drugim uporabnikom se morate najprej <0>odjaviti</0>.",
"logout": "Odjava",
"logoutUser": "Odjavi uporabnika",
"newAPIKeyGenerated": "Nov API ključ je generiran.",
"newAccountCreated": "Za vas je bil pravkar ustvarjen nov račun za dostop do <a href=\"{{serverURL}}\">{{serverURL}}</a>. Prosimo, kliknite na povezavo ali jo prilepite v svoj brskalnik, da potrdite svoj e-poštni naslov: <a href=\"{{verificationURL}}\">{{verificationURL}}</a><br> Po potrditvi e-poštnega naslova se boste lahko uspešno prijavili.",
"newPassword": "Novo geslo",
"resetPassword": "Ponastavi geslo",
"resetPasswordExpiration": "Potek veljavnosti ponastavitve gesla",
"resetPasswordToken": "Žeton za ponastavitev gesla",
"resetYourPassword": "Ponastavite svoje geslo",
"stayLoggedIn": "Ostani prijavljen",
"successfullyUnlocked": "Uspešno odklenjeno",
"unableToVerify": "Ni mogoče preveriti",
"verified": "Preverjeno",
"verifiedSuccessfully": "Uspešno preverjeno",
"verify": "Preveri",
"verifyUser": "Preveri uporabnika",
"verifyYourEmail": "Potrdite svoj e-poštni naslov",
"youAreInactive": "Že nekaj časa niste bili aktivni in boste kmalu samodejno odjavljeni zaradi vaše varnosti. Ali želite ostati prijavljeni?",
"youAreReceivingResetPassword": "To sporočilo ste prejeli, ker ste vi (ali nekdo drug) zahtevali ponastavitev gesla za vaš račun. Prosimo, kliknite na naslednjo povezavo ali jo prilepite v svoj brskalnik, da zaključite postopek:",
"youDidNotRequestPassword": "Če tega niste zahtevali vi, prosimo, ignorirajte to e-pošto in vaše geslo bo ostalo nespremenjeno."
},
"error": {
"accountAlreadyActivated": "Ta račun je že aktiviran.",
"autosaving": "Pri samodejnem shranjevanju tega dokumenta je prišlo do napake.",
"correctInvalidFields": "Prosimo, popravite neveljavna polja.",
"deletingFile": "Pri brisanju datoteke je prišlo do napake.",
"deletingTitle": "Pri brisanju {{title}} je prišlo do napake. Prosimo, preverite svojo povezavo in poskusite znova.",
"emailOrPasswordIncorrect": "Vneseni e-poštni naslov ali geslo je napačno.",
"followingFieldsInvalid_one": "Naslednje polje je neveljavno:",
"followingFieldsInvalid_other": "Naslednja polja so neveljavna:",
"incorrectCollection": "Napačna zbirka",
"invalidFileType": "Neveljaven tip datoteke",
"invalidFileTypeValue": "Neveljaven tip datoteke: {{value}}",
"loadingDocument": "Pri nalaganju dokumenta z ID-jem {{id}} je prišlo do težave.",
"localesNotSaved_one": "Naslednjega jezika ni bilo mogoče shraniti:",
"localesNotSaved_other": "Naslednjih jezikov ni bilo mogoče shraniti:",
"missingEmail": "Manjka e-poštni naslov.",
"missingIDOfDocument": "Manjka ID dokumenta za posodobitev.",
"missingIDOfVersion": "Manjka ID verzije.",
"missingRequiredData": "Manjkajo zahtevani podatki.",
"noFilesUploaded": "Nobena datoteka ni bila naložena.",
"noMatchedField": "Za \"{{label}}\" ni bilo najdeno ujemajoče se polje",
"noUser": "Ni uporabnika",
"notAllowedToAccessPage": "Nimate dovoljenja za dostop do te strani.",
"notAllowedToPerformAction": "Nimate dovoljenja za izvedbo tega dejanja.",
"notFound": "Zahtevani vir ni bil najden.",
"previewing": "Pri predogledu tega dokumenta je prišlo do težave.",
"problemUploadingFile": "Pri nalaganju datoteke je prišlo do težave.",
"tokenInvalidOrExpired": "Žeton je neveljaven ali je potekel.",
"unPublishingDocument": "Pri umiku objave tega dokumenta je prišlo do težave.",
"unableToDeleteCount": "Ni mogoče izbrisati {{count}} od {{total}} {{label}}.",
"unableToUpdateCount": "Ni mogoče posodobiti {{count}} od {{total}} {{label}}.",
"unauthorized": "Nepooblaščeno, za to zahtevo morate biti prijavljeni.",
"unknown": "Prišlo je do neznane napake.",
"unspecific": "Prišlo je do napake.",
"userEmailAlreadyRegistered": "Uporabnik s tem e-poštnim naslovom je že registriran.",
"userLocked": "Ta uporabnik je zaklenjen zaradi prevelikega števila neuspešnih poskusov prijave.",
"valueMustBeUnique": "Vrednost mora biti unikatna",
"verificationTokenInvalid": "Verifikacijski žeton je neveljaven."
},
"fields": {
"addLabel": "Dodaj {{label}}",
"addLink": "Dodaj povezavo",
"addNew": "Dodaj novo",
"addNewLabel": "Dodaj nov {{label}}",
"addRelationship": "Dodaj relacijo",
"addUpload": "Dodaj nalaganje",
"block": "blok",
"blockType": "Tip bloka",
"blocks": "bloki",
"chooseBetweenCustomTextOrDocument": "Izberite med vnosom URL-ja po meri ali povezavo na drug dokument.",
"chooseDocumentToLink": "Izberite dokument za povezavo",
"chooseFromExisting": "Izberite iz obstoječih",
"chooseLabel": "Izberite {{label}}",
"collapseAll": "Strni vse",
"customURL": "URL po meri",
"editLabelData": "Uredi podatke {{label}}",
"editLink": "Uredi povezavo",
"editRelationship": "Uredi relacijo",
"enterURL": "Vnesite URL",
"internalLink": "Notranja povezava",
"itemsAndMore": "{{items}} in še {{count}}",
"labelRelationship": "Relacija {{label}}",
"latitude": "Zemljepisna širina",
"linkType": "Tip povezave",
"linkedTo": "Povezano z <0>{{label}}</0>",
"longitude": "Zemljepisna dolžina",
"newLabel": "Nov {{label}}",
"openInNewTab": "Odpri v novem zavihku",
"passwordsDoNotMatch": "Gesli se ne ujemata.",
"relatedDocument": "Povezan dokument",
"relationTo": "Relacija z",
"removeRelationship": "Odstrani relacijo",
"removeUpload": "Odstrani nalaganje",
"saveChanges": "Shrani spremembe",
"searchForBlock": "Išči blok",
"selectExistingLabel": "Izberi obstoječ {{label}}",
"selectFieldsToEdit": "Izberite polja za urejanje",
"showAll": "Pokaži vse",
"swapRelationship": "Zamenjaj relacijo",
"swapUpload": "Zamenjaj nalaganje",
"textToDisplay": "Besedilo za prikaz",
"toggleBlock": "Preklopi blok",
"uploadNewLabel": "Naloži nov {{label}}"
},
"general": {
"aboutToDelete": "Izbrisali boste {{label}} <1>{{title}}</1>. Ste prepričani?",
"aboutToDeleteCount_many": "Izbrisali boste {{count}} {{label}}",
"aboutToDeleteCount_one": "Izbrisali boste {{count}} {{label}}",
"aboutToDeleteCount_other": "Izbrisali boste {{count}} {{label}}",
"addBelow": "Dodaj spodaj",
"addFilter": "Dodaj filter",
"adminTheme": "Admin tema",
"and": "In",
"applyChanges": "Uveljavi spremembe",
"ascending": "Naraščajoče",
"automatic": "Samodejno",
"backToDashboard": "Nazaj na nadzorno ploščo",
"cancel": "Prekliči",
"changesNotSaved": "Vaše spremembe niso bile shranjene. Če zapustite zdaj, boste izgubili svoje spremembe.",
"close": "Zapri",
"collapse": "Strni",
"collections": "Zbirke",
"columnToSort": "Stolpec za razvrščanje",
"columns": "Stolpci",
"confirm": "Potrdi",
"confirmDeletion": "Potrdi brisanje",
"confirmDuplication": "Potrdi podvajanje",
"copied": "Kopirano",
"copy": "Kopiraj",
"create": "Ustvari",
"createNew": "Ustvari novo",
"createNewLabel": "Ustvari nov {{label}}",
"creatingNewLabel": "Ustvarjanje novega {{label}}",
"created": "Ustvarjeno",
"createdAt": "Ustvarjeno",
"creating": "Ustvarjanje",
"dark": "Temno",
"dashboard": "Nadzorna plošča",
"delete": "Izbriši",
"deletedCountSuccessfully": "Uspešno izbrisano {{count}} {{label}}.",
"deletedSuccessfully": "Uspešno izbrisano.",
"deleting": "Brisanje...",
"depth": "Globina",
"descending": "Padajoče",
"deselectAllRows": "Odznači vse vrstice",
"document": "Dokument",
"documents": "Dokumenti",
"duplicate": "Podvoji",
"duplicateWithoutSaving": "Podvoji brez shranjevanja sprememb",
"edit": "Uredi",
"editLabel": "Uredi {{label}}",
"editing": "Urejanje",
"editingLabel_many": "Urejanje {{count}} {{label}}",
"editingLabel_one": "Urejanje {{count}} {{label}}",
"editingLabel_other": "Urejanje {{count}} {{label}}",
"email": "E-pošta",
"emailAddress": "E-poštni naslov",
"enterAValue": "Vnesite vrednost",
"error": "Napaka",
"errors": "Napake",
"fallbackToDefaultLocale": "Uporabi privzeti jezik",
"false": "Ne",
"filter": "Filter",
"filterWhere": "Filtriraj {{label}} kjer",
"filters": "Filtri",
"globals": "Globalne nastavitve",
"language": "Jezik",
"lastModified": "Zadnja sprememba",
"leaveAnyway": "Vseeno zapusti",
"leaveWithoutSaving": "Zapusti brez shranjevanja",
"light": "Svetlo",
"livePreview": "Predogled v živo",
"loading": "Nalaganje",
"locale": "Jezik",
"locales": "Jeziki",
"menu": "Meni",
"moveDown": "Premakni navzdol",
"moveUp": "Premakni navzgor",
"newPassword": "Novo geslo",
"noFiltersSet": "Ni nastavljenih filtrov",
"noLabel": "<Ni {{label}}>",
"noOptions": "Ni možnosti",
"noResults": "Ni najdenih {{label}}. Ali še ne obstajajo {{label}} ali pa ne ustrezajo filtrom, ki ste jih določili zgoraj.",
"noValue": "Ni vrednosti",
"none": "Brez",
"notFound": "Ni najdeno",
"nothingFound": "Nič ni najdeno",
"of": "od",
"or": "Ali",
"open": "Odpri",
"order": "Vrstni red",
"pageNotFound": "Stran ni najdena",
"password": "Geslo",
"payloadSettings": "Nastavitve Payloada",
"perPage": "Na stran: {{limit}}",
"remove": "Odstrani",
"reset": "Ponastavi",
"row": "Vrstica",
"rows": "Vrstice",
"save": "Shrani",
"saving": "Shranjevanje...",
"searchBy": "Išči po {{label}}",
"selectAll": "Izberi vse {{count}} {{label}}",
"selectAllRows": "Izberi vse vrstice",
"selectValue": "Izberi vrednost",
"selectedCount": "{{count}} {{label}} izbranih",
"showAllLabel": "Pokaži vse {{label}}",
"sorryNotFound": "Oprostite - ničesar ni, kar bi ustrezalo vaši zahtevi.",
"sort": "Razvrsti",
"sortByLabelDirection": "Razvrsti po {{label}} {{direction}}",
"stayOnThisPage": "Ostani na tej strani",
"submissionSuccessful": "Oddaja uspešna.",
"submit": "Oddaj",
"successfullyCreated": "{{label}} uspešno ustvarjen.",
"successfullyDuplicated": "{{label}} uspešno podvojen.",
"thisLanguage": "Slovenščina",
"titleDeleted": "{{label}} \"{{title}}\" uspešno izbrisan.",
"true": "Da",
"unauthorized": "Neavtorizirano",
"unsavedChangesDuplicate": "Imate neshranjene spremembe. Ali želite nadaljevati s podvajanjem?",
"untitled": "Neimenovano",
"updatedAt": "Posodobljeno",
"updatedCountSuccessfully": "Uspešno posodobljeno {{count}} {{label}}.",
"updatedSuccessfully": "Uspešno posodobljeno.",
"updating": "Posodabljanje",
"uploading": "Nalaganje",
"user": "Uporabnik",
"users": "Uporabniki",
"value": "Vrednost",
"welcome": "Dobrodošli"
},
"operators": {
"contains": "vsebuje",
"equals": "je enako",
"exists": "obstaja",
"isGreaterThan": "je večje od",
"isGreaterThanOrEqualTo": "je večje ali enako",
"isIn": "je v",
"isLessThan": "je manjše od",
"isLessThanOrEqualTo": "je manjše ali enako",
"isLike": "je podobno",
"isNotEqualTo": "ni enako",
"isNotIn": "ni v",
"near": "blizu"
},
"upload": {
"addFile": "Dodaj datoteko",
"crop": "Obreži",
"cropToolDescription": "Povlecite vogale izbranega območja, narišite novo območje ali prilagodite vrednosti spodaj.",
"dragAndDrop": "Povlecite in spustite datoteko",
"dragAndDropHere": "ali povlecite in spustite datoteko sem",
"editImage": "Uredi sliko",
"focalPoint": "Fokusna točka",
"focalPointDescription": "Povlecite fokusno točko neposredno na predogledu ali prilagodite vrednosti spodaj.",
"fileName": "Ime datoteke",
"fileSize": "Velikost datoteke",
"height": "Višina",
"lessInfo": "Manj informacij",
"moreInfo": "Več informacij",
"pasteURL": "Prilepi URL",
"previewSizes": "Velikosti predogleda",
"selectCollectionToBrowse": "Izberite zbirko za brskanje",
"selectFile": "Izberi datoteko",
"setCropArea": "Nastavi območje obrezovanja",
"setFocalPoint": "Nastavi fokusno točko",
"sizes": "Velikosti",
"sizesFor": "Velikosti za {{label}}",
"width": "Širina"
},
"validation": {
"emailAddress": "Vnesite veljaven e-poštni naslov.",
"enterNumber": "Vnesite veljavno število.",
"fieldHasNo": "To polje nima {{label}}",
"greaterThanMax": "{{value}} je večje od največje dovoljene vrednosti {{label}}, ki je {{max}}.",
"invalidInput": "To polje ima neveljaven vnos.",
"invalidSelection": "To polje ima neveljavno izbiro.",
"invalidSelections": "To polje ima naslednje neveljavne izbire:",
"lessThanMin": "{{value}} je manjše od najmanjše dovoljene vrednosti {{label}}, ki je {{min}}.",
"limitReached": "Dosežena omejitev, dodate lahko samo {{max}} elementov.",
"longerThanMin": "Ta vrednost mora biti daljša od minimalne dolžine {{minLength}} znakov.",
"notValidDate": "\"{{value}}\" ni veljaven datum.",
"required": "To polje je obvezno.",
"requiresAtLeast": "To polje zahteva vsaj {{count}} {{label}}.",
"requiresNoMoreThan": "To polje zahteva največ {{count}} {{label}}.",
"requiresTwoNumbers": "To polje zahteva dve števili.",
"shorterThanMax": "Ta vrednost mora biti krajša od največje dolžine {{maxLength}} znakov.",
"trueOrFalse": "To polje je lahko enako samo true ali false.",
"validUploadID": "To polje ni veljaven ID nalaganja."
},
"version": {
"aboutToPublishSelection": "Objavili boste vse {{label}} v izboru. Ste prepričani?",
"aboutToRestore": "Ta dokument {{label}} boste obnovili v stanje, v katerem je bil {{versionDate}}.",
"aboutToRestoreGlobal": "Globalne nastavitve {{label}} boste obnovili v stanje, v katerem so bile {{versionDate}}.",
"aboutToRevertToPublished": "Spremembe tega dokumenta boste povrnili v objavljeno stanje. Ste prepričani?",
"aboutToUnpublish": "Ta dokument boste umaknili iz objave. Ste prepričani?",
"aboutToUnpublishSelection": "Iz objave boste umaknili vse {{label}} v izboru. Ste prepričani?",
"autosave": "Samodejno shranjevanje",
"autosavedSuccessfully": "Samodejno shranjevanje uspešno.",
"autosavedVersion": "Samodejno shranjena verzija",
"changed": "Spremenjeno",
"compareVersion": "Primerjaj verzijo z:",
"confirmPublish": "Potrdi objavo",
"confirmRevertToSaved": "Potrdi povrnitev na shranjeno",
"confirmUnpublish": "Potrdi umik iz objave",
"confirmVersionRestoration": "Potrdi obnovitev verzije",
"currentDocumentStatus": "Trenutni {{docStatus}} dokument",
"currentDraft": "Trenutni osnutek",
"currentPublishedVersion": "Trenutna objavljena verzija",
"draft": "Osnutek",
"draftSavedSuccessfully": "Osnutek uspešno shranjen.",
"lastSavedAgo": "Zadnjič shranjeno pred {{distance}}",
"noFurtherVersionsFound": "Ni najdenih nadaljnjih verzij",
"noRowsFound": "Ni najdenih {{label}}",
"preview": "Predogled",
"previouslyPublished": "Predhodno objavljeno",
"problemRestoringVersion": "Pri obnavljanju te verzije je prišlo do težave",
"publish": "Objavi",
"publishChanges": "Objavi spremembe",
"published": "Objavljeno",
"restoreThisVersion": "Obnovi to verzijo",
"restoredSuccessfully": "Uspešno obnovljeno.",
"restoring": "Obnavljanje...",
"revertToPublished": "Povrni na objavljeno",
"reverting": "Povračanje...",
"saveDraft": "Shrani osnutek",
"selectLocales": "Izberi jezike za prikaz",
"selectVersionToCompare": "Izberi verzijo za primerjavo",
"showLocales": "Prikaži jezike:",
"showingVersionsFor": "Prikaz verzij za:",
"status": "Status",
"type": "Tip",
"unpublish": "Umakni iz objave",
"unpublishing": "Umikanje iz objave...",
"version": "Verzija",
"versionCount_many": "Najdenih {{count}} verzij",
"versionCount_none": "Ni najdenih verzij",
"versionCount_one": "Najdena {{count}} verzija",
"versionCount_other": "Najdene {{count}} verzije",
"versionCreatedOn": "{{version}} ustvarjena:",
"versionID": "ID verzije",
"versions": "Verzije",
"viewingVersion": "Ogled verzije za {{entityLabel}} {{documentTitle}}",
"viewingVersionGlobal": "Ogled verzije za globalne nastavitve {{entityLabel}}",
"viewingVersions": "Ogled verzij za {{entityLabel}} {{documentTitle}}",
"viewingVersionsGlobal": "Ogled verzij za globalne nastavitve {{entityLabel}}"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "@payloadcms/plugin-cloud-storage",
"description": "The official cloud storage plugin for Payload CMS",
"version": "1.2.0",
"version": "1.2.2",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
@@ -63,7 +63,7 @@
"payload": "workspace:*",
"rimraf": "^4.1.2",
"ts-node": "^9.1.1",
"webpack": "^5.78.0"
"webpack": "5.91.0"
},
"dependencies": {
"find-node-modules": "^2.1.3",

View File

@@ -1,7 +1,7 @@
{
"name": "@payloadcms/plugin-cloud",
"description": "The official Payload Cloud plugin",
"version": "3.0.2",
"version": "3.0.4",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
@@ -36,7 +36,7 @@
"@types/nodemailer": "6.4.16",
"payload": "workspace:*",
"ts-jest": "^29.1.0",
"webpack": "^5.78.0"
"webpack": "5.91.0"
},
"files": [
"dist"

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-relationship-object-ids",
"version": "0.0.4",
"version": "0.0.6",
"homepage:": "https://payloadcms.com",
"repository": {
"type": "git",
@@ -24,7 +24,7 @@
"license": "MIT",
"peerDependencies": {
"payload": "workspace:*",
"mongoose": "6.12.3"
"mongoose": "^6.12.3"
},
"files": [
"dist",
@@ -35,6 +35,6 @@
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
"payload": "workspace:*",
"webpack": "^5.78.0"
"webpack": "5.91.0"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-sentry",
"version": "0.0.6",
"version": "0.0.8",
"homepage:": "https://payloadcms.com",
"repository": {
"type": "git",
@@ -37,7 +37,7 @@
"dependencies": {
"@sentry/node": "^7.55.2",
"@sentry/types": "^7.54.0",
"express": "^4.18.2"
"express": "^4.21.2"
},
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
@@ -52,6 +52,6 @@
"nodemon": "3.0.3",
"payload": "workspace:*",
"ts-jest": "^29.1.0",
"webpack": "^5.78.0"
"webpack": "5.91.0"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-stripe",
"version": "0.0.17",
"version": "0.0.19",
"homepage:": "https://payloadcms.com",
"repository": {
"type": "git",
@@ -48,7 +48,7 @@
"@types/react": "18.0.21",
"payload": "workspace:*",
"prettier": "^2.7.1",
"webpack": "^5.78.0"
"webpack": "5.91.0"
},
"files": [
"dist",

5805
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
import type { CollectionConfig } from 'payload/dist/collections/config/types'
import { customIdCollectionSlug } from '../slugs'
export const CustomIdTab: CollectionConfig = {
slug: 'customIdTab',
labels: {

View File

@@ -0,0 +1,532 @@
import type { CollectionConfig } from 'payload/dist/collections/config/types'
import { forceRenderCollectionSlug } from '../slugs'
export const CollectionForceRender: CollectionConfig = {
slug: forceRenderCollectionSlug,
admin: {
forceRenderAllFields: true,
},
fields: [
{
name: 'groupOne',
type: 'group',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
{
name: 'field3',
type: 'text',
},
{
name: 'field4',
type: 'text',
},
{
name: 'field5',
type: 'text',
},
],
},
{
name: 'groupTwo',
type: 'group',
fields: [
{
name: 'field6',
type: 'text',
},
{
name: 'field7',
type: 'text',
},
{
name: 'field8',
type: 'text',
},
{
name: 'field9',
type: 'text',
},
{
name: 'field10',
type: 'text',
},
],
},
{
name: 'groupThree',
type: 'group',
fields: [
{
name: 'field11',
type: 'text',
},
{
name: 'field12',
type: 'text',
},
{
name: 'field13',
type: 'text',
},
{
name: 'field14',
type: 'text',
},
{
name: 'field15',
type: 'text',
},
],
},
{
name: 'groupFour',
type: 'group',
fields: [
{
name: 'field16',
type: 'text',
},
{
name: 'field17',
type: 'text',
},
{
name: 'field18',
type: 'text',
},
{
name: 'field19',
type: 'text',
},
{
name: 'field20',
type: 'text',
},
],
},
{
name: 'groupFive',
type: 'group',
fields: [
{
name: 'field21',
type: 'text',
},
{
name: 'field22',
type: 'text',
},
{
name: 'field23',
type: 'text',
},
{
name: 'field24',
type: 'text',
},
{
name: 'field25',
type: 'text',
},
],
},
{
name: 'groupSix',
type: 'group',
fields: [
{
name: 'field26',
type: 'text',
},
{
name: 'field27',
type: 'text',
},
{
name: 'field28',
type: 'text',
},
{
name: 'field29',
type: 'text',
},
{
name: 'field30',
type: 'text',
},
],
},
{
name: 'groupSeven',
type: 'group',
fields: [
{
name: 'field31',
type: 'text',
},
{
name: 'field32',
type: 'text',
},
{
name: 'field33',
type: 'text',
},
{
name: 'field34',
type: 'text',
},
{
name: 'field35',
type: 'text',
},
],
},
{
name: 'groupEight',
type: 'group',
fields: [
{
name: 'field36',
type: 'text',
},
{
name: 'field37',
type: 'text',
},
{
name: 'field38',
type: 'text',
},
{
name: 'field39',
type: 'text',
},
{
name: 'field40',
type: 'text',
},
],
},
{
name: 'groupNine',
type: 'group',
fields: [
{
name: 'field41',
type: 'text',
},
{
name: 'field42',
type: 'text',
},
{
name: 'field43',
type: 'text',
},
{
name: 'field44',
type: 'text',
},
{
name: 'field45',
type: 'text',
},
],
},
{
name: 'groupTen',
type: 'group',
fields: [
{
name: 'field46',
type: 'text',
},
{
name: 'field47',
type: 'text',
},
{
name: 'field48',
type: 'text',
},
{
name: 'field49',
type: 'text',
},
{
name: 'field50',
type: 'text',
},
],
},
{
name: 'groupEleven',
type: 'group',
fields: [
{
name: 'field51',
type: 'text',
},
{
name: 'field52',
type: 'text',
},
{
name: 'field53',
type: 'text',
},
{
name: 'field54',
type: 'text',
},
{
name: 'field55',
type: 'text',
},
],
},
{
name: 'groupTwelve',
type: 'group',
fields: [
{
name: 'field56',
type: 'text',
},
{
name: 'field57',
type: 'text',
},
{
name: 'field58',
type: 'text',
},
{
name: 'field59',
type: 'text',
},
{
name: 'field60',
type: 'text',
},
],
},
{
name: 'groupThirteen',
type: 'group',
fields: [
{
name: 'field61',
type: 'text',
},
{
name: 'field62',
type: 'text',
},
{
name: 'field63',
type: 'text',
},
{
name: 'field64',
type: 'text',
},
{
name: 'field65',
type: 'text',
},
],
},
{
name: 'groupFourteen',
type: 'group',
fields: [
{
name: 'field66',
type: 'text',
},
{
name: 'field67',
type: 'text',
},
{
name: 'field68',
type: 'text',
},
{
name: 'field69',
type: 'text',
},
{
name: 'field70',
type: 'text',
},
],
},
{
name: 'groupFifteen',
type: 'group',
fields: [
{
name: 'field71',
type: 'text',
},
{
name: 'field72',
type: 'text',
},
{
name: 'field73',
type: 'text',
},
{
name: 'field74',
type: 'text',
},
{
name: 'field75',
type: 'text',
},
],
},
{
name: 'groupSixteen',
type: 'group',
fields: [
{
name: 'field76',
type: 'text',
},
{
name: 'field77',
type: 'text',
},
{
name: 'field78',
type: 'text',
},
{
name: 'field79',
type: 'text',
},
{
name: 'field80',
type: 'text',
},
],
},
{
name: 'groupSeventeen',
type: 'group',
fields: [
{
name: 'field81',
type: 'text',
},
{
name: 'field82',
type: 'text',
},
{
name: 'field83',
type: 'text',
},
{
name: 'field84',
type: 'text',
},
{
name: 'field85',
type: 'text',
},
],
},
{
name: 'groupEighteen',
type: 'group',
fields: [
{
name: 'field86',
type: 'text',
},
{
name: 'field87',
type: 'text',
},
{
name: 'field88',
type: 'text',
},
{
name: 'field89',
type: 'text',
},
{
name: 'field90',
type: 'text',
},
],
},
{
name: 'groupNineteen',
type: 'group',
fields: [
{
name: 'field91',
type: 'text',
},
{
name: 'field92',
type: 'text',
},
{
name: 'field93',
type: 'text',
},
{
name: 'field94',
type: 'text',
},
{
name: 'field95',
type: 'text',
},
],
},
{
name: 'groupTwenty',
type: 'group',
fields: [
{
name: 'field96',
type: 'text',
},
{
name: 'field97',
type: 'text',
},
{
name: 'field98',
type: 'text',
},
{
name: 'field99',
type: 'text',
},
{
name: 'field100',
type: 'text',
},
],
},
],
}

View File

@@ -0,0 +1,532 @@
import type { CollectionConfig } from 'payload/dist/collections/config/types'
import { noForceRenderCollectionSlug } from '../slugs'
export const CollectionNoForceRender: CollectionConfig = {
slug: noForceRenderCollectionSlug,
admin: {
forceRenderAllFields: false,
},
fields: [
{
name: 'groupOne',
type: 'group',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
{
name: 'field3',
type: 'text',
},
{
name: 'field4',
type: 'text',
},
{
name: 'field5',
type: 'text',
},
],
},
{
name: 'groupTwo',
type: 'group',
fields: [
{
name: 'field6',
type: 'text',
},
{
name: 'field7',
type: 'text',
},
{
name: 'field8',
type: 'text',
},
{
name: 'field9',
type: 'text',
},
{
name: 'field10',
type: 'text',
},
],
},
{
name: 'groupThree',
type: 'group',
fields: [
{
name: 'field11',
type: 'text',
},
{
name: 'field12',
type: 'text',
},
{
name: 'field13',
type: 'text',
},
{
name: 'field14',
type: 'text',
},
{
name: 'field15',
type: 'text',
},
],
},
{
name: 'groupFour',
type: 'group',
fields: [
{
name: 'field16',
type: 'text',
},
{
name: 'field17',
type: 'text',
},
{
name: 'field18',
type: 'text',
},
{
name: 'field19',
type: 'text',
},
{
name: 'field20',
type: 'text',
},
],
},
{
name: 'groupFive',
type: 'group',
fields: [
{
name: 'field21',
type: 'text',
},
{
name: 'field22',
type: 'text',
},
{
name: 'field23',
type: 'text',
},
{
name: 'field24',
type: 'text',
},
{
name: 'field25',
type: 'text',
},
],
},
{
name: 'groupSix',
type: 'group',
fields: [
{
name: 'field26',
type: 'text',
},
{
name: 'field27',
type: 'text',
},
{
name: 'field28',
type: 'text',
},
{
name: 'field29',
type: 'text',
},
{
name: 'field30',
type: 'text',
},
],
},
{
name: 'groupSeven',
type: 'group',
fields: [
{
name: 'field31',
type: 'text',
},
{
name: 'field32',
type: 'text',
},
{
name: 'field33',
type: 'text',
},
{
name: 'field34',
type: 'text',
},
{
name: 'field35',
type: 'text',
},
],
},
{
name: 'groupEight',
type: 'group',
fields: [
{
name: 'field36',
type: 'text',
},
{
name: 'field37',
type: 'text',
},
{
name: 'field38',
type: 'text',
},
{
name: 'field39',
type: 'text',
},
{
name: 'field40',
type: 'text',
},
],
},
{
name: 'groupNine',
type: 'group',
fields: [
{
name: 'field41',
type: 'text',
},
{
name: 'field42',
type: 'text',
},
{
name: 'field43',
type: 'text',
},
{
name: 'field44',
type: 'text',
},
{
name: 'field45',
type: 'text',
},
],
},
{
name: 'groupTen',
type: 'group',
fields: [
{
name: 'field46',
type: 'text',
},
{
name: 'field47',
type: 'text',
},
{
name: 'field48',
type: 'text',
},
{
name: 'field49',
type: 'text',
},
{
name: 'field50',
type: 'text',
},
],
},
{
name: 'groupEleven',
type: 'group',
fields: [
{
name: 'field51',
type: 'text',
},
{
name: 'field52',
type: 'text',
},
{
name: 'field53',
type: 'text',
},
{
name: 'field54',
type: 'text',
},
{
name: 'field55',
type: 'text',
},
],
},
{
name: 'groupTwelve',
type: 'group',
fields: [
{
name: 'field56',
type: 'text',
},
{
name: 'field57',
type: 'text',
},
{
name: 'field58',
type: 'text',
},
{
name: 'field59',
type: 'text',
},
{
name: 'field60',
type: 'text',
},
],
},
{
name: 'groupThirteen',
type: 'group',
fields: [
{
name: 'field61',
type: 'text',
},
{
name: 'field62',
type: 'text',
},
{
name: 'field63',
type: 'text',
},
{
name: 'field64',
type: 'text',
},
{
name: 'field65',
type: 'text',
},
],
},
{
name: 'groupFourteen',
type: 'group',
fields: [
{
name: 'field66',
type: 'text',
},
{
name: 'field67',
type: 'text',
},
{
name: 'field68',
type: 'text',
},
{
name: 'field69',
type: 'text',
},
{
name: 'field70',
type: 'text',
},
],
},
{
name: 'groupFifteen',
type: 'group',
fields: [
{
name: 'field71',
type: 'text',
},
{
name: 'field72',
type: 'text',
},
{
name: 'field73',
type: 'text',
},
{
name: 'field74',
type: 'text',
},
{
name: 'field75',
type: 'text',
},
],
},
{
name: 'groupSixteen',
type: 'group',
fields: [
{
name: 'field76',
type: 'text',
},
{
name: 'field77',
type: 'text',
},
{
name: 'field78',
type: 'text',
},
{
name: 'field79',
type: 'text',
},
{
name: 'field80',
type: 'text',
},
],
},
{
name: 'groupSeventeen',
type: 'group',
fields: [
{
name: 'field81',
type: 'text',
},
{
name: 'field82',
type: 'text',
},
{
name: 'field83',
type: 'text',
},
{
name: 'field84',
type: 'text',
},
{
name: 'field85',
type: 'text',
},
],
},
{
name: 'groupEighteen',
type: 'group',
fields: [
{
name: 'field86',
type: 'text',
},
{
name: 'field87',
type: 'text',
},
{
name: 'field88',
type: 'text',
},
{
name: 'field89',
type: 'text',
},
{
name: 'field90',
type: 'text',
},
],
},
{
name: 'groupNineteen',
type: 'group',
fields: [
{
name: 'field91',
type: 'text',
},
{
name: 'field92',
type: 'text',
},
{
name: 'field93',
type: 'text',
},
{
name: 'field94',
type: 'text',
},
{
name: 'field95',
type: 'text',
},
],
},
{
name: 'groupTwenty',
type: 'group',
fields: [
{
name: 'field96',
type: 'text',
},
{
name: 'field97',
type: 'text',
},
{
name: 'field98',
type: 'text',
},
{
name: 'field99',
type: 'text',
},
{
name: 'field100',
type: 'text',
},
],
},
],
}

View File

@@ -1,17 +1,19 @@
import path from 'path'
import { buildConfigWithDefaults } from '../buildConfigWithDefaults'
import { CustomIdRow } from './collections/CustomIdRow'
import { CustomIdTab } from './collections/CustomIdTab'
import { CustomViews1 } from './collections/CustomViews1'
import { CustomViews2 } from './collections/CustomViews2'
import { CollectionForceRender } from './collections/ForceRender'
import { Geo } from './collections/Geo'
import { CollectionGroup1A } from './collections/Group1A'
import { CollectionGroup1B } from './collections/Group1B'
import { CollectionGroup2A } from './collections/Group2A'
import { CollectionGroup2B } from './collections/Group2B'
import { CollectionHidden } from './collections/Hidden'
import { CustomIdTab } from './collections/CustomIdTab'
import { CustomIdRow } from './collections/CustomIdRow'
import { CollectionNoApiView } from './collections/NoApiView'
import { CollectionNoForceRender } from './collections/NoForceRender'
import { Posts } from './collections/Posts'
import { Users } from './collections/Users'
import AdminButton from './components/AdminButton'
@@ -25,11 +27,13 @@ import CustomView from './components/views/CustomView'
import CustomNestedView from './components/views/CustomViewNested'
import { CustomGlobalViews1 } from './globals/CustomViews1'
import { CustomGlobalViews2 } from './globals/CustomViews2'
import { GlobalForceRender } from './globals/ForceRender'
import { Global } from './globals/Global'
import { GlobalGroup1A } from './globals/Group1A'
import { GlobalGroup1B } from './globals/Group1B'
import { GlobalHidden } from './globals/Hidden'
import { GlobalNoApiView } from './globals/NoApiView'
import { GlobalNoForceRender } from './globals/NoForceRender'
import { clearAndSeedEverything } from './seed'
import { customNestedViewPath, customViewPath } from './shared'
@@ -120,6 +124,8 @@ export default buildConfigWithDefaults({
Geo,
CustomIdTab,
CustomIdRow,
CollectionForceRender,
CollectionNoForceRender,
],
globals: [
GlobalHidden,
@@ -129,6 +135,8 @@ export default buildConfigWithDefaults({
CustomGlobalViews2,
GlobalGroup1A,
GlobalGroup1B,
GlobalForceRender,
GlobalNoForceRender,
],
onInit: async (payload) => {
await clearAndSeedEverything(payload)

View File

@@ -35,16 +35,19 @@ import {
slugPluralLabel,
} from './shared'
import {
customIdCollectionId,
customViews2CollectionSlug,
forceRenderCollectionSlug,
forceRenderGlobalSlug,
geoCollectionSlug,
globalSlug,
group1Collection1Slug,
group1GlobalSlug,
noApiViewCollectionSlug,
noApiViewGlobalSlug,
noForceRenderCollectionSlug,
noForceRenderGlobalSlug,
postsCollectionSlug,
customIdCollectionSlug,
customIdCollectionId,
} from './slugs'
const { beforeAll, beforeEach, describe } = test
@@ -58,12 +61,20 @@ describe('admin', () => {
let url: AdminUrlUtil
let customViewsURL: AdminUrlUtil
let serverURL: string
let forceRenderCollectionURL: AdminUrlUtil
let forceRenderGlobalURL: AdminUrlUtil
let noForceRenderCollectionURL: AdminUrlUtil
let noForceRenderGlobalURL: AdminUrlUtil
beforeAll(async ({ browser }) => {
serverURL = (await initPayloadE2E(__dirname)).serverURL
geoUrl = new AdminUrlUtil(serverURL, geoCollectionSlug)
url = new AdminUrlUtil(serverURL, postsCollectionSlug)
customViewsURL = new AdminUrlUtil(serverURL, customViews2CollectionSlug)
forceRenderCollectionURL = new AdminUrlUtil(serverURL, forceRenderCollectionSlug)
forceRenderGlobalURL = new AdminUrlUtil(serverURL, forceRenderGlobalSlug)
noForceRenderCollectionURL = new AdminUrlUtil(serverURL, noForceRenderCollectionSlug)
noForceRenderGlobalURL = new AdminUrlUtil(serverURL, noForceRenderGlobalSlug)
const context = await browser.newContext()
page = await context.newPage()
@@ -534,7 +545,7 @@ describe('admin', () => {
test('should allow custom ID field nested inside an unnamed tab', async () => {
await page.goto(url.collection('customIdTab') + '/' + customIdCollectionId)
const idField = await page.locator('#field-id')
const idField = page.locator('#field-id')
await expect(idField).toHaveValue(customIdCollectionId)
})
@@ -542,7 +553,7 @@ describe('admin', () => {
test('should allow custom ID field nested inside a row', async () => {
await page.goto(url.collection('customIdRow') + '/' + customIdCollectionId)
const idField = await page.locator('#field-id')
const idField = page.locator('#field-id')
await expect(idField).toHaveValue(customIdCollectionId)
})
@@ -615,6 +626,64 @@ describe('admin', () => {
})
})
describe('browser search', () => {
test('should successfully find field in large collection edit view document', async () => {
await page.goto(forceRenderCollectionURL.create)
await page.waitForURL(forceRenderCollectionURL.create)
const isMac = process.platform === 'darwin'
// eslint-disable-next-line playwright/no-conditional-in-test
const searchKey = isMac ? 'Meta+F' : 'Control+F'
await page.keyboard.press(searchKey)
await page.keyboard.type('Field100')
await expect(page.locator('label >> text=Field100')).toBeVisible()
})
test('should not find field in large collection edit view document', async () => {
await page.goto(noForceRenderCollectionURL.create)
await page.waitForURL(noForceRenderCollectionURL.create)
const isMac = process.platform === 'darwin'
// eslint-disable-next-line playwright/no-conditional-in-test
const searchKey = isMac ? 'Meta+F' : 'Control+F'
await page.keyboard.press(searchKey)
await page.keyboard.type('Field100')
await expect(page.locator('label >> text=Field100')).toBeHidden()
})
test('should successfully find field in large global edit view document', async () => {
await page.goto(forceRenderGlobalURL.global(forceRenderGlobalSlug))
await page.waitForURL(forceRenderGlobalURL.global(forceRenderGlobalSlug))
const isMac = process.platform === 'darwin'
// eslint-disable-next-line playwright/no-conditional-in-test
const searchKey = isMac ? 'Meta+F' : 'Control+F'
await page.keyboard.press(searchKey)
await page.keyboard.type('Field100')
await expect(page.locator('label >> text=Field100')).toBeVisible()
})
test('should not find field in large global edit view document', async () => {
await page.goto(noForceRenderGlobalURL.global(noForceRenderGlobalSlug))
await page.waitForURL(noForceRenderGlobalURL.global(noForceRenderGlobalSlug))
const isMac = process.platform === 'darwin'
// eslint-disable-next-line playwright/no-conditional-in-test
const searchKey = isMac ? 'Meta+F' : 'Control+F'
await page.keyboard.press(searchKey)
await page.keyboard.type('Field100')
await expect(page.locator('label >> text=Field100')).toBeHidden()
})
})
describe('list view', () => {
const tableRowLocator = 'table > tbody > tr'
@@ -768,8 +837,8 @@ describe('admin', () => {
await valueField.fill(id)
await expect(page.locator(tableRowLocator)).toHaveCount(1)
const firstId = await page.locator(tableRowLocator).first().locator('.cell-id').innerText()
expect(firstId).toEqual(`ID: ${id}`)
const firstId = page.locator(tableRowLocator).first().locator('.cell-id')
await expect(firstId).toHaveText(`ID: ${id}`)
// Remove filter
await page.locator('.condition__actions-remove').click()
@@ -1221,7 +1290,7 @@ describe('admin', () => {
await page.locator('.where-builder__add-first-filter').click()
await page.locator('.condition__field .rs__control').click()
const options = page.locator('.rs__option')
await expect(options.locator('text=Title')).toHaveText('Title')
await expect(options.locator('text=Title').first()).toHaveText('Title')
// list columns
await expect(page.locator('#heading-title .sort-column__label')).toHaveText('Title')

View File

@@ -0,0 +1,532 @@
import type { GlobalConfig } from '../../../packages/payload/src/globals/config/types'
import { forceRenderGlobalSlug } from '../slugs'
export const GlobalForceRender: GlobalConfig = {
slug: forceRenderGlobalSlug,
admin: {
forceRenderAllFields: true,
},
fields: [
{
name: 'groupOne',
type: 'group',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
{
name: 'field3',
type: 'text',
},
{
name: 'field4',
type: 'text',
},
{
name: 'field5',
type: 'text',
},
],
},
{
name: 'groupTwo',
type: 'group',
fields: [
{
name: 'field6',
type: 'text',
},
{
name: 'field7',
type: 'text',
},
{
name: 'field8',
type: 'text',
},
{
name: 'field9',
type: 'text',
},
{
name: 'field10',
type: 'text',
},
],
},
{
name: 'groupThree',
type: 'group',
fields: [
{
name: 'field11',
type: 'text',
},
{
name: 'field12',
type: 'text',
},
{
name: 'field13',
type: 'text',
},
{
name: 'field14',
type: 'text',
},
{
name: 'field15',
type: 'text',
},
],
},
{
name: 'groupFour',
type: 'group',
fields: [
{
name: 'field16',
type: 'text',
},
{
name: 'field17',
type: 'text',
},
{
name: 'field18',
type: 'text',
},
{
name: 'field19',
type: 'text',
},
{
name: 'field20',
type: 'text',
},
],
},
{
name: 'groupFive',
type: 'group',
fields: [
{
name: 'field21',
type: 'text',
},
{
name: 'field22',
type: 'text',
},
{
name: 'field23',
type: 'text',
},
{
name: 'field24',
type: 'text',
},
{
name: 'field25',
type: 'text',
},
],
},
{
name: 'groupSix',
type: 'group',
fields: [
{
name: 'field26',
type: 'text',
},
{
name: 'field27',
type: 'text',
},
{
name: 'field28',
type: 'text',
},
{
name: 'field29',
type: 'text',
},
{
name: 'field30',
type: 'text',
},
],
},
{
name: 'groupSeven',
type: 'group',
fields: [
{
name: 'field31',
type: 'text',
},
{
name: 'field32',
type: 'text',
},
{
name: 'field33',
type: 'text',
},
{
name: 'field34',
type: 'text',
},
{
name: 'field35',
type: 'text',
},
],
},
{
name: 'groupEight',
type: 'group',
fields: [
{
name: 'field36',
type: 'text',
},
{
name: 'field37',
type: 'text',
},
{
name: 'field38',
type: 'text',
},
{
name: 'field39',
type: 'text',
},
{
name: 'field40',
type: 'text',
},
],
},
{
name: 'groupNine',
type: 'group',
fields: [
{
name: 'field41',
type: 'text',
},
{
name: 'field42',
type: 'text',
},
{
name: 'field43',
type: 'text',
},
{
name: 'field44',
type: 'text',
},
{
name: 'field45',
type: 'text',
},
],
},
{
name: 'groupTen',
type: 'group',
fields: [
{
name: 'field46',
type: 'text',
},
{
name: 'field47',
type: 'text',
},
{
name: 'field48',
type: 'text',
},
{
name: 'field49',
type: 'text',
},
{
name: 'field50',
type: 'text',
},
],
},
{
name: 'groupEleven',
type: 'group',
fields: [
{
name: 'field51',
type: 'text',
},
{
name: 'field52',
type: 'text',
},
{
name: 'field53',
type: 'text',
},
{
name: 'field54',
type: 'text',
},
{
name: 'field55',
type: 'text',
},
],
},
{
name: 'groupTwelve',
type: 'group',
fields: [
{
name: 'field56',
type: 'text',
},
{
name: 'field57',
type: 'text',
},
{
name: 'field58',
type: 'text',
},
{
name: 'field59',
type: 'text',
},
{
name: 'field60',
type: 'text',
},
],
},
{
name: 'groupThirteen',
type: 'group',
fields: [
{
name: 'field61',
type: 'text',
},
{
name: 'field62',
type: 'text',
},
{
name: 'field63',
type: 'text',
},
{
name: 'field64',
type: 'text',
},
{
name: 'field65',
type: 'text',
},
],
},
{
name: 'groupFourteen',
type: 'group',
fields: [
{
name: 'field66',
type: 'text',
},
{
name: 'field67',
type: 'text',
},
{
name: 'field68',
type: 'text',
},
{
name: 'field69',
type: 'text',
},
{
name: 'field70',
type: 'text',
},
],
},
{
name: 'groupFifteen',
type: 'group',
fields: [
{
name: 'field71',
type: 'text',
},
{
name: 'field72',
type: 'text',
},
{
name: 'field73',
type: 'text',
},
{
name: 'field74',
type: 'text',
},
{
name: 'field75',
type: 'text',
},
],
},
{
name: 'groupSixteen',
type: 'group',
fields: [
{
name: 'field76',
type: 'text',
},
{
name: 'field77',
type: 'text',
},
{
name: 'field78',
type: 'text',
},
{
name: 'field79',
type: 'text',
},
{
name: 'field80',
type: 'text',
},
],
},
{
name: 'groupSeventeen',
type: 'group',
fields: [
{
name: 'field81',
type: 'text',
},
{
name: 'field82',
type: 'text',
},
{
name: 'field83',
type: 'text',
},
{
name: 'field84',
type: 'text',
},
{
name: 'field85',
type: 'text',
},
],
},
{
name: 'groupEighteen',
type: 'group',
fields: [
{
name: 'field86',
type: 'text',
},
{
name: 'field87',
type: 'text',
},
{
name: 'field88',
type: 'text',
},
{
name: 'field89',
type: 'text',
},
{
name: 'field90',
type: 'text',
},
],
},
{
name: 'groupNineteen',
type: 'group',
fields: [
{
name: 'field91',
type: 'text',
},
{
name: 'field92',
type: 'text',
},
{
name: 'field93',
type: 'text',
},
{
name: 'field94',
type: 'text',
},
{
name: 'field95',
type: 'text',
},
],
},
{
name: 'groupTwenty',
type: 'group',
fields: [
{
name: 'field96',
type: 'text',
},
{
name: 'field97',
type: 'text',
},
{
name: 'field98',
type: 'text',
},
{
name: 'field99',
type: 'text',
},
{
name: 'field100',
type: 'text',
},
],
},
],
}

View File

@@ -0,0 +1,532 @@
import type { GlobalConfig } from '../../../packages/payload/src/globals/config/types'
import { noForceRenderGlobalSlug } from '../slugs'
export const GlobalNoForceRender: GlobalConfig = {
slug: noForceRenderGlobalSlug,
admin: {
forceRenderAllFields: false,
},
fields: [
{
name: 'groupOne',
type: 'group',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
{
name: 'field3',
type: 'text',
},
{
name: 'field4',
type: 'text',
},
{
name: 'field5',
type: 'text',
},
],
},
{
name: 'groupTwo',
type: 'group',
fields: [
{
name: 'field6',
type: 'text',
},
{
name: 'field7',
type: 'text',
},
{
name: 'field8',
type: 'text',
},
{
name: 'field9',
type: 'text',
},
{
name: 'field10',
type: 'text',
},
],
},
{
name: 'groupThree',
type: 'group',
fields: [
{
name: 'field11',
type: 'text',
},
{
name: 'field12',
type: 'text',
},
{
name: 'field13',
type: 'text',
},
{
name: 'field14',
type: 'text',
},
{
name: 'field15',
type: 'text',
},
],
},
{
name: 'groupFour',
type: 'group',
fields: [
{
name: 'field16',
type: 'text',
},
{
name: 'field17',
type: 'text',
},
{
name: 'field18',
type: 'text',
},
{
name: 'field19',
type: 'text',
},
{
name: 'field20',
type: 'text',
},
],
},
{
name: 'groupFive',
type: 'group',
fields: [
{
name: 'field21',
type: 'text',
},
{
name: 'field22',
type: 'text',
},
{
name: 'field23',
type: 'text',
},
{
name: 'field24',
type: 'text',
},
{
name: 'field25',
type: 'text',
},
],
},
{
name: 'groupSix',
type: 'group',
fields: [
{
name: 'field26',
type: 'text',
},
{
name: 'field27',
type: 'text',
},
{
name: 'field28',
type: 'text',
},
{
name: 'field29',
type: 'text',
},
{
name: 'field30',
type: 'text',
},
],
},
{
name: 'groupSeven',
type: 'group',
fields: [
{
name: 'field31',
type: 'text',
},
{
name: 'field32',
type: 'text',
},
{
name: 'field33',
type: 'text',
},
{
name: 'field34',
type: 'text',
},
{
name: 'field35',
type: 'text',
},
],
},
{
name: 'groupEight',
type: 'group',
fields: [
{
name: 'field36',
type: 'text',
},
{
name: 'field37',
type: 'text',
},
{
name: 'field38',
type: 'text',
},
{
name: 'field39',
type: 'text',
},
{
name: 'field40',
type: 'text',
},
],
},
{
name: 'groupNine',
type: 'group',
fields: [
{
name: 'field41',
type: 'text',
},
{
name: 'field42',
type: 'text',
},
{
name: 'field43',
type: 'text',
},
{
name: 'field44',
type: 'text',
},
{
name: 'field45',
type: 'text',
},
],
},
{
name: 'groupTen',
type: 'group',
fields: [
{
name: 'field46',
type: 'text',
},
{
name: 'field47',
type: 'text',
},
{
name: 'field48',
type: 'text',
},
{
name: 'field49',
type: 'text',
},
{
name: 'field50',
type: 'text',
},
],
},
{
name: 'groupEleven',
type: 'group',
fields: [
{
name: 'field51',
type: 'text',
},
{
name: 'field52',
type: 'text',
},
{
name: 'field53',
type: 'text',
},
{
name: 'field54',
type: 'text',
},
{
name: 'field55',
type: 'text',
},
],
},
{
name: 'groupTwelve',
type: 'group',
fields: [
{
name: 'field56',
type: 'text',
},
{
name: 'field57',
type: 'text',
},
{
name: 'field58',
type: 'text',
},
{
name: 'field59',
type: 'text',
},
{
name: 'field60',
type: 'text',
},
],
},
{
name: 'groupThirteen',
type: 'group',
fields: [
{
name: 'field61',
type: 'text',
},
{
name: 'field62',
type: 'text',
},
{
name: 'field63',
type: 'text',
},
{
name: 'field64',
type: 'text',
},
{
name: 'field65',
type: 'text',
},
],
},
{
name: 'groupFourteen',
type: 'group',
fields: [
{
name: 'field66',
type: 'text',
},
{
name: 'field67',
type: 'text',
},
{
name: 'field68',
type: 'text',
},
{
name: 'field69',
type: 'text',
},
{
name: 'field70',
type: 'text',
},
],
},
{
name: 'groupFifteen',
type: 'group',
fields: [
{
name: 'field71',
type: 'text',
},
{
name: 'field72',
type: 'text',
},
{
name: 'field73',
type: 'text',
},
{
name: 'field74',
type: 'text',
},
{
name: 'field75',
type: 'text',
},
],
},
{
name: 'groupSixteen',
type: 'group',
fields: [
{
name: 'field76',
type: 'text',
},
{
name: 'field77',
type: 'text',
},
{
name: 'field78',
type: 'text',
},
{
name: 'field79',
type: 'text',
},
{
name: 'field80',
type: 'text',
},
],
},
{
name: 'groupSeventeen',
type: 'group',
fields: [
{
name: 'field81',
type: 'text',
},
{
name: 'field82',
type: 'text',
},
{
name: 'field83',
type: 'text',
},
{
name: 'field84',
type: 'text',
},
{
name: 'field85',
type: 'text',
},
],
},
{
name: 'groupEighteen',
type: 'group',
fields: [
{
name: 'field86',
type: 'text',
},
{
name: 'field87',
type: 'text',
},
{
name: 'field88',
type: 'text',
},
{
name: 'field89',
type: 'text',
},
{
name: 'field90',
type: 'text',
},
],
},
{
name: 'groupNineteen',
type: 'group',
fields: [
{
name: 'field91',
type: 'text',
},
{
name: 'field92',
type: 'text',
},
{
name: 'field93',
type: 'text',
},
{
name: 'field94',
type: 'text',
},
{
name: 'field95',
type: 'text',
},
],
},
{
name: 'groupTwenty',
type: 'group',
fields: [
{
name: 'field96',
type: 'text',
},
{
name: 'field97',
type: 'text',
},
{
name: 'field98',
type: 'text',
},
{
name: 'field99',
type: 'text',
},
{
name: 'field100',
type: 'text',
},
],
},
],
}

Some files were not shown because too many files have changed in this diff Show More