implements babel transpilation of config, removes customComponents logic

This commit is contained in:
James
2020-09-21 17:31:19 -04:00
parent 9c28086ba4
commit fe99952561
64 changed files with 550 additions and 443 deletions

View File

@@ -1,9 +0,0 @@
import PageList from '../collections/Page/components/List';
const components = {
pages: {
List: PageList,
},
};
export default components;

View File

@@ -3,16 +3,14 @@ import PropTypes from 'prop-types';
import './index.scss'; import './index.scss';
const Filter = ({ onChange, value }) => { const Filter = ({ onChange, value }) => (
return (
<input <input
className="custom-description-filter" className="custom-description-filter"
type="text" type="text"
onChange={e => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
value={value} value={value}
/> />
); );
};
Filter.defaultProps = { Filter.defaultProps = {
value: '', value: '',

View File

@@ -4,15 +4,13 @@ import DefaultList from '../../../../../../src/client/components/views/collectio
import './index.scss'; import './index.scss';
const CustomListView = (props) => { const CustomListView = (props) => (
return (
<div className="custom-list"> <div className="custom-list">
<p>This is a custom Pages list view</p> <p>This is a custom Pages list view</p>
<p>Sup</p> <p>Sup</p>
<DefaultList {...props} /> <DefaultList {...props} />
</div> </div>
); );
};
CustomListView.propTypes = { CustomListView.propTypes = {
collection: PropTypes.shape({ collection: PropTypes.shape({

View File

@@ -1,3 +1,12 @@
const DescriptionField = require('./components/fields/Description/Field');
const DescriptionCell = require('./components/fields/Description/Cell');
const DescriptionFilter = require('./components/fields/Description/Filter');
const NestedArrayField = require('./components/fields/NestedArrayCustomField/Field');
const GroupField = require('./components/fields/Group/Field');
const NestedGroupField = require('./components/fields/NestedGroupCustomField/Field');
const NestedText1Field = require('./components/fields/NestedText1/Field');
const ListView = require('./components/views/List');
module.exports = { module.exports = {
slug: 'custom-components', slug: 'custom-components',
labels: { labels: {
@@ -23,9 +32,9 @@ module.exports = {
localized: true, localized: true,
admin: { admin: {
components: { components: {
field: 'collections/CustomComponents/components/fields/Description/Field/index.js', field: DescriptionField,
cell: 'collections/CustomComponents/components/fields/Description/Cell/index.js', cell: DescriptionCell,
filter: 'collections/CustomComponents/components/fields/Description/Filter/index.js', filter: DescriptionFilter,
}, },
}, },
}, },
@@ -40,7 +49,7 @@ module.exports = {
label: 'Nested Array Custom Field', label: 'Nested Array Custom Field',
admin: { admin: {
components: { components: {
field: 'collections/CustomComponents/components/fields/NestedArrayCustomField/Field/index.js', field: NestedArrayField,
}, },
}, },
}, },
@@ -52,7 +61,7 @@ module.exports = {
type: 'group', type: 'group',
admin: { admin: {
components: { components: {
field: 'collections/CustomComponents/components/fields/Group/Field/index.js', field: GroupField,
}, },
}, },
fields: [ fields: [
@@ -62,7 +71,7 @@ module.exports = {
label: 'Nested Group Custom Field', label: 'Nested Group Custom Field',
admin: { admin: {
components: { components: {
field: 'collections/CustomComponents/components/fields/NestedGroupCustomField/Field/index.js', field: NestedGroupField,
}, },
}, },
}, },
@@ -77,7 +86,7 @@ module.exports = {
type: 'text', type: 'text',
admin: { admin: {
components: { components: {
field: 'collections/CustomComponents/components/fields/NestedText1/Field/index.js', field: NestedText1Field,
}, },
}, },
}, { }, {
@@ -93,7 +102,7 @@ module.exports = {
useAsTitle: 'title', useAsTitle: 'title',
components: { components: {
views: { views: {
List: 'collections/CustomComponents/components/views/List/index.js', List: ListView,
}, },
}, },
}, },

View File

@@ -1,3 +1,8 @@
const ButtonToolbarButton = require('../client/components/richText/elements/Button/Button');
const ButtonElement = require('../client/components/richText/elements/Button/Element');
const StrikethroughButton = require('../client/components/richText/leaves/Strikethrough/Button');
const StrikethroughLeaf = require('../client/components/richText/leaves/Strikethrough/Leaf');
const RichText = { const RichText = {
slug: 'rich-text', slug: 'rich-text',
labels: { labels: {
@@ -17,8 +22,8 @@ const RichText = {
// 'h3', // 'h3',
{ {
name: 'button', name: 'button',
button: 'client/components/richText/elements/Button/Button', button: ButtonToolbarButton,
element: 'client/components/richText/elements/Button/Element', element: ButtonElement,
}, },
// 'blockquote', // 'blockquote',
'ul', 'ul',
@@ -29,8 +34,8 @@ const RichText = {
'italic', 'italic',
{ {
name: 'strikethrough', name: 'strikethrough',
button: 'client/components/richText/leaves/Strikethrough/Button', button: StrikethroughButton,
leaf: 'client/components/richText/leaves/Strikethrough/Leaf', leaf: StrikethroughLeaf,
}, },
], ],
}, },

View File

@@ -37,7 +37,9 @@ module.exports = {
disable: false, disable: false,
components: { components: {
layout: { layout: {
// Sidebar: 'client/components/layout/Sidebar/index.js', // Sidebar: () => (
// <div>Hello</div>
// ),
}, },
}, },
}, },

View File

@@ -19,10 +19,12 @@
"test:unit": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test jest" "test:unit": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.js NODE_ENV=test jest"
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.8.3", "@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/preset-env": "^7.8.3", "@babel/preset-env": "^7.8.3",
"@babel/preset-react": "^7.8.3", "@babel/preset-react": "^7.8.3",
"@babel/register": "^7.11.5",
"@date-io/date-fns": "^1.3.13", "@date-io/date-fns": "^1.3.13",
"@faceless-ui/collapsibles": "^0.1.0", "@faceless-ui/collapsibles": "^0.1.0",
"@faceless-ui/modal": "^1.0.4", "@faceless-ui/modal": "^1.0.4",
@@ -31,8 +33,9 @@
"@udecode/slate-plugins": "^0.64.3", "@udecode/slate-plugins": "^0.64.3",
"async-some": "^1.0.2", "async-some": "^1.0.2",
"autoprefixer": "^9.7.4", "autoprefixer": "^9.7.4",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-module-resolver": "^4.0.0",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"connect-history-api-fallback": "^1.6.0", "connect-history-api-fallback": "^1.6.0",
@@ -55,6 +58,7 @@
"graphql-type-json": "^0.3.1", "graphql-type-json": "^0.3.1",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"http-status": "^1.4.2", "http-status": "^1.4.2",
"ignore-styles": "^5.0.1",
"image-size": "^0.7.5", "image-size": "^0.7.5",
"is-hotkey": "^0.1.6", "is-hotkey": "^0.1.6",
"isomorphic-fetch": "^2.2.1", "isomorphic-fetch": "^2.2.1",
@@ -110,7 +114,7 @@
"style-loader": "^0.21.0", "style-loader": "^0.21.0",
"url-loader": "^1.0.1", "url-loader": "^1.0.1",
"uuid": "^8.1.0", "uuid": "^8.1.0",
"val-loader": "^2.1.0", "val-loader": "^2.1.1",
"webpack": "^4.43.0", "webpack": "^4.43.0",
"webpack-bundle-analyzer": "^3.8.0", "webpack-bundle-analyzer": "^3.8.0",
"webpack-dev-middleware": "^3.7.2", "webpack-dev-middleware": "^3.7.2",

View File

@@ -2,9 +2,9 @@ import React, { useState, useEffect } from 'react';
import { import {
Route, Switch, withRouter, Redirect, useHistory, Route, Switch, withRouter, Redirect, useHistory,
} from 'react-router-dom'; } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from './providers/Config';
import List from './views/collections/List'; import List from './views/collections/List';
import { useUser } from './data/User'; import { useAuthentication } from './providers/Authentication';
import DefaultTemplate from './templates/Default'; import DefaultTemplate from './templates/Default';
import Dashboard from './views/Dashboard'; import Dashboard from './views/Dashboard';
import ForgotPassword from './views/ForgotPassword'; import ForgotPassword from './views/ForgotPassword';
@@ -20,14 +20,14 @@ import Unauthorized from './views/Unauthorized';
import Account from './views/Account'; import Account from './views/Account';
import Loading from './elements/Loading'; import Loading from './elements/Loading';
const {
admin: { user: userSlug }, routes, collections, globals,
} = config;
const Routes = () => { const Routes = () => {
const history = useHistory(); const history = useHistory();
const [initialized, setInitialized] = useState(null); const [initialized, setInitialized] = useState(null);
const { user, permissions, permissions: { canAccessAdmin } } = useUser(); const { user, permissions, permissions: { canAccessAdmin } } = useAuthentication();
const {
admin: { user: userSlug }, routes, collections, globals,
} = useConfig();
useEffect(() => { useEffect(() => {
requests.get(`${routes.api}/${userSlug}/init`).then((res) => res.json().then((data) => { requests.get(`${routes.api}/${userSlug}/init`).then((res) => res.json().then((data) => {
@@ -35,7 +35,7 @@ const Routes = () => {
setInitialized(data.initialized); setInitialized(data.initialized);
} }
})); }));
}, []); }, [routes, userSlug]);
useEffect(() => { useEffect(() => {
history.replace(); history.replace();

View File

@@ -1,8 +1,8 @@
import React, { useState, useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { Modal, useModal } from '@faceless-ui/modal'; import { Modal, useModal } from '@faceless-ui/modal';
import { useConfig } from '../../providers/Config';
import Button from '../Button'; import Button from '../Button';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import useTitle from '../../../hooks/useTitle'; import useTitle from '../../../hooks/useTitle';
@@ -11,8 +11,6 @@ import { useStatusList } from '../Status';
import './index.scss'; import './index.scss';
const { serverURL, routes: { api, admin } } = config;
const baseClass = 'delete-document'; const baseClass = 'delete-document';
const DeleteDocument = (props) => { const DeleteDocument = (props) => {
@@ -30,6 +28,7 @@ const DeleteDocument = (props) => {
} = {}, } = {},
} = props; } = props;
const { serverURL, routes: { api, admin } } = useConfig();
const { replaceStatus } = useStatusList(); const { replaceStatus } = useStatusList();
const [deleting, setDeleting] = useState(false); const [deleting, setDeleting] = useState(false);
const { closeAll, toggle } = useModal(); const { closeAll, toggle } = useModal();
@@ -78,7 +77,7 @@ const DeleteDocument = (props) => {
return addDefaultError(); return addDefaultError();
} }
}); });
}, [addDefaultError, closeAll, history, id, replaceStatus, singular, slug, title]); }, [addDefaultError, closeAll, history, id, replaceStatus, singular, slug, title, admin, api, serverURL]);
if (id) { if (id) {
return ( return (

View File

@@ -1,19 +1,18 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Button from '../Button'; import Button from '../Button';
import { useForm } from '../../forms/Form/context'; import { useForm } from '../../forms/Form/context';
import './index.scss'; import './index.scss';
const { routes: { admin } } = config;
const baseClass = 'duplicate'; const baseClass = 'duplicate';
const Duplicate = ({ slug }) => { const Duplicate = ({ slug }) => {
const { push } = useHistory(); const { push } = useHistory();
const { getData } = useForm(); const { getData } = useForm();
const { routes: { admin } } = useConfig();
const handleClick = useCallback(() => { const handleClick = useCallback(() => {
const data = getData(); const data = getData();
@@ -24,7 +23,7 @@ const Duplicate = ({ slug }) => {
data, data,
}, },
}); });
}, [push, getData, slug]); }, [push, getData, slug, admin]);
return ( return (
<Button <Button

View File

@@ -1,13 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from '../../../../config'; import { useConfig } from '../../../providers/Config';
import CopyToClipboard from '../../CopyToClipboard'; import CopyToClipboard from '../../CopyToClipboard';
import formatFilesize from '../../../../../uploads/formatFilesize'; import formatFilesize from '../../../../../uploads/formatFilesize';
import './index.scss'; import './index.scss';
const { serverURL } = config;
const baseClass = 'file-meta'; const baseClass = 'file-meta';
const Meta = (props) => { const Meta = (props) => {
@@ -15,6 +13,8 @@ const Meta = (props) => {
filename, filesize, width, height, mimeType, staticURL, filename, filesize, width, height, mimeType, staticURL,
} = props; } = props;
const { serverURL } = useConfig();
const fileURL = `${serverURL}${staticURL}/${filename}`; const fileURL = `${serverURL}${staticURL}/${filename}`;
return ( return (
@@ -35,18 +35,18 @@ const Meta = (props) => {
<div className={`${baseClass}__size-type`}> <div className={`${baseClass}__size-type`}>
{formatFilesize(filesize)} {formatFilesize(filesize)}
{(width && height) && ( {(width && height) && (
<> <React.Fragment>
&nbsp;-&nbsp; &nbsp;-&nbsp;
{width} {width}
x x
{height} {height}
</> </React.Fragment>
)} )}
{mimeType && ( {mimeType && (
<> <React.Fragment>
&nbsp;-&nbsp; &nbsp;-&nbsp;
{mimeType} {mimeType}
</> </React.Fragment>
)} )}
</div> </div>
</div> </div>

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import qs from 'qs'; import qs from 'qs';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useLocale } from '../../utilities/Locale'; import { useLocale } from '../../utilities/Locale';
import { useSearchParams } from '../../utilities/SearchParams'; import { useSearchParams } from '../../utilities/SearchParams';
import Popup from '../Popup'; import Popup from '../Popup';
@@ -10,9 +10,8 @@ import './index.scss';
const baseClass = 'localizer'; const baseClass = 'localizer';
const { localization } = config;
const Localizer = () => { const Localizer = () => {
const { localization } = useConfig();
const locale = useLocale(); const locale = useLocale();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
@@ -24,8 +23,7 @@ const Localizer = () => {
<Popup <Popup
align="left" align="left"
button={locale} button={locale}
render={({ close }) => { render={({ close }) => (
return (
<div> <div>
<span>Locales</span> <span>Locales</span>
<ul> <ul>
@@ -64,8 +62,7 @@ const Localizer = () => {
})} })}
</ul> </ul>
</div> </div>
); )}
}}
/> />
</div> </div>
); );

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { NavLink, Link, useHistory } from 'react-router-dom'; import { NavLink, Link, useHistory } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import Chevron from '../../icons/Chevron'; import Chevron from '../../icons/Chevron';
import LogOut from '../../icons/LogOut'; import LogOut from '../../icons/LogOut';
import Menu from '../../icons/Menu'; import Menu from '../../icons/Menu';
@@ -14,18 +14,17 @@ import './index.scss';
const baseClass = 'nav'; const baseClass = 'nav';
const { const Nav = () => {
const { permissions } = useAuthentication();
const [menuActive, setMenuActive] = useState(false);
const history = useHistory();
const {
collections, collections,
globals, globals,
routes: { routes: {
admin, admin,
}, },
} = config; } = useConfig();
const Nav = () => {
const { permissions } = useUser();
const [menuActive, setMenuActive] = useState(false);
const history = useHistory();
const classes = [ const classes = [
baseClass, baseClass,
@@ -34,7 +33,7 @@ const Nav = () => {
useEffect(() => history.listen(() => { useEffect(() => history.listen(() => {
setMenuActive(false); setMenuActive(false);
}), []); }), [history]);
return ( return (
<aside className={classes}> <aside className={classes}>

View File

@@ -1,13 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useForm } from '../../forms/Form/context'; import { useForm } from '../../forms/Form/context';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import Button from '../Button'; import Button from '../Button';
const baseClass = 'preview-btn'; const baseClass = 'preview-btn';
const PreviewButton = ({ generatePreviewURL }) => { const PreviewButton = ({ generatePreviewURL }) => {
const { token } = useUser(); const { token } = useAuthentication();
const { getFields } = useForm(); const { getFields } = useForm();
const fields = getFields(); const fields = getFields();

View File

@@ -1,13 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from '../../../config'; import { useConfig } from '../../providers/Config';
import FileGraphic from '../../graphics/File'; import FileGraphic from '../../graphics/File';
import getThumbnail from '../../../../uploads/getThumbnail'; import getThumbnail from '../../../../uploads/getThumbnail';
import './index.scss'; import './index.scss';
const { serverURL } = config;
const baseClass = 'thumbnail'; const baseClass = 'thumbnail';
const Thumbnail = (props) => { const Thumbnail = (props) => {
@@ -15,6 +13,8 @@ const Thumbnail = (props) => {
filename, mimeType, staticURL, sizes, adminThumbnail, size, filename, mimeType, staticURL, sizes, adminThumbnail, size,
} = props; } = props;
const { serverURL } = useConfig();
const thumbnail = getThumbnail(mimeType, staticURL, filename, sizes, adminThumbnail); const thumbnail = getThumbnail(mimeType, staticURL, filename, sizes, adminThumbnail);
const classes = [ const classes = [

View File

@@ -25,7 +25,6 @@ const Condition = (props) => {
value, value,
orIndex, orIndex,
andIndex, andIndex,
collectionSlug,
} = props; } = props;
const [activeField, setActiveField] = useState({ operators: [] }); const [activeField, setActiveField] = useState({ operators: [] });
@@ -33,7 +32,7 @@ const Condition = (props) => {
const debouncedValue = useDebounce(internalValue, 300); const debouncedValue = useDebounce(internalValue, 300);
useEffect(() => { useEffect(() => {
const newActiveField = fields.find(field => value.field === field.value); const newActiveField = fields.find((field) => value.field === field.value);
if (newActiveField) { if (newActiveField) {
setActiveField(newActiveField); setActiveField(newActiveField);
@@ -57,9 +56,9 @@ const Condition = (props) => {
<div className={`${baseClass}__inputs`}> <div className={`${baseClass}__inputs`}>
<div className={`${baseClass}__field`}> <div className={`${baseClass}__field`}>
<ReactSelect <ReactSelect
value={fields.find(field => value.field === field.value)} value={fields.find((field) => value.field === field.value)}
options={fields} options={fields}
onChange={field => dispatch({ onChange={(field) => dispatch({
type: 'update', type: 'update',
orIndex, orIndex,
andIndex, andIndex,
@@ -69,9 +68,9 @@ const Condition = (props) => {
</div> </div>
<div className={`${baseClass}__operator`}> <div className={`${baseClass}__operator`}>
<ReactSelect <ReactSelect
value={activeField.operators.find(operator => value.operator === operator.value)} value={activeField.operators.find((operator) => value.operator === operator.value)}
options={activeField.operators} options={activeField.operators}
onChange={operator => dispatch({ onChange={(operator) => dispatch({
type: 'update', type: 'update',
orIndex, orIndex,
andIndex, andIndex,
@@ -81,7 +80,7 @@ const Condition = (props) => {
</div> </div>
<div className={`${baseClass}__value`}> <div className={`${baseClass}__value`}>
<RenderCustomComponent <RenderCustomComponent
path={`${collectionSlug}.fields.${activeField.value}.filter`} CustomComponent={activeField?.props?.admin?.components?.filter}
DefaultComponent={ValueComponent} DefaultComponent={ValueComponent}
componentProps={{ componentProps={{
...activeField.props, ...activeField.props,
@@ -144,7 +143,6 @@ Condition.propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
orIndex: PropTypes.number.isRequired, orIndex: PropTypes.number.isRequired,
andIndex: PropTypes.number.isRequired, andIndex: PropTypes.number.isRequired,
collectionSlug: PropTypes.string.isRequired,
}; };
export default Condition; export default Condition;

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useReducer } from 'react'; import React, { useState, useReducer } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import useThrottledEffect from '../../../hooks/useThrottledEffect'; import useThrottledEffect from '../../../hooks/useThrottledEffect';
import Button from '../Button'; import Button from '../Button';
@@ -43,7 +43,6 @@ const WhereBuilder = (props) => {
const { const {
collection, collection,
collection: { collection: {
slug,
labels: { labels: {
plural, plural,
} = {}, } = {},
@@ -114,7 +113,6 @@ const WhereBuilder = (props) => {
</div> </div>
)} )}
<Condition <Condition
collectionSlug={slug}
value={where[orIndex][andIndex]} value={where[orIndex][andIndex]}
orIndex={orIndex} orIndex={orIndex}
andIndex={andIndex} andIndex={andIndex}
@@ -162,7 +160,6 @@ const WhereBuilder = (props) => {
WhereBuilder.propTypes = { WhereBuilder.propTypes = {
handleChange: PropTypes.func.isRequired, handleChange: PropTypes.func.isRequired,
collection: PropTypes.shape({ collection: PropTypes.shape({
slug: PropTypes.string,
fields: PropTypes.arrayOf( fields: PropTypes.arrayOf(
PropTypes.shape({}), PropTypes.shape({}),
), ),

View File

@@ -27,7 +27,6 @@ const DraggableSection = (props) => {
singularLabel, singularLabel,
blockType, blockType,
fieldTypes, fieldTypes,
customComponentsPath,
toggleRowCollapse, toggleRowCollapse,
id, id,
positionPanelVerticalAlignment, positionPanelVerticalAlignment,
@@ -100,7 +99,6 @@ const DraggableSection = (props) => {
> >
<RenderFields <RenderFields
readOnly={readOnly} readOnly={readOnly}
customComponentsPath={customComponentsPath}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
key={rowIndex} key={rowIndex}
permissions={permissions} permissions={permissions}
@@ -142,7 +140,6 @@ DraggableSection.defaultProps = {
initialData: undefined, initialData: undefined,
singularLabel: '', singularLabel: '',
blockType: '', blockType: '',
customComponentsPath: '',
isOpen: true, isOpen: true,
positionPanelVerticalAlignment: 'sticky', positionPanelVerticalAlignment: 'sticky',
actionPanelVerticalAlignment: 'sticky', actionPanelVerticalAlignment: 'sticky',
@@ -164,7 +161,6 @@ DraggableSection.propTypes = {
isOpen: PropTypes.bool, isOpen: PropTypes.bool,
blockType: PropTypes.string, blockType: PropTypes.string,
fieldTypes: PropTypes.shape({}).isRequired, fieldTypes: PropTypes.shape({}).isRequired,
customComponentsPath: PropTypes.string,
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
positionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']), positionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']),
actionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']), actionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']),

View File

@@ -8,7 +8,7 @@ import { useLocale } from '../../utilities/Locale';
import { useStatusList } from '../../elements/Status'; import { useStatusList } from '../../elements/Status';
import { requests } from '../../../api'; import { requests } from '../../../api';
import useThrottledEffect from '../../../hooks/useThrottledEffect'; import useThrottledEffect from '../../../hooks/useThrottledEffect';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import fieldReducer from './fieldReducer'; import fieldReducer from './fieldReducer';
import initContextState from './initContextState'; import initContextState from './initContextState';
import reduceFieldsToValues from './reduceFieldsToValues'; import reduceFieldsToValues from './reduceFieldsToValues';
@@ -39,7 +39,7 @@ const Form = (props) => {
const history = useHistory(); const history = useHistory();
const locale = useLocale(); const locale = useLocale();
const { replaceStatus, addStatus, clearStatus } = useStatusList(); const { replaceStatus, addStatus, clearStatus } = useStatusList();
const { refreshCookie } = useUser(); const { refreshCookie } = useAuthentication();
const [modified, setModified] = useState(false); const [modified, setModified] = useState(false);
const [processing, setProcessing] = useState(false); const [processing, setProcessing] = useState(false);

View File

@@ -16,7 +16,6 @@ export const useRenderedFields = () => useContext(RenderedFieldContext);
const RenderFields = (props) => { const RenderFields = (props) => {
const { const {
fieldSchema, fieldSchema,
customComponentsPath: customComponentsPathFromProps,
fieldTypes, fieldTypes,
filter, filter,
permissions, permissions,
@@ -29,22 +28,19 @@ const RenderFields = (props) => {
const [intersectionRef, entry] = useIntersect(intersectionObserverOptions); const [intersectionRef, entry] = useIntersect(intersectionObserverOptions);
const isIntersecting = Boolean(entry?.isIntersecting); const isIntersecting = Boolean(entry?.isIntersecting);
const { customComponentsPath: customComponentsPathFromContext, operation: operationFromContext } = useRenderedFields(); const { operation: operationFromContext } = useRenderedFields();
const operation = operationFromProps || operationFromContext; const operation = operationFromProps || operationFromContext;
const customComponentsPath = customComponentsPathFromProps || customComponentsPathFromContext;
const [contextValue, setContextValue] = useState({ const [contextValue, setContextValue] = useState({
operation, operation,
customComponentsPath,
}); });
useEffect(() => { useEffect(() => {
setContextValue({ setContextValue({
operation, operation,
customComponentsPath,
}); });
}, [operation, customComponentsPath]); }, [operation]);
useEffect(() => { useEffect(() => {
if (isIntersecting && !hasIntersected) { if (isIntersecting && !hasIntersected) {
@@ -87,16 +83,13 @@ const RenderFields = (props) => {
readOnly = true; readOnly = true;
} }
const customComponentPath = `${customComponentsPath}${field.name ? `${field.name}` : ''}`;
if (FieldComponent) { if (FieldComponent) {
return ( return (
<RenderCustomComponent <RenderCustomComponent
key={i} key={i}
path={`${customComponentPath}.field`} CustomComponent={field?.admin?.components?.field}
DefaultComponent={FieldComponent} DefaultComponent={FieldComponent}
componentProps={{ componentProps={{
customComponentPath,
...field, ...field,
path: field.path || field.name, path: field.path || field.name,
fieldTypes, fieldTypes,
@@ -140,7 +133,6 @@ const RenderFields = (props) => {
}; };
RenderFields.defaultProps = { RenderFields.defaultProps = {
customComponentsPath: '',
filter: null, filter: null,
readOnly: false, readOnly: false,
permissions: {}, permissions: {},
@@ -152,7 +144,6 @@ RenderFields.propTypes = {
fieldSchema: PropTypes.arrayOf( fieldSchema: PropTypes.arrayOf(
PropTypes.shape({}), PropTypes.shape({}),
).isRequired, ).isRequired,
customComponentsPath: PropTypes.string,
fieldTypes: PropTypes.shape({ fieldTypes: PropTypes.shape({
hidden: PropTypes.function, hidden: PropTypes.function,
}).isRequired, }).isRequired,

View File

@@ -6,7 +6,6 @@ import withCondition from '../../withCondition';
import Button from '../../../elements/Button'; import Button from '../../../elements/Button';
import DraggableSection from '../../DraggableSection'; import DraggableSection from '../../DraggableSection';
import reducer from '../rowReducer'; import reducer from '../rowReducer';
import { useRenderedFields } from '../../RenderFields';
import { useForm } from '../../Form/context'; import { useForm } from '../../Form/context';
import useFieldType from '../../useFieldType'; import useFieldType from '../../useFieldType';
import Error from '../../Error'; import Error from '../../Error';
@@ -36,7 +35,6 @@ const ArrayFieldType = (props) => {
} = props; } = props;
const [rows, dispatchRows] = useReducer(reducer, []); const [rows, dispatchRows] = useReducer(reducer, []);
const { customComponentsPath } = useRenderedFields();
const { initialState, dispatchFields } = useForm(); const { initialState, dispatchFields } = useForm();
const path = pathFromProps || name; const path = pathFromProps || name;
@@ -111,7 +109,6 @@ const ArrayFieldType = (props) => {
removeRow={removeRow} removeRow={removeRow}
moveRow={moveRow} moveRow={moveRow}
path={path} path={path}
customComponentsPath={customComponentsPath}
name={name} name={name}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fields={fields} fields={fields}
@@ -166,8 +163,6 @@ const RenderArray = React.memo((props) => {
removeRow, removeRow,
moveRow, moveRow,
path, path,
customComponentsPath,
name,
fieldTypes, fieldTypes,
fields, fields,
permissions, permissions,
@@ -206,7 +201,6 @@ const RenderArray = React.memo((props) => {
moveRow={moveRow} moveRow={moveRow}
parentPath={path} parentPath={path}
initNull={row.initNull} initNull={row.initNull}
customComponentsPath={`${customComponentsPath}${name}.fields.`}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
permissions={permissions.fields} permissions={permissions.fields}
@@ -241,7 +235,6 @@ RenderArray.defaultProps = {
rows: [], rows: [],
singularLabel: 'Row', singularLabel: 'Row',
path: '', path: '',
customComponentsPath: undefined,
value: undefined, value: undefined,
readOnly: false, readOnly: false,
}; };
@@ -255,7 +248,6 @@ RenderArray.propTypes = {
), ),
singularLabel: PropTypes.string, singularLabel: PropTypes.string,
path: PropTypes.string, path: PropTypes.string,
customComponentsPath: PropTypes.string,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
value: PropTypes.number, value: PropTypes.number,
onDragEnd: PropTypes.func.isRequired, onDragEnd: PropTypes.func.isRequired,

View File

@@ -9,7 +9,6 @@ import Button from '../../../elements/Button';
import reducer from '../rowReducer'; import reducer from '../rowReducer';
import { useForm } from '../../Form/context'; import { useForm } from '../../Form/context';
import DraggableSection from '../../DraggableSection'; import DraggableSection from '../../DraggableSection';
import { useRenderedFields } from '../../RenderFields';
import Error from '../../Error'; import Error from '../../Error';
import useFieldType from '../../useFieldType'; import useFieldType from '../../useFieldType';
import Popup from '../../../elements/Popup'; import Popup from '../../../elements/Popup';
@@ -42,7 +41,6 @@ const Blocks = (props) => {
const path = pathFromProps || name; const path = pathFromProps || name;
const [rows, dispatchRows] = useReducer(reducer, []); const [rows, dispatchRows] = useReducer(reducer, []);
const { customComponentsPath } = useRenderedFields();
const { initialState, dispatchFields } = useForm(); const { initialState, dispatchFields } = useForm();
const memoizedValidate = useCallback((value) => { const memoizedValidate = useCallback((value) => {
@@ -127,7 +125,6 @@ const Blocks = (props) => {
removeRow={removeRow} removeRow={removeRow}
moveRow={moveRow} moveRow={moveRow}
path={path} path={path}
customComponentsPath={customComponentsPath}
name={name} name={name}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
toggleCollapse={toggleCollapse} toggleCollapse={toggleCollapse}
@@ -183,8 +180,6 @@ const RenderBlocks = React.memo((props) => {
removeRow, removeRow,
moveRow, moveRow,
path, path,
customComponentsPath,
name,
fieldTypes, fieldTypes,
permissions, permissions,
value, value,
@@ -235,7 +230,6 @@ const RenderBlocks = React.memo((props) => {
moveRow={moveRow} moveRow={moveRow}
toggleRowCollapse={() => toggleCollapse(i)} toggleRowCollapse={() => toggleCollapse(i)}
parentPath={path} parentPath={path}
customComponentsPath={`${customComponentsPath}${name}.fields.`}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
permissions={permissions.fields} permissions={permissions.fields}
fieldSchema={[ fieldSchema={[
@@ -296,7 +290,6 @@ RenderBlocks.defaultProps = {
rows: [], rows: [],
singularLabel: 'Row', singularLabel: 'Row',
path: '', path: '',
customComponentsPath: undefined,
value: undefined, value: undefined,
readOnly: false, readOnly: false,
}; };
@@ -310,7 +303,6 @@ RenderBlocks.propTypes = {
), ),
singularLabel: PropTypes.string, singularLabel: PropTypes.string,
path: PropTypes.string, path: PropTypes.string,
customComponentsPath: PropTypes.string,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
value: PropTypes.number, value: PropTypes.number,
onDragEnd: PropTypes.func.isRequired, onDragEnd: PropTypes.func.isRequired,

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import RenderFields, { useRenderedFields } from '../../RenderFields'; import RenderFields from '../../RenderFields';
import withCondition from '../../withCondition'; import withCondition from '../../withCondition';
import FieldTypeGutter from '../../FieldTypeGutter'; import FieldTypeGutter from '../../FieldTypeGutter';
@@ -22,8 +22,6 @@ const Group = (props) => {
const path = pathFromProps || name; const path = pathFromProps || name;
const { customComponentsPath } = useRenderedFields();
return ( return (
<div className="field-type group"> <div className="field-type group">
<FieldTypeGutter /> <FieldTypeGutter />
@@ -36,7 +34,6 @@ const Group = (props) => {
<RenderFields <RenderFields
readOnly={readOnly} readOnly={readOnly}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
customComponentsPath={`${customComponentsPath}${name}.fields.`}
fieldSchema={fields.map((subField) => ({ fieldSchema={fields.map((subField) => ({
...subField, ...subField,
path: `${path}${subField.name ? `.${subField.name}` : ''}`, path: `${path}${subField.name ? `.${subField.name}` : ''}`,

View File

@@ -3,7 +3,7 @@ import React, {
} from 'react'; } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import some from 'async-some'; import some from 'async-some';
import config from 'payload/config'; import { useConfig } from '../../../providers/Config';
import withCondition from '../../withCondition'; import withCondition from '../../withCondition';
import ReactSelect from '../../../elements/ReactSelect'; import ReactSelect from '../../../elements/ReactSelect';
import useFieldType from '../../useFieldType'; import useFieldType from '../../useFieldType';
@@ -13,10 +13,6 @@ import { relationship } from '../../../../../fields/validations';
import './index.scss'; import './index.scss';
const {
serverURL, routes: { api }, collections,
} = config;
const maxResultsPerRequest = 10; const maxResultsPerRequest = 10;
const baseClass = 'relationship'; const baseClass = 'relationship';
@@ -56,6 +52,7 @@ class Relationship extends Component {
} }
getNextOptions = (params = {}) => { getNextOptions = (params = {}) => {
const { config: { serverURL, routes: { api }, collections } } = this.props;
const { errorLoading } = this.state; const { errorLoading } = this.state;
const { clear } = params; const { clear } = params;
@@ -165,7 +162,7 @@ class Relationship extends Component {
} }
addOptions = (data, relation) => { addOptions = (data, relation) => {
const { hasMultipleRelations } = this.props; const { hasMultipleRelations, config: { collections } } = this.props;
const { options, loadedIDs } = this.state; const { options, loadedIDs } = this.state;
const collection = collections.find((coll) => coll.slug === relation); const collection = collections.find((coll) => coll.slug === relation);
@@ -263,6 +260,7 @@ class Relationship extends Component {
} }
addOptionByID = async (id, relation) => { addOptionByID = async (id, relation) => {
const { config: { serverURL, routes: { api } } } = this.props;
const { errorLoading } = this.state; const { errorLoading } = this.state;
if (!errorLoading) { if (!errorLoading) {
const response = await fetch(`${serverURL}${api}/${relation}/${id}`); const response = await fetch(`${serverURL}${api}/${relation}/${id}`);
@@ -377,9 +375,9 @@ Relationship.defaultProps = {
Relationship.propTypes = { Relationship.propTypes = {
relationTo: PropTypes.oneOfType([ relationTo: PropTypes.oneOfType([
PropTypes.oneOf(Object.keys(collections).map((key) => collections[key].slug)), PropTypes.string,
PropTypes.arrayOf( PropTypes.arrayOf(
PropTypes.oneOf(Object.keys(collections).map((key) => collections[key].slug)), PropTypes.string,
), ),
]).isRequired, ]).isRequired,
required: PropTypes.bool, required: PropTypes.bool,
@@ -401,6 +399,22 @@ Relationship.propTypes = {
PropTypes.array, PropTypes.array,
PropTypes.shape({}), PropTypes.shape({}),
]), ]),
config: PropTypes.shape({
serverURL: PropTypes.string,
routes: PropTypes.shape({
admin: PropTypes.string,
api: PropTypes.string,
}),
collections: PropTypes.arrayOf(
PropTypes.shape({
slug: PropTypes.string,
labels: PropTypes.shape({
singular: PropTypes.string,
plural: PropTypes.string,
}),
}),
),
}).isRequired,
}; };
const RelationshipFieldType = (props) => { const RelationshipFieldType = (props) => {
@@ -408,6 +422,8 @@ const RelationshipFieldType = (props) => {
relationTo, validate, path, name, required, relationTo, validate, path, name, required,
} = props; } = props;
const config = useConfig;
const hasMultipleRelations = Array.isArray(relationTo); const hasMultipleRelations = Array.isArray(relationTo);
const memoizedValidate = useCallback((value) => { const memoizedValidate = useCallback((value) => {
@@ -423,6 +439,7 @@ const RelationshipFieldType = (props) => {
return ( return (
<Relationship <Relationship
config={config}
{...props} {...props}
{...fieldType} {...fieldType}
hasMultipleRelations={hasMultipleRelations} hasMultipleRelations={hasMultipleRelations}

View File

@@ -1,7 +1,7 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Modal, useModal } from '@faceless-ui/modal'; import { Modal, useModal } from '@faceless-ui/modal';
import config from '../../../../../config'; import { useConfig } from '../../../../providers/Config';
import MinimalTemplate from '../../../../templates/Minimal'; import MinimalTemplate from '../../../../templates/Minimal';
import Form from '../../../Form'; import Form from '../../../Form';
import Button from '../../../../elements/Button'; import Button from '../../../../elements/Button';
@@ -11,8 +11,6 @@ import Upload from '../../../../views/collections/Edit/Upload';
import './index.scss'; import './index.scss';
const { serverURL, routes: { api } } = config;
const baseClass = 'add-upload-modal'; const baseClass = 'add-upload-modal';
const AddUploadModal = (props) => { const AddUploadModal = (props) => {
@@ -23,6 +21,7 @@ const AddUploadModal = (props) => {
setValue, setValue,
} = props; } = props;
const { serverURL, routes: { api } } = useConfig();
const { closeAll } = useModal(); const { closeAll } = useModal();
const onSuccess = useCallback((json) => { const onSuccess = useCallback((json) => {
@@ -69,7 +68,6 @@ const AddUploadModal = (props) => {
filter={(field) => (!field.position || (field.position && field.position !== 'sidebar'))} filter={(field) => (!field.position || (field.position && field.position !== 'sidebar'))}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={collection.fields} fieldSchema={collection.fields}
customComponentsPath={`${collection.slug}.fields.`}
/> />
</Form> </Form>
</MinimalTemplate> </MinimalTemplate>

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Modal, useModal } from '@faceless-ui/modal'; import { Modal, useModal } from '@faceless-ui/modal';
import config from '../../../../../config'; import { useConfig } from '../../../../providers/Config';
import MinimalTemplate from '../../../../templates/Minimal'; import MinimalTemplate from '../../../../templates/Minimal';
import Button from '../../../../elements/Button'; import Button from '../../../../elements/Button';
import formatFields from '../../../../views/collections/List/formatFields'; import formatFields from '../../../../views/collections/List/formatFields';
@@ -12,8 +12,6 @@ import UploadGallery from '../../../../elements/UploadGallery';
import './index.scss'; import './index.scss';
const { serverURL, routes: { api } } = config;
const baseClass = 'select-existing-upload-modal'; const baseClass = 'select-existing-upload-modal';
const SelectExistingUploadModal = (props) => { const SelectExistingUploadModal = (props) => {
@@ -26,6 +24,7 @@ const SelectExistingUploadModal = (props) => {
slug: modalSlug, slug: modalSlug,
} = props; } = props;
const { serverURL, routes: { api } } = useConfig();
const { closeAll } = useModal(); const { closeAll } = useModal();
const [fields, setFields] = useState(collection.fields); const [fields, setFields] = useState(collection.fields);
const [listControls, setListControls] = useState({}); const [listControls, setListControls] = useState({});

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useModal } from '@faceless-ui/modal'; import { useModal } from '@faceless-ui/modal';
import config from '../../../../config'; import { useConfig } from '../../../providers/Config';
import useFieldType from '../../useFieldType'; import useFieldType from '../../useFieldType';
import withCondition from '../../withCondition'; import withCondition from '../../withCondition';
import Button from '../../../elements/Button'; import Button from '../../../elements/Button';
@@ -14,13 +14,12 @@ import SelectExistingModal from './SelectExisting';
import './index.scss'; import './index.scss';
const { collections, serverURL, routes: { api } } = config;
const baseClass = 'upload'; const baseClass = 'upload';
const Upload = (props) => { const Upload = (props) => {
const { toggle } = useModal(); const { toggle } = useModal();
const [internalValue, setInternalValue] = useState(undefined); const [internalValue, setInternalValue] = useState(undefined);
const { collections, serverURL, routes: { api } } = useConfig();
const { const {
path: pathFromProps, path: pathFromProps,

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import RenderCustomComponent from '../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import { useConfig } from '../../providers/Config';
const PayloadIcon = () => ( const PayloadIcon = () => (
<svg <svg
@@ -19,11 +20,24 @@ const PayloadIcon = () => (
</svg> </svg>
); );
const Icon = () => ( const Icon = () => {
const {
admin: {
components: {
graphics: {
icon: CustomIcon,
} = {},
} = {},
} = {},
} = useConfig();
return (
<RenderCustomComponent <RenderCustomComponent
CustomComponent={CustomIcon}
path="graphics.Icon" path="graphics.Icon"
DefaultComponent={PayloadIcon} DefaultComponent={PayloadIcon}
/> />
); );
};
export default Icon; export default Icon;

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import RenderCustomComponent from '../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import { useConfig } from '../../providers/Config';
const PayloadLogo = () => ( const PayloadLogo = () => (
<svg <svg
@@ -49,11 +50,23 @@ const PayloadLogo = () => (
</svg> </svg>
); );
const Logo = () => ( const Logo = () => {
const {
admin: {
components: {
graphics: {
Logo: CustomLogo,
} = {},
} = {},
} = {},
} = useConfig();
return (
<RenderCustomComponent <RenderCustomComponent
path="graphics.Logo" CustomComponent={CustomLogo}
DefaultComponent={PayloadLogo} DefaultComponent={PayloadLogo}
/> />
); );
};
export default Logo; export default Logo;

View File

@@ -7,9 +7,10 @@ import { ModalProvider, ModalContainer } from '@faceless-ui/modal';
import { SearchParamsProvider } from './utilities/SearchParams'; import { SearchParamsProvider } from './utilities/SearchParams';
import { LocaleProvider } from './utilities/Locale'; import { LocaleProvider } from './utilities/Locale';
import StatusList, { StatusListProvider } from './elements/Status'; import StatusList, { StatusListProvider } from './elements/Status';
import { UserProvider } from './data/User'; import { AuthenticationProvider } from './providers/Authentication';
import Routes from './Routes'; import Routes from './Routes';
import getCSSVariable from '../../utilities/getCSSVariable'; import getCSSVariable from '../../utilities/getCSSVariable';
import ConfigProvider from './providers/Config/Provider';
import '../scss/app.scss'; import '../scss/app.scss';
@@ -24,6 +25,7 @@ const Index = () => {
}; };
return ( return (
<ConfigProvider>
<WindowInfoProvider {...windowInfoProps}> <WindowInfoProvider {...windowInfoProps}>
<ScrollInfoProvider> <ScrollInfoProvider>
<Router> <Router>
@@ -31,7 +33,7 @@ const Index = () => {
classPrefix="payload" classPrefix="payload"
zIndex={parseInt(getCSSVariable('z-modal'), 10)} zIndex={parseInt(getCSSVariable('z-modal'), 10)}
> >
<UserProvider> <AuthenticationProvider>
<StatusListProvider> <StatusListProvider>
<SearchParamsProvider> <SearchParamsProvider>
<LocaleProvider> <LocaleProvider>
@@ -41,11 +43,12 @@ const Index = () => {
</SearchParamsProvider> </SearchParamsProvider>
</StatusListProvider> </StatusListProvider>
<ModalContainer /> <ModalContainer />
</UserProvider> </AuthenticationProvider>
</ModalProvider> </ModalProvider>
</Router> </Router>
</ScrollInfoProvider> </ScrollInfoProvider>
</WindowInfoProvider> </WindowInfoProvider>
</ConfigProvider>
); );
}; };

View File

@@ -3,7 +3,7 @@ import NavigationPrompt from 'react-router-navigation-prompt';
import { useFormModified } from '../../forms/Form/context'; import { useFormModified } from '../../forms/Form/context';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import './index.scss'; import './index.scss';
@@ -11,7 +11,7 @@ const modalSlug = 'leave-without-saving';
const LeaveWithoutSaving = () => { const LeaveWithoutSaving = () => {
const modified = useFormModified(); const modified = useFormModified();
const { user } = useUser(); const { user } = useAuthentication();
return ( return (
<NavigationPrompt when={modified && user}> <NavigationPrompt when={modified && user}>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useModal, Modal } from '@faceless-ui/modal'; import { useModal, Modal } from '@faceless-ui/modal';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
@@ -10,11 +10,10 @@ import './index.scss';
const baseClass = 'stay-logged-in'; const baseClass = 'stay-logged-in';
const { routes: { admin } } = config;
const StayLoggedInModal = (props) => { const StayLoggedInModal = (props) => {
const { refreshCookie } = props; const { refreshCookie } = props;
const history = useHistory(); const history = useHistory();
const { routes: { admin } } = useConfig();
const { closeAll: closeAllModals } = useModal(); const { closeAll: closeAllModals } = useModal();
return ( return (

View File

@@ -4,13 +4,19 @@ import React, {
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { useLocation, useHistory } from 'react-router-dom'; import { useLocation, useHistory } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config';
import { useModal } from '@faceless-ui/modal'; import { useModal } from '@faceless-ui/modal';
import { useConfig } from './Config';
import { requests } from '../../api'; import { requests } from '../../api';
import StayLoggedInModal from '../modals/StayLoggedIn'; import StayLoggedInModal from '../modals/StayLoggedIn';
import useDebounce from '../../hooks/useDebounce'; import useDebounce from '../../hooks/useDebounce';
const { const Context = createContext({});
const AuthenticationProvider = ({ children }) => {
const [user, setUser] = useState(undefined);
const [tokenInMemory, setTokenInMemory] = useState(null);
const {
admin: { admin: {
user: userSlug, user: userSlug,
}, },
@@ -19,13 +25,8 @@ const {
admin, admin,
api, api,
}, },
} = config; } = useConfig();
const Context = createContext({});
const UserProvider = ({ children }) => {
const [user, setUser] = useState(undefined);
const [tokenInMemory, setTokenInMemory] = useState(null);
const exp = user?.exp; const exp = user?.exp;
const [permissions, setPermissions] = useState({ canAccessAdmin: null }); const [permissions, setPermissions] = useState({ canAccessAdmin: null });
@@ -54,7 +55,7 @@ const UserProvider = ({ children }) => {
} }
}, 1000); }, 1000);
} }
}, [setUser, history, exp]); }, [setUser, history, exp, admin, api, serverURL, userSlug]);
const setToken = useCallback((token) => { const setToken = useCallback((token) => {
const decoded = jwt.decode(token); const decoded = jwt.decode(token);
@@ -112,7 +113,7 @@ const UserProvider = ({ children }) => {
if (email) { if (email) {
getPermissions(); getPermissions();
} }
}, [email]); }, [email, api, serverURL]);
useEffect(() => { useEffect(() => {
let reminder = false; let reminder = false;
@@ -145,7 +146,7 @@ const UserProvider = ({ children }) => {
return () => { return () => {
if (forceLogOut) clearTimeout(forceLogOut); if (forceLogOut) clearTimeout(forceLogOut);
}; };
}, [exp, history, closeAllModals]); }, [exp, history, closeAllModals, admin]);
return ( return (
<Context.Provider value={{ <Context.Provider value={{
@@ -163,16 +164,16 @@ const UserProvider = ({ children }) => {
); );
}; };
UserProvider.propTypes = { AuthenticationProvider.propTypes = {
children: PropTypes.oneOfType([ children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node), PropTypes.arrayOf(PropTypes.node),
PropTypes.node, PropTypes.node,
]).isRequired, ]).isRequired,
}; };
const useUser = () => useContext(Context); const useAuthentication = () => useContext(Context);
export { export {
UserProvider, AuthenticationProvider,
useUser, useAuthentication,
}; };

View File

@@ -0,0 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import unsanitizedConfig from 'payload/unsanitizedConfig';
import sanitizeConfig from '../../../../utilities/sanitizeConfig';
import Context from './context';
const sanitizedConfig = sanitizeConfig(unsanitizedConfig);
const ConfigProvider = ({ children }) => (
<Context.Provider value={sanitizedConfig}>
{children}
</Context.Provider>
);
ConfigProvider.propTypes = {
children: PropTypes.node.isRequired,
};
export default ConfigProvider;

View File

@@ -0,0 +1,5 @@
import { createContext } from 'react';
const Context = createContext({});
export default Context;

View File

@@ -0,0 +1 @@
export { default as useConfig } from './useConfig';

View File

@@ -0,0 +1,6 @@
import { useContext } from 'react';
import Context from './context';
const useConfig = () => useContext(Context);
export default useConfig;

View File

@@ -2,22 +2,21 @@ import React, {
createContext, useContext, useState, useEffect, createContext, useContext, useState, useEffect,
} from 'react'; } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useSearchParams } from '../SearchParams'; import { useSearchParams } from '../SearchParams';
const { localization } = config;
const defaultLocale = (localization && localization.defaultLocale) ? localization.defaultLocale : 'en';
const Context = createContext({}); const Context = createContext({});
export const LocaleProvider = ({ children }) => { export const LocaleProvider = ({ children }) => {
const { localization } = useConfig();
const defaultLocale = (localization && localization.defaultLocale) ? localization.defaultLocale : 'en';
const [locale, setLocale] = useState(defaultLocale); const [locale, setLocale] = useState(defaultLocale);
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const localeFromParams = searchParams.locale; const localeFromParams = searchParams.locale;
useEffect(() => { useEffect(() => {
if (localeFromParams && localization.locales.indexOf(localeFromParams) > -1) setLocale(localeFromParams); if (localeFromParams && localization.locales.indexOf(localeFromParams) > -1) setLocale(localeFromParams);
}, [localeFromParams]); }, [localeFromParams, localization]);
return ( return (
<Context.Provider value={locale}> <Context.Provider value={locale}>

View File

@@ -1,14 +1,16 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import payloadFavicon from '../../../assets/images/favicon.svg'; import payloadFavicon from '../../../assets/images/favicon.svg';
import payloadOgImage from '../../../assets/images/og-image.png'; import payloadOgImage from '../../../assets/images/og-image.png';
function Meta({ description, lang, meta, title, keywords }) { function Meta({ description, lang, meta, title, keywords }) {
const config = useConfig();
const titleSuffix = config?.admin?.meta?.titleSuffix ?? '- Payload'; const titleSuffix = config?.admin?.meta?.titleSuffix ?? '- Payload';
const favicon = config?.admin?.meta?.favicon ?? payloadFavicon; const favicon = config?.admin?.meta?.favicon ?? payloadFavicon;
const ogImage = config?.admin?.meta?.ogImage ?? payloadOgImage; const ogImage = config?.admin?.meta?.ogImage ?? payloadOgImage;
return ( return (
<Helmet <Helmet
htmlAttributes={{ htmlAttributes={{

View File

@@ -1,36 +1,14 @@
import React, { Suspense } from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import customComponents from '../../customComponents';
import Loading from '../../elements/Loading';
const RenderCustomComponent = (props) => { const RenderCustomComponent = (props) => {
const { path, DefaultComponent, componentProps } = props; const { CustomComponent, DefaultComponent, componentProps } = props;
if (path) {
const customComponentImport = path.split('.').reduce((res, prop) => {
const potentialRowIndex = parseInt(prop, 10);
if (!Number.isNaN(potentialRowIndex) && res.fields) {
return res.fields;
}
if (res) {
return res[prop];
}
return false;
}, customComponents);
if (customComponentImport) {
const CustomComponent = React.lazy(customComponentImport);
if (CustomComponent) {
return ( return (
<Suspense fallback={<Loading />}>
<CustomComponent {...componentProps} /> <CustomComponent {...componentProps} />
</Suspense>
); );
} }
}
return ( return (
<DefaultComponent {...componentProps} /> <DefaultComponent {...componentProps} />
@@ -40,6 +18,7 @@ const RenderCustomComponent = (props) => {
RenderCustomComponent.defaultProps = { RenderCustomComponent.defaultProps = {
path: undefined, path: undefined,
componentProps: {}, componentProps: {},
CustomComponent: null,
}; };
RenderCustomComponent.propTypes = { RenderCustomComponent.propTypes = {
@@ -50,6 +29,7 @@ RenderCustomComponent.propTypes = {
PropTypes.node, PropTypes.node,
PropTypes.element, PropTypes.element,
]).isRequired, ]).isRequired,
CustomComponent: PropTypes.func,
componentProps: PropTypes.shape({}), componentProps: PropTypes.shape({}),
}; };

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import format from 'date-fns/format'; import format from 'date-fns/format';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Eyebrow from '../../elements/Eyebrow'; import Eyebrow from '../../elements/Eyebrow';
import Form from '../../forms/Form'; import Form from '../../forms/Form';
import PreviewButton from '../../elements/PreviewButton'; import PreviewButton from '../../elements/PreviewButton';
@@ -18,8 +18,6 @@ import Loading from '../../elements/Loading';
import './index.scss'; import './index.scss';
const { serverURL, routes: { api, admin } } = config;
const baseClass = 'account'; const baseClass = 'account';
const DefaultAccount = (props) => { const DefaultAccount = (props) => {
@@ -44,6 +42,8 @@ const DefaultAccount = (props) => {
auth, auth,
} = collection; } = collection;
const { serverURL, routes: { api, admin } } = useConfig();
const classes = [ const classes = [
baseClass, baseClass,
].filter(Boolean).join(' '); ].filter(Boolean).join(' ');
@@ -84,7 +84,6 @@ const DefaultAccount = (props) => {
filter={(field) => (!field.position || field?.admin?.position !== 'sidebar')} filter={(field) => (!field.position || field?.admin?.position !== 'sidebar')}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</React.Fragment> </React.Fragment>
)} )}
@@ -127,7 +126,6 @@ const DefaultAccount = (props) => {
position="sidebar" position="sidebar"
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</div> </div>
<ul className={`${baseClass}__meta`}> <ul className={`${baseClass}__meta`}>

View File

@@ -1,21 +1,29 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import config from 'payload/config';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useConfig } from '../../providers/Config';
import { useStepNav } from '../../elements/StepNav'; import { useStepNav } from '../../elements/StepNav';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import usePayloadAPI from '../../../hooks/usePayloadAPI'; import usePayloadAPI from '../../../hooks/usePayloadAPI';
import DefaultAccount from './Default'; import DefaultAccount from './Default';
import buildStateFromSchema from '../../forms/Form/buildStateFromSchema'; import buildStateFromSchema from '../../forms/Form/buildStateFromSchema';
import RenderCustomComponent from '../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../utilities/RenderCustomComponent';
const { serverURL, routes: { api }, collections } = config;
const AccountView = () => { const AccountView = () => {
const { state: locationState } = useLocation(); const { state: locationState } = useLocation();
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();
const { user, permissions } = useUser(); const { user, permissions } = useAuthentication();
const [initialState, setInitialState] = useState({}); const [initialState, setInitialState] = useState({});
const {
serverURL,
routes: { api },
collections,
admin: {
components: {
account: CustomAccount,
} = {},
} = {},
} = useConfig();
const collection = collections.find((coll) => coll.slug === user.collection); const collection = collections.find((coll) => coll.slug === user.collection);
@@ -52,7 +60,7 @@ const AccountView = () => {
return ( return (
<RenderCustomComponent <RenderCustomComponent
DefaultComponent={DefaultAccount} DefaultComponent={DefaultAccount}
path="account" CustomComponent={CustomAccount}
componentProps={{ componentProps={{
data, data,
collection, collection,

View File

@@ -1,27 +1,26 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import Form from '../../forms/Form'; import Form from '../../forms/Form';
import RenderFields from '../../forms/RenderFields'; import RenderFields from '../../forms/RenderFields';
import fieldTypes from '../../forms/field-types'; import fieldTypes from '../../forms/field-types';
import FormSubmit from '../../forms/Submit'; import FormSubmit from '../../forms/Submit';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import './index.scss'; import './index.scss';
const {
admin: { user: userSlug }, collections, serverURL, routes: { admin, api },
} = config;
const userConfig = collections.find((collection) => collection.slug === userSlug);
const baseClass = 'create-first-user'; const baseClass = 'create-first-user';
const CreateFirstUser = (props) => { const CreateFirstUser = (props) => {
const { setInitialized } = props; const { setInitialized } = props;
const { setToken } = useUser(); const { setToken } = useAuthentication();
const {
admin: { user: userSlug }, collections, serverURL, routes: { admin, api },
} = useConfig();
const userConfig = collections.find((collection) => collection.slug === userSlug);
const onSuccess = (json) => { const onSuccess = (json) => {
if (json?.user?.token) { if (json?.user?.token) {

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Eyebrow from '../../elements/Eyebrow'; import Eyebrow from '../../elements/Eyebrow';
import Card from '../../elements/Card'; import Card from '../../elements/Card';
@@ -9,12 +9,6 @@ import Button from '../../elements/Button';
import './index.scss'; import './index.scss';
const {
routes: {
admin,
},
} = config;
const baseClass = 'dashboard'; const baseClass = 'dashboard';
const Dashboard = (props) => { const Dashboard = (props) => {
@@ -26,6 +20,12 @@ const Dashboard = (props) => {
const { push } = useHistory(); const { push } = useHistory();
const {
routes: {
admin,
},
} = useConfig();
return ( return (
<div className={baseClass}> <div className={baseClass}>
<Eyebrow /> <Eyebrow />

View File

@@ -1,25 +1,30 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import { useStepNav } from '../../elements/StepNav'; import { useStepNav } from '../../elements/StepNav';
import RenderCustomComponent from '../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import DefaultDashboard from './Default'; import DefaultDashboard from './Default';
const {
collections,
globals,
} = config;
const Dashboard = () => { const Dashboard = () => {
const { permissions } = useUser(); const { permissions } = useAuthentication();
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();
const [filteredGlobals, setFilteredGlobals] = useState([]); const [filteredGlobals, setFilteredGlobals] = useState([]);
const {
collections,
globals,
admin: {
components: {
dashboard: CustomDashboard,
} = {},
} = {},
} = useConfig();
useEffect(() => { useEffect(() => {
setFilteredGlobals( setFilteredGlobals(
globals.filter((global) => permissions?.[global.slug]?.read?.permission), globals.filter((global) => permissions?.[global.slug]?.read?.permission),
); );
}, [permissions]); }, [permissions, globals]);
useEffect(() => { useEffect(() => {
setStepNav([]); setStepNav([]);
@@ -28,7 +33,7 @@ const Dashboard = () => {
return ( return (
<RenderCustomComponent <RenderCustomComponent
DefaultComponent={DefaultDashboard} DefaultComponent={DefaultDashboard}
path="views.List" CustomComponent={CustomDashboard}
componentProps={{ componentProps={{
globals: filteredGlobals, globals: filteredGlobals,
collections: collections.filter((collection) => permissions?.[collection.slug]?.read?.permission), collections: collections.filter((collection) => permissions?.[collection.slug]?.read?.permission),

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import StatusList, { useStatusList } from '../../elements/Status'; import StatusList, { useStatusList } from '../../elements/Status';
import Form from '../../forms/Form'; import Form from '../../forms/Form';
@@ -8,25 +8,24 @@ import Email from '../../forms/field-types/Email';
import FormSubmit from '../../forms/Submit'; import FormSubmit from '../../forms/Submit';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import './index.scss'; import './index.scss';
const baseClass = 'forgot-password'; const baseClass = 'forgot-password';
const { const ForgotPassword = () => {
const { addStatus } = useStatusList();
const [hasSubmitted, setHasSubmitted] = useState(false);
const { user } = useAuthentication();
const {
admin: { user: userSlug }, admin: { user: userSlug },
serverURL, serverURL,
routes: { routes: {
admin, admin,
api, api,
}, },
} = config; } = useConfig();
const ForgotPassword = () => {
const { addStatus } = useStatusList();
const [hasSubmitted, setHasSubmitted] = useState(false);
const { user } = useUser();
const handleResponse = (res) => { const handleResponse = (res) => {
res.json() res.json()

View File

@@ -62,7 +62,6 @@ const DefaultGlobalView = (props) => {
filter={(field) => (!field.position || (field.position && field.position !== 'sidebar'))} filter={(field) => (!field.position || (field.position && field.position !== 'sidebar'))}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</div> </div>
</div> </div>
@@ -98,7 +97,6 @@ const DefaultGlobalView = (props) => {
position="sidebar" position="sidebar"
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</div> </div>
{data && ( {data && (

View File

@@ -1,32 +1,45 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useStepNav } from '../../elements/StepNav'; import { useStepNav } from '../../elements/StepNav';
import usePayloadAPI from '../../../hooks/usePayloadAPI'; import usePayloadAPI from '../../../hooks/usePayloadAPI';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import { useLocale } from '../../utilities/Locale'; import { useLocale } from '../../utilities/Locale';
import RenderCustomComponent from '../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import DefaultGlobal from './Default'; import DefaultGlobal from './Default';
import buildStateFromSchema from '../../forms/Form/buildStateFromSchema'; import buildStateFromSchema from '../../forms/Form/buildStateFromSchema';
const { serverURL, routes: { admin, api } } = config;
const GlobalView = (props) => { const GlobalView = (props) => {
const { state: locationState } = useLocation(); const { state: locationState } = useLocation();
const history = useHistory(); const history = useHistory();
const locale = useLocale(); const locale = useLocale();
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();
const { permissions } = useUser(); const { permissions } = useAuthentication();
const [initialState, setInitialState] = useState({}); const [initialState, setInitialState] = useState({});
const {
serverURL,
routes: {
admin,
api,
},
} = useConfig();
const { global } = props; const { global } = props;
const { const {
slug, slug,
label, label,
fields, fields,
admin: {
components: {
views: {
edit: CustomEdit,
} = {},
} = {},
} = {},
} = global; } = global;
const onSave = (json) => { const onSave = (json) => {
@@ -68,7 +81,7 @@ const GlobalView = (props) => {
return ( return (
<RenderCustomComponent <RenderCustomComponent
DefaultComponent={DefaultGlobal} DefaultComponent={DefaultGlobal}
path={`${slug}.views.Edit`} CustomComponent={CustomEdit}
componentProps={{ componentProps={{
data: dataToRender, data: dataToRender,
permissions: globalPermissions, permissions: globalPermissions,

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Logo from '../../graphics/Logo'; import Logo from '../../graphics/Logo';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import Form from '../../forms/Form'; import Form from '../../forms/Form';
@@ -9,17 +9,16 @@ import Password from '../../forms/field-types/Password';
import FormSubmit from '../../forms/Submit'; import FormSubmit from '../../forms/Submit';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import './index.scss'; import './index.scss';
const baseClass = 'login'; const baseClass = 'login';
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = config;
const Login = () => { const Login = () => {
const history = useHistory(); const history = useHistory();
const { user, setToken } = useUser(); const { user, setToken } = useAuthentication();
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = useConfig();
const onSuccess = (data) => { const onSuccess = (data) => {
if (data.token) { if (data.token) {

View File

@@ -1,21 +1,20 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import Minimal from '../../templates/Minimal'; import Minimal from '../../templates/Minimal';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import './index.scss'; import './index.scss';
const { routes: { admin } } = config;
const baseClass = 'logout'; const baseClass = 'logout';
const Logout = (props) => { const Logout = (props) => {
const { inactivity } = props; const { inactivity } = props;
const { logOut } = useUser(); const { logOut } = useAuthentication();
const { routes: { admin } } = useConfig();
useEffect(() => { useEffect(() => {
logOut(); logOut();

View File

@@ -1,14 +1,13 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Eyebrow from '../../elements/Eyebrow'; import Eyebrow from '../../elements/Eyebrow';
import { useStepNav } from '../../elements/StepNav'; import { useStepNav } from '../../elements/StepNav';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
const { routes: { admin } } = config;
const NotFound = () => { const NotFound = () => {
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();
const { routes: { admin } } = useConfig;
useEffect(() => { useEffect(() => {
setStepNav([{ setStepNav([{

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Link, useHistory, useParams } from 'react-router-dom'; import { Link, useHistory, useParams } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
import Form from '../../forms/Form'; import Form from '../../forms/Form';
import Password from '../../forms/field-types/Password'; import Password from '../../forms/field-types/Password';
@@ -8,19 +8,18 @@ import ConfirmPassword from '../../forms/field-types/ConfirmPassword';
import FormSubmit from '../../forms/Submit'; import FormSubmit from '../../forms/Submit';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import { useUser } from '../../data/User'; import { useAuthentication } from '../../providers/Authentication';
import './index.scss'; import './index.scss';
import HiddenInput from '../../forms/field-types/HiddenInput'; import HiddenInput from '../../forms/field-types/HiddenInput';
const baseClass = 'reset-password'; const baseClass = 'reset-password';
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = config;
const ResetPassword = () => { const ResetPassword = () => {
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = useConfig();
const { token } = useParams(); const { token } = useParams();
const history = useHistory(); const history = useHistory();
const { user, setToken } = useUser(); const { user, setToken } = useAuthentication();
const onSuccess = (data) => { const onSuccess = (data) => {
if (data.token) { if (data.token) {

View File

@@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import config from 'payload/config'; import { useConfig } from '../../providers/Config';
import Button from '../../elements/Button'; import Button from '../../elements/Button';
import Meta from '../../utilities/Meta'; import Meta from '../../utilities/Meta';
import MinimalTemplate from '../../templates/Minimal'; import MinimalTemplate from '../../templates/Minimal';
const { routes: { admin } } = config; const Unauthorized = () => {
const { routes: { admin } } = useConfig();
const Unauthorized = () => ( return (
<MinimalTemplate className="unauthorized"> <MinimalTemplate className="unauthorized">
<Meta <Meta
title="Unauthorized" title="Unauthorized"
@@ -22,5 +23,7 @@ const Unauthorized = () => (
Log out Log out
</Button> </Button>
</MinimalTemplate> </MinimalTemplate>
); );
};
export default Unauthorized; export default Unauthorized;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link, useRouteMatch } from 'react-router-dom'; import { Link, useRouteMatch } from 'react-router-dom';
import format from 'date-fns/format'; import format from 'date-fns/format';
import config from 'payload/config'; import { useConfig } from '../../../providers/Config';
import Eyebrow from '../../../elements/Eyebrow'; import Eyebrow from '../../../elements/Eyebrow';
import Form from '../../../forms/Form'; import Form from '../../../forms/Form';
import Loading from '../../../elements/Loading'; import Loading from '../../../elements/Loading';
@@ -21,12 +21,11 @@ import Upload from './Upload';
import './index.scss'; import './index.scss';
const { routes: { admin } } = config;
const baseClass = 'collection-edit'; const baseClass = 'collection-edit';
const DefaultEditView = (props) => { const DefaultEditView = (props) => {
const { params: { id } = {} } = useRouteMatch(); const { params: { id } = {} } = useRouteMatch();
const { routes: { admin } } = useConfig();
const { const {
collection, collection,
@@ -108,7 +107,6 @@ const DefaultEditView = (props) => {
filter={(field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'))} filter={(field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'))}
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</React.Fragment> </React.Fragment>
)} )}
@@ -171,7 +169,6 @@ const DefaultEditView = (props) => {
position="sidebar" position="sidebar"
fieldTypes={fieldTypes} fieldTypes={fieldTypes}
fieldSchema={fields} fieldSchema={fields}
customComponentsPath={`${slug}.fields.`}
/> />
</div> </div>
{isEditing && ( {isEditing && (

View File

@@ -1,17 +1,15 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Redirect, useRouteMatch, useHistory, useLocation } from 'react-router-dom'; import { Redirect, useRouteMatch, useHistory, useLocation } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../../providers/Config';
import { useStepNav } from '../../../elements/StepNav'; import { useStepNav } from '../../../elements/StepNav';
import usePayloadAPI from '../../../../hooks/usePayloadAPI'; import usePayloadAPI from '../../../../hooks/usePayloadAPI';
import { useUser } from '../../../data/User'; import { useAuthentication } from '../../../providers/Authentication';
import RenderCustomComponent from '../../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
import DefaultEdit from './Default'; import DefaultEdit from './Default';
import buildStateFromSchema from '../../../forms/Form/buildStateFromSchema'; import buildStateFromSchema from '../../../forms/Form/buildStateFromSchema';
const { serverURL, routes: { admin, api } } = config;
const EditView = (props) => { const EditView = (props) => {
const { collection, isEditing } = props; const { collection, isEditing } = props;
@@ -22,16 +20,22 @@ const EditView = (props) => {
}, },
admin: { admin: {
useAsTitle, useAsTitle,
components: {
views: {
edit: CustomEdit,
} = {},
} = {},
}, },
fields, fields,
} = collection; } = collection;
const { serverURL, routes: { admin, api } } = useConfig();
const { params: { id } = {} } = useRouteMatch(); const { params: { id } = {} } = useRouteMatch();
const { state: locationState } = useLocation(); const { state: locationState } = useLocation();
const history = useHistory(); const history = useHistory();
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();
const [initialState, setInitialState] = useState({}); const [initialState, setInitialState] = useState({});
const { permissions } = useUser(); const { permissions } = useAuthentication();
const onSave = (json) => { const onSave = (json) => {
history.push(`${admin}/collections/${collection.slug}/${json?.doc?.id}`, { history.push(`${admin}/collections/${collection.slug}/${json?.doc?.id}`, {
@@ -95,7 +99,7 @@ const EditView = (props) => {
return ( return (
<RenderCustomComponent <RenderCustomComponent
DefaultComponent={DefaultEdit} DefaultComponent={DefaultEdit}
path={`${slug}.views.Edit`} CustomComponent={CustomEdit}
componentProps={{ componentProps={{
isLoading, isLoading,
data: dataToRender, data: dataToRender,

View File

@@ -1,13 +1,11 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config'; import { useConfig } from '../../../../../providers/Config';
const { collections } = config;
const RelationshipCell = (props) => { const RelationshipCell = (props) => {
const { field, cellData } = props; const { field, cellData } = props;
const { relationTo } = field; const { relationTo } = field;
const { collections } = useConfig();
const [data, setData] = useState(); const [data, setData] = useState();
useEffect(() => { useEffect(() => {

View File

@@ -2,13 +2,11 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import format from 'date-fns/format'; import format from 'date-fns/format';
import config from 'payload/config'; import { useConfig } from '../../../../providers/Config';
import RenderCustomComponent from '../../../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../../../utilities/RenderCustomComponent';
import Thumbnail from '../../../../elements/Thumbnail'; import Thumbnail from '../../../../elements/Thumbnail';
import Relationship from './Relationship'; import Relationship from './Relationship';
const { routes: { admin } } = config;
const DefaultCell = (props) => { const DefaultCell = (props) => {
const { const {
field, field,
@@ -29,6 +27,8 @@ const DefaultCell = (props) => {
} = {}, } = {},
} = props; } = props;
const { routes: { admin } } = useConfig();
let WrapElement = 'span'; let WrapElement = 'span';
const wrapElementProps = {}; const wrapElementProps = {};
@@ -89,14 +89,15 @@ const Cell = (props) => {
const { const {
colIndex, colIndex,
collection, collection,
collection: {
slug,
},
cellData, cellData,
rowData, rowData,
field, field,
field: { field: {
name, admin: {
components: {
cell: CustomCell,
} = {},
} = {},
}, },
} = props; } = props;
@@ -109,7 +110,7 @@ const Cell = (props) => {
collection, collection,
field, field,
}} }}
path={`${slug}.fields.${name}.cell`} CustomComponent={CustomCell}
DefaultComponent={DefaultCell} DefaultComponent={DefaultCell}
/> />
); );
@@ -141,6 +142,11 @@ const propTypes = {
field: PropTypes.shape({ field: PropTypes.shape({
name: PropTypes.string, name: PropTypes.string,
type: PropTypes.string, type: PropTypes.string,
admin: PropTypes.shape({
components: PropTypes.shape({
cell: PropTypes.func,
}),
}),
}).isRequired, }).isRequired,
}; };

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import config from 'payload/config'; import { useConfig } from '../../../providers/Config';
import UploadGallery from '../../../elements/UploadGallery'; import UploadGallery from '../../../elements/UploadGallery';
import Eyebrow from '../../../elements/Eyebrow'; import Eyebrow from '../../../elements/Eyebrow';
import Paginator from '../../../elements/Paginator'; import Paginator from '../../../elements/Paginator';
@@ -13,8 +13,6 @@ import Meta from '../../../utilities/Meta';
import './index.scss'; import './index.scss';
const { routes: { admin } } = config;
const baseClass = 'collection-list'; const baseClass = 'collection-list';
const DefaultList = (props) => { const DefaultList = (props) => {
@@ -35,6 +33,7 @@ const DefaultList = (props) => {
hasCreatePermission, hasCreatePermission,
} = props; } = props;
const { routes: { admin } } = useConfig();
const history = useHistory(); const history = useHistory();
return ( return (

View File

@@ -2,8 +2,8 @@ import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import queryString from 'qs'; import queryString from 'qs';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import config from 'payload/config'; import { useConfig } from '../../../providers/Config';
import { useUser } from '../../../data/User'; import { useAuthentication } from '../../../providers/Authentication';
import usePayloadAPI from '../../../../hooks/usePayloadAPI'; import usePayloadAPI from '../../../../hooks/usePayloadAPI';
import DefaultList from './Default'; import DefaultList from './Default';
import RenderCustomComponent from '../../../utilities/RenderCustomComponent'; import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
@@ -11,8 +11,6 @@ import { useStepNav } from '../../../elements/StepNav';
import formatFields from './formatFields'; import formatFields from './formatFields';
import buildColumns from './buildColumns'; import buildColumns from './buildColumns';
const { serverURL, routes: { api, admin } } = config;
const ListView = (props) => { const ListView = (props) => {
const { const {
collection, collection,
@@ -24,7 +22,8 @@ const ListView = (props) => {
}, },
} = props; } = props;
const { permissions } = useUser(); const { serverURL, routes: { api, admin } } = useConfig();
const { permissions } = useAuthentication();
const location = useLocation(); const location = useLocation();
const { setStepNav } = useStepNav(); const { setStepNav } = useStepNav();

View File

@@ -1,6 +0,0 @@
import config from 'payload/unsanitizedConfig';
import sanitizeConfig from '../utilities/sanitizeConfig';
const sanitizedConfig = sanitizeConfig(config);
export default sanitizedConfig;

View File

@@ -1,7 +1,42 @@
const findConfig = require('./findConfig');
/* eslint-disable import/no-dynamic-require */ /* eslint-disable import/no-dynamic-require */
/* eslint-disable global-require */ /* eslint-disable global-require */
const findConfig = require('./findConfig');
const configPath = findConfig();
require('ignore-styles');
require('@babel/register')({
presets: [
[
'@babel/preset-env',
{
targets: [
'defaults',
'not IE 11',
'not IE_Mob 11',
'maintained node versions',
],
},
],
'@babel/preset-react',
],
plugins: [
['module-resolver', {
alias: {
'payload/unsanitizedConfig': configPath,
'@payloadcms/payload$': '../',
},
}],
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-optional-chaining',
'add-module-exports',
],
ignore: [
'*.scss',
'*.css',
'node_modules',
],
});
const getConfig = (options = {}) => { const getConfig = (options = {}) => {
if (!options.secret) { if (!options.secret) {
@@ -12,7 +47,6 @@ const getConfig = (options = {}) => {
throw new Error('Error: missing MongoDB connection URL.'); throw new Error('Error: missing MongoDB connection URL.');
} }
const configPath = findConfig();
const publicConfig = require(configPath); const publicConfig = require(configPath);
const email = { ...(publicConfig.email || {}), ...(options.email || {}) }; const email = { ...(publicConfig.email || {}), ...(options.email || {}) };

View File

@@ -24,15 +24,6 @@ module.exports = (config) => {
resolveLoader: { modules: ['node_modules', path.join(__dirname, '../../node_modules')] }, resolveLoader: { modules: ['node_modules', path.join(__dirname, '../../node_modules')] },
module: { module: {
rules: [ rules: [
{
test: require.resolve('../client/components/customComponents'),
use: [
{
loader: 'val-loader',
options: config,
},
],
},
{ {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules\/(?!(@payloadcms\/payload)\/).*/, exclude: /node_modules\/(?!(@payloadcms\/payload)\/).*/,
@@ -47,15 +38,15 @@ module.exports = (config) => {
'defaults', 'defaults',
'not IE 11', 'not IE 11',
'not IE_Mob 11', 'not IE_Mob 11',
'maintained node versions',
], ],
}, },
], ],
require.resolve('@babel/preset-react'), require.resolve('@babel/preset-react'),
], ],
plugins: [ plugins: [
require.resolve('@babel/plugin-proposal-class-properties'), 'add-module-exports',
require.resolve('@babel/plugin-proposal-optional-chaining'), '@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-optional-chaining',
], ],
}, },
}, },
@@ -115,7 +106,6 @@ module.exports = (config) => {
modules: ['node_modules', path.resolve(__dirname, '../../node_modules')], modules: ['node_modules', path.resolve(__dirname, '../../node_modules')],
alias: { alias: {
'payload/unsanitizedConfig': config.paths.config, 'payload/unsanitizedConfig': config.paths.config,
'payload/config': path.resolve(__dirname, '../client/config.js'),
'@payloadcms/payload$': mockModulePath, '@payloadcms/payload$': mockModulePath,
}, },
}, },

View File

@@ -50,6 +50,7 @@ module.exports = (config) => {
require.resolve('@babel/preset-react'), require.resolve('@babel/preset-react'),
], ],
plugins: [ plugins: [
'add-module-exports',
require.resolve('@babel/plugin-proposal-optional-chaining'), require.resolve('@babel/plugin-proposal-optional-chaining'),
require.resolve('@babel/plugin-proposal-class-properties'), require.resolve('@babel/plugin-proposal-class-properties'),
], ],

View File

@@ -18,7 +18,7 @@
invariant "^2.2.4" invariant "^2.2.4"
semver "^5.5.0" semver "^5.5.0"
"@babel/core@^7.1.0", "@babel/core@^7.7.5": "@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.7.5":
version "7.11.6" version "7.11.6"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651"
integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==
@@ -889,6 +889,17 @@
"@babel/plugin-transform-react-jsx-source" "^7.10.4" "@babel/plugin-transform-react-jsx-source" "^7.10.4"
"@babel/plugin-transform-react-pure-annotations" "^7.10.4" "@babel/plugin-transform-react-pure-annotations" "^7.10.4"
"@babel/register@^7.11.5":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea"
integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w==
dependencies:
find-cache-dir "^2.0.0"
lodash "^4.17.19"
make-dir "^2.1.0"
pirates "^4.0.0"
source-map-support "^0.5.16"
"@babel/runtime-corejs3@^7.10.2": "@babel/runtime-corejs3@^7.10.2":
version "7.11.2" version "7.11.2"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz#02c3029743150188edeb66541195f54600278419" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz#02c3029743150188edeb66541195f54600278419"
@@ -2134,11 +2145,6 @@ babel-code-frame@^6.26.0:
esutils "^2.0.2" esutils "^2.0.2"
js-tokens "^3.0.2" js-tokens "^3.0.2"
babel-core@^7.0.0-bridge.0:
version "7.0.0-bridge.0"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
babel-eslint@^10.0.1: babel-eslint@^10.0.1:
version "10.1.0" version "10.1.0"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232"
@@ -2176,6 +2182,11 @@ babel-loader@^8.0.6:
pify "^4.0.1" pify "^4.0.1"
schema-utils "^2.6.5" schema-utils "^2.6.5"
babel-plugin-add-module-exports@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz#6caa4ddbe1f578c6a5264d4d3e6c8a2720a7ca2b"
integrity sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==
babel-plugin-dynamic-import-node@^2.3.3: babel-plugin-dynamic-import-node@^2.3.3:
version "2.3.3" version "2.3.3"
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3"
@@ -2228,6 +2239,17 @@ babel-plugin-macros@^2.0.0:
cosmiconfig "^6.0.0" cosmiconfig "^6.0.0"
resolve "^1.12.0" resolve "^1.12.0"
babel-plugin-module-resolver@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz#8f3a3d9d48287dc1d3b0d5595113adabd36a847f"
integrity sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==
dependencies:
find-babel-config "^1.2.0"
glob "^7.1.6"
pkg-up "^3.1.0"
reselect "^4.0.0"
resolve "^1.13.1"
babel-plugin-syntax-jsx@^6.18.0: babel-plugin-syntax-jsx@^6.18.0:
version "6.18.0" version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
@@ -4745,7 +4767,15 @@ finalhandler@~1.1.2:
statuses "~1.5.0" statuses "~1.5.0"
unpipe "~1.0.0" unpipe "~1.0.0"
find-cache-dir@^2.1.0: find-babel-config@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2"
integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==
dependencies:
json5 "^0.5.1"
path-exists "^3.0.0"
find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
@@ -5530,6 +5560,11 @@ ignore-by-default@^1.0.1:
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
ignore-styles@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ignore-styles/-/ignore-styles-5.0.1.tgz#b49ef2274bdafcd8a4880a966bfe38d1a0bf4671"
integrity sha1-tJ7yJ0va/NikiAqWa/440aC/RnE=
ignore@^4.0.6: ignore@^4.0.6:
version "4.0.6" version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
@@ -6640,7 +6675,7 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^0.5.0: json5@^0.5.0, json5@^0.5.1:
version "0.5.1" version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
@@ -7033,7 +7068,7 @@ make-dir@^1.0.0:
dependencies: dependencies:
pify "^3.0.0" pify "^3.0.0"
make-dir@^2.0.0: make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
@@ -8371,7 +8406,7 @@ pino@^6.4.1:
quick-format-unescaped "^4.0.1" quick-format-unescaped "^4.0.1"
sonic-boom "^1.0.2" sonic-boom "^1.0.2"
pirates@^4.0.1: pirates@^4.0.0, pirates@^4.0.1:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==
@@ -8399,6 +8434,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
dependencies: dependencies:
find-up "^4.0.0" find-up "^4.0.0"
pkg-up@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
dependencies:
find-up "^3.0.0"
pn@^1.1.0: pn@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@@ -9865,6 +9907,11 @@ requireindex@^1.2.0:
resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef"
integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==
reselect@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
resize-observer-polyfill@^1.5.1: resize-observer-polyfill@^1.5.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
@@ -10495,7 +10542,7 @@ source-map-resolve@^0.5.0:
source-map-url "^0.4.0" source-map-url "^0.4.0"
urix "^0.1.0" urix "^0.1.0"
source-map-support@^0.5.6, source-map-support@~0.5.12: source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12:
version "0.5.19" version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@@ -11697,7 +11744,7 @@ v8-to-istanbul@^4.1.3:
convert-source-map "^1.6.0" convert-source-map "^1.6.0"
source-map "^0.7.3" source-map "^0.7.3"
val-loader@^2.1.0: val-loader@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-2.1.1.tgz#6d9a51e5f4d7604683fab1a739acd4c9540e1ef4" resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-2.1.1.tgz#6d9a51e5f4d7604683fab1a739acd4c9540e1ef4"
integrity sha512-0JKslgCSncZEGFuXAZp+caZMi15gjSC+WRUhrG0B6wPzLT7c0KfUzaOJHPYS49TrCbfUstXNQsw60FLUFqwmPw== integrity sha512-0JKslgCSncZEGFuXAZp+caZMi15gjSC+WRUhrG0B6wPzLT7c0KfUzaOJHPYS49TrCbfUstXNQsw60FLUFqwmPw==