payload 1.1.24 → 1.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/admin/components/Routes.js +4 -3
  2. package/dist/admin/components/elements/Logout/index.d.ts +3 -0
  3. package/dist/admin/components/elements/Logout/index.js +19 -0
  4. package/dist/admin/components/elements/Nav/index.js +3 -4
  5. package/dist/admin/components/elements/UploadGallery/index.js +1 -1
  6. package/dist/admin/components/forms/RenderFields/index.js +6 -5
  7. package/dist/admin/components/forms/RenderFields/types.d.ts +1 -0
  8. package/dist/admin/components/forms/field-types/Array/index.js +2 -2
  9. package/dist/admin/components/forms/field-types/Array/types.d.ts +1 -0
  10. package/dist/admin/components/forms/field-types/Blocks/index.js +2 -2
  11. package/dist/admin/components/forms/field-types/Blocks/types.d.ts +1 -0
  12. package/dist/admin/components/forms/field-types/Collapsible/index.js +2 -2
  13. package/dist/admin/components/forms/field-types/Collapsible/types.d.ts +1 -0
  14. package/dist/admin/components/forms/field-types/Group/index.js +2 -2
  15. package/dist/admin/components/forms/field-types/Group/types.d.ts +1 -0
  16. package/dist/admin/components/forms/field-types/Row/index.js +2 -2
  17. package/dist/admin/components/forms/field-types/Row/types.d.ts +1 -0
  18. package/dist/admin/components/forms/field-types/Tabs/index.js +55 -14
  19. package/dist/admin/components/forms/field-types/Tabs/types.d.ts +1 -0
  20. package/dist/admin/components/forms/field-types/Textarea/Input.js +4 -1
  21. package/dist/admin/components/forms/field-types/Textarea/index.scss +72 -3
  22. package/dist/admin/components/forms/useField/index.js +5 -1
  23. package/dist/admin/components/modals/StayLoggedIn/index.js +3 -2
  24. package/dist/admin/components/utilities/Auth/index.js +3 -3
  25. package/dist/admin/components/utilities/DocumentInfo/types.d.ts +2 -0
  26. package/dist/admin/components/views/Login/index.js +3 -2
  27. package/dist/admin/components/views/ResetPassword/index.js +3 -2
  28. package/dist/admin/components/views/Unauthorized/index.js +3 -2
  29. package/dist/config/defaults.js +3 -1
  30. package/dist/config/schema.js +6 -1
  31. package/dist/config/types.d.ts +5 -0
  32. package/dist/globals/operations/update.js +2 -3
  33. package/dist/preferences/types.d.ts +4 -0
  34. package/docs/admin/components.mdx +90 -81
  35. package/docs/admin/overview.mdx +14 -12
  36. package/docs/fields/ui.mdx +2 -2
  37. package/docs/getting-started/what-is-payload.mdx +1 -1
  38. package/docs/graphql/overview.mdx +1 -1
  39. package/package.json +1 -1
@@ -26,7 +26,8 @@ const Routes = () => {
26
26
  const [initialized, setInitialized] = useState(null);
27
27
  const { user, permissions, refreshCookie } = useAuth();
28
28
  const canAccessAdmin = permissions === null || permissions === void 0 ? void 0 : permissions.canAccessAdmin;
29
- const { admin: { user: userSlug, components: { routes: customRoutes, } = {}, }, routes, collections, globals, } = useConfig();
29
+ const config = useConfig();
30
+ const { admin: { user: userSlug, logoutRoute, inactivityRoute: logoutInactivityRoute, components: { routes: customRoutes, } = {}, }, routes, collections, globals, } = config;
30
31
  const userCollection = collections.find(({ slug }) => slug === userSlug);
31
32
  useEffect(() => {
32
33
  const { slug } = userCollection;
@@ -59,9 +60,9 @@ const Routes = () => {
59
60
  React.createElement(Component, { user: user, canAccessAdmin: canAccessAdmin })))),
60
61
  React.createElement(Route, { path: `${match.url}/login` },
61
62
  React.createElement(Login, null)),
62
- React.createElement(Route, { path: `${match.url}/logout` },
63
+ React.createElement(Route, { path: `${match.url}${logoutRoute}` },
63
64
  React.createElement(Logout, null)),
64
- React.createElement(Route, { path: `${match.url}/logout-inactivity` },
65
+ React.createElement(Route, { path: `${match.url}${logoutInactivityRoute}` },
65
66
  React.createElement(Logout, { inactivity: true })),
66
67
  !userCollection.auth.disableLocalStrategy && (React.createElement(Route, { path: `${match.url}/forgot` },
67
68
  React.createElement(ForgotPassword, null))),
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const Logout: React.FC;
3
+ export default Logout;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { Link } from 'react-router-dom';
3
+ import { useConfig } from '../../utilities/Config';
4
+ import RenderCustomComponent from '../../utilities/RenderCustomComponent';
5
+ import LogOut from '../../icons/LogOut';
6
+ const baseClass = 'nav';
7
+ const DefaultLogout = () => {
8
+ const config = useConfig();
9
+ const { routes: { admin }, admin: { logoutRoute, components: { logout } } } = config;
10
+ return (React.createElement(Link, { to: `${admin}${logoutRoute}`, className: `${baseClass}__log-out` },
11
+ React.createElement(LogOut, null)));
12
+ };
13
+ const Logout = () => {
14
+ const { admin: { components: { logout: { Button: CustomLogout } = {
15
+ Button: undefined,
16
+ }, } = {}, } = {}, } = useConfig();
17
+ return (React.createElement(RenderCustomComponent, { CustomComponent: CustomLogout, DefaultComponent: DefaultLogout }));
18
+ };
19
+ export default Logout;
@@ -4,7 +4,6 @@ import { useConfig } from '../../utilities/Config';
4
4
  import { useAuth } from '../../utilities/Auth';
5
5
  import RenderCustomComponent from '../../utilities/RenderCustomComponent';
6
6
  import Chevron from '../../icons/Chevron';
7
- import LogOut from '../../icons/LogOut';
8
7
  import Menu from '../../icons/Menu';
9
8
  import CloseMenu from '../../icons/CloseMenu';
10
9
  import Icon from '../../graphics/Icon';
@@ -13,13 +12,14 @@ import Localizer from '../Localizer';
13
12
  import NavGroup from '../NavGroup';
14
13
  import { groupNavItems, EntityType } from '../../../utilities/groupNavItems';
15
14
  import './index.scss';
15
+ import Logout from '../Logout';
16
16
  const baseClass = 'nav';
17
17
  const DefaultNav = () => {
18
18
  const { permissions } = useAuth();
19
19
  const [menuActive, setMenuActive] = useState(false);
20
20
  const [groups, setGroups] = useState([]);
21
21
  const history = useHistory();
22
- const { collections, globals, routes: { admin, }, admin: { components: { beforeNavLinks, afterNavLinks, }, }, } = useConfig();
22
+ const { collections, globals, routes: { admin, }, admin: { components: { beforeNavLinks, afterNavLinks }, }, } = useConfig();
23
23
  const classes = [
24
24
  baseClass,
25
25
  menuActive && `${baseClass}--menu-active`,
@@ -81,8 +81,7 @@ const DefaultNav = () => {
81
81
  React.createElement(Localizer, null),
82
82
  React.createElement(Link, { to: `${admin}/account`, className: `${baseClass}__account` },
83
83
  React.createElement(Account, null)),
84
- React.createElement(Link, { to: `${admin}/logout`, className: `${baseClass}__log-out` },
85
- React.createElement(LogOut, null)))))));
84
+ React.createElement(Logout, null))))));
86
85
  };
