Compare commits
42 Commits
plugin-for
...
v2.32.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8ec6a7490 | ||
|
|
5ecee3f6f6 | ||
|
|
a09fefaed7 | ||
|
|
e97606a91b | ||
|
|
fde64094ac | ||
|
|
1b1d690874 | ||
|
|
09d715ff38 | ||
|
|
db51b4c5ab | ||
|
|
0ec5e096f3 | ||
|
|
c3f80aaa4b | ||
|
|
2ba5cae83e | ||
|
|
c2120c06bb | ||
|
|
9c6ab39bf4 | ||
|
|
965d3d8d47 | ||
|
|
34ce21c1f8 | ||
|
|
ca6725b4ec | ||
|
|
a54fc12189 | ||
|
|
cfe0fdf3f6 | ||
|
|
2e2013602d | ||
|
|
9f17391475 | ||
|
|
cd12963296 | ||
|
|
165442028c | ||
|
|
3c4c32fecd | ||
|
|
7648b32669 | ||
|
|
c835a21707 | ||
|
|
a5e6ea5737 | ||
|
|
106d7dde23 | ||
|
|
276a6dde06 | ||
|
|
f12cb6298a | ||
|
|
2e352552d1 | ||
|
|
aae52181b0 | ||
|
|
07ff181ccf | ||
|
|
f430db8bc5 | ||
|
|
a2e54db469 | ||
|
|
73bd4370b8 | ||
|
|
95a4443ea1 | ||
|
|
59ee821cec | ||
|
|
4892d96515 | ||
|
|
b0de37ba95 | ||
|
|
0cf96785bc | ||
|
|
e7ae5f0a97 | ||
|
|
7039b1f82e |
12
.github/workflows/label-on-change.yml
vendored
12
.github/workflows/label-on-change.yml
vendored
@@ -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:
|
||||
|
||||
2
.github/workflows/lock-issues.yml
vendored
2
.github/workflows/lock-issues.yml
vendored
@@ -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
|
||||
|
||||
78
.github/workflows/main.yml
vendored
78
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/post-release.yml
vendored
2
.github/workflows/post-release.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
post_release:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
2
.github/workflows/release-canary.yml
vendored
2
.github/workflows/release-canary.yml
vendored
@@ -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"
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
6
.github/workflows/triage.yml
vendored
6
.github/workflows/triage.yml
vendored
@@ -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:
|
||||
|
||||
42
CHANGELOG.md
42
CHANGELOG.md
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
\`\`\`
|
||||
`
|
||||
}
|
||||
],
|
||||
]}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 team’s 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. We’ll remind you 7 days before your trial ends and
|
||||
you can cancel anytime.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||

|
||||
<br />
|
||||
|
||||

|
||||
<br />
|
||||
|
||||

|
||||
<br />
|
||||
|
||||

|
||||
<br />
|
||||
|
||||

|
||||
<br />
|
||||
|
||||

|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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:
|
||||
|
||||
28
package.json
28
package.json
@@ -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": {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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:*"
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -122,7 +122,7 @@ const Condition: React.FC<Props> = (props) => {
|
||||
onChange: setInternalValue,
|
||||
operator: operatorValue,
|
||||
options: valueOptions,
|
||||
value: internalValue,
|
||||
value: internalValue ?? '',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
))}
|
||||
|
||||
@@ -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 : ''),
|
||||
|
||||
@@ -7,6 +7,7 @@ export type Props = {
|
||||
className?: string
|
||||
fieldTypes: FieldTypes
|
||||
forceRender?: boolean
|
||||
forceRenderAllFields?: boolean
|
||||
margins?: 'small' | false
|
||||
permissions?:
|
||||
| {
|
||||
|
||||
@@ -42,7 +42,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
|
||||
duplicateRow,
|
||||
fieldTypes,
|
||||
fields,
|
||||
forceRender = false,
|
||||
forceRender,
|
||||
hasMaxRows,
|
||||
indexPath,
|
||||
isSortable,
|
||||
|
||||
@@ -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],
|
||||
)
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@ export const ConfigProvider: React.FC<{ children: React.ReactNode; config: Sanit
|
||||
const resolvedConfig = await incomingConfig
|
||||
setConfig(resolvedConfig)
|
||||
}
|
||||
awaitConfig()
|
||||
void awaitConfig()
|
||||
}
|
||||
}, [incomingConfig])
|
||||
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
* */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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'
|
||||
|
||||
16
packages/payload/src/express/middleware/addParsedQuery.ts
Normal file
16
packages/payload/src/express/middleware/addParsedQuery.ts
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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()])),
|
||||
|
||||
@@ -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
|
||||
* */
|
||||
|
||||
@@ -405,7 +405,7 @@ function buildObjectType({
|
||||
}
|
||||
|
||||
await Promise.all(resultPromises)
|
||||
return results
|
||||
return results.filter((doc) => doc != null)
|
||||
}
|
||||
|
||||
let id = value
|
||||
|
||||
@@ -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,
|
||||
|
||||
386
packages/payload/src/translations/sl.json
Normal file
386
packages/payload/src/translations/sl.json
Normal 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}}"
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
5805
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
||||
import type { CollectionConfig } from 'payload/dist/collections/config/types'
|
||||
|
||||
import { customIdCollectionSlug } from '../slugs'
|
||||
|
||||
export const CustomIdTab: CollectionConfig = {
|
||||
slug: 'customIdTab',
|
||||
labels: {
|
||||
|
||||
532
test/admin/collections/ForceRender.ts
Normal file
532
test/admin/collections/ForceRender.ts
Normal 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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
532
test/admin/collections/NoForceRender.ts
Normal file
532
test/admin/collections/NoForceRender.ts
Normal 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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
532
test/admin/globals/ForceRender.ts
Normal file
532
test/admin/globals/ForceRender.ts
Normal 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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
532
test/admin/globals/NoForceRender.ts
Normal file
532
test/admin/globals/NoForceRender.ts
Normal 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
Reference in New Issue
Block a user