diff --git a/.editorconfig b/.editorconfig
index 4fb74f2b88..d4e6ee36ed 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -4,7 +4,7 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
-[*.js]
+[*.{js,ts}]
indent_style = space
indent_size = 2
diff --git a/.eslintrc.js b/.eslintrc.js
index 3a0aefe583..8cd8e7c0ce 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,15 +1,18 @@
module.exports = {
- parser: "babel-eslint",
- extends: "@trbl",
+ parser: 'babel-eslint',
+ extends: '@trbl',
+ ignorePatterns: [
+ '/**/*.d.ts'
+ ],
rules: {
- "import/no-unresolved": [
+ 'import/no-unresolved': [
2,
{
ignore: [
'payload/config',
'payload/unsanitizedConfig',
- ]
- }
+ ],
+ },
],
'no-underscore-dangle': 'off',
},
diff --git a/demo/payload.config.js b/demo/payload.config.js
index 0db7c9c9f4..4e81e04cd6 100644
--- a/demo/payload.config.js
+++ b/demo/payload.config.js
@@ -43,6 +43,7 @@ module.exports = {
},
},
email: {
+ transport: 'mock',
fromName: 'Payload',
fromAddress: 'hello@payloadcms.com',
},
diff --git a/demo/server.js b/demo/server.js
index 13ff99eda4..9781723d56 100644
--- a/demo/server.js
+++ b/demo/server.js
@@ -9,9 +9,6 @@ const expressApp = express();
expressApp.use('/static', express.static(path.resolve(__dirname, 'client/static')));
payload.init({
- email: {
- transport: 'mock',
- },
secret: 'SECRET_KEY',
mongoURL: 'mongodb://localhost/payload',
express: expressApp,
@@ -39,11 +36,6 @@ exports.start = (cb) => {
const server = expressApp.listen(3000, async () => {
logger.info(`listening on ${3000}...`);
- const creds = await payload.getMockEmailCredentials();
- logger.info(`Mock email account username: ${creds.user}`);
- logger.info(`Mock email account password: ${creds.pass}`);
- logger.info(`Log in to mock email provider at ${creds.web}`);
-
if (cb) cb();
});
diff --git a/errors.js b/errors.js
index da53a253f3..7a06ef8053 100644
--- a/errors.js
+++ b/errors.js
@@ -1,5 +1,6 @@
-const { APIError } = require('./src/errors');
+const { APIError, Forbidden } = require('./src/errors');
module.exports = {
APIError,
+ Forbidden,
};
diff --git a/package.json b/package.json
index 170122d7d0..c7af9d8b42 100644
--- a/package.json
+++ b/package.json
@@ -113,6 +113,7 @@
"react-router-navigation-prompt": "^1.8.11",
"react-select": "^3.0.8",
"react-simple-code-editor": "^0.11.0",
+ "react-toastify": "^6.1.0",
"sanitize-filename": "^1.6.3",
"sass": "^1.27.0",
"sass-loader": "7.1.0",
diff --git a/payload.d.ts b/payload.d.ts
index c937b0ef2c..85ec54d9aa 100644
--- a/payload.d.ts
+++ b/payload.d.ts
@@ -130,7 +130,6 @@ declare module "@payloadcms/payload/types" {
admin?: {
useAsTitle?: string;
defaultColumns?: string[];
- disableScrollOnSuccess?: boolean;
components?: any;
},
hooks?: {
@@ -215,3 +214,13 @@ declare module "@payloadcms/payload/types" {
webpack?: (config: any) => any;
}
}
+
+declare module "@payloadcms/payload/src/utilities/sanitizeConfig" {
+ import { PayloadConfig } from '@payloadcms/payload/types';
+
+ export type SanitizeConfig = (config: PayloadConfig) => PayloadConfig;
+
+ const sanitizeConfig: SanitizeConfig;
+
+ export default sanitizeConfig;
+}
diff --git a/src/admin/components/elements/DeleteDocument/index.js b/src/admin/components/elements/DeleteDocument/index.js
index 8016e6290f..3fd192b7ae 100644
--- a/src/admin/components/elements/DeleteDocument/index.js
+++ b/src/admin/components/elements/DeleteDocument/index.js
@@ -1,5 +1,6 @@
import React, { useState, useCallback } from 'react';
import PropTypes from 'prop-types';
+import { toast } from 'react-toastify';
import { useHistory } from 'react-router-dom';
import { Modal, useModal } from '@faceless-ui/modal';
import { useConfig } from '../../providers/Config';
@@ -8,7 +9,6 @@ import MinimalTemplate from '../../templates/Minimal';
import { useForm } from '../../forms/Form/context';
import useTitle from '../../../hooks/useTitle';
import { requests } from '../../../api';
-import { useStatusList } from '../Status';
import './index.scss';
@@ -30,7 +30,6 @@ const DeleteDocument = (props) => {
} = props;
const { serverURL, routes: { api, admin } } = useConfig();
- const { replaceStatus } = useStatusList();
const { setModified } = useForm();
const [deleting, setDeleting] = useState(false);
const { closeAll, toggle } = useModal();
@@ -41,11 +40,8 @@ const DeleteDocument = (props) => {
const modalSlug = `delete-${id}`;
const addDefaultError = useCallback(() => {
- replaceStatus([{
- message: `There was an error while deleting ${title}. Please check your connection and try again.`,
- type: 'error',
- }]);
- }, [replaceStatus, title]);
+ toast.error(`There was an error while deleting ${title}. Please check your connection and try again.`);
+ }, [title]);
const handleDelete = useCallback(() => {
setDeleting(true);
@@ -72,7 +68,7 @@ const DeleteDocument = (props) => {
closeAll();
if (json.errors) {
- replaceStatus(json.errors);
+ toast.error(json.errors);
}
addDefaultError();
return false;
@@ -80,7 +76,7 @@ const DeleteDocument = (props) => {
return addDefaultError();
}
});
- }, [addDefaultError, closeAll, history, id, replaceStatus, singular, slug, title, admin, api, serverURL, setModified]);
+ }, [addDefaultError, closeAll, history, id, singular, slug, title, admin, api, serverURL, setModified]);
if (id) {
return (
diff --git a/src/admin/components/elements/GenerateConfirmation/index.js b/src/admin/components/elements/GenerateConfirmation/index.js
index 9704d1c6b2..091da4f424 100644
--- a/src/admin/components/elements/GenerateConfirmation/index.js
+++ b/src/admin/components/elements/GenerateConfirmation/index.js
@@ -1,9 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
+import { toast } from 'react-toastify';
import { Modal, useModal } from '@faceless-ui/modal';
import Button from '../Button';
import MinimalTemplate from '../../templates/Minimal';
-import { useStatusList } from '../Status';
import './index.scss';
@@ -16,17 +16,13 @@ const GenerateConfirmation = (props) => {
} = props;
const { toggle } = useModal();
- const { replaceStatus } = useStatusList();
const modalSlug = 'generate-confirmation';
const handleGenerate = () => {
setKey();
toggle(modalSlug);
- replaceStatus([{
- message: 'New API Key Generated.',
- type: 'success',
- }]);
+ toast.success('New API Key Generated.', { autoClose: 3000 });
highlightField(true);
};
diff --git a/src/admin/components/elements/Status/index.js b/src/admin/components/elements/Status/index.js
deleted file mode 100644
index b15c7be7c0..0000000000
--- a/src/admin/components/elements/Status/index.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import React, {
- useReducer, createContext, useContext, useEffect, useCallback,
-} from 'react';
-import { useLocation } from 'react-router-dom';
-import PropTypes from 'prop-types';
-import X from '../../icons/X';
-import reducer from './reducer';
-import './index.scss';
-
-const baseClass = 'status-list';
-
-const Context = createContext({});
-
-const useStatusList = () => useContext(Context);
-
-const StatusListProvider = ({ children }) => {
- const [statusList, dispatchStatus] = useReducer(reducer, []);
- const { pathname, state } = useLocation();
-
- const removeStatus = useCallback((i) => dispatchStatus({ type: 'REMOVE', payload: i }), []);
- const addStatus = useCallback((status) => dispatchStatus({ type: 'ADD', payload: status }), []);
- const clearStatus = useCallback(() => dispatchStatus({ type: 'CLEAR' }), []);
- const replaceStatus = useCallback((status) => dispatchStatus({ type: 'REPLACE', payload: status }), []);
-
- useEffect(() => {
- if (state && state.status) {
- if (Array.isArray(state.status)) {
- replaceStatus(state.status);
- } else {
- replaceStatus([state.status]);
- }
- } else {
- clearStatus();
- }
- }, [addStatus, replaceStatus, clearStatus, state, pathname]);
-
- return (
-