87
86
  const Nav = () => {
88
87
  const { admin: { components: { Nav: CustomNav, } = {
@@ -5,7 +5,7 @@ const baseClass = 'upload-gallery';
5
5
  const UploadGallery = (props) => {
6
6
  const { docs, onCardClick, collection } = props;
7
7
  if (docs && docs.length > 0) {
8
- return (React.createElement("ul", { className: baseClass }, docs.map((doc, i) => (React.createElement("li", { key: i },
8
+ return (React.createElement("ul", { className: baseClass }, docs.map((doc) => (React.createElement("li", { key: String(doc.id) },
9
9
  React.createElement(UploadCard, { doc: doc, ...{ collection }, onClick: () => onCardClick(doc) }))))));
10
10
  }
11
11
  return null;
@@ -9,7 +9,7 @@ const intersectionObserverOptions = {
9
9
  };
10
10
  const RenderFields = (props) => {
11
11
  var _a;
12
- const { fieldSchema, fieldTypes, filter, permissions, readOnly: readOnlyOverride, className, forceRender, } = props;
12
+ const { fieldSchema, fieldTypes, filter, permissions, readOnly: readOnlyOverride, className, forceRender, indexPath: incomingIndexPath } = props;
13
13
  const [hasRendered, setHasRendered] = useState(Boolean(forceRender));
14
14
  const [intersectionRef, entry] = useIntersect(intersectionObserverOptions);
15
15
  const operation = useOperation();
@@ -26,14 +26,14 @@ const RenderFields = (props) => {
26
26
  className,
27
27
  ].filter(Boolean).join(' ');
28
28
  if (fieldSchema) {
29
- return (React.createElement("div", { ref: intersectionRef, className: classes }, hasRendered && (fieldSchema.map((field, i) => {
29
+ return (React.createElement("div", { ref: intersectionRef, className: classes }, hasRendered && (fieldSchema.map((field, fieldIndex) => {
30
30
  var _a, _b, _c, _d, _e, _f, _g, _h;
31
31
  const fieldIsPresentational = fieldIsPresentationalOnly(field);
32
32
  let FieldComponent = fieldTypes[field.type];
33
33
  if (fieldIsPresentational || (!(field === null || field === void 0 ? void 0 : field.hidden) && ((_a = field === null || field === void 0 ? void 0 : field.admin) === null || _a === void 0 ? void 0 : _a.disabled) !== true)) {
34
34
  if ((filter && typeof filter === 'function' && filter(field)) || !filter) {
35
35
  if (fieldIsPresentational) {
36
- return (React.createElement(FieldComponent, { ...field, key: i }));
36
+ return (React.createElement(FieldComponent, { ...field, key: fieldIndex }));
37
37
  }
38
38
  if ((_b = field === null || field === void 0 ? void 0 : field.admin) === null || _b === void 0 ? void 0 : _b.hidden) {
39
39
  FieldComponent = fieldTypes.hidden;
@@ -48,10 +48,11 @@ const RenderFields = (props) => {
48
48
  readOnly = true;
49
49
  }
50
50
  if (FieldComponent) {
51
- return (React.createElement(RenderCustomComponent, { key: i, CustomComponent: (_h = (_g = field === null || field === void 0 ? void 0 : field.admin) === null || _g === void 0 ? void 0 : _g.components) === null || _h === void 0 ? void 0 : _h.Field, DefaultComponent: FieldComponent, componentProps: {
51
+ return (React.createElement(RenderCustomComponent, { key: fieldIndex, CustomComponent: (_h = (_g = field === null || field === void 0 ? void 0 : field.admin) === null || _g === void 0 ? void 0 : _g.components) === null || _h === void 0 ? void 0 : _h.Field, DefaultComponent: FieldComponent, componentProps: {
52
52
  ...field,
53
53
  path: field.path || (isFieldAffectingData ? field.name : ''),
54
54
  fieldTypes,
55
+ indexPath: incomingIndexPath ? `${incomingIndexPath}.${fieldIndex}` : `${fieldIndex}`,
55
56
  admin: {
56
57
  ...(field.admin || {}),
57
58
  readOnly,
@@ -59,7 +60,7 @@ const RenderFields = (props) => {
59
60
  permissions: fieldPermissions,
60
61
  } }));
61
62
  }
62
- return (React.createElement("div", { className: "missing-field", key: i },
63
+ return (React.createElement("div", { className: "missing-field", key: fieldIndex },
63
64
  "No matched field found for",
64
65
  ' ',
65
66
  "\"",
@@ -11,4 +11,5 @@ export declare type Props = {
11
11
  filter?: (field: Field) => boolean;
12
12
  fieldSchema: FieldWithPath[];
13
13
  fieldTypes: FieldTypes;
14
+ indexPath?: string;
14
15
  };
@@ -25,7 +25,7 @@ import './index.scss';
25
25
  const baseClass = 'array-field';
26
26
  const ArrayFieldType = (props) => {
27
27
  var _a, _b;
28
- const { name, path: pathFromProps, fields, fieldTypes, validate = array, required, maxRows, minRows, permissions, admin: { readOnly, description, condition, initCollapsed, className, }, } = props;
28
+ const { name, path: pathFromProps, fields, fieldTypes, validate = array, required, maxRows, minRows, permissions, indexPath, admin: { readOnly, description, condition, initCollapsed, className, }, } = props;
29
29
  const path = pathFromProps || name;
30
30
  // Handle labeling for Arrays, Global Arrays, and Blocks
31
31
  const getLabels = (p) => {
@@ -174,7 +174,7 @@ const ArrayFieldType = (props) => {
174
174
  return (React.createElement(Draggable, { key: row.id, draggableId: row.id, index: i, isDragDisabled: readOnly }, (providedDrag) => (React.createElement("div", { id: `${path}-row-${i}`, ref: providedDrag.innerRef, ...providedDrag.draggableProps },
175
175
  React.createElement(Collapsible, { collapsed: row.collapsed, onToggle: (collapsed) => setCollapse(row.id, collapsed), className: `${baseClass}__row`, key: row.id, dragHandleProps: providedDrag.dragHandleProps, header: `${labels.singular} ${rowNumber >= 10 ? rowNumber : `0${rowNumber}`}`, actions: !readOnly ? (React.createElement(ArrayAction, { rowCount: rows.length, duplicateRow: duplicateRow, addRow: addRow, moveRow: moveRow, removeRow: removeRow, index: i })) : undefined },
176
176
  React.createElement(HiddenInput, { name: `${path}.${i}.id`, value: row.id }),
177
- React.createElement(RenderFields, { className: `${baseClass}__fields`, forceRender: true, readOnly: readOnly, fieldTypes: fieldTypes, permissions: permissions === null || permissions === void 0 ? void 0 : permissions.fields, fieldSchema: fields.map((field) => ({
177
+ React.createElement(RenderFields, { className: `${baseClass}__fields`, forceRender: true, readOnly: readOnly, fieldTypes: fieldTypes, permissions: permissions === null || permissions === void 0 ? void 0 : permissions.fields, indexPath: indexPath, fieldSchema: fields.map((field) => ({
178
178
  ...field,
179
179
  path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
180
180
  })) }))))));
@@ -6,4 +6,5 @@ export declare type Props = Omit<ArrayField, 'type'> & {
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
8
  label: string | false;
9
+ indexPath: string;
9
10
  };
@@ -32,7 +32,7 @@ const labelDefaults = {
32
32
  plural: 'Blocks',
33
33
  };
34
34
  const BlocksField = (props) => {
35
- const { label, name, path: pathFromProps, blocks, labels = labelDefaults, fieldTypes, maxRows, minRows, required, validate = blocksValidator, permissions, admin: { readOnly, description, condition, initCollapsed, className, }, } = props;
35
+ const { label, name, path: pathFromProps, blocks, labels = labelDefaults, fieldTypes, maxRows, minRows, required, validate = blocksValidator, permissions, indexPath, admin: { readOnly, description, condition, initCollapsed, className, }, } = props;
36
36
  const path = pathFromProps || name;
37
37
  const { preferencesKey } = useDocumentInfo();
38
38
  const { getPreference } = usePreferences();
@@ -189,7 +189,7 @@ const BlocksField = (props) => {
189
189
  React.createElement(RenderFields, { className: `${baseClass}__fields`, forceRender: true, readOnly: readOnly, fieldTypes: fieldTypes, permissions: permissions === null || permissions === void 0 ? void 0 : permissions.fields, fieldSchema: blockToRender.fields.map((field) => ({
190
190
  ...field,
191
191
  path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
192
- })) }))))));
192
+ })), indexPath: indexPath }))))));
193
193
  }
194
194
  return null;
195
195
  }),
@@ -5,4 +5,5 @@ export declare type Props = Omit<BlockField, 'type'> & {
5
5
  path?: string;
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
+ indexPath: string;
8
9
  };
@@ -10,7 +10,7 @@ import { getFieldPath } from '../getFieldPath';
10
10
  import './index.scss';
11
11
  const baseClass = 'collapsible-field';
12
12
  const CollapsibleField = (props) => {
13
- const { label, fields, fieldTypes, path, permissions, admin: { readOnly, className, initCollapsed, description, }, } = props;
13
+ const { label, fields, fieldTypes, path, permissions, indexPath, admin: { readOnly, className, initCollapsed, description, }, } = props;
14
14
  const { getPreference, setPreference } = usePreferences();
15
15
  const { preferencesKey } = useDocumentInfo();
16
16
  const [collapsedOnMount, setCollapsedOnMount] = useState();
@@ -45,7 +45,7 @@ const CollapsibleField = (props) => {
45
45
  baseClass,
46
46
  className,
47
47
  ].filter(Boolean).join(' '), header: React.createElement("div", { className: `${baseClass}__label` }, label), onToggle: onToggle },
48
- React.createElement(RenderFields, { forceRender: true, readOnly: readOnly, permissions: permissions, fieldTypes: fieldTypes, fieldSchema: fields.map((field) => ({
48
+ React.createElement(RenderFields, { forceRender: true, readOnly: readOnly, permissions: permissions, fieldTypes: fieldTypes, indexPath: indexPath, fieldSchema: fields.map((field) => ({
49
49
  ...field,
50
50
  path: getFieldPath(path, field),
51
51
  })) })),
@@ -5,4 +5,5 @@ export declare type Props = Omit<CollapsibleField, 'type'> & {
5
5
  path?: string;
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
+ indexPath: string;
8
9
  };
@@ -9,7 +9,7 @@ import { GroupProvider, useGroup } from './provider';
9
9
  import { useTabs } from '../Tabs/provider';
10
10
  const baseClass = 'group-field';
11
11
  const Group = (props) => {
12
- const { label, fields, name, path: pathFromProps, fieldTypes, admin: { readOnly, style, className, width, description, hideGutter = false, }, permissions, } = props;
12
+ const { label, fields, name, path: pathFromProps, fieldTypes, indexPath, admin: { readOnly, style, className, width, description, hideGutter = false, }, permissions, } = props;
13
13
  const isWithinCollapsible = useCollapsible();
14
14
  const isWithinGroup = useGroup();
15
15
  const isWithinTab = useTabs();
@@ -31,7 +31,7 @@ const Group = (props) => {
31
31
  (label || description) && (React.createElement("header", { className: `${baseClass}__header` },
32
32
  label && (React.createElement("h3", { className: `${baseClass}__title` }, label)),
33
33
  React.createElement(FieldDescription, { value: null, description: description }))),
34
- React.createElement(RenderFields, { permissions: permissions === null || permissions === void 0 ? void 0 : permissions.fields, readOnly: readOnly, fieldTypes: fieldTypes, fieldSchema: fields.map((subField) => ({
34
+ React.createElement(RenderFields, { permissions: permissions === null || permissions === void 0 ? void 0 : permissions.fields, readOnly: readOnly, fieldTypes: fieldTypes, indexPath: indexPath, fieldSchema: fields.map((subField) => ({
35
35
  ...subField,
36
36
  path: `${path}${fieldAffectsData(subField) ? `.${subField.name}` : ''}`,
37
37
  })) })))));
@@ -5,4 +5,5 @@ export declare type Props = Omit<GroupField, 'type'> & {
5
5
  path?: string;
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
+ indexPath: string;
8
9
  };
@@ -4,13 +4,13 @@ import withCondition from '../../withCondition';
4
4
  import { getFieldPath } from '../getFieldPath';
5
5
  import './index.scss';
6
6
  const Row = (props) => {
7
- const { fields, fieldTypes, path, permissions, admin: { readOnly, className, }, } = props;
7
+ const { fields, fieldTypes, path, permissions, admin: { readOnly, className, }, indexPath } = props;
8
8
  const classes = [
9
9
  'field-type',
10
10
  'row',
11
11
  className,
12
12
  ].filter(Boolean).join(' ');
13
- return (React.createElement(RenderFields, { readOnly: readOnly, className: classes, permissions: permissions, fieldTypes: fieldTypes, fieldSchema: fields.map((field) => ({
13
+ return (React.createElement(RenderFields, { readOnly: readOnly, className: classes, permissions: permissions, fieldTypes: fieldTypes, indexPath: indexPath, fieldSchema: fields.map((field) => ({
14
14
  ...field,
15
15
  path: getFieldPath(path, field),
16
16
  })) }));
@@ -5,4 +5,5 @@ export declare type Props = Omit<RowField, 'type'> & {
5
5
  path?: string;
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
+ indexPath: string;
8
9
  };
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
  import RenderFields from '../../RenderFields';
3
3
  import withCondition from '../../withCondition';
4
4
  import { fieldAffectsData, tabHasName } from '../../../../../fields/config/types';
@@ -6,13 +6,52 @@ import FieldDescription from '../../FieldDescription';
6
6
  import toKebabCase from '../../../../../utilities/toKebabCase';
7
7
  import { useCollapsible } from '../../../elements/Collapsible/provider';
8
8
  import { TabsProvider } from './provider';
9
+ import { usePreferences } from '../../../utilities/Preferences';
10
+ import { useDocumentInfo } from '../../../utilities/DocumentInfo';
9
11
  import './index.scss';
10
12
  const baseClass = 'tabs-field';
11
13
  const TabsField = (props) => {
12
- const { tabs, fieldTypes, path, permissions, admin: { readOnly, className, }, } = props;
14
+ const { tabs, fieldTypes, path, permissions, indexPath, admin: { readOnly, className, }, } = props;
15
+ const { getPreference, setPreference } = usePreferences();
16
+ const { preferencesKey } = useDocumentInfo();
13
17
  const isWithinCollapsible = useCollapsible();
14
- const [active, setActive] = useState(0);
15
- const activeTab = tabs[active];
18
+ const [activeTabIndex, setActiveTabIndex] = useState(0);
19
+ const tabsPrefKey = `tabs-${indexPath}`;
20
+ useEffect(() => {
21
+ const getInitialPref = async () => {
22
+ var _a, _b, _c, _d;
23
+ const existingPreferences = await getPreference(preferencesKey);
24
+ const initialIndex = path ? (_b = (_a = existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields) === null || _a === void 0 ? void 0 : _a[path]) === null || _b === void 0 ? void 0 : _b.tabIndex : (_d = (_c = existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields) === null || _c === void 0 ? void 0 : _c[tabsPrefKey]) === null || _d === void 0 ? void 0 : _d.tabIndex;
25
+ setActiveTabIndex(initialIndex || 0);
26
+ };
27
+ getInitialPref();
28
+ }, [path, indexPath]);
29
+ const handleTabChange = useCallback(async (incomingTabIndex) => {
30
+ var _a, _b;
31
+ setActiveTabIndex(incomingTabIndex);
32
+ const existingPreferences = await getPreference(preferencesKey);
33
+ setPreference(preferencesKey, {
34
+ ...existingPreferences,
35
+ ...path ? {
36
+ fields: {
37
+ ...(existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields) || {},
38
+ [path]: {
39
+ ...(_a = existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields) === null || _a === void 0 ? void 0 : _a[path],
40
+ tabIndex: incomingTabIndex,
41
+ },
42
+ },
43
+ } : {
44
+ fields: {
45
+ ...existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields,
46
+ [tabsPrefKey]: {
47
+ ...(_b = existingPreferences === null || existingPreferences === void 0 ? void 0 : existingPreferences.fields) === null || _b === void 0 ? void 0 : _b[tabsPrefKey],
48
+ tabIndex: incomingTabIndex,
49
+ }
50
+ },
51
+ }
52
+ });
53
+ }, [indexPath, preferencesKey, getPreference, setPreference, path]);
54
+ const activeTabConfig = tabs[activeTabIndex];
16
55
  return (React.createElement("div", { className: [
17
56
  className,
18
57
  baseClass,
@@ -20,20 +59,22 @@ const TabsField = (props) => {
20
59
  ].filter(Boolean).join(' ') },
21
60
  React.createElement(TabsProvider, null,
22
61
  React.createElement("div", { className: `${baseClass}__tabs-wrap` },
23
- React.createElement("div", { className: `${baseClass}__tabs` }, tabs.map((tab, i) => {
24
- return (React.createElement("button", { key: i, type: "button", className: [
62
+ React.createElement("div", { className: `${baseClass}__tabs` }, tabs.map((tab, tabIndex) => {
63
+ return (React.createElement("button", { key: tabIndex, type: "button", className: [
25
64
  `${baseClass}__tab-button`,
26
- active === i && `${baseClass}__tab-button--active`,
27
- ].filter(Boolean).join(' '), onClick: () => setActive(i) }, tab.label ? tab.label : (tabHasName(tab) && tab.name)));
65
+ activeTabIndex === tabIndex && `${baseClass}__tab-button--active`,
66
+ ].filter(Boolean).join(' '), onClick: () => {
67
+ handleTabChange(tabIndex);
68
+ } }, tab.label ? tab.label : (tabHasName(tab) && tab.name)));
28
69
  }))),
29
- React.createElement("div", { className: `${baseClass}__content-wrap` }, activeTab && (React.createElement("div", { className: [
70
+ React.createElement("div", { className: `${baseClass}__content-wrap` }, activeTabConfig && (React.createElement("div", { className: [
30
71
  `${baseClass}__tab`,
31
- `${baseClass}__tab-${toKebabCase(activeTab.label)}`,
72
+ `${baseClass}__tab-${toKebabCase(activeTabConfig.label)}`,
32
73
  ].join(' ') },
33
- React.createElement(FieldDescription, { className: `${baseClass}__description`, description: activeTab.description }),
34
- React.createElement(RenderFields, { key: String(activeTab.label), forceRender: true, readOnly: readOnly, permissions: tabHasName(activeTab) ? permissions[activeTab.name].fields : permissions, fieldTypes: fieldTypes, fieldSchema: activeTab.fields.map((field) => ({
74
+ React.createElement(FieldDescription, { className: `${baseClass}__description`, description: activeTabConfig.description }),
75
+ React.createElement(RenderFields, { key: String(activeTabConfig.label), forceRender: true, readOnly: readOnly, permissions: tabHasName(activeTabConfig) ? permissions[activeTabConfig.name].fields : permissions, fieldTypes: fieldTypes, fieldSchema: activeTabConfig.fields.map((field) => ({
35
76
  ...field,
36
- path: `${path ? `${path}.` : ''}${tabHasName(activeTab) ? `${activeTab.name}.` : ''}${fieldAffectsData(field) ? field.name : ''}`,
37
- })) })))))));
77
+ path: `${path ? `${path}.` : ''}${tabHasName(activeTabConfig) ? `${activeTabConfig.name}.` : ''}${fieldAffectsData(field) ? field.name : ''}`,
78
+ })), indexPath: indexPath })))))));
38
79
  };
39
80
  export default withCondition(TabsField);
@@ -5,4 +5,5 @@ export declare type Props = Omit<TabsField, 'type'> & {
5
5
  path?: string;
6
6
  fieldTypes: FieldTypes;
7
7
  permissions: FieldPermissions;
8
+ indexPath: string;
8
9
  };
@@ -18,7 +18,10 @@ const TextareaInput = (props) => {
18
18
  } },
19
19
  React.createElement(Error, { showError: showError, message: errorMessage }),
20
20
  React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
21
- React.createElement("textarea", { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, name: path, rows: rows }),
21
+ React.createElement("div", { className: "textarea-outer" },
22
+ React.createElement("div", { className: "textarea-inner" },
23
+ React.createElement("div", { className: "textarea-clone", "data-value": value || placeholder || '' }),
24
+ React.createElement("textarea", { className: "textarea-element", id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, name: path, rows: rows }))),
22
25
  React.createElement(FieldDescription, { value: value, description: description })));
23
26
  };
24
27
  export default TextareaInput;
@@ -1,14 +1,22 @@
1
- @import '../../../../scss/styles.scss';
1
+ @import "../../../../scss/styles.scss";
2
2
 
3
3
  .field-type.textarea {
4
4
  position: relative;
5
5
  margin-bottom: $baseline;
6
6
 
7
- textarea {
7
+ .textarea-outer {
8
8
  @include formInput();
9
+ resize: vertical;
9
10
  height: auto;
10
11
  min-height: base(3);
11
- resize: vertical;
12
+
13
+ // Scrollbar for giant content
14
+ max-height: 90vh;
15
+ overflow: auto;
16
+
17
+ @include mid-break {
18
+ max-height: 60vh;
19
+ }
12
20
  }
13
21
 
14
22
  &.error {
@@ -16,4 +24,65 @@
16
24
  background-color: var(--theme-error-200);
17
25
  }
18
26
  }
27
+
28
+ // This element takes exactly the same dimensions as the clone
29
+ .textarea-inner {
30
+ display: block;
31
+ position: relative;
32
+ line-height: inherit;
33
+ flex-grow: 1;
34
+ box-sizing: border-box;
35
+ background: none;
36
+ outline: none;
37
+ }
38
+
39
+ // Unstyle the textarea, the border is rendered on .textarea-outer
40
+ .textarea-element {
41
+ position: absolute;
42
+ top: 0;
43
+ left: 0;
44
+ width: 100%;
45
+ height: 100%;
46
+ border: inherit;
47
+ padding: inherit;
48
+ font: inherit;
49
+ line-height: inherit;
50
+ color: inherit;
51
+ background: none;
52
+ box-sizing: border-box;
53
+ overflow: auto;
54
+ resize: none;
55
+ outline: none;
56
+ text-transform: inherit;
57
+
58
+ &::-webkit-scrollbar {
59
+ display: none;
60
+ }
61
+ }
62
+
63
+ // Clone of textarea with same height
64
+ .textarea-clone {
65
+ vertical-align: top;
66
+ display: inline-block;
67
+ flex-grow: 1;
68
+ white-space: pre;
69
+ box-sizing: border-box;
70
+ overflow: hidden;
71
+ text-overflow: ellipsis;
72
+ white-space: pre-wrap;
73
+ pointer-events: none;
74
+ }
75
+
76
+ .textarea-clone::before {
77
+ content: attr(data-value) " ";
78
+ visibility: hidden;
79
+ opacity: 0;
80
+ white-space: pre-wrap;
81
+ overflow-wrap: break-word;
82
+ }
83
+
84
+ .textarea-clone::after {
85
+ content: attr(data-after);
86
+ opacity: 0.5;
87
+ }
19
88
  }
@@ -25,7 +25,11 @@ const useField = (options) => {
25
25
  const val = (e && e.target) ? e.target.value : e;
26
26
  if (!modified && !disableModifyingForm) {
27
27
  if (typeof setModified === 'function') {
28
- Promise.resolve(() => setModified(true));
28
+ // Update modified state after field value comes back
29
+ // to avoid cursor jump caused by state value / DOM mismatch
30
+ setTimeout(() => {
31
+ setModified(true);
32
+ }, 10);
29
33
  }
30
34
  }
31
35
  dispatchField({
@@ -10,7 +10,8 @@ const modalSlug = 'stay-logged-in';
10
10
  const StayLoggedInModal = (props) => {
11
11
  const { refreshCookie } = props;
12
12
  const history = useHistory();
13
- const { routes: { admin } } = useConfig();
13
+ const config = useConfig();
14
+ const { routes: { admin }, admin: { logoutRoute } } = config;
14
15
  const { toggleModal } = useModal();
15
16
  return (React.createElement(Modal, { className: baseClass, slug: "stay-logged-in" },
16
17
  React.createElement(MinimalTemplate, { className: `${baseClass}__template` },
@@ -19,7 +20,7 @@ const StayLoggedInModal = (props) => {
19
20
  React.createElement("div", { className: `${baseClass}__actions` },
20
21
  React.createElement(Button, { buttonStyle: "secondary", onClick: () => {
21
22
  toggleModal(modalSlug);
22
- history.push(`${admin}/logout`);
23
+ history.push(`${admin}${logoutRoute}`);
23
24
  } }, "Log out"),
24
25
  React.createElement(Button, { onClick: () => {
25
26
  refreshCookie();
@@ -13,7 +13,7 @@ export const AuthProvider = ({ children }) => {
13
13
  const { pathname } = useLocation();
14
14
  const { push } = useHistory();
15
15
  const config = useConfig();
16
- const { admin: { user: userSlug, }, serverURL, routes: { admin, api, }, } = config;
16
+ const { admin: { user: userSlug, inactivityRoute: logoutInactivityRoute, }, serverURL, routes: { admin, api, }, } = config;
17
17
  const exp = user === null || user === void 0 ? void 0 : user.exp;
18
18
  const [permissions, setPermissions] = useState();
19
19
  const { openModal, closeAllModals } = useModal();
@@ -32,7 +32,7 @@ export const AuthProvider = ({ children }) => {
32
32
  }
33
33
  else {
34
34
  setUser(null);
35
- push(`${admin}/logout-inactivity`);
35
+ push(`${admin}${logoutInactivityRoute}`);
36
36
  }
37
37
  }, 1000);
38
38
  }
@@ -104,7 +104,7 @@ export const AuthProvider = ({ children }) => {
104
104
  if (remainingTime > 0) {
105
105
  forceLogOut = setTimeout(() => {
106
106
  setUser(null);
107
- push(`${admin}/logout-inactivity`);
107
+ push(`${admin}${logoutInactivityRoute}`);
108
108
  closeAllModals();
109
109
  }, Math.min(remainingTime * 1000, maxTimeoutTime));
110
110
  }
@@ -8,6 +8,8 @@ export declare type ContextType = {
8
8
  collection?: SanitizedCollectionConfig;
9
9
  global?: SanitizedGlobalConfig;
10
10
  type: 'global' | 'collection';
11
+ /** Slug of the collection or global */
12
+ slug?: string;
11
13
  id?: string | number;
12
14
  preferencesKey?: string;
13
15
  versions?: PaginatedDocs<Version>;
@@ -15,7 +15,8 @@ const baseClass = 'login';
15
15
  const Login = () => {
16
16
  const history = useHistory();
17
17
  const { user, setToken } = useAuth();
18
- const { admin: { user: userSlug, components: { beforeLogin, afterLogin, } = {}, }, serverURL, routes: { admin, api, }, collections, } = useConfig();
18
+ const config = useConfig();
19
+ const { admin: { user: userSlug, logoutRoute, components: { beforeLogin, afterLogin, logout } = {}, }, serverURL, routes: { admin, api, }, collections, } = config;
19
20
  const collection = collections.find(({ slug }) => slug === userSlug);
20
21
  const onSuccess = (data) => {
21
22
  if (data.token) {
@@ -31,7 +32,7 @@ const Login = () => {
31
32
  React.createElement("p", null,
32
33
  "To log in with another user, you should",
33
34
  ' ',
34
- React.createElement(Link, { to: `${admin}/logout` }, "log out"),
35
+ React.createElement(Link, { to: `${admin}${logoutRoute}` }, "log out"),
35
36
  ' ',
36
37
  "first."),
37
38
  React.createElement("br", null),
@@ -13,7 +13,8 @@ import './index.scss';
13
13
  import HiddenInput from '../../forms/field-types/HiddenInput';
14
14
  const baseClass = 'reset-password';
15
15
  const ResetPassword = () => {
16
- const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = useConfig();
16
+ const config = useConfig();
17
+ const { admin: { user: userSlug, logoutRoute }, serverURL, routes: { admin, api } } = config;
17
18
  const { token } = useParams();
18
19
  const history = useHistory();
19
20
  const { user, setToken } = useAuth();
@@ -31,7 +32,7 @@ const ResetPassword = () => {
31
32
  React.createElement("p", null,
32
33
  "To log in with another user, you should",
33
34
  ' ',
34
- React.createElement(Link, { to: `${admin}/logout` }, "log out"),
35
+ React.createElement(Link, { to: `${admin}${logoutRoute}` }, "log out"),
35
36
  ' ',
36
37
  "first."),
37
38
  React.createElement("br", null),
@@ -4,12 +4,13 @@ import Button from '../../elements/Button';
4
4
  import Meta from '../../utilities/Meta';
5
5
  import MinimalTemplate from '../../templates/Minimal';
6
6
  const Unauthorized = () => {
7
- const { routes: { admin } } = useConfig();
7
+ const config = useConfig();
8
+ const { routes: { admin }, admin: { logoutRoute }, } = config;
8
9
  return (React.createElement(MinimalTemplate, { className: "unauthorized" },
9
10
  React.createElement(Meta, { title: "Unauthorized", description: "Unauthorized", keywords: "Unauthorized, Payload, CMS" }),
10
11
  React.createElement("h2", null, "Unauthorized"),
11
12
  React.createElement("p", null, "You are not allowed to access this page."),
12
13
  React.createElement("br", null),
13
- React.createElement(Button, { el: "link", to: `${admin}/logout` }, "Log out")));
14
+ React.createElement(Button, { el: "link", to: `${admin}${logoutRoute}` }, "Log out")));
14
15
  };
15
16
  export default Unauthorized;
@@ -24,6 +24,8 @@ exports.defaults = {
24
24
  indexHTML: path_1.default.resolve(__dirname, '../admin/index.html'),
25
25
  avatar: 'default',
26
26
  components: {},
27
+ logoutRoute: '/logout',
28
+ inactivityRoute: '/logout-inactivity',
27
29
  css: path_1.default.resolve(__dirname, '../admin/scss/custom.css'),
28
30
  dateFormat: 'MMMM do yyyy, h:mm a',
29
31
  },
@@ -57,4 +59,4 @@ exports.defaults = {
57
59
  localization: false,
58
60
  telemetry: true,
59
61
  };
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL2RlZmF1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUdYLFFBQUEsUUFBUSxHQUFXO0lBQzlCLFNBQVMsRUFBRSxFQUFFO0lBQ2IsWUFBWSxFQUFFLENBQUM7SUFDZixRQUFRLEVBQUUsRUFBRTtJQUNaLG9CQUFvQixFQUFFLEtBQUs7SUFDM0IsV0FBVyxFQUFFLEVBQUU7SUFDZixPQUFPLEVBQUUsRUFBRTtJQUNYLFNBQVMsRUFBRSxFQUFFO0lBQ2IsWUFBWSxFQUFFLFNBQVM7SUFDdkIsSUFBSSxFQUFFLEVBQUU7SUFDUixJQUFJLEVBQUUsRUFBRTtJQUNSLEtBQUssRUFBRTtRQUNMLElBQUksRUFBRTtZQUNKLFdBQVcsRUFBRSxXQUFXO1NBQ3pCO1FBQ0QsT0FBTyxFQUFFLEtBQUs7UUFDZCxTQUFTLEVBQUUsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUscUJBQXFCLENBQUM7UUFDekQsTUFBTSxFQUFFLFNBQVM7UUFDakIsVUFBVSxFQUFFLEVBQUU7UUFDZCxHQUFHLEVBQUUsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsMEJBQTBCLENBQUM7UUFDeEQsVUFBVSxFQUFFLHNCQUFzQjtLQUNuQztJQUNELFVBQVUsRUFBRTtRQUNWLFVBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsR0FBRyxDQUFBLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsbUJBQW1CO0tBQzFGO0lBQ0QsTUFBTSxFQUFFLEVBQUU7SUFDVixPQUFPLEVBQUU7UUFDUCxhQUFhLEVBQUUsSUFBSTtRQUNuQiw2QkFBNkIsRUFBRSxJQUFJO1FBQ25DLGdCQUFnQixFQUFFLEdBQUcsT0FBTyxDQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxHQUFHLENBQUEsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxpQkFBaUI7S0FDOUY7SUFDRCxNQUFNLEVBQUU7UUFDTixLQUFLLEVBQUUsUUFBUTtRQUNmLEdBQUcsRUFBRSxNQUFNO1FBQ1gsT0FBTyxFQUFFLFVBQVU7UUFDbkIsaUJBQWlCLEVBQUUscUJBQXFCO0tBQ3pDO0lBQ0QsU0FBUyxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRztRQUNyQixHQUFHLEVBQUUsR0FBRztLQUNUO0lBQ0QsT0FBTyxFQUFFO1FBQ1AsSUFBSSxFQUFFLEVBQUU7UUFDUixXQUFXLEVBQUUsRUFBRTtRQUNmLFVBQVUsRUFBRSxFQUFFO1FBQ2QsYUFBYSxFQUFFLEVBQUU7UUFDakIsY0FBYyxFQUFFLEVBQUU7S0FDbkI7SUFDRCxLQUFLLEVBQUUsRUFBRTtJQUNULFlBQVksRUFBRSxLQUFLO0lBQ25CLFNBQVMsRUFBRSxJQUFJO0NBQ2hCLENBQUMifQ==
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL2RlZmF1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUdYLFFBQUEsUUFBUSxHQUFXO0lBQzlCLFNBQVMsRUFBRSxFQUFFO0lBQ2IsWUFBWSxFQUFFLENBQUM7SUFDZixRQUFRLEVBQUUsRUFBRTtJQUNaLG9CQUFvQixFQUFFLEtBQUs7SUFDM0IsV0FBVyxFQUFFLEVBQUU7SUFDZixPQUFPLEVBQUUsRUFBRTtJQUNYLFNBQVMsRUFBRSxFQUFFO0lBQ2IsWUFBWSxFQUFFLFNBQVM7SUFDdkIsSUFBSSxFQUFFLEVBQUU7SUFDUixJQUFJLEVBQUUsRUFBRTtJQUNSLEtBQUssRUFBRTtRQUNMLElBQUksRUFBRTtZQUNKLFdBQVcsRUFBRSxXQUFXO1NBQ3pCO1FBQ0QsT0FBTyxFQUFFLEtBQUs7UUFDZCxTQUFTLEVBQUUsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUscUJBQXFCLENBQUM7UUFDekQsTUFBTSxFQUFFLFNBQVM7UUFDakIsVUFBVSxFQUFFLEVBQUU7UUFDZCxXQUFXLEVBQUUsU0FBUztRQUN0QixlQUFlLEVBQUUsb0JBQW9CO1FBQ3JDLEdBQUcsRUFBRSxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSwwQkFBMEIsQ0FBQztRQUN4RCxVQUFVLEVBQUUsc0JBQXNCO0tBQ25DO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxHQUFHLENBQUEsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxtQkFBbUI7S0FDMUY7SUFDRCxNQUFNLEVBQUUsRUFBRTtJQUNWLE9BQU8sRUFBRTtRQUNQLGFBQWEsRUFBRSxJQUFJO1FBQ25CLDZCQUE2QixFQUFFLElBQUk7UUFDbkMsZ0JBQWdCLEVBQUUsR0FBRyxPQUFPLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLEdBQUcsQ0FBQSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGlCQUFpQjtLQUM5RjtJQUNELE1BQU0sRUFBRTtRQUNOLEtBQUssRUFBRSxRQUFRO1FBQ2YsR0FBRyxFQUFFLE1BQU07UUFDWCxPQUFPLEVBQUUsVUFBVTtRQUNuQixpQkFBaUIsRUFBRSxxQkFBcUI7S0FDekM7SUFDRCxTQUFTLEVBQUU7UUFDVCxNQUFNLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHO1FBQ3JCLEdBQUcsRUFBRSxHQUFHO0tBQ1Q7SUFDRCxPQUFPLEVBQUU7UUFDUCxJQUFJLEVBQUUsRUFBRTtRQUNSLFdBQVcsRUFBRSxFQUFFO1FBQ2YsVUFBVSxFQUFFLEVBQUU7UUFDZCxhQUFhLEVBQUUsRUFBRTtRQUNqQixjQUFjLEVBQUUsRUFBRTtLQUNuQjtJQUNELEtBQUssRUFBRSxFQUFFO0lBQ1QsWUFBWSxFQUFFLEtBQUs7SUFDbkIsU0FBUyxFQUFFLElBQUk7Q0FDaEIsQ0FBQyJ9
@@ -53,6 +53,8 @@ exports.default = joi_1.default.object({
53
53
  dateFormat: joi_1.default.string(),
54
54
  avatar: joi_1.default.alternatives()
55
55
  .try(joi_1.default.string(), component),
56
+ logoutRoute: joi_1.default.string(),
57
+ inactivityRoute: joi_1.default.string(),
56
58
  components: joi_1.default.object()
57
59
  .keys({
58
60
  routes: joi_1.default.array()
@@ -71,6 +73,9 @@ exports.default = joi_1.default.object({
71
73
  beforeNavLinks: joi_1.default.array().items(component),
72
74
  afterNavLinks: joi_1.default.array().items(component),
73
75
  Nav: component,
76
+ logout: joi_1.default.object({
77
+ Button: component,
78
+ }),
74
79
  views: joi_1.default.object({
75
80
  Dashboard: component,
76
81
  Account: component,
@@ -139,4 +144,4 @@ exports.default = joi_1.default.object({
139
144
  onInit: joi_1.default.func(),
140
145
  debug: joi_1.default.boolean(),
141
146
  });
142
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsOENBQXNCO0FBRXRCLE1BQU0sU0FBUyxHQUFHLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQ3RDLGFBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFDdEIsYUFBRyxDQUFDLElBQUksRUFBRSxDQUNYLENBQUM7QUFFVyxRQUFBLGVBQWUsR0FBRyxhQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUFDLGFBQUcsQ0FBQyxNQUFNLENBQUM7SUFDMUQsSUFBSSxFQUFFLGFBQUcsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsTUFBTSxFQUFFLGFBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNqRyxJQUFJLEVBQUUsYUFBRyxDQUFDLElBQUksRUFBRTtJQUNoQixPQUFPLEVBQUUsYUFBRyxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FDN0IsYUFBRyxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsRUFDN0IsYUFBRyxDQUFDLElBQUksRUFBRSxDQUNYO0NBQ0YsQ0FBQyxDQUFDLENBQUM7QUFFSixrQkFBZSxhQUFHLENBQUMsTUFBTSxDQUFDO0lBQ3hCLFNBQVMsRUFBRSxhQUFHLENBQUMsTUFBTSxFQUFFO1NBQ3BCLEdBQUcsRUFBRTtTQUNMLEtBQUssQ0FBQyxFQUFFLENBQUM7U0FDVCxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDeEIsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUks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
147
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EsOENBQXNCO0FBRXRCLE1BQU0sU0FBUyxHQUFHLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQ3RDLGFBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFDdEIsYUFBRyxDQUFDLElBQUksRUFBRSxDQUNYLENBQUM7QUFFVyxRQUFBLGVBQWUsR0FBRyxhQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUFDLGFBQUcsQ0FBQyxNQUFNLENBQUM7SUFDMUQsSUFBSSxFQUFFLGFBQUcsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsTUFBTSxFQUFFLGFBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNqRyxJQUFJLEVBQUUsYUFBRyxDQUFDLElBQUksRUFBRTtJQUNoQixPQUFPLEVBQUUsYUFBRyxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FDN0IsYUFBRyxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsRUFDN0IsYUFBRyxDQUFDLElBQUksRUFBRSxDQUNYO0NBQ0YsQ0FBQyxDQUFDLENBQUM7QUFFSixrQkFBZSxhQUFHLENBQUMsTUFBTSxDQUFDO0lBQ3hCLFNBQVMsRUFBRSxhQUFHLENBQUMsTUFBTSxFQUFFO1NBQ3BCLEdBQUcsRUFBRTtTQUNMLEtBQUssQ0FBQyxFQUFFLENBQUM7U0FDVCxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDeEIsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUks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
@@ -123,6 +123,8 @@ export declare type Config = {
123
123
  css?: string;
124
124
  dateFormat?: string;
125
125
  avatar?: 'default' | 'gravatar' | React.ComponentType<any>;
126
+ logoutRoute?: string;
127
+ inactivityRoute?: string;
126
128
  components?: {
127
129
  routes?: AdminRoute[];
128
130
  providers?: React.ComponentType<{
@@ -135,6 +137,9 @@ export declare type Config = {
135
137
  beforeNavLinks?: React.ComponentType<any>[];
136
138
  afterNavLinks?: React.ComponentType<any>[];
137
139
  Nav?: React.ComponentType<any>;
140
+ logout?: {
141
+ Button?: React.ComponentType<any>;
142
+ };
138
143
  graphics?: {
139
144
  Icon?: React.ComponentType<any>;
140
145
  Logo?: React.ComponentType<any>;
@@ -171,11 +171,10 @@ async function update(args) {
171
171
  // /////////////////////////////////////
172
172
  // afterRead - Global
173
173
  // /////////////////////////////////////
174
- await globalConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
174
+ await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
175
175
  await priorHook;
176
176
  global = await hook({
177
177
  doc: global,
178
- previousDoc: originalDoc,
179
178
  req,
180
179
  }) || global;
181
180
  }, Promise.resolve());
@@ -207,4 +206,4 @@ async function update(args) {
207
206
  return global;
208
207
  }
209
208
  exports.default = update;
210
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2dsb2JhbHMvb3BlcmF0aW9ucy91cGRhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSw2RUFBcUQ7QUFDckQsb0dBQTRFO0FBQzVFLHdFQUFxRTtBQUNyRSwyRUFBd0U7QUFDeEUsOEZBQTJGO0FBQzNGLCtGQUF1RTtBQUN2RSxxQ0FBa0Q7QUFDbEQsa0VBQStEO0FBQy9ELHNFQUFtRTtBQUNuRSxnRUFBNkQ7QUFDN0QsNERBQXlEO0FBZXpELEtBQUssVUFBVSxNQUFNLENBQTZCLElBQVU7O0lBQzFELE1BQU0sRUFDSixZQUFZLEVBQ1osSUFBSSxFQUNKLEdBQUcsRUFDSCxHQUFHLEVBQUUsRUFDSCxNQUFNLEVBQ04sT0FBTyxFQUNQLE9BQU8sRUFBRSxFQUNQLE9BQU8sRUFBRSxFQUNQLEtBQUssR0FDTixHQUNGLEdBQ0YsRUFDRCxLQUFLLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixLQUFLLEVBQUUsUUFBUSxFQUNmLFFBQVEsR0FDVCxHQUFHLElBQUksQ0FBQztJQUVULElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7SUFFcEIsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLFFBQVEsS0FBSSxNQUFBLFlBQVksQ0FBQyxRQUFRLDBDQUFFLE1BQU0sQ0FBQSxDQUFDLENBQUM7SUFFM0Usd0NBQXdDO0lBQ3hDLGlDQUFpQztJQUNqQyx3Q0FBd0M7SUFFeEMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBQSx1QkFBYSxFQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUU5Ryx3Q0FBd0M7SUFDeEMsb0JBQW9CO0lBQ3BCLHdDQUF3QztJQUV4QyxNQUFNLFlBQVksR0FBcUI7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
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2dsb2JhbHMvb3BlcmF0aW9ucy91cGRhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSw2RUFBcUQ7QUFDckQsb0dBQTRFO0FBQzVFLHdFQUFxRTtBQUNyRSwyRUFBd0U7QUFDeEUsOEZBQTJGO0FBQzNGLCtGQUF1RTtBQUN2RSxxQ0FBa0Q7QUFDbEQsa0VBQStEO0FBQy9ELHNFQUFtRTtBQUNuRSxnRUFBNkQ7QUFDN0QsNERBQXlEO0FBZXpELEtBQUssVUFBVSxNQUFNLENBQTZCLElBQVU7O0lBQzFELE1BQU0sRUFDSixZQUFZLEVBQ1osSUFBSSxFQUNKLEdBQUcsRUFDSCxHQUFHLEVBQUUsRUFDSCxNQUFNLEVBQ04sT0FBTyxFQUNQLE9BQU8sRUFBRSxFQUNQLE9BQU8sRUFBRSxFQUNQLEtBQUssR0FDTixHQUNGLEdBQ0YsRUFDRCxLQUFLLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixLQUFLLEVBQUUsUUFBUSxFQUNmLFFBQVEsR0FDVCxHQUFHLElBQUksQ0FBQztJQUVULElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7SUFFcEIsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLFFBQVEsS0FBSSxNQUFBLFlBQVksQ0FBQyxRQUFRLDBDQUFFLE1BQU0sQ0FBQSxDQUFDLENBQUM7SUFFM0Usd0NBQXdDO0lBQ3hDLGlDQUFpQztJQUNqQyx3Q0FBd0M7SUFFeEMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBQSx1QkFBYSxFQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUU5Ryx3Q0FBd0M7SUFDeEMsb0JBQW9CO0lBQ3BCLHdDQUF3QztJQUV4QyxNQUFNLFlBQVksR0FBcUI7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
@@ -24,8 +24,12 @@ export declare type PreferenceUpdateRequest = PreferenceRequest & {
24
24
  value: undefined;
25
25
  };
26
26
  export declare type CollapsedPreferences = string[];
27
+ export declare type TabsPreferences = Array<{
28
+ [path: string]: number;
29
+ }>;
27
30
  export declare type FieldsPreferences = {
28
31
  [key: string]: {
32
+ tabIndex: number;
29
33
  collapsed: CollapsedPreferences;
30
34
  };
31
35
  };
@@ -11,35 +11,39 @@ While designing the Payload Admin panel, we determined it should be as minimal a
11
11
  To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
12
12
 
13
13
  <Banner type="success">
14
- <strong>Tip:</strong><br/>
15
- Custom components will automatically be provided with all props that the default component would accept.
14
+ <strong>Tip:</strong>
15
+ <br />
16
+ Custom components will automatically be provided with all props that the
17
+ default component would accept.
16
18
  </Banner>
17
19
 
18
20
  ### Base Component Overrides
19
21
 
20
22
  You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
21
23
 
22
- | Path | Description |
23
- | --------------------- | -------------|
24
- | **`Nav`** | Contains the sidebar and mobile Nav in its entirety. |
25
- | **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
26
- | **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/master/test/admin/components/AfterDashboard/index.tsx)|
27
- | **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
28
- | **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
29
- | **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
30
- | **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
31
- | **`views.Account`** | The Account view is used to show the currently logged in user's Account page. |
32
- | **`views.Dashboard`** | The main landing page of the Admin panel. |
33
- | **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
34
- | **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
35
- | **`routes`** | Define your own routes to add to the Payload Admin UI. [More](#custom-routes) |
36
- | **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
24
+ | Path | Description |
25
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | **`Nav`** | Contains the sidebar and mobile Nav in its entirety. |
27
+ | **`logout.Button`** | A custom React component.
28
+ | **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
29
+ | **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/master/test/admin/components/AfterDashboard/index.tsx) |
30
+ | **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
31
+ | **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
32
+ | **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
33
+ | **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
34
+ | **`views.Account`** | The Account view is used to show the currently logged in user's Account page. |
35
+ | **`views.Dashboard`** | The main landing page of the Admin panel. |
36
+ | **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
37
+ | **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
38
+ | **`routes`** | Define your own routes to add to the Payload Admin UI. [More](#custom-routes) |
39
+ | **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
37
40
 
38
41
  #### Full example:
39
42
 
40
43
  `payload.config.js`
44
+
41
45
  ```ts
42
- import { buildConfig } from 'payload/config'
46
+ import { buildConfig } from "payload/config";
43
47
  import {
44
48
  MyCustomNav,
45
49
  MyCustomLogo,
@@ -47,7 +51,7 @@ import {
47
51
  MyCustomAccount,
48
52
  MyCustomDashboard,
49
53
  MyProvider,
50
- } from './customComponents';
54
+ } from "./customComponents";
51
55
 
52
56
  export default buildConfig({
53
57
  admin: {
@@ -67,75 +71,69 @@ export default buildConfig({
67
71
  });
68
72
  ```
69
73
 
70
- *For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/master/test/admin/components).*
74
+ _For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/master/test/admin/components)._
71
75
 
72
76
  ### Collections
73
77
 
74
78
  You can override components on a Collection-by-Collection basis via each Collection's `admin` property.
75
79
 
76
- | Path | Description |
77
- | ---------------- | -------------|
78
- | **`views.Edit`** | Used while a document within this Collection is being edited. |
79
- | **`views.List`** | The `List` view is used to render a paginated, filterable table of Documents in this Collection. |
80
+ | Path | Description |
81
+ | ---------------- | ------------------------------------------------------------------------------------------------ |
82
+ | **`views.Edit`** | Used while a document within this Collection is being edited. |
83
+ | **`views.List`** | The `List` view is used to render a paginated, filterable table of Documents in this Collection. |
80
84
 
81
85
  ### Globals
82
86
 
83
87
  As with Collections, You can override components on a global-by-global basis via their `admin` property.
84
88
 
85
- | Path | Description |
86
- | ---------------- | -------------|
87
- | **`views.Edit`** | Used while this Global is being edited. |
89
+ | Path | Description |
90
+ | ---------------- | --------------------------------------- |
91
+ | **`views.Edit`** | Used while this Global is being edited. |
88
92
 
89
93
  ### Fields
90
94
 
91
95
  All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
92
96
 
93
97
  <Banner type="success">
94
- <strong>Tip:</strong><br/>
95
- Don't see a built-in field type that you need? Build it! Using a combination of custom validation and custom components, you can override the entirety of how a component functions within the admin panel and effectively create your own field type.
98
+ <strong>Tip:</strong>
99
+ <br />
100
+ Don't see a built-in field type that you need? Build it! Using a combination
101
+ of custom validation and custom components, you can override the entirety of
102
+ how a component functions within the admin panel and effectively create your
103
+ own field type.
96
104
  </Banner>
97
105
 
98
106
  **Fields support the following custom components:**
99
107
 
100
- | Component | Description |
101
- | --------------- |------------------------------------------------------------------------------------------------------------------------------|
102
- | **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
103
- | **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) |
104
- | **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
108
+ | Component | Description |
109
+ | ------------ | --------------------------------------------------------------------------------------------------------------------------- |
110
+ | **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
111
+ | **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) |
112
+ | **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
105
113
 
106
114
  ## Cell Component
107
115
 
108
116
  These are the props that will be passed to your custom Cell to use in your own components.
109
117
 
110
- | Property | Description |
111
- |--------------|-------------------------------------------------------------------|
112
- | **`field`** | An object that includes the field configuration. |
113
- | **`colIndex`** | A unique number for the column in the list. |
118
+ | Property | Description |
119
+ | ---------------- | ----------------------------------------------------------------- |
120
+ | **`field`** | An object that includes the field configuration. |
121
+ | **`colIndex`** | A unique number for the column in the list. |
114
122
  | **`collection`** | An object with the config of the collection that the field is in. |
115
123
  | **`cellData`** | The data for the field that the cell represents. |
116
- | **`rowData`** | An object with all the field values for the row. |
124
+ | **`rowData`** | An object with all the field values for the row. |
117
125
 
118
126
  #### Example
119
127
 
120
128
  ```tsx
121
- import React from 'react';
122
- import './index.scss';
123
- const baseClass = 'custom-cell';
129
+ import React from "react";
130
+ import "./index.scss";
131
+ const baseClass = "custom-cell";
124
132
 
125
133
  const CustomCell: React.FC<Props> = (props) => {
126
- const {
127
- field,
128
- colIndex,
129
- collection,
130
- cellData,
131
- rowData,
132
- } = props;
134
+ const { field, colIndex, collection, cellData, rowData } = props;
133
135
 
134
- return (
135
- <span className={baseClass}>
136
- { cellData }
137
- </span>
138
- );
136
+ return <span className={baseClass}>{cellData}</span>;
139
137
  };
140
138
  ```
141
139
 
@@ -148,21 +146,28 @@ When writing your own custom components you can make use of a number of hooks to
148
146
  When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
149
147
 
150
148
  ```tsx
151
- import { useField } from 'payload/components/forms'
149
+ import { useField } from "payload/components/forms";
152
150
 
153
- type Props = { path: string }
151
+ type Props = { path: string };
154
152
 
155
153
  const CustomTextField: React.FC<Props> = ({ path }) => {
156
154
  // highlight-start
157
- const { value, setValue } = useField<Props>({ path })
155
+ const { value, setValue } = useField<Props>({ path });
158
156
  // highlight-end
159
157
 
160
- return <input onChange={e => setValue(e.target.value)} value={value.path} />
161
- }
158
+ return (
159
+ <input onChange={(e) => setValue(e.target.value)} value={value.path} />
160
+ );
161
+ };
162
162
  ```
163
163
 
164
164
  <Banner type="success">
165
- For more information regarding the hooks that are available to you while you build custom components, including the <strong>useField</strong> hook, <a href="/docs/admin/hooks" style={{color: 'black'}}>click here</a>.
165
+ For more information regarding the hooks that are available to you while you
166
+ build custom components, including the <strong>useField</strong> hook,{" "}
167
+ <a href="/docs/admin/hooks" style={{ color: "black" }}>
168
+ click here
169
+ </a>
170
+ .
166
171
  </Banner>
167
172
 
168
173
  ## Custom routes
@@ -171,28 +176,31 @@ You can easily add your own custom routes to the Payload Admin panel using the `
171
176
 
172
177
  **Custom routes support the following properties:**
173
178
 
174
- | Property | Description |
175
- | ----------------- | -------------|
176
- | **`Component`** * | Pass in the component that should be rendered when a user navigates to this route. |
177
- | **`path`** * | React Router `path`. [See the React Router docs](https://v5.reactrouter.com/web/api/Route/path-string-string) for more info. |
178
- | **`exact`** | React Router `exact` property. [More](https://v5.reactrouter.com/web/api/Route/exact-bool) |
179
- | **`strict`** | React Router `strict` property. [More](https://v5.reactrouter.com/web/api/Route/strict-bool) |
180
- | **`sensitive`** | React Router `sensitive` property. [More](https://v5.reactrouter.com/web/api/Route/sensitive-bool) |
179
+ | Property | Description |
180
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
181
+ | **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
182
+ | **`path`** \* | React Router `path`. [See the React Router docs](https://v5.reactrouter.com/web/api/Route/path-string-string) for more info. |
183
+ | **`exact`** | React Router `exact` property. [More](https://v5.reactrouter.com/web/api/Route/exact-bool) |
184
+ | **`strict`** | React Router `strict` property. [More](https://v5.reactrouter.com/web/api/Route/strict-bool) |
185
+ | **`sensitive`** | React Router `sensitive` property. [More](https://v5.reactrouter.com/web/api/Route/sensitive-bool) |
181
186
 
182
- *\* An asterisk denotes that a property is required.*
187
+ _\* An asterisk denotes that a property is required._
183
188
 
184
189
  #### Custom route components
185
190
 
186
191
  Your custom route components will be given all the props that a React Router `<Route />` typically would receive, as well as two props from Payload:
187
192
 
188
- | Prop | Description |
189
- | ---------------------- | -------------|
190
- | **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
191
- | **`canAccessAdmin`** * | If the currently logged in user is allowed to access the admin panel or not. |
193
+ | Prop | Description |
194
+ | ----------------------- | ---------------------------------------------------------------------------- |
195
+ | **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
196
+ | **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the admin panel or not. |
192
197
 
193
198
  <Banner type="warning">
194
- <strong>Note:</strong><br/>
195
- It's up to you to secure your custom routes. If your route requires a user to be logged in or to have certain access rights, you should handle that within your route component yourself.
199
+ <strong>Note:</strong>
200
+ <br />
201
+ It's up to you to secure your custom routes. If your route requires a user to
202
+ be logged in or to have certain access rights, you should handle that within
203
+ your route component yourself.
196
204
  </Banner>
197
205
 
198
206
  #### Example
@@ -208,7 +216,10 @@ To see how to pass in your custom views to create custom routes of your own, tak
208
216
 
209
217
  As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the admin panel. Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. Read the [React context](https://reactjs.org/docs/context.html) docs to learn more.
210
218
 
211
- <Banner type="warning"><strong>Reminder:</strong> Don't forget to pass the **children** prop through the provider component for the admin UI to show</Banner>
219
+ <Banner type="warning">
220
+ <strong>Reminder:</strong> Don't forget to pass the **children** prop through
221
+ the provider component for the admin UI to show
222
+ </Banner>
212
223
 
213
224
  ### Styling Custom Components
214
225
 
@@ -225,7 +236,7 @@ To make use of Payload SCSS variables / mixins to use directly in your own compo
225
236
  In any custom component you can get the selected locale with the `useLocale` hook. Here is a simple example:
226
237
 
227
238
  ```tsx
228
- import { useLocale } from 'payload/components/utilities';
239
+ import { useLocale } from "payload/components/utilities";
229
240
 
230
241
  const Greeting: React.FC = () => {
231
242
  // highlight-start
@@ -233,12 +244,10 @@ const Greeting: React.FC = () => {
233
244
  // highlight-end
234
245
 
235
246
  const trans = {
236
- en: 'Hello',
237
- es: 'Hola',
247
+ en: "Hello",
248
+ es: "Hola",
238
249
  };
239
250
 
240
- return (
241
- <span> { trans[locale] } </span>
242
- );
251
+ return <span> {trans[locale]} </span>;
243
252
  };
244
253
  ```
@@ -22,18 +22,20 @@ The Payload Admin panel is built with Webpack, code-split, highly performant (ev
22
22
 
23
23
  All options for the Admin panel are defined in your base Payload config file.
24
24
 
25
- | Option | Description |
26
- | -------------------- | -------------|
27
- | `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) |
28
- | `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. |
29
- | `disable` | If set to `true`, the entire Admin panel will be disabled. |
30
- | `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/master/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. |
31
- | `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). |
32
- | `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
33
- | `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
34
- | `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
35
- | `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) |
36
- | `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) |
25
+ | Option | Description |
26
+ | --------------------- | -------------|
27
+ | `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) |
28
+ | `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. |
29
+ | `disable` | If set to `true`, the entire Admin panel will be disabled. |
30
+ | `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/master/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. |
31
+ | `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). |
32
+ | `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
33
+ | `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
34
+ | `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
35
+ | `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) |
36
+ | `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) | |
37
+ | **`logoutRoute`** | The route for the `logout` page. |
38
+ | **`inactivityRoute`** | The route for the `logout` inactivity page. |
37
39
 
38
40
 
39
41
  ### The Admin User Collection
@@ -27,8 +27,8 @@ With this field, you can also inject custom `Cell` components that appear as add
27
27
  | ---------------------------- |-------------------------------------------------------------------------------------------------------------------|
28
28
  | **`name`** * | A unique identifier for this field. |
29
29
  | **`label`** | Human-readable label for this UI field. |
30
- | **`admin.components.Field`** | React component to be rendered for this field within the Edit view. [More](/admin/components/#field-component) |
31
- | **`admin.components.Cell`** | React component to be rendered as a Cell within collection List views. [More](/admin/components/#field-component) |
30
+ | **`admin.components.Field`** | React component to be rendered for this field within the Edit view. [More](/docs/admin/components/#field-component) |
31
+ | **`admin.components.Cell`** | React component to be rendered as a Cell within collection List views. [More](/docs/admin/components/#field-component) |
32
32
 
33
33
  *\* An asterisk denotes that a property is required.*
34
34
 
@@ -48,7 +48,7 @@ The team behind Payload has been building websites and apps with existing conten
48
48
  - Secure
49
49
  - Fully flexible and extensible
50
50
 
51
- Payload is our silver bullet solution. It represents over two years of passionate development and brings everything we need when we build new apps and websites:
51
+ Payload is our silver bullet solution. We've blended the best parts of our experience with other CMS and app frameworks into Payload, and we finally have everything we need when we build new apps and websites:
52
52
 
53
53
  - A beautiful, dynamic, customizable admin UI
54
54
  - Extensible and reusable authentication
@@ -14,7 +14,7 @@ The labels you provide for your Collections and Globals are used to name the Gra
14
14
 
15
15
  ## GraphQL Options
16
16
 
17
- At the top of your Payload config you can define all the options to manage GraphQL. The
17
+ At the top of your Payload config you can define all the options to manage GraphQL.
18
18
 
19
19
  | Option | Description |
20
20
  | -------------------- | -------------|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
4
4
  "description": "Node, React and MongoDB Headless CMS and Application Framework",
5
5
  "license": "MIT",
6
6
  "engines": {