Compare commits

..

80 Commits

Author SHA1 Message Date
James
6b932168ce 0.0.118 2020-10-12 12:41:48 -04:00
James
681bba82a9 removes mongoose-hidden, updates globals accordingly 2020-10-12 12:41:31 -04:00
Elliot DeNolf
5aede8affb fix component compilation 2020-10-11 14:29:46 -04:00
Elliot DeNolf
09dfb9793a fix webpack paths for both unix and windows 2020-10-11 14:14:21 -04:00
Elliot DeNolf
09897de77d add sort complex 2020-10-11 14:10:42 -04:00
Dan Ribbens
0362290d40 fix windows compatibility with webpack 2020-10-11 12:04:26 -04:00
James
57ef9fe623 fixes broken tests 2020-10-10 18:37:31 -04:00
James
38f08d54e3 0.0.117 2020-10-10 18:28:27 -04:00
James
84191ec8fd renames client to admin, sets up component library 2020-10-10 18:28:17 -04:00
James
e88be6b251 0.0.116 2020-10-09 13:39:14 -04:00
James
3bec424d05 Merge branch 'master' of github.com:keen-studio/payload 2020-10-09 13:39:07 -04:00
James
fc56a42fb0 fixes issue with relationship field and null value 2020-10-09 13:39:02 -04:00
James
05a5cc16bd further removes dependency on mongoose-hidden 2020-10-09 13:38:51 -04:00
Elliot DeNolf
c99b2f35f4 add disableScrollOnSuccess per-collection 2020-10-09 12:24:17 -04:00
Elliot DeNolf
8ae7457a3f add missing autoComplete attribute on password fields 2020-10-09 12:06:29 -04:00
Elliot DeNolf
bb8a04dd7b add style and width props for Group, Array, and Blocks 2020-10-09 11:45:58 -04:00
James
a681f5f725 builds unlock operation 2020-10-09 11:04:36 -04:00
Elliot DeNolf
613552de0a add style and width props for Blocks 2020-10-09 10:07:16 -04:00
Elliot DeNolf
cd38d37242 enforce maxRows on Arrays and Blocks 2020-10-09 10:07:10 -04:00
James
6b6b503ef0 0.0.115 2020-10-09 08:04:13 -04:00
James
f880072697 fixes bug with adding blocks and arrays due to async buildStateFromSchema 2020-10-08 23:03:37 -04:00
James
ffc3f10177 adds indication for readOnly Array and Blocks when no rows are present 2020-10-08 21:41:47 -04:00
James
f9b7e3239e adds both singular and plural labels to Blocks and Array, adjusts impacted files accordingly 2020-10-08 21:33:37 -04:00
James
09cc61c96a fixes modal scroll 2020-10-08 20:09:00 -04:00
James
a6325c69f4 Merge branch 'master' of github.com:keen-studio/payload 2020-10-08 19:32:36 -04:00
James
2f1b1a02b1 enables default values in new rows of array / block fields 2020-10-08 19:32:10 -04:00
James
727c5a4a53 styles baseline richText 2020-10-08 19:31:42 -04:00
James
918d3bd2bc fixes bug with clearing hasMany relationship field values 2020-10-08 19:31:26 -04:00
Elliot DeNolf
2d7bacad09 don't render 'Add Blocks' button when readOnly 2020-10-08 17:00:41 -04:00
James
234ed07ad6 Merge branch 'master' of github.com:keen-studio/payload 2020-10-08 16:18:08 -04:00
Elliot DeNolf
964fdf779a make rich text respect readOnly 2020-10-08 16:05:23 -04:00
Elliot DeNolf
40afb5e8fa add default value test for normal fields 2020-10-08 10:16:05 -04:00
James
72c0145816 0.0.114 2020-10-08 09:15:24 -04:00
James
12eb33b5c9 fixes bug with fromAddress in sanitizeConfig 2020-10-08 09:14:50 -04:00
Elliot DeNolf
ddb238c7e4 add blocks cell tests 2020-10-08 07:09:24 -04:00
Elliot DeNolf
32980fcafc Merge pull request #410 from trouble/tests-reorg 2020-10-08 06:29:30 -04:00
Elliot DeNolf
db6315a621 fix date cell test for timezone in CI 2020-10-08 06:27:19 -04:00
Elliot DeNolf
6bf0c2aab6 ci: add client tests 2020-10-08 05:53:47 -04:00
Elliot DeNolf
3dc9ddcb52 add some cell type tests 2020-10-08 05:50:07 -04:00
Elliot DeNolf
352dfa9a09 finish configuring client tests 2020-10-08 05:20:52 -04:00
Elliot DeNolf
60a3e680dd move tests dir to root 2020-10-08 05:01:48 -04:00
Elliot DeNolf
18f98e24e5 disable logging during tests, remove unused test:unit script, and add 'test' task to run all 2020-10-08 04:55:06 -04:00
Elliot DeNolf
c599522e44 isolate api tests inside tests/api 2020-10-08 04:50:33 -04:00
Elliot DeNolf
64fef7d380 implement basic react testing suite 2020-10-07 17:20:10 -04:00
James
6381d4cf6b 0.0.113 2020-10-07 16:52:58 -04:00
James
91016ec206 removes image-size in favor of probe-image-size to handle CMYK jpgs 2020-10-07 16:52:48 -04:00
James
9aeab9548d ensures default values work for Group and Array 2020-10-07 16:43:08 -04:00
James
69d7f21b56 partially working buildStateFromSchema 2020-10-07 16:26:56 -04:00
James
9de596605b fixes bug with localization 2020-10-07 16:18:01 -04:00
James
650edcf56a reduces padding on position-panel 2020-10-07 16:17:49 -04:00
James
2c4dedff2c only loads uploads if modal is open 2020-10-07 15:55:25 -04:00
James
870e39961c implements env-based bundle analyzer 2020-10-07 15:55:16 -04:00
James
319148ca68 adds default value collection 2020-10-07 15:54:53 -04:00
James
6dac68606b adds build scripts 2020-10-07 15:54:42 -04:00
James
9716d008a9 Merge branch 'master' of github.com:keen-studio/payload 2020-10-07 15:39:08 -04:00
James
b5fd68c3dc 0.0.112 2020-10-07 15:10:48 -04:00
James
eea9d14749 ensures modals have proper Z index, allows Upload field to handle deleted files gracefully 2020-10-07 15:10:39 -04:00
Elliot DeNolf
77de6e4b60 fix: initial form state 2020-10-07 14:53:55 -04:00
James
58f68e3bda 0.0.111 2020-10-07 14:51:50 -04:00
James
1ea3763185 better handles failed form submissions, allows customization of file uploads 2020-10-07 14:51:42 -04:00
James
920251f296 0.0.110 2020-10-07 12:42:41 -04:00
James
dffb554ebe fixes bug in Number field type 2020-10-07 12:42:32 -04:00
James
7255f6108f 0.0.109 2020-10-06 14:40:57 -04:00
James
078392f2c5 0.0.107 2020-10-06 14:40:52 -04:00
James
c2e9407f50 removes unused arg in findByID memoization 2020-10-06 14:39:53 -04:00
James
a5a4f1490e Merge branch 'master' of github.com:keen-studio/payload 2020-10-06 14:39:10 -04:00
James Mikrut
e20555f9cf Memoize populate (#408)
* Revert "0.0.108"

This reverts commit 7aafe49662.

* Revert "swaps out fast-memoize for micro-memoize that supports async"

This reverts commit 33d8ec8a13.

* Revert "implements a named populate function to memoize"

This reverts commit fb73e772af.

* Revert "0.0.107"

This reverts commit c2692e9b4a.

* reverts back to 106

* memoizes findByID
2020-10-06 14:38:20 -04:00
James
791a222d28 reverts back to 106 2020-10-06 13:16:36 -04:00
James
cb97090d88 Revert "0.0.107"
This reverts commit c2692e9b4a.
2020-10-06 13:15:33 -04:00
James
923cdc7b6a Revert "implements a named populate function to memoize"
This reverts commit fb73e772af.
2020-10-06 13:15:09 -04:00
James
19369b4c33 Revert "swaps out fast-memoize for micro-memoize that supports async"
This reverts commit 33d8ec8a13.
2020-10-06 13:15:00 -04:00
James
4ec230e8a0 Revert "0.0.108"
This reverts commit 7aafe49662.
2020-10-06 13:14:52 -04:00
James
7aafe49662 0.0.108 2020-10-06 09:47:13 -04:00
James
33d8ec8a13 swaps out fast-memoize for micro-memoize that supports async 2020-10-06 09:47:05 -04:00
James
fb73e772af implements a named populate function to memoize 2020-10-06 09:11:09 -04:00
James
c2692e9b4a 0.0.107 2020-10-06 08:58:30 -04:00
James
a0d6fe5ca7 memoizes the Populate function 2020-10-06 08:58:25 -04:00
James
7f65e68e82 0.0.106 2020-10-05 22:14:44 -04:00
James
d9f78fc5bf removes unused salt and hash hidden options 2020-10-05 22:14:11 -04:00
James
b2a5279bcb hides fields manually, removes isLocked virtual in favor of a defined Payload field 2020-10-05 22:12:33 -04:00
455 changed files with 4204 additions and 1672 deletions

View File

@@ -25,6 +25,7 @@ jobs:
${{ runner.os }}-build-
${{ runner.os }}-
- run: yarn
- run: yarn test:client
- run: yarn test:int # In-memory db + api tests
env:
CI: true

5
.gitignore vendored
View File

@@ -215,7 +215,6 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
# End of https://www.gitignore.io/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
# Ignore all uploads
@@ -225,3 +224,7 @@ demo/files
# Ignore build folder
build
# Ignore built components
components/index.js
components/styles.css

View File

@@ -1,3 +0,0 @@
export { default as Popup } from '../src/client/components/elements/Popup';
export { default as MinimalTemplate } from '../src/client/components/templates/Minimal';

View File

@@ -1 +0,0 @@
export { default as Button } from '../src/client/components/elements/Button';

View File

@@ -1,7 +0,0 @@
export { default as Form } from '../src/client/components/forms/Form';
export { default as Text } from '../src/client/components/forms/field-types/Text';
export { default as Group } from '../src/client/components/forms/field-types/Group';
export { default as Select } from '../src/client/components/forms/field-types/Select';
export { default as Checkbox } from '../src/client/components/forms/field-types/Checkbox';
export { default as Submit } from '../src/client/components/forms/Submit';
export { default as reduceFieldsToValues } from '../src/client/components/forms/Form/reduceFieldsToValues';

View File

@@ -1 +0,0 @@
export { default as X } from '../src/client/components/icons/X';

View File

@@ -1,3 +0,0 @@
export { default as LeafButton } from '../src/client/components/forms/field-types/RichText/leaves/Button';
export { default as ElementButton } from '../src/client/components/forms/field-types/RichText/elements/Button';
export { default as toggleElement } from '../src/client/components/forms/field-types/RichText/elements/toggle';

View File

@@ -1 +0,0 @@
@import '../src/client/scss/styles.scss';

View File

@@ -1,2 +0,0 @@
export { default as Edit } from '../src/client/components/views/collections/Edit/Default';
export { default as List } from '../src/client/components/views/collections/List/Default';

7
components/forms.js Normal file
View File

@@ -0,0 +1,7 @@
export { default as Form } from '../src/admin/components/forms/Form';
export { default as Text } from '../src/admin/components/forms/field-types/Text';
export { default as Group } from '../src/admin/components/forms/field-types/Group';
export { default as Select } from '../src/admin/components/forms/field-types/Select';
export { default as Checkbox } from '../src/admin/components/forms/field-types/Checkbox';
export { default as Submit } from '../src/admin/components/forms/Submit';
export { default as reduceFieldsToValues } from '../src/admin/components/forms/Form/reduceFieldsToValues';

3
components/rich-text.js Normal file
View File

@@ -0,0 +1,3 @@
export { default as LeafButton } from '../src/admin/components/forms/field-types/RichText/leaves/Button';
export { default as ElementButton } from '../src/admin/components/forms/field-types/RichText/elements/Button';
export { default as toggleElement } from '../src/admin/components/forms/field-types/RichText/elements/toggle';

2
components/views.js Normal file
View File

@@ -0,0 +1,2 @@
export { default as Edit } from '../src/admin/components/views/collections/Edit/Default';
export { default as List } from '../src/admin/components/views/collections/List/Default';

View File

@@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
import { Modal, useModal } from '@faceless-ui/modal';
import { Transforms } from 'slate';
import { useSlate } from 'slate-react';
import { MinimalTemplate } from '../../../../../../../admin/components';
import { ElementButton } from '../../../../../../../admin/rich-text';
import { X } from '../../../../../../../admin/icons';
import { Button } from '../../../../../../../admin/elements';
import { Form, Text, Checkbox, Select, Submit, reduceFieldsToValues } from '../../../../../../../admin/forms';
import MinimalTemplate from '../../../../../../../src/admin/components/templates/Minimal';
import { ElementButton } from '../../../../../../../components/rich-text';
import X from '../../../../../../../src/admin/components/icons/X';
import Button from '../../../../../../../src/admin/components/elements/Button';
import { Form, Text, Checkbox, Select, Submit, reduceFieldsToValues } from '../../../../../../../components/forms';
import './index.scss';

View File

@@ -1,4 +1,4 @@
@import '../../../../../../../admin/styles.scss';
@import '../../../../../../../scss/vars.scss';
.button-rich-text-button {
.btn {

View File

@@ -1,4 +1,4 @@
@import '../../../../../../../admin/styles.scss';
@import '../../../../../../../scss/vars.scss';
.rich-text-button {
margin: $baseline 0;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { LeafButton } from '../../../../../../../admin/rich-text';
import { LeafButton } from '../../../../../../../components/rich-text';
const Button = () => (
<LeafButton format="purple-background">

View File

@@ -12,6 +12,7 @@ const AllFields = {
},
admin: {
useAsTitle: 'text',
disableScrollOnSuccess: true,
},
preview: (doc, token) => {
if (doc && doc.text) {
@@ -188,9 +189,12 @@ const AllFields = {
{
type: 'blocks',
label: 'Blocks Content',
labels: {
singular: 'Block',
plural: 'Blocks',
},
name: 'blocks',
minRows: 2,
singularLabel: 'Block',
blocks: [Email, NumberBlock, Quote, CallToAction],
localized: true,
required: true,

View File

@@ -16,7 +16,10 @@ module.exports = {
{
name: 'layout',
label: 'Layout Blocks',
singularLabel: 'Block',
labels: {
singular: 'Block',
plural: 'Blocks',
},
type: 'blocks',
blocks: [Email, NumberBlock, Quote, CallToAction],
localized: true,
@@ -25,7 +28,10 @@ module.exports = {
{
name: 'nonLocalizedLayout',
label: 'Non Localized Layout',
singularLabel: 'Block',
labels: {
singular: 'Layout',
plural: 'Layouts',
},
type: 'blocks',
blocks: [Email, NumberBlock, Quote, CallToAction],
required: true,

View File

@@ -1,5 +1,5 @@
import React from 'react';
const Description = () => <div className="description">fake description field</div>
const Description = () => <div className="description">fake description field</div>;
export default Description;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Group } from '../../../../../../../admin/forms';
import { Group } from '../../../../../../../components/forms';
const CustomGroup = (props) => (
<div className="custom-group">

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import DefaultList from '../../../../../../src/client/components/views/collections/List/Default';
import DefaultList from '../../../../../../src/admin/components/views/collections/List/Default';
import './index.scss';

View File

@@ -0,0 +1,272 @@
const checkRole = require('../access/checkRole');
const Email = require('../blocks/Email');
const Quote = require('../blocks/Quote');
const NumberBlock = require('../blocks/Number');
const CallToAction = require('../blocks/CallToAction');
const DefaultValueTest = {
slug: 'default-value-test',
labels: {
singular: 'Default Value Test',
plural: 'Default Value Tests',
},
admin: {
useAsTitle: 'text',
},
preview: (doc, token) => {
if (doc && doc.text) {
return `http://localhost:3000/previewable-posts/${doc.text.value}?preview=true&token=${token}`;
}
return null;
},
access: {
read: () => true,
},
fields: [
{
name: 'text',
type: 'text',
label: 'Text',
defaultValue: 'Default Value',
unique: true,
access: {
create: ({ req: { user } }) => checkRole(['admin'], user),
update: ({ req: { user } }) => checkRole(['admin'], user),
read: ({ req: { user } }) => Boolean(user),
},
},
{
name: 'image',
type: 'upload',
label: 'Image',
relationTo: 'media',
},
{
name: 'select',
label: 'Select',
type: 'select',
options: [{
value: 'option-1',
label: 'Option 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}, {
value: 'option-4',
label: 'Option 4 Label',
}],
defaultValue: 'option-1',
},
{
name: 'selectMany',
label: 'Select w/ hasMany',
type: 'select',
options: [{
value: 'option-1',
label: 'Option 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}, {
value: 'option-4',
label: 'Option 4 Label',
}],
defaultValue: ['option-1', 'option-4'],
hasMany: true,
},
{
name: 'radioGroupExample',
label: 'Radio Group Example',
type: 'radio',
options: [{
value: 'option-1',
label: 'Options 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}],
defaultValue: 'option-2',
},
{
type: 'row',
fields: [
{
name: 'email',
label: 'Email',
type: 'email',
defaultValue: 'some@email.com',
}, {
name: 'number',
label: 'Number',
type: 'number',
defaultValue: 5,
},
],
},
{
type: 'group',
label: 'Group',
name: 'group',
fields: [
{
type: 'row',
fields: [
{
name: 'nestedText1',
label: 'Nested Text 1',
type: 'text',
defaultValue: 'nested default text 1',
}, {
name: 'nestedText2',
label: 'Nested Text 2',
type: 'text',
defaultValue: 'nested default text 2',
},
],
},
],
},
{
type: 'array',
label: 'Array',
name: 'array',
fields: [
{
type: 'row',
fields: [
{
name: 'arrayText1',
label: 'Array Text 1',
type: 'text',
admin: {
width: '50%',
},
defaultValue: 'default array text',
},
{
name: 'arrayText2',
label: 'Array Text 2',
type: 'text',
admin: {
width: '50%',
},
access: {
read: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => checkRole(['admin'], user),
},
},
],
},
{
type: 'text',
name: 'arrayText3',
label: 'Array Text 3',
admin: {
readOnly: true,
},
},
{
name: 'checkbox',
label: 'Checkbox',
type: 'checkbox',
default: true,
},
],
},
{
type: 'blocks',
label: 'Blocks Content',
name: 'blocks',
labels: {
singular: 'Block',
plural: 'Blocks',
},
blocks: [Email, NumberBlock, Quote, CallToAction],
localized: true,
},
{
type: 'relationship',
label: 'Relationship to One Collection',
name: 'relationship',
relationTo: 'conditions',
},
{
type: 'relationship',
label: 'Relationship hasMany',
name: 'relationshipHasMany',
relationTo: 'localized-posts',
hasMany: true,
},
{
type: 'relationship',
label: 'Relationship to Multiple Collections',
name: 'relationshipMultipleCollections',
relationTo: ['localized-posts', 'conditions'],
},
{
type: 'textarea',
label: 'Textarea',
name: 'textarea',
defaultValue: 'my textarea text',
},
{
name: 'slug',
type: 'text',
label: 'Slug',
admin: {
position: 'sidebar',
},
localized: true,
unique: true,
defaultValue: 'my-slug',
},
{
name: 'checkbox',
type: 'checkbox',
label: 'Checkbox',
admin: {
position: 'sidebar',
},
defaultValue: true,
},
{
name: 'richText',
type: 'richText',
label: 'Rich Text',
admin: {
elements: [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'blockquote',
'ul',
'ol',
'link',
],
leaves: [
'bold',
'italic',
'underline',
'strikethrough',
],
},
// defaultValue: 'sooo riiiiiiiich',
},
],
timestamps: true,
};
module.exports = DefaultValueTest;

View File

@@ -0,0 +1,283 @@
const checkRole = require('../access/checkRole');
const Email = require('../blocks/Email');
const Quote = require('../blocks/Quote');
const NumberBlock = require('../blocks/Number');
const CallToAction = require('../blocks/CallToAction');
const DefaultValues = {
slug: 'default-values',
labels: {
singular: 'Default Value Test',
plural: 'Default Value Tests',
},
admin: {
useAsTitle: 'text',
},
preview: (doc, token) => {
if (doc && doc.text) {
return `http://localhost:3000/previewable-posts/${doc.text.value}?preview=true&token=${token}`;
}
return null;
},
access: {
read: () => true,
},
fields: [
{
name: 'text',
type: 'text',
label: 'Text',
defaultValue: 'Default Value',
unique: true,
access: {
create: ({ req: { user } }) => checkRole(['admin'], user),
update: ({ req: { user } }) => checkRole(['admin'], user),
read: ({ req: { user } }) => Boolean(user),
},
},
{
name: 'image',
type: 'upload',
label: 'Image',
relationTo: 'media',
},
{
name: 'select',
label: 'Select',
type: 'select',
options: [{
value: 'option-1',
label: 'Option 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}, {
value: 'option-4',
label: 'Option 4 Label',
}],
defaultValue: 'option-1',
},
{
name: 'selectMany',
label: 'Select w/ hasMany',
type: 'select',
options: [{
value: 'option-1',
label: 'Option 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}, {
value: 'option-4',
label: 'Option 4 Label',
}],
defaultValue: ['option-1', 'option-4'],
hasMany: true,
},
{
name: 'radioGroupExample',
label: 'Radio Group Example',
type: 'radio',
options: [{
value: 'option-1',
label: 'Options 1 Label',
}, {
value: 'option-2',
label: 'Option 2 Label',
}, {
value: 'option-3',
label: 'Option 3 Label',
}],
defaultValue: 'option-2',
},
{
type: 'row',
fields: [
{
name: 'email',
label: 'Email',
type: 'email',
defaultValue: 'some@email.com',
}, {
name: 'number',
label: 'Number',
type: 'number',
defaultValue: 5,
},
],
},
{
type: 'group',
label: 'Group',
name: 'group',
defaultValue: {
nestedText1: 'neat',
},
fields: [
{
type: 'row',
fields: [
{
name: 'nestedText1',
label: 'Nested Text 1',
type: 'text',
defaultValue: 'nested default text 1',
}, {
name: 'nestedText2',
label: 'Nested Text 2',
type: 'text',
defaultValue: 'nested default text 2',
},
],
},
],
},
{
type: 'array',
label: 'Array',
name: 'array',
admin: {
readOnly: true,
},
defaultValue: [
{
arrayText1: 'Get out',
},
],
fields: [
{
type: 'row',
fields: [
{
name: 'arrayText1',
label: 'Array Text 1',
type: 'text',
admin: {
width: '50%',
},
defaultValue: 'default array text',
},
{
name: 'arrayText2',
label: 'Array Text 2',
type: 'text',
admin: {
width: '50%',
},
access: {
read: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => checkRole(['admin'], user),
},
},
],
},
{
type: 'text',
name: 'arrayText3',
label: 'Array Text 3',
admin: {
readOnly: true,
},
},
{
name: 'checkbox',
label: 'Checkbox',
type: 'checkbox',
default: true,
},
],
},
{
type: 'blocks',
label: 'Blocks Content',
name: 'blocks',
labels: {
singular: 'Block',
plural: 'Blocks',
},
blocks: [Email, NumberBlock, Quote, CallToAction],
localized: true,
},
{
type: 'relationship',
label: 'Relationship to One Collection',
name: 'relationship',
relationTo: 'conditions',
},
{
type: 'relationship',
label: 'Relationship hasMany',
name: 'relationshipHasMany',
relationTo: 'localized-posts',
hasMany: true,
},
{
type: 'relationship',
label: 'Relationship to Multiple Collections',
name: 'relationshipMultipleCollections',
relationTo: ['localized-posts', 'conditions'],
},
{
type: 'textarea',
label: 'Textarea',
name: 'textarea',
defaultValue: 'my textarea text',
},
{
name: 'slug',
type: 'text',
label: 'Slug',
admin: {
position: 'sidebar',
},
localized: true,
unique: true,
defaultValue: 'my-slug',
},
{
name: 'checkbox',
type: 'checkbox',
label: 'Checkbox',
admin: {
position: 'sidebar',
},
defaultValue: true,
},
{
name: 'richText',
type: 'richText',
label: 'Rich Text',
admin: {
elements: [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'blockquote',
'ul',
'ol',
'link',
],
leaves: [
'bold',
'italic',
'underline',
'strikethrough',
],
},
defaultValue: [{
children: [{ text: 'Cookin now' }],
}],
},
],
timestamps: true,
};
module.exports = DefaultValues;

View File

@@ -5,6 +5,7 @@ const Conditions = require('./collections/Conditions');
const CustomComponents = require('./collections/CustomComponents');
const File = require('./collections/File');
const Blocks = require('./collections/Blocks');
const DefaultValues = require('./collections/DefaultValues');
const HiddenFields = require('./collections/HiddenFields');
const Hooks = require('./collections/Hooks');
const Localized = require('./collections/Localized');
@@ -52,6 +53,7 @@ module.exports = {
Conditions,
CustomComponents,
File,
DefaultValues,
Blocks,
HiddenFields,
Hooks,
@@ -122,5 +124,10 @@ module.exports = {
console.error('global error config handler', err);
},
},
upload: {
limits: {
fileSize: 10000000, // 10MB
},
},
webpack: (config) => config,
};

View File

@@ -1,2 +1,2 @@
export { default as useFieldType } from './src/client/components/forms/useFieldType';
export { useForm } from './src/client/components/forms/Form/context';
export { default as useFieldType } from './src/admin/components/forms/useFieldType';
export { useForm } from './src/admin/components/forms/Form/context';

View File

@@ -1,8 +1,12 @@
module.exports = {
verbose: true,
testEnvironment: 'node',
globalSetup: '<rootDir>/src/tests/globalSetup.js',
globalTeardown: '<rootDir>/src/tests/globalTeardown.js',
globalSetup: '<rootDir>/tests/api/globalSetup.js',
globalTeardown: '<rootDir>/tests/api/globalTeardown.js',
testPathIgnorePatterns: [
'node_modules',
'src/admin/*',
],
testTimeout: 15000,
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/mocks/fileMock.js',

10
jest.react.config.js Normal file
View File

@@ -0,0 +1,10 @@
module.exports = {
verbose: true,
testTimeout: 15000,
testRegex: '(/src/admin/.*\\.(test|spec))\\.[jt]sx?$',
setupFilesAfterEnv: ['<rootDir>/tests/client/globalSetup.js'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/mocks/fileMock.js',
'\\.(css|scss)$': '<rootDir>/src/mocks/emptyModule.js',
},
};

View File

@@ -1,22 +1,27 @@
{
"name": "@payloadcms/payload",
"version": "0.0.105",
"version": "0.0.118",
"description": "CMS and Application Framework",
"license": "ISC",
"author": "Payload CMS LLC",
"main": "index.js",
"typings": "payload.d.ts",
"sideEffects": false,
"bin": {
"payload": "./src/bin/index.js"
},
"scripts": {
"build:components": "webpack --config src/webpack/components.config.js",
"build": "PAYLOAD_CONFIG_PATH=demo/payload.config.js node src/bin/build",
"build:analyze": "PAYLOAD_CONFIG_PATH=demo/payload.config.js PAYLOAD_ANALYZE_BUNDLE=true node src/bin/build",
"cov": "npm run core:build && node ./node_modules/jest/bin/jest.js src/tests --coverage",
"debug": "nodemon --inspect demo/server.js",
"debug:test:int": "node --inspect-brk node_modules/.bin/jest --runInBand",
"dev": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js nodemon demo/server.js",
"lint": "eslint .",
"test:int": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test jest --forceExit --runInBand",
"test:unit": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test jest"
"test": "yarn test:int && yarn test:client",
"test:int": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test DISABLE_LOGGING=true jest --forceExit --runInBand",
"test:client": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test jest --config=jest.react.config.js"
},
"dependencies": {
"@babel/core": "^7.11.6",
@@ -62,26 +67,24 @@
"html-webpack-plugin": "^3.2.0",
"http-status": "^1.4.2",
"ignore-styles": "^5.0.1",
"image-size": "^0.7.5",
"is-hotkey": "^0.1.6",
"is-url": "^1.2.4",
"isomorphic-fetch": "^2.2.1",
"isomorphic-style-loader": "^5.1.0",
"jest": "^25.3.0",
"jsonwebtoken": "^8.5.1",
"jwt-decode": "^3.0.0",
"method-override": "^3.0.0",
"micro-memoize": "^4.0.9",
"mini-css-extract-plugin": "^1.0.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mongodb-memory-server": "^6.5.2",
"mongoose": "^5.8.9",
"mongoose-hidden": "^1.8.1",
"mongoose-paginate-v2": "^1.3.6",
"node-sass": "^4.13.1",
"node-sass-chokidar": "^1.4.0",
"nodemailer": "^6.4.2",
"object-to-formdata": "^3.0.9",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"passport": "^0.4.1",
"passport-anonymous": "^1.0.1",
"passport-headerapikey": "^1.2.1",
@@ -90,10 +93,10 @@
"passport-local-mongoose": "^6.0.1",
"pino": "^6.4.1",
"pino-pretty": "^4.1.0",
"postcss-flexbugs-fixes": "^3.3.1",
"postcss-loader": "^2.1.6",
"postcss-preset-env": "6.0.6",
"postcss-loader": "^4.0.4",
"postcss-preset-env": "^6.7.0",
"prismjs": "^1.21.0",
"probe-image-size": "^5.0.0",
"prop-types": "^15.7.2",
"qs": "^6.9.1",
"qs-middleware": "^1.0.3",
@@ -109,26 +112,28 @@
"react-select": "^3.0.8",
"react-simple-code-editor": "^0.11.0",
"sanitize-filename": "^1.6.3",
"sass": "^1.27.0",
"sass-loader": "7.1.0",
"sharp": "^0.25.2",
"slate": "^0.58.4",
"slate-history": "^0.58.3",
"slate-hyperscript": "^0.58.3",
"slate-react": "^0.58.3",
"style-loader": "^0.21.0",
"terser-webpack-plugin": "^4.2.3",
"url-loader": "^1.0.1",
"uuid": "^8.1.0",
"webpack": "^4.43.0",
"webpack": "4.44.2",
"webpack-bundle-analyzer": "^3.8.0",
"webpack-dev-middleware": "^3.7.2",
"webpack-hot-middleware": "^2.25.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.4",
"@trbl/eslint-config": "^1.2.4",
"babel-eslint": "^10.0.1",
"cross-env": "^7.0.2",
"eslint": "^6.8.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-jest": "^23.16.0",
"eslint-plugin-jest-dom": "^3.0.1",
@@ -138,13 +143,15 @@
"faker": "^4.1.0",
"form-data": "^3.0.0",
"graphql-request": "^2.0.0",
"nodemon": "^1.19.4"
"nodemon": "^1.19.4",
"webpack-cli": "^4.0.0"
},
"files": [
"*.js",
"!jest.config.js",
"payload.d.ts",
"src",
"admin"
"components",
"scss"
]
}

8
payload.d.ts vendored
View File

@@ -110,6 +110,12 @@ declare module "@payloadcms/payload/types" {
type: 'number' | 'text' | 'email' | 'textarea' | 'richText' | 'code' | 'radio' | 'checkbox' | 'date' | 'upload' | 'relationship' | 'row' | 'array' | 'group' | 'select' | 'blocks';
localized?: boolean;
fields?: PayloadField[];
admin?:
{
position?: string;
width?: string;
style?: Object;
}
}
export type PayloadCollectionHook = (...args: any[]) => any | void;
@@ -122,6 +128,8 @@ declare module "@payloadcms/payload/types" {
},
admin?: {
useAsTitle?: string;
defaultColumns?: string[];
disableScrollOnSuccess?: boolean;
components?: any;
},
hooks?: {

1
scss/vars.scss Normal file
View File

@@ -0,0 +1 @@
@import '../src/admin/scss/vars';

View File

Before

Width:  |  Height:  |  Size: 437 B

After

Width:  |  Height:  |  Size: 437 B

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,69 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import './index.scss';
const baseClass = 'banner';
const Banner = ({
children, className, to, icon, alignIcon, onClick, type,
}) => {
const classes = [
baseClass,
`${baseClass}--type-${type}`,
className && className,
to && `${baseClass}--has-link`,
(to || onClick) && `${baseClass}--has-action`,
icon && `${baseClass}--has-icon`,
icon && `${baseClass}--align-icon-${alignIcon}`,
].filter(Boolean).join(' ');
let RenderedType = 'div';
if (onClick && !to) RenderedType = 'button';
if (to) RenderedType = Link;
return (
<RenderedType
className={classes}
onClick={onClick}
type={RenderedType === 'button' ? 'button' : undefined}
to={to || undefined}
>
{(icon && alignIcon === 'left') && (
<React.Fragment>
{icon}
</React.Fragment>
)}
{children}
{(icon && alignIcon === 'right') && (
<React.Fragment>
{icon}
</React.Fragment>
)}
</RenderedType>
);
};
Banner.defaultProps = {
children: undefined,
className: '',
to: undefined,
icon: undefined,
alignIcon: 'right',
onClick: undefined,
type: 'default',
};
Banner.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
icon: PropTypes.node,
alignIcon: PropTypes.oneOf(['left', 'right']),
onClick: PropTypes.func,
to: PropTypes.string,
type: PropTypes.oneOf(['error', 'success', 'info', 'default']),
};
export default Banner;

View File

@@ -0,0 +1,74 @@
@import '../../../scss/styles.scss';
.banner {
font-size: 1rem;
line-height: base(1);
border: 0;
vertical-align: middle;
background: rgba($color-dark-gray, .1);
color: $color-dark-gray;
border-radius: $style-radius-s;
padding: base(.5);
margin-bottom: $baseline;
&--has-action {
cursor: pointer;
text-decoration: none;
}
&--has-icon {
svg {
display: block;
}
}
&--align-icon-left {
padding-left: base(.125);
}
&--align-icon-right {
padding-right: base(.125);
}
&--type-default {
&.button--has-action {
&:hover {
background: darken($color-dark-gray, .15);
}
&:active {
background: darken($color-dark-gray, .2);
}
}
}
&--type-error {
background: rgba($color-red, .1);
color: $color-red;
&.button--has-action {
&:hover {
background: rgba($color-red, .15);
}
&:active {
background: rgba($color-red, .2);
}
}
}
&--type-success {
background: rgba($color-green, .1);
color: darken($color-green, 20%);
&.button--has-action {
&:hover {
background: rgba($color-green, .15);
}
&:active {
background: rgba($color-green, .2);
}
}
}
}

View File

@@ -4,6 +4,7 @@ import AnimateHeight from 'react-animate-height';
import SearchFilter from '../SearchFilter';
import ColumnSelector from '../ColumnSelector';
import WhereBuilder from '../WhereBuilder';
import SortComplex from '../SortComplex';
import Button from '../Button';
import './index.scss';
@@ -15,6 +16,8 @@ const ListControls = (props) => {
handleChange,
collection,
enableColumns,
enableSort,
setSort,
collection: {
fields,
admin: {
@@ -96,6 +99,17 @@ const ListControls = (props) => {
>
Filters
</Button>
{enableSort && (
<Button
className={`${baseClass}__toggle-sort`}
buttonStyle={visibleDrawer === 'sort' ? undefined : 'secondary'}
onClick={() => setVisibleDrawer(visibleDrawer !== 'sort' ? 'sort' : false)}
icon="chevron"
iconStyle="none"
>
Sort
</Button>
)}
</div>
</div>
</div>
@@ -120,16 +134,31 @@ const ListControls = (props) => {
collection={collection}
/>
</AnimateHeight>
{enableSort && (
<AnimateHeight
className={`${baseClass}__sort`}
height={visibleDrawer === 'sort' ? 'auto' : 0}
>
<SortComplex
handleChange={setSort}
collection={collection}
enableSort
/>
</AnimateHeight>
)}
</div>
);
};
ListControls.defaultProps = {
enableColumns: true,
enableSort: false,
};
ListControls.propTypes = {
enableColumns: PropTypes.bool,
enableSort: PropTypes.bool,
setSort: PropTypes.func.isRequired,
collection: PropTypes.shape({
admin: PropTypes.shape({
useAsTitle: PropTypes.string,

View File

@@ -27,7 +27,8 @@
}
&__toggle-columns,
&__toggle-where {
&__toggle-where,
&__toggle-sort {
margin: 0 base(.5);
min-width: 140px;
@@ -39,7 +40,8 @@
}
.column-selector,
.where-builder {
.where-builder,
.sort-complex {
margin-top: base(1);
}
@@ -68,7 +70,8 @@
}
&__toggle-columns,
&__toggle-where {
&__toggle-where,
&__toggle-sort {
flex-grow: 1;
}
}

View File

@@ -1,4 +1,4 @@
@import '../../../scss//styles';
@import '../../../scss/styles';
div.react-select {
div.rs__control {

Some files were not shown because too many files have changed in this diff Show More