Compare commits

..

14 Commits

Author SHA1 Message Date
Elliot DeNolf
2d6e7f8a37 chore(release): v3.0.0-beta.84 [skip ci] 2024-08-16 13:56:50 -04:00
James Mikrut
3d37d74c6e fix: adds default drizzle package exports (#7728)
Default exports were missing for Drizzle package.
2024-08-16 13:40:41 -04:00
James Mikrut
de19822ed4 fix: ensures user is accurate in useAuth (#7727)
## Description

Fixes an issue where the `user` could be out of date after logging in.
2024-08-16 17:10:32 +00:00
Tylan Davis
2b2bcb5264 fix: corrects logout icon styling (#7726)
## Description

before: 
<img width="89" alt="Screenshot 2024-08-16 at 12 43 56 PM"
src="https://github.com/user-attachments/assets/1052cfdb-6dde-4b65-a4c0-e37a909dac34">

after:
<img width="48" alt="Screenshot 2024-08-16 at 12 43 35 PM"
src="https://github.com/user-attachments/assets/aa4d6aed-4a78-4b17-a209-df3618b273a1">

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

## Type of change

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

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

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 17:01:42 +00:00
Elliot DeNolf
e9b01e6d9f chore(release): v3.0.0-beta.83 [skip ci] 2024-08-16 12:36:30 -04:00
Alessio Gravili
b0a760193e fix: type RelationshipFieldClient typed incorrectly (#7725) 2024-08-16 12:35:05 -04:00
Jarrod Flesch
95569e44e4 fix: login with username server validations (#7719) 2024-08-16 12:07:53 -04:00
Paul
11816080a6 fix: bin script error when running on linux (#7721)
Fixes https://github.com/payloadcms/payload/issues/7717
2024-08-16 10:07:03 -06:00
Paul
3a86822f0a fix(ui): ensure that aborting Autosave always has a valid reason for the controller - fixes uncaught error (#7723) 2024-08-16 16:04:32 +00:00
Jarrod Flesch
6f8604e18c fix: ensures users cannot be created without confirming pw (#7583) 2024-08-16 11:44:27 -04:00
Tylan Davis
aec3f5e308 chore: admin panel style updates (#7720)
## Description

Minor admin panel style updates:
- Adjusts document header title spacing.
- Makes toast notifications more apparent.
- Adjusts alignment of create new button.
- Improves chevron icon.

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

## Type of change

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

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 15:23:08 +00:00
Jarrod Flesch
e0a5de6730 chore: extends dropzone and upload field (#7713)
## Description

Tweaks to Upload and Dropzone components, making them more extendable.

- Dropzone adds prop to allow multiple files
- Upload correctly sets url if state is initialized with a File

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

## Type of change

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 09:38:41 -04:00
Paul
5eee49da9a feat(plugin-seo): pass req through to generate functions (#7711)
Closes https://github.com/payloadcms/payload/issues/7708
2024-08-15 23:09:08 +00:00
dependabot[bot]
b7d01dec70 chore(deps): bump pnpm/action-setup from 3 to 4 in /.github/actions/setup in the github_actions group across 1 directory (#7687)
Bumps the github_actions group with 1 update in the
/.github/actions/setup directory:
[pnpm/action-setup](https://github.com/pnpm/action-setup).

Updates `pnpm/action-setup` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>An error is thrown if one version of pnpm is specified in the
<code>packageManager</code> field of <code>package.json</code> and a
different version is specified in the action's settings <a
href="https://redirect.github.com/pnpm/action-setup/pull/122">#122</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe02b34f77"><code>fe02b34</code></a>
docs: bump action-setup version in README</li>
<li><a
href="bee1f099e5"><code>bee1f09</code></a>
feat: throw error when multiple versions specified (<a
href="https://redirect.github.com/pnpm/action-setup/issues/122">#122</a>)</li>
<li><a
href="ce859e384f"><code>ce859e3</code></a>
refactor: replace <code>fs-extra</code> with Node.js built-in fs methods
(<a
href="https://redirect.github.com/pnpm/action-setup/issues/120">#120</a>)</li>
<li><a
href="2ab6dce4f5"><code>2ab6dce</code></a>
docs(README): fix link to LICENSE</li>
<li><a
href="e280758d01"><code>e280758</code></a>
docs(README): update dependency versions (<a
href="https://redirect.github.com/pnpm/action-setup/issues/117">#117</a>)</li>
<li><a
href="129abb77bf"><code>129abb7</code></a>
Bump undici from 5.28.2 to 5.28.3 (<a
href="https://redirect.github.com/pnpm/action-setup/issues/115">#115</a>)</li>
<li>See full diff in <a
href="https://github.com/pnpm/action-setup/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pnpm/action-setup&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 15:57:33 -04:00
61 changed files with 221 additions and 157 deletions

View File

@@ -25,7 +25,7 @@ runs:
node-version: ${{ inputs.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ inputs.pnpm-version }}
run_install: false

View File

@@ -119,7 +119,7 @@ A function that allows you to return any meta title, including from document's c
{
// ...
seoPlugin({
generateTitle: ({ ...docInfo, doc, locale }) => `Website.com — ${doc?.title}`,
generateTitle: ({ ...docInfo, doc, locale, req }) => `Website.com — ${doc?.title}`,
})
}
```
@@ -133,7 +133,7 @@ A function that allows you to return any meta description, including from docume
{
// ...
seoPlugin({
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt,
generateDescription: ({ ...docInfo, doc, locale, req }) => doc?.excerpt,
})
}
```
@@ -147,7 +147,7 @@ A function that allows you to return any meta image, including from document's c
{
// ...
seoPlugin({
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage,
generateImage: ({ ...docInfo, doc, locale, req }) => doc?.featuredImage,
})
}
```
@@ -161,7 +161,7 @@ A function called by the search preview component to display the actual URL of y
{
// ...
seoPlugin({
generateURL: ({ ...docInfo, doc, locale }) =>
generateURL: ({ ...docInfo, doc, locale, req }) =>
`https://yoursite.com/${collection?.slug}/${doc?.slug}`,
})
}

View File

@@ -1,6 +1,6 @@
{
"name": "payload-monorepo",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "create-payload-app",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-mongodb",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The officially supported MongoDB database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-postgres",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The officially supported Postgres database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-sqlite",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The officially supported SQLite database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/drizzle",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "A library of shared functions used by different payload database adapters",
"homepage": "https://payloadcms.com",
"repository": {
@@ -58,11 +58,13 @@
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./types": {
"import": "./dist/types.js",
"types": "./dist/types.d.ts"
"types": "./dist/types.d.ts",
"default": "./dist/types.js"
}
},
"main": "./dist/index.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-nodemailer",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload Nodemailer Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-resend",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload Resend Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/graphql",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview-react",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official React SDK for Payload Live Preview",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview-vue",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official Vue SDK for Payload Live Preview",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official live preview JavaScript SDK for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/next",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -2,8 +2,8 @@
.doc-header {
width: 100%;
margin-top: base(0.5);
padding-bottom: calc(var(--base) * 1.5);
margin-top: base(0.4);
padding-bottom: calc(var(--base) * 1.2);
display: flex;
align-items: center;
position: relative;
@@ -27,6 +27,9 @@
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
padding-bottom: base(0.2);
line-height: 1;
vertical-align: top;
}
@include mid-break {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -149,8 +149,10 @@ export const Auth: React.FC<Props> = (props) => {
{(showPasswordFields || requirePassword) && (
<div className={`${baseClass}__changing-password`}>
<PasswordField
autoComplete="new-password"
field={{
name: 'password',
_path: 'password',
admin: {
disabled,
},

View File

@@ -98,14 +98,18 @@ export const DefaultEditView: React.FC = () => {
if (globalSlug) classes.push(`global-edit--${globalSlug}`)
if (collectionSlug) classes.push(`collection-edit--${collectionSlug}`)
const [schemaPath, setSchemaPath] = React.useState(entitySlug)
const [schemaPath, setSchemaPath] = React.useState(() => {
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
return `_${entitySlug}.auth`
}
return entitySlug
})
const [validateBeforeSubmit, setValidateBeforeSubmit] = useState(() => {
if (
operation === 'create' &&
collectionConfig.auth &&
!collectionConfig.auth.disableLocalStrategy
)
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
return true
}
return false
})

View File

@@ -13,7 +13,7 @@
&__header {
display: flex;
align-items: center;
align-items: flex-end;
flex-wrap: wrap;
gap: base(0.8);
@@ -27,7 +27,7 @@
.pill {
position: relative;
margin: 0;
margin: 0 0 base(0.2);
}
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env node --no-deprecation
#!/usr/bin/env -S node --no-deprecation
import path from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'

View File

@@ -1,6 +1,6 @@
{
"name": "payload",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
"keywords": [
"admin panel",

View File

@@ -44,11 +44,11 @@ export const ensureUsernameOrEmail = <TSlug extends CollectionSlug>({
missingFields = true
}
// prevent clearing email if no username
if ('email' in data && !data.email && !originalDoc.username) {
if ('email' in data && !data.email && !originalDoc.username && !data?.username) {
missingFields = true
}
// prevent clearing username if no email
if ('username' in data && !data.username && !originalDoc.email) {
if ('username' in data && !data.username && !originalDoc.email && !data?.email) {
missingFields = true
}
}

View File

@@ -962,7 +962,9 @@ export type SingleRelationshipFieldClient = {
export type RelationshipField = PolymorphicRelationshipField | SingleRelationshipField
export type RelationshipFieldClient = PolymorphicRelationshipFieldClient
export type RelationshipFieldClient =
| PolymorphicRelationshipFieldClient
| SingleRelationshipFieldClient
export type ValueWithRelation = {
relationTo: CollectionSlug

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-cloud-storage",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official cloud storage plugin for Payload CMS",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-cloud",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official Payload Cloud plugin",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-form-builder",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Form builder plugin for Payload CMS",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-nested-docs",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The official Nested Docs plugin for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-redirects",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Redirects plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-relationship-object-ids",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "A Payload plugin to store all relationship IDs as ObjectIDs",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-search",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Search plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-seo",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "SEO plugin for Payload",
"keywords": [
"payload",

View File

@@ -61,7 +61,7 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateDescription>[0]),
} satisfies Omit<Parameters<GenerateDescription>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -57,7 +57,7 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateImage>[0]),
} satisfies Omit<Parameters<GenerateImage>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -62,7 +62,7 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateTitle>[0]),
} satisfies Omit<Parameters<GenerateTitle>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -49,7 +49,7 @@ export const PreviewComponent: React.FC<PreviewProps> = ({
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateURL>[0]),
} satisfies Omit<Parameters<GenerateURL>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -134,11 +134,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
req.t
const result = pluginConfig.generateTitle
? await pluginConfig.generateTitle(
req.data as unknown as Parameters<GenerateTitle>[0],
)
? await pluginConfig.generateTitle({
...req.data,
req,
} as unknown as Parameters<GenerateTitle>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -148,10 +149,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateDescription
? await pluginConfig.generateDescription(
req.data as unknown as Parameters<GenerateDescription>[0],
)
? await pluginConfig.generateDescription({
...req.data,
req,
} as unknown as Parameters<GenerateDescription>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -161,8 +164,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateURL
? await pluginConfig.generateURL(req.data as unknown as Parameters<GenerateURL>[0])
? await pluginConfig.generateURL({
...req.data,
req,
} as unknown as Parameters<GenerateURL>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -172,10 +179,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateImage
? await pluginConfig.generateImage(
req.data as unknown as Parameters<GenerateImage>[0],
)
? await pluginConfig.generateImage({
...req.data,
req,
} as unknown as Parameters<GenerateImage>[0])
: ''
return new Response(result, { status: 200 })
},

View File

@@ -1,23 +1,24 @@
import type { DocumentInfoContext } from '@payloadcms/ui'
import type { Field, TextField, TextareaField, UploadField } from 'payload'
import type { Field, PayloadRequest, TextField, TextareaField, UploadField } from 'payload'
export type GenerateTitle<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type GenerateDescription<T = any> = (
args: {
doc: T
locale?: string
req: PayloadRequest
} & DocumentInfoContext,
) => Promise<string> | string
export type GenerateImage<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type GenerateURL<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type SEOPluginConfig = {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-stripe",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Stripe plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-lexical",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The officially supported Lexical richtext adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-slate",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "The officially supported Slate richtext adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-azure",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Azure Blob Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-gcs",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Google Cloud Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-s3",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Amazon S3",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-uploadthing",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for uploadthing",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-vercel-blob",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Vercel Blob Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/translations",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/ui",
"version": "3.0.0-beta.82",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -224,7 +224,7 @@ export const Autosave: React.FC<Props> = ({
if (autosaveTimeout) clearTimeout(autosaveTimeout)
if (abortController.signal) {
try {
abortController.abort()
abortController.abort('Autosave closed early.')
} catch (error) {
// swallow error
}

View File

@@ -13,13 +13,20 @@ const handleDragOver = (e: DragEvent) => {
const baseClass = 'dropzone'
export type Props = {
className?: string
mimeTypes?: string[]
onChange: (e: FileList) => void
onPasteUrlClick?: () => void
readonly className?: string
readonly mimeTypes?: string[]
readonly multipleFiles?: boolean
readonly onChange: (e: FileList) => void
readonly onPasteUrlClick?: () => void
}
export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPasteUrlClick }) => {
export const Dropzone: React.FC<Props> = ({
className,
mimeTypes,
multipleFiles,
onChange,
onPasteUrlClick,
}) => {
const dropRef = React.useRef<HTMLDivElement>(null)
const [dragging, setDragging] = React.useState(false)
const inputRef = React.useRef(null)
@@ -111,17 +118,21 @@ export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPa
>
{t('upload:selectFile')}
</Button>
<Button
buttonStyle="secondary"
className={`${baseClass}__file-button`}
onClick={onPasteUrlClick}
size="medium"
>
{t('upload:pasteURL')}
</Button>
{typeof onPasteUrlClick === 'function' && (
<Button
buttonStyle="secondary"
className={`${baseClass}__file-button`}
onClick={onPasteUrlClick}
size="medium"
>
{t('upload:pasteURL')}
</Button>
)}
<input
accept={mimeTypes?.join(',')}
aria-hidden="true"
className={`${baseClass}__hidden-input`}
multiple={multipleFiles}
onChange={handleFileSelection}
ref={inputRef}
type="file"

View File

@@ -1,11 +1,12 @@
@import '../../scss/styles';
.id-label {
font-size: base(0.75);
font-size: base(0.8);
line-height: base(1.2);
font-weight: normal;
color: var(--theme-elevation-600);
background: var(--theme-elevation-100);
padding: 0 base(0.6);
padding: base(0.2) base(0.4);
border-radius: $style-radius-m;
display: inline-flex;
}

View File

@@ -1,7 +1,7 @@
@import '../../scss/styles.scss';
.render-title {
display: inline-flex;
display: inline-block;
&__id {
vertical-align: middle;
position: relative;

View File

@@ -109,15 +109,7 @@ export const Upload: React.FC<UploadProps> = (props) => {
const handleFileChange = useCallback(
(newFile: File) => {
if (newFile instanceof File) {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const imgSrc = e.target?.result
if (typeof imgSrc === 'string') {
setFileSrc(imgSrc)
}
}
fileReader.readAsDataURL(newFile)
setFileSrc(URL.createObjectURL(newFile))
}
setValue(newFile)
@@ -202,6 +194,9 @@ export const Upload: React.FC<UploadProps> = (props) => {
useEffect(() => {
setDoc(reduceFieldsToValues(initialState || {}, true))
if (initialState?.file?.value instanceof File) {
setFileSrc(URL.createObjectURL(initialState.file.value))
}
setReplacingFile(false)
}, [initialState])

View File

@@ -32,6 +32,7 @@ export { Collapsible } from '../../elements/Collapsible/index.js'
export { CopyToClipboard } from '../../elements/CopyToClipboard/index.js'
export { DeleteMany } from '../../elements/DeleteMany/index.js'
export { DocumentControls } from '../../elements/DocumentControls/index.js'
export { Dropzone } from '../../elements/Dropzone/index.js'
export { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js'
export { DocumentFields } from '../../elements/DocumentFields/index.js'
export { Drawer, DrawerToggler, formatDrawerSlug } from '../../elements/Drawer/index.js'

View File

@@ -26,6 +26,6 @@ export const ChevronIcon: React.FC<{
width={20}
xmlns="http://www.w3.org/2000/svg"
>
<path className="stroke" d="M6 9L10 13L14 9" strokeLinecap="square" />
<path className="stroke" d="M6 8L10 12.5L14 8" strokeLinecap="square" />
</svg>
)

View File

@@ -13,7 +13,8 @@ export const LogOutIcon: React.FC = () => (
>
<path
className="stroke"
d="M8 16H5.33333C4.97971 16 4.64057 15.8595 4.39052 15.6095C4.14048 15.3594 4 15.0203 4 14.6667V5.33333C4 4.97971 4.14048 4.64057 4.39052 4.39052C4.64057 4.14048 4.97971 4 5.33333 4H8M12.6667 13.3333L16 10M16 10L12.6667 6.66667M16 10H8"
d="M12 16H14.6667C15.0203 16 15.3594 15.8595 15.6095 15.6095C15.8595 15.3594 16 15.0203 16 14.6667V5.33333C16 4.97971 15.8595 4.64057 15.6095 4.39052C15.3594 4.14048 15.0203 4 14.6667 4H12M7.33333 13.3333L4 10M4 10L7.33333 6.66667M4 10H12"
strokeLinecap="square"
/>
</svg>
)

View File

@@ -263,6 +263,11 @@ export function AuthProvider({
}
}, [debouncedLocationChange, refreshCookie, id])
// When initialUser changes, reset in state
useEffect(() => {
setUser(initialUser)
}, [initialUser])
useEffect(() => {
setLastLocationChange(Date.now())
}, [pathname])

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -120,7 +120,7 @@ describe('auth', () => {
await ensureCompilationIsDone({ page, serverURL })
})
describe('authenticated users', () => {
describe('passwords', () => {
beforeAll(() => {
url = new AdminUrlUtil(serverURL, slug)
})
@@ -155,6 +155,29 @@ describe('auth', () => {
await expect(page.locator('#field-email')).toHaveValue(emailBeforeSave)
})
test('should prevent new user creation without confirm password', async () => {
await page.goto(url.create)
await page.locator('#field-email').fill('dev2@payloadcms.com')
await page.locator('#field-password').fill('password')
// should fail to save without confirm password
await page.locator('#action-save').click()
await expect(
page.locator('.field-type.confirm-password .tooltip--show', {
hasText: exactText('This field is required.'),
}),
).toBeVisible()
// should succeed with matching confirm password
await page.locator('#field-confirm-password').fill('password')
await saveDocAndAssert(page, '#action-save')
})
})
describe('authenticated users', () => {
beforeAll(() => {
url = new AdminUrlUtil(serverURL, slug)
})
test('should have up-to-date user in `useAuth` hook', async () => {
await page.goto(url.account)
await page.waitForURL(url.account)