Compare commits
27 Commits
v3.0.0-bet
...
fix/expose
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4283bebc37 | ||
|
|
4082680099 | ||
|
|
9056b9fe9b | ||
|
|
82f278931b | ||
|
|
a7895560a6 | ||
|
|
1f0d8da182 | ||
|
|
c91f21bb78 | ||
|
|
7136515f8d | ||
|
|
73102e97fe | ||
|
|
f37e476758 | ||
|
|
90bca15f52 | ||
|
|
872b205acc | ||
|
|
99b4359e89 | ||
|
|
b269d33278 | ||
|
|
c63b7bc606 | ||
|
|
0fb92d3a0a | ||
|
|
99228b62ce | ||
|
|
7019f22aad | ||
|
|
c4fa885e84 | ||
|
|
a9c6a91c1c | ||
|
|
a19e8d382d | ||
|
|
e6a1ca5049 | ||
|
|
6d0676ab09 | ||
|
|
93545f3103 | ||
|
|
8d10737b2f | ||
|
|
303a224072 | ||
|
|
2315719c28 |
@@ -145,7 +145,7 @@ Instead, we utilize component paths to reference React Components. This method e
|
||||
|
||||
When constructing the `ClientConfig`, Payload uses the component paths as keys to fetch the corresponding React Component imports from the Import Map. It then substitutes the `PayloadComponent` with a `MappedComponent`. A `MappedComponent` includes the React Component and additional metadata, such as whether it's a server or a client component and which props it should receive. These components are then rendered through the `<RenderComponent />` component within the Payload Admin Panel.
|
||||
|
||||
Import maps are regenerated whenever you modify any element related to component paths. This regeneration occurs at startup and whenever Hot Module Replacement (HMR) runs. If the import maps fail to regenerate during HMR, you can restart your application and execute the `payload generate:importmap` command to manually create a new import map. If you encounter any errors running this command, see the [Troubleshooting](/docs/beta/local-api/outside-nextjs#troubleshooting) section.
|
||||
Import maps are regenerated whenever you modify any element related to component paths. This regeneration occurs at startup and whenever Hot Module Replacement (HMR) runs. If the import maps fail to regenerate during HMR, you can restart your application and execute the `payload generate:importmap` command to manually create a new import map. If you encounter any errors running this command, see the [Troubleshooting](../local-api/outside-nextjs#troubleshooting) section.
|
||||
|
||||
### Component paths in external packages
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ Cookies can cross subdomains without being considered third party cookies, for e
|
||||
|
||||
##### 2. Configure cookies
|
||||
|
||||
If option 1 isn't possible, then you can get around this limitation by [configuring your cookies](https://payloadcms.com/docs/beta/authentication/overview#config-options) on your authentication collection to achieve the following setup:
|
||||
If option 1 isn't possible, then you can get around this limitation by [configuring your cookies](./overview#config-options) on your authentication collection to achieve the following setup:
|
||||
|
||||
```
|
||||
SameSite: None // allows the cookie to cross domains
|
||||
@@ -122,7 +122,7 @@ Configuration example:
|
||||
},
|
||||
```
|
||||
|
||||
If you're configuring [cors](https://payloadcms.com/docs/beta/production/preventing-abuse#cross-origin-resource-sharing-cors) in your Payload config, you won't be able to use a wildcard anymore, you'll need to specify the list of allowed domains.
|
||||
If you're configuring [cors](../production/preventing-abuse#cross-origin-resource-sharing-cors) in your Payload config, you won't be able to use a wildcard anymore, you'll need to specify the list of allowed domains.
|
||||
|
||||
|
||||
<Banner type="success">
|
||||
|
||||
@@ -84,7 +84,7 @@ export default buildConfig({
|
||||
|
||||
## Email
|
||||
|
||||
Powered by [Resend](https://resend.com), Payload Cloud comes with integrated email support out of the box. No configuration is needed, and you can use `payload.sendEmail()` to send email right from your Payload app. To learn more about sending email with Payload, checkout the [Email Configuration](https://payloadcms.com/docs/email/overview) overview.
|
||||
Powered by [Resend](https://resend.com), Payload Cloud comes with integrated email support out of the box. No configuration is needed, and you can use `payload.sendEmail()` to send email right from your Payload app. To learn more about sending email with Payload, checkout the [Email Configuration](../email/overview) overview.
|
||||
|
||||
If you are on the Pro or Enterprise plan, you can add your own custom Email domain name. From the Email page of your project’s Settings, add the domain you wish to use for email delivery. This will generate a set of DNS records. Add these records to your DNS provider and click verify to check that your records are resolving properly. Once verified, your emails will now be sent from your custom domain name.
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ You can disable this setting and solely use migrations to manage your local deve
|
||||
|
||||
For this reason, we suggest that you leave `push` as its default setting and treat your local dev database as a sandbox.
|
||||
|
||||
For more information about push mode and prototyping in development, [click here](/docs/beta/database/postgres#prototyping-in-dev-mode).
|
||||
For more information about push mode and prototyping in development, [click here](./postgres#prototyping-in-dev-mode).
|
||||
|
||||
The typical workflow in Payload is to build out your Payload configs, install plugins, and make progress in development mode - allowing Drizzle to push your changes to your local database for you. Once you're finished, you can create a migration.
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ Alternatively, you can disable `push` and rely solely on migrations to keep your
|
||||
|
||||
In Postgres, migrations are a fundamental aspect of working with Payload and you should become familiar with how they work.
|
||||
|
||||
For more information about migrations, [click here](/docs/beta/database/migrations#when-to-run-migrations).
|
||||
For more information about migrations, [click here](./migrations#when-to-run-migrations).
|
||||
|
||||
## Drizzle schema hooks
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ Alternatively, you can disable `push` and rely solely on migrations to keep your
|
||||
|
||||
In SQLite, migrations are a fundamental aspect of working with Payload and you should become familiar with how they work.
|
||||
|
||||
For more information about migrations, [click here](/docs/beta/database/migrations#when-to-run-migrations).
|
||||
For more information about migrations, [click here](./migrations#when-to-run-migrations).
|
||||
|
||||
## Drizzle schema hooks
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ import config from '@payload-config'
|
||||
const payload = await getPayload({ config })
|
||||
```
|
||||
|
||||
Both options function in exactly the same way outside of one having HMR support and the other not. For more information about using Payload outside of Next.js, [click here](/docs/beta/local-api/outside-nextjs).
|
||||
Both options function in exactly the same way outside of one having HMR support and the other not. For more information about using Payload outside of Next.js, [click here](./outside-nextjs).
|
||||
|
||||
## Local options available
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangePara
|
||||
|
||||
### `defaultToEmail`
|
||||
|
||||
Provide a fallback for the email address to send form submissions to. If the email in form configuration does not have a to email set, this email address will be used. If this is not provided then it falls back to the `defaultFromAddress` in your [email configuration](https://payloadcms.com/docs/beta/email/overview).
|
||||
Provide a fallback for the email address to send form submissions to. If the email in form configuration does not have a to email set, this email address will be used. If this is not provided then it falls back to the `defaultFromAddress` in your [email configuration](../email/overview).
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
@@ -412,7 +412,7 @@ formBuilder({
|
||||
|
||||
## Email
|
||||
|
||||
This plugin relies on the [email configuration](https://payloadcms.com/docs/beta/email/overview) defined in your payload configuration. It will read from your config and attempt to send your emails using the credentials provided.
|
||||
This plugin relies on the [email configuration](../email/overview) defined in your payload configuration. It will read from your config and attempt to send your emails using the credentials provided.
|
||||
|
||||
### Email formatting
|
||||
|
||||
|
||||
@@ -276,6 +276,10 @@ OverviewField({
|
||||
})
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
Tip: You can override the length rules by changing the minLength and maxLength props on the fields. In the case of the OverviewField you can use `titleOverrides` and `descriptionOverrides` to override the length rules.
|
||||
</Banner>
|
||||
|
||||
## TypeScript
|
||||
|
||||
All types can be directly imported:
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use client'
|
||||
import { RelationshipField, useField } from '@payloadcms/ui'
|
||||
import { RelationshipField, useField, useFieldProps } from '@payloadcms/ui'
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
initialValue?: string
|
||||
path: string
|
||||
readOnly: boolean
|
||||
}
|
||||
export function TenantFieldComponentClient({ initialValue, path, readOnly }: Props) {
|
||||
export function TenantFieldComponentClient({ initialValue, readOnly }: Props) {
|
||||
const { path } = useFieldProps()
|
||||
const { formInitializing, setValue, value } = useField({ path })
|
||||
const hasSetInitialValue = React.useRef(false)
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import React from 'react'
|
||||
import { TenantFieldComponentClient } from './Field.client'
|
||||
|
||||
export const TenantFieldComponent: React.FC<{
|
||||
path: string
|
||||
payload: Payload
|
||||
readOnly: boolean
|
||||
}> = async (args) => {
|
||||
@@ -22,7 +21,6 @@ export const TenantFieldComponent: React.FC<{
|
||||
return (
|
||||
<TenantFieldComponentClient
|
||||
initialValue={cookies.get('payload-tenant')?.value || undefined}
|
||||
path={args.path}
|
||||
readOnly={args.readOnly}
|
||||
/>
|
||||
)
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -104,7 +104,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/globals": "29.7.0",
|
||||
"@libsql/client": "0.6.2",
|
||||
"@libsql/client": "0.14.0",
|
||||
"@next/bundle-analyzer": "15.0.0-canary.173",
|
||||
"@payloadcms/db-postgres": "workspace:*",
|
||||
"@payloadcms/eslint-config": "workspace:*",
|
||||
@@ -132,8 +132,8 @@
|
||||
"create-payload-app": "workspace:*",
|
||||
"cross-env": "7.0.3",
|
||||
"dotenv": "16.4.5",
|
||||
"drizzle-kit": "0.23.2-df9e596",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.26.2",
|
||||
"drizzle-orm": "0.35.1",
|
||||
"escape-html": "^1.0.3",
|
||||
"execa": "5.1.1",
|
||||
"form-data": "3.0.1",
|
||||
@@ -163,7 +163,7 @@
|
||||
"swc-plugin-transform-remove-imports": "1.15.0",
|
||||
"tempy": "1.0.1",
|
||||
"tsx": "4.19.1",
|
||||
"turbo": "^2.1.2",
|
||||
"turbo": "^2.1.3",
|
||||
"typescript": "5.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The officially supported MongoDB database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -246,6 +246,10 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
|
||||
buildSchemaOptions: BuildSchemaOptions,
|
||||
): void => {
|
||||
field.fields.forEach((subField: Field) => {
|
||||
if (fieldIsVirtual(subField)) {
|
||||
return
|
||||
}
|
||||
|
||||
const addFieldSchema: FieldSchemaGenerator = fieldToSchemaMap[subField.type]
|
||||
|
||||
if (addFieldSchema) {
|
||||
@@ -501,6 +505,10 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
|
||||
buildSchemaOptions: BuildSchemaOptions,
|
||||
): void => {
|
||||
field.fields.forEach((subField: Field) => {
|
||||
if (fieldIsVirtual(subField)) {
|
||||
return
|
||||
}
|
||||
|
||||
const addFieldSchema: FieldSchemaGenerator = fieldToSchemaMap[subField.type]
|
||||
|
||||
if (addFieldSchema) {
|
||||
@@ -545,6 +553,9 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
|
||||
): void => {
|
||||
field.tabs.forEach((tab) => {
|
||||
if (tabHasName(tab)) {
|
||||
if (fieldIsVirtual(tab)) {
|
||||
return
|
||||
}
|
||||
const baseSchema = {
|
||||
type: buildSchema(config, tab.fields, {
|
||||
disableUnique: buildSchemaOptions.disableUnique,
|
||||
@@ -562,6 +573,9 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
|
||||
})
|
||||
} else {
|
||||
tab.fields.forEach((subField: Field) => {
|
||||
if (fieldIsVirtual(subField)) {
|
||||
return
|
||||
}
|
||||
const addFieldSchema: FieldSchemaGenerator = fieldToSchemaMap[subField.type]
|
||||
|
||||
if (addFieldSchema) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-postgres",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -50,8 +50,8 @@
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"@types/pg": "8.10.2",
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-kit": "0.23.2-df9e596",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.26.2",
|
||||
"drizzle-orm": "0.35.1",
|
||||
"pg": "8.11.3",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
|
||||
@@ -136,6 +136,7 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
|
||||
findGlobalVersions,
|
||||
findOne,
|
||||
findVersions,
|
||||
indexes: new Set<string>(),
|
||||
init,
|
||||
insert,
|
||||
migrate,
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { DrizzleConfig } from 'drizzle-orm'
|
||||
import type { PgSchema, PgTableFn, PgTransactionConfig } from 'drizzle-orm/pg-core'
|
||||
import type { Pool, PoolConfig } from 'pg'
|
||||
import type { Client, Pool, PoolConfig } from 'pg'
|
||||
|
||||
export type Args = {
|
||||
/**
|
||||
@@ -62,7 +62,9 @@ declare module 'payload' {
|
||||
afterSchemaInit: PostgresSchemaHook[]
|
||||
beforeSchemaInit: PostgresSchemaHook[]
|
||||
beginTransaction: (options?: PgTransactionConfig) => Promise<null | number | string>
|
||||
drizzle: PostgresDB
|
||||
drizzle: {
|
||||
$client: Client | Pool
|
||||
} & PostgresDB
|
||||
enums: Record<string, GenericEnum>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-sqlite",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The officially supported SQLite database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -45,11 +45,11 @@
|
||||
"prepublishOnly": "pnpm clean && pnpm turbo build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libsql/client": "^0.6.2",
|
||||
"@libsql/client": "0.14.0",
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-kit": "0.23.2-df9e596",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.26.2",
|
||||
"drizzle-orm": "0.35.1",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
"uuid": "9.0.0"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||
import type { Connect } from 'payload'
|
||||
|
||||
import { createClient } from '@libsql/client'
|
||||
@@ -27,7 +26,7 @@ export const connect: Connect = async function connect(
|
||||
}
|
||||
|
||||
const logger = this.logger || false
|
||||
this.drizzle = drizzle(this.client, { logger, schema: this.schema }) as LibSQLDatabase
|
||||
this.drizzle = drizzle(this.client, { logger, schema: this.schema })
|
||||
|
||||
if (!hotReload) {
|
||||
if (process.env.PAYLOAD_DROP_DATABASE === 'true') {
|
||||
|
||||
@@ -11,4 +11,5 @@ export const defaultDrizzleSnapshot: DrizzleSQLiteSnapshotJSON = {
|
||||
prevId: '00000000-0000-0000-0000-00000000000',
|
||||
tables: {},
|
||||
version: '6',
|
||||
views: {},
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
|
||||
findGlobalVersions,
|
||||
findOne,
|
||||
findVersions,
|
||||
indexes: new Set<string>(),
|
||||
init,
|
||||
insert,
|
||||
migrate,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { Relation } from 'drizzle-orm'
|
||||
import type {
|
||||
AnySQLiteColumn,
|
||||
@@ -9,7 +10,7 @@ import type {
|
||||
} from 'drizzle-orm/sqlite-core'
|
||||
import type { Field, SanitizedJoins } from 'payload'
|
||||
|
||||
import { createTableName } from '@payloadcms/drizzle'
|
||||
import { buildIndexName, createTableName } from '@payloadcms/drizzle'
|
||||
import { relations, sql } from 'drizzle-orm'
|
||||
import {
|
||||
foreignKey,
|
||||
@@ -416,21 +417,25 @@ export const buildTable = ({
|
||||
foreignColumns: [adapter.tables[formattedRelationTo].id],
|
||||
}).onDelete('cascade')
|
||||
|
||||
const indexName = [colName]
|
||||
const indexColumns = [colName]
|
||||
|
||||
const unique = !disableUnique && uniqueRelationships.has(relationTo)
|
||||
|
||||
if (unique) {
|
||||
indexName.push('path')
|
||||
indexColumns.push('path')
|
||||
}
|
||||
if (hasLocalizedRelationshipField) {
|
||||
indexName.push('locale')
|
||||
indexColumns.push('locale')
|
||||
}
|
||||
|
||||
relationExtraConfig[`${relationTo}IdIdx`] = createIndex({
|
||||
name: indexName,
|
||||
columnName: `${formattedRelationTo}_id`,
|
||||
tableName: relationshipsTableName,
|
||||
const indexName = buildIndexName({
|
||||
name: `${relationshipsTableName}_${formattedRelationTo}_id`,
|
||||
adapter: adapter as unknown as DrizzleAdapter,
|
||||
})
|
||||
|
||||
relationExtraConfig[indexName] = createIndex({
|
||||
name: indexColumns,
|
||||
indexName,
|
||||
unique,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,13 +3,12 @@ import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'
|
||||
import { index, uniqueIndex } from 'drizzle-orm/sqlite-core'
|
||||
|
||||
type CreateIndexArgs = {
|
||||
columnName: string
|
||||
indexName: string
|
||||
name: string | string[]
|
||||
tableName: string
|
||||
unique?: boolean
|
||||
}
|
||||
|
||||
export const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {
|
||||
export const createIndex = ({ name, indexName, unique }: CreateIndexArgs) => {
|
||||
return (table: { [x: string]: AnySQLiteColumn }) => {
|
||||
let columns
|
||||
if (Array.isArray(name)) {
|
||||
@@ -21,8 +20,8 @@ export const createIndex = ({ name, columnName, tableName, unique }: CreateIndex
|
||||
columns = [table[name]]
|
||||
}
|
||||
if (unique) {
|
||||
return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
|
||||
return uniqueIndex(indexName).on(columns[0], ...columns.slice(1))
|
||||
}
|
||||
return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
|
||||
return index(indexName).on(columns[0], ...columns.slice(1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { Relation } from 'drizzle-orm'
|
||||
import type { IndexBuilder, SQLiteColumnBuilder } from 'drizzle-orm/sqlite-core'
|
||||
import type { Field, SanitizedJoins, TabAsField } from 'payload'
|
||||
|
||||
import {
|
||||
buildIndexName,
|
||||
createTableName,
|
||||
hasLocalesTable,
|
||||
validateExistingBlockIsIdentical,
|
||||
@@ -164,10 +166,15 @@ export const traverseFields = ({
|
||||
}
|
||||
adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue
|
||||
}
|
||||
targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
|
||||
|
||||
const indexName = buildIndexName({
|
||||
name: `${newTableName}_${columnName}`,
|
||||
adapter: adapter as unknown as DrizzleAdapter,
|
||||
})
|
||||
|
||||
targetIndexes[indexName] = createIndex({
|
||||
name: field.localized ? [fieldName, '_locale'] : fieldName,
|
||||
columnName,
|
||||
tableName: newTableName,
|
||||
indexName,
|
||||
unique,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,7 +117,9 @@ export type SQLiteAdapter = {
|
||||
countDistinct: CountDistinct
|
||||
defaultDrizzleSnapshot: any
|
||||
deleteWhere: DeleteWhere
|
||||
drizzle: LibSQLDatabase
|
||||
drizzle: { $client: Client } & LibSQLDatabase<
|
||||
Record<string, GenericRelation | GenericTable> & Record<string, unknown>
|
||||
>
|
||||
dropDatabase: DropDatabase
|
||||
execute: Execute<unknown>
|
||||
/**
|
||||
@@ -165,7 +167,9 @@ declare module 'payload' {
|
||||
extends Omit<Args, 'idType' | 'logger' | 'migrationDir' | 'pool'>,
|
||||
DrizzleAdapter {
|
||||
beginTransaction: (options?: SQLiteTransactionConfig) => Promise<null | number | string>
|
||||
drizzle: LibSQLDatabase
|
||||
drizzle: { $client: Client } & LibSQLDatabase<
|
||||
Record<string, GenericRelation | GenericTable> & Record<string, unknown>
|
||||
>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
* Used for returning properly formed errors from unique fields
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-vercel-postgres",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Vercel Postgres adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -50,8 +50,8 @@
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"@vercel/postgres": "^0.9.0",
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-kit": "0.23.2-df9e596",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.26.2",
|
||||
"drizzle-orm": "0.35.1",
|
||||
"pg": "8.11.3",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
|
||||
@@ -90,6 +90,7 @@ export function vercelPostgresAdapter(args: Args = {}): DatabaseAdapterObj<Verce
|
||||
fieldConstraints: {},
|
||||
getMigrationTemplate,
|
||||
idType: postgresIDType,
|
||||
indexes: new Set<string>(),
|
||||
initializing,
|
||||
localesSuffix: args.localesSuffix || '_locales',
|
||||
logger: args.logger,
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
PostgresSchemaHook,
|
||||
} from '@payloadcms/drizzle/postgres'
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { VercelPool, VercelPostgresPoolConfig } from '@vercel/postgres'
|
||||
import type { VercelClient, VercelPool, VercelPostgresPoolConfig } from '@vercel/postgres'
|
||||
import type { DrizzleConfig } from 'drizzle-orm'
|
||||
import type { PgSchema, PgTableFn, PgTransactionConfig } from 'drizzle-orm/pg-core'
|
||||
|
||||
@@ -56,6 +56,9 @@ export type Args = {
|
||||
}
|
||||
|
||||
export type VercelPostgresAdapter = {
|
||||
drizzle: {
|
||||
$client: VercelClient | VercelPool
|
||||
} & PostgresDB
|
||||
pool?: VercelPool
|
||||
poolOptions?: Args['pool']
|
||||
} & BasePostgresAdapter
|
||||
@@ -67,7 +70,9 @@ declare module 'payload' {
|
||||
afterSchemaInit: PostgresSchemaHook[]
|
||||
beforeSchemaInit: PostgresSchemaHook[]
|
||||
beginTransaction: (options?: PgTransactionConfig) => Promise<null | number | string>
|
||||
drizzle: PostgresDB
|
||||
drizzle: {
|
||||
$client: VercelClient | VercelPool
|
||||
} & PostgresDB
|
||||
enums: Record<string, GenericEnum>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/drizzle",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "A library of shared functions used by different payload database adapters",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -46,13 +46,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-orm": "0.35.1",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
"uuid": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@libsql/client": "^0.6.2",
|
||||
"@libsql/client": "0.14.0",
|
||||
"@payloadcms/eslint-config": "workspace:*",
|
||||
"@types/pg": "8.10.2",
|
||||
"@types/to-snake-case": "1.0.0",
|
||||
|
||||
@@ -32,6 +32,7 @@ export { updateGlobal } from './updateGlobal.js'
|
||||
export { updateGlobalVersion } from './updateGlobalVersion.js'
|
||||
export { updateVersion } from './updateVersion.js'
|
||||
export { upsertRow } from './upsertRow/index.js'
|
||||
export { buildIndexName } from './utilities/buildIndexName.js'
|
||||
export { executeSchemaHooks } from './utilities/executeSchemaHooks.js'
|
||||
export { extendDrizzleTable } from './utilities/extendDrizzleTable.js'
|
||||
export { hasLocalesTable } from './utilities/hasLocalesTable.js'
|
||||
|
||||
@@ -54,7 +54,7 @@ export const createDatabase = async function (this: BasePostgresAdapter, args: A
|
||||
}
|
||||
|
||||
// import pg only when createDatabase is used
|
||||
const pg = await import('pg')
|
||||
const pg = await import('pg').then((mod) => mod.default)
|
||||
|
||||
const managementClient = new pg.Client(managementClientConfig)
|
||||
|
||||
|
||||
@@ -14,4 +14,5 @@ export const defaultDrizzleSnapshot: DrizzleSnapshotJSON = {
|
||||
sequences: {},
|
||||
tables: {},
|
||||
version: '7',
|
||||
views: {},
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import type {
|
||||
} from '../types.js'
|
||||
|
||||
import { createTableName } from '../../createTableName.js'
|
||||
import { buildIndexName } from '../../utilities/buildIndexName.js'
|
||||
import { createIndex } from './createIndex.js'
|
||||
import { parentIDColumnMap } from './parentIDColumnMap.js'
|
||||
import { setColumnID } from './setColumnID.js'
|
||||
@@ -389,21 +390,25 @@ export const buildTable = ({
|
||||
foreignColumns: [adapter.tables[formattedRelationTo].id],
|
||||
}).onDelete('cascade')
|
||||
|
||||
const indexName = [colName]
|
||||
const indexColumns = [colName]
|
||||
|
||||
const unique = !disableUnique && uniqueRelationships.has(relationTo)
|
||||
|
||||
if (unique) {
|
||||
indexName.push('path')
|
||||
indexColumns.push('path')
|
||||
}
|
||||
if (hasLocalizedRelationshipField) {
|
||||
indexName.push('locale')
|
||||
indexColumns.push('locale')
|
||||
}
|
||||
|
||||
relationExtraConfig[`${relationTo}IdIdx`] = createIndex({
|
||||
name: indexName,
|
||||
columnName: `${formattedRelationTo}_id`,
|
||||
tableName: relationshipsTableName,
|
||||
const indexName = buildIndexName({
|
||||
name: `${relationshipsTableName}_${formattedRelationTo}_id`,
|
||||
adapter,
|
||||
})
|
||||
|
||||
relationExtraConfig[indexName] = createIndex({
|
||||
name: indexColumns,
|
||||
indexName,
|
||||
unique,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,13 +3,12 @@ import { index, uniqueIndex } from 'drizzle-orm/pg-core'
|
||||
import type { GenericColumn } from '../types.js'
|
||||
|
||||
type CreateIndexArgs = {
|
||||
columnName: string
|
||||
indexName: string
|
||||
name: string | string[]
|
||||
tableName: string
|
||||
unique?: boolean
|
||||
}
|
||||
|
||||
export const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {
|
||||
export const createIndex = ({ name, indexName, unique }: CreateIndexArgs) => {
|
||||
return (table: { [x: string]: GenericColumn }) => {
|
||||
let columns
|
||||
if (Array.isArray(name)) {
|
||||
@@ -21,8 +20,8 @@ export const createIndex = ({ name, columnName, tableName, unique }: CreateIndex
|
||||
columns = [table[name]]
|
||||
}
|
||||
if (unique) {
|
||||
return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
|
||||
return uniqueIndex(indexName).on(columns[0], ...columns.slice(1))
|
||||
}
|
||||
return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
|
||||
return index(indexName).on(columns[0], ...columns.slice(1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import type {
|
||||
} from '../types.js'
|
||||
|
||||
import { createTableName } from '../../createTableName.js'
|
||||
import { buildIndexName } from '../../utilities/buildIndexName.js'
|
||||
import { hasLocalesTable } from '../../utilities/hasLocalesTable.js'
|
||||
import { validateExistingBlockIsIdentical } from '../../utilities/validateExistingBlockIsIdentical.js'
|
||||
import { buildTable } from './build.js'
|
||||
@@ -169,10 +170,12 @@ export const traverseFields = ({
|
||||
}
|
||||
adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue
|
||||
}
|
||||
targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
|
||||
|
||||
const indexName = buildIndexName({ name: `${newTableName}_${columnName}`, adapter })
|
||||
|
||||
targetIndexes[indexName] = createIndex({
|
||||
name: field.localized ? [fieldName, '_locale'] : fieldName,
|
||||
columnName,
|
||||
tableName: newTableName,
|
||||
indexName,
|
||||
unique,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import type {
|
||||
} from 'drizzle-orm/pg-core'
|
||||
import type { PgTableFn } from 'drizzle-orm/pg-core/table'
|
||||
import type { Payload, PayloadRequest } from 'payload'
|
||||
import type { ClientConfig, QueryResult } from 'pg'
|
||||
import type { Client, ClientConfig, Pool, QueryResult } from 'pg'
|
||||
|
||||
import type { extendDrizzleTable, Operators } from '../index.js'
|
||||
import type { BuildQueryJoinAliases, DrizzleAdapter, TransactionPg } from '../types.js'
|
||||
@@ -106,7 +106,7 @@ export type CreateDatabase = (args?: {
|
||||
type Schema =
|
||||
| {
|
||||
enum: typeof pgEnum
|
||||
table: PgTableFn
|
||||
table: PgTableFn<string>
|
||||
}
|
||||
| PgSchema
|
||||
|
||||
@@ -134,7 +134,9 @@ export type BasePostgresAdapter = {
|
||||
defaultDrizzleSnapshot: DrizzleSnapshotJSON
|
||||
deleteWhere: DeleteWhere
|
||||
disableCreateDatabase: boolean
|
||||
drizzle: PostgresDB
|
||||
drizzle: {
|
||||
$client: Client | Pool
|
||||
} & PostgresDB
|
||||
dropDatabase: DropDatabase
|
||||
enums: Record<string, GenericEnum>
|
||||
execute: Execute<unknown>
|
||||
@@ -149,7 +151,7 @@ export type BasePostgresAdapter = {
|
||||
localesSuffix?: string
|
||||
logger: DrizzleConfig['logger']
|
||||
operators: Operators
|
||||
pgSchema?: Schema
|
||||
pgSchema: Schema
|
||||
poolOptions?: ClientConfig
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
|
||||
@@ -212,6 +212,9 @@ export const traverseFields = ({
|
||||
if (typeof data[field.name] === 'object' && data[field.name] !== null) {
|
||||
if (field.localized) {
|
||||
Object.entries(data[field.name]).forEach(([localeKey, localeData]) => {
|
||||
// preserve array ID if there is
|
||||
localeData._uuid = data.id || data._uuid
|
||||
|
||||
traverseFields({
|
||||
adapter,
|
||||
arrays,
|
||||
@@ -237,6 +240,10 @@ export const traverseFields = ({
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// preserve array ID if there is
|
||||
const groupData = data[field.name] as Record<string, unknown>
|
||||
groupData._uuid = data.id || data._uuid
|
||||
|
||||
traverseFields({
|
||||
adapter,
|
||||
arrays,
|
||||
@@ -244,7 +251,7 @@ export const traverseFields = ({
|
||||
blocks,
|
||||
blocksToDelete,
|
||||
columnPrefix: `${columnName}_`,
|
||||
data: data[field.name] as Record<string, unknown>,
|
||||
data: groupData,
|
||||
existingLocales,
|
||||
fieldPrefix: `${fieldName}_`,
|
||||
fields: field.fields,
|
||||
@@ -275,6 +282,9 @@ export const traverseFields = ({
|
||||
if (typeof data[tab.name] === 'object' && data[tab.name] !== null) {
|
||||
if (tab.localized) {
|
||||
Object.entries(data[tab.name]).forEach(([localeKey, localeData]) => {
|
||||
// preserve array ID if there is
|
||||
localeData._uuid = data.id || data._uuid
|
||||
|
||||
traverseFields({
|
||||
adapter,
|
||||
arrays,
|
||||
@@ -300,6 +310,10 @@ export const traverseFields = ({
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const tabData = data[tab.name] as Record<string, unknown>
|
||||
// preserve array ID if there is
|
||||
tabData._uuid = data.id || data._uuid
|
||||
|
||||
traverseFields({
|
||||
adapter,
|
||||
arrays,
|
||||
@@ -307,7 +321,7 @@ export const traverseFields = ({
|
||||
blocks,
|
||||
blocksToDelete,
|
||||
columnPrefix: `${columnPrefix || ''}${toSnakeCase(tab.name)}_`,
|
||||
data: data[tab.name] as Record<string, unknown>,
|
||||
data: tabData,
|
||||
existingLocales,
|
||||
fieldPrefix: `${fieldPrefix || ''}${tab.name}_`,
|
||||
fields: tab.fields,
|
||||
|
||||
@@ -174,6 +174,7 @@ export interface DrizzleAdapter extends BaseDatabaseAdapter {
|
||||
fieldConstraints: Record<string, Record<string, string>>
|
||||
getMigrationTemplate: (args: MigrationTemplateArgs) => string
|
||||
idType: 'serial' | 'uuid'
|
||||
indexes: Set<string>
|
||||
initializing: Promise<void>
|
||||
insert: Insert
|
||||
localesSuffix?: string
|
||||
|
||||
24
packages/drizzle/src/utilities/buildIndexName.ts
Normal file
24
packages/drizzle/src/utilities/buildIndexName.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { DrizzleAdapter } from '../types.js'
|
||||
|
||||
export const buildIndexName = ({
|
||||
name,
|
||||
adapter,
|
||||
number = 0,
|
||||
}: {
|
||||
adapter: DrizzleAdapter
|
||||
name: string
|
||||
number?: number
|
||||
}): string => {
|
||||
const indexName = `${name}${number ? `_${number}` : ''}_idx`
|
||||
|
||||
if (!adapter.indexes.has(indexName)) {
|
||||
adapter.indexes.add(indexName)
|
||||
return indexName
|
||||
}
|
||||
|
||||
return buildIndexName({
|
||||
name,
|
||||
adapter,
|
||||
number: number + 1,
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-react",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official React SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-vue",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official Vue SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official live preview JavaScript SDK for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/next",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,93 +1,95 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.doc-tab {
|
||||
@extend %h5;
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.doc-tab {
|
||||
@extend %h5;
|
||||
position: relative;
|
||||
|
||||
&__link {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
&__link {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
|
||||
// Use a pseudo element for the accessability so that it doesn't take up DOM space
|
||||
// Also because the parent element has `overflow: hidden` which would clip an outline
|
||||
&:focus-visible::after {
|
||||
content: '';
|
||||
border: var(--accessibility-outline);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: var(--style-radius-s);
|
||||
background-color: var(--theme-elevation-50);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.doc-tab__count {
|
||||
background-color: var(--theme-elevation-150);
|
||||
}
|
||||
}
|
||||
|
||||
&--active {
|
||||
font-weight: 600;
|
||||
&::before {
|
||||
opacity: 1;
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
.doc-tab {
|
||||
&__count {
|
||||
background-color: var(--theme-elevation-250);
|
||||
// Use a pseudo element for the accessability so that it doesn't take up DOM space
|
||||
// Also because the parent element has `overflow: hidden` which would clip an outline
|
||||
&:focus-visible::after {
|
||||
content: '';
|
||||
border: var(--accessibility-outline);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: var(--style-radius-s);
|
||||
background-color: var(--theme-elevation-50);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.doc-tab__count {
|
||||
background-color: var(--theme-elevation-150);
|
||||
}
|
||||
}
|
||||
|
||||
&--active {
|
||||
font-weight: 600;
|
||||
&::before {
|
||||
opacity: 1;
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
.doc-tab {
|
||||
&__count {
|
||||
background-color: var(--theme-elevation-250);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.doc-tab {
|
||||
&__count {
|
||||
background-color: var(--theme-elevation-250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: base(1.2);
|
||||
padding: base(0.2) base(0.6);
|
||||
}
|
||||
|
||||
&__count {
|
||||
line-height: base(0.8);
|
||||
min-width: base(0.8);
|
||||
text-align: center;
|
||||
background-color: var(--theme-elevation-100);
|
||||
border-radius: var(--style-radius-s);
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: base(1.2);
|
||||
padding: base(0.2) base(0.6);
|
||||
}
|
||||
|
||||
&__count {
|
||||
line-height: base(0.8);
|
||||
min-width: base(0.8);
|
||||
text-align: center;
|
||||
background-color: var(--theme-elevation-100);
|
||||
border-radius: var(--style-radius-s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,54 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.doc-tabs {
|
||||
display: flex;
|
||||
|
||||
&__tabs {
|
||||
@layer payload-default {
|
||||
.doc-tabs {
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
|
||||
// this container has a gradient overlay as visual indication of `overflow: scroll`
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: sticky;
|
||||
right: 0;
|
||||
width: calc(var(--base) * 2);
|
||||
height: calc(var(--base) * 2);
|
||||
background: linear-gradient(to right, transparent, var(--theme-bg));
|
||||
flex-shrink: 0;
|
||||
z-index: 1111;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
overflow: auto;
|
||||
|
||||
@include small-break {
|
||||
&__tabs-container {
|
||||
margin-right: var(--gutter-h);
|
||||
// this container has a gradient overlay as visual indication of `overflow: scroll`
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: sticky;
|
||||
right: 0;
|
||||
width: calc(var(--base) * 2);
|
||||
height: calc(var(--base) * 2);
|
||||
background: linear-gradient(to right, transparent, var(--theme-bg));
|
||||
flex-shrink: 0;
|
||||
z-index: 1111;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
gap: var(--gutter-h);
|
||||
@include small-break {
|
||||
&__tabs-container {
|
||||
margin-right: var(--gutter-h);
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
gap: var(--gutter-h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,54 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.doc-header {
|
||||
width: 100%;
|
||||
margin-top: base(0.4);
|
||||
padding-bottom: calc(var(--base) * 1.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: var(--theme-elevation-100);
|
||||
@layer payload-default {
|
||||
.doc-header {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: calc(100% - 1px);
|
||||
}
|
||||
|
||||
&__title {
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0;
|
||||
padding-bottom: base(0.4);
|
||||
line-height: 1;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-top: base(0.25);
|
||||
padding-bottom: calc(var(--base) / 1.5);
|
||||
flex-direction: column;
|
||||
margin-top: base(0.4);
|
||||
padding-bottom: calc(var(--base) * 1.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
padding-bottom: calc(var(--base) / 2);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: var(--theme-elevation-100);
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: calc(100% - 1px);
|
||||
}
|
||||
|
||||
&__title {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0;
|
||||
padding-bottom: base(0.4);
|
||||
line-height: 1;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-top: base(0.25);
|
||||
padding-bottom: calc(var(--base) / 1.5);
|
||||
flex-direction: column;
|
||||
gap: calc(var(--base) / 2);
|
||||
padding-bottom: calc(var(--base) / 2);
|
||||
|
||||
&__title {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.document-locked {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.document-locked {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
padding: base(2);
|
||||
}
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
padding: base(2);
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.document-take-over {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.document-take-over {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
padding: base(2);
|
||||
}
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
padding: base(2);
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
.form-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(var(--base) * .5);
|
||||
margin-bottom: var(--base);
|
||||
@layer payload-default {
|
||||
.form-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(var(--base) * 0.5);
|
||||
margin-bottom: var(--base);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.leave-without-saving {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.leave-without-saving {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.8);
|
||||
padding: base(2);
|
||||
}
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.4);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.8);
|
||||
padding: base(2);
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: base(0.4);
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.4);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: base(0.4);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-shrink: 0;
|
||||
height: 100vh;
|
||||
width: var(--nav-width);
|
||||
border-right: 1px solid var(--theme-elevation-100);
|
||||
opacity: 0;
|
||||
@layer payload-default {
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-shrink: 0;
|
||||
height: 100vh;
|
||||
width: var(--nav-width);
|
||||
border-right: 1px solid var(--theme-elevation-100);
|
||||
opacity: 0;
|
||||
|
||||
[dir='rtl'] & {
|
||||
border-right: none;
|
||||
border-left: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
[dir='rtl'] & {
|
||||
border-right: none;
|
||||
border-left: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
&--nav-animate {
|
||||
transition: opacity var(--nav-trans-time) ease-in-out;
|
||||
}
|
||||
&--nav-animate {
|
||||
transition: opacity var(--nav-trans-time) ease-in-out;
|
||||
}
|
||||
|
||||
&--nav-open {
|
||||
opacity: 1;
|
||||
&--nav-open {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +1,162 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-shrink: 0;
|
||||
height: 100vh;
|
||||
width: var(--nav-width);
|
||||
border-right: 1px solid var(--theme-elevation-100);
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
|
||||
[dir='rtl'] & {
|
||||
border-right: none;
|
||||
border-left: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
&--nav-animate {
|
||||
transition: opacity var(--nav-trans-time) ease-in-out;
|
||||
}
|
||||
|
||||
&--nav-open {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&__header {
|
||||
position: absolute;
|
||||
@layer payload-default {
|
||||
.nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
height: var(--app-header-height);
|
||||
}
|
||||
left: 0;
|
||||
flex-shrink: 0;
|
||||
height: 100vh;
|
||||
width: var(--nav-width);
|
||||
border-right: 1px solid var(--theme-elevation-100);
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
|
||||
&__header-content {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__mobile-close {
|
||||
display: none;
|
||||
background: none;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding: base(0.8) 0;
|
||||
}
|
||||
|
||||
&__scroll {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: var(--app-header-height) base(1) base(2) base(1);
|
||||
overflow-y: auto;
|
||||
|
||||
// remove the scrollbar here to prevent layout shift as nav groups are toggled
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
&__label {
|
||||
color: var(--theme-elevation-400);
|
||||
}
|
||||
|
||||
&__controls {
|
||||
margin-top: auto;
|
||||
margin-bottom: 0;
|
||||
|
||||
> * {
|
||||
margin-top: base(1);
|
||||
[dir='rtl'] & {
|
||||
border-right: none;
|
||||
border-left: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
a:focus-visible {
|
||||
outline: var(--accessibility-outline);
|
||||
&--nav-animate {
|
||||
transition: opacity var(--nav-trans-time) ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&__log-out {
|
||||
&:hover {
|
||||
g {
|
||||
transform: translateX(-#{base(0.125)});
|
||||
}
|
||||
&--nav-open {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
a {
|
||||
&__header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
height: var(--app-header-height);
|
||||
}
|
||||
|
||||
&__header-content {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
padding-block: base(0.125);
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: base(1.5);
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
box-shadow: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: normal;
|
||||
padding-left: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__link-indicator {
|
||||
position: absolute;
|
||||
display: block;
|
||||
// top: 0;
|
||||
inset-inline-start: base(-1);
|
||||
width: 2px;
|
||||
height: 16px;
|
||||
border-start-end-radius: 2px;
|
||||
border-end-end-radius: 2px;
|
||||
background: var(--theme-text);
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
&__scroll {
|
||||
padding: var(--app-header-height) base(0.5) base(2);
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__scroll {
|
||||
padding: var(--app-header-height) var(--gutter-h) base(2);
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-size: base(0.875);
|
||||
line-height: base(1.5);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__mobile-close {
|
||||
display: none;
|
||||
background: none;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding: base(0.8) 0;
|
||||
}
|
||||
|
||||
&__scroll {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: var(--app-header-height) base(1) base(2) base(1);
|
||||
overflow-y: auto;
|
||||
|
||||
// remove the scrollbar here to prevent layout shift as nav groups are toggled
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
&__label {
|
||||
color: var(--theme-elevation-400);
|
||||
}
|
||||
|
||||
&__controls {
|
||||
margin-top: auto;
|
||||
margin-bottom: 0;
|
||||
|
||||
> * {
|
||||
margin-top: base(1);
|
||||
}
|
||||
|
||||
a:focus-visible {
|
||||
outline: var(--accessibility-outline);
|
||||
}
|
||||
}
|
||||
|
||||
&__log-out {
|
||||
&:hover {
|
||||
g {
|
||||
transform: translateX(-#{base(0.125)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
a {
|
||||
position: relative;
|
||||
padding-block: base(0.125);
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: base(1.5);
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
box-shadow: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: normal;
|
||||
padding-left: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__link-indicator {
|
||||
position: absolute;
|
||||
display: block;
|
||||
// top: 0;
|
||||
inset-inline-start: base(-1);
|
||||
width: 2px;
|
||||
height: 16px;
|
||||
border-start-end-radius: 2px;
|
||||
border-end-end-radius: 2px;
|
||||
background: var(--theme-text);
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
&__scroll {
|
||||
padding: var(--app-header-height) base(0.5) base(2);
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__scroll {
|
||||
padding: var(--app-header-height) var(--gutter-h) base(2);
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-size: base(0.875);
|
||||
line-height: base(1.5);
|
||||
}
|
||||
|
||||
&__mobile-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +1,57 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.template-default {
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
&--nav-animate {
|
||||
transition: grid-template-columns var(--nav-trans-time) linear;
|
||||
}
|
||||
|
||||
&--nav-open {
|
||||
.template-default {
|
||||
&__nav-overlay {
|
||||
transition: opacity var(--nav-trans-time) linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1441px) {
|
||||
@layer payload-default {
|
||||
.template-default {
|
||||
grid-template-columns: 0 auto;
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
&--nav-animate {
|
||||
transition: grid-template-columns var(--nav-trans-time) linear;
|
||||
}
|
||||
|
||||
&--nav-open {
|
||||
grid-template-columns: var(--nav-width) auto;
|
||||
.template-default {
|
||||
&__nav-overlay {
|
||||
transition: opacity var(--nav-trans-time) linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
.template-default--nav-hydrated.template-default--nav-open {
|
||||
grid-template-columns: var(--nav-width) auto;
|
||||
}
|
||||
|
||||
.template-default {
|
||||
grid-template-columns: 1fr auto;
|
||||
|
||||
.nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&--nav-hydrated {
|
||||
@media (min-width: 1441px) {
|
||||
.template-default {
|
||||
grid-template-columns: 0 auto;
|
||||
|
||||
&--nav-open {
|
||||
grid-template-columns: var(--nav-width) auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
.template-default--nav-hydrated.template-default--nav-open {
|
||||
grid-template-columns: var(--nav-width) auto;
|
||||
}
|
||||
|
||||
.template-default {
|
||||
grid-template-columns: 1fr auto;
|
||||
|
||||
.nav {
|
||||
display: unset;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&--nav-hydrated {
|
||||
grid-template-columns: 0 auto;
|
||||
|
||||
.nav {
|
||||
display: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +1,78 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.template-default {
|
||||
background-color: var(--theme-bg);
|
||||
color: var(--theme-text);
|
||||
|
||||
[dir='rtl'] &__nav-toggler-wrapper {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&__nav-toggler-wrapper {
|
||||
position: sticky;
|
||||
z-index: var(--z-modal);
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: var(--gutter-h);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__nav-toggler-container {
|
||||
height: var(--app-header-height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__nav-toggler {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.template-default {
|
||||
background-color: var(--theme-bg);
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: inherit;
|
||||
opacity: 0;
|
||||
z-index: var(--z-status);
|
||||
visibility: hidden;
|
||||
transition: all var(--nav-trans-time) linear;
|
||||
color: var(--theme-text);
|
||||
|
||||
[dir='rtl'] &__nav-toggler-wrapper {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
&__nav-toggler-wrapper {
|
||||
.hamburger {
|
||||
left: unset;
|
||||
}
|
||||
position: sticky;
|
||||
z-index: var(--z-modal);
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: var(--gutter-h);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__nav-toggler-wrapper {
|
||||
width: unset;
|
||||
justify-content: unset;
|
||||
&__nav-toggler-container {
|
||||
height: var(--app-header-height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
display: none;
|
||||
&__nav-toggler {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
background-color: var(--theme-bg);
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: inherit;
|
||||
opacity: 0;
|
||||
z-index: var(--z-status);
|
||||
visibility: hidden;
|
||||
transition: all var(--nav-trans-time) linear;
|
||||
}
|
||||
}
|
||||
|
||||
.template-default {
|
||||
&__wrap {
|
||||
min-width: 100%;
|
||||
@include mid-break {
|
||||
&__nav-toggler-wrapper {
|
||||
.hamburger {
|
||||
left: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__nav-toggler-wrapper {
|
||||
width: unset;
|
||||
justify-content: unset;
|
||||
|
||||
.hamburger {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.template-default {
|
||||
&__wrap {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
@import '../../scss/styles';
|
||||
|
||||
.template-minimal {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: base(3) $baseline;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
min-height: 100%;
|
||||
background-color: var(--theme-bg-color);
|
||||
color: var(--theme-text);
|
||||
@layer payload-default {
|
||||
.template-minimal {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: base(3) $baseline;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
min-height: 100%;
|
||||
background-color: var(--theme-bg-color);
|
||||
color: var(--theme-text);
|
||||
|
||||
&--width-normal {
|
||||
.template-minimal__wrap {
|
||||
max-width: base(24);
|
||||
width: 100%;
|
||||
&--width-normal {
|
||||
.template-minimal__wrap {
|
||||
max-width: base(24);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--width-wide {
|
||||
.template-minimal__wrap {
|
||||
max-width: base(48);
|
||||
width: 100%;
|
||||
&--width-wide {
|
||||
.template-minimal__wrap {
|
||||
max-width: base(48);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,90 +1,92 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.query-inspector {
|
||||
&__json-children {
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.query-inspector {
|
||||
&__json-children {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 8px;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px dashed var(--theme-elevation-200);
|
||||
}
|
||||
}
|
||||
|
||||
&__list-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__list-toggle {
|
||||
all: unset;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
left: -3px;
|
||||
width: calc(100% + 3px);
|
||||
|
||||
svg {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
svg .stroke {
|
||||
stroke: var(--theme-elevation-400);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
&--empty {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__toggle-row-icon {
|
||||
&--open {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
&--closed {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&__value-type {
|
||||
&--number {
|
||||
.query-inspector__value {
|
||||
color: var(--number-color);
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 8px;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px dashed var(--theme-elevation-200);
|
||||
}
|
||||
}
|
||||
|
||||
&--string {
|
||||
.query-inspector__value {
|
||||
color: var(--string-color);
|
||||
&__list-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__list-toggle {
|
||||
all: unset;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
left: -3px;
|
||||
width: calc(100% + 3px);
|
||||
|
||||
svg {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
svg .stroke {
|
||||
stroke: var(--theme-elevation-400);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
&--empty {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__row-line--nested {
|
||||
margin-left: 25px;
|
||||
}
|
||||
&__toggle-row-icon {
|
||||
&--open {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
&--closed {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&__bracket {
|
||||
position: relative;
|
||||
&__value-type {
|
||||
&--number {
|
||||
.query-inspector__value {
|
||||
color: var(--number-color);
|
||||
}
|
||||
}
|
||||
|
||||
&--position-end {
|
||||
left: 5px;
|
||||
width: calc(100% - 5px);
|
||||
&--string {
|
||||
.query-inspector__value {
|
||||
color: var(--string-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__row-line--nested {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
&__bracket {
|
||||
position: relative;
|
||||
|
||||
&--position-end {
|
||||
left: 5px;
|
||||
width: calc(100% - 5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
|
||||
@@ -18,4 +18,5 @@ export const migrationsCollection: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
graphQL: false,
|
||||
lockDocuments: false,
|
||||
}
|
||||
|
||||
@@ -49,6 +49,13 @@ type Args = {
|
||||
validRelationships: null | string[]
|
||||
}
|
||||
|
||||
function generateSchemaPath({ name, path = '' }: { name?: string; path?: string }): string {
|
||||
if (!name) {
|
||||
return path
|
||||
}
|
||||
return path ? `${path}.${name}` : name
|
||||
}
|
||||
|
||||
export const sanitizeFields = async ({
|
||||
config,
|
||||
existingFieldNames = new Set(),
|
||||
@@ -57,15 +64,13 @@ export const sanitizeFields = async ({
|
||||
parentIsLocalized,
|
||||
requireFieldLevelRichTextEditor = false,
|
||||
richTextSanitizationPromises,
|
||||
schemaPath: schemaPathArg,
|
||||
schemaPath = '',
|
||||
validRelationships,
|
||||
}: Args): Promise<Field[]> => {
|
||||
if (!fields) {
|
||||
return []
|
||||
}
|
||||
|
||||
let schemaPath = schemaPathArg
|
||||
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const field = fields[i]
|
||||
|
||||
@@ -248,9 +253,6 @@ export const sanitizeFields = async ({
|
||||
}
|
||||
|
||||
if ('fields' in field && field.fields) {
|
||||
if ('name' in field && field.name) {
|
||||
schemaPath = `${schemaPath || ''}${schemaPath ? '.' : ''}${field.name}`
|
||||
}
|
||||
field.fields = await sanitizeFields({
|
||||
config,
|
||||
existingFieldNames: fieldAffectsData(field) ? new Set() : existingFieldNames,
|
||||
@@ -259,7 +261,10 @@ export const sanitizeFields = async ({
|
||||
parentIsLocalized: parentIsLocalized || field.localized,
|
||||
requireFieldLevelRichTextEditor,
|
||||
richTextSanitizationPromises,
|
||||
schemaPath,
|
||||
schemaPath: generateSchemaPath({
|
||||
name: 'name' in field ? field.name : undefined,
|
||||
path: schemaPath,
|
||||
}),
|
||||
validRelationships,
|
||||
})
|
||||
}
|
||||
@@ -268,7 +273,6 @@ export const sanitizeFields = async ({
|
||||
for (let j = 0; j < field.tabs.length; j++) {
|
||||
const tab = field.tabs[j]
|
||||
if (tabHasName(tab)) {
|
||||
schemaPath = `${schemaPath || ''}${schemaPath ? '.' : ''}${tab.name}`
|
||||
if (typeof tab.label === 'undefined') {
|
||||
tab.label = toWords(tab.name)
|
||||
}
|
||||
@@ -282,7 +286,10 @@ export const sanitizeFields = async ({
|
||||
parentIsLocalized: parentIsLocalized || (tabHasName(tab) && tab.localized),
|
||||
requireFieldLevelRichTextEditor,
|
||||
richTextSanitizationPromises,
|
||||
schemaPath,
|
||||
schemaPath: generateSchemaPath({
|
||||
name: 'name' in tab ? tab.name : undefined,
|
||||
path: schemaPath,
|
||||
}),
|
||||
validRelationships,
|
||||
})
|
||||
field.tabs[j] = tab
|
||||
|
||||
@@ -29,4 +29,5 @@ export const getLockedDocumentsCollection = (config: Config): CollectionConfig =
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
lockDocuments: false,
|
||||
})
|
||||
|
||||
@@ -70,6 +70,7 @@ const getPreferencesCollection = (config: Config): CollectionConfig => ({
|
||||
type: 'json',
|
||||
},
|
||||
],
|
||||
lockDocuments: false,
|
||||
})
|
||||
|
||||
export default getPreferencesCollection
|
||||
|
||||
@@ -47,8 +47,12 @@ export const checkDocumentLockStatus = async ({
|
||||
throw new Error('Either collectionSlug or globalSlug must be provided.')
|
||||
}
|
||||
|
||||
if (!isLockingEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
// Only perform lock checks if overrideLock is false and locking is enabled
|
||||
if (!overrideLock && isLockingEnabled !== false) {
|
||||
if (!overrideLock) {
|
||||
const defaultLockErrorMessage = collectionSlug
|
||||
? `Document with ID ${id} is currently locked by another user and cannot be modified.`
|
||||
: `Global document with slug "${globalSlug}" is currently locked by another user and cannot be modified.`
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { Field, FieldAccess } from '../fields/config/types.js'
|
||||
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
|
||||
import type { AllOperations, Document, PayloadRequest, Where } from '../types/index.js'
|
||||
|
||||
import { combineQueries } from '../database/combineQueries.js'
|
||||
import { tabHasName } from '../fields/config/types.js'
|
||||
|
||||
type Args = {
|
||||
@@ -63,17 +64,7 @@ export async function getEntityPolicies<T extends Args>(args: T): Promise<Return
|
||||
overrideAccess: true,
|
||||
pagination: false,
|
||||
req,
|
||||
where: {
|
||||
...where,
|
||||
and: [
|
||||
...(where.and || []),
|
||||
{
|
||||
id: {
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
where: combineQueries(where, { id: { equals: id } }),
|
||||
})
|
||||
|
||||
return paginatedRes?.docs?.[0] || undefined
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Where } from '../../types/index.js'
|
||||
|
||||
export const appendVersionToQueryKey = (query: Where): Where => {
|
||||
export const appendVersionToQueryKey = (query: Where = {}): Where => {
|
||||
return Object.entries(query).reduce((res, [key, val]) => {
|
||||
if (['AND', 'and', 'OR', 'or'].includes(key) && Array.isArray(val)) {
|
||||
return {
|
||||
|
||||
@@ -3,6 +3,9 @@ import type { FindOneArgs } from '../database/types.js'
|
||||
import type { Payload, PayloadRequest } from '../types/index.js'
|
||||
import type { TypeWithVersion } from './types.js'
|
||||
|
||||
import { combineQueries } from '../database/combineQueries.js'
|
||||
import { appendVersionToQueryKey } from './drafts/appendVersionToQueryKey.js'
|
||||
|
||||
type Args = {
|
||||
config: SanitizedCollectionConfig
|
||||
id: number | string
|
||||
@@ -33,7 +36,7 @@ export const getLatestCollectionVersion = async <T extends TypeWithID = any>({
|
||||
pagination: false,
|
||||
req,
|
||||
sort: '-updatedAt',
|
||||
where: whereQuery,
|
||||
where: combineQueries(appendVersionToQueryKey(query.where), whereQuery),
|
||||
})
|
||||
;[latestVersion] = docs
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official cloud storage plugin for Payload CMS",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official Payload Cloud plugin",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-form-builder",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The official Nested Docs plugin for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-redirects",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Redirects plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-search",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Search plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-sentry",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Sentry plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-seo",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "SEO plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { GenerateDescription } from '../../types.js'
|
||||
import { defaults } from '../../defaults.js'
|
||||
import { LengthIndicator } from '../../ui/LengthIndicator.js'
|
||||
|
||||
const { maxLength, minLength } = defaults.description
|
||||
const { maxLength: maxLengthDefault, minLength: minLengthDefault } = defaults.description
|
||||
|
||||
type MetaDescriptionProps = {
|
||||
readonly hasGenerateDescriptionFn: boolean
|
||||
@@ -35,6 +35,8 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
|
||||
components: { Label },
|
||||
},
|
||||
label,
|
||||
maxLength: maxLengthFromProps,
|
||||
minLength: minLengthFromProps,
|
||||
required,
|
||||
},
|
||||
hasGenerateDescriptionFn,
|
||||
@@ -55,6 +57,9 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
|
||||
const { getData } = useForm()
|
||||
const docInfo = useDocumentInfo()
|
||||
|
||||
const maxLength = maxLengthFromProps || maxLengthDefault
|
||||
const minLength = minLengthFromProps || minLengthDefault
|
||||
|
||||
const field: FieldType<string> = useField({
|
||||
path: pathFromContext,
|
||||
} as Options)
|
||||
|
||||
@@ -23,7 +23,7 @@ import { defaults } from '../../defaults.js'
|
||||
import { LengthIndicator } from '../../ui/LengthIndicator.js'
|
||||
import '../index.scss'
|
||||
|
||||
const { maxLength, minLength } = defaults.title
|
||||
const { maxLength: maxLengthDefault, minLength: minLengthDefault } = defaults.title
|
||||
|
||||
type MetaTitleProps = {
|
||||
readonly hasGenerateTitleFn: boolean
|
||||
@@ -36,6 +36,8 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
|
||||
components: { Label },
|
||||
},
|
||||
label,
|
||||
maxLength: maxLengthFromProps,
|
||||
minLength: minLengthFromProps,
|
||||
required,
|
||||
},
|
||||
field: fieldFromProps,
|
||||
@@ -60,6 +62,9 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
|
||||
const { getData } = useForm()
|
||||
const docInfo = useDocumentInfo()
|
||||
|
||||
const minLength = minLengthFromProps || minLengthDefault
|
||||
const maxLength = maxLengthFromProps || maxLengthDefault
|
||||
|
||||
const { errorMessage, setValue, showError, value } = field
|
||||
|
||||
const regenerateTitle = useCallback(async () => {
|
||||
|
||||
@@ -10,25 +10,32 @@ import type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../tran
|
||||
import { defaults } from '../../defaults.js'
|
||||
|
||||
const {
|
||||
description: { maxLength: maxDesc, minLength: minDesc },
|
||||
title: { maxLength: maxTitle, minLength: minTitle },
|
||||
description: { maxLength: maxDescDefault, minLength: minDescDefault },
|
||||
title: { maxLength: maxTitleDefault, minLength: minTitleDefault },
|
||||
} = defaults
|
||||
|
||||
type OverviewProps = {
|
||||
descriptionOverrides?: {
|
||||
maxLength?: number
|
||||
minLength?: number
|
||||
}
|
||||
descriptionPath?: string
|
||||
imagePath?: string
|
||||
titleOverrides?: {
|
||||
maxLength?: number
|
||||
minLength?: number
|
||||
}
|
||||
titlePath?: string
|
||||
} & UIField
|
||||
|
||||
export const OverviewComponent: React.FC<OverviewProps> = ({
|
||||
descriptionOverrides,
|
||||
descriptionPath: descriptionPathFromContext,
|
||||
imagePath: imagePathFromContext,
|
||||
titleOverrides,
|
||||
titlePath: titlePathFromContext,
|
||||
}) => {
|
||||
const {
|
||||
// dispatchFields,
|
||||
getFields,
|
||||
} = useForm()
|
||||
const { getFields } = useForm()
|
||||
|
||||
const descriptionPath = descriptionPathFromContext || 'meta.description'
|
||||
const titlePath = titlePathFromContext || 'meta.title'
|
||||
@@ -47,6 +54,11 @@ export const OverviewComponent: React.FC<OverviewProps> = ({
|
||||
const [descIsValid, setDescIsValid] = useState<boolean | undefined>()
|
||||
const [imageIsValid, setImageIsValid] = useState<boolean | undefined>()
|
||||
|
||||
const minDesc = descriptionOverrides?.minLength || minDescDefault
|
||||
const maxDesc = descriptionOverrides?.maxLength || maxDescDefault
|
||||
const minTitle = titleOverrides?.minLength || minTitleDefault
|
||||
const maxTitle = titleOverrides?.maxLength || maxTitleDefault
|
||||
|
||||
const resetAll = useCallback(() => {
|
||||
const fields = getFields()
|
||||
const fieldsWithoutMeta = fields
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { UIField } from 'payload'
|
||||
|
||||
interface FieldFunctionProps {
|
||||
descriptionOverrides?: {
|
||||
maxLength?: number
|
||||
minLength?: number
|
||||
}
|
||||
/**
|
||||
* Path to the description field to use for the preview
|
||||
*
|
||||
@@ -14,6 +18,10 @@ interface FieldFunctionProps {
|
||||
*/
|
||||
imagePath?: string
|
||||
overrides?: Partial<UIField>
|
||||
titleOverrides?: {
|
||||
maxLength?: number
|
||||
minLength?: number
|
||||
}
|
||||
/**
|
||||
* Path to the title field to use for the preview
|
||||
*
|
||||
@@ -25,9 +33,11 @@ interface FieldFunctionProps {
|
||||
type FieldFunction = ({ overrides }: FieldFunctionProps) => UIField
|
||||
|
||||
export const OverviewField: FieldFunction = ({
|
||||
descriptionOverrides,
|
||||
descriptionPath,
|
||||
imagePath,
|
||||
overrides,
|
||||
titleOverrides,
|
||||
titlePath,
|
||||
}) => {
|
||||
return {
|
||||
@@ -37,8 +47,10 @@ export const OverviewField: FieldFunction = ({
|
||||
components: {
|
||||
Field: {
|
||||
clientProps: {
|
||||
descriptionOverrides,
|
||||
descriptionPath,
|
||||
imagePath,
|
||||
titleOverrides,
|
||||
titlePath,
|
||||
},
|
||||
path: '@payloadcms/plugin-seo/client#OverviewComponent',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-stripe",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Stripe plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-lexical",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The officially supported Lexical richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from '@payloadcms/ui'
|
||||
import { dequal } from 'dequal/lite'
|
||||
import { $getNodeByKey } from 'lexical'
|
||||
import React, { useCallback } from 'react'
|
||||
import React, { useCallback, useEffect } from 'react'
|
||||
|
||||
import type { LexicalRichTextFieldProps } from '../../../../types.js'
|
||||
import type { BlockFields } from '../../server/nodes/BlocksNode.js'
|
||||
@@ -70,21 +70,15 @@ export const BlockContent: React.FC<Props> = (props) => {
|
||||
// is important to consider for the data path used in setDocFieldPreferences
|
||||
const { getDocPreferences, setDocFieldPreferences } = useDocumentInfo()
|
||||
|
||||
const [isCollapsed, setIsCollapsed] = React.useState<boolean>(() => {
|
||||
let initialState = false
|
||||
const [isCollapsed, setIsCollapsed] = React.useState<boolean>()
|
||||
|
||||
useEffect(() => {
|
||||
void getDocPreferences().then((currentDocPreferences) => {
|
||||
const currentFieldPreferences = currentDocPreferences?.fields[field.name]
|
||||
|
||||
const collapsedArray = currentFieldPreferences?.collapsed
|
||||
|
||||
if (collapsedArray && collapsedArray.includes(formData.id)) {
|
||||
initialState = true
|
||||
setIsCollapsed(true)
|
||||
}
|
||||
setIsCollapsed(collapsedArray ? collapsedArray.includes(formData.id) : false)
|
||||
})
|
||||
return initialState
|
||||
})
|
||||
}, [field.name, formData.id, getDocPreferences])
|
||||
|
||||
const hasSubmitted = useFormSubmitted()
|
||||
|
||||
@@ -180,6 +174,10 @@ export const BlockContent: React.FC<Props> = (props) => {
|
||||
})
|
||||
}, [editor, nodeKey])
|
||||
|
||||
if (typeof isCollapsed !== 'boolean') {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Collapsible
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
span.unknownConverted {
|
||||
text-transform: uppercase;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
letter-spacing: 2px;
|
||||
font-size: calc(var(--base) * 0.5);
|
||||
margin: 0 0 var(--base);
|
||||
background: red;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
|
||||
div {
|
||||
@layer payload-default {
|
||||
span.unknownConverted {
|
||||
text-transform: uppercase;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
letter-spacing: 2px;
|
||||
font-size: calc(var(--base) * 0.5);
|
||||
margin: 0 0 var(--base);
|
||||
background: red;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
|
||||
div {
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
span.unknownConverted {
|
||||
text-transform: uppercase;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
letter-spacing: 2px;
|
||||
font-size: calc(var(--base) * 0.5);
|
||||
margin: 0 0 var(--base);
|
||||
background: red;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
|
||||
div {
|
||||
@layer payload-default {
|
||||
span.unknownConverted {
|
||||
text-transform: uppercase;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
letter-spacing: 2px;
|
||||
font-size: calc(var(--base) * 0.5);
|
||||
margin: 0 0 var(--base);
|
||||
background: red;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
|
||||
div {
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
@import '../../../../scss/styles';
|
||||
|
||||
.toolbar-popup__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border: 0;
|
||||
background: none;
|
||||
border-radius: $style-radius-m;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
@layer payload-default {
|
||||
.toolbar-popup__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border: 0;
|
||||
background: none;
|
||||
border-radius: $style-radius-m;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
|
||||
&.spaced {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--theme-elevation-150);
|
||||
color: var(--theme-text);
|
||||
&:hover {
|
||||
background-color: var(--theme-elevation-200);
|
||||
&.spaced {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
opacity: 1;
|
||||
&:hover:not(.disabled) {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
&.active {
|
||||
background-color: var(--theme-elevation-150);
|
||||
color: var(--theme-text);
|
||||
&:hover {
|
||||
background-color: var(--theme-elevation-200);
|
||||
}
|
||||
|
||||
.icon {
|
||||
opacity: 0.2;
|
||||
.icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
.icon {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +1,121 @@
|
||||
@import '../../../../scss/styles';
|
||||
|
||||
.toolbar-popup__dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
gap: base(0.2);
|
||||
height: base(1.5);
|
||||
border: 0;
|
||||
background: none;
|
||||
border-radius: $style-radius-m;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding: 0 base(0.4) 0 base(0.3);
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
|
||||
&-label {
|
||||
color: var(--theme-elevation-600);
|
||||
padding-block: 0;
|
||||
padding-inline: base(0.2) base(0.4);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
&:hover:not([disabled]) {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--theme-elevation-100);
|
||||
|
||||
.toolbar-popup__dropdown-caret {
|
||||
&:after {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-caret {
|
||||
width: base(0.4);
|
||||
@layer payload-default {
|
||||
.toolbar-popup__dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
transform: rotate(45deg);
|
||||
&:after {
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
|
||||
/* Vector 3 */
|
||||
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
transform: translateY(-2px);
|
||||
border: solid 1px var(--theme-elevation-600);
|
||||
border-width: 0 1px 1px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-items {
|
||||
position: absolute;
|
||||
background: var(--theme-elevation-0);
|
||||
gap: base(0.2);
|
||||
height: base(1.5);
|
||||
border: 0;
|
||||
background: none;
|
||||
border-radius: $style-radius-m;
|
||||
min-width: 132.5px;
|
||||
max-width: 200px;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding: 0 base(0.4) 0 base(0.3);
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
|
||||
.toolbar-popup__dropdown-item {
|
||||
all: unset; // reset all default button styles
|
||||
cursor: pointer;
|
||||
color: var(--theme-elevation-900);
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
&-label {
|
||||
color: var(--theme-elevation-600);
|
||||
padding-block: 0;
|
||||
padding-inline: base(0.2) base(0.4);
|
||||
}
|
||||
|
||||
.text {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
&:hover:not([disabled]) {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--theme-elevation-100);
|
||||
|
||||
.toolbar-popup__dropdown-caret {
|
||||
&:after {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not([disabled]),
|
||||
&.active {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
padding-left: 6.25px;
|
||||
padding-right: 6.25px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border-radius: $style-radius-m;
|
||||
box-sizing: border-box;
|
||||
&-caret {
|
||||
width: base(0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6.25px;
|
||||
justify-content: center;
|
||||
transform: rotate(45deg);
|
||||
&:after {
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
|
||||
.icon {
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
color: var(--theme-elevation-600);
|
||||
/* Vector 3 */
|
||||
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
transform: translateY(-2px);
|
||||
border: solid 1px var(--theme-elevation-600);
|
||||
border-width: 0 1px 1px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-items {
|
||||
position: absolute;
|
||||
background: var(--theme-elevation-0);
|
||||
border-radius: $style-radius-m;
|
||||
min-width: 132.5px;
|
||||
max-width: 200px;
|
||||
z-index: 100;
|
||||
|
||||
.toolbar-popup__dropdown-item {
|
||||
all: unset; // reset all default button styles
|
||||
cursor: pointer;
|
||||
color: var(--theme-elevation-900);
|
||||
transition: background-color 0.15s cubic-bezier(0, 0.2, 0.2, 1);
|
||||
|
||||
.text {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover:not([disabled]),
|
||||
&.active {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
padding-left: 6.25px;
|
||||
padding-right: 6.25px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border-radius: $style-radius-m;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6.25px;
|
||||
|
||||
.icon {
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
color: var(--theme-elevation-600);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html[data-theme='light'] {
|
||||
.toolbar-popup__dropdown {
|
||||
&-items {
|
||||
position: absolute;
|
||||
@include shadow-m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html[data-theme='light'] {
|
||||
.toolbar-popup__dropdown {
|
||||
&-items {
|
||||
position: absolute;
|
||||
@include shadow-m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-slate",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "The officially supported Slate richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.rich-text-blockquote {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
padding-left: base(0.625);
|
||||
border-left: 1px solid var(--theme-elevation-200);
|
||||
@layer payload-default {
|
||||
.rich-text-blockquote {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
padding-left: base(0.625);
|
||||
border-left: 1px solid var(--theme-elevation-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +1,90 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.rich-text-link {
|
||||
position: relative;
|
||||
@layer payload-default {
|
||||
.rich-text-link {
|
||||
position: relative;
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
.popup__hide-scrollbar,
|
||||
.popup__scroll-container {
|
||||
overflow: visible;
|
||||
.popup__hide-scrollbar,
|
||||
.popup__scroll-container {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.popup__scroll-content {
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
|
||||
.popup__scroll-content {
|
||||
white-space: pre;
|
||||
.icon--x line {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon--x line {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
&__popup {
|
||||
@extend %body;
|
||||
font-family: var(--font-body);
|
||||
display: flex;
|
||||
|
||||
&__popup {
|
||||
@extend %body;
|
||||
font-family: var(--font-body);
|
||||
display: flex;
|
||||
|
||||
button {
|
||||
@extend %btn-reset;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
button {
|
||||
@extend %btn-reset;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__link-label {
|
||||
max-width: base(8);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-radius: 2px;
|
||||
&__link-label {
|
||||
max-width: base(8);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-radius: 2px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--popup-button-highlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rich-text-link__popup {
|
||||
display: flex;
|
||||
gap: calc(var(--base) * 0.25);
|
||||
button {
|
||||
&:hover {
|
||||
.btn__icon {
|
||||
&:hover {
|
||||
background-color: var(--popup-button-highlight);
|
||||
.fill {
|
||||
fill: var(--theme-text);
|
||||
}
|
||||
.stroke {
|
||||
stroke: var(--theme-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rich-text-link__popup {
|
||||
display: flex;
|
||||
gap: calc(var(--base) * 0.25);
|
||||
button {
|
||||
&:hover {
|
||||
.btn__icon {
|
||||
background-color: var(--popup-button-highlight);
|
||||
.fill {
|
||||
fill: var(--theme-text);
|
||||
}
|
||||
.stroke {
|
||||
stroke: var(--theme-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rich-text-link__popup-toggler {
|
||||
position: relative;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
color: var(--theme-success-600);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted;
|
||||
cursor: text;
|
||||
.rich-text-link__popup-toggler {
|
||||
position: relative;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
color: var(--theme-success-600);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted;
|
||||
cursor: text;
|
||||
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
outline: none;
|
||||
}
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&--open {
|
||||
z-index: var(--z-popup);
|
||||
&--open {
|
||||
z-index: var(--z-popup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,51 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.rich-text-link-edit-modal {
|
||||
&__template {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-top: base(1);
|
||||
padding-bottom: base(2);
|
||||
}
|
||||
|
||||
&__header {
|
||||
width: 100%;
|
||||
margin-bottom: $baseline;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: base(2.5);
|
||||
margin-bottom: base(1);
|
||||
|
||||
@include mid-break {
|
||||
margin-top: base(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__header-text {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__header-close {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
width: base(1);
|
||||
height: base(1);
|
||||
|
||||
svg {
|
||||
width: base(2);
|
||||
height: base(2);
|
||||
@layer payload-default {
|
||||
.rich-text-link-edit-modal {
|
||||
&__template {
|
||||
position: relative;
|
||||
inset-inline-start: base(-0.5);
|
||||
top: base(-0.5);
|
||||
z-index: 1;
|
||||
padding-top: base(1);
|
||||
padding-bottom: base(2);
|
||||
}
|
||||
|
||||
.stroke {
|
||||
stroke-width: 2px;
|
||||
vector-effect: non-scaling-stroke;
|
||||
&__header {
|
||||
width: 100%;
|
||||
margin-bottom: $baseline;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: base(2.5);
|
||||
margin-bottom: base(1);
|
||||
|
||||
@include mid-break {
|
||||
margin-top: base(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__header-text {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__header-close {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
width: base(1);
|
||||
height: base(1);
|
||||
|
||||
svg {
|
||||
width: base(2);
|
||||
height: base(2);
|
||||
position: relative;
|
||||
inset-inline-start: base(-0.5);
|
||||
top: base(-0.5);
|
||||
|
||||
.stroke {
|
||||
stroke-width: 2px;
|
||||
vector-effect: non-scaling-stroke;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.rich-text-ol {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
@layer payload-default {
|
||||
.rich-text-ol {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.relationship-rich-text-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
@layer payload-default {
|
||||
.relationship-rich-text-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,93 +1,95 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.rich-text-relationship {
|
||||
@extend %body;
|
||||
@include shadow-sm;
|
||||
padding: base(0.75);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--theme-input-bg);
|
||||
border: 1px solid var(--theme-elevation-100);
|
||||
max-width: base(15);
|
||||
font-family: var(--font-body);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--theme-elevation-150);
|
||||
}
|
||||
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
|
||||
&__label {
|
||||
margin-bottom: base(0.25);
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__label,
|
||||
&__title {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
line-height: 1 !important;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&--selected {
|
||||
box-shadow: $focus-box-shadow;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.rich-text-relationship__doc-drawer-toggler {
|
||||
text-decoration: underline;
|
||||
pointer-events: all;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
@layer payload-default {
|
||||
.rich-text-relationship {
|
||||
@extend %body;
|
||||
@include shadow-sm;
|
||||
padding: base(0.75);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-left: base(0.5);
|
||||
background: var(--theme-input-bg);
|
||||
border: 1px solid var(--theme-elevation-100);
|
||||
max-width: base(15);
|
||||
font-family: var(--font-body);
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: base(0.25);
|
||||
}
|
||||
}
|
||||
|
||||
&__removeButton {
|
||||
margin: 0;
|
||||
|
||||
line {
|
||||
stroke-width: $style-stroke-width-m;
|
||||
&:hover {
|
||||
border: 1px solid var(--theme-elevation-150);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler,
|
||||
&__list-drawer-toggler {
|
||||
& > * {
|
||||
&__label {
|
||||
margin-bottom: base(0.25);
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
&__label,
|
||||
&__title {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
line-height: 1 !important;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&--selected {
|
||||
box-shadow: $focus-box-shadow;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.rich-text-relationship__doc-drawer-toggler {
|
||||
text-decoration: underline;
|
||||
pointer-events: all;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-left: base(0.5);
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: base(0.25);
|
||||
}
|
||||
}
|
||||
|
||||
&__removeButton {
|
||||
margin: 0;
|
||||
|
||||
line {
|
||||
stroke-width: $style-stroke-width-m;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler,
|
||||
&__list-drawer-toggler {
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.rich-text-ul {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
@layer payload-default {
|
||||
.rich-text-ul {
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.upload-rich-text-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
@layer payload-default {
|
||||
.upload-rich-text-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,147 +1,149 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.rich-text-upload {
|
||||
@extend %body;
|
||||
@include shadow-sm;
|
||||
max-width: base(15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--theme-input-bg);
|
||||
border: 1px solid var(--theme-elevation-100);
|
||||
position: relative;
|
||||
font-family: var(--font-body);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--theme-elevation-150);
|
||||
}
|
||||
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
|
||||
&__card {
|
||||
@include soft-shadow-bottom;
|
||||
@layer payload-default {
|
||||
.rich-text-upload {
|
||||
@extend %body;
|
||||
@include shadow-sm;
|
||||
max-width: base(15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__topRow {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__thumbnail {
|
||||
width: base(3.25);
|
||||
height: auto;
|
||||
align-items: center;
|
||||
background: var(--theme-input-bg);
|
||||
border: 1px solid var(--theme-elevation-100);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
font-family: var(--font-body);
|
||||
|
||||
img,
|
||||
svg {
|
||||
position: absolute;
|
||||
object-fit: cover;
|
||||
&:hover {
|
||||
border: 1px solid var(--theme-elevation-150);
|
||||
}
|
||||
|
||||
&[data-slate-node='element'] {
|
||||
margin: base(0.625) 0;
|
||||
}
|
||||
|
||||
&__card {
|
||||
@include soft-shadow-bottom;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--theme-elevation-800);
|
||||
}
|
||||
}
|
||||
|
||||
&__topRowRightPanel {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: base(0.75);
|
||||
justify-content: space-between;
|
||||
max-width: calc(100% - #{base(3.25)});
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-left: base(0.5);
|
||||
|
||||
.rich-text-upload__doc-drawer-toggler {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: base(0.25);
|
||||
}
|
||||
}
|
||||
|
||||
&__removeButton {
|
||||
margin: 0;
|
||||
|
||||
line {
|
||||
stroke-width: $style-stroke-width-m;
|
||||
&__topRow {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
&__thumbnail {
|
||||
width: base(3.25);
|
||||
height: auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
|
||||
&__upload-drawer-toggler {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler,
|
||||
&__list-drawer-toggler,
|
||||
&__upload-drawer-toggler {
|
||||
& > * {
|
||||
margin: 0;
|
||||
img,
|
||||
svg {
|
||||
position: absolute;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--theme-elevation-800);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__collectionLabel {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__bottomRow {
|
||||
padding: base(0.5);
|
||||
border-top: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
h5 {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
padding: base(0.5) base(0.5) base(0.5) base(1);
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&--selected {
|
||||
box-shadow: $focus-box-shadow;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__topRowRightPanel {
|
||||
padding: base(0.75) base(0.5);
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: base(0.75);
|
||||
justify-content: space-between;
|
||||
max-width: calc(100% - #{base(3.25)});
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-left: base(0.5);
|
||||
|
||||
.rich-text-upload__doc-drawer-toggler {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: base(0.25);
|
||||
}
|
||||
}
|
||||
|
||||
&__removeButton {
|
||||
margin: 0;
|
||||
|
||||
line {
|
||||
stroke-width: $style-stroke-width-m;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__upload-drawer-toggler {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&__doc-drawer-toggler,
|
||||
&__list-drawer-toggler,
|
||||
&__upload-drawer-toggler {
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--theme-elevation-300);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__collectionLabel {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__bottomRow {
|
||||
padding: base(0.5);
|
||||
border-top: 1px solid var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
h5 {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
padding: base(0.5) base(0.5) base(0.5) base(1);
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&--selected {
|
||||
box-shadow: $focus-box-shadow;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__topRowRightPanel {
|
||||
padding: base(0.75) base(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-azure",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Payload storage adapter for Azure Blob Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-gcs",
|
||||
"version": "3.0.0-beta.114",
|
||||
"version": "3.0.0-beta.116",
|
||||
"description": "Payload storage adapter for Google Cloud Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user