Compare commits

..

12 Commits

Author SHA1 Message Date
Elliot DeNolf
348d1256cc chore(release): richtext-slate/1.0.2 2023-10-10 15:58:41 -04:00
Elliot DeNolf
e3ef443217 chore(release): db-postgres/0.1.2 2023-10-10 15:57:51 -04:00
Elliot DeNolf
a42e84bbb2 chore(eslint): prepare config for publishing 2023-10-10 15:10:22 -04:00
James Mikrut
470bdb72ff Merge pull request #3553 from payloadcms/fix/#3541
fix: #3541
2023-10-10 14:49:11 -04:00
James Mikrut
5c36be949c Merge pull request #3554 from payloadcms/fix/#3540
fix: #3540
2023-10-10 14:49:01 -04:00
James
2567ac58ba fix: #3540 2023-10-10 14:21:12 -04:00
Jacob Fletcher
9ff014bbfe fix: row field width (#3550) 2023-10-10 14:09:47 -04:00
James
e6f0d35985 fix: #3541 2023-10-10 14:07:26 -04:00
Alessio Gravili
b1e449e005 Merge pull request #3551 from payloadcms/fix/slate-toolbar
fix: Slate toolbar rendered even if it has no elements and leaves
2023-10-10 19:36:29 +02:00
Alessio Gravili
9ae585d23c fix: Slate toolbar rendered even if it has no elements and leaves 2023-10-10 19:22:08 +02:00
Elliot DeNolf
9de3320933 chore(release): richtext-lexical/0.1.5 2023-10-10 12:08:13 -04:00
Elliot DeNolf
5d429fa7ae chore(release): live-preview-react/0.1.2 2023-10-10 12:08:08 -04:00
21 changed files with 168 additions and 70 deletions

2
.vscode/launch.json vendored
View File

@@ -17,7 +17,7 @@
"type": "node-terminal"
},
{
"command": "pnpm run dev:postgres collections-graphql",
"command": "pnpm run dev:postgres fields",
"cwd": "${workspaceFolder}",
"name": "Run Dev Postgres",
"request": "launch",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-postgres",
"version": "0.1.1",
"version": "0.1.2",
"description": "The officially supported Postgres database adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -1,7 +1,7 @@
/* eslint-disable no-param-reassign */
import type { Field } from 'payload/types'
import { fieldAffectsData } from 'payload/types'
import { fieldAffectsData, tabHasName } from 'payload/types'
import toSnakeCase from 'to-snake-case'
import type { PostgresAdapter } from '../types'
@@ -31,6 +31,42 @@ export const traverseFields = ({
topLevelTableName,
}: TraverseFieldArgs) => {
fields.forEach((field) => {
if (field.type === 'collapsible' || field.type === 'row') {
traverseFields({
_locales,
adapter,
currentArgs,
currentTableName,
depth,
fields: field.fields,
path,
topLevelArgs,
topLevelTableName,
})
return
}
if (field.type === 'tabs') {
field.tabs.forEach((tab) => {
const tabPath = tabHasName(tab) ? `${path}${tab.name}_` : path
traverseFields({
_locales,
adapter,
currentArgs,
currentTableName,
depth,
fields: tab.fields,
path: tabPath,
topLevelArgs,
topLevelTableName,
})
})
return
}
if (fieldAffectsData(field)) {
switch (field.type) {
case 'array': {

View File

@@ -406,7 +406,7 @@ export const traverseFields = ({
indexes,
localesColumns,
localesIndexes,
newTableName: parentTableName,
newTableName,
parentTableName,
relationsToBuild,
relationships,

View File

@@ -3,6 +3,6 @@ module.exports = {
jest: true,
},
plugins: ['jest', 'jest-dom'],
extends: ['./rules/jest.cjs', './rules/jest-dom.cjs'].map(require.resolve),
extends: ['./rules/jest.js', './rules/jest-dom.js'].map(require.resolve),
rules: {},
}

View File

@@ -13,6 +13,6 @@ module.exports = {
jsx: true,
},
},
extends: ['./rules/react-a11y.cjs', './rules/react.cjs'].map(require.resolve),
extends: ['./rules/react-a11y.js', './rules/react.js'].map(require.resolve),
rules: {},
}

View File

@@ -11,8 +11,8 @@ module.exports = {
'plugin:regexp/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'./configs/jest/index.cjs',
'./configs/react/index.cjs',
'./configs/jest/index.js',
'./configs/react/index.js',
'prettier',
],
parser: '@typescript-eslint/parser',

View File

@@ -1,4 +1,4 @@
module.exports = {
root: true,
extends: ['./eslint-config/index.cjs'],
extends: ['./eslint-config/index.js'],
}

View File

@@ -1,7 +1,6 @@
{
"name": "@payloadcms/eslint-config",
"version": "0.0.1",
"private": true,
"description": "Payload styles for ESLint and Prettier",
"license": "MIT",
"author": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview-react",
"version": "0.1.1",
"version": "0.1.2",
"description": "The official live preview React SDK for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -3,18 +3,28 @@
.field-type.row {
display: flex;
flex-wrap: wrap;
width: 100%;
gap: var(--base);
width: calc(100% + var(--base));
margin-left: calc(var(--base) * -0.5);
margin-right: calc(var(--base) * -0.5);
> * {
flex-grow: 1;
padding-left: calc(var(--base) * 0.5);
padding-right: calc(var(--base) * 0.5);
}
@include mid-break {
flex-direction: column;
display: block;
margin-left: 0;
margin-right: 0;
width: 100%;
> * {
margin-left: 0;
margin-right: 0;
width: 100% !important;
padding-left: 0;
padding-right: 0;
}
}
}

View File

@@ -18,8 +18,8 @@ import { GetFilterOptions } from '../../../utilities/GetFilterOptions'
import Error from '../../Error'
import FieldDescription from '../../FieldDescription'
import Label from '../../Label'
import './index.scss'
import { fieldBaseClass } from '../shared'
import './index.scss'
const baseClass = 'upload'
@@ -81,7 +81,7 @@ const UploadInput: React.FC<UploadInputProps> = (props) => {
})
useEffect(() => {
if (typeof value === 'string' && value !== '') {
if (typeof value !== 'undefined' && value !== '') {
const fetchFile = async () => {
const response = await fetch(`${serverURL}${api}/${relationTo}/${value}`, {
credentials: 'include',

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-lexical",
"version": "0.1.4",
"version": "0.1.5",
"description": "The officially supported Lexical richtext adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-slate",
"version": "1.0.1",
"version": "1.0.2",
"description": "The officially supported Slate richtext adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -329,43 +329,45 @@ const RichText: React.FC<FieldProps> = (props) => {
value={valueToRender as any[]}
>
<div className={`${baseClass}__wrapper`}>
<div
className={[`${baseClass}__toolbar`, drawerIsOpen && `${baseClass}__drawerIsOpen`]
.filter(Boolean)
.join(' ')}
ref={toolbarRef}
>
<div className={`${baseClass}__toolbar-wrap`}>
{elements.map((element, i) => {
let elementName: string
if (typeof element === 'object' && element?.name) elementName = element.name
if (typeof element === 'string') elementName = element
{elements?.length + leaves?.length > 0 && (
<div
className={[`${baseClass}__toolbar`, drawerIsOpen && `${baseClass}__drawerIsOpen`]
.filter(Boolean)
.join(' ')}
ref={toolbarRef}
>
<div className={`${baseClass}__toolbar-wrap`}>
{elements.map((element, i) => {
let elementName: string
if (typeof element === 'object' && element?.name) elementName = element.name
if (typeof element === 'string') elementName = element
const elementType = enabledElements[elementName]
const Button = elementType?.Button
const elementType = enabledElements[elementName]
const Button = elementType?.Button
if (Button) {
return <Button fieldProps={props} key={i} path={path} />
}
if (Button) {
return <Button fieldProps={props} key={i} path={path} />
}
return null
})}
{leaves.map((leaf, i) => {
let leafName: string
if (typeof leaf === 'object' && leaf?.name) leafName = leaf.name
if (typeof leaf === 'string') leafName = leaf
return null
})}
{leaves.map((leaf, i) => {
let leafName: string
if (typeof leaf === 'object' && leaf?.name) leafName = leaf.name
if (typeof leaf === 'string') leafName = leaf
const leafType = enabledLeaves[leafName]
const Button = leafType?.Button
const leafType = enabledLeaves[leafName]
const Button = leafType?.Button
if (Button) {
return <Button fieldProps={props} key={i} path={path} />
}
if (Button) {
return <Button fieldProps={props} key={i} path={path} />
}
return null
})}
return null
})}
</div>
</div>
</div>
)}
<div className={`${baseClass}__editor`} ref={editorRef}>
<Editable
className={`${baseClass}__input`}

View File

@@ -26,6 +26,27 @@ const RowFields: CollectionConfig = {
},
],
},
{
type: 'row',
fields: [
{
name: 'field_with_width_a',
label: 'Field with 50% width',
type: 'text',
admin: {
width: '50%',
},
},
{
name: 'field_with_width_b',
label: 'Field with 50% width',
type: 'text',
admin: {
width: '50%',
},
},
],
},
],
}

View File

@@ -79,42 +79,43 @@ describe('fields', () => {
await expect(textCell).toHaveText(String(numberDoc.number))
})
test('should filter Number fields in the collection view - greaterThanOrEqual', async () => {
await page.goto(url.list);
await page.goto(url.list)
// should have 3 entries
await expect(page.locator('table >> tbody >> tr')).toHaveCount(3);
await expect(page.locator('table >> tbody >> tr')).toHaveCount(3)
// open the filter options
await page.locator('.list-controls__toggle-where').click();
await expect(page.locator('.list-controls__where.rah-static--height-auto')).toBeVisible();
await page.locator('.where-builder__add-first-filter').click();
await page.locator('.list-controls__toggle-where').click()
await expect(page.locator('.list-controls__where.rah-static--height-auto')).toBeVisible()
await page.locator('.where-builder__add-first-filter').click()
const initialField = page.locator('.condition__field');
const operatorField = page.locator('.condition__operator');
const valueField = page.locator('.condition__value >> input');
const initialField = page.locator('.condition__field')
const operatorField = page.locator('.condition__operator')
const valueField = page.locator('.condition__value >> input')
// select Number field to filter on
await initialField.click();
const initialFieldOptions = initialField.locator('.rs__option');
await initialFieldOptions.locator('text=number').first().click();
expect(initialField.locator('.rs__single-value')).toContainText('Number');
await initialField.click()
const initialFieldOptions = initialField.locator('.rs__option')
await initialFieldOptions.locator('text=number').first().click()
await expect(initialField.locator('.rs__single-value')).toContainText('Number')
// select >= operator
await operatorField.click();
const operatorOptions = operatorField.locator('.rs__option');
await operatorOptions.last().click();
expect(operatorField.locator('.rs__single-value')).toContainText('is greater than or equal to');
await operatorField.click()
const operatorOptions = operatorField.locator('.rs__option')
await operatorOptions.last().click()
await expect(operatorField.locator('.rs__single-value')).toContainText(
'is greater than or equal to',
)
// enter value of 3
await valueField.fill('3');
await expect(valueField).toHaveValue('3');
await wait(300);
await valueField.fill('3')
await expect(valueField).toHaveValue('3')
await wait(300)
// should have 2 entries after filtering
await expect(page.locator('table >> tbody >> tr')).toHaveCount(2);
});
await expect(page.locator('table >> tbody >> tr')).toHaveCount(2)
})
test('should create', async () => {
const input = 5
@@ -676,6 +677,22 @@ describe('fields', () => {
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click()
await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue)
})
test('should render array data within unnamed tabs', async () => {
await page.goto(url.list)
await page.locator('.cell-id a').click()
await page.locator('.tabs-field__tab-button:has-text("Tab with Array")').click()
await expect(page.locator('#field-array__0__text')).toHaveValue("Hello, I'm the first row")
})
test('should render array data within named tabs', async () => {
await page.goto(url.list)
await page.locator('.cell-id a').click()
await page.locator('.tabs-field__tab-button:nth-child(5)').click()
await expect(page.locator('#field-tab__array__0__text')).toHaveValue(
"Hello, I'm the first row, in a named tab",
)
})
})
describe('richText', () => {
@@ -1430,6 +1447,19 @@ describe('fields', () => {
await expect(idHeadings).toBeVisible()
await expect(idHeadings).toHaveCount(1)
})
test('should render row fields inline', async () => {
await page.goto(url.create)
const fieldA = page.locator('input#field-field_with_width_a')
await expect(fieldA).toBeVisible()
const fieldB = page.locator('input#field-field_with_width_b')
await expect(fieldB).toBeVisible()
const fieldABox = await fieldA.boundingBox()
const fieldBBox = await fieldB.boundingBox()
// give it some wiggle room of like 2px to account for differences in rendering
const difference = Math.abs(fieldABox.width - fieldBBox.width)
expect(difference).toBeLessThanOrEqual(2)
})
})
describe('conditional logic', () => {