chore: merge master
This commit is contained in:
@@ -14,6 +14,10 @@ export const blocksField: Field = {
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'richText',
|
||||
type: 'richText',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -63,12 +67,55 @@ export const blocksField: Field = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'tabs',
|
||||
fields: [
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
label: 'Tab with Collapsible',
|
||||
fields: [
|
||||
{
|
||||
type: 'collapsible',
|
||||
label: 'Collapsible within Block',
|
||||
fields: [
|
||||
{
|
||||
// collapsible
|
||||
name: 'textInCollapsible',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
// collapsible
|
||||
name: 'textInRow',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const BlockFields: CollectionConfig = {
|
||||
slug: 'block-fields',
|
||||
fields: [blocksField],
|
||||
fields: [
|
||||
blocksField,
|
||||
{
|
||||
...blocksField,
|
||||
name: 'localizedBlocks',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const blocksFieldSeedData = [
|
||||
@@ -76,6 +123,7 @@ export const blocksFieldSeedData = [
|
||||
blockName: 'First block',
|
||||
blockType: 'text',
|
||||
text: 'first block',
|
||||
richText: [],
|
||||
},
|
||||
{
|
||||
blockName: 'Second block',
|
||||
@@ -102,6 +150,7 @@ export const blocksFieldSeedData = [
|
||||
|
||||
export const blocksDoc = {
|
||||
blocks: blocksFieldSeedData,
|
||||
localizedBlocks: blocksFieldSeedData,
|
||||
};
|
||||
|
||||
export default BlockFields;
|
||||
|
||||
126
test/fields/collections/Code/index.tsx
Normal file
126
test/fields/collections/Code/index.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import type { CollectionConfig } from '../../../../src/collections/config/types';
|
||||
import { CodeField } from '../../payload-types';
|
||||
|
||||
const Code: CollectionConfig = {
|
||||
slug: 'code-fields',
|
||||
fields: [
|
||||
{
|
||||
name: 'javascript',
|
||||
type: 'code',
|
||||
admin: {
|
||||
language: 'js',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'typescript',
|
||||
type: 'code',
|
||||
admin: {
|
||||
language: 'ts',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'json',
|
||||
type: 'code',
|
||||
admin: {
|
||||
language: 'json',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'html',
|
||||
type: 'code',
|
||||
admin: {
|
||||
language: 'html',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'css',
|
||||
type: 'code',
|
||||
admin: {
|
||||
language: 'css',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const codeDoc: Partial<CodeField> = {
|
||||
javascript: "console.log('Hello');",
|
||||
typescript: `class Greeter {
|
||||
greeting: string;
|
||||
|
||||
constructor(message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
let greeter = new Greeter("world");`,
|
||||
|
||||
html: `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<script>
|
||||
// Just a lil’ script to show off that inline JS gets highlighted
|
||||
window.console && console.log('foo');
|
||||
</script>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="assets/favicon.png" />
|
||||
<title>Prism</title>
|
||||
<link rel="stylesheet" href="assets/style.css" />
|
||||
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
|
||||
<script src="assets/vendor/prefixfree.min.js"></script>
|
||||
|
||||
<script>var _gaq = [['_setAccount', 'UA-11111111-1'], ['_trackPageview']];</script>
|
||||
<script src="https://www.google-analytics.com/ga.js" async></script>
|
||||
</head>
|
||||
<body>`,
|
||||
|
||||
css: `@import url(https://fonts.googleapis.com/css?family=Questrial);
|
||||
@import url(https://fonts.googleapis.com/css?family=Arvo);
|
||||
|
||||
@font-face {
|
||||
src: url(https://lea.verou.me/logo.otf);
|
||||
font-family: 'LeaVerou';
|
||||
}
|
||||
|
||||
/*
|
||||
Shared styles
|
||||
*/
|
||||
|
||||
section h1,
|
||||
#features li strong,
|
||||
header h2,
|
||||
footer p {
|
||||
font: 100% Rockwell, Arvo, serif;
|
||||
}
|
||||
|
||||
/*
|
||||
Styles
|
||||
*/
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font: 100%/1.5 Questrial, sans-serif;
|
||||
tab-size: 4;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
section h1 {
|
||||
font-size: 250%;
|
||||
}`,
|
||||
|
||||
json: JSON.stringify({ property: 'value', arr: ['val1', 'val2', 'val3'] }, null, 2),
|
||||
};
|
||||
|
||||
export default Code;
|
||||
63
test/fields/collections/Date/index.ts
Normal file
63
test/fields/collections/Date/index.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { CollectionConfig } from '../../../../src/collections/config/types';
|
||||
|
||||
export const defaultText = 'default-text';
|
||||
|
||||
const DateFields: CollectionConfig = {
|
||||
slug: 'date-fields',
|
||||
admin: {
|
||||
useAsTitle: 'date',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'default',
|
||||
type: 'date',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'timeOnly',
|
||||
type: 'date',
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: 'timeOnly',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dayOnly',
|
||||
type: 'date',
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: 'dayOnly',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dayAndTime',
|
||||
type: 'date',
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: 'dayAndTime',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'monthOnly',
|
||||
type: 'date',
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: 'monthOnly',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const dateDoc = {
|
||||
default: '2022-08-12T10:00:00.000+00:00',
|
||||
timeOnly: '2022-08-12T10:00:00.157+00:00',
|
||||
dayOnly: '2022-08-11T22:00:00.000+00:00',
|
||||
dayAndTime: '2022-08-12T10:00:00.052+00:00',
|
||||
monthOnly: '2022-07-31T22:00:00.000+00:00',
|
||||
};
|
||||
|
||||
export default DateFields;
|
||||
@@ -34,6 +34,24 @@ const IndexedFields: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'collapsible',
|
||||
label: 'Collapsible',
|
||||
fields: [
|
||||
{
|
||||
name: 'collapsibleLocalizedUnique',
|
||||
type: 'text',
|
||||
unique: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'collapsibleTextUnique',
|
||||
type: 'text',
|
||||
label: 'collapsibleTextUnique',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ const PointFields: CollectionConfig = {
|
||||
name: 'localized',
|
||||
type: 'point',
|
||||
label: 'Localized Point',
|
||||
unique: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
@@ -36,7 +37,7 @@ const PointFields: CollectionConfig = {
|
||||
|
||||
export const pointDoc = {
|
||||
point: [7, -7],
|
||||
localized: [5, -2],
|
||||
localized: [15, -12],
|
||||
group: { point: [1, 9] },
|
||||
};
|
||||
|
||||
|
||||
@@ -43,6 +43,22 @@ const RichTextFields: CollectionConfig = {
|
||||
type: 'richText',
|
||||
required: true,
|
||||
admin: {
|
||||
link: {
|
||||
fields: [
|
||||
{
|
||||
name: 'rel',
|
||||
label: 'Rel Attribute',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: [
|
||||
'noopener', 'noreferrer', 'nofollow',
|
||||
],
|
||||
admin: {
|
||||
description: 'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
upload: {
|
||||
collections: {
|
||||
uploads: {
|
||||
@@ -78,7 +94,7 @@ export const richTextDoc = {
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
url: 'test.com',
|
||||
url: 'https://payloadcms.com',
|
||||
newTab: true,
|
||||
children: [
|
||||
{
|
||||
@@ -87,7 +103,24 @@ export const richTextDoc = {
|
||||
],
|
||||
},
|
||||
{
|
||||
text: ' and store nested relationship fields:',
|
||||
text: ', ',
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
linkType: 'internal',
|
||||
doc: {
|
||||
value: '{{ARRAY_DOC_ID}}',
|
||||
relationTo: 'array-fields',
|
||||
},
|
||||
fields: {},
|
||||
children: [
|
||||
{
|
||||
text: 'link to relationships',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: ', and store nested relationship fields:',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -30,6 +30,7 @@ const SelectFields: CollectionConfig = {
|
||||
type: 'select',
|
||||
admin: {
|
||||
isClearable: true,
|
||||
isSortable: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -13,6 +13,11 @@ const TextFields: CollectionConfig = {
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'localizedText',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'defaultFunction',
|
||||
type: 'text',
|
||||
@@ -32,6 +37,7 @@ const TextFields: CollectionConfig = {
|
||||
|
||||
export const textDoc = {
|
||||
text: 'Seeded text document',
|
||||
localizedText: 'Localized text',
|
||||
};
|
||||
|
||||
export default TextFields;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { buildConfig } from '../buildConfig';
|
||||
@@ -6,6 +7,7 @@ import ArrayFields, { arrayDoc } from './collections/Array';
|
||||
import BlockFields, { blocksDoc } from './collections/Blocks';
|
||||
import CollapsibleFields, { collapsibleDoc } from './collections/Collapsible';
|
||||
import ConditionalLogic, { conditionalLogicDoc } from './collections/ConditionalLogic';
|
||||
import DateFields, { dateDoc } from './collections/Date';
|
||||
import RichTextFields, { richTextDoc } from './collections/RichText';
|
||||
import SelectFields, { selectsDoc } from './collections/Select';
|
||||
import TabsFields, { tabsDoc } from './collections/Tabs';
|
||||
@@ -16,6 +18,7 @@ import getFileByPath from '../../src/uploads/getFileByPath';
|
||||
import Uploads, { uploadsDoc } from './collections/Upload';
|
||||
import IndexedFields from './collections/Indexed';
|
||||
import NumberFields, { numberDoc } from './collections/Number';
|
||||
import CodeFields, { codeDoc } from './collections/Code';
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
@@ -33,6 +36,7 @@ export default buildConfig({
|
||||
collections: [
|
||||
ArrayFields,
|
||||
BlockFields,
|
||||
CodeFields,
|
||||
CollapsibleFields,
|
||||
ConditionalLogic,
|
||||
GroupFields,
|
||||
@@ -44,6 +48,7 @@ export default buildConfig({
|
||||
NumberFields,
|
||||
Uploads,
|
||||
IndexedFields,
|
||||
DateFields,
|
||||
],
|
||||
localization: {
|
||||
defaultLocale: 'en',
|
||||
@@ -58,14 +63,15 @@ export default buildConfig({
|
||||
},
|
||||
});
|
||||
|
||||
await payload.create({ collection: 'array-fields', data: arrayDoc });
|
||||
await payload.create({ collection: 'block-fields', data: blocksDoc });
|
||||
const createdArrayDoc = await payload.create({ collection: 'array-fields', data: arrayDoc });
|
||||
await payload.create({ collection: 'collapsible-fields', data: collapsibleDoc });
|
||||
await payload.create({ collection: 'conditional-logic', data: conditionalLogicDoc });
|
||||
await payload.create({ collection: 'group-fields', data: groupDoc });
|
||||
await payload.create({ collection: 'select-fields', data: selectsDoc });
|
||||
await payload.create({ collection: 'tabs-fields', data: tabsDoc });
|
||||
await payload.create({ collection: 'point-fields', data: pointDoc });
|
||||
await payload.create({ collection: 'date-fields', data: dateDoc });
|
||||
await payload.create({ collection: 'code-fields', data: codeDoc });
|
||||
|
||||
const createdTextDoc = await payload.create({ collection: 'text-fields', data: textDoc });
|
||||
|
||||
@@ -78,7 +84,8 @@ export default buildConfig({
|
||||
|
||||
const createdUploadDoc = await payload.create({ collection: 'uploads', data: uploadsDoc, file });
|
||||
|
||||
const richTextDocWithRelationship = { ...richTextDoc };
|
||||
const richTextDocWithRelId = JSON.parse(JSON.stringify(richTextDoc).replace('{{ARRAY_DOC_ID}}', createdArrayDoc.id));
|
||||
const richTextDocWithRelationship = { ...richTextDocWithRelId };
|
||||
|
||||
const richTextRelationshipIndex = richTextDocWithRelationship.richText.findIndex(({ type }) => type === 'relationship');
|
||||
richTextDocWithRelationship.richText[richTextRelationshipIndex].value = { id: createdTextDoc.id };
|
||||
@@ -89,5 +96,14 @@ export default buildConfig({
|
||||
await payload.create({ collection: 'rich-text-fields', data: richTextDocWithRelationship });
|
||||
|
||||
await payload.create({ collection: 'number-fields', data: numberDoc });
|
||||
|
||||
const blocksDocWithRichText = { ...blocksDoc };
|
||||
|
||||
// @ts-ignore
|
||||
blocksDocWithRichText.blocks[0].richText = richTextDocWithRelationship.richText;
|
||||
// @ts-ignore
|
||||
blocksDocWithRichText.localizedBlocks[0].richText = richTextDocWithRelationship.richText;
|
||||
|
||||
await payload.create({ collection: 'block-fields', data: blocksDocWithRichText });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -139,4 +139,75 @@ describe('fields', () => {
|
||||
await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fields - richText', () => {
|
||||
test('should create new url link', async () => {
|
||||
const url: AdminUrlUtil = new AdminUrlUtil(serverURL, 'rich-text-fields');
|
||||
await page.goto(url.list);
|
||||
await page.locator('.row-1 .cell-id').click();
|
||||
|
||||
// Open link popup
|
||||
await page.locator('.rich-text__toolbar .link').click();
|
||||
|
||||
const editLinkModal = page.locator('.rich-text-link-edit-modal__template');
|
||||
await expect(editLinkModal).toBeVisible();
|
||||
|
||||
// Fill values and click Confirm
|
||||
await editLinkModal.locator('#field-text').fill('link text');
|
||||
await editLinkModal.locator('label[for="field-linkType-custom"]').click();
|
||||
await editLinkModal.locator('#field-url').fill('https://payloadcms.com');
|
||||
await wait(200);
|
||||
await editLinkModal.locator('button[type="submit"]').click();
|
||||
|
||||
// Remove link
|
||||
await page.locator('span >> text="link text"').click();
|
||||
const popup = page.locator('.popup--active .rich-text-link__popup');
|
||||
await expect(popup.locator('.rich-text-link__link-label')).toBeVisible();
|
||||
await popup.locator('.rich-text-link__link-close').click();
|
||||
await expect(page.locator('span >> text="link text"')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('should populate url link', async () => {
|
||||
const url: AdminUrlUtil = new AdminUrlUtil(serverURL, 'rich-text-fields');
|
||||
await page.goto(url.list);
|
||||
await page.locator('.row-1 .cell-id').click();
|
||||
|
||||
// Open link popup
|
||||
await page.locator('span >> text="render links"').click();
|
||||
const popup = page.locator('.popup--active .rich-text-link__popup');
|
||||
await expect(popup).toBeVisible();
|
||||
await expect(popup.locator('a')).toHaveAttribute('href', 'https://payloadcms.com');
|
||||
|
||||
// Open link edit modal
|
||||
await popup.locator('.rich-text-link__link-edit').click();
|
||||
const editLinkModal = page.locator('.rich-text-link-edit-modal__template');
|
||||
await expect(editLinkModal).toBeVisible();
|
||||
|
||||
// Close link edit modal
|
||||
await editLinkModal.locator('button[type="submit"]').click();
|
||||
await expect(editLinkModal).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should populate relationship link', async () => {
|
||||
const url: AdminUrlUtil = new AdminUrlUtil(serverURL, 'rich-text-fields');
|
||||
await page.goto(url.list);
|
||||
await page.locator('.row-1 .cell-id').click();
|
||||
|
||||
// Open link popup
|
||||
await page.locator('span >> text="link to relationships"').click();
|
||||
const popup = page.locator('.popup--active .rich-text-link__popup');
|
||||
await expect(popup).toBeVisible();
|
||||
await expect(popup.locator('a')).toHaveAttribute('href', /\/admin\/collections\/array-fields\/.*/);
|
||||
|
||||
// Open link edit modal
|
||||
await popup.locator('.rich-text-link__link-edit').click();
|
||||
const editLinkModal = page.locator('.rich-text-link-edit-modal__template');
|
||||
await expect(editLinkModal).toBeVisible();
|
||||
|
||||
// Close link edit modal
|
||||
await editLinkModal.locator('button[type="submit"]').click();
|
||||
await expect(editLinkModal).not.toBeVisible();
|
||||
// await page.locator('span >> text="render links"').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -120,6 +120,9 @@ describe('Fields', () => {
|
||||
const options: Record<string, IndexOptions> = {};
|
||||
|
||||
beforeAll(() => {
|
||||
// mongoose model schema indexes do not always create indexes in the actual database
|
||||
// see: https://github.com/payloadcms/payload/issues/571
|
||||
|
||||
indexes = payload.collections['indexed-fields'].Model.schema.indexes() as [Record<string, IndexDirection>, IndexOptions];
|
||||
|
||||
indexes.forEach((index) => {
|
||||
@@ -149,10 +152,19 @@ describe('Fields', () => {
|
||||
expect(definitions['group.localizedUnique.es']).toEqual(1);
|
||||
expect(options['group.localizedUnique.es']).toMatchObject({ unique: true, sparse: true });
|
||||
});
|
||||
it('should have unique indexes in a collapsible', () => {
|
||||
expect(definitions['collapsibleLocalizedUnique.en']).toEqual(1);
|
||||
expect(options['collapsibleLocalizedUnique.en']).toMatchObject({ unique: true, sparse: true });
|
||||
expect(definitions.collapsibleTextUnique).toEqual(1);
|
||||
expect(options.collapsibleTextUnique).toMatchObject({ unique: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('point', () => {
|
||||
let doc;
|
||||
const point = [7, -7];
|
||||
const localized = [5, -2];
|
||||
const group = { point: [1, 9] };
|
||||
|
||||
beforeAll(async () => {
|
||||
const findDoc = await payload.find({
|
||||
@@ -176,9 +188,6 @@ describe('Fields', () => {
|
||||
});
|
||||
|
||||
it('should create', async () => {
|
||||
const point = [7, -7];
|
||||
const localized = [5, -2];
|
||||
const group = { point: [1, 9] };
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
@@ -192,6 +201,30 @@ describe('Fields', () => {
|
||||
expect(doc.localized).toEqual(localized);
|
||||
expect(doc.group).toMatchObject(group);
|
||||
});
|
||||
|
||||
it('should not create duplicate point when unique', async () => {
|
||||
await expect(() => payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
point,
|
||||
localized,
|
||||
group,
|
||||
},
|
||||
}))
|
||||
.rejects
|
||||
.toThrow(Error);
|
||||
|
||||
await expect(async () => payload.create({
|
||||
collection: 'number-fields',
|
||||
data: {
|
||||
min: 5,
|
||||
},
|
||||
})).rejects.toThrow('The following field is invalid: min');
|
||||
|
||||
expect(doc.point).toEqual(point);
|
||||
expect(doc.localized).toEqual(localized);
|
||||
expect(doc.group).toMatchObject(group);
|
||||
});
|
||||
});
|
||||
describe('array', () => {
|
||||
let doc;
|
||||
@@ -359,6 +392,78 @@ describe('Fields', () => {
|
||||
expect(blockFields.docs[0].blocks[2].subBlocks[0].number).toEqual(blocksFieldSeedData[2].subBlocks[0].number);
|
||||
expect(blockFields.docs[0].blocks[2].subBlocks[1].text).toEqual(blocksFieldSeedData[2].subBlocks[1].text);
|
||||
});
|
||||
|
||||
it('should query based on richtext data within a block', async () => {
|
||||
const blockFieldsSuccess = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'blocks.richText.children.text': {
|
||||
like: 'fun',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsSuccess.docs).toHaveLength(1);
|
||||
|
||||
const blockFieldsFail = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'blocks.richText.children.text': {
|
||||
like: 'funny',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsFail.docs).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should query based on richtext data within a localized block, specifying locale', async () => {
|
||||
const blockFieldsSuccess = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'localizedBlocks.en.richText.children.text': {
|
||||
like: 'fun',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsSuccess.docs).toHaveLength(1);
|
||||
|
||||
const blockFieldsFail = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'localizedBlocks.en.richText.children.text': {
|
||||
like: 'funny',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsFail.docs).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should query based on richtext data within a localized block, without specifying locale', async () => {
|
||||
const blockFieldsSuccess = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'localizedBlocks.richText.children.text': {
|
||||
like: 'fun',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsSuccess.docs).toHaveLength(1);
|
||||
|
||||
const blockFieldsFail = await payload.find({
|
||||
collection: 'block-fields',
|
||||
where: {
|
||||
'localizedBlocks.richText.children.text': {
|
||||
like: 'funny',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(blockFieldsFail.docs).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('richText', () => {
|
||||
@@ -385,5 +490,28 @@ describe('Fields', () => {
|
||||
|
||||
expect(workingRichTextQuery.docs).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should populate link relationship', async () => {
|
||||
const query = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.linkType': {
|
||||
equals: 'internal',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const nodes = query.docs[0].richText;
|
||||
expect(nodes).toBeDefined();
|
||||
const child = nodes.flatMap((n) => n.children)
|
||||
.find((c) => c.doc);
|
||||
expect(child).toMatchObject({
|
||||
type: 'link',
|
||||
linkType: 'internal',
|
||||
});
|
||||
expect(child.doc.relationTo).toEqual('array-fields');
|
||||
expect(typeof child.doc.value.id).toBe('string');
|
||||
expect(child.doc.value.items).toHaveLength(6);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,6 +40,9 @@ export interface BlockField {
|
||||
blocks: (
|
||||
| {
|
||||
text: string;
|
||||
richText?: {
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'text';
|
||||
@@ -70,6 +73,56 @@ export interface BlockField {
|
||||
blockType: 'subBlocks';
|
||||
}
|
||||
)[];
|
||||
localizedBlocks: (
|
||||
| {
|
||||
text: string;
|
||||
richText?: {
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'text';
|
||||
}
|
||||
| {
|
||||
number: number;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'number';
|
||||
}
|
||||
| {
|
||||
subBlocks: (
|
||||
| {
|
||||
text: string;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'text';
|
||||
}
|
||||
| {
|
||||
number: number;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'number';
|
||||
}
|
||||
)[];
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'subBlocks';
|
||||
}
|
||||
)[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "code-fields".
|
||||
*/
|
||||
export interface CodeField {
|
||||
id: string;
|
||||
javascript?: string;
|
||||
typescript?: string;
|
||||
json?: string;
|
||||
html?: string;
|
||||
css?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
@@ -188,6 +241,9 @@ export interface TabsField {
|
||||
blocks: (
|
||||
| {
|
||||
text: string;
|
||||
richText?: {
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'text';
|
||||
@@ -235,6 +291,7 @@ export interface TabsField {
|
||||
export interface TextField {
|
||||
id: string;
|
||||
text: string;
|
||||
localizedText?: string;
|
||||
defaultFunction?: string;
|
||||
defaultAsync?: string;
|
||||
createdAt: string;
|
||||
@@ -292,6 +349,22 @@ export interface IndexedField {
|
||||
*/
|
||||
point?: [number, number];
|
||||
};
|
||||
collapsibleLocalizedUnique?: string;
|
||||
collapsibleTextUnique?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "date-fields".
|
||||
*/
|
||||
export interface DateField {
|
||||
id: string;
|
||||
default: string;
|
||||
timeOnly?: string;
|
||||
dayOnly?: string;
|
||||
dayAndTime?: string;
|
||||
monthOnly?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